blob: c18e5ac519cd604bc95d4536d8d078afadd69021 [file] [log] [blame]
Douglas Gregor2436e712009-09-17 21:32:03 +00001//===---------------- SemaCodeComplete.cpp - Code Completion ----*- C++ -*-===//
2//
3// The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9//
10// This file defines the code-completion semantic actions.
11//
12//===----------------------------------------------------------------------===//
13#include "Sema.h"
14#include "clang/Sema/CodeCompleteConsumer.h"
Douglas Gregorf2510672009-09-21 19:57:38 +000015#include "clang/AST/ExprCXX.h"
Douglas Gregor8ce33212009-11-17 17:59:40 +000016#include "clang/AST/ExprObjC.h"
Douglas Gregorf329c7c2009-10-30 16:50:04 +000017#include "clang/Lex/MacroInfo.h"
18#include "clang/Lex/Preprocessor.h"
Douglas Gregor3545ff42009-09-21 16:56:56 +000019#include "llvm/ADT/SmallPtrSet.h"
Douglas Gregore6688e62009-09-28 03:51:44 +000020#include "llvm/ADT/StringExtras.h"
Douglas Gregor3545ff42009-09-21 16:56:56 +000021#include <list>
22#include <map>
23#include <vector>
Douglas Gregor2436e712009-09-17 21:32:03 +000024
25using namespace clang;
26
Douglas Gregor3545ff42009-09-21 16:56:56 +000027namespace {
28 /// \brief A container of code-completion results.
29 class ResultBuilder {
30 public:
31 /// \brief The type of a name-lookup filter, which can be provided to the
32 /// name-lookup routines to specify which declarations should be included in
33 /// the result set (when it returns true) and which declarations should be
34 /// filtered out (returns false).
35 typedef bool (ResultBuilder::*LookupFilter)(NamedDecl *) const;
36
37 typedef CodeCompleteConsumer::Result Result;
38
39 private:
40 /// \brief The actual results we have found.
41 std::vector<Result> Results;
42
43 /// \brief A record of all of the declarations we have found and placed
44 /// into the result set, used to ensure that no declaration ever gets into
45 /// the result set twice.
46 llvm::SmallPtrSet<Decl*, 16> AllDeclsFound;
47
Douglas Gregor05e7ca32009-12-06 20:23:50 +000048 typedef std::pair<NamedDecl *, unsigned> DeclIndexPair;
49
50 /// \brief An entry in the shadow map, which is optimized to store
51 /// a single (declaration, index) mapping (the common case) but
52 /// can also store a list of (declaration, index) mappings.
53 class ShadowMapEntry {
54 typedef llvm::SmallVector<DeclIndexPair, 4> DeclIndexPairVector;
55
56 /// \brief Contains either the solitary NamedDecl * or a vector
57 /// of (declaration, index) pairs.
58 llvm::PointerUnion<NamedDecl *, DeclIndexPairVector*> DeclOrVector;
59
60 /// \brief When the entry contains a single declaration, this is
61 /// the index associated with that entry.
62 unsigned SingleDeclIndex;
63
64 public:
65 ShadowMapEntry() : DeclOrVector(), SingleDeclIndex(0) { }
66
67 void Add(NamedDecl *ND, unsigned Index) {
68 if (DeclOrVector.isNull()) {
69 // 0 - > 1 elements: just set the single element information.
70 DeclOrVector = ND;
71 SingleDeclIndex = Index;
72 return;
73 }
74
75 if (NamedDecl *PrevND = DeclOrVector.dyn_cast<NamedDecl *>()) {
76 // 1 -> 2 elements: create the vector of results and push in the
77 // existing declaration.
78 DeclIndexPairVector *Vec = new DeclIndexPairVector;
79 Vec->push_back(DeclIndexPair(PrevND, SingleDeclIndex));
80 DeclOrVector = Vec;
81 }
82
83 // Add the new element to the end of the vector.
84 DeclOrVector.get<DeclIndexPairVector*>()->push_back(
85 DeclIndexPair(ND, Index));
86 }
87
88 void Destroy() {
89 if (DeclIndexPairVector *Vec
90 = DeclOrVector.dyn_cast<DeclIndexPairVector *>()) {
91 delete Vec;
92 DeclOrVector = ((NamedDecl *)0);
93 }
94 }
95
96 // Iteration.
97 class iterator;
98 iterator begin() const;
99 iterator end() const;
100 };
101
Douglas Gregor3545ff42009-09-21 16:56:56 +0000102 /// \brief A mapping from declaration names to the declarations that have
103 /// this name within a particular scope and their index within the list of
104 /// results.
Douglas Gregor05e7ca32009-12-06 20:23:50 +0000105 typedef llvm::DenseMap<DeclarationName, ShadowMapEntry> ShadowMap;
Douglas Gregor3545ff42009-09-21 16:56:56 +0000106
107 /// \brief The semantic analysis object for which results are being
108 /// produced.
109 Sema &SemaRef;
110
111 /// \brief If non-NULL, a filter function used to remove any code-completion
112 /// results that are not desirable.
113 LookupFilter Filter;
114
115 /// \brief A list of shadow maps, which is used to model name hiding at
116 /// different levels of, e.g., the inheritance hierarchy.
117 std::list<ShadowMap> ShadowMaps;
118
119 public:
120 explicit ResultBuilder(Sema &SemaRef, LookupFilter Filter = 0)
121 : SemaRef(SemaRef), Filter(Filter) { }
122
123 /// \brief Set the filter used for code-completion results.
124 void setFilter(LookupFilter Filter) {
125 this->Filter = Filter;
126 }
127
128 typedef std::vector<Result>::iterator iterator;
129 iterator begin() { return Results.begin(); }
130 iterator end() { return Results.end(); }
131
132 Result *data() { return Results.empty()? 0 : &Results.front(); }
133 unsigned size() const { return Results.size(); }
134 bool empty() const { return Results.empty(); }
135
136 /// \brief Add a new result to this result set (if it isn't already in one
137 /// of the shadow maps), or replace an existing result (for, e.g., a
138 /// redeclaration).
Douglas Gregor2af2f672009-09-21 20:12:40 +0000139 ///
140 /// \param R the result to add (if it is unique).
141 ///
142 /// \param R the context in which this result will be named.
143 void MaybeAddResult(Result R, DeclContext *CurContext = 0);
Douglas Gregor3545ff42009-09-21 16:56:56 +0000144
145 /// \brief Enter into a new scope.
146 void EnterNewScope();
147
148 /// \brief Exit from the current scope.
149 void ExitScope();
150
Douglas Gregorbaf69612009-11-18 04:19:12 +0000151 /// \brief Ignore this declaration, if it is seen again.
152 void Ignore(Decl *D) { AllDeclsFound.insert(D->getCanonicalDecl()); }
153
Douglas Gregor3545ff42009-09-21 16:56:56 +0000154 /// \name Name lookup predicates
155 ///
156 /// These predicates can be passed to the name lookup functions to filter the
157 /// results of name lookup. All of the predicates have the same type, so that
158 ///
159 //@{
Douglas Gregor9d64c5e2009-09-21 20:51:25 +0000160 bool IsOrdinaryName(NamedDecl *ND) const;
Douglas Gregor504a6ae2010-01-10 23:08:15 +0000161 bool IsOrdinaryNonValueName(NamedDecl *ND) const;
Douglas Gregor3545ff42009-09-21 16:56:56 +0000162 bool IsNestedNameSpecifier(NamedDecl *ND) const;
163 bool IsEnum(NamedDecl *ND) const;
164 bool IsClassOrStruct(NamedDecl *ND) const;
165 bool IsUnion(NamedDecl *ND) const;
166 bool IsNamespace(NamedDecl *ND) const;
167 bool IsNamespaceOrAlias(NamedDecl *ND) const;
168 bool IsType(NamedDecl *ND) const;
Douglas Gregore412a5a2009-09-23 22:26:46 +0000169 bool IsMember(NamedDecl *ND) const;
Douglas Gregor3545ff42009-09-21 16:56:56 +0000170 //@}
171 };
172}
173
Douglas Gregor05e7ca32009-12-06 20:23:50 +0000174class ResultBuilder::ShadowMapEntry::iterator {
175 llvm::PointerUnion<NamedDecl*, const DeclIndexPair*> DeclOrIterator;
176 unsigned SingleDeclIndex;
177
178public:
179 typedef DeclIndexPair value_type;
180 typedef value_type reference;
181 typedef std::ptrdiff_t difference_type;
182 typedef std::input_iterator_tag iterator_category;
183
184 class pointer {
185 DeclIndexPair Value;
186
187 public:
188 pointer(const DeclIndexPair &Value) : Value(Value) { }
189
190 const DeclIndexPair *operator->() const {
191 return &Value;
192 }
193 };
194
195 iterator() : DeclOrIterator((NamedDecl *)0), SingleDeclIndex(0) { }
196
197 iterator(NamedDecl *SingleDecl, unsigned Index)
198 : DeclOrIterator(SingleDecl), SingleDeclIndex(Index) { }
199
200 iterator(const DeclIndexPair *Iterator)
201 : DeclOrIterator(Iterator), SingleDeclIndex(0) { }
202
203 iterator &operator++() {
204 if (DeclOrIterator.is<NamedDecl *>()) {
205 DeclOrIterator = (NamedDecl *)0;
206 SingleDeclIndex = 0;
207 return *this;
208 }
209
210 const DeclIndexPair *I = DeclOrIterator.get<const DeclIndexPair*>();
211 ++I;
212 DeclOrIterator = I;
213 return *this;
214 }
215
216 iterator operator++(int) {
217 iterator tmp(*this);
218 ++(*this);
219 return tmp;
220 }
221
222 reference operator*() const {
223 if (NamedDecl *ND = DeclOrIterator.dyn_cast<NamedDecl *>())
224 return reference(ND, SingleDeclIndex);
225
Douglas Gregor94bb5e82009-12-06 21:27:58 +0000226 return *DeclOrIterator.get<const DeclIndexPair*>();
Douglas Gregor05e7ca32009-12-06 20:23:50 +0000227 }
228
229 pointer operator->() const {
230 return pointer(**this);
231 }
232
233 friend bool operator==(const iterator &X, const iterator &Y) {
Douglas Gregor94bb5e82009-12-06 21:27:58 +0000234 return X.DeclOrIterator.getOpaqueValue()
235 == Y.DeclOrIterator.getOpaqueValue() &&
Douglas Gregor05e7ca32009-12-06 20:23:50 +0000236 X.SingleDeclIndex == Y.SingleDeclIndex;
237 }
238
239 friend bool operator!=(const iterator &X, const iterator &Y) {
Douglas Gregor94bb5e82009-12-06 21:27:58 +0000240 return !(X == Y);
Douglas Gregor05e7ca32009-12-06 20:23:50 +0000241 }
242};
243
Douglas Gregor05e7ca32009-12-06 20:23:50 +0000244ResultBuilder::ShadowMapEntry::iterator
245ResultBuilder::ShadowMapEntry::begin() const {
246 if (DeclOrVector.isNull())
247 return iterator();
248
249 if (NamedDecl *ND = DeclOrVector.dyn_cast<NamedDecl *>())
250 return iterator(ND, SingleDeclIndex);
251
252 return iterator(DeclOrVector.get<DeclIndexPairVector *>()->begin());
253}
254
255ResultBuilder::ShadowMapEntry::iterator
256ResultBuilder::ShadowMapEntry::end() const {
257 if (DeclOrVector.is<NamedDecl *>() || DeclOrVector.isNull())
258 return iterator();
259
260 return iterator(DeclOrVector.get<DeclIndexPairVector *>()->end());
261}
262
Douglas Gregor3545ff42009-09-21 16:56:56 +0000263/// \brief Determines whether the given hidden result could be found with
264/// some extra work, e.g., by qualifying the name.
265///
266/// \param Hidden the declaration that is hidden by the currenly \p Visible
267/// declaration.
268///
269/// \param Visible the declaration with the same name that is already visible.
270///
271/// \returns true if the hidden result can be found by some mechanism,
272/// false otherwise.
273static bool canHiddenResultBeFound(const LangOptions &LangOpts,
274 NamedDecl *Hidden, NamedDecl *Visible) {
275 // In C, there is no way to refer to a hidden name.
276 if (!LangOpts.CPlusPlus)
277 return false;
278
279 DeclContext *HiddenCtx = Hidden->getDeclContext()->getLookupContext();
280
281 // There is no way to qualify a name declared in a function or method.
282 if (HiddenCtx->isFunctionOrMethod())
283 return false;
284
Douglas Gregor3545ff42009-09-21 16:56:56 +0000285 return HiddenCtx != Visible->getDeclContext()->getLookupContext();
286}
287
Douglas Gregor2af2f672009-09-21 20:12:40 +0000288/// \brief Compute the qualification required to get from the current context
289/// (\p CurContext) to the target context (\p TargetContext).
290///
291/// \param Context the AST context in which the qualification will be used.
292///
293/// \param CurContext the context where an entity is being named, which is
294/// typically based on the current scope.
295///
296/// \param TargetContext the context in which the named entity actually
297/// resides.
298///
299/// \returns a nested name specifier that refers into the target context, or
300/// NULL if no qualification is needed.
301static NestedNameSpecifier *
302getRequiredQualification(ASTContext &Context,
303 DeclContext *CurContext,
304 DeclContext *TargetContext) {
305 llvm::SmallVector<DeclContext *, 4> TargetParents;
306
307 for (DeclContext *CommonAncestor = TargetContext;
308 CommonAncestor && !CommonAncestor->Encloses(CurContext);
309 CommonAncestor = CommonAncestor->getLookupParent()) {
310 if (CommonAncestor->isTransparentContext() ||
311 CommonAncestor->isFunctionOrMethod())
312 continue;
313
314 TargetParents.push_back(CommonAncestor);
315 }
316
317 NestedNameSpecifier *Result = 0;
318 while (!TargetParents.empty()) {
319 DeclContext *Parent = TargetParents.back();
320 TargetParents.pop_back();
321
322 if (NamespaceDecl *Namespace = dyn_cast<NamespaceDecl>(Parent))
323 Result = NestedNameSpecifier::Create(Context, Result, Namespace);
324 else if (TagDecl *TD = dyn_cast<TagDecl>(Parent))
325 Result = NestedNameSpecifier::Create(Context, Result,
326 false,
327 Context.getTypeDeclType(TD).getTypePtr());
328 else
329 assert(Parent->isTranslationUnit());
Douglas Gregor9eb77012009-11-07 00:00:49 +0000330 }
Douglas Gregor2af2f672009-09-21 20:12:40 +0000331 return Result;
332}
333
334void ResultBuilder::MaybeAddResult(Result R, DeclContext *CurContext) {
Douglas Gregor64b12b52009-09-22 23:31:26 +0000335 assert(!ShadowMaps.empty() && "Must enter into a results scope");
336
Douglas Gregor3545ff42009-09-21 16:56:56 +0000337 if (R.Kind != Result::RK_Declaration) {
338 // For non-declaration results, just add the result.
339 Results.push_back(R);
340 return;
341 }
Douglas Gregor58acf322009-10-09 22:16:47 +0000342
343 // Skip unnamed entities.
344 if (!R.Declaration->getDeclName())
345 return;
346
Douglas Gregor3545ff42009-09-21 16:56:56 +0000347 // Look through using declarations.
John McCall3f746822009-11-17 05:59:44 +0000348 if (UsingShadowDecl *Using = dyn_cast<UsingShadowDecl>(R.Declaration))
Douglas Gregorf98e6a22010-01-13 23:51:12 +0000349 MaybeAddResult(Result(Using->getTargetDecl(), R.Qualifier), CurContext);
Douglas Gregor3545ff42009-09-21 16:56:56 +0000350
Douglas Gregor3545ff42009-09-21 16:56:56 +0000351 Decl *CanonDecl = R.Declaration->getCanonicalDecl();
352 unsigned IDNS = CanonDecl->getIdentifierNamespace();
353
354 // Friend declarations and declarations introduced due to friends are never
355 // added as results.
356 if (isa<FriendDecl>(CanonDecl) ||
357 (IDNS & (Decl::IDNS_OrdinaryFriend | Decl::IDNS_TagFriend)))
358 return;
Douglas Gregor83c49b52009-12-11 16:18:54 +0000359
Douglas Gregor99fe2ad2009-12-11 17:31:05 +0000360 // Class template (partial) specializations are never added as results.
Douglas Gregor83c49b52009-12-11 16:18:54 +0000361 if (isa<ClassTemplateSpecializationDecl>(CanonDecl) ||
362 isa<ClassTemplatePartialSpecializationDecl>(CanonDecl))
363 return;
Douglas Gregor3545ff42009-09-21 16:56:56 +0000364
Douglas Gregor99fe2ad2009-12-11 17:31:05 +0000365 // Using declarations themselves are never added as results.
366 if (isa<UsingDecl>(CanonDecl))
367 return;
368
Douglas Gregor3545ff42009-09-21 16:56:56 +0000369 if (const IdentifierInfo *Id = R.Declaration->getIdentifier()) {
370 // __va_list_tag is a freak of nature. Find it and skip it.
371 if (Id->isStr("__va_list_tag") || Id->isStr("__builtin_va_list"))
372 return;
373
Douglas Gregor58acf322009-10-09 22:16:47 +0000374 // Filter out names reserved for the implementation (C99 7.1.3,
375 // C++ [lib.global.names]). Users don't need to see those.
Daniel Dunbar2c422dc92009-10-18 20:26:12 +0000376 //
377 // FIXME: Add predicate for this.
Douglas Gregor58acf322009-10-09 22:16:47 +0000378 if (Id->getLength() >= 2) {
Daniel Dunbar2c422dc92009-10-18 20:26:12 +0000379 const char *Name = Id->getNameStart();
Douglas Gregor58acf322009-10-09 22:16:47 +0000380 if (Name[0] == '_' &&
381 (Name[1] == '_' || (Name[1] >= 'A' && Name[1] <= 'Z')))
382 return;
383 }
Douglas Gregor3545ff42009-09-21 16:56:56 +0000384 }
385
386 // C++ constructors are never found by name lookup.
387 if (isa<CXXConstructorDecl>(CanonDecl))
388 return;
389
390 // Filter out any unwanted results.
391 if (Filter && !(this->*Filter)(R.Declaration))
392 return;
393
394 ShadowMap &SMap = ShadowMaps.back();
Douglas Gregor05e7ca32009-12-06 20:23:50 +0000395 ShadowMapEntry::iterator I, IEnd;
396 ShadowMap::iterator NamePos = SMap.find(R.Declaration->getDeclName());
397 if (NamePos != SMap.end()) {
398 I = NamePos->second.begin();
399 IEnd = NamePos->second.end();
400 }
401
402 for (; I != IEnd; ++I) {
403 NamedDecl *ND = I->first;
404 unsigned Index = I->second;
Douglas Gregor3545ff42009-09-21 16:56:56 +0000405 if (ND->getCanonicalDecl() == CanonDecl) {
406 // This is a redeclaration. Always pick the newer declaration.
Douglas Gregor3545ff42009-09-21 16:56:56 +0000407 Results[Index].Declaration = R.Declaration;
408
Douglas Gregor3545ff42009-09-21 16:56:56 +0000409 // We're done.
410 return;
411 }
412 }
413
414 // This is a new declaration in this scope. However, check whether this
415 // declaration name is hidden by a similarly-named declaration in an outer
416 // scope.
417 std::list<ShadowMap>::iterator SM, SMEnd = ShadowMaps.end();
418 --SMEnd;
419 for (SM = ShadowMaps.begin(); SM != SMEnd; ++SM) {
Douglas Gregor05e7ca32009-12-06 20:23:50 +0000420 ShadowMapEntry::iterator I, IEnd;
421 ShadowMap::iterator NamePos = SM->find(R.Declaration->getDeclName());
422 if (NamePos != SM->end()) {
423 I = NamePos->second.begin();
424 IEnd = NamePos->second.end();
425 }
426 for (; I != IEnd; ++I) {
Douglas Gregor3545ff42009-09-21 16:56:56 +0000427 // A tag declaration does not hide a non-tag declaration.
Douglas Gregor05e7ca32009-12-06 20:23:50 +0000428 if (I->first->getIdentifierNamespace() == Decl::IDNS_Tag &&
Douglas Gregor3545ff42009-09-21 16:56:56 +0000429 (IDNS & (Decl::IDNS_Member | Decl::IDNS_Ordinary |
430 Decl::IDNS_ObjCProtocol)))
431 continue;
432
433 // Protocols are in distinct namespaces from everything else.
Douglas Gregor05e7ca32009-12-06 20:23:50 +0000434 if (((I->first->getIdentifierNamespace() & Decl::IDNS_ObjCProtocol)
Douglas Gregor3545ff42009-09-21 16:56:56 +0000435 || (IDNS & Decl::IDNS_ObjCProtocol)) &&
Douglas Gregor05e7ca32009-12-06 20:23:50 +0000436 I->first->getIdentifierNamespace() != IDNS)
Douglas Gregor3545ff42009-09-21 16:56:56 +0000437 continue;
438
439 // The newly-added result is hidden by an entry in the shadow map.
440 if (canHiddenResultBeFound(SemaRef.getLangOptions(), R.Declaration,
Douglas Gregor05e7ca32009-12-06 20:23:50 +0000441 I->first)) {
Douglas Gregor3545ff42009-09-21 16:56:56 +0000442 // Note that this result was hidden.
443 R.Hidden = true;
Douglas Gregor5bf52692009-09-22 23:15:58 +0000444 R.QualifierIsInformative = false;
Douglas Gregor2af2f672009-09-21 20:12:40 +0000445
446 if (!R.Qualifier)
447 R.Qualifier = getRequiredQualification(SemaRef.Context,
448 CurContext,
449 R.Declaration->getDeclContext());
Douglas Gregor3545ff42009-09-21 16:56:56 +0000450 } else {
451 // This result was hidden and cannot be found; don't bother adding
452 // it.
453 return;
454 }
455
456 break;
457 }
458 }
459
460 // Make sure that any given declaration only shows up in the result set once.
461 if (!AllDeclsFound.insert(CanonDecl))
462 return;
463
Douglas Gregore412a5a2009-09-23 22:26:46 +0000464 // If the filter is for nested-name-specifiers, then this result starts a
465 // nested-name-specifier.
466 if ((Filter == &ResultBuilder::IsNestedNameSpecifier) ||
467 (Filter == &ResultBuilder::IsMember &&
468 isa<CXXRecordDecl>(R.Declaration) &&
469 cast<CXXRecordDecl>(R.Declaration)->isInjectedClassName()))
470 R.StartsNestedNameSpecifier = true;
471
Douglas Gregor5bf52692009-09-22 23:15:58 +0000472 // If this result is supposed to have an informative qualifier, add one.
Douglas Gregore412a5a2009-09-23 22:26:46 +0000473 if (R.QualifierIsInformative && !R.Qualifier &&
474 !R.StartsNestedNameSpecifier) {
Douglas Gregor5bf52692009-09-22 23:15:58 +0000475 DeclContext *Ctx = R.Declaration->getDeclContext();
476 if (NamespaceDecl *Namespace = dyn_cast<NamespaceDecl>(Ctx))
477 R.Qualifier = NestedNameSpecifier::Create(SemaRef.Context, 0, Namespace);
478 else if (TagDecl *Tag = dyn_cast<TagDecl>(Ctx))
479 R.Qualifier = NestedNameSpecifier::Create(SemaRef.Context, 0, false,
480 SemaRef.Context.getTypeDeclType(Tag).getTypePtr());
481 else
482 R.QualifierIsInformative = false;
483 }
Douglas Gregore412a5a2009-09-23 22:26:46 +0000484
Douglas Gregor3545ff42009-09-21 16:56:56 +0000485 // Insert this result into the set of results and into the current shadow
486 // map.
Douglas Gregor05e7ca32009-12-06 20:23:50 +0000487 SMap[R.Declaration->getDeclName()].Add(R.Declaration, Results.size());
Douglas Gregor3545ff42009-09-21 16:56:56 +0000488 Results.push_back(R);
489}
490
491/// \brief Enter into a new scope.
492void ResultBuilder::EnterNewScope() {
493 ShadowMaps.push_back(ShadowMap());
494}
495
496/// \brief Exit from the current scope.
497void ResultBuilder::ExitScope() {
Douglas Gregor05e7ca32009-12-06 20:23:50 +0000498 for (ShadowMap::iterator E = ShadowMaps.back().begin(),
499 EEnd = ShadowMaps.back().end();
500 E != EEnd;
501 ++E)
502 E->second.Destroy();
503
Douglas Gregor3545ff42009-09-21 16:56:56 +0000504 ShadowMaps.pop_back();
505}
506
Douglas Gregor9d64c5e2009-09-21 20:51:25 +0000507/// \brief Determines whether this given declaration will be found by
508/// ordinary name lookup.
509bool ResultBuilder::IsOrdinaryName(NamedDecl *ND) const {
510 unsigned IDNS = Decl::IDNS_Ordinary;
511 if (SemaRef.getLangOptions().CPlusPlus)
512 IDNS |= Decl::IDNS_Tag;
513
514 return ND->getIdentifierNamespace() & IDNS;
515}
516
Douglas Gregor504a6ae2010-01-10 23:08:15 +0000517/// \brief Determines whether this given declaration will be found by
518/// ordinary name lookup.
519bool ResultBuilder::IsOrdinaryNonValueName(NamedDecl *ND) const {
520 unsigned IDNS = Decl::IDNS_Ordinary;
521 if (SemaRef.getLangOptions().CPlusPlus)
522 IDNS |= Decl::IDNS_Tag;
523
524 return (ND->getIdentifierNamespace() & IDNS) &&
525 !isa<ValueDecl>(ND) && !isa<FunctionTemplateDecl>(ND);
526}
527
Douglas Gregor3545ff42009-09-21 16:56:56 +0000528/// \brief Determines whether the given declaration is suitable as the
529/// start of a C++ nested-name-specifier, e.g., a class or namespace.
530bool ResultBuilder::IsNestedNameSpecifier(NamedDecl *ND) const {
531 // Allow us to find class templates, too.
532 if (ClassTemplateDecl *ClassTemplate = dyn_cast<ClassTemplateDecl>(ND))
533 ND = ClassTemplate->getTemplatedDecl();
534
535 return SemaRef.isAcceptableNestedNameSpecifier(ND);
536}
537
538/// \brief Determines whether the given declaration is an enumeration.
539bool ResultBuilder::IsEnum(NamedDecl *ND) const {
540 return isa<EnumDecl>(ND);
541}
542
543/// \brief Determines whether the given declaration is a class or struct.
544bool ResultBuilder::IsClassOrStruct(NamedDecl *ND) const {
545 // Allow us to find class templates, too.
546 if (ClassTemplateDecl *ClassTemplate = dyn_cast<ClassTemplateDecl>(ND))
547 ND = ClassTemplate->getTemplatedDecl();
548
549 if (RecordDecl *RD = dyn_cast<RecordDecl>(ND))
550 return RD->getTagKind() == TagDecl::TK_class ||
551 RD->getTagKind() == TagDecl::TK_struct;
552
553 return false;
554}
555
556/// \brief Determines whether the given declaration is a union.
557bool ResultBuilder::IsUnion(NamedDecl *ND) const {
558 // Allow us to find class templates, too.
559 if (ClassTemplateDecl *ClassTemplate = dyn_cast<ClassTemplateDecl>(ND))
560 ND = ClassTemplate->getTemplatedDecl();
561
562 if (RecordDecl *RD = dyn_cast<RecordDecl>(ND))
563 return RD->getTagKind() == TagDecl::TK_union;
564
565 return false;
566}
567
568/// \brief Determines whether the given declaration is a namespace.
569bool ResultBuilder::IsNamespace(NamedDecl *ND) const {
570 return isa<NamespaceDecl>(ND);
571}
572
573/// \brief Determines whether the given declaration is a namespace or
574/// namespace alias.
575bool ResultBuilder::IsNamespaceOrAlias(NamedDecl *ND) const {
576 return isa<NamespaceDecl>(ND) || isa<NamespaceAliasDecl>(ND);
577}
578
Douglas Gregor99fe2ad2009-12-11 17:31:05 +0000579/// \brief Determines whether the given declaration is a type.
Douglas Gregor3545ff42009-09-21 16:56:56 +0000580bool ResultBuilder::IsType(NamedDecl *ND) const {
581 return isa<TypeDecl>(ND);
582}
583
Douglas Gregor99fe2ad2009-12-11 17:31:05 +0000584/// \brief Determines which members of a class should be visible via
585/// "." or "->". Only value declarations, nested name specifiers, and
586/// using declarations thereof should show up.
Douglas Gregore412a5a2009-09-23 22:26:46 +0000587bool ResultBuilder::IsMember(NamedDecl *ND) const {
Douglas Gregor99fe2ad2009-12-11 17:31:05 +0000588 if (UsingShadowDecl *Using = dyn_cast<UsingShadowDecl>(ND))
589 ND = Using->getTargetDecl();
590
Douglas Gregor70788392009-12-11 18:14:22 +0000591 return isa<ValueDecl>(ND) || isa<FunctionTemplateDecl>(ND) ||
592 isa<ObjCPropertyDecl>(ND);
Douglas Gregore412a5a2009-09-23 22:26:46 +0000593}
594
Douglas Gregor3545ff42009-09-21 16:56:56 +0000595// Find the next outer declaration context corresponding to this scope.
596static DeclContext *findOuterContext(Scope *S) {
597 for (S = S->getParent(); S; S = S->getParent())
598 if (S->getEntity())
599 return static_cast<DeclContext *>(S->getEntity())->getPrimaryContext();
600
601 return 0;
602}
603
604/// \brief Collect the results of searching for members within the given
605/// declaration context.
606///
607/// \param Ctx the declaration context from which we will gather results.
608///
Douglas Gregor3545ff42009-09-21 16:56:56 +0000609/// \param Visited the set of declaration contexts that have already been
610/// visited. Declaration contexts will only be visited once.
611///
612/// \param Results the result set that will be extended with any results
613/// found within this declaration context (and, for a C++ class, its bases).
614///
Douglas Gregor5bf52692009-09-22 23:15:58 +0000615/// \param InBaseClass whether we are in a base class.
Douglas Gregorf98e6a22010-01-13 23:51:12 +0000616static void CollectMemberLookupResults(DeclContext *Ctx,
617 DeclContext *CurContext,
Douglas Gregor2af2f672009-09-21 20:12:40 +0000618 llvm::SmallPtrSet<DeclContext *, 16> &Visited,
Douglas Gregorf98e6a22010-01-13 23:51:12 +0000619 ResultBuilder &Results,
620 bool InBaseClass = false) {
Douglas Gregor3545ff42009-09-21 16:56:56 +0000621 // Make sure we don't visit the same context twice.
622 if (!Visited.insert(Ctx->getPrimaryContext()))
Douglas Gregorf98e6a22010-01-13 23:51:12 +0000623 return;
Douglas Gregor3545ff42009-09-21 16:56:56 +0000624
625 // Enumerate all of the results in this context.
Douglas Gregor5bf52692009-09-22 23:15:58 +0000626 typedef CodeCompleteConsumer::Result Result;
Douglas Gregor3545ff42009-09-21 16:56:56 +0000627 Results.EnterNewScope();
628 for (DeclContext *CurCtx = Ctx->getPrimaryContext(); CurCtx;
629 CurCtx = CurCtx->getNextContext()) {
630 for (DeclContext::decl_iterator D = CurCtx->decls_begin(),
Douglas Gregor8caea942009-11-09 21:35:27 +0000631 DEnd = CurCtx->decls_end();
Douglas Gregor3545ff42009-09-21 16:56:56 +0000632 D != DEnd; ++D) {
633 if (NamedDecl *ND = dyn_cast<NamedDecl>(*D))
Douglas Gregorf98e6a22010-01-13 23:51:12 +0000634 Results.MaybeAddResult(Result(ND, 0, InBaseClass), CurContext);
Douglas Gregor8caea942009-11-09 21:35:27 +0000635
636 // Visit transparent contexts inside this context.
637 if (DeclContext *InnerCtx = dyn_cast<DeclContext>(*D)) {
638 if (InnerCtx->isTransparentContext())
Douglas Gregorf98e6a22010-01-13 23:51:12 +0000639 CollectMemberLookupResults(InnerCtx, CurContext, Visited,
Douglas Gregor8caea942009-11-09 21:35:27 +0000640 Results, InBaseClass);
641 }
Douglas Gregor3545ff42009-09-21 16:56:56 +0000642 }
643 }
644
645 // Traverse the contexts of inherited classes.
Douglas Gregor3545ff42009-09-21 16:56:56 +0000646 if (CXXRecordDecl *Record = dyn_cast<CXXRecordDecl>(Ctx)) {
647 for (CXXRecordDecl::base_class_iterator B = Record->bases_begin(),
Douglas Gregor8caea942009-11-09 21:35:27 +0000648 BEnd = Record->bases_end();
Douglas Gregor3545ff42009-09-21 16:56:56 +0000649 B != BEnd; ++B) {
650 QualType BaseType = B->getType();
651
652 // Don't look into dependent bases, because name lookup can't look
653 // there anyway.
654 if (BaseType->isDependentType())
655 continue;
656
657 const RecordType *Record = BaseType->getAs<RecordType>();
658 if (!Record)
659 continue;
660
661 // FIXME: It would be nice to be able to determine whether referencing
662 // a particular member would be ambiguous. For example, given
663 //
664 // struct A { int member; };
665 // struct B { int member; };
666 // struct C : A, B { };
667 //
668 // void f(C *c) { c->### }
669 // accessing 'member' would result in an ambiguity. However, code
670 // completion could be smart enough to qualify the member with the
671 // base class, e.g.,
672 //
673 // c->B::member
674 //
675 // or
676 //
677 // c->A::member
678
679 // Collect results from this base class (and its bases).
Douglas Gregorf98e6a22010-01-13 23:51:12 +0000680 CollectMemberLookupResults(Record->getDecl(), CurContext, Visited,
Douglas Gregor5bf52692009-09-22 23:15:58 +0000681 Results, /*InBaseClass=*/true);
Douglas Gregor3545ff42009-09-21 16:56:56 +0000682 }
683 }
684
685 // FIXME: Look into base classes in Objective-C!
686
687 Results.ExitScope();
Douglas Gregor3545ff42009-09-21 16:56:56 +0000688}
689
690/// \brief Collect the results of searching for members within the given
691/// declaration context.
692///
693/// \param Ctx the declaration context from which we will gather results.
694///
Douglas Gregor3545ff42009-09-21 16:56:56 +0000695/// \param Results the result set that will be extended with any results
696/// found within this declaration context (and, for a C++ class, its bases).
Douglas Gregorf98e6a22010-01-13 23:51:12 +0000697static void CollectMemberLookupResults(DeclContext *Ctx,
698 DeclContext *CurContext,
699 ResultBuilder &Results) {
Douglas Gregor3545ff42009-09-21 16:56:56 +0000700 llvm::SmallPtrSet<DeclContext *, 16> Visited;
Douglas Gregorf98e6a22010-01-13 23:51:12 +0000701 CollectMemberLookupResults(Ctx, CurContext, Visited, Results);
Douglas Gregor3545ff42009-09-21 16:56:56 +0000702}
703
704/// \brief Collect the results of searching for declarations within the given
705/// scope and its parent scopes.
706///
707/// \param S the scope in which we will start looking for declarations.
708///
Douglas Gregor2af2f672009-09-21 20:12:40 +0000709/// \param CurContext the context from which lookup results will be found.
710///
Douglas Gregor3545ff42009-09-21 16:56:56 +0000711/// \param Results the builder object that will receive each result.
Douglas Gregorf98e6a22010-01-13 23:51:12 +0000712static void CollectLookupResults(Scope *S,
713 TranslationUnitDecl *TranslationUnit,
714 DeclContext *CurContext,
715 ResultBuilder &Results) {
Douglas Gregor3545ff42009-09-21 16:56:56 +0000716 if (!S)
Douglas Gregorf98e6a22010-01-13 23:51:12 +0000717 return;
Douglas Gregor3545ff42009-09-21 16:56:56 +0000718
719 // FIXME: Using directives!
720
Douglas Gregor3545ff42009-09-21 16:56:56 +0000721 Results.EnterNewScope();
722 if (S->getEntity() &&
723 !((DeclContext *)S->getEntity())->isFunctionOrMethod()) {
724 // Look into this scope's declaration context, along with any of its
725 // parent lookup contexts (e.g., enclosing classes), up to the point
726 // where we hit the context stored in the next outer scope.
727 DeclContext *Ctx = (DeclContext *)S->getEntity();
728 DeclContext *OuterCtx = findOuterContext(S);
729
730 for (; Ctx && Ctx->getPrimaryContext() != OuterCtx;
731 Ctx = Ctx->getLookupParent()) {
732 if (Ctx->isFunctionOrMethod())
733 continue;
734
Douglas Gregorf98e6a22010-01-13 23:51:12 +0000735 CollectMemberLookupResults(Ctx, CurContext, Results);
Douglas Gregor3545ff42009-09-21 16:56:56 +0000736 }
737 } else if (!S->getParent()) {
738 // Look into the translation unit scope. We walk through the translation
739 // unit's declaration context, because the Scope itself won't have all of
740 // the declarations if we loaded a precompiled header.
741 // FIXME: We would like the translation unit's Scope object to point to the
742 // translation unit, so we don't need this special "if" branch. However,
743 // doing so would force the normal C++ name-lookup code to look into the
744 // translation unit decl when the IdentifierInfo chains would suffice.
745 // Once we fix that problem (which is part of a more general "don't look
746 // in DeclContexts unless we have to" optimization), we can eliminate the
747 // TranslationUnit parameter entirely.
Douglas Gregorf98e6a22010-01-13 23:51:12 +0000748 CollectMemberLookupResults(TranslationUnit, CurContext, Results);
Douglas Gregor3545ff42009-09-21 16:56:56 +0000749 } else {
750 // Walk through the declarations in this Scope.
751 for (Scope::decl_iterator D = S->decl_begin(), DEnd = S->decl_end();
752 D != DEnd; ++D) {
753 if (NamedDecl *ND = dyn_cast<NamedDecl>((Decl *)((*D).get())))
Douglas Gregorf98e6a22010-01-13 23:51:12 +0000754 Results.MaybeAddResult(CodeCompleteConsumer::Result(ND), CurContext);
Douglas Gregor3545ff42009-09-21 16:56:56 +0000755 }
Douglas Gregor3545ff42009-09-21 16:56:56 +0000756 }
757
758 // Lookup names in the parent scope.
Douglas Gregorf98e6a22010-01-13 23:51:12 +0000759 CollectLookupResults(S->getParent(), TranslationUnit, CurContext, Results);
Douglas Gregor3545ff42009-09-21 16:56:56 +0000760 Results.ExitScope();
Douglas Gregor3545ff42009-09-21 16:56:56 +0000761}
762
763/// \brief Add type specifiers for the current language as keyword results.
Douglas Gregorf98e6a22010-01-13 23:51:12 +0000764static void AddTypeSpecifierResults(const LangOptions &LangOpts,
Douglas Gregor3545ff42009-09-21 16:56:56 +0000765 ResultBuilder &Results) {
766 typedef CodeCompleteConsumer::Result Result;
Douglas Gregorf98e6a22010-01-13 23:51:12 +0000767 Results.MaybeAddResult(Result("short"));
768 Results.MaybeAddResult(Result("long"));
769 Results.MaybeAddResult(Result("signed"));
770 Results.MaybeAddResult(Result("unsigned"));
771 Results.MaybeAddResult(Result("void"));
772 Results.MaybeAddResult(Result("char"));
773 Results.MaybeAddResult(Result("int"));
774 Results.MaybeAddResult(Result("float"));
775 Results.MaybeAddResult(Result("double"));
776 Results.MaybeAddResult(Result("enum"));
777 Results.MaybeAddResult(Result("struct"));
778 Results.MaybeAddResult(Result("union"));
779 Results.MaybeAddResult(Result("const"));
780 Results.MaybeAddResult(Result("volatile"));
Douglas Gregor504a6ae2010-01-10 23:08:15 +0000781
Douglas Gregor3545ff42009-09-21 16:56:56 +0000782 if (LangOpts.C99) {
783 // C99-specific
Douglas Gregorf98e6a22010-01-13 23:51:12 +0000784 Results.MaybeAddResult(Result("_Complex"));
785 Results.MaybeAddResult(Result("_Imaginary"));
786 Results.MaybeAddResult(Result("_Bool"));
787 Results.MaybeAddResult(Result("restrict"));
Douglas Gregor3545ff42009-09-21 16:56:56 +0000788 }
789
790 if (LangOpts.CPlusPlus) {
791 // C++-specific
Douglas Gregorf98e6a22010-01-13 23:51:12 +0000792 Results.MaybeAddResult(Result("bool"));
793 Results.MaybeAddResult(Result("class"));
794 Results.MaybeAddResult(Result("wchar_t"));
Douglas Gregor3545ff42009-09-21 16:56:56 +0000795
Douglas Gregor504a6ae2010-01-10 23:08:15 +0000796 // typename qualified-id
797 CodeCompletionString *Pattern = new CodeCompletionString;
798 Pattern->AddTypedTextChunk("typename");
799 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
800 Pattern->AddPlaceholderChunk("qualified-id");
Douglas Gregorf98e6a22010-01-13 23:51:12 +0000801 Results.MaybeAddResult(Result(Pattern));
Douglas Gregor504a6ae2010-01-10 23:08:15 +0000802
Douglas Gregor3545ff42009-09-21 16:56:56 +0000803 if (LangOpts.CPlusPlus0x) {
Douglas Gregorf98e6a22010-01-13 23:51:12 +0000804 Results.MaybeAddResult(Result("auto"));
805 Results.MaybeAddResult(Result("char16_t"));
806 Results.MaybeAddResult(Result("char32_t"));
807 Results.MaybeAddResult(Result("decltype"));
Douglas Gregor3545ff42009-09-21 16:56:56 +0000808 }
809 }
810
811 // GNU extensions
812 if (LangOpts.GNUMode) {
813 // FIXME: Enable when we actually support decimal floating point.
Douglas Gregorf98e6a22010-01-13 23:51:12 +0000814 // Results.MaybeAddResult(Result("_Decimal32"));
815 // Results.MaybeAddResult(Result("_Decimal64"));
816 // Results.MaybeAddResult(Result("_Decimal128"));
Douglas Gregor504a6ae2010-01-10 23:08:15 +0000817
818 CodeCompletionString *Pattern = new CodeCompletionString;
819 Pattern->AddTypedTextChunk("typeof");
820 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
821 Pattern->AddPlaceholderChunk("expression-or-type");
822 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
Douglas Gregorf98e6a22010-01-13 23:51:12 +0000823 Results.MaybeAddResult(Result(Pattern));
Douglas Gregor3545ff42009-09-21 16:56:56 +0000824 }
825}
826
Douglas Gregor504a6ae2010-01-10 23:08:15 +0000827static void AddStorageSpecifiers(Action::CodeCompletionContext CCC,
828 const LangOptions &LangOpts,
Douglas Gregor504a6ae2010-01-10 23:08:15 +0000829 ResultBuilder &Results) {
830 typedef CodeCompleteConsumer::Result Result;
831 // Note: we don't suggest either "auto" or "register", because both
832 // are pointless as storage specifiers. Elsewhere, we suggest "auto"
833 // in C++0x as a type specifier.
Douglas Gregorf98e6a22010-01-13 23:51:12 +0000834 Results.MaybeAddResult(Result("extern"));
835 Results.MaybeAddResult(Result("static"));
Douglas Gregor504a6ae2010-01-10 23:08:15 +0000836}
837
838static void AddFunctionSpecifiers(Action::CodeCompletionContext CCC,
839 const LangOptions &LangOpts,
Douglas Gregor504a6ae2010-01-10 23:08:15 +0000840 ResultBuilder &Results) {
841 typedef CodeCompleteConsumer::Result Result;
842 switch (CCC) {
843 case Action::CCC_Class:
844 case Action::CCC_MemberTemplate:
845 if (LangOpts.CPlusPlus) {
Douglas Gregorf98e6a22010-01-13 23:51:12 +0000846 Results.MaybeAddResult(Result("explicit"));
847 Results.MaybeAddResult(Result("friend"));
848 Results.MaybeAddResult(Result("mutable"));
849 Results.MaybeAddResult(Result("virtual"));
Douglas Gregor504a6ae2010-01-10 23:08:15 +0000850 }
851 // Fall through
852
Douglas Gregorf1934162010-01-13 21:24:21 +0000853 case Action::CCC_ObjCInterface:
854 case Action::CCC_ObjCImplementation:
Douglas Gregor504a6ae2010-01-10 23:08:15 +0000855 case Action::CCC_Namespace:
856 case Action::CCC_Template:
857 if (LangOpts.CPlusPlus || LangOpts.C99)
Douglas Gregorf98e6a22010-01-13 23:51:12 +0000858 Results.MaybeAddResult(Result("inline"));
Douglas Gregor504a6ae2010-01-10 23:08:15 +0000859 break;
860
Douglas Gregor48d46252010-01-13 21:54:15 +0000861 case Action::CCC_ObjCInstanceVariableList:
Douglas Gregor504a6ae2010-01-10 23:08:15 +0000862 case Action::CCC_Expression:
863 case Action::CCC_Statement:
864 case Action::CCC_ForInit:
865 case Action::CCC_Condition:
866 break;
867 }
868}
869
Douglas Gregorf98e6a22010-01-13 23:51:12 +0000870static void AddObjCExpressionResults(ResultBuilder &Results, bool NeedAt);
871static void AddObjCStatementResults(ResultBuilder &Results, bool NeedAt);
872static void AddObjCVisibilityResults(const LangOptions &LangOpts,
Douglas Gregor48d46252010-01-13 21:54:15 +0000873 ResultBuilder &Results,
874 bool NeedAt);
Douglas Gregorf98e6a22010-01-13 23:51:12 +0000875static void AddObjCImplementationResults(const LangOptions &LangOpts,
Douglas Gregorf1934162010-01-13 21:24:21 +0000876 ResultBuilder &Results,
877 bool NeedAt);
Douglas Gregorf98e6a22010-01-13 23:51:12 +0000878static void AddObjCInterfaceResults(const LangOptions &LangOpts,
Douglas Gregorf1934162010-01-13 21:24:21 +0000879 ResultBuilder &Results,
880 bool NeedAt);
Douglas Gregorf98e6a22010-01-13 23:51:12 +0000881static void AddObjCTopLevelResults(ResultBuilder &Results, bool NeedAt);
Douglas Gregorf1934162010-01-13 21:24:21 +0000882
Douglas Gregor504a6ae2010-01-10 23:08:15 +0000883/// \brief Add language constructs that show up for "ordinary" names.
884static void AddOrdinaryNameResults(Action::CodeCompletionContext CCC,
885 Scope *S,
886 Sema &SemaRef,
Douglas Gregor504a6ae2010-01-10 23:08:15 +0000887 ResultBuilder &Results) {
888 typedef CodeCompleteConsumer::Result Result;
889 switch (CCC) {
890 case Action::CCC_Namespace:
891 if (SemaRef.getLangOptions().CPlusPlus) {
892 // namespace <identifier> { }
893 CodeCompletionString *Pattern = new CodeCompletionString;
894 Pattern->AddTypedTextChunk("namespace");
895 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
896 Pattern->AddPlaceholderChunk("identifier");
897 Pattern->AddChunk(CodeCompletionString::CK_LeftBrace);
898 Pattern->AddPlaceholderChunk("declarations");
899 Pattern->AddChunk(CodeCompletionString::CK_VerticalSpace);
900 Pattern->AddChunk(CodeCompletionString::CK_RightBrace);
Douglas Gregorf98e6a22010-01-13 23:51:12 +0000901 Results.MaybeAddResult(Result(Pattern));
Douglas Gregor504a6ae2010-01-10 23:08:15 +0000902
903 // namespace identifier = identifier ;
904 Pattern = new CodeCompletionString;
905 Pattern->AddTypedTextChunk("namespace");
906 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
907 Pattern->AddPlaceholderChunk("identifier");
908 Pattern->AddChunk(CodeCompletionString::CK_Equal);
909 Pattern->AddPlaceholderChunk("identifier");
910 Pattern->AddChunk(CodeCompletionString::CK_SemiColon);
Douglas Gregorf98e6a22010-01-13 23:51:12 +0000911 Results.MaybeAddResult(Result(Pattern));
Douglas Gregor504a6ae2010-01-10 23:08:15 +0000912
913 // Using directives
914 Pattern = new CodeCompletionString;
915 Pattern->AddTypedTextChunk("using");
916 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
917 Pattern->AddTextChunk("namespace");
918 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
919 Pattern->AddPlaceholderChunk("identifier");
920 Pattern->AddChunk(CodeCompletionString::CK_SemiColon);
Douglas Gregorf98e6a22010-01-13 23:51:12 +0000921 Results.MaybeAddResult(Result(Pattern));
Douglas Gregor504a6ae2010-01-10 23:08:15 +0000922
923 // asm(string-literal)
924 Pattern = new CodeCompletionString;
925 Pattern->AddTypedTextChunk("asm");
926 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
927 Pattern->AddPlaceholderChunk("string-literal");
928 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
929 Pattern->AddChunk(CodeCompletionString::CK_SemiColon);
Douglas Gregorf98e6a22010-01-13 23:51:12 +0000930 Results.MaybeAddResult(Result(Pattern));
Douglas Gregor504a6ae2010-01-10 23:08:15 +0000931
932 // Explicit template instantiation
933 Pattern = new CodeCompletionString;
934 Pattern->AddTypedTextChunk("template");
935 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
936 Pattern->AddPlaceholderChunk("declaration");
937 Pattern->AddChunk(CodeCompletionString::CK_SemiColon);
Douglas Gregorf98e6a22010-01-13 23:51:12 +0000938 Results.MaybeAddResult(Result(Pattern));
Douglas Gregor504a6ae2010-01-10 23:08:15 +0000939 }
Douglas Gregorf1934162010-01-13 21:24:21 +0000940
941 if (SemaRef.getLangOptions().ObjC1)
Douglas Gregorf98e6a22010-01-13 23:51:12 +0000942 AddObjCTopLevelResults(Results, true);
Douglas Gregorf1934162010-01-13 21:24:21 +0000943
Douglas Gregor504a6ae2010-01-10 23:08:15 +0000944 // Fall through
945
946 case Action::CCC_Class:
Douglas Gregorf98e6a22010-01-13 23:51:12 +0000947 Results.MaybeAddResult(Result("typedef"));
Douglas Gregor504a6ae2010-01-10 23:08:15 +0000948 if (SemaRef.getLangOptions().CPlusPlus) {
949 // Using declaration
950 CodeCompletionString *Pattern = new CodeCompletionString;
951 Pattern->AddTypedTextChunk("using");
952 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
953 Pattern->AddPlaceholderChunk("qualified-id");
954 Pattern->AddChunk(CodeCompletionString::CK_SemiColon);
Douglas Gregorf98e6a22010-01-13 23:51:12 +0000955 Results.MaybeAddResult(Result(Pattern));
Douglas Gregor504a6ae2010-01-10 23:08:15 +0000956
957 // using typename qualified-id; (only in a dependent context)
958 if (SemaRef.CurContext->isDependentContext()) {
959 Pattern = new CodeCompletionString;
960 Pattern->AddTypedTextChunk("using");
961 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
962 Pattern->AddTextChunk("typename");
963 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
964 Pattern->AddPlaceholderChunk("qualified-id");
965 Pattern->AddChunk(CodeCompletionString::CK_SemiColon);
Douglas Gregorf98e6a22010-01-13 23:51:12 +0000966 Results.MaybeAddResult(Result(Pattern));
Douglas Gregor504a6ae2010-01-10 23:08:15 +0000967 }
968
969 if (CCC == Action::CCC_Class) {
970 // public:
971 Pattern = new CodeCompletionString;
972 Pattern->AddTypedTextChunk("public");
973 Pattern->AddChunk(CodeCompletionString::CK_Colon);
Douglas Gregorf98e6a22010-01-13 23:51:12 +0000974 Results.MaybeAddResult(Result(Pattern));
Douglas Gregor504a6ae2010-01-10 23:08:15 +0000975
976 // protected:
977 Pattern = new CodeCompletionString;
978 Pattern->AddTypedTextChunk("protected");
979 Pattern->AddChunk(CodeCompletionString::CK_Colon);
Douglas Gregorf98e6a22010-01-13 23:51:12 +0000980 Results.MaybeAddResult(Result(Pattern));
Douglas Gregor504a6ae2010-01-10 23:08:15 +0000981
982 // private:
983 Pattern = new CodeCompletionString;
984 Pattern->AddTypedTextChunk("private");
985 Pattern->AddChunk(CodeCompletionString::CK_Colon);
Douglas Gregorf98e6a22010-01-13 23:51:12 +0000986 Results.MaybeAddResult(Result(Pattern));
Douglas Gregor504a6ae2010-01-10 23:08:15 +0000987 }
988 }
989 // Fall through
990
991 case Action::CCC_Template:
992 case Action::CCC_MemberTemplate:
993 if (SemaRef.getLangOptions().CPlusPlus) {
994 // template < parameters >
995 CodeCompletionString *Pattern = new CodeCompletionString;
996 Pattern->AddTypedTextChunk("template");
997 Pattern->AddChunk(CodeCompletionString::CK_LeftAngle);
998 Pattern->AddPlaceholderChunk("parameters");
999 Pattern->AddChunk(CodeCompletionString::CK_RightAngle);
Douglas Gregorf98e6a22010-01-13 23:51:12 +00001000 Results.MaybeAddResult(Result(Pattern));
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001001 }
1002
Douglas Gregorf98e6a22010-01-13 23:51:12 +00001003 AddStorageSpecifiers(CCC, SemaRef.getLangOptions(), Results);
1004 AddFunctionSpecifiers(CCC, SemaRef.getLangOptions(), Results);
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001005 break;
1006
Douglas Gregorf1934162010-01-13 21:24:21 +00001007 case Action::CCC_ObjCInterface:
Douglas Gregorf98e6a22010-01-13 23:51:12 +00001008 AddObjCInterfaceResults(SemaRef.getLangOptions(), Results, true);
1009 AddStorageSpecifiers(CCC, SemaRef.getLangOptions(), Results);
1010 AddFunctionSpecifiers(CCC, SemaRef.getLangOptions(), Results);
Douglas Gregorf1934162010-01-13 21:24:21 +00001011 break;
1012
1013 case Action::CCC_ObjCImplementation:
Douglas Gregorf98e6a22010-01-13 23:51:12 +00001014 AddObjCImplementationResults(SemaRef.getLangOptions(), Results, true);
1015 AddStorageSpecifiers(CCC, SemaRef.getLangOptions(), Results);
1016 AddFunctionSpecifiers(CCC, SemaRef.getLangOptions(), Results);
Douglas Gregorf1934162010-01-13 21:24:21 +00001017 break;
1018
Douglas Gregor48d46252010-01-13 21:54:15 +00001019 case Action::CCC_ObjCInstanceVariableList:
Douglas Gregorf98e6a22010-01-13 23:51:12 +00001020 AddObjCVisibilityResults(SemaRef.getLangOptions(), Results, true);
Douglas Gregor48d46252010-01-13 21:54:15 +00001021 break;
1022
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001023 case Action::CCC_Statement: {
Douglas Gregorf98e6a22010-01-13 23:51:12 +00001024 Results.MaybeAddResult(Result("typedef"));
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001025
1026 CodeCompletionString *Pattern = 0;
1027 if (SemaRef.getLangOptions().CPlusPlus) {
1028 Pattern = new CodeCompletionString;
1029 Pattern->AddTypedTextChunk("try");
1030 Pattern->AddChunk(CodeCompletionString::CK_LeftBrace);
1031 Pattern->AddPlaceholderChunk("statements");
1032 Pattern->AddChunk(CodeCompletionString::CK_VerticalSpace);
1033 Pattern->AddChunk(CodeCompletionString::CK_RightBrace);
1034 Pattern->AddTextChunk("catch");
1035 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
1036 Pattern->AddPlaceholderChunk("declaration");
1037 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
1038 Pattern->AddChunk(CodeCompletionString::CK_LeftBrace);
1039 Pattern->AddPlaceholderChunk("statements");
1040 Pattern->AddChunk(CodeCompletionString::CK_VerticalSpace);
1041 Pattern->AddChunk(CodeCompletionString::CK_RightBrace);
Douglas Gregorf98e6a22010-01-13 23:51:12 +00001042 Results.MaybeAddResult(Result(Pattern));
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001043 }
Douglas Gregorf1934162010-01-13 21:24:21 +00001044 if (SemaRef.getLangOptions().ObjC1)
Douglas Gregorf98e6a22010-01-13 23:51:12 +00001045 AddObjCStatementResults(Results, true);
Douglas Gregorf1934162010-01-13 21:24:21 +00001046
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001047 // if (condition) { statements }
1048 Pattern = new CodeCompletionString;
1049 Pattern->AddTypedTextChunk("if");
1050 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
1051 if (SemaRef.getLangOptions().CPlusPlus)
1052 Pattern->AddPlaceholderChunk("condition");
1053 else
1054 Pattern->AddPlaceholderChunk("expression");
1055 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
1056 Pattern->AddChunk(CodeCompletionString::CK_LeftBrace);
1057 Pattern->AddPlaceholderChunk("statements");
1058 Pattern->AddChunk(CodeCompletionString::CK_VerticalSpace);
1059 Pattern->AddChunk(CodeCompletionString::CK_RightBrace);
Douglas Gregorf98e6a22010-01-13 23:51:12 +00001060 Results.MaybeAddResult(Result(Pattern));
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001061
1062 // switch (condition) { }
1063 Pattern = new CodeCompletionString;
1064 Pattern->AddTypedTextChunk("switch");
1065 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
1066 if (SemaRef.getLangOptions().CPlusPlus)
1067 Pattern->AddPlaceholderChunk("condition");
1068 else
1069 Pattern->AddPlaceholderChunk("expression");
1070 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
1071 Pattern->AddChunk(CodeCompletionString::CK_LeftBrace);
1072 Pattern->AddChunk(CodeCompletionString::CK_VerticalSpace);
1073 Pattern->AddChunk(CodeCompletionString::CK_RightBrace);
Douglas Gregorf98e6a22010-01-13 23:51:12 +00001074 Results.MaybeAddResult(Result(Pattern));
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001075
1076 // Switch-specific statements.
1077 if (!SemaRef.getSwitchStack().empty()) {
1078 // case expression:
1079 Pattern = new CodeCompletionString;
1080 Pattern->AddTypedTextChunk("case");
1081 Pattern->AddPlaceholderChunk("expression");
1082 Pattern->AddChunk(CodeCompletionString::CK_Colon);
Douglas Gregorf98e6a22010-01-13 23:51:12 +00001083 Results.MaybeAddResult(Result(Pattern));
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001084
1085 // default:
1086 Pattern = new CodeCompletionString;
1087 Pattern->AddTypedTextChunk("default");
1088 Pattern->AddChunk(CodeCompletionString::CK_Colon);
Douglas Gregorf98e6a22010-01-13 23:51:12 +00001089 Results.MaybeAddResult(Result(Pattern));
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001090 }
1091
1092 /// while (condition) { statements }
1093 Pattern = new CodeCompletionString;
1094 Pattern->AddTypedTextChunk("while");
1095 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
1096 if (SemaRef.getLangOptions().CPlusPlus)
1097 Pattern->AddPlaceholderChunk("condition");
1098 else
1099 Pattern->AddPlaceholderChunk("expression");
1100 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
1101 Pattern->AddChunk(CodeCompletionString::CK_LeftBrace);
1102 Pattern->AddPlaceholderChunk("statements");
1103 Pattern->AddChunk(CodeCompletionString::CK_VerticalSpace);
1104 Pattern->AddChunk(CodeCompletionString::CK_RightBrace);
Douglas Gregorf98e6a22010-01-13 23:51:12 +00001105 Results.MaybeAddResult(Result(Pattern));
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001106
1107 // do { statements } while ( expression );
1108 Pattern = new CodeCompletionString;
1109 Pattern->AddTypedTextChunk("do");
1110 Pattern->AddChunk(CodeCompletionString::CK_LeftBrace);
1111 Pattern->AddPlaceholderChunk("statements");
1112 Pattern->AddChunk(CodeCompletionString::CK_VerticalSpace);
1113 Pattern->AddChunk(CodeCompletionString::CK_RightBrace);
1114 Pattern->AddTextChunk("while");
1115 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
1116 Pattern->AddPlaceholderChunk("expression");
1117 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
1118 Pattern->AddChunk(CodeCompletionString::CK_SemiColon);
Douglas Gregorf98e6a22010-01-13 23:51:12 +00001119 Results.MaybeAddResult(Result(Pattern));
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001120
1121 // for ( for-init-statement ; condition ; expression ) { statements }
1122 Pattern = new CodeCompletionString;
1123 Pattern->AddTypedTextChunk("for");
1124 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
1125 if (SemaRef.getLangOptions().CPlusPlus || SemaRef.getLangOptions().C99)
1126 Pattern->AddPlaceholderChunk("init-statement");
1127 else
1128 Pattern->AddPlaceholderChunk("init-expression");
1129 Pattern->AddChunk(CodeCompletionString::CK_SemiColon);
1130 Pattern->AddPlaceholderChunk("condition");
1131 Pattern->AddChunk(CodeCompletionString::CK_SemiColon);
1132 Pattern->AddPlaceholderChunk("inc-expression");
1133 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
1134 Pattern->AddChunk(CodeCompletionString::CK_LeftBrace);
1135 Pattern->AddPlaceholderChunk("statements");
1136 Pattern->AddChunk(CodeCompletionString::CK_VerticalSpace);
1137 Pattern->AddChunk(CodeCompletionString::CK_RightBrace);
Douglas Gregorf98e6a22010-01-13 23:51:12 +00001138 Results.MaybeAddResult(Result(Pattern));
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001139
1140 if (S->getContinueParent()) {
1141 // continue ;
1142 Pattern = new CodeCompletionString;
1143 Pattern->AddTypedTextChunk("continue");
1144 Pattern->AddChunk(CodeCompletionString::CK_SemiColon);
Douglas Gregorf98e6a22010-01-13 23:51:12 +00001145 Results.MaybeAddResult(Result(Pattern));
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001146 }
1147
1148 if (S->getBreakParent()) {
1149 // break ;
1150 Pattern = new CodeCompletionString;
1151 Pattern->AddTypedTextChunk("break");
1152 Pattern->AddChunk(CodeCompletionString::CK_SemiColon);
Douglas Gregorf98e6a22010-01-13 23:51:12 +00001153 Results.MaybeAddResult(Result(Pattern));
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001154 }
1155
1156 // "return expression ;" or "return ;", depending on whether we
1157 // know the function is void or not.
1158 bool isVoid = false;
1159 if (FunctionDecl *Function = dyn_cast<FunctionDecl>(SemaRef.CurContext))
1160 isVoid = Function->getResultType()->isVoidType();
1161 else if (ObjCMethodDecl *Method
1162 = dyn_cast<ObjCMethodDecl>(SemaRef.CurContext))
1163 isVoid = Method->getResultType()->isVoidType();
1164 else if (SemaRef.CurBlock && !SemaRef.CurBlock->ReturnType.isNull())
1165 isVoid = SemaRef.CurBlock->ReturnType->isVoidType();
1166 Pattern = new CodeCompletionString;
1167 Pattern->AddTypedTextChunk("return");
1168 if (!isVoid)
1169 Pattern->AddPlaceholderChunk("expression");
1170 Pattern->AddChunk(CodeCompletionString::CK_SemiColon);
Douglas Gregorf98e6a22010-01-13 23:51:12 +00001171 Results.MaybeAddResult(Result(Pattern));
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001172
1173 // goto identifier ;
1174 Pattern = new CodeCompletionString;
1175 Pattern->AddTypedTextChunk("goto");
1176 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
1177 Pattern->AddPlaceholderChunk("identifier");
1178 Pattern->AddChunk(CodeCompletionString::CK_SemiColon);
Douglas Gregorf98e6a22010-01-13 23:51:12 +00001179 Results.MaybeAddResult(Result(Pattern));
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001180
1181 // Using directives
1182 Pattern = new CodeCompletionString;
1183 Pattern->AddTypedTextChunk("using");
1184 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
1185 Pattern->AddTextChunk("namespace");
1186 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
1187 Pattern->AddPlaceholderChunk("identifier");
1188 Pattern->AddChunk(CodeCompletionString::CK_SemiColon);
Douglas Gregorf98e6a22010-01-13 23:51:12 +00001189 Results.MaybeAddResult(Result(Pattern));
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001190 }
1191
1192 // Fall through (for statement expressions).
1193 case Action::CCC_ForInit:
1194 case Action::CCC_Condition:
Douglas Gregorf98e6a22010-01-13 23:51:12 +00001195 AddStorageSpecifiers(CCC, SemaRef.getLangOptions(), Results);
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001196 // Fall through: conditions and statements can have expressions.
1197
1198 case Action::CCC_Expression: {
1199 CodeCompletionString *Pattern = 0;
1200 if (SemaRef.getLangOptions().CPlusPlus) {
1201 // 'this', if we're in a non-static member function.
1202 if (CXXMethodDecl *Method = dyn_cast<CXXMethodDecl>(SemaRef.CurContext))
1203 if (!Method->isStatic())
Douglas Gregorf98e6a22010-01-13 23:51:12 +00001204 Results.MaybeAddResult(Result("this"));
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001205
1206 // true, false
Douglas Gregorf98e6a22010-01-13 23:51:12 +00001207 Results.MaybeAddResult(Result("true"));
1208 Results.MaybeAddResult(Result("false"));
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001209
1210 // dynamic_cast < type-id > ( expression )
1211 Pattern = new CodeCompletionString;
1212 Pattern->AddTypedTextChunk("dynamic_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 Gregorf98e6a22010-01-13 23:51:12 +00001219 Results.MaybeAddResult(Result(Pattern));
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001220
1221 // static_cast < type-id > ( expression )
1222 Pattern = new CodeCompletionString;
1223 Pattern->AddTypedTextChunk("static_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 Gregorf98e6a22010-01-13 23:51:12 +00001230 Results.MaybeAddResult(Result(Pattern));
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001231
1232 // reinterpret_cast < type-id > ( expression )
1233 Pattern = new CodeCompletionString;
1234 Pattern->AddTypedTextChunk("reinterpret_cast");
1235 Pattern->AddChunk(CodeCompletionString::CK_LeftAngle);
1236 Pattern->AddPlaceholderChunk("type-id");
1237 Pattern->AddChunk(CodeCompletionString::CK_RightAngle);
1238 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
1239 Pattern->AddPlaceholderChunk("expression");
1240 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
Douglas Gregorf98e6a22010-01-13 23:51:12 +00001241 Results.MaybeAddResult(Result(Pattern));
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001242
1243 // const_cast < type-id > ( expression )
1244 Pattern = new CodeCompletionString;
1245 Pattern->AddTypedTextChunk("const_cast");
1246 Pattern->AddChunk(CodeCompletionString::CK_LeftAngle);
1247 Pattern->AddPlaceholderChunk("type-id");
1248 Pattern->AddChunk(CodeCompletionString::CK_RightAngle);
1249 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
1250 Pattern->AddPlaceholderChunk("expression");
1251 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
Douglas Gregorf98e6a22010-01-13 23:51:12 +00001252 Results.MaybeAddResult(Result(Pattern));
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001253
1254 // typeid ( expression-or-type )
1255 Pattern = new CodeCompletionString;
1256 Pattern->AddTypedTextChunk("typeid");
1257 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
1258 Pattern->AddPlaceholderChunk("expression-or-type");
1259 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
Douglas Gregorf98e6a22010-01-13 23:51:12 +00001260 Results.MaybeAddResult(Result(Pattern));
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001261
1262 // new T ( ... )
1263 Pattern = new CodeCompletionString;
1264 Pattern->AddTypedTextChunk("new");
1265 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
1266 Pattern->AddPlaceholderChunk("type-id");
1267 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
1268 Pattern->AddPlaceholderChunk("expressions");
1269 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
Douglas Gregorf98e6a22010-01-13 23:51:12 +00001270 Results.MaybeAddResult(Result(Pattern));
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001271
1272 // new T [ ] ( ... )
1273 Pattern = new CodeCompletionString;
1274 Pattern->AddTypedTextChunk("new");
1275 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
1276 Pattern->AddPlaceholderChunk("type-id");
1277 Pattern->AddChunk(CodeCompletionString::CK_LeftBracket);
1278 Pattern->AddPlaceholderChunk("size");
1279 Pattern->AddChunk(CodeCompletionString::CK_RightBracket);
1280 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
1281 Pattern->AddPlaceholderChunk("expressions");
1282 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
Douglas Gregorf98e6a22010-01-13 23:51:12 +00001283 Results.MaybeAddResult(Result(Pattern));
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001284
1285 // delete expression
1286 Pattern = new CodeCompletionString;
1287 Pattern->AddTypedTextChunk("delete");
1288 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
1289 Pattern->AddPlaceholderChunk("expression");
Douglas Gregorf98e6a22010-01-13 23:51:12 +00001290 Results.MaybeAddResult(Result(Pattern));
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001291
1292 // delete [] expression
1293 Pattern = new CodeCompletionString;
1294 Pattern->AddTypedTextChunk("delete");
1295 Pattern->AddChunk(CodeCompletionString::CK_LeftBracket);
1296 Pattern->AddChunk(CodeCompletionString::CK_RightBracket);
1297 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
1298 Pattern->AddPlaceholderChunk("expression");
Douglas Gregorf98e6a22010-01-13 23:51:12 +00001299 Results.MaybeAddResult(Result(Pattern));
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001300
1301 // throw expression
1302 Pattern = new CodeCompletionString;
1303 Pattern->AddTypedTextChunk("throw");
1304 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
1305 Pattern->AddPlaceholderChunk("expression");
Douglas Gregorf98e6a22010-01-13 23:51:12 +00001306 Results.MaybeAddResult(Result(Pattern));
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001307 }
1308
1309 if (SemaRef.getLangOptions().ObjC1) {
1310 // Add "super", if we're in an Objective-C class with a superclass.
1311 if (ObjCMethodDecl *Method = SemaRef.getCurMethodDecl())
1312 if (Method->getClassInterface()->getSuperClass())
Douglas Gregorf98e6a22010-01-13 23:51:12 +00001313 Results.MaybeAddResult(Result("super"));
Douglas Gregorf1934162010-01-13 21:24:21 +00001314
Douglas Gregorf98e6a22010-01-13 23:51:12 +00001315 AddObjCExpressionResults(Results, true);
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001316 }
1317
1318 // sizeof expression
1319 Pattern = new CodeCompletionString;
1320 Pattern->AddTypedTextChunk("sizeof");
1321 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
1322 Pattern->AddPlaceholderChunk("expression-or-type");
1323 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
Douglas Gregorf98e6a22010-01-13 23:51:12 +00001324 Results.MaybeAddResult(Result(Pattern));
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001325 break;
1326 }
1327 }
1328
Douglas Gregorf98e6a22010-01-13 23:51:12 +00001329 AddTypeSpecifierResults(SemaRef.getLangOptions(), Results);
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001330
1331 if (SemaRef.getLangOptions().CPlusPlus)
Douglas Gregorf98e6a22010-01-13 23:51:12 +00001332 Results.MaybeAddResult(Result("operator"));
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001333}
1334
Douglas Gregorb3fa9192009-12-18 18:53:37 +00001335/// \brief If the given declaration has an associated type, add it as a result
1336/// type chunk.
1337static void AddResultTypeChunk(ASTContext &Context,
1338 NamedDecl *ND,
1339 CodeCompletionString *Result) {
1340 if (!ND)
1341 return;
1342
1343 // Determine the type of the declaration (if it has a type).
1344 QualType T;
1345 if (FunctionDecl *Function = dyn_cast<FunctionDecl>(ND))
1346 T = Function->getResultType();
1347 else if (ObjCMethodDecl *Method = dyn_cast<ObjCMethodDecl>(ND))
1348 T = Method->getResultType();
1349 else if (FunctionTemplateDecl *FunTmpl = dyn_cast<FunctionTemplateDecl>(ND))
1350 T = FunTmpl->getTemplatedDecl()->getResultType();
1351 else if (EnumConstantDecl *Enumerator = dyn_cast<EnumConstantDecl>(ND))
1352 T = Context.getTypeDeclType(cast<TypeDecl>(Enumerator->getDeclContext()));
1353 else if (isa<UnresolvedUsingValueDecl>(ND)) {
1354 /* Do nothing: ignore unresolved using declarations*/
1355 } else if (ValueDecl *Value = dyn_cast<ValueDecl>(ND))
1356 T = Value->getType();
1357 else if (ObjCPropertyDecl *Property = dyn_cast<ObjCPropertyDecl>(ND))
1358 T = Property->getType();
1359
1360 if (T.isNull() || Context.hasSameType(T, Context.DependentTy))
1361 return;
1362
1363 std::string TypeStr;
1364 T.getAsStringInternal(TypeStr, Context.PrintingPolicy);
1365 Result->AddResultTypeChunk(TypeStr);
1366}
1367
Douglas Gregor3545ff42009-09-21 16:56:56 +00001368/// \brief Add function parameter chunks to the given code completion string.
1369static void AddFunctionParameterChunks(ASTContext &Context,
1370 FunctionDecl *Function,
1371 CodeCompletionString *Result) {
Douglas Gregor9eb77012009-11-07 00:00:49 +00001372 typedef CodeCompletionString::Chunk Chunk;
1373
Douglas Gregor3545ff42009-09-21 16:56:56 +00001374 CodeCompletionString *CCStr = Result;
1375
1376 for (unsigned P = 0, N = Function->getNumParams(); P != N; ++P) {
1377 ParmVarDecl *Param = Function->getParamDecl(P);
1378
1379 if (Param->hasDefaultArg()) {
1380 // When we see an optional default argument, put that argument and
1381 // the remaining default arguments into a new, optional string.
1382 CodeCompletionString *Opt = new CodeCompletionString;
1383 CCStr->AddOptionalChunk(std::auto_ptr<CodeCompletionString>(Opt));
1384 CCStr = Opt;
1385 }
1386
1387 if (P != 0)
Douglas Gregor9eb77012009-11-07 00:00:49 +00001388 CCStr->AddChunk(Chunk(CodeCompletionString::CK_Comma));
Douglas Gregor3545ff42009-09-21 16:56:56 +00001389
1390 // Format the placeholder string.
1391 std::string PlaceholderStr;
1392 if (Param->getIdentifier())
1393 PlaceholderStr = Param->getIdentifier()->getName();
1394
1395 Param->getType().getAsStringInternal(PlaceholderStr,
1396 Context.PrintingPolicy);
1397
1398 // Add the placeholder string.
Benjamin Kramerb33a97c2009-11-29 20:18:50 +00001399 CCStr->AddPlaceholderChunk(PlaceholderStr);
Douglas Gregor3545ff42009-09-21 16:56:56 +00001400 }
Douglas Gregorba449032009-09-22 21:42:17 +00001401
1402 if (const FunctionProtoType *Proto
1403 = Function->getType()->getAs<FunctionProtoType>())
1404 if (Proto->isVariadic())
1405 CCStr->AddPlaceholderChunk(", ...");
Douglas Gregor3545ff42009-09-21 16:56:56 +00001406}
1407
1408/// \brief Add template parameter chunks to the given code completion string.
1409static void AddTemplateParameterChunks(ASTContext &Context,
1410 TemplateDecl *Template,
1411 CodeCompletionString *Result,
1412 unsigned MaxParameters = 0) {
Douglas Gregor9eb77012009-11-07 00:00:49 +00001413 typedef CodeCompletionString::Chunk Chunk;
1414
Douglas Gregor3545ff42009-09-21 16:56:56 +00001415 CodeCompletionString *CCStr = Result;
1416 bool FirstParameter = true;
1417
1418 TemplateParameterList *Params = Template->getTemplateParameters();
1419 TemplateParameterList::iterator PEnd = Params->end();
1420 if (MaxParameters)
1421 PEnd = Params->begin() + MaxParameters;
1422 for (TemplateParameterList::iterator P = Params->begin(); P != PEnd; ++P) {
1423 bool HasDefaultArg = false;
1424 std::string PlaceholderStr;
1425 if (TemplateTypeParmDecl *TTP = dyn_cast<TemplateTypeParmDecl>(*P)) {
1426 if (TTP->wasDeclaredWithTypename())
1427 PlaceholderStr = "typename";
1428 else
1429 PlaceholderStr = "class";
1430
1431 if (TTP->getIdentifier()) {
1432 PlaceholderStr += ' ';
1433 PlaceholderStr += TTP->getIdentifier()->getName();
1434 }
1435
1436 HasDefaultArg = TTP->hasDefaultArgument();
1437 } else if (NonTypeTemplateParmDecl *NTTP
1438 = dyn_cast<NonTypeTemplateParmDecl>(*P)) {
1439 if (NTTP->getIdentifier())
1440 PlaceholderStr = NTTP->getIdentifier()->getName();
1441 NTTP->getType().getAsStringInternal(PlaceholderStr,
1442 Context.PrintingPolicy);
1443 HasDefaultArg = NTTP->hasDefaultArgument();
1444 } else {
1445 assert(isa<TemplateTemplateParmDecl>(*P));
1446 TemplateTemplateParmDecl *TTP = cast<TemplateTemplateParmDecl>(*P);
1447
1448 // Since putting the template argument list into the placeholder would
1449 // be very, very long, we just use an abbreviation.
1450 PlaceholderStr = "template<...> class";
1451 if (TTP->getIdentifier()) {
1452 PlaceholderStr += ' ';
1453 PlaceholderStr += TTP->getIdentifier()->getName();
1454 }
1455
1456 HasDefaultArg = TTP->hasDefaultArgument();
1457 }
1458
1459 if (HasDefaultArg) {
1460 // When we see an optional default argument, put that argument and
1461 // the remaining default arguments into a new, optional string.
1462 CodeCompletionString *Opt = new CodeCompletionString;
1463 CCStr->AddOptionalChunk(std::auto_ptr<CodeCompletionString>(Opt));
1464 CCStr = Opt;
1465 }
1466
1467 if (FirstParameter)
1468 FirstParameter = false;
1469 else
Douglas Gregor9eb77012009-11-07 00:00:49 +00001470 CCStr->AddChunk(Chunk(CodeCompletionString::CK_Comma));
Douglas Gregor3545ff42009-09-21 16:56:56 +00001471
1472 // Add the placeholder string.
Benjamin Kramerb33a97c2009-11-29 20:18:50 +00001473 CCStr->AddPlaceholderChunk(PlaceholderStr);
Douglas Gregor3545ff42009-09-21 16:56:56 +00001474 }
1475}
1476
Douglas Gregorf2510672009-09-21 19:57:38 +00001477/// \brief Add a qualifier to the given code-completion string, if the
1478/// provided nested-name-specifier is non-NULL.
Douglas Gregor0f622362009-12-11 18:44:16 +00001479static void
1480AddQualifierToCompletionString(CodeCompletionString *Result,
1481 NestedNameSpecifier *Qualifier,
1482 bool QualifierIsInformative,
1483 ASTContext &Context) {
Douglas Gregorf2510672009-09-21 19:57:38 +00001484 if (!Qualifier)
1485 return;
1486
1487 std::string PrintedNNS;
1488 {
1489 llvm::raw_string_ostream OS(PrintedNNS);
1490 Qualifier->print(OS, Context.PrintingPolicy);
1491 }
Douglas Gregor5bf52692009-09-22 23:15:58 +00001492 if (QualifierIsInformative)
Benjamin Kramerb33a97c2009-11-29 20:18:50 +00001493 Result->AddInformativeChunk(PrintedNNS);
Douglas Gregor5bf52692009-09-22 23:15:58 +00001494 else
Benjamin Kramerb33a97c2009-11-29 20:18:50 +00001495 Result->AddTextChunk(PrintedNNS);
Douglas Gregorf2510672009-09-21 19:57:38 +00001496}
1497
Douglas Gregor0f622362009-12-11 18:44:16 +00001498static void AddFunctionTypeQualsToCompletionString(CodeCompletionString *Result,
1499 FunctionDecl *Function) {
1500 const FunctionProtoType *Proto
1501 = Function->getType()->getAs<FunctionProtoType>();
1502 if (!Proto || !Proto->getTypeQuals())
1503 return;
1504
1505 std::string QualsStr;
1506 if (Proto->getTypeQuals() & Qualifiers::Const)
1507 QualsStr += " const";
1508 if (Proto->getTypeQuals() & Qualifiers::Volatile)
1509 QualsStr += " volatile";
1510 if (Proto->getTypeQuals() & Qualifiers::Restrict)
1511 QualsStr += " restrict";
1512 Result->AddInformativeChunk(QualsStr);
1513}
1514
Douglas Gregor3545ff42009-09-21 16:56:56 +00001515/// \brief If possible, create a new code completion string for the given
1516/// result.
1517///
1518/// \returns Either a new, heap-allocated code completion string describing
1519/// how to use this result, or NULL to indicate that the string or name of the
1520/// result is all that is needed.
1521CodeCompletionString *
1522CodeCompleteConsumer::Result::CreateCodeCompletionString(Sema &S) {
Douglas Gregor9eb77012009-11-07 00:00:49 +00001523 typedef CodeCompletionString::Chunk Chunk;
1524
Douglas Gregorf09935f2009-12-01 05:55:20 +00001525 if (Kind == RK_Pattern)
1526 return Pattern->Clone();
1527
1528 CodeCompletionString *Result = new CodeCompletionString;
1529
1530 if (Kind == RK_Keyword) {
1531 Result->AddTypedTextChunk(Keyword);
1532 return Result;
1533 }
Douglas Gregor3545ff42009-09-21 16:56:56 +00001534
Douglas Gregorf329c7c2009-10-30 16:50:04 +00001535 if (Kind == RK_Macro) {
1536 MacroInfo *MI = S.PP.getMacroInfo(Macro);
Douglas Gregorf09935f2009-12-01 05:55:20 +00001537 assert(MI && "Not a macro?");
1538
1539 Result->AddTypedTextChunk(Macro->getName());
1540
1541 if (!MI->isFunctionLike())
1542 return Result;
Douglas Gregorf329c7c2009-10-30 16:50:04 +00001543
1544 // Format a function-like macro with placeholders for the arguments.
Douglas Gregor9eb77012009-11-07 00:00:49 +00001545 Result->AddChunk(Chunk(CodeCompletionString::CK_LeftParen));
Douglas Gregorf329c7c2009-10-30 16:50:04 +00001546 for (MacroInfo::arg_iterator A = MI->arg_begin(), AEnd = MI->arg_end();
1547 A != AEnd; ++A) {
1548 if (A != MI->arg_begin())
Douglas Gregor9eb77012009-11-07 00:00:49 +00001549 Result->AddChunk(Chunk(CodeCompletionString::CK_Comma));
Douglas Gregorf329c7c2009-10-30 16:50:04 +00001550
1551 if (!MI->isVariadic() || A != AEnd - 1) {
1552 // Non-variadic argument.
Benjamin Kramerb33a97c2009-11-29 20:18:50 +00001553 Result->AddPlaceholderChunk((*A)->getName());
Douglas Gregorf329c7c2009-10-30 16:50:04 +00001554 continue;
1555 }
1556
1557 // Variadic argument; cope with the different between GNU and C99
1558 // variadic macros, providing a single placeholder for the rest of the
1559 // arguments.
1560 if ((*A)->isStr("__VA_ARGS__"))
1561 Result->AddPlaceholderChunk("...");
1562 else {
1563 std::string Arg = (*A)->getName();
1564 Arg += "...";
Benjamin Kramerb33a97c2009-11-29 20:18:50 +00001565 Result->AddPlaceholderChunk(Arg);
Douglas Gregorf329c7c2009-10-30 16:50:04 +00001566 }
1567 }
Douglas Gregor9eb77012009-11-07 00:00:49 +00001568 Result->AddChunk(Chunk(CodeCompletionString::CK_RightParen));
Douglas Gregorf329c7c2009-10-30 16:50:04 +00001569 return Result;
1570 }
1571
1572 assert(Kind == RK_Declaration && "Missed a macro kind?");
Douglas Gregor3545ff42009-09-21 16:56:56 +00001573 NamedDecl *ND = Declaration;
1574
Douglas Gregor9eb77012009-11-07 00:00:49 +00001575 if (StartsNestedNameSpecifier) {
Benjamin Kramerb33a97c2009-11-29 20:18:50 +00001576 Result->AddTypedTextChunk(ND->getNameAsString());
Douglas Gregor9eb77012009-11-07 00:00:49 +00001577 Result->AddTextChunk("::");
1578 return Result;
1579 }
1580
Douglas Gregorb3fa9192009-12-18 18:53:37 +00001581 AddResultTypeChunk(S.Context, ND, Result);
1582
Douglas Gregor3545ff42009-09-21 16:56:56 +00001583 if (FunctionDecl *Function = dyn_cast<FunctionDecl>(ND)) {
Douglas Gregor5bf52692009-09-22 23:15:58 +00001584 AddQualifierToCompletionString(Result, Qualifier, QualifierIsInformative,
1585 S.Context);
Benjamin Kramerb33a97c2009-11-29 20:18:50 +00001586 Result->AddTypedTextChunk(Function->getNameAsString());
Douglas Gregor9eb77012009-11-07 00:00:49 +00001587 Result->AddChunk(Chunk(CodeCompletionString::CK_LeftParen));
Douglas Gregor3545ff42009-09-21 16:56:56 +00001588 AddFunctionParameterChunks(S.Context, Function, Result);
Douglas Gregor9eb77012009-11-07 00:00:49 +00001589 Result->AddChunk(Chunk(CodeCompletionString::CK_RightParen));
Douglas Gregor0f622362009-12-11 18:44:16 +00001590 AddFunctionTypeQualsToCompletionString(Result, Function);
Douglas Gregor3545ff42009-09-21 16:56:56 +00001591 return Result;
1592 }
1593
1594 if (FunctionTemplateDecl *FunTmpl = dyn_cast<FunctionTemplateDecl>(ND)) {
Douglas Gregor5bf52692009-09-22 23:15:58 +00001595 AddQualifierToCompletionString(Result, Qualifier, QualifierIsInformative,
1596 S.Context);
Douglas Gregor3545ff42009-09-21 16:56:56 +00001597 FunctionDecl *Function = FunTmpl->getTemplatedDecl();
Benjamin Kramerb33a97c2009-11-29 20:18:50 +00001598 Result->AddTypedTextChunk(Function->getNameAsString());
Douglas Gregor3545ff42009-09-21 16:56:56 +00001599
1600 // Figure out which template parameters are deduced (or have default
1601 // arguments).
1602 llvm::SmallVector<bool, 16> Deduced;
1603 S.MarkDeducedTemplateParameters(FunTmpl, Deduced);
1604 unsigned LastDeducibleArgument;
1605 for (LastDeducibleArgument = Deduced.size(); LastDeducibleArgument > 0;
1606 --LastDeducibleArgument) {
1607 if (!Deduced[LastDeducibleArgument - 1]) {
1608 // C++0x: Figure out if the template argument has a default. If so,
1609 // the user doesn't need to type this argument.
1610 // FIXME: We need to abstract template parameters better!
1611 bool HasDefaultArg = false;
1612 NamedDecl *Param = FunTmpl->getTemplateParameters()->getParam(
1613 LastDeducibleArgument - 1);
1614 if (TemplateTypeParmDecl *TTP = dyn_cast<TemplateTypeParmDecl>(Param))
1615 HasDefaultArg = TTP->hasDefaultArgument();
1616 else if (NonTypeTemplateParmDecl *NTTP
1617 = dyn_cast<NonTypeTemplateParmDecl>(Param))
1618 HasDefaultArg = NTTP->hasDefaultArgument();
1619 else {
1620 assert(isa<TemplateTemplateParmDecl>(Param));
1621 HasDefaultArg
Douglas Gregor9eb77012009-11-07 00:00:49 +00001622 = cast<TemplateTemplateParmDecl>(Param)->hasDefaultArgument();
Douglas Gregor3545ff42009-09-21 16:56:56 +00001623 }
1624
1625 if (!HasDefaultArg)
1626 break;
1627 }
1628 }
1629
1630 if (LastDeducibleArgument) {
1631 // Some of the function template arguments cannot be deduced from a
1632 // function call, so we introduce an explicit template argument list
1633 // containing all of the arguments up to the first deducible argument.
Douglas Gregor9eb77012009-11-07 00:00:49 +00001634 Result->AddChunk(Chunk(CodeCompletionString::CK_LeftAngle));
Douglas Gregor3545ff42009-09-21 16:56:56 +00001635 AddTemplateParameterChunks(S.Context, FunTmpl, Result,
1636 LastDeducibleArgument);
Douglas Gregor9eb77012009-11-07 00:00:49 +00001637 Result->AddChunk(Chunk(CodeCompletionString::CK_RightAngle));
Douglas Gregor3545ff42009-09-21 16:56:56 +00001638 }
1639
1640 // Add the function parameters
Douglas Gregor9eb77012009-11-07 00:00:49 +00001641 Result->AddChunk(Chunk(CodeCompletionString::CK_LeftParen));
Douglas Gregor3545ff42009-09-21 16:56:56 +00001642 AddFunctionParameterChunks(S.Context, Function, Result);
Douglas Gregor9eb77012009-11-07 00:00:49 +00001643 Result->AddChunk(Chunk(CodeCompletionString::CK_RightParen));
Douglas Gregor0f622362009-12-11 18:44:16 +00001644 AddFunctionTypeQualsToCompletionString(Result, Function);
Douglas Gregor3545ff42009-09-21 16:56:56 +00001645 return Result;
1646 }
1647
1648 if (TemplateDecl *Template = dyn_cast<TemplateDecl>(ND)) {
Douglas Gregor5bf52692009-09-22 23:15:58 +00001649 AddQualifierToCompletionString(Result, Qualifier, QualifierIsInformative,
1650 S.Context);
Benjamin Kramerb33a97c2009-11-29 20:18:50 +00001651 Result->AddTypedTextChunk(Template->getNameAsString());
Douglas Gregor9eb77012009-11-07 00:00:49 +00001652 Result->AddChunk(Chunk(CodeCompletionString::CK_LeftAngle));
Douglas Gregor3545ff42009-09-21 16:56:56 +00001653 AddTemplateParameterChunks(S.Context, Template, Result);
Douglas Gregor9eb77012009-11-07 00:00:49 +00001654 Result->AddChunk(Chunk(CodeCompletionString::CK_RightAngle));
Douglas Gregor3545ff42009-09-21 16:56:56 +00001655 return Result;
1656 }
1657
Douglas Gregord3c5d792009-11-17 16:44:22 +00001658 if (ObjCMethodDecl *Method = dyn_cast<ObjCMethodDecl>(ND)) {
Douglas Gregord3c5d792009-11-17 16:44:22 +00001659 Selector Sel = Method->getSelector();
1660 if (Sel.isUnarySelector()) {
1661 Result->AddTypedTextChunk(Sel.getIdentifierInfoForSlot(0)->getName());
1662 return Result;
1663 }
1664
Douglas Gregor1b605f72009-11-19 01:08:35 +00001665 std::string SelName = Sel.getIdentifierInfoForSlot(0)->getName().str();
1666 SelName += ':';
1667 if (StartParameter == 0)
1668 Result->AddTypedTextChunk(SelName);
1669 else {
1670 Result->AddInformativeChunk(SelName);
1671
1672 // If there is only one parameter, and we're past it, add an empty
1673 // typed-text chunk since there is nothing to type.
1674 if (Method->param_size() == 1)
1675 Result->AddTypedTextChunk("");
1676 }
Douglas Gregord3c5d792009-11-17 16:44:22 +00001677 unsigned Idx = 0;
1678 for (ObjCMethodDecl::param_iterator P = Method->param_begin(),
1679 PEnd = Method->param_end();
1680 P != PEnd; (void)++P, ++Idx) {
1681 if (Idx > 0) {
Douglas Gregor1b605f72009-11-19 01:08:35 +00001682 std::string Keyword;
1683 if (Idx > StartParameter)
Douglas Gregor6a803932010-01-12 06:38:28 +00001684 Result->AddChunk(CodeCompletionString::CK_HorizontalSpace);
Douglas Gregord3c5d792009-11-17 16:44:22 +00001685 if (IdentifierInfo *II = Sel.getIdentifierInfoForSlot(Idx))
1686 Keyword += II->getName().str();
1687 Keyword += ":";
Douglas Gregorc8537c52009-11-19 07:41:15 +00001688 if (Idx < StartParameter || AllParametersAreInformative) {
Douglas Gregor1b605f72009-11-19 01:08:35 +00001689 Result->AddInformativeChunk(Keyword);
1690 } else if (Idx == StartParameter)
1691 Result->AddTypedTextChunk(Keyword);
1692 else
1693 Result->AddTextChunk(Keyword);
Douglas Gregord3c5d792009-11-17 16:44:22 +00001694 }
Douglas Gregor1b605f72009-11-19 01:08:35 +00001695
1696 // If we're before the starting parameter, skip the placeholder.
1697 if (Idx < StartParameter)
1698 continue;
Douglas Gregord3c5d792009-11-17 16:44:22 +00001699
1700 std::string Arg;
1701 (*P)->getType().getAsStringInternal(Arg, S.Context.PrintingPolicy);
1702 Arg = "(" + Arg + ")";
1703 if (IdentifierInfo *II = (*P)->getIdentifier())
1704 Arg += II->getName().str();
Douglas Gregorc8537c52009-11-19 07:41:15 +00001705 if (AllParametersAreInformative)
1706 Result->AddInformativeChunk(Arg);
1707 else
1708 Result->AddPlaceholderChunk(Arg);
Douglas Gregord3c5d792009-11-17 16:44:22 +00001709 }
1710
Douglas Gregor04c5f972009-12-23 00:21:46 +00001711 if (Method->isVariadic()) {
1712 if (AllParametersAreInformative)
1713 Result->AddInformativeChunk(", ...");
1714 else
1715 Result->AddPlaceholderChunk(", ...");
1716 }
1717
Douglas Gregord3c5d792009-11-17 16:44:22 +00001718 return Result;
1719 }
1720
Douglas Gregorf09935f2009-12-01 05:55:20 +00001721 if (Qualifier)
Douglas Gregor5bf52692009-09-22 23:15:58 +00001722 AddQualifierToCompletionString(Result, Qualifier, QualifierIsInformative,
1723 S.Context);
Douglas Gregorf09935f2009-12-01 05:55:20 +00001724
1725 Result->AddTypedTextChunk(ND->getNameAsString());
1726 return Result;
Douglas Gregor3545ff42009-09-21 16:56:56 +00001727}
1728
Douglas Gregorf0f51982009-09-23 00:34:09 +00001729CodeCompletionString *
1730CodeCompleteConsumer::OverloadCandidate::CreateSignatureString(
1731 unsigned CurrentArg,
1732 Sema &S) const {
Douglas Gregor9eb77012009-11-07 00:00:49 +00001733 typedef CodeCompletionString::Chunk Chunk;
1734
Douglas Gregorf0f51982009-09-23 00:34:09 +00001735 CodeCompletionString *Result = new CodeCompletionString;
1736 FunctionDecl *FDecl = getFunction();
Douglas Gregorb3fa9192009-12-18 18:53:37 +00001737 AddResultTypeChunk(S.Context, FDecl, Result);
Douglas Gregorf0f51982009-09-23 00:34:09 +00001738 const FunctionProtoType *Proto
1739 = dyn_cast<FunctionProtoType>(getFunctionType());
1740 if (!FDecl && !Proto) {
1741 // Function without a prototype. Just give the return type and a
1742 // highlighted ellipsis.
1743 const FunctionType *FT = getFunctionType();
1744 Result->AddTextChunk(
Benjamin Kramerb33a97c2009-11-29 20:18:50 +00001745 FT->getResultType().getAsString(S.Context.PrintingPolicy));
Douglas Gregor9eb77012009-11-07 00:00:49 +00001746 Result->AddChunk(Chunk(CodeCompletionString::CK_LeftParen));
1747 Result->AddChunk(Chunk(CodeCompletionString::CK_CurrentParameter, "..."));
1748 Result->AddChunk(Chunk(CodeCompletionString::CK_RightParen));
Douglas Gregorf0f51982009-09-23 00:34:09 +00001749 return Result;
1750 }
1751
1752 if (FDecl)
Benjamin Kramerb33a97c2009-11-29 20:18:50 +00001753 Result->AddTextChunk(FDecl->getNameAsString());
Douglas Gregorf0f51982009-09-23 00:34:09 +00001754 else
1755 Result->AddTextChunk(
Benjamin Kramerb33a97c2009-11-29 20:18:50 +00001756 Proto->getResultType().getAsString(S.Context.PrintingPolicy));
Douglas Gregorf0f51982009-09-23 00:34:09 +00001757
Douglas Gregor9eb77012009-11-07 00:00:49 +00001758 Result->AddChunk(Chunk(CodeCompletionString::CK_LeftParen));
Douglas Gregorf0f51982009-09-23 00:34:09 +00001759 unsigned NumParams = FDecl? FDecl->getNumParams() : Proto->getNumArgs();
1760 for (unsigned I = 0; I != NumParams; ++I) {
1761 if (I)
Douglas Gregor9eb77012009-11-07 00:00:49 +00001762 Result->AddChunk(Chunk(CodeCompletionString::CK_Comma));
Douglas Gregorf0f51982009-09-23 00:34:09 +00001763
1764 std::string ArgString;
1765 QualType ArgType;
1766
1767 if (FDecl) {
1768 ArgString = FDecl->getParamDecl(I)->getNameAsString();
1769 ArgType = FDecl->getParamDecl(I)->getOriginalType();
1770 } else {
1771 ArgType = Proto->getArgType(I);
1772 }
1773
1774 ArgType.getAsStringInternal(ArgString, S.Context.PrintingPolicy);
1775
1776 if (I == CurrentArg)
Douglas Gregor9eb77012009-11-07 00:00:49 +00001777 Result->AddChunk(Chunk(CodeCompletionString::CK_CurrentParameter,
Benjamin Kramerb33a97c2009-11-29 20:18:50 +00001778 ArgString));
Douglas Gregorf0f51982009-09-23 00:34:09 +00001779 else
Benjamin Kramerb33a97c2009-11-29 20:18:50 +00001780 Result->AddTextChunk(ArgString);
Douglas Gregorf0f51982009-09-23 00:34:09 +00001781 }
1782
1783 if (Proto && Proto->isVariadic()) {
Douglas Gregor9eb77012009-11-07 00:00:49 +00001784 Result->AddChunk(Chunk(CodeCompletionString::CK_Comma));
Douglas Gregorf0f51982009-09-23 00:34:09 +00001785 if (CurrentArg < NumParams)
1786 Result->AddTextChunk("...");
1787 else
Douglas Gregor9eb77012009-11-07 00:00:49 +00001788 Result->AddChunk(Chunk(CodeCompletionString::CK_CurrentParameter, "..."));
Douglas Gregorf0f51982009-09-23 00:34:09 +00001789 }
Douglas Gregor9eb77012009-11-07 00:00:49 +00001790 Result->AddChunk(Chunk(CodeCompletionString::CK_RightParen));
Douglas Gregorf0f51982009-09-23 00:34:09 +00001791
1792 return Result;
1793}
1794
Douglas Gregor3545ff42009-09-21 16:56:56 +00001795namespace {
1796 struct SortCodeCompleteResult {
1797 typedef CodeCompleteConsumer::Result Result;
1798
Douglas Gregore6688e62009-09-28 03:51:44 +00001799 bool isEarlierDeclarationName(DeclarationName X, DeclarationName Y) const {
Douglas Gregor249d6822009-12-05 09:08:56 +00001800 Selector XSel = X.getObjCSelector();
1801 Selector YSel = Y.getObjCSelector();
1802 if (!XSel.isNull() && !YSel.isNull()) {
1803 // We are comparing two selectors.
1804 unsigned N = std::min(XSel.getNumArgs(), YSel.getNumArgs());
1805 if (N == 0)
1806 ++N;
1807 for (unsigned I = 0; I != N; ++I) {
1808 IdentifierInfo *XId = XSel.getIdentifierInfoForSlot(I);
1809 IdentifierInfo *YId = YSel.getIdentifierInfoForSlot(I);
1810 if (!XId || !YId)
1811 return XId && !YId;
1812
1813 switch (XId->getName().compare_lower(YId->getName())) {
1814 case -1: return true;
1815 case 1: return false;
1816 default: break;
1817 }
1818 }
1819
1820 return XSel.getNumArgs() < YSel.getNumArgs();
1821 }
1822
1823 // For non-selectors, order by kind.
1824 if (X.getNameKind() != Y.getNameKind())
Douglas Gregore6688e62009-09-28 03:51:44 +00001825 return X.getNameKind() < Y.getNameKind();
1826
Douglas Gregor249d6822009-12-05 09:08:56 +00001827 // Order identifiers by comparison of their lowercased names.
1828 if (IdentifierInfo *XId = X.getAsIdentifierInfo())
1829 return XId->getName().compare_lower(
1830 Y.getAsIdentifierInfo()->getName()) < 0;
1831
1832 // Order overloaded operators by the order in which they appear
1833 // in our list of operators.
1834 if (OverloadedOperatorKind XOp = X.getCXXOverloadedOperator())
1835 return XOp < Y.getCXXOverloadedOperator();
1836
1837 // Order C++0x user-defined literal operators lexically by their
1838 // lowercased suffixes.
1839 if (IdentifierInfo *XLit = X.getCXXLiteralIdentifier())
1840 return XLit->getName().compare_lower(
1841 Y.getCXXLiteralIdentifier()->getName()) < 0;
1842
1843 // The only stable ordering we have is to turn the name into a
1844 // string and then compare the lower-case strings. This is
1845 // inefficient, but thankfully does not happen too often.
Benjamin Kramer4053e5d2009-12-05 10:22:15 +00001846 return llvm::StringRef(X.getAsString()).compare_lower(
1847 Y.getAsString()) < 0;
Douglas Gregore6688e62009-09-28 03:51:44 +00001848 }
1849
Douglas Gregor52ce62f2010-01-13 23:24:38 +00001850 /// \brief Retrieve the name that should be used to order a result.
1851 ///
1852 /// If the name needs to be constructed as a string, that string will be
1853 /// saved into Saved and the returned StringRef will refer to it.
1854 static llvm::StringRef getOrderedName(const Result &R,
1855 std::string &Saved) {
1856 switch (R.Kind) {
1857 case Result::RK_Keyword:
1858 return R.Keyword;
1859
1860 case Result::RK_Pattern:
1861 return R.Pattern->getTypedText();
1862
1863 case Result::RK_Macro:
1864 return R.Macro->getName();
1865
1866 case Result::RK_Declaration:
1867 // Handle declarations below.
1868 break;
Douglas Gregor45f83ee2009-11-19 00:01:57 +00001869 }
Douglas Gregor52ce62f2010-01-13 23:24:38 +00001870
1871 DeclarationName Name = R.Declaration->getDeclName();
Douglas Gregor45f83ee2009-11-19 00:01:57 +00001872
Douglas Gregor52ce62f2010-01-13 23:24:38 +00001873 // If the name is a simple identifier (by far the common case), or a
1874 // zero-argument selector, just return a reference to that identifier.
1875 if (IdentifierInfo *Id = Name.getAsIdentifierInfo())
1876 return Id->getName();
1877 if (Name.isObjCZeroArgSelector())
1878 if (IdentifierInfo *Id
1879 = Name.getObjCSelector().getIdentifierInfoForSlot(0))
1880 return Id->getName();
1881
1882 Saved = Name.getAsString();
1883 return Saved;
1884 }
1885
1886 bool operator()(const Result &X, const Result &Y) const {
1887 std::string XSaved, YSaved;
1888 llvm::StringRef XStr = getOrderedName(X, XSaved);
1889 llvm::StringRef YStr = getOrderedName(Y, YSaved);
1890 int cmp = XStr.compare_lower(YStr);
1891 if (cmp)
1892 return cmp < 0;
Douglas Gregor3545ff42009-09-21 16:56:56 +00001893
1894 // Non-hidden names precede hidden names.
1895 if (X.Hidden != Y.Hidden)
1896 return !X.Hidden;
1897
Douglas Gregore412a5a2009-09-23 22:26:46 +00001898 // Non-nested-name-specifiers precede nested-name-specifiers.
1899 if (X.StartsNestedNameSpecifier != Y.StartsNestedNameSpecifier)
1900 return !X.StartsNestedNameSpecifier;
1901
Douglas Gregor3545ff42009-09-21 16:56:56 +00001902 return false;
1903 }
1904 };
1905}
1906
Douglas Gregorf98e6a22010-01-13 23:51:12 +00001907static void AddMacroResults(Preprocessor &PP, ResultBuilder &Results) {
Douglas Gregorf329c7c2009-10-30 16:50:04 +00001908 Results.EnterNewScope();
Douglas Gregor9eb77012009-11-07 00:00:49 +00001909 for (Preprocessor::macro_iterator M = PP.macro_begin(),
1910 MEnd = PP.macro_end();
Douglas Gregorf329c7c2009-10-30 16:50:04 +00001911 M != MEnd; ++M)
Douglas Gregorf98e6a22010-01-13 23:51:12 +00001912 Results.MaybeAddResult(M->first);
Douglas Gregorf329c7c2009-10-30 16:50:04 +00001913 Results.ExitScope();
1914}
1915
Daniel Dunbar242ea9a2009-11-13 08:58:20 +00001916static void HandleCodeCompleteResults(Sema *S,
1917 CodeCompleteConsumer *CodeCompleter,
1918 CodeCompleteConsumer::Result *Results,
1919 unsigned NumResults) {
Douglas Gregor3545ff42009-09-21 16:56:56 +00001920 std::stable_sort(Results, Results + NumResults, SortCodeCompleteResult());
1921
1922 if (CodeCompleter)
Daniel Dunbar242ea9a2009-11-13 08:58:20 +00001923 CodeCompleter->ProcessCodeCompleteResults(*S, Results, NumResults);
Douglas Gregor45f83ee2009-11-19 00:01:57 +00001924
1925 for (unsigned I = 0; I != NumResults; ++I)
1926 Results[I].Destroy();
Douglas Gregor3545ff42009-09-21 16:56:56 +00001927}
1928
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001929void Sema::CodeCompleteOrdinaryName(Scope *S,
1930 CodeCompletionContext CompletionContext) {
Douglas Gregor92253692009-12-07 09:54:55 +00001931 typedef CodeCompleteConsumer::Result Result;
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001932 ResultBuilder Results(*this);
1933
1934 // Determine how to filter results, e.g., so that the names of
1935 // values (functions, enumerators, function templates, etc.) are
1936 // only allowed where we can have an expression.
1937 switch (CompletionContext) {
1938 case CCC_Namespace:
1939 case CCC_Class:
Douglas Gregorf1934162010-01-13 21:24:21 +00001940 case CCC_ObjCInterface:
1941 case CCC_ObjCImplementation:
Douglas Gregor48d46252010-01-13 21:54:15 +00001942 case CCC_ObjCInstanceVariableList:
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001943 case CCC_Template:
1944 case CCC_MemberTemplate:
1945 Results.setFilter(&ResultBuilder::IsOrdinaryNonValueName);
1946 break;
1947
1948 case CCC_Expression:
1949 case CCC_Statement:
1950 case CCC_ForInit:
1951 case CCC_Condition:
1952 Results.setFilter(&ResultBuilder::IsOrdinaryName);
1953 break;
1954 }
1955
Douglas Gregorf98e6a22010-01-13 23:51:12 +00001956 CollectLookupResults(S, Context.getTranslationUnitDecl(), CurContext,
1957 Results);
Douglas Gregor92253692009-12-07 09:54:55 +00001958
1959 Results.EnterNewScope();
Douglas Gregorf98e6a22010-01-13 23:51:12 +00001960 AddOrdinaryNameResults(CompletionContext, S, *this, Results);
Douglas Gregor92253692009-12-07 09:54:55 +00001961 Results.ExitScope();
1962
Douglas Gregor9eb77012009-11-07 00:00:49 +00001963 if (CodeCompleter->includeMacros())
Douglas Gregorf98e6a22010-01-13 23:51:12 +00001964 AddMacroResults(PP, Results);
Daniel Dunbar242ea9a2009-11-13 08:58:20 +00001965 HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
Douglas Gregor9d64c5e2009-09-21 20:51:25 +00001966}
1967
Douglas Gregor9291bad2009-11-18 01:29:26 +00001968static void AddObjCProperties(ObjCContainerDecl *Container,
Douglas Gregor5d649882009-11-18 22:32:06 +00001969 bool AllowCategories,
Douglas Gregor9291bad2009-11-18 01:29:26 +00001970 DeclContext *CurContext,
1971 ResultBuilder &Results) {
1972 typedef CodeCompleteConsumer::Result Result;
1973
1974 // Add properties in this container.
1975 for (ObjCContainerDecl::prop_iterator P = Container->prop_begin(),
1976 PEnd = Container->prop_end();
1977 P != PEnd;
1978 ++P)
1979 Results.MaybeAddResult(Result(*P, 0), CurContext);
1980
1981 // Add properties in referenced protocols.
1982 if (ObjCProtocolDecl *Protocol = dyn_cast<ObjCProtocolDecl>(Container)) {
1983 for (ObjCProtocolDecl::protocol_iterator P = Protocol->protocol_begin(),
1984 PEnd = Protocol->protocol_end();
1985 P != PEnd; ++P)
Douglas Gregor5d649882009-11-18 22:32:06 +00001986 AddObjCProperties(*P, AllowCategories, CurContext, Results);
Douglas Gregor9291bad2009-11-18 01:29:26 +00001987 } else if (ObjCInterfaceDecl *IFace = dyn_cast<ObjCInterfaceDecl>(Container)){
Douglas Gregor5d649882009-11-18 22:32:06 +00001988 if (AllowCategories) {
1989 // Look through categories.
1990 for (ObjCCategoryDecl *Category = IFace->getCategoryList();
1991 Category; Category = Category->getNextClassCategory())
1992 AddObjCProperties(Category, AllowCategories, CurContext, Results);
1993 }
Douglas Gregor9291bad2009-11-18 01:29:26 +00001994
1995 // Look through protocols.
1996 for (ObjCInterfaceDecl::protocol_iterator I = IFace->protocol_begin(),
1997 E = IFace->protocol_end();
1998 I != E; ++I)
Douglas Gregor5d649882009-11-18 22:32:06 +00001999 AddObjCProperties(*I, AllowCategories, CurContext, Results);
Douglas Gregor9291bad2009-11-18 01:29:26 +00002000
2001 // Look in the superclass.
2002 if (IFace->getSuperClass())
Douglas Gregor5d649882009-11-18 22:32:06 +00002003 AddObjCProperties(IFace->getSuperClass(), AllowCategories, CurContext,
2004 Results);
Douglas Gregor9291bad2009-11-18 01:29:26 +00002005 } else if (const ObjCCategoryDecl *Category
2006 = dyn_cast<ObjCCategoryDecl>(Container)) {
2007 // Look through protocols.
2008 for (ObjCInterfaceDecl::protocol_iterator P = Category->protocol_begin(),
2009 PEnd = Category->protocol_end();
2010 P != PEnd; ++P)
Douglas Gregor5d649882009-11-18 22:32:06 +00002011 AddObjCProperties(*P, AllowCategories, CurContext, Results);
Douglas Gregor9291bad2009-11-18 01:29:26 +00002012 }
2013}
2014
Douglas Gregor2436e712009-09-17 21:32:03 +00002015void Sema::CodeCompleteMemberReferenceExpr(Scope *S, ExprTy *BaseE,
2016 SourceLocation OpLoc,
2017 bool IsArrow) {
2018 if (!BaseE || !CodeCompleter)
2019 return;
2020
Douglas Gregor3545ff42009-09-21 16:56:56 +00002021 typedef CodeCompleteConsumer::Result Result;
2022
Douglas Gregor2436e712009-09-17 21:32:03 +00002023 Expr *Base = static_cast<Expr *>(BaseE);
2024 QualType BaseType = Base->getType();
Douglas Gregor3545ff42009-09-21 16:56:56 +00002025
2026 if (IsArrow) {
2027 if (const PointerType *Ptr = BaseType->getAs<PointerType>())
2028 BaseType = Ptr->getPointeeType();
2029 else if (BaseType->isObjCObjectPointerType())
2030 /*Do nothing*/ ;
2031 else
2032 return;
2033 }
2034
Douglas Gregore412a5a2009-09-23 22:26:46 +00002035 ResultBuilder Results(*this, &ResultBuilder::IsMember);
Douglas Gregor9291bad2009-11-18 01:29:26 +00002036 Results.EnterNewScope();
2037 if (const RecordType *Record = BaseType->getAs<RecordType>()) {
2038 // Access to a C/C++ class, struct, or union.
Douglas Gregorf98e6a22010-01-13 23:51:12 +00002039 CollectMemberLookupResults(Record->getDecl(), Record->getDecl(), Results);
Daniel Dunbar242ea9a2009-11-13 08:58:20 +00002040
Douglas Gregor9291bad2009-11-18 01:29:26 +00002041 if (getLangOptions().CPlusPlus) {
2042 if (!Results.empty()) {
2043 // The "template" keyword can follow "->" or "." in the grammar.
2044 // However, we only want to suggest the template keyword if something
2045 // is dependent.
2046 bool IsDependent = BaseType->isDependentType();
2047 if (!IsDependent) {
2048 for (Scope *DepScope = S; DepScope; DepScope = DepScope->getParent())
2049 if (DeclContext *Ctx = (DeclContext *)DepScope->getEntity()) {
2050 IsDependent = Ctx->isDependentContext();
2051 break;
2052 }
2053 }
Daniel Dunbar242ea9a2009-11-13 08:58:20 +00002054
Douglas Gregor9291bad2009-11-18 01:29:26 +00002055 if (IsDependent)
Douglas Gregorf98e6a22010-01-13 23:51:12 +00002056 Results.MaybeAddResult(Result("template"));
Daniel Dunbar242ea9a2009-11-13 08:58:20 +00002057 }
2058
Douglas Gregor9291bad2009-11-18 01:29:26 +00002059 // We could have the start of a nested-name-specifier. Add those
2060 // results as well.
Douglas Gregor99fe2ad2009-12-11 17:31:05 +00002061 // FIXME: We should really walk base classes to produce
2062 // nested-name-specifiers so that we produce more-precise results.
Douglas Gregor9291bad2009-11-18 01:29:26 +00002063 Results.setFilter(&ResultBuilder::IsNestedNameSpecifier);
Douglas Gregorf98e6a22010-01-13 23:51:12 +00002064 CollectLookupResults(S, Context.getTranslationUnitDecl(),
Douglas Gregor9291bad2009-11-18 01:29:26 +00002065 CurContext, Results);
Daniel Dunbar242ea9a2009-11-13 08:58:20 +00002066 }
Douglas Gregor9291bad2009-11-18 01:29:26 +00002067 } else if (!IsArrow && BaseType->getAsObjCInterfacePointerType()) {
2068 // Objective-C property reference.
2069
2070 // Add property results based on our interface.
2071 const ObjCObjectPointerType *ObjCPtr
2072 = BaseType->getAsObjCInterfacePointerType();
2073 assert(ObjCPtr && "Non-NULL pointer guaranteed above!");
Douglas Gregor5d649882009-11-18 22:32:06 +00002074 AddObjCProperties(ObjCPtr->getInterfaceDecl(), true, CurContext, Results);
Douglas Gregor9291bad2009-11-18 01:29:26 +00002075
2076 // Add properties from the protocols in a qualified interface.
2077 for (ObjCObjectPointerType::qual_iterator I = ObjCPtr->qual_begin(),
2078 E = ObjCPtr->qual_end();
2079 I != E; ++I)
Douglas Gregor5d649882009-11-18 22:32:06 +00002080 AddObjCProperties(*I, true, CurContext, Results);
Douglas Gregor9291bad2009-11-18 01:29:26 +00002081 } else if ((IsArrow && BaseType->isObjCObjectPointerType()) ||
2082 (!IsArrow && BaseType->isObjCInterfaceType())) {
2083 // Objective-C instance variable access.
2084 ObjCInterfaceDecl *Class = 0;
2085 if (const ObjCObjectPointerType *ObjCPtr
2086 = BaseType->getAs<ObjCObjectPointerType>())
2087 Class = ObjCPtr->getInterfaceDecl();
2088 else
2089 Class = BaseType->getAs<ObjCInterfaceType>()->getDecl();
2090
2091 // Add all ivars from this class and its superclasses.
2092 for (; Class; Class = Class->getSuperClass()) {
2093 for (ObjCInterfaceDecl::ivar_iterator IVar = Class->ivar_begin(),
2094 IVarEnd = Class->ivar_end();
2095 IVar != IVarEnd; ++IVar)
2096 Results.MaybeAddResult(Result(*IVar, 0), CurContext);
2097 }
Douglas Gregor3545ff42009-09-21 16:56:56 +00002098 }
Douglas Gregor9291bad2009-11-18 01:29:26 +00002099
2100 // FIXME: How do we cope with isa?
2101
2102 Results.ExitScope();
Daniel Dunbar242ea9a2009-11-13 08:58:20 +00002103
2104 // Add macros
2105 if (CodeCompleter->includeMacros())
Douglas Gregorf98e6a22010-01-13 23:51:12 +00002106 AddMacroResults(PP, Results);
Daniel Dunbar242ea9a2009-11-13 08:58:20 +00002107
2108 // Hand off the results found for code completion.
2109 HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
Douglas Gregor2436e712009-09-17 21:32:03 +00002110}
2111
Douglas Gregorf45b0cf2009-09-18 15:37:17 +00002112void Sema::CodeCompleteTag(Scope *S, unsigned TagSpec) {
2113 if (!CodeCompleter)
2114 return;
2115
Douglas Gregor3545ff42009-09-21 16:56:56 +00002116 typedef CodeCompleteConsumer::Result Result;
2117 ResultBuilder::LookupFilter Filter = 0;
Douglas Gregorf45b0cf2009-09-18 15:37:17 +00002118 switch ((DeclSpec::TST)TagSpec) {
2119 case DeclSpec::TST_enum:
Douglas Gregor3545ff42009-09-21 16:56:56 +00002120 Filter = &ResultBuilder::IsEnum;
Douglas Gregorf45b0cf2009-09-18 15:37:17 +00002121 break;
2122
2123 case DeclSpec::TST_union:
Douglas Gregor3545ff42009-09-21 16:56:56 +00002124 Filter = &ResultBuilder::IsUnion;
Douglas Gregorf45b0cf2009-09-18 15:37:17 +00002125 break;
2126
2127 case DeclSpec::TST_struct:
Douglas Gregorf45b0cf2009-09-18 15:37:17 +00002128 case DeclSpec::TST_class:
Douglas Gregor3545ff42009-09-21 16:56:56 +00002129 Filter = &ResultBuilder::IsClassOrStruct;
Douglas Gregorf45b0cf2009-09-18 15:37:17 +00002130 break;
2131
2132 default:
2133 assert(false && "Unknown type specifier kind in CodeCompleteTag");
2134 return;
2135 }
Douglas Gregor3545ff42009-09-21 16:56:56 +00002136
2137 ResultBuilder Results(*this, Filter);
Douglas Gregorf98e6a22010-01-13 23:51:12 +00002138 CollectLookupResults(S, Context.getTranslationUnitDecl(), CurContext,Results);
Douglas Gregor3545ff42009-09-21 16:56:56 +00002139
2140 if (getLangOptions().CPlusPlus) {
2141 // We could have the start of a nested-name-specifier. Add those
2142 // results as well.
2143 Results.setFilter(&ResultBuilder::IsNestedNameSpecifier);
Douglas Gregorf98e6a22010-01-13 23:51:12 +00002144 CollectLookupResults(S, Context.getTranslationUnitDecl(), CurContext,
2145 Results);
Douglas Gregor3545ff42009-09-21 16:56:56 +00002146 }
2147
Douglas Gregor9eb77012009-11-07 00:00:49 +00002148 if (CodeCompleter->includeMacros())
Douglas Gregorf98e6a22010-01-13 23:51:12 +00002149 AddMacroResults(PP, Results);
Daniel Dunbar242ea9a2009-11-13 08:58:20 +00002150 HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
Douglas Gregorf45b0cf2009-09-18 15:37:17 +00002151}
2152
Douglas Gregord328d572009-09-21 18:10:23 +00002153void Sema::CodeCompleteCase(Scope *S) {
2154 if (getSwitchStack().empty() || !CodeCompleter)
2155 return;
2156
2157 SwitchStmt *Switch = getSwitchStack().back();
2158 if (!Switch->getCond()->getType()->isEnumeralType())
2159 return;
2160
2161 // Code-complete the cases of a switch statement over an enumeration type
2162 // by providing the list of
2163 EnumDecl *Enum = Switch->getCond()->getType()->getAs<EnumType>()->getDecl();
2164
2165 // Determine which enumerators we have already seen in the switch statement.
2166 // FIXME: Ideally, we would also be able to look *past* the code-completion
2167 // token, in case we are code-completing in the middle of the switch and not
2168 // at the end. However, we aren't able to do so at the moment.
2169 llvm::SmallPtrSet<EnumConstantDecl *, 8> EnumeratorsSeen;
Douglas Gregorf2510672009-09-21 19:57:38 +00002170 NestedNameSpecifier *Qualifier = 0;
Douglas Gregord328d572009-09-21 18:10:23 +00002171 for (SwitchCase *SC = Switch->getSwitchCaseList(); SC;
2172 SC = SC->getNextSwitchCase()) {
2173 CaseStmt *Case = dyn_cast<CaseStmt>(SC);
2174 if (!Case)
2175 continue;
2176
2177 Expr *CaseVal = Case->getLHS()->IgnoreParenCasts();
2178 if (DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(CaseVal))
2179 if (EnumConstantDecl *Enumerator
2180 = dyn_cast<EnumConstantDecl>(DRE->getDecl())) {
2181 // We look into the AST of the case statement to determine which
2182 // enumerator was named. Alternatively, we could compute the value of
2183 // the integral constant expression, then compare it against the
2184 // values of each enumerator. However, value-based approach would not
2185 // work as well with C++ templates where enumerators declared within a
2186 // template are type- and value-dependent.
2187 EnumeratorsSeen.insert(Enumerator);
2188
Douglas Gregorf2510672009-09-21 19:57:38 +00002189 // If this is a qualified-id, keep track of the nested-name-specifier
2190 // so that we can reproduce it as part of code completion, e.g.,
Douglas Gregord328d572009-09-21 18:10:23 +00002191 //
2192 // switch (TagD.getKind()) {
2193 // case TagDecl::TK_enum:
2194 // break;
2195 // case XXX
2196 //
Douglas Gregorf2510672009-09-21 19:57:38 +00002197 // At the XXX, our completions are TagDecl::TK_union,
Douglas Gregord328d572009-09-21 18:10:23 +00002198 // TagDecl::TK_struct, and TagDecl::TK_class, rather than TK_union,
2199 // TK_struct, and TK_class.
Douglas Gregor4bd90e52009-10-23 18:54:35 +00002200 Qualifier = DRE->getQualifier();
Douglas Gregord328d572009-09-21 18:10:23 +00002201 }
2202 }
2203
Douglas Gregorf2510672009-09-21 19:57:38 +00002204 if (getLangOptions().CPlusPlus && !Qualifier && EnumeratorsSeen.empty()) {
2205 // If there are no prior enumerators in C++, check whether we have to
2206 // qualify the names of the enumerators that we suggest, because they
2207 // may not be visible in this scope.
2208 Qualifier = getRequiredQualification(Context, CurContext,
2209 Enum->getDeclContext());
2210
2211 // FIXME: Scoped enums need to start with "EnumDecl" as the context!
2212 }
2213
Douglas Gregord328d572009-09-21 18:10:23 +00002214 // Add any enumerators that have not yet been mentioned.
2215 ResultBuilder Results(*this);
2216 Results.EnterNewScope();
2217 for (EnumDecl::enumerator_iterator E = Enum->enumerator_begin(),
2218 EEnd = Enum->enumerator_end();
2219 E != EEnd; ++E) {
2220 if (EnumeratorsSeen.count(*E))
2221 continue;
2222
Douglas Gregorf98e6a22010-01-13 23:51:12 +00002223 Results.MaybeAddResult(CodeCompleteConsumer::Result(*E, Qualifier));
Douglas Gregord328d572009-09-21 18:10:23 +00002224 }
2225 Results.ExitScope();
2226
Douglas Gregor9eb77012009-11-07 00:00:49 +00002227 if (CodeCompleter->includeMacros())
Douglas Gregorf98e6a22010-01-13 23:51:12 +00002228 AddMacroResults(PP, Results);
Daniel Dunbar242ea9a2009-11-13 08:58:20 +00002229 HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
Douglas Gregord328d572009-09-21 18:10:23 +00002230}
2231
Douglas Gregorcabea402009-09-22 15:41:20 +00002232namespace {
2233 struct IsBetterOverloadCandidate {
2234 Sema &S;
2235
2236 public:
2237 explicit IsBetterOverloadCandidate(Sema &S) : S(S) { }
2238
2239 bool
2240 operator()(const OverloadCandidate &X, const OverloadCandidate &Y) const {
2241 return S.isBetterOverloadCandidate(X, Y);
2242 }
2243 };
2244}
2245
2246void Sema::CodeCompleteCall(Scope *S, ExprTy *FnIn,
2247 ExprTy **ArgsIn, unsigned NumArgs) {
2248 if (!CodeCompleter)
2249 return;
Douglas Gregor3ef59522009-12-11 19:06:04 +00002250
2251 // When we're code-completing for a call, we fall back to ordinary
2252 // name code-completion whenever we can't produce specific
2253 // results. We may want to revisit this strategy in the future,
2254 // e.g., by merging the two kinds of results.
2255
Douglas Gregorcabea402009-09-22 15:41:20 +00002256 Expr *Fn = (Expr *)FnIn;
2257 Expr **Args = (Expr **)ArgsIn;
Douglas Gregor3ef59522009-12-11 19:06:04 +00002258
Douglas Gregorcabea402009-09-22 15:41:20 +00002259 // Ignore type-dependent call expressions entirely.
2260 if (Fn->isTypeDependent() ||
Douglas Gregor3ef59522009-12-11 19:06:04 +00002261 Expr::hasAnyTypeDependentArguments(Args, NumArgs)) {
Douglas Gregor504a6ae2010-01-10 23:08:15 +00002262 CodeCompleteOrdinaryName(S, CCC_Expression);
Douglas Gregorcabea402009-09-22 15:41:20 +00002263 return;
Douglas Gregor3ef59522009-12-11 19:06:04 +00002264 }
Douglas Gregorcabea402009-09-22 15:41:20 +00002265
John McCall57500772009-12-16 12:17:52 +00002266 // Build an overload candidate set based on the functions we find.
2267 OverloadCandidateSet CandidateSet;
2268
Douglas Gregorcabea402009-09-22 15:41:20 +00002269 // FIXME: What if we're calling something that isn't a function declaration?
2270 // FIXME: What if we're calling a pseudo-destructor?
2271 // FIXME: What if we're calling a member function?
2272
John McCall57500772009-12-16 12:17:52 +00002273 Expr *NakedFn = Fn->IgnoreParenCasts();
2274 if (UnresolvedLookupExpr *ULE = dyn_cast<UnresolvedLookupExpr>(NakedFn))
2275 AddOverloadedCallCandidates(ULE, Args, NumArgs, CandidateSet,
2276 /*PartialOverloading=*/ true);
2277 else if (DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(NakedFn)) {
2278 FunctionDecl *FDecl = dyn_cast<FunctionDecl>(DRE->getDecl());
2279 if (FDecl)
2280 AddOverloadCandidate(FDecl, Args, NumArgs, CandidateSet,
2281 false, false, /*PartialOverloading*/ true);
2282 }
Douglas Gregorcabea402009-09-22 15:41:20 +00002283
2284 // Sort the overload candidate set by placing the best overloads first.
2285 std::stable_sort(CandidateSet.begin(), CandidateSet.end(),
2286 IsBetterOverloadCandidate(*this));
2287
2288 // Add the remaining viable overload candidates as code-completion reslults.
Douglas Gregor05f477c2009-09-23 00:16:58 +00002289 typedef CodeCompleteConsumer::OverloadCandidate ResultCandidate;
2290 llvm::SmallVector<ResultCandidate, 8> Results;
Anders Carlssone7ceb852009-09-22 17:29:51 +00002291
Douglas Gregorcabea402009-09-22 15:41:20 +00002292 for (OverloadCandidateSet::iterator Cand = CandidateSet.begin(),
2293 CandEnd = CandidateSet.end();
2294 Cand != CandEnd; ++Cand) {
2295 if (Cand->Viable)
Douglas Gregor05f477c2009-09-23 00:16:58 +00002296 Results.push_back(ResultCandidate(Cand->Function));
Douglas Gregorcabea402009-09-22 15:41:20 +00002297 }
Douglas Gregor3ef59522009-12-11 19:06:04 +00002298
2299 if (Results.empty())
Douglas Gregor504a6ae2010-01-10 23:08:15 +00002300 CodeCompleteOrdinaryName(S, CCC_Expression);
Douglas Gregor3ef59522009-12-11 19:06:04 +00002301 else
2302 CodeCompleter->ProcessOverloadCandidates(*this, NumArgs, Results.data(),
2303 Results.size());
Douglas Gregorcabea402009-09-22 15:41:20 +00002304}
2305
Douglas Gregor2436e712009-09-17 21:32:03 +00002306void Sema::CodeCompleteQualifiedId(Scope *S, const CXXScopeSpec &SS,
2307 bool EnteringContext) {
2308 if (!SS.getScopeRep() || !CodeCompleter)
2309 return;
2310
Douglas Gregor3545ff42009-09-21 16:56:56 +00002311 DeclContext *Ctx = computeDeclContext(SS, EnteringContext);
2312 if (!Ctx)
2313 return;
Douglas Gregor800f2f02009-12-11 18:28:39 +00002314
2315 // Try to instantiate any non-dependent declaration contexts before
2316 // we look in them.
2317 if (!isDependentScopeSpecifier(SS) && RequireCompleteDeclContext(SS))
2318 return;
2319
Douglas Gregor3545ff42009-09-21 16:56:56 +00002320 ResultBuilder Results(*this);
Douglas Gregorf98e6a22010-01-13 23:51:12 +00002321 CollectMemberLookupResults(Ctx, Ctx, Results);
Douglas Gregor3545ff42009-09-21 16:56:56 +00002322
2323 // The "template" keyword can follow "::" in the grammar, but only
2324 // put it into the grammar if the nested-name-specifier is dependent.
2325 NestedNameSpecifier *NNS = (NestedNameSpecifier *)SS.getScopeRep();
2326 if (!Results.empty() && NNS->isDependent())
Douglas Gregorf98e6a22010-01-13 23:51:12 +00002327 Results.MaybeAddResult("template");
Douglas Gregor3545ff42009-09-21 16:56:56 +00002328
Douglas Gregor9eb77012009-11-07 00:00:49 +00002329 if (CodeCompleter->includeMacros())
Douglas Gregorf98e6a22010-01-13 23:51:12 +00002330 AddMacroResults(PP, Results);
Daniel Dunbar242ea9a2009-11-13 08:58:20 +00002331 HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
Douglas Gregor2436e712009-09-17 21:32:03 +00002332}
Douglas Gregor7e90c6d2009-09-18 19:03:04 +00002333
2334void Sema::CodeCompleteUsing(Scope *S) {
2335 if (!CodeCompleter)
2336 return;
2337
Douglas Gregor3545ff42009-09-21 16:56:56 +00002338 ResultBuilder Results(*this, &ResultBuilder::IsNestedNameSpecifier);
Douglas Gregor64b12b52009-09-22 23:31:26 +00002339 Results.EnterNewScope();
Douglas Gregor3545ff42009-09-21 16:56:56 +00002340
2341 // If we aren't in class scope, we could see the "namespace" keyword.
2342 if (!S->isClassScope())
Douglas Gregorf98e6a22010-01-13 23:51:12 +00002343 Results.MaybeAddResult(CodeCompleteConsumer::Result("namespace"));
Douglas Gregor3545ff42009-09-21 16:56:56 +00002344
2345 // After "using", we can see anything that would start a
2346 // nested-name-specifier.
Douglas Gregorf98e6a22010-01-13 23:51:12 +00002347 CollectLookupResults(S, Context.getTranslationUnitDecl(), CurContext,Results);
Douglas Gregor64b12b52009-09-22 23:31:26 +00002348 Results.ExitScope();
Douglas Gregor3545ff42009-09-21 16:56:56 +00002349
Douglas Gregor9eb77012009-11-07 00:00:49 +00002350 if (CodeCompleter->includeMacros())
Douglas Gregorf98e6a22010-01-13 23:51:12 +00002351 AddMacroResults(PP, Results);
Daniel Dunbar242ea9a2009-11-13 08:58:20 +00002352 HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
Douglas Gregor7e90c6d2009-09-18 19:03:04 +00002353}
2354
2355void Sema::CodeCompleteUsingDirective(Scope *S) {
2356 if (!CodeCompleter)
2357 return;
2358
Douglas Gregor3545ff42009-09-21 16:56:56 +00002359 // After "using namespace", we expect to see a namespace name or namespace
2360 // alias.
2361 ResultBuilder Results(*this, &ResultBuilder::IsNamespaceOrAlias);
Douglas Gregor64b12b52009-09-22 23:31:26 +00002362 Results.EnterNewScope();
Douglas Gregorf98e6a22010-01-13 23:51:12 +00002363 CollectLookupResults(S, Context.getTranslationUnitDecl(), CurContext,Results);
Douglas Gregor64b12b52009-09-22 23:31:26 +00002364 Results.ExitScope();
Douglas Gregor9eb77012009-11-07 00:00:49 +00002365 if (CodeCompleter->includeMacros())
Douglas Gregorf98e6a22010-01-13 23:51:12 +00002366 AddMacroResults(PP, Results);
Daniel Dunbar242ea9a2009-11-13 08:58:20 +00002367 HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
Douglas Gregor7e90c6d2009-09-18 19:03:04 +00002368}
2369
2370void Sema::CodeCompleteNamespaceDecl(Scope *S) {
2371 if (!CodeCompleter)
2372 return;
2373
Douglas Gregor3545ff42009-09-21 16:56:56 +00002374 ResultBuilder Results(*this, &ResultBuilder::IsNamespace);
2375 DeclContext *Ctx = (DeclContext *)S->getEntity();
2376 if (!S->getParent())
2377 Ctx = Context.getTranslationUnitDecl();
2378
2379 if (Ctx && Ctx->isFileContext()) {
2380 // We only want to see those namespaces that have already been defined
2381 // within this scope, because its likely that the user is creating an
2382 // extended namespace declaration. Keep track of the most recent
2383 // definition of each namespace.
2384 std::map<NamespaceDecl *, NamespaceDecl *> OrigToLatest;
2385 for (DeclContext::specific_decl_iterator<NamespaceDecl>
2386 NS(Ctx->decls_begin()), NSEnd(Ctx->decls_end());
2387 NS != NSEnd; ++NS)
2388 OrigToLatest[NS->getOriginalNamespace()] = *NS;
2389
2390 // Add the most recent definition (or extended definition) of each
2391 // namespace to the list of results.
Douglas Gregor64b12b52009-09-22 23:31:26 +00002392 Results.EnterNewScope();
Douglas Gregor3545ff42009-09-21 16:56:56 +00002393 for (std::map<NamespaceDecl *, NamespaceDecl *>::iterator
2394 NS = OrigToLatest.begin(), NSEnd = OrigToLatest.end();
2395 NS != NSEnd; ++NS)
Douglas Gregor2af2f672009-09-21 20:12:40 +00002396 Results.MaybeAddResult(CodeCompleteConsumer::Result(NS->second, 0),
2397 CurContext);
Douglas Gregor64b12b52009-09-22 23:31:26 +00002398 Results.ExitScope();
Douglas Gregor3545ff42009-09-21 16:56:56 +00002399 }
2400
Douglas Gregor9eb77012009-11-07 00:00:49 +00002401 if (CodeCompleter->includeMacros())
Douglas Gregorf98e6a22010-01-13 23:51:12 +00002402 AddMacroResults(PP, Results);
Daniel Dunbar242ea9a2009-11-13 08:58:20 +00002403 HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
Douglas Gregor7e90c6d2009-09-18 19:03:04 +00002404}
2405
2406void Sema::CodeCompleteNamespaceAliasDecl(Scope *S) {
2407 if (!CodeCompleter)
2408 return;
2409
Douglas Gregor3545ff42009-09-21 16:56:56 +00002410 // After "namespace", we expect to see a namespace or alias.
2411 ResultBuilder Results(*this, &ResultBuilder::IsNamespaceOrAlias);
Douglas Gregorf98e6a22010-01-13 23:51:12 +00002412 CollectLookupResults(S, Context.getTranslationUnitDecl(), CurContext,Results);
Douglas Gregor9eb77012009-11-07 00:00:49 +00002413 if (CodeCompleter->includeMacros())
Douglas Gregorf98e6a22010-01-13 23:51:12 +00002414 AddMacroResults(PP, Results);
Daniel Dunbar242ea9a2009-11-13 08:58:20 +00002415 HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
Douglas Gregor7e90c6d2009-09-18 19:03:04 +00002416}
2417
Douglas Gregorc811ede2009-09-18 20:05:18 +00002418void Sema::CodeCompleteOperatorName(Scope *S) {
2419 if (!CodeCompleter)
2420 return;
Douglas Gregor3545ff42009-09-21 16:56:56 +00002421
2422 typedef CodeCompleteConsumer::Result Result;
2423 ResultBuilder Results(*this, &ResultBuilder::IsType);
Douglas Gregor64b12b52009-09-22 23:31:26 +00002424 Results.EnterNewScope();
Douglas Gregorc811ede2009-09-18 20:05:18 +00002425
Douglas Gregor3545ff42009-09-21 16:56:56 +00002426 // Add the names of overloadable operators.
2427#define OVERLOADED_OPERATOR(Name,Spelling,Token,Unary,Binary,MemberOnly) \
2428 if (std::strcmp(Spelling, "?")) \
Douglas Gregorf98e6a22010-01-13 23:51:12 +00002429 Results.MaybeAddResult(Result(Spelling));
Douglas Gregor3545ff42009-09-21 16:56:56 +00002430#include "clang/Basic/OperatorKinds.def"
2431
2432 // Add any type names visible from the current scope
Douglas Gregorf98e6a22010-01-13 23:51:12 +00002433 CollectLookupResults(S, Context.getTranslationUnitDecl(), CurContext,Results);
Douglas Gregor3545ff42009-09-21 16:56:56 +00002434
2435 // Add any type specifiers
Douglas Gregorf98e6a22010-01-13 23:51:12 +00002436 AddTypeSpecifierResults(getLangOptions(), Results);
Douglas Gregor3545ff42009-09-21 16:56:56 +00002437
2438 // Add any nested-name-specifiers
2439 Results.setFilter(&ResultBuilder::IsNestedNameSpecifier);
Douglas Gregorf98e6a22010-01-13 23:51:12 +00002440 CollectLookupResults(S, Context.getTranslationUnitDecl(), CurContext,Results);
Douglas Gregor64b12b52009-09-22 23:31:26 +00002441 Results.ExitScope();
Douglas Gregor3545ff42009-09-21 16:56:56 +00002442
Douglas Gregor9eb77012009-11-07 00:00:49 +00002443 if (CodeCompleter->includeMacros())
Douglas Gregorf98e6a22010-01-13 23:51:12 +00002444 AddMacroResults(PP, Results);
Daniel Dunbar242ea9a2009-11-13 08:58:20 +00002445 HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
Douglas Gregorc811ede2009-09-18 20:05:18 +00002446}
Douglas Gregor7e90c6d2009-09-18 19:03:04 +00002447
Douglas Gregorf1934162010-01-13 21:24:21 +00002448// Macro that expands to @Keyword or Keyword, depending on whether NeedAt is
2449// true or false.
2450#define OBJC_AT_KEYWORD_NAME(NeedAt,Keyword) NeedAt? "@" #Keyword : #Keyword
Douglas Gregorf98e6a22010-01-13 23:51:12 +00002451static void AddObjCImplementationResults(const LangOptions &LangOpts,
Douglas Gregorf1934162010-01-13 21:24:21 +00002452 ResultBuilder &Results,
2453 bool NeedAt) {
2454 typedef CodeCompleteConsumer::Result Result;
2455 // Since we have an implementation, we can end it.
Douglas Gregorf98e6a22010-01-13 23:51:12 +00002456 Results.MaybeAddResult(Result(OBJC_AT_KEYWORD_NAME(NeedAt,end)));
Douglas Gregorf1934162010-01-13 21:24:21 +00002457
2458 CodeCompletionString *Pattern = 0;
2459 if (LangOpts.ObjC2) {
2460 // @dynamic
2461 Pattern = new CodeCompletionString;
2462 Pattern->AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt,dynamic));
2463 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
2464 Pattern->AddPlaceholderChunk("property");
Douglas Gregorf98e6a22010-01-13 23:51:12 +00002465 Results.MaybeAddResult(Result(Pattern));
Douglas Gregorf1934162010-01-13 21:24:21 +00002466
2467 // @synthesize
2468 Pattern = new CodeCompletionString;
2469 Pattern->AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt,synthesize));
2470 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
2471 Pattern->AddPlaceholderChunk("property");
Douglas Gregorf98e6a22010-01-13 23:51:12 +00002472 Results.MaybeAddResult(Result(Pattern));
Douglas Gregorf1934162010-01-13 21:24:21 +00002473 }
2474}
2475
Douglas Gregorf98e6a22010-01-13 23:51:12 +00002476static void AddObjCInterfaceResults(const LangOptions &LangOpts,
Douglas Gregorf1934162010-01-13 21:24:21 +00002477 ResultBuilder &Results,
2478 bool NeedAt) {
2479 typedef CodeCompleteConsumer::Result Result;
2480
2481 // Since we have an interface or protocol, we can end it.
Douglas Gregorf98e6a22010-01-13 23:51:12 +00002482 Results.MaybeAddResult(Result(OBJC_AT_KEYWORD_NAME(NeedAt,end)));
Douglas Gregorf1934162010-01-13 21:24:21 +00002483
2484 if (LangOpts.ObjC2) {
2485 // @property
Douglas Gregorf98e6a22010-01-13 23:51:12 +00002486 Results.MaybeAddResult(Result(OBJC_AT_KEYWORD_NAME(NeedAt,property)));
Douglas Gregorf1934162010-01-13 21:24:21 +00002487
2488 // @required
Douglas Gregorf98e6a22010-01-13 23:51:12 +00002489 Results.MaybeAddResult(Result(OBJC_AT_KEYWORD_NAME(NeedAt,required)));
Douglas Gregorf1934162010-01-13 21:24:21 +00002490
2491 // @optional
Douglas Gregorf98e6a22010-01-13 23:51:12 +00002492 Results.MaybeAddResult(Result(OBJC_AT_KEYWORD_NAME(NeedAt,optional)));
Douglas Gregorf1934162010-01-13 21:24:21 +00002493 }
2494}
2495
Douglas Gregorf98e6a22010-01-13 23:51:12 +00002496static void AddObjCTopLevelResults(ResultBuilder &Results, bool NeedAt) {
Douglas Gregorf1934162010-01-13 21:24:21 +00002497 typedef CodeCompleteConsumer::Result Result;
2498 CodeCompletionString *Pattern = 0;
2499
2500 // @class name ;
2501 Pattern = new CodeCompletionString;
2502 Pattern->AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt,class));
2503 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
2504 Pattern->AddPlaceholderChunk("identifier");
2505 Pattern->AddChunk(CodeCompletionString::CK_SemiColon);
Douglas Gregorf98e6a22010-01-13 23:51:12 +00002506 Results.MaybeAddResult(Result(Pattern));
Douglas Gregorf1934162010-01-13 21:24:21 +00002507
2508 // @interface name
2509 // FIXME: Could introduce the whole pattern, including superclasses and
2510 // such.
2511 Pattern = new CodeCompletionString;
2512 Pattern->AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt,interface));
2513 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
2514 Pattern->AddPlaceholderChunk("class");
Douglas Gregorf98e6a22010-01-13 23:51:12 +00002515 Results.MaybeAddResult(Result(Pattern));
Douglas Gregorf1934162010-01-13 21:24:21 +00002516
2517 // @protocol name
2518 Pattern = new CodeCompletionString;
2519 Pattern->AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt,protocol));
2520 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
2521 Pattern->AddPlaceholderChunk("protocol");
Douglas Gregorf98e6a22010-01-13 23:51:12 +00002522 Results.MaybeAddResult(Result(Pattern));
Douglas Gregorf1934162010-01-13 21:24:21 +00002523
2524 // @implementation name
2525 Pattern = new CodeCompletionString;
2526 Pattern->AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt,implementation));
2527 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
2528 Pattern->AddPlaceholderChunk("class");
Douglas Gregorf98e6a22010-01-13 23:51:12 +00002529 Results.MaybeAddResult(Result(Pattern));
Douglas Gregorf1934162010-01-13 21:24:21 +00002530
2531 // @compatibility_alias name
2532 Pattern = new CodeCompletionString;
2533 Pattern->AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt,compatibility_alias));
2534 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
2535 Pattern->AddPlaceholderChunk("alias");
2536 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
2537 Pattern->AddPlaceholderChunk("class");
Douglas Gregorf98e6a22010-01-13 23:51:12 +00002538 Results.MaybeAddResult(Result(Pattern));
Douglas Gregorf1934162010-01-13 21:24:21 +00002539}
2540
Douglas Gregorf48706c2009-12-07 09:27:33 +00002541void Sema::CodeCompleteObjCAtDirective(Scope *S, DeclPtrTy ObjCImpDecl,
2542 bool InInterface) {
2543 typedef CodeCompleteConsumer::Result Result;
2544 ResultBuilder Results(*this);
2545 Results.EnterNewScope();
Douglas Gregorf1934162010-01-13 21:24:21 +00002546 if (ObjCImpDecl)
Douglas Gregorf98e6a22010-01-13 23:51:12 +00002547 AddObjCImplementationResults(getLangOptions(), Results, false);
Douglas Gregorf1934162010-01-13 21:24:21 +00002548 else if (InInterface)
Douglas Gregorf98e6a22010-01-13 23:51:12 +00002549 AddObjCInterfaceResults(getLangOptions(), Results, false);
Douglas Gregorf1934162010-01-13 21:24:21 +00002550 else
Douglas Gregorf98e6a22010-01-13 23:51:12 +00002551 AddObjCTopLevelResults(Results, false);
Douglas Gregorf48706c2009-12-07 09:27:33 +00002552 Results.ExitScope();
2553 HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
2554}
2555
Douglas Gregorf98e6a22010-01-13 23:51:12 +00002556static void AddObjCExpressionResults(ResultBuilder &Results, bool NeedAt) {
Douglas Gregorbc7c5e42009-12-07 09:51:25 +00002557 typedef CodeCompleteConsumer::Result Result;
2558 CodeCompletionString *Pattern = 0;
2559
2560 // @encode ( type-name )
2561 Pattern = new CodeCompletionString;
Douglas Gregorf1934162010-01-13 21:24:21 +00002562 Pattern->AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt,encode));
Douglas Gregorbc7c5e42009-12-07 09:51:25 +00002563 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
2564 Pattern->AddPlaceholderChunk("type-name");
2565 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
Douglas Gregorf98e6a22010-01-13 23:51:12 +00002566 Results.MaybeAddResult(Result(Pattern));
Douglas Gregorbc7c5e42009-12-07 09:51:25 +00002567
2568 // @protocol ( protocol-name )
2569 Pattern = new CodeCompletionString;
Douglas Gregorf1934162010-01-13 21:24:21 +00002570 Pattern->AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt,protocol));
Douglas Gregorbc7c5e42009-12-07 09:51:25 +00002571 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
2572 Pattern->AddPlaceholderChunk("protocol-name");
2573 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
Douglas Gregorf98e6a22010-01-13 23:51:12 +00002574 Results.MaybeAddResult(Result(Pattern));
Douglas Gregorbc7c5e42009-12-07 09:51:25 +00002575
2576 // @selector ( selector )
2577 Pattern = new CodeCompletionString;
Douglas Gregorf1934162010-01-13 21:24:21 +00002578 Pattern->AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt,selector));
Douglas Gregorbc7c5e42009-12-07 09:51:25 +00002579 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
2580 Pattern->AddPlaceholderChunk("selector");
2581 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
Douglas Gregorf98e6a22010-01-13 23:51:12 +00002582 Results.MaybeAddResult(Result(Pattern));
Douglas Gregorbc7c5e42009-12-07 09:51:25 +00002583}
2584
Douglas Gregorf98e6a22010-01-13 23:51:12 +00002585static void AddObjCStatementResults(ResultBuilder &Results, bool NeedAt) {
Douglas Gregorbc7c5e42009-12-07 09:51:25 +00002586 typedef CodeCompleteConsumer::Result Result;
Douglas Gregorbc7c5e42009-12-07 09:51:25 +00002587 CodeCompletionString *Pattern = 0;
Douglas Gregorf1934162010-01-13 21:24:21 +00002588
Douglas Gregorbc7c5e42009-12-07 09:51:25 +00002589 // @try { statements } @catch ( declaration ) { statements } @finally
2590 // { statements }
2591 Pattern = new CodeCompletionString;
Douglas Gregorf1934162010-01-13 21:24:21 +00002592 Pattern->AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt,try));
Douglas Gregorbc7c5e42009-12-07 09:51:25 +00002593 Pattern->AddChunk(CodeCompletionString::CK_LeftBrace);
2594 Pattern->AddPlaceholderChunk("statements");
2595 Pattern->AddChunk(CodeCompletionString::CK_RightBrace);
2596 Pattern->AddTextChunk("@catch");
2597 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
2598 Pattern->AddPlaceholderChunk("parameter");
2599 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
2600 Pattern->AddChunk(CodeCompletionString::CK_LeftBrace);
2601 Pattern->AddPlaceholderChunk("statements");
2602 Pattern->AddChunk(CodeCompletionString::CK_RightBrace);
2603 Pattern->AddTextChunk("@finally");
2604 Pattern->AddChunk(CodeCompletionString::CK_LeftBrace);
2605 Pattern->AddPlaceholderChunk("statements");
2606 Pattern->AddChunk(CodeCompletionString::CK_RightBrace);
Douglas Gregorf98e6a22010-01-13 23:51:12 +00002607 Results.MaybeAddResult(Result(Pattern));
Douglas Gregorf1934162010-01-13 21:24:21 +00002608
Douglas Gregorbc7c5e42009-12-07 09:51:25 +00002609 // @throw
2610 Pattern = new CodeCompletionString;
Douglas Gregorf1934162010-01-13 21:24:21 +00002611 Pattern->AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt,throw));
Douglas Gregor6a803932010-01-12 06:38:28 +00002612 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
Douglas Gregorbc7c5e42009-12-07 09:51:25 +00002613 Pattern->AddPlaceholderChunk("expression");
Douglas Gregor6a803932010-01-12 06:38:28 +00002614 Pattern->AddChunk(CodeCompletionString::CK_SemiColon);
Douglas Gregorf98e6a22010-01-13 23:51:12 +00002615 Results.MaybeAddResult(Result(Pattern));
Douglas Gregorf1934162010-01-13 21:24:21 +00002616
Douglas Gregorbc7c5e42009-12-07 09:51:25 +00002617 // @synchronized ( expression ) { statements }
2618 Pattern = new CodeCompletionString;
Douglas Gregorf1934162010-01-13 21:24:21 +00002619 Pattern->AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt,synchronized));
Douglas Gregor6a803932010-01-12 06:38:28 +00002620 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
Douglas Gregorbc7c5e42009-12-07 09:51:25 +00002621 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
2622 Pattern->AddPlaceholderChunk("expression");
2623 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
2624 Pattern->AddChunk(CodeCompletionString::CK_LeftBrace);
2625 Pattern->AddPlaceholderChunk("statements");
2626 Pattern->AddChunk(CodeCompletionString::CK_RightBrace);
Douglas Gregorf98e6a22010-01-13 23:51:12 +00002627 Results.MaybeAddResult(Result(Pattern));
Douglas Gregorf1934162010-01-13 21:24:21 +00002628}
Douglas Gregorbc7c5e42009-12-07 09:51:25 +00002629
Douglas Gregorf98e6a22010-01-13 23:51:12 +00002630static void AddObjCVisibilityResults(const LangOptions &LangOpts,
Douglas Gregor48d46252010-01-13 21:54:15 +00002631 ResultBuilder &Results,
2632 bool NeedAt) {
Douglas Gregorf1934162010-01-13 21:24:21 +00002633 typedef CodeCompleteConsumer::Result Result;
Douglas Gregorf98e6a22010-01-13 23:51:12 +00002634 Results.MaybeAddResult(Result(OBJC_AT_KEYWORD_NAME(NeedAt,private)));
2635 Results.MaybeAddResult(Result(OBJC_AT_KEYWORD_NAME(NeedAt,protected)));
2636 Results.MaybeAddResult(Result(OBJC_AT_KEYWORD_NAME(NeedAt,public)));
Douglas Gregor48d46252010-01-13 21:54:15 +00002637 if (LangOpts.ObjC2)
Douglas Gregorf98e6a22010-01-13 23:51:12 +00002638 Results.MaybeAddResult(Result(OBJC_AT_KEYWORD_NAME(NeedAt,package)));
Douglas Gregor48d46252010-01-13 21:54:15 +00002639}
2640
2641void Sema::CodeCompleteObjCAtVisibility(Scope *S) {
2642 ResultBuilder Results(*this);
2643 Results.EnterNewScope();
Douglas Gregorf98e6a22010-01-13 23:51:12 +00002644 AddObjCVisibilityResults(getLangOptions(), Results, false);
Douglas Gregor48d46252010-01-13 21:54:15 +00002645 Results.ExitScope();
2646 HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
2647}
2648
2649void Sema::CodeCompleteObjCAtStatement(Scope *S) {
Douglas Gregorf1934162010-01-13 21:24:21 +00002650 ResultBuilder Results(*this);
2651 Results.EnterNewScope();
Douglas Gregorf98e6a22010-01-13 23:51:12 +00002652 AddObjCStatementResults(Results, false);
2653 AddObjCExpressionResults(Results, false);
Douglas Gregorbc7c5e42009-12-07 09:51:25 +00002654 Results.ExitScope();
2655 HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
2656}
2657
2658void Sema::CodeCompleteObjCAtExpression(Scope *S) {
2659 ResultBuilder Results(*this);
2660 Results.EnterNewScope();
Douglas Gregorf98e6a22010-01-13 23:51:12 +00002661 AddObjCExpressionResults(Results, false);
Douglas Gregorbc7c5e42009-12-07 09:51:25 +00002662 Results.ExitScope();
2663 HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
2664}
2665
Douglas Gregore6078da2009-11-19 00:14:45 +00002666/// \brief Determine whether the addition of the given flag to an Objective-C
2667/// property's attributes will cause a conflict.
2668static bool ObjCPropertyFlagConflicts(unsigned Attributes, unsigned NewFlag) {
2669 // Check if we've already added this flag.
2670 if (Attributes & NewFlag)
2671 return true;
2672
2673 Attributes |= NewFlag;
2674
2675 // Check for collisions with "readonly".
2676 if ((Attributes & ObjCDeclSpec::DQ_PR_readonly) &&
2677 (Attributes & (ObjCDeclSpec::DQ_PR_readwrite |
2678 ObjCDeclSpec::DQ_PR_assign |
2679 ObjCDeclSpec::DQ_PR_copy |
2680 ObjCDeclSpec::DQ_PR_retain)))
2681 return true;
2682
2683 // Check for more than one of { assign, copy, retain }.
2684 unsigned AssignCopyRetMask = Attributes & (ObjCDeclSpec::DQ_PR_assign |
2685 ObjCDeclSpec::DQ_PR_copy |
2686 ObjCDeclSpec::DQ_PR_retain);
2687 if (AssignCopyRetMask &&
2688 AssignCopyRetMask != ObjCDeclSpec::DQ_PR_assign &&
2689 AssignCopyRetMask != ObjCDeclSpec::DQ_PR_copy &&
2690 AssignCopyRetMask != ObjCDeclSpec::DQ_PR_retain)
2691 return true;
2692
2693 return false;
2694}
2695
Douglas Gregor36029f42009-11-18 23:08:07 +00002696void Sema::CodeCompleteObjCPropertyFlags(Scope *S, ObjCDeclSpec &ODS) {
Steve Naroff936354c2009-10-08 21:55:05 +00002697 if (!CodeCompleter)
2698 return;
Douglas Gregor1b605f72009-11-19 01:08:35 +00002699
Steve Naroff936354c2009-10-08 21:55:05 +00002700 unsigned Attributes = ODS.getPropertyAttributes();
2701
2702 typedef CodeCompleteConsumer::Result Result;
2703 ResultBuilder Results(*this);
2704 Results.EnterNewScope();
Douglas Gregore6078da2009-11-19 00:14:45 +00002705 if (!ObjCPropertyFlagConflicts(Attributes, ObjCDeclSpec::DQ_PR_readonly))
Douglas Gregorf98e6a22010-01-13 23:51:12 +00002706 Results.MaybeAddResult(CodeCompleteConsumer::Result("readonly"));
Douglas Gregore6078da2009-11-19 00:14:45 +00002707 if (!ObjCPropertyFlagConflicts(Attributes, ObjCDeclSpec::DQ_PR_assign))
Douglas Gregorf98e6a22010-01-13 23:51:12 +00002708 Results.MaybeAddResult(CodeCompleteConsumer::Result("assign"));
Douglas Gregore6078da2009-11-19 00:14:45 +00002709 if (!ObjCPropertyFlagConflicts(Attributes, ObjCDeclSpec::DQ_PR_readwrite))
Douglas Gregorf98e6a22010-01-13 23:51:12 +00002710 Results.MaybeAddResult(CodeCompleteConsumer::Result("readwrite"));
Douglas Gregore6078da2009-11-19 00:14:45 +00002711 if (!ObjCPropertyFlagConflicts(Attributes, ObjCDeclSpec::DQ_PR_retain))
Douglas Gregorf98e6a22010-01-13 23:51:12 +00002712 Results.MaybeAddResult(CodeCompleteConsumer::Result("retain"));
Douglas Gregore6078da2009-11-19 00:14:45 +00002713 if (!ObjCPropertyFlagConflicts(Attributes, ObjCDeclSpec::DQ_PR_copy))
Douglas Gregorf98e6a22010-01-13 23:51:12 +00002714 Results.MaybeAddResult(CodeCompleteConsumer::Result("copy"));
Douglas Gregore6078da2009-11-19 00:14:45 +00002715 if (!ObjCPropertyFlagConflicts(Attributes, ObjCDeclSpec::DQ_PR_nonatomic))
Douglas Gregorf98e6a22010-01-13 23:51:12 +00002716 Results.MaybeAddResult(CodeCompleteConsumer::Result("nonatomic"));
Douglas Gregore6078da2009-11-19 00:14:45 +00002717 if (!ObjCPropertyFlagConflicts(Attributes, ObjCDeclSpec::DQ_PR_setter)) {
Douglas Gregor45f83ee2009-11-19 00:01:57 +00002718 CodeCompletionString *Setter = new CodeCompletionString;
2719 Setter->AddTypedTextChunk("setter");
2720 Setter->AddTextChunk(" = ");
2721 Setter->AddPlaceholderChunk("method");
Douglas Gregorf98e6a22010-01-13 23:51:12 +00002722 Results.MaybeAddResult(CodeCompleteConsumer::Result(Setter));
Douglas Gregor45f83ee2009-11-19 00:01:57 +00002723 }
Douglas Gregore6078da2009-11-19 00:14:45 +00002724 if (!ObjCPropertyFlagConflicts(Attributes, ObjCDeclSpec::DQ_PR_getter)) {
Douglas Gregor45f83ee2009-11-19 00:01:57 +00002725 CodeCompletionString *Getter = new CodeCompletionString;
2726 Getter->AddTypedTextChunk("getter");
2727 Getter->AddTextChunk(" = ");
2728 Getter->AddPlaceholderChunk("method");
Douglas Gregorf98e6a22010-01-13 23:51:12 +00002729 Results.MaybeAddResult(CodeCompleteConsumer::Result(Getter));
Douglas Gregor45f83ee2009-11-19 00:01:57 +00002730 }
Steve Naroff936354c2009-10-08 21:55:05 +00002731 Results.ExitScope();
Daniel Dunbar242ea9a2009-11-13 08:58:20 +00002732 HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
Steve Naroff936354c2009-10-08 21:55:05 +00002733}
Steve Naroffeae65032009-11-07 02:08:14 +00002734
Douglas Gregorc8537c52009-11-19 07:41:15 +00002735/// \brief Descripts the kind of Objective-C method that we want to find
2736/// via code completion.
2737enum ObjCMethodKind {
2738 MK_Any, //< Any kind of method, provided it means other specified criteria.
2739 MK_ZeroArgSelector, //< Zero-argument (unary) selector.
2740 MK_OneArgSelector //< One-argument selector.
2741};
2742
2743static bool isAcceptableObjCMethod(ObjCMethodDecl *Method,
2744 ObjCMethodKind WantKind,
2745 IdentifierInfo **SelIdents,
2746 unsigned NumSelIdents) {
2747 Selector Sel = Method->getSelector();
2748 if (NumSelIdents > Sel.getNumArgs())
2749 return false;
2750
2751 switch (WantKind) {
2752 case MK_Any: break;
2753 case MK_ZeroArgSelector: return Sel.isUnarySelector();
2754 case MK_OneArgSelector: return Sel.getNumArgs() == 1;
2755 }
2756
2757 for (unsigned I = 0; I != NumSelIdents; ++I)
2758 if (SelIdents[I] != Sel.getIdentifierInfoForSlot(I))
2759 return false;
2760
2761 return true;
2762}
2763
Douglas Gregorbab2b3c2009-11-17 23:22:23 +00002764/// \brief Add all of the Objective-C methods in the given Objective-C
2765/// container to the set of results.
2766///
2767/// The container will be a class, protocol, category, or implementation of
2768/// any of the above. This mether will recurse to include methods from
2769/// the superclasses of classes along with their categories, protocols, and
2770/// implementations.
2771///
2772/// \param Container the container in which we'll look to find methods.
2773///
2774/// \param WantInstance whether to add instance methods (only); if false, this
2775/// routine will add factory methods (only).
2776///
2777/// \param CurContext the context in which we're performing the lookup that
2778/// finds methods.
2779///
2780/// \param Results the structure into which we'll add results.
2781static void AddObjCMethods(ObjCContainerDecl *Container,
2782 bool WantInstanceMethods,
Douglas Gregorc8537c52009-11-19 07:41:15 +00002783 ObjCMethodKind WantKind,
Douglas Gregor1b605f72009-11-19 01:08:35 +00002784 IdentifierInfo **SelIdents,
2785 unsigned NumSelIdents,
Douglas Gregorbab2b3c2009-11-17 23:22:23 +00002786 DeclContext *CurContext,
2787 ResultBuilder &Results) {
2788 typedef CodeCompleteConsumer::Result Result;
2789 for (ObjCContainerDecl::method_iterator M = Container->meth_begin(),
2790 MEnd = Container->meth_end();
2791 M != MEnd; ++M) {
Douglas Gregor1b605f72009-11-19 01:08:35 +00002792 if ((*M)->isInstanceMethod() == WantInstanceMethods) {
2793 // Check whether the selector identifiers we've been given are a
2794 // subset of the identifiers for this particular method.
Douglas Gregorc8537c52009-11-19 07:41:15 +00002795 if (!isAcceptableObjCMethod(*M, WantKind, SelIdents, NumSelIdents))
Douglas Gregor1b605f72009-11-19 01:08:35 +00002796 continue;
Douglas Gregorc8537c52009-11-19 07:41:15 +00002797
Douglas Gregor1b605f72009-11-19 01:08:35 +00002798 Result R = Result(*M, 0);
2799 R.StartParameter = NumSelIdents;
Douglas Gregorc8537c52009-11-19 07:41:15 +00002800 R.AllParametersAreInformative = (WantKind != MK_Any);
Douglas Gregor1b605f72009-11-19 01:08:35 +00002801 Results.MaybeAddResult(R, CurContext);
2802 }
Douglas Gregorbab2b3c2009-11-17 23:22:23 +00002803 }
2804
2805 ObjCInterfaceDecl *IFace = dyn_cast<ObjCInterfaceDecl>(Container);
2806 if (!IFace)
2807 return;
2808
2809 // Add methods in protocols.
2810 const ObjCList<ObjCProtocolDecl> &Protocols= IFace->getReferencedProtocols();
2811 for (ObjCList<ObjCProtocolDecl>::iterator I = Protocols.begin(),
2812 E = Protocols.end();
2813 I != E; ++I)
Douglas Gregorc8537c52009-11-19 07:41:15 +00002814 AddObjCMethods(*I, WantInstanceMethods, WantKind, SelIdents, NumSelIdents,
Douglas Gregor1b605f72009-11-19 01:08:35 +00002815 CurContext, Results);
Douglas Gregorbab2b3c2009-11-17 23:22:23 +00002816
2817 // Add methods in categories.
2818 for (ObjCCategoryDecl *CatDecl = IFace->getCategoryList(); CatDecl;
2819 CatDecl = CatDecl->getNextClassCategory()) {
Douglas Gregorc8537c52009-11-19 07:41:15 +00002820 AddObjCMethods(CatDecl, WantInstanceMethods, WantKind, SelIdents,
2821 NumSelIdents, CurContext, Results);
Douglas Gregorbab2b3c2009-11-17 23:22:23 +00002822
2823 // Add a categories protocol methods.
2824 const ObjCList<ObjCProtocolDecl> &Protocols
2825 = CatDecl->getReferencedProtocols();
2826 for (ObjCList<ObjCProtocolDecl>::iterator I = Protocols.begin(),
2827 E = Protocols.end();
2828 I != E; ++I)
Douglas Gregorc8537c52009-11-19 07:41:15 +00002829 AddObjCMethods(*I, WantInstanceMethods, WantKind, SelIdents,
2830 NumSelIdents, CurContext, Results);
Douglas Gregorbab2b3c2009-11-17 23:22:23 +00002831
2832 // Add methods in category implementations.
2833 if (ObjCCategoryImplDecl *Impl = CatDecl->getImplementation())
Douglas Gregorc8537c52009-11-19 07:41:15 +00002834 AddObjCMethods(Impl, WantInstanceMethods, WantKind, SelIdents,
2835 NumSelIdents, CurContext, Results);
Douglas Gregorbab2b3c2009-11-17 23:22:23 +00002836 }
2837
2838 // Add methods in superclass.
2839 if (IFace->getSuperClass())
Douglas Gregorc8537c52009-11-19 07:41:15 +00002840 AddObjCMethods(IFace->getSuperClass(), WantInstanceMethods, WantKind,
2841 SelIdents, NumSelIdents, CurContext, Results);
Douglas Gregorbab2b3c2009-11-17 23:22:23 +00002842
2843 // Add methods in our implementation, if any.
2844 if (ObjCImplementationDecl *Impl = IFace->getImplementation())
Douglas Gregorc8537c52009-11-19 07:41:15 +00002845 AddObjCMethods(Impl, WantInstanceMethods, WantKind, SelIdents,
2846 NumSelIdents, CurContext, Results);
2847}
2848
2849
2850void Sema::CodeCompleteObjCPropertyGetter(Scope *S, DeclPtrTy ClassDecl,
2851 DeclPtrTy *Methods,
2852 unsigned NumMethods) {
2853 typedef CodeCompleteConsumer::Result Result;
2854
2855 // Try to find the interface where getters might live.
2856 ObjCInterfaceDecl *Class
2857 = dyn_cast_or_null<ObjCInterfaceDecl>(ClassDecl.getAs<Decl>());
2858 if (!Class) {
2859 if (ObjCCategoryDecl *Category
2860 = dyn_cast_or_null<ObjCCategoryDecl>(ClassDecl.getAs<Decl>()))
2861 Class = Category->getClassInterface();
2862
2863 if (!Class)
2864 return;
2865 }
2866
2867 // Find all of the potential getters.
2868 ResultBuilder Results(*this);
2869 Results.EnterNewScope();
2870
2871 // FIXME: We need to do this because Objective-C methods don't get
2872 // pushed into DeclContexts early enough. Argh!
2873 for (unsigned I = 0; I != NumMethods; ++I) {
2874 if (ObjCMethodDecl *Method
2875 = dyn_cast_or_null<ObjCMethodDecl>(Methods[I].getAs<Decl>()))
2876 if (Method->isInstanceMethod() &&
2877 isAcceptableObjCMethod(Method, MK_ZeroArgSelector, 0, 0)) {
2878 Result R = Result(Method, 0);
2879 R.AllParametersAreInformative = true;
2880 Results.MaybeAddResult(R, CurContext);
2881 }
2882 }
2883
2884 AddObjCMethods(Class, true, MK_ZeroArgSelector, 0, 0, CurContext, Results);
2885 Results.ExitScope();
2886 HandleCodeCompleteResults(this, CodeCompleter,Results.data(),Results.size());
2887}
2888
2889void Sema::CodeCompleteObjCPropertySetter(Scope *S, DeclPtrTy ObjCImplDecl,
2890 DeclPtrTy *Methods,
2891 unsigned NumMethods) {
2892 typedef CodeCompleteConsumer::Result Result;
2893
2894 // Try to find the interface where setters might live.
2895 ObjCInterfaceDecl *Class
2896 = dyn_cast_or_null<ObjCInterfaceDecl>(ObjCImplDecl.getAs<Decl>());
2897 if (!Class) {
2898 if (ObjCCategoryDecl *Category
2899 = dyn_cast_or_null<ObjCCategoryDecl>(ObjCImplDecl.getAs<Decl>()))
2900 Class = Category->getClassInterface();
2901
2902 if (!Class)
2903 return;
2904 }
2905
2906 // Find all of the potential getters.
2907 ResultBuilder Results(*this);
2908 Results.EnterNewScope();
2909
2910 // FIXME: We need to do this because Objective-C methods don't get
2911 // pushed into DeclContexts early enough. Argh!
2912 for (unsigned I = 0; I != NumMethods; ++I) {
2913 if (ObjCMethodDecl *Method
2914 = dyn_cast_or_null<ObjCMethodDecl>(Methods[I].getAs<Decl>()))
2915 if (Method->isInstanceMethod() &&
2916 isAcceptableObjCMethod(Method, MK_OneArgSelector, 0, 0)) {
2917 Result R = Result(Method, 0);
2918 R.AllParametersAreInformative = true;
2919 Results.MaybeAddResult(R, CurContext);
2920 }
2921 }
2922
2923 AddObjCMethods(Class, true, MK_OneArgSelector, 0, 0, CurContext, Results);
2924
2925 Results.ExitScope();
2926 HandleCodeCompleteResults(this, CodeCompleter,Results.data(),Results.size());
Douglas Gregorbab2b3c2009-11-17 23:22:23 +00002927}
2928
Douglas Gregor090dd182009-11-17 23:31:36 +00002929void Sema::CodeCompleteObjCClassMessage(Scope *S, IdentifierInfo *FName,
Douglas Gregor1b605f72009-11-19 01:08:35 +00002930 SourceLocation FNameLoc,
2931 IdentifierInfo **SelIdents,
2932 unsigned NumSelIdents) {
Steve Naroffeae65032009-11-07 02:08:14 +00002933 typedef CodeCompleteConsumer::Result Result;
Douglas Gregor8ce33212009-11-17 17:59:40 +00002934 ObjCInterfaceDecl *CDecl = 0;
2935
Douglas Gregor8ce33212009-11-17 17:59:40 +00002936 if (FName->isStr("super")) {
2937 // We're sending a message to "super".
2938 if (ObjCMethodDecl *CurMethod = getCurMethodDecl()) {
2939 // Figure out which interface we're in.
2940 CDecl = CurMethod->getClassInterface();
2941 if (!CDecl)
2942 return;
2943
2944 // Find the superclass of this class.
2945 CDecl = CDecl->getSuperClass();
2946 if (!CDecl)
2947 return;
2948
2949 if (CurMethod->isInstanceMethod()) {
2950 // We are inside an instance method, which means that the message
2951 // send [super ...] is actually calling an instance method on the
2952 // current object. Build the super expression and handle this like
2953 // an instance method.
2954 QualType SuperTy = Context.getObjCInterfaceType(CDecl);
2955 SuperTy = Context.getObjCObjectPointerType(SuperTy);
2956 OwningExprResult Super
Douglas Gregor090dd182009-11-17 23:31:36 +00002957 = Owned(new (Context) ObjCSuperExpr(FNameLoc, SuperTy));
Douglas Gregor1b605f72009-11-19 01:08:35 +00002958 return CodeCompleteObjCInstanceMessage(S, (Expr *)Super.get(),
2959 SelIdents, NumSelIdents);
Douglas Gregor8ce33212009-11-17 17:59:40 +00002960 }
2961
2962 // Okay, we're calling a factory method in our superclass.
2963 }
2964 }
2965
2966 // If the given name refers to an interface type, retrieve the
2967 // corresponding declaration.
2968 if (!CDecl)
Douglas Gregor090dd182009-11-17 23:31:36 +00002969 if (TypeTy *Ty = getTypeName(*FName, FNameLoc, S, 0, false)) {
Douglas Gregor8ce33212009-11-17 17:59:40 +00002970 QualType T = GetTypeFromParser(Ty, 0);
2971 if (!T.isNull())
2972 if (const ObjCInterfaceType *Interface = T->getAs<ObjCInterfaceType>())
2973 CDecl = Interface->getDecl();
2974 }
2975
2976 if (!CDecl && FName->isStr("super")) {
2977 // "super" may be the name of a variable, in which case we are
2978 // probably calling an instance method.
John McCalle66edc12009-11-24 19:00:30 +00002979 CXXScopeSpec SS;
2980 UnqualifiedId id;
2981 id.setIdentifier(FName, FNameLoc);
2982 OwningExprResult Super = ActOnIdExpression(S, SS, id, false, false);
Douglas Gregor1b605f72009-11-19 01:08:35 +00002983 return CodeCompleteObjCInstanceMessage(S, (Expr *)Super.get(),
2984 SelIdents, NumSelIdents);
Douglas Gregor8ce33212009-11-17 17:59:40 +00002985 }
2986
Douglas Gregorbab2b3c2009-11-17 23:22:23 +00002987 // Add all of the factory methods in this Objective-C class, its protocols,
2988 // superclasses, categories, implementation, etc.
Steve Naroffeae65032009-11-07 02:08:14 +00002989 ResultBuilder Results(*this);
2990 Results.EnterNewScope();
Douglas Gregorc8537c52009-11-19 07:41:15 +00002991 AddObjCMethods(CDecl, false, MK_Any, SelIdents, NumSelIdents, CurContext,
2992 Results);
Steve Naroffeae65032009-11-07 02:08:14 +00002993 Results.ExitScope();
Douglas Gregorbab2b3c2009-11-17 23:22:23 +00002994
Steve Naroffeae65032009-11-07 02:08:14 +00002995 // This also suppresses remaining diagnostics.
Daniel Dunbar242ea9a2009-11-13 08:58:20 +00002996 HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
Steve Naroffeae65032009-11-07 02:08:14 +00002997}
2998
Douglas Gregor1b605f72009-11-19 01:08:35 +00002999void Sema::CodeCompleteObjCInstanceMessage(Scope *S, ExprTy *Receiver,
3000 IdentifierInfo **SelIdents,
3001 unsigned NumSelIdents) {
Steve Naroffeae65032009-11-07 02:08:14 +00003002 typedef CodeCompleteConsumer::Result Result;
Steve Naroffeae65032009-11-07 02:08:14 +00003003
3004 Expr *RecExpr = static_cast<Expr *>(Receiver);
Steve Naroffeae65032009-11-07 02:08:14 +00003005
Douglas Gregorbab2b3c2009-11-17 23:22:23 +00003006 // If necessary, apply function/array conversion to the receiver.
3007 // C99 6.7.5.3p[7,8].
3008 DefaultFunctionArrayConversion(RecExpr);
3009 QualType ReceiverType = RecExpr->getType();
Steve Naroffeae65032009-11-07 02:08:14 +00003010
Douglas Gregorbab2b3c2009-11-17 23:22:23 +00003011 if (ReceiverType->isObjCIdType() || ReceiverType->isBlockPointerType()) {
3012 // FIXME: We're messaging 'id'. Do we actually want to look up every method
3013 // in the universe?
3014 return;
3015 }
3016
Douglas Gregorbab2b3c2009-11-17 23:22:23 +00003017 // Build the set of methods we can see.
3018 ResultBuilder Results(*this);
3019 Results.EnterNewScope();
Douglas Gregorbab2b3c2009-11-17 23:22:23 +00003020
Douglas Gregora3329fa2009-11-18 00:06:18 +00003021 // Handle messages to Class. This really isn't a message to an instance
3022 // method, so we treat it the same way we would treat a message send to a
3023 // class method.
3024 if (ReceiverType->isObjCClassType() ||
3025 ReceiverType->isObjCQualifiedClassType()) {
3026 if (ObjCMethodDecl *CurMethod = getCurMethodDecl()) {
3027 if (ObjCInterfaceDecl *ClassDecl = CurMethod->getClassInterface())
Douglas Gregorc8537c52009-11-19 07:41:15 +00003028 AddObjCMethods(ClassDecl, false, MK_Any, SelIdents, NumSelIdents,
3029 CurContext, Results);
Douglas Gregora3329fa2009-11-18 00:06:18 +00003030 }
3031 }
3032 // Handle messages to a qualified ID ("id<foo>").
3033 else if (const ObjCObjectPointerType *QualID
3034 = ReceiverType->getAsObjCQualifiedIdType()) {
3035 // Search protocols for instance methods.
3036 for (ObjCObjectPointerType::qual_iterator I = QualID->qual_begin(),
3037 E = QualID->qual_end();
3038 I != E; ++I)
Douglas Gregorc8537c52009-11-19 07:41:15 +00003039 AddObjCMethods(*I, true, MK_Any, SelIdents, NumSelIdents, CurContext,
3040 Results);
Douglas Gregora3329fa2009-11-18 00:06:18 +00003041 }
3042 // Handle messages to a pointer to interface type.
3043 else if (const ObjCObjectPointerType *IFacePtr
3044 = ReceiverType->getAsObjCInterfacePointerType()) {
3045 // Search the class, its superclasses, etc., for instance methods.
Douglas Gregorc8537c52009-11-19 07:41:15 +00003046 AddObjCMethods(IFacePtr->getInterfaceDecl(), true, MK_Any, SelIdents,
3047 NumSelIdents, CurContext, Results);
Douglas Gregora3329fa2009-11-18 00:06:18 +00003048
3049 // Search protocols for instance methods.
3050 for (ObjCObjectPointerType::qual_iterator I = IFacePtr->qual_begin(),
3051 E = IFacePtr->qual_end();
3052 I != E; ++I)
Douglas Gregorc8537c52009-11-19 07:41:15 +00003053 AddObjCMethods(*I, true, MK_Any, SelIdents, NumSelIdents, CurContext,
3054 Results);
Douglas Gregora3329fa2009-11-18 00:06:18 +00003055 }
3056
Steve Naroffeae65032009-11-07 02:08:14 +00003057 Results.ExitScope();
Daniel Dunbar242ea9a2009-11-13 08:58:20 +00003058 HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
Steve Naroffeae65032009-11-07 02:08:14 +00003059}
Douglas Gregorbaf69612009-11-18 04:19:12 +00003060
3061/// \brief Add all of the protocol declarations that we find in the given
3062/// (translation unit) context.
3063static void AddProtocolResults(DeclContext *Ctx, DeclContext *CurContext,
Douglas Gregor5b4671c2009-11-18 04:49:41 +00003064 bool OnlyForwardDeclarations,
Douglas Gregorbaf69612009-11-18 04:19:12 +00003065 ResultBuilder &Results) {
3066 typedef CodeCompleteConsumer::Result Result;
3067
3068 for (DeclContext::decl_iterator D = Ctx->decls_begin(),
3069 DEnd = Ctx->decls_end();
3070 D != DEnd; ++D) {
3071 // Record any protocols we find.
3072 if (ObjCProtocolDecl *Proto = dyn_cast<ObjCProtocolDecl>(*D))
Douglas Gregor5b4671c2009-11-18 04:49:41 +00003073 if (!OnlyForwardDeclarations || Proto->isForwardDecl())
3074 Results.MaybeAddResult(Result(Proto, 0), CurContext);
Douglas Gregorbaf69612009-11-18 04:19:12 +00003075
3076 // Record any forward-declared protocols we find.
3077 if (ObjCForwardProtocolDecl *Forward
3078 = dyn_cast<ObjCForwardProtocolDecl>(*D)) {
3079 for (ObjCForwardProtocolDecl::protocol_iterator
3080 P = Forward->protocol_begin(),
3081 PEnd = Forward->protocol_end();
3082 P != PEnd; ++P)
Douglas Gregor5b4671c2009-11-18 04:49:41 +00003083 if (!OnlyForwardDeclarations || (*P)->isForwardDecl())
3084 Results.MaybeAddResult(Result(*P, 0), CurContext);
Douglas Gregorbaf69612009-11-18 04:19:12 +00003085 }
3086 }
3087}
3088
3089void Sema::CodeCompleteObjCProtocolReferences(IdentifierLocPair *Protocols,
3090 unsigned NumProtocols) {
3091 ResultBuilder Results(*this);
3092 Results.EnterNewScope();
3093
3094 // Tell the result set to ignore all of the protocols we have
3095 // already seen.
3096 for (unsigned I = 0; I != NumProtocols; ++I)
3097 if (ObjCProtocolDecl *Protocol = LookupProtocol(Protocols[I].first))
3098 Results.Ignore(Protocol);
3099
3100 // Add all protocols.
Douglas Gregor5b4671c2009-11-18 04:49:41 +00003101 AddProtocolResults(Context.getTranslationUnitDecl(), CurContext, false,
3102 Results);
3103
3104 Results.ExitScope();
3105 HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
3106}
3107
3108void Sema::CodeCompleteObjCProtocolDecl(Scope *) {
3109 ResultBuilder Results(*this);
3110 Results.EnterNewScope();
3111
3112 // Add all protocols.
3113 AddProtocolResults(Context.getTranslationUnitDecl(), CurContext, true,
3114 Results);
Douglas Gregorbaf69612009-11-18 04:19:12 +00003115
3116 Results.ExitScope();
3117 HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
3118}
Douglas Gregor49c22a72009-11-18 16:26:39 +00003119
3120/// \brief Add all of the Objective-C interface declarations that we find in
3121/// the given (translation unit) context.
3122static void AddInterfaceResults(DeclContext *Ctx, DeclContext *CurContext,
3123 bool OnlyForwardDeclarations,
3124 bool OnlyUnimplemented,
3125 ResultBuilder &Results) {
3126 typedef CodeCompleteConsumer::Result Result;
3127
3128 for (DeclContext::decl_iterator D = Ctx->decls_begin(),
3129 DEnd = Ctx->decls_end();
3130 D != DEnd; ++D) {
3131 // Record any interfaces we find.
3132 if (ObjCInterfaceDecl *Class = dyn_cast<ObjCInterfaceDecl>(*D))
3133 if ((!OnlyForwardDeclarations || Class->isForwardDecl()) &&
3134 (!OnlyUnimplemented || !Class->getImplementation()))
3135 Results.MaybeAddResult(Result(Class, 0), CurContext);
3136
3137 // Record any forward-declared interfaces we find.
3138 if (ObjCClassDecl *Forward = dyn_cast<ObjCClassDecl>(*D)) {
3139 for (ObjCClassDecl::iterator C = Forward->begin(), CEnd = Forward->end();
3140 C != CEnd; ++C)
3141 if ((!OnlyForwardDeclarations || C->getInterface()->isForwardDecl()) &&
3142 (!OnlyUnimplemented || !C->getInterface()->getImplementation()))
3143 Results.MaybeAddResult(Result(C->getInterface(), 0), CurContext);
3144 }
3145 }
3146}
3147
3148void Sema::CodeCompleteObjCInterfaceDecl(Scope *S) {
3149 ResultBuilder Results(*this);
3150 Results.EnterNewScope();
3151
3152 // Add all classes.
3153 AddInterfaceResults(Context.getTranslationUnitDecl(), CurContext, true,
3154 false, Results);
3155
3156 Results.ExitScope();
3157 HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
3158}
3159
3160void Sema::CodeCompleteObjCSuperclass(Scope *S, IdentifierInfo *ClassName) {
3161 ResultBuilder Results(*this);
3162 Results.EnterNewScope();
3163
3164 // Make sure that we ignore the class we're currently defining.
3165 NamedDecl *CurClass
3166 = LookupSingleName(TUScope, ClassName, LookupOrdinaryName);
Douglas Gregor5d34fd32009-11-18 19:08:43 +00003167 if (CurClass && isa<ObjCInterfaceDecl>(CurClass))
Douglas Gregor49c22a72009-11-18 16:26:39 +00003168 Results.Ignore(CurClass);
3169
3170 // Add all classes.
3171 AddInterfaceResults(Context.getTranslationUnitDecl(), CurContext, false,
3172 false, Results);
3173
3174 Results.ExitScope();
3175 HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
3176}
3177
3178void Sema::CodeCompleteObjCImplementationDecl(Scope *S) {
3179 ResultBuilder Results(*this);
3180 Results.EnterNewScope();
3181
3182 // Add all unimplemented classes.
3183 AddInterfaceResults(Context.getTranslationUnitDecl(), CurContext, false,
3184 true, Results);
3185
3186 Results.ExitScope();
3187 HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
3188}
Douglas Gregor5d34fd32009-11-18 19:08:43 +00003189
3190void Sema::CodeCompleteObjCInterfaceCategory(Scope *S,
3191 IdentifierInfo *ClassName) {
3192 typedef CodeCompleteConsumer::Result Result;
3193
3194 ResultBuilder Results(*this);
3195
3196 // Ignore any categories we find that have already been implemented by this
3197 // interface.
3198 llvm::SmallPtrSet<IdentifierInfo *, 16> CategoryNames;
3199 NamedDecl *CurClass
3200 = LookupSingleName(TUScope, ClassName, LookupOrdinaryName);
3201 if (ObjCInterfaceDecl *Class = dyn_cast_or_null<ObjCInterfaceDecl>(CurClass))
3202 for (ObjCCategoryDecl *Category = Class->getCategoryList(); Category;
3203 Category = Category->getNextClassCategory())
3204 CategoryNames.insert(Category->getIdentifier());
3205
3206 // Add all of the categories we know about.
3207 Results.EnterNewScope();
3208 TranslationUnitDecl *TU = Context.getTranslationUnitDecl();
3209 for (DeclContext::decl_iterator D = TU->decls_begin(),
3210 DEnd = TU->decls_end();
3211 D != DEnd; ++D)
3212 if (ObjCCategoryDecl *Category = dyn_cast<ObjCCategoryDecl>(*D))
3213 if (CategoryNames.insert(Category->getIdentifier()))
3214 Results.MaybeAddResult(Result(Category, 0), CurContext);
3215 Results.ExitScope();
3216
3217 HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
3218}
3219
3220void Sema::CodeCompleteObjCImplementationCategory(Scope *S,
3221 IdentifierInfo *ClassName) {
3222 typedef CodeCompleteConsumer::Result Result;
3223
3224 // Find the corresponding interface. If we couldn't find the interface, the
3225 // program itself is ill-formed. However, we'll try to be helpful still by
3226 // providing the list of all of the categories we know about.
3227 NamedDecl *CurClass
3228 = LookupSingleName(TUScope, ClassName, LookupOrdinaryName);
3229 ObjCInterfaceDecl *Class = dyn_cast_or_null<ObjCInterfaceDecl>(CurClass);
3230 if (!Class)
3231 return CodeCompleteObjCInterfaceCategory(S, ClassName);
3232
3233 ResultBuilder Results(*this);
3234
3235 // Add all of the categories that have have corresponding interface
3236 // declarations in this class and any of its superclasses, except for
3237 // already-implemented categories in the class itself.
3238 llvm::SmallPtrSet<IdentifierInfo *, 16> CategoryNames;
3239 Results.EnterNewScope();
3240 bool IgnoreImplemented = true;
3241 while (Class) {
3242 for (ObjCCategoryDecl *Category = Class->getCategoryList(); Category;
3243 Category = Category->getNextClassCategory())
3244 if ((!IgnoreImplemented || !Category->getImplementation()) &&
3245 CategoryNames.insert(Category->getIdentifier()))
3246 Results.MaybeAddResult(Result(Category, 0), CurContext);
3247
3248 Class = Class->getSuperClass();
3249 IgnoreImplemented = false;
3250 }
3251 Results.ExitScope();
3252
3253 HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
3254}
Douglas Gregor5d649882009-11-18 22:32:06 +00003255
Douglas Gregor52e78bd2009-11-18 22:56:13 +00003256void Sema::CodeCompleteObjCPropertyDefinition(Scope *S, DeclPtrTy ObjCImpDecl) {
Douglas Gregor5d649882009-11-18 22:32:06 +00003257 typedef CodeCompleteConsumer::Result Result;
3258 ResultBuilder Results(*this);
3259
3260 // Figure out where this @synthesize lives.
3261 ObjCContainerDecl *Container
3262 = dyn_cast_or_null<ObjCContainerDecl>(ObjCImpDecl.getAs<Decl>());
3263 if (!Container ||
3264 (!isa<ObjCImplementationDecl>(Container) &&
3265 !isa<ObjCCategoryImplDecl>(Container)))
3266 return;
3267
3268 // Ignore any properties that have already been implemented.
3269 for (DeclContext::decl_iterator D = Container->decls_begin(),
3270 DEnd = Container->decls_end();
3271 D != DEnd; ++D)
3272 if (ObjCPropertyImplDecl *PropertyImpl = dyn_cast<ObjCPropertyImplDecl>(*D))
3273 Results.Ignore(PropertyImpl->getPropertyDecl());
3274
3275 // Add any properties that we find.
3276 Results.EnterNewScope();
3277 if (ObjCImplementationDecl *ClassImpl
3278 = dyn_cast<ObjCImplementationDecl>(Container))
3279 AddObjCProperties(ClassImpl->getClassInterface(), false, CurContext,
3280 Results);
3281 else
3282 AddObjCProperties(cast<ObjCCategoryImplDecl>(Container)->getCategoryDecl(),
3283 false, CurContext, Results);
3284 Results.ExitScope();
3285
3286 HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
3287}
3288
3289void Sema::CodeCompleteObjCPropertySynthesizeIvar(Scope *S,
3290 IdentifierInfo *PropertyName,
3291 DeclPtrTy ObjCImpDecl) {
3292 typedef CodeCompleteConsumer::Result Result;
3293 ResultBuilder Results(*this);
3294
3295 // Figure out where this @synthesize lives.
3296 ObjCContainerDecl *Container
3297 = dyn_cast_or_null<ObjCContainerDecl>(ObjCImpDecl.getAs<Decl>());
3298 if (!Container ||
3299 (!isa<ObjCImplementationDecl>(Container) &&
3300 !isa<ObjCCategoryImplDecl>(Container)))
3301 return;
3302
3303 // Figure out which interface we're looking into.
3304 ObjCInterfaceDecl *Class = 0;
3305 if (ObjCImplementationDecl *ClassImpl
3306 = dyn_cast<ObjCImplementationDecl>(Container))
3307 Class = ClassImpl->getClassInterface();
3308 else
3309 Class = cast<ObjCCategoryImplDecl>(Container)->getCategoryDecl()
3310 ->getClassInterface();
3311
3312 // Add all of the instance variables in this class and its superclasses.
3313 Results.EnterNewScope();
3314 for(; Class; Class = Class->getSuperClass()) {
3315 // FIXME: We could screen the type of each ivar for compatibility with
3316 // the property, but is that being too paternal?
3317 for (ObjCInterfaceDecl::ivar_iterator IVar = Class->ivar_begin(),
3318 IVarEnd = Class->ivar_end();
3319 IVar != IVarEnd; ++IVar)
3320 Results.MaybeAddResult(Result(*IVar, 0), CurContext);
3321 }
3322 Results.ExitScope();
3323
3324 HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
3325}