blob: b828a02255ab5928e942bdc1532290546deb71a5 [file] [log] [blame]
Douglas Gregor81b747b2009-09-17 21:32:03 +00001//===---------------- SemaCodeComplete.cpp - Code Completion ----*- C++ -*-===//
2//
3// The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9//
10// This file defines the code-completion semantic actions.
11//
12//===----------------------------------------------------------------------===//
13#include "Sema.h"
14#include "clang/Sema/CodeCompleteConsumer.h"
Douglas Gregorb9d0ef72009-09-21 19:57:38 +000015#include "clang/AST/ExprCXX.h"
Douglas Gregor24a069f2009-11-17 17:59:40 +000016#include "clang/AST/ExprObjC.h"
Douglas Gregor3f7c7f42009-10-30 16:50:04 +000017#include "clang/Lex/MacroInfo.h"
18#include "clang/Lex/Preprocessor.h"
Douglas Gregor86d9a522009-09-21 16:56:56 +000019#include "llvm/ADT/SmallPtrSet.h"
Douglas Gregor6a684032009-09-28 03:51:44 +000020#include "llvm/ADT/StringExtras.h"
Douglas Gregor86d9a522009-09-21 16:56:56 +000021#include <list>
22#include <map>
23#include <vector>
Douglas Gregor81b747b2009-09-17 21:32:03 +000024
25using namespace clang;
26
Douglas Gregor86d9a522009-09-21 16:56:56 +000027namespace {
28 /// \brief A container of code-completion results.
29 class ResultBuilder {
30 public:
31 /// \brief The type of a name-lookup filter, which can be provided to the
32 /// name-lookup routines to specify which declarations should be included in
33 /// the result set (when it returns true) and which declarations should be
34 /// filtered out (returns false).
35 typedef bool (ResultBuilder::*LookupFilter)(NamedDecl *) const;
36
37 typedef CodeCompleteConsumer::Result Result;
38
39 private:
40 /// \brief The actual results we have found.
41 std::vector<Result> Results;
42
43 /// \brief A record of all of the declarations we have found and placed
44 /// into the result set, used to ensure that no declaration ever gets into
45 /// the result set twice.
46 llvm::SmallPtrSet<Decl*, 16> AllDeclsFound;
47
Douglas Gregorfbcb5d62009-12-06 20:23:50 +000048 typedef std::pair<NamedDecl *, unsigned> DeclIndexPair;
49
50 /// \brief An entry in the shadow map, which is optimized to store
51 /// a single (declaration, index) mapping (the common case) but
52 /// can also store a list of (declaration, index) mappings.
53 class ShadowMapEntry {
54 typedef llvm::SmallVector<DeclIndexPair, 4> DeclIndexPairVector;
55
56 /// \brief Contains either the solitary NamedDecl * or a vector
57 /// of (declaration, index) pairs.
58 llvm::PointerUnion<NamedDecl *, DeclIndexPairVector*> DeclOrVector;
59
60 /// \brief When the entry contains a single declaration, this is
61 /// the index associated with that entry.
62 unsigned SingleDeclIndex;
63
64 public:
65 ShadowMapEntry() : DeclOrVector(), SingleDeclIndex(0) { }
66
67 void Add(NamedDecl *ND, unsigned Index) {
68 if (DeclOrVector.isNull()) {
69 // 0 - > 1 elements: just set the single element information.
70 DeclOrVector = ND;
71 SingleDeclIndex = Index;
72 return;
73 }
74
75 if (NamedDecl *PrevND = DeclOrVector.dyn_cast<NamedDecl *>()) {
76 // 1 -> 2 elements: create the vector of results and push in the
77 // existing declaration.
78 DeclIndexPairVector *Vec = new DeclIndexPairVector;
79 Vec->push_back(DeclIndexPair(PrevND, SingleDeclIndex));
80 DeclOrVector = Vec;
81 }
82
83 // Add the new element to the end of the vector.
84 DeclOrVector.get<DeclIndexPairVector*>()->push_back(
85 DeclIndexPair(ND, Index));
86 }
87
88 void Destroy() {
89 if (DeclIndexPairVector *Vec
90 = DeclOrVector.dyn_cast<DeclIndexPairVector *>()) {
91 delete Vec;
92 DeclOrVector = ((NamedDecl *)0);
93 }
94 }
95
96 // Iteration.
97 class iterator;
98 iterator begin() const;
99 iterator end() const;
100 };
101
Douglas Gregor86d9a522009-09-21 16:56:56 +0000102 /// \brief A mapping from declaration names to the declarations that have
103 /// this name within a particular scope and their index within the list of
104 /// results.
Douglas Gregorfbcb5d62009-12-06 20:23:50 +0000105 typedef llvm::DenseMap<DeclarationName, ShadowMapEntry> ShadowMap;
Douglas Gregor86d9a522009-09-21 16:56:56 +0000106
107 /// \brief The semantic analysis object for which results are being
108 /// produced.
109 Sema &SemaRef;
110
111 /// \brief If non-NULL, a filter function used to remove any code-completion
112 /// results that are not desirable.
113 LookupFilter Filter;
114
115 /// \brief A list of shadow maps, which is used to model name hiding at
116 /// different levels of, e.g., the inheritance hierarchy.
117 std::list<ShadowMap> ShadowMaps;
118
119 public:
120 explicit ResultBuilder(Sema &SemaRef, LookupFilter Filter = 0)
121 : SemaRef(SemaRef), Filter(Filter) { }
122
123 /// \brief Set the filter used for code-completion results.
124 void setFilter(LookupFilter Filter) {
125 this->Filter = Filter;
126 }
127
128 typedef std::vector<Result>::iterator iterator;
129 iterator begin() { return Results.begin(); }
130 iterator end() { return Results.end(); }
131
132 Result *data() { return Results.empty()? 0 : &Results.front(); }
133 unsigned size() const { return Results.size(); }
134 bool empty() const { return Results.empty(); }
135
136 /// \brief Add a new result to this result set (if it isn't already in one
137 /// of the shadow maps), or replace an existing result (for, e.g., a
138 /// redeclaration).
Douglas Gregor456c4a12009-09-21 20:12:40 +0000139 ///
140 /// \param R the result to add (if it is unique).
141 ///
142 /// \param R the context in which this result will be named.
143 void MaybeAddResult(Result R, DeclContext *CurContext = 0);
Douglas Gregor86d9a522009-09-21 16:56:56 +0000144
145 /// \brief Enter into a new scope.
146 void EnterNewScope();
147
148 /// \brief Exit from the current scope.
149 void ExitScope();
150
Douglas Gregor55385fe2009-11-18 04:19:12 +0000151 /// \brief Ignore this declaration, if it is seen again.
152 void Ignore(Decl *D) { AllDeclsFound.insert(D->getCanonicalDecl()); }
153
Douglas Gregor86d9a522009-09-21 16:56:56 +0000154 /// \name Name lookup predicates
155 ///
156 /// These predicates can be passed to the name lookup functions to filter the
157 /// results of name lookup. All of the predicates have the same type, so that
158 ///
159 //@{
Douglas Gregor791215b2009-09-21 20:51:25 +0000160 bool IsOrdinaryName(NamedDecl *ND) const;
Douglas Gregor01dfea02010-01-10 23:08:15 +0000161 bool IsOrdinaryNonValueName(NamedDecl *ND) const;
Douglas Gregor86d9a522009-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 Gregoreb5758b2009-09-23 22:26:46 +0000169 bool IsMember(NamedDecl *ND) const;
Douglas Gregor86d9a522009-09-21 16:56:56 +0000170 //@}
171 };
172}
173
Douglas Gregorfbcb5d62009-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 Gregord490f952009-12-06 21:27:58 +0000226 return *DeclOrIterator.get<const DeclIndexPair*>();
Douglas Gregorfbcb5d62009-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 Gregord490f952009-12-06 21:27:58 +0000234 return X.DeclOrIterator.getOpaqueValue()
235 == Y.DeclOrIterator.getOpaqueValue() &&
Douglas Gregorfbcb5d62009-12-06 20:23:50 +0000236 X.SingleDeclIndex == Y.SingleDeclIndex;
237 }
238
239 friend bool operator!=(const iterator &X, const iterator &Y) {
Douglas Gregord490f952009-12-06 21:27:58 +0000240 return !(X == Y);
Douglas Gregorfbcb5d62009-12-06 20:23:50 +0000241 }
242};
243
Douglas Gregorfbcb5d62009-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 Gregor86d9a522009-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 Gregor86d9a522009-09-21 16:56:56 +0000285 return HiddenCtx != Visible->getDeclContext()->getLookupContext();
286}
287
Douglas Gregor456c4a12009-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 Gregor0c8296d2009-11-07 00:00:49 +0000330 }
Douglas Gregor456c4a12009-09-21 20:12:40 +0000331 return Result;
332}
333
334void ResultBuilder::MaybeAddResult(Result R, DeclContext *CurContext) {
Douglas Gregor8e0a0e42009-09-22 23:31:26 +0000335 assert(!ShadowMaps.empty() && "Must enter into a results scope");
336
Douglas Gregor86d9a522009-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 Gregorf52cede2009-10-09 22:16:47 +0000342
343 // Skip unnamed entities.
344 if (!R.Declaration->getDeclName())
345 return;
346
Douglas Gregor86d9a522009-09-21 16:56:56 +0000347 // Look through using declarations.
John McCall9488ea12009-11-17 05:59:44 +0000348 if (UsingShadowDecl *Using = dyn_cast<UsingShadowDecl>(R.Declaration))
Douglas Gregor0563c262009-09-22 23:15:58 +0000349 MaybeAddResult(Result(Using->getTargetDecl(), R.Rank, R.Qualifier),
350 CurContext);
Douglas Gregor86d9a522009-09-21 16:56:56 +0000351
Douglas Gregor86d9a522009-09-21 16:56:56 +0000352 Decl *CanonDecl = R.Declaration->getCanonicalDecl();
353 unsigned IDNS = CanonDecl->getIdentifierNamespace();
354
355 // Friend declarations and declarations introduced due to friends are never
356 // added as results.
357 if (isa<FriendDecl>(CanonDecl) ||
358 (IDNS & (Decl::IDNS_OrdinaryFriend | Decl::IDNS_TagFriend)))
359 return;
Douglas Gregore29ffaa2009-12-11 16:18:54 +0000360
Douglas Gregor76282942009-12-11 17:31:05 +0000361 // Class template (partial) specializations are never added as results.
Douglas Gregore29ffaa2009-12-11 16:18:54 +0000362 if (isa<ClassTemplateSpecializationDecl>(CanonDecl) ||
363 isa<ClassTemplatePartialSpecializationDecl>(CanonDecl))
364 return;
Douglas Gregor86d9a522009-09-21 16:56:56 +0000365
Douglas Gregor76282942009-12-11 17:31:05 +0000366 // Using declarations themselves are never added as results.
367 if (isa<UsingDecl>(CanonDecl))
368 return;
369
Douglas Gregor86d9a522009-09-21 16:56:56 +0000370 if (const IdentifierInfo *Id = R.Declaration->getIdentifier()) {
371 // __va_list_tag is a freak of nature. Find it and skip it.
372 if (Id->isStr("__va_list_tag") || Id->isStr("__builtin_va_list"))
373 return;
374
Douglas Gregorf52cede2009-10-09 22:16:47 +0000375 // Filter out names reserved for the implementation (C99 7.1.3,
376 // C++ [lib.global.names]). Users don't need to see those.
Daniel Dunbare013d682009-10-18 20:26:12 +0000377 //
378 // FIXME: Add predicate for this.
Douglas Gregorf52cede2009-10-09 22:16:47 +0000379 if (Id->getLength() >= 2) {
Daniel Dunbare013d682009-10-18 20:26:12 +0000380 const char *Name = Id->getNameStart();
Douglas Gregorf52cede2009-10-09 22:16:47 +0000381 if (Name[0] == '_' &&
382 (Name[1] == '_' || (Name[1] >= 'A' && Name[1] <= 'Z')))
383 return;
384 }
Douglas Gregor86d9a522009-09-21 16:56:56 +0000385 }
386
387 // C++ constructors are never found by name lookup.
388 if (isa<CXXConstructorDecl>(CanonDecl))
389 return;
390
391 // Filter out any unwanted results.
392 if (Filter && !(this->*Filter)(R.Declaration))
393 return;
394
395 ShadowMap &SMap = ShadowMaps.back();
Douglas Gregorfbcb5d62009-12-06 20:23:50 +0000396 ShadowMapEntry::iterator I, IEnd;
397 ShadowMap::iterator NamePos = SMap.find(R.Declaration->getDeclName());
398 if (NamePos != SMap.end()) {
399 I = NamePos->second.begin();
400 IEnd = NamePos->second.end();
401 }
402
403 for (; I != IEnd; ++I) {
404 NamedDecl *ND = I->first;
405 unsigned Index = I->second;
Douglas Gregor86d9a522009-09-21 16:56:56 +0000406 if (ND->getCanonicalDecl() == CanonDecl) {
407 // This is a redeclaration. Always pick the newer declaration.
Douglas Gregor86d9a522009-09-21 16:56:56 +0000408 Results[Index].Declaration = R.Declaration;
409
410 // Pick the best rank of the two.
411 Results[Index].Rank = std::min(Results[Index].Rank, R.Rank);
412
413 // We're done.
414 return;
415 }
416 }
417
418 // This is a new declaration in this scope. However, check whether this
419 // declaration name is hidden by a similarly-named declaration in an outer
420 // scope.
421 std::list<ShadowMap>::iterator SM, SMEnd = ShadowMaps.end();
422 --SMEnd;
423 for (SM = ShadowMaps.begin(); SM != SMEnd; ++SM) {
Douglas Gregorfbcb5d62009-12-06 20:23:50 +0000424 ShadowMapEntry::iterator I, IEnd;
425 ShadowMap::iterator NamePos = SM->find(R.Declaration->getDeclName());
426 if (NamePos != SM->end()) {
427 I = NamePos->second.begin();
428 IEnd = NamePos->second.end();
429 }
430 for (; I != IEnd; ++I) {
Douglas Gregor86d9a522009-09-21 16:56:56 +0000431 // A tag declaration does not hide a non-tag declaration.
Douglas Gregorfbcb5d62009-12-06 20:23:50 +0000432 if (I->first->getIdentifierNamespace() == Decl::IDNS_Tag &&
Douglas Gregor86d9a522009-09-21 16:56:56 +0000433 (IDNS & (Decl::IDNS_Member | Decl::IDNS_Ordinary |
434 Decl::IDNS_ObjCProtocol)))
435 continue;
436
437 // Protocols are in distinct namespaces from everything else.
Douglas Gregorfbcb5d62009-12-06 20:23:50 +0000438 if (((I->first->getIdentifierNamespace() & Decl::IDNS_ObjCProtocol)
Douglas Gregor86d9a522009-09-21 16:56:56 +0000439 || (IDNS & Decl::IDNS_ObjCProtocol)) &&
Douglas Gregorfbcb5d62009-12-06 20:23:50 +0000440 I->first->getIdentifierNamespace() != IDNS)
Douglas Gregor86d9a522009-09-21 16:56:56 +0000441 continue;
442
443 // The newly-added result is hidden by an entry in the shadow map.
444 if (canHiddenResultBeFound(SemaRef.getLangOptions(), R.Declaration,
Douglas Gregorfbcb5d62009-12-06 20:23:50 +0000445 I->first)) {
Douglas Gregor86d9a522009-09-21 16:56:56 +0000446 // Note that this result was hidden.
447 R.Hidden = true;
Douglas Gregor0563c262009-09-22 23:15:58 +0000448 R.QualifierIsInformative = false;
Douglas Gregor456c4a12009-09-21 20:12:40 +0000449
450 if (!R.Qualifier)
451 R.Qualifier = getRequiredQualification(SemaRef.Context,
452 CurContext,
453 R.Declaration->getDeclContext());
Douglas Gregor86d9a522009-09-21 16:56:56 +0000454 } else {
455 // This result was hidden and cannot be found; don't bother adding
456 // it.
457 return;
458 }
459
460 break;
461 }
462 }
463
464 // Make sure that any given declaration only shows up in the result set once.
465 if (!AllDeclsFound.insert(CanonDecl))
466 return;
467
Douglas Gregoreb5758b2009-09-23 22:26:46 +0000468 // If the filter is for nested-name-specifiers, then this result starts a
469 // nested-name-specifier.
470 if ((Filter == &ResultBuilder::IsNestedNameSpecifier) ||
471 (Filter == &ResultBuilder::IsMember &&
472 isa<CXXRecordDecl>(R.Declaration) &&
473 cast<CXXRecordDecl>(R.Declaration)->isInjectedClassName()))
474 R.StartsNestedNameSpecifier = true;
475
Douglas Gregor0563c262009-09-22 23:15:58 +0000476 // If this result is supposed to have an informative qualifier, add one.
Douglas Gregoreb5758b2009-09-23 22:26:46 +0000477 if (R.QualifierIsInformative && !R.Qualifier &&
478 !R.StartsNestedNameSpecifier) {
Douglas Gregor0563c262009-09-22 23:15:58 +0000479 DeclContext *Ctx = R.Declaration->getDeclContext();
480 if (NamespaceDecl *Namespace = dyn_cast<NamespaceDecl>(Ctx))
481 R.Qualifier = NestedNameSpecifier::Create(SemaRef.Context, 0, Namespace);
482 else if (TagDecl *Tag = dyn_cast<TagDecl>(Ctx))
483 R.Qualifier = NestedNameSpecifier::Create(SemaRef.Context, 0, false,
484 SemaRef.Context.getTypeDeclType(Tag).getTypePtr());
485 else
486 R.QualifierIsInformative = false;
487 }
Douglas Gregoreb5758b2009-09-23 22:26:46 +0000488
Douglas Gregor86d9a522009-09-21 16:56:56 +0000489 // Insert this result into the set of results and into the current shadow
490 // map.
Douglas Gregorfbcb5d62009-12-06 20:23:50 +0000491 SMap[R.Declaration->getDeclName()].Add(R.Declaration, Results.size());
Douglas Gregor86d9a522009-09-21 16:56:56 +0000492 Results.push_back(R);
493}
494
495/// \brief Enter into a new scope.
496void ResultBuilder::EnterNewScope() {
497 ShadowMaps.push_back(ShadowMap());
498}
499
500/// \brief Exit from the current scope.
501void ResultBuilder::ExitScope() {
Douglas Gregorfbcb5d62009-12-06 20:23:50 +0000502 for (ShadowMap::iterator E = ShadowMaps.back().begin(),
503 EEnd = ShadowMaps.back().end();
504 E != EEnd;
505 ++E)
506 E->second.Destroy();
507
Douglas Gregor86d9a522009-09-21 16:56:56 +0000508 ShadowMaps.pop_back();
509}
510
Douglas Gregor791215b2009-09-21 20:51:25 +0000511/// \brief Determines whether this given declaration will be found by
512/// ordinary name lookup.
513bool ResultBuilder::IsOrdinaryName(NamedDecl *ND) const {
514 unsigned IDNS = Decl::IDNS_Ordinary;
515 if (SemaRef.getLangOptions().CPlusPlus)
516 IDNS |= Decl::IDNS_Tag;
517
518 return ND->getIdentifierNamespace() & IDNS;
519}
520
Douglas Gregor01dfea02010-01-10 23:08:15 +0000521/// \brief Determines whether this given declaration will be found by
522/// ordinary name lookup.
523bool ResultBuilder::IsOrdinaryNonValueName(NamedDecl *ND) const {
524 unsigned IDNS = Decl::IDNS_Ordinary;
525 if (SemaRef.getLangOptions().CPlusPlus)
526 IDNS |= Decl::IDNS_Tag;
527
528 return (ND->getIdentifierNamespace() & IDNS) &&
529 !isa<ValueDecl>(ND) && !isa<FunctionTemplateDecl>(ND);
530}
531
Douglas Gregor86d9a522009-09-21 16:56:56 +0000532/// \brief Determines whether the given declaration is suitable as the
533/// start of a C++ nested-name-specifier, e.g., a class or namespace.
534bool ResultBuilder::IsNestedNameSpecifier(NamedDecl *ND) const {
535 // Allow us to find class templates, too.
536 if (ClassTemplateDecl *ClassTemplate = dyn_cast<ClassTemplateDecl>(ND))
537 ND = ClassTemplate->getTemplatedDecl();
538
539 return SemaRef.isAcceptableNestedNameSpecifier(ND);
540}
541
542/// \brief Determines whether the given declaration is an enumeration.
543bool ResultBuilder::IsEnum(NamedDecl *ND) const {
544 return isa<EnumDecl>(ND);
545}
546
547/// \brief Determines whether the given declaration is a class or struct.
548bool ResultBuilder::IsClassOrStruct(NamedDecl *ND) const {
549 // Allow us to find class templates, too.
550 if (ClassTemplateDecl *ClassTemplate = dyn_cast<ClassTemplateDecl>(ND))
551 ND = ClassTemplate->getTemplatedDecl();
552
553 if (RecordDecl *RD = dyn_cast<RecordDecl>(ND))
554 return RD->getTagKind() == TagDecl::TK_class ||
555 RD->getTagKind() == TagDecl::TK_struct;
556
557 return false;
558}
559
560/// \brief Determines whether the given declaration is a union.
561bool ResultBuilder::IsUnion(NamedDecl *ND) const {
562 // Allow us to find class templates, too.
563 if (ClassTemplateDecl *ClassTemplate = dyn_cast<ClassTemplateDecl>(ND))
564 ND = ClassTemplate->getTemplatedDecl();
565
566 if (RecordDecl *RD = dyn_cast<RecordDecl>(ND))
567 return RD->getTagKind() == TagDecl::TK_union;
568
569 return false;
570}
571
572/// \brief Determines whether the given declaration is a namespace.
573bool ResultBuilder::IsNamespace(NamedDecl *ND) const {
574 return isa<NamespaceDecl>(ND);
575}
576
577/// \brief Determines whether the given declaration is a namespace or
578/// namespace alias.
579bool ResultBuilder::IsNamespaceOrAlias(NamedDecl *ND) const {
580 return isa<NamespaceDecl>(ND) || isa<NamespaceAliasDecl>(ND);
581}
582
Douglas Gregor76282942009-12-11 17:31:05 +0000583/// \brief Determines whether the given declaration is a type.
Douglas Gregor86d9a522009-09-21 16:56:56 +0000584bool ResultBuilder::IsType(NamedDecl *ND) const {
585 return isa<TypeDecl>(ND);
586}
587
Douglas Gregor76282942009-12-11 17:31:05 +0000588/// \brief Determines which members of a class should be visible via
589/// "." or "->". Only value declarations, nested name specifiers, and
590/// using declarations thereof should show up.
Douglas Gregoreb5758b2009-09-23 22:26:46 +0000591bool ResultBuilder::IsMember(NamedDecl *ND) const {
Douglas Gregor76282942009-12-11 17:31:05 +0000592 if (UsingShadowDecl *Using = dyn_cast<UsingShadowDecl>(ND))
593 ND = Using->getTargetDecl();
594
Douglas Gregorce821962009-12-11 18:14:22 +0000595 return isa<ValueDecl>(ND) || isa<FunctionTemplateDecl>(ND) ||
596 isa<ObjCPropertyDecl>(ND);
Douglas Gregoreb5758b2009-09-23 22:26:46 +0000597}
598
Douglas Gregor86d9a522009-09-21 16:56:56 +0000599// Find the next outer declaration context corresponding to this scope.
600static DeclContext *findOuterContext(Scope *S) {
601 for (S = S->getParent(); S; S = S->getParent())
602 if (S->getEntity())
603 return static_cast<DeclContext *>(S->getEntity())->getPrimaryContext();
604
605 return 0;
606}
607
608/// \brief Collect the results of searching for members within the given
609/// declaration context.
610///
611/// \param Ctx the declaration context from which we will gather results.
612///
Douglas Gregor0563c262009-09-22 23:15:58 +0000613/// \param Rank the rank given to results in this declaration context.
Douglas Gregor86d9a522009-09-21 16:56:56 +0000614///
615/// \param Visited the set of declaration contexts that have already been
616/// visited. Declaration contexts will only be visited once.
617///
618/// \param Results the result set that will be extended with any results
619/// found within this declaration context (and, for a C++ class, its bases).
620///
Douglas Gregor0563c262009-09-22 23:15:58 +0000621/// \param InBaseClass whether we are in a base class.
622///
Douglas Gregor86d9a522009-09-21 16:56:56 +0000623/// \returns the next higher rank value, after considering all of the
624/// names within this declaration context.
625static unsigned CollectMemberLookupResults(DeclContext *Ctx,
Douglas Gregor0563c262009-09-22 23:15:58 +0000626 unsigned Rank,
Douglas Gregor456c4a12009-09-21 20:12:40 +0000627 DeclContext *CurContext,
628 llvm::SmallPtrSet<DeclContext *, 16> &Visited,
Douglas Gregor0563c262009-09-22 23:15:58 +0000629 ResultBuilder &Results,
630 bool InBaseClass = false) {
Douglas Gregor86d9a522009-09-21 16:56:56 +0000631 // Make sure we don't visit the same context twice.
632 if (!Visited.insert(Ctx->getPrimaryContext()))
Douglas Gregor0563c262009-09-22 23:15:58 +0000633 return Rank;
Douglas Gregor86d9a522009-09-21 16:56:56 +0000634
635 // Enumerate all of the results in this context.
Douglas Gregor0563c262009-09-22 23:15:58 +0000636 typedef CodeCompleteConsumer::Result Result;
Douglas Gregor86d9a522009-09-21 16:56:56 +0000637 Results.EnterNewScope();
638 for (DeclContext *CurCtx = Ctx->getPrimaryContext(); CurCtx;
639 CurCtx = CurCtx->getNextContext()) {
640 for (DeclContext::decl_iterator D = CurCtx->decls_begin(),
Douglas Gregorff4393c2009-11-09 21:35:27 +0000641 DEnd = CurCtx->decls_end();
Douglas Gregor86d9a522009-09-21 16:56:56 +0000642 D != DEnd; ++D) {
643 if (NamedDecl *ND = dyn_cast<NamedDecl>(*D))
Douglas Gregor0563c262009-09-22 23:15:58 +0000644 Results.MaybeAddResult(Result(ND, Rank, 0, InBaseClass), CurContext);
Douglas Gregorff4393c2009-11-09 21:35:27 +0000645
646 // Visit transparent contexts inside this context.
647 if (DeclContext *InnerCtx = dyn_cast<DeclContext>(*D)) {
648 if (InnerCtx->isTransparentContext())
649 CollectMemberLookupResults(InnerCtx, Rank, CurContext, Visited,
650 Results, InBaseClass);
651 }
Douglas Gregor86d9a522009-09-21 16:56:56 +0000652 }
653 }
654
655 // Traverse the contexts of inherited classes.
Douglas Gregor86d9a522009-09-21 16:56:56 +0000656 if (CXXRecordDecl *Record = dyn_cast<CXXRecordDecl>(Ctx)) {
657 for (CXXRecordDecl::base_class_iterator B = Record->bases_begin(),
Douglas Gregorff4393c2009-11-09 21:35:27 +0000658 BEnd = Record->bases_end();
Douglas Gregor86d9a522009-09-21 16:56:56 +0000659 B != BEnd; ++B) {
660 QualType BaseType = B->getType();
661
662 // Don't look into dependent bases, because name lookup can't look
663 // there anyway.
664 if (BaseType->isDependentType())
665 continue;
666
667 const RecordType *Record = BaseType->getAs<RecordType>();
668 if (!Record)
669 continue;
670
671 // FIXME: It would be nice to be able to determine whether referencing
672 // a particular member would be ambiguous. For example, given
673 //
674 // struct A { int member; };
675 // struct B { int member; };
676 // struct C : A, B { };
677 //
678 // void f(C *c) { c->### }
679 // accessing 'member' would result in an ambiguity. However, code
680 // completion could be smart enough to qualify the member with the
681 // base class, e.g.,
682 //
683 // c->B::member
684 //
685 // or
686 //
687 // c->A::member
688
689 // Collect results from this base class (and its bases).
Douglas Gregor0563c262009-09-22 23:15:58 +0000690 CollectMemberLookupResults(Record->getDecl(), Rank, CurContext, Visited,
691 Results, /*InBaseClass=*/true);
Douglas Gregor86d9a522009-09-21 16:56:56 +0000692 }
693 }
694
695 // FIXME: Look into base classes in Objective-C!
696
697 Results.ExitScope();
Douglas Gregor0563c262009-09-22 23:15:58 +0000698 return Rank + 1;
Douglas Gregor86d9a522009-09-21 16:56:56 +0000699}
700
701/// \brief Collect the results of searching for members within the given
702/// declaration context.
703///
704/// \param Ctx the declaration context from which we will gather results.
705///
706/// \param InitialRank the initial rank given to results in this declaration
707/// context. Larger rank values will be used for, e.g., members found in
708/// base classes.
709///
710/// \param Results the result set that will be extended with any results
711/// found within this declaration context (and, for a C++ class, its bases).
712///
713/// \returns the next higher rank value, after considering all of the
714/// names within this declaration context.
715static unsigned CollectMemberLookupResults(DeclContext *Ctx,
716 unsigned InitialRank,
Douglas Gregor456c4a12009-09-21 20:12:40 +0000717 DeclContext *CurContext,
Douglas Gregor86d9a522009-09-21 16:56:56 +0000718 ResultBuilder &Results) {
719 llvm::SmallPtrSet<DeclContext *, 16> Visited;
Douglas Gregor456c4a12009-09-21 20:12:40 +0000720 return CollectMemberLookupResults(Ctx, InitialRank, CurContext, Visited,
721 Results);
Douglas Gregor86d9a522009-09-21 16:56:56 +0000722}
723
724/// \brief Collect the results of searching for declarations within the given
725/// scope and its parent scopes.
726///
727/// \param S the scope in which we will start looking for declarations.
728///
729/// \param InitialRank the initial rank given to results in this scope.
730/// Larger rank values will be used for results found in parent scopes.
731///
Douglas Gregor456c4a12009-09-21 20:12:40 +0000732/// \param CurContext the context from which lookup results will be found.
733///
Douglas Gregor86d9a522009-09-21 16:56:56 +0000734/// \param Results the builder object that will receive each result.
735static unsigned CollectLookupResults(Scope *S,
736 TranslationUnitDecl *TranslationUnit,
737 unsigned InitialRank,
Douglas Gregor456c4a12009-09-21 20:12:40 +0000738 DeclContext *CurContext,
Douglas Gregor86d9a522009-09-21 16:56:56 +0000739 ResultBuilder &Results) {
740 if (!S)
741 return InitialRank;
742
743 // FIXME: Using directives!
744
745 unsigned NextRank = InitialRank;
746 Results.EnterNewScope();
747 if (S->getEntity() &&
748 !((DeclContext *)S->getEntity())->isFunctionOrMethod()) {
749 // Look into this scope's declaration context, along with any of its
750 // parent lookup contexts (e.g., enclosing classes), up to the point
751 // where we hit the context stored in the next outer scope.
752 DeclContext *Ctx = (DeclContext *)S->getEntity();
753 DeclContext *OuterCtx = findOuterContext(S);
754
755 for (; Ctx && Ctx->getPrimaryContext() != OuterCtx;
756 Ctx = Ctx->getLookupParent()) {
757 if (Ctx->isFunctionOrMethod())
758 continue;
759
Douglas Gregor456c4a12009-09-21 20:12:40 +0000760 NextRank = CollectMemberLookupResults(Ctx, NextRank + 1, CurContext,
761 Results);
Douglas Gregor86d9a522009-09-21 16:56:56 +0000762 }
763 } else if (!S->getParent()) {
764 // Look into the translation unit scope. We walk through the translation
765 // unit's declaration context, because the Scope itself won't have all of
766 // the declarations if we loaded a precompiled header.
767 // FIXME: We would like the translation unit's Scope object to point to the
768 // translation unit, so we don't need this special "if" branch. However,
769 // doing so would force the normal C++ name-lookup code to look into the
770 // translation unit decl when the IdentifierInfo chains would suffice.
771 // Once we fix that problem (which is part of a more general "don't look
772 // in DeclContexts unless we have to" optimization), we can eliminate the
773 // TranslationUnit parameter entirely.
774 NextRank = CollectMemberLookupResults(TranslationUnit, NextRank + 1,
Douglas Gregor456c4a12009-09-21 20:12:40 +0000775 CurContext, Results);
Douglas Gregor86d9a522009-09-21 16:56:56 +0000776 } else {
777 // Walk through the declarations in this Scope.
778 for (Scope::decl_iterator D = S->decl_begin(), DEnd = S->decl_end();
779 D != DEnd; ++D) {
780 if (NamedDecl *ND = dyn_cast<NamedDecl>((Decl *)((*D).get())))
Douglas Gregor456c4a12009-09-21 20:12:40 +0000781 Results.MaybeAddResult(CodeCompleteConsumer::Result(ND, NextRank),
782 CurContext);
Douglas Gregor86d9a522009-09-21 16:56:56 +0000783 }
784
785 NextRank = NextRank + 1;
786 }
787
788 // Lookup names in the parent scope.
789 NextRank = CollectLookupResults(S->getParent(), TranslationUnit, NextRank,
Douglas Gregor456c4a12009-09-21 20:12:40 +0000790 CurContext, Results);
Douglas Gregor86d9a522009-09-21 16:56:56 +0000791 Results.ExitScope();
792
793 return NextRank;
794}
795
796/// \brief Add type specifiers for the current language as keyword results.
Douglas Gregor9a0c85e2009-12-07 09:51:25 +0000797static void AddTypeSpecifierResults(const LangOptions &LangOpts, unsigned Rank,
Douglas Gregor86d9a522009-09-21 16:56:56 +0000798 ResultBuilder &Results) {
799 typedef CodeCompleteConsumer::Result Result;
800 Results.MaybeAddResult(Result("short", Rank));
801 Results.MaybeAddResult(Result("long", Rank));
802 Results.MaybeAddResult(Result("signed", Rank));
803 Results.MaybeAddResult(Result("unsigned", Rank));
804 Results.MaybeAddResult(Result("void", Rank));
805 Results.MaybeAddResult(Result("char", Rank));
806 Results.MaybeAddResult(Result("int", Rank));
807 Results.MaybeAddResult(Result("float", Rank));
808 Results.MaybeAddResult(Result("double", Rank));
809 Results.MaybeAddResult(Result("enum", Rank));
810 Results.MaybeAddResult(Result("struct", Rank));
811 Results.MaybeAddResult(Result("union", Rank));
Douglas Gregor01dfea02010-01-10 23:08:15 +0000812 Results.MaybeAddResult(Result("const", Rank));
813 Results.MaybeAddResult(Result("volatile", Rank));
814
Douglas Gregor86d9a522009-09-21 16:56:56 +0000815 if (LangOpts.C99) {
816 // C99-specific
817 Results.MaybeAddResult(Result("_Complex", Rank));
818 Results.MaybeAddResult(Result("_Imaginary", Rank));
819 Results.MaybeAddResult(Result("_Bool", Rank));
Douglas Gregor01dfea02010-01-10 23:08:15 +0000820 Results.MaybeAddResult(Result("restrict", Rank));
Douglas Gregor86d9a522009-09-21 16:56:56 +0000821 }
822
823 if (LangOpts.CPlusPlus) {
824 // C++-specific
825 Results.MaybeAddResult(Result("bool", Rank));
826 Results.MaybeAddResult(Result("class", Rank));
Douglas Gregor86d9a522009-09-21 16:56:56 +0000827 Results.MaybeAddResult(Result("wchar_t", Rank));
828
Douglas Gregor01dfea02010-01-10 23:08:15 +0000829 // typename qualified-id
830 CodeCompletionString *Pattern = new CodeCompletionString;
831 Pattern->AddTypedTextChunk("typename");
832 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
833 Pattern->AddPlaceholderChunk("qualified-id");
834 Results.MaybeAddResult(Result(Pattern, Rank));
835
Douglas Gregor86d9a522009-09-21 16:56:56 +0000836 if (LangOpts.CPlusPlus0x) {
Douglas Gregor01dfea02010-01-10 23:08:15 +0000837 Results.MaybeAddResult(Result("auto", Rank));
Douglas Gregor86d9a522009-09-21 16:56:56 +0000838 Results.MaybeAddResult(Result("char16_t", Rank));
839 Results.MaybeAddResult(Result("char32_t", Rank));
840 Results.MaybeAddResult(Result("decltype", Rank));
841 }
842 }
843
844 // GNU extensions
845 if (LangOpts.GNUMode) {
846 // FIXME: Enable when we actually support decimal floating point.
847 // Results.MaybeAddResult(Result("_Decimal32", Rank));
848 // Results.MaybeAddResult(Result("_Decimal64", Rank));
849 // Results.MaybeAddResult(Result("_Decimal128", Rank));
Douglas Gregor01dfea02010-01-10 23:08:15 +0000850
851 CodeCompletionString *Pattern = new CodeCompletionString;
852 Pattern->AddTypedTextChunk("typeof");
853 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
854 Pattern->AddPlaceholderChunk("expression-or-type");
855 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
856 Results.MaybeAddResult(Result(Pattern, Rank));
Douglas Gregor86d9a522009-09-21 16:56:56 +0000857 }
858}
859
Douglas Gregor01dfea02010-01-10 23:08:15 +0000860static void AddStorageSpecifiers(Action::CodeCompletionContext CCC,
861 const LangOptions &LangOpts,
862 unsigned Rank,
863 ResultBuilder &Results) {
864 typedef CodeCompleteConsumer::Result Result;
865 // Note: we don't suggest either "auto" or "register", because both
866 // are pointless as storage specifiers. Elsewhere, we suggest "auto"
867 // in C++0x as a type specifier.
868 Results.MaybeAddResult(Result("extern", Rank));
869 Results.MaybeAddResult(Result("static", Rank));
870}
871
872static void AddFunctionSpecifiers(Action::CodeCompletionContext CCC,
873 const LangOptions &LangOpts,
874 unsigned Rank,
875 ResultBuilder &Results) {
876 typedef CodeCompleteConsumer::Result Result;
877 switch (CCC) {
878 case Action::CCC_Class:
879 case Action::CCC_MemberTemplate:
880 if (LangOpts.CPlusPlus) {
881 Results.MaybeAddResult(Result("explicit", Rank));
882 Results.MaybeAddResult(Result("friend", Rank));
883 Results.MaybeAddResult(Result("mutable", Rank));
884 Results.MaybeAddResult(Result("virtual", Rank));
885 }
886 // Fall through
887
Douglas Gregorb6ac2452010-01-13 21:24:21 +0000888 case Action::CCC_ObjCInterface:
889 case Action::CCC_ObjCImplementation:
Douglas Gregor01dfea02010-01-10 23:08:15 +0000890 case Action::CCC_Namespace:
891 case Action::CCC_Template:
892 if (LangOpts.CPlusPlus || LangOpts.C99)
893 Results.MaybeAddResult(Result("inline", Rank));
894 break;
895
Douglas Gregorc38c3e12010-01-13 21:54:15 +0000896 case Action::CCC_ObjCInstanceVariableList:
Douglas Gregor01dfea02010-01-10 23:08:15 +0000897 case Action::CCC_Expression:
898 case Action::CCC_Statement:
899 case Action::CCC_ForInit:
900 case Action::CCC_Condition:
901 break;
902 }
903}
904
Douglas Gregorb6ac2452010-01-13 21:24:21 +0000905static void AddObjCExpressionResults(unsigned Rank, ResultBuilder &Results,
906 bool NeedAt);
907static void AddObjCStatementResults(unsigned Rank, ResultBuilder &Results,
908 bool NeedAt);
Douglas Gregorc38c3e12010-01-13 21:54:15 +0000909static void AddObjCVisibilityResults(unsigned Rank,
910 const LangOptions &LangOpts,
911 ResultBuilder &Results,
912 bool NeedAt);
Douglas Gregorb6ac2452010-01-13 21:24:21 +0000913static void AddObjCImplementationResults(unsigned Rank,
914 const LangOptions &LangOpts,
915 ResultBuilder &Results,
916 bool NeedAt);
917static void AddObjCInterfaceResults(unsigned Rank,
918 const LangOptions &LangOpts,
919 ResultBuilder &Results,
920 bool NeedAt);
921static void AddObjCTopLevelResults(unsigned Rank, ResultBuilder &Results,
922 bool NeedAt);
923
Douglas Gregor01dfea02010-01-10 23:08:15 +0000924/// \brief Add language constructs that show up for "ordinary" names.
925static void AddOrdinaryNameResults(Action::CodeCompletionContext CCC,
926 Scope *S,
927 Sema &SemaRef,
928 unsigned Rank,
929 ResultBuilder &Results) {
930 typedef CodeCompleteConsumer::Result Result;
931 switch (CCC) {
932 case Action::CCC_Namespace:
933 if (SemaRef.getLangOptions().CPlusPlus) {
934 // namespace <identifier> { }
935 CodeCompletionString *Pattern = new CodeCompletionString;
936 Pattern->AddTypedTextChunk("namespace");
937 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
938 Pattern->AddPlaceholderChunk("identifier");
939 Pattern->AddChunk(CodeCompletionString::CK_LeftBrace);
940 Pattern->AddPlaceholderChunk("declarations");
941 Pattern->AddChunk(CodeCompletionString::CK_VerticalSpace);
942 Pattern->AddChunk(CodeCompletionString::CK_RightBrace);
943 Results.MaybeAddResult(Result(Pattern, Rank));
944
945 // namespace identifier = identifier ;
946 Pattern = new CodeCompletionString;
947 Pattern->AddTypedTextChunk("namespace");
948 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
949 Pattern->AddPlaceholderChunk("identifier");
950 Pattern->AddChunk(CodeCompletionString::CK_Equal);
951 Pattern->AddPlaceholderChunk("identifier");
952 Pattern->AddChunk(CodeCompletionString::CK_SemiColon);
953 Results.MaybeAddResult(Result(Pattern, Rank));
954
955 // Using directives
956 Pattern = new CodeCompletionString;
957 Pattern->AddTypedTextChunk("using");
958 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
959 Pattern->AddTextChunk("namespace");
960 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
961 Pattern->AddPlaceholderChunk("identifier");
962 Pattern->AddChunk(CodeCompletionString::CK_SemiColon);
963 Results.MaybeAddResult(Result(Pattern, Rank));
964
965 // asm(string-literal)
966 Pattern = new CodeCompletionString;
967 Pattern->AddTypedTextChunk("asm");
968 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
969 Pattern->AddPlaceholderChunk("string-literal");
970 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
971 Pattern->AddChunk(CodeCompletionString::CK_SemiColon);
972 Results.MaybeAddResult(Result(Pattern, Rank));
973
974 // Explicit template instantiation
975 Pattern = new CodeCompletionString;
976 Pattern->AddTypedTextChunk("template");
977 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
978 Pattern->AddPlaceholderChunk("declaration");
979 Pattern->AddChunk(CodeCompletionString::CK_SemiColon);
980 Results.MaybeAddResult(Result(Pattern, Rank));
981 }
Douglas Gregorb6ac2452010-01-13 21:24:21 +0000982
983 if (SemaRef.getLangOptions().ObjC1)
984 AddObjCTopLevelResults(Rank, Results, true);
985
Douglas Gregor01dfea02010-01-10 23:08:15 +0000986 // Fall through
987
988 case Action::CCC_Class:
989 Results.MaybeAddResult(Result("typedef", Rank));
990 if (SemaRef.getLangOptions().CPlusPlus) {
991 // Using declaration
992 CodeCompletionString *Pattern = new CodeCompletionString;
993 Pattern->AddTypedTextChunk("using");
994 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
995 Pattern->AddPlaceholderChunk("qualified-id");
996 Pattern->AddChunk(CodeCompletionString::CK_SemiColon);
997 Results.MaybeAddResult(Result(Pattern, Rank));
998
999 // using typename qualified-id; (only in a dependent context)
1000 if (SemaRef.CurContext->isDependentContext()) {
1001 Pattern = new CodeCompletionString;
1002 Pattern->AddTypedTextChunk("using");
1003 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
1004 Pattern->AddTextChunk("typename");
1005 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
1006 Pattern->AddPlaceholderChunk("qualified-id");
1007 Pattern->AddChunk(CodeCompletionString::CK_SemiColon);
1008 Results.MaybeAddResult(Result(Pattern, Rank));
1009 }
1010
1011 if (CCC == Action::CCC_Class) {
1012 // public:
1013 Pattern = new CodeCompletionString;
1014 Pattern->AddTypedTextChunk("public");
1015 Pattern->AddChunk(CodeCompletionString::CK_Colon);
1016 Results.MaybeAddResult(Result(Pattern, Rank));
1017
1018 // protected:
1019 Pattern = new CodeCompletionString;
1020 Pattern->AddTypedTextChunk("protected");
1021 Pattern->AddChunk(CodeCompletionString::CK_Colon);
1022 Results.MaybeAddResult(Result(Pattern, Rank));
1023
1024 // private:
1025 Pattern = new CodeCompletionString;
1026 Pattern->AddTypedTextChunk("private");
1027 Pattern->AddChunk(CodeCompletionString::CK_Colon);
1028 Results.MaybeAddResult(Result(Pattern, Rank));
1029 }
1030 }
1031 // Fall through
1032
1033 case Action::CCC_Template:
1034 case Action::CCC_MemberTemplate:
1035 if (SemaRef.getLangOptions().CPlusPlus) {
1036 // template < parameters >
1037 CodeCompletionString *Pattern = new CodeCompletionString;
1038 Pattern->AddTypedTextChunk("template");
1039 Pattern->AddChunk(CodeCompletionString::CK_LeftAngle);
1040 Pattern->AddPlaceholderChunk("parameters");
1041 Pattern->AddChunk(CodeCompletionString::CK_RightAngle);
1042 Results.MaybeAddResult(Result(Pattern, Rank));
1043 }
1044
1045 AddStorageSpecifiers(CCC, SemaRef.getLangOptions(), Rank, Results);
1046 AddFunctionSpecifiers(CCC, SemaRef.getLangOptions(), Rank, Results);
1047 break;
1048
Douglas Gregorb6ac2452010-01-13 21:24:21 +00001049 case Action::CCC_ObjCInterface:
1050 AddObjCInterfaceResults(Rank, SemaRef.getLangOptions(), Results, true);
1051 AddStorageSpecifiers(CCC, SemaRef.getLangOptions(), Rank, Results);
1052 AddFunctionSpecifiers(CCC, SemaRef.getLangOptions(), Rank, Results);
1053 break;
1054
1055 case Action::CCC_ObjCImplementation:
1056 AddObjCImplementationResults(Rank, SemaRef.getLangOptions(), Results, true);
1057 AddStorageSpecifiers(CCC, SemaRef.getLangOptions(), Rank, Results);
1058 AddFunctionSpecifiers(CCC, SemaRef.getLangOptions(), Rank, Results);
1059 break;
1060
Douglas Gregorc38c3e12010-01-13 21:54:15 +00001061 case Action::CCC_ObjCInstanceVariableList:
1062 AddObjCVisibilityResults(Rank, SemaRef.getLangOptions(), Results, true);
1063 break;
1064
Douglas Gregor01dfea02010-01-10 23:08:15 +00001065 case Action::CCC_Statement: {
1066 Results.MaybeAddResult(Result("typedef", Rank));
1067
1068 CodeCompletionString *Pattern = 0;
1069 if (SemaRef.getLangOptions().CPlusPlus) {
1070 Pattern = new CodeCompletionString;
1071 Pattern->AddTypedTextChunk("try");
1072 Pattern->AddChunk(CodeCompletionString::CK_LeftBrace);
1073 Pattern->AddPlaceholderChunk("statements");
1074 Pattern->AddChunk(CodeCompletionString::CK_VerticalSpace);
1075 Pattern->AddChunk(CodeCompletionString::CK_RightBrace);
1076 Pattern->AddTextChunk("catch");
1077 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
1078 Pattern->AddPlaceholderChunk("declaration");
1079 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
1080 Pattern->AddChunk(CodeCompletionString::CK_LeftBrace);
1081 Pattern->AddPlaceholderChunk("statements");
1082 Pattern->AddChunk(CodeCompletionString::CK_VerticalSpace);
1083 Pattern->AddChunk(CodeCompletionString::CK_RightBrace);
1084 Results.MaybeAddResult(Result(Pattern, Rank));
1085 }
Douglas Gregorb6ac2452010-01-13 21:24:21 +00001086 if (SemaRef.getLangOptions().ObjC1)
1087 AddObjCStatementResults(Rank, Results, true);
1088
Douglas Gregor01dfea02010-01-10 23:08:15 +00001089 // if (condition) { statements }
1090 Pattern = new CodeCompletionString;
1091 Pattern->AddTypedTextChunk("if");
1092 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
1093 if (SemaRef.getLangOptions().CPlusPlus)
1094 Pattern->AddPlaceholderChunk("condition");
1095 else
1096 Pattern->AddPlaceholderChunk("expression");
1097 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
1098 Pattern->AddChunk(CodeCompletionString::CK_LeftBrace);
1099 Pattern->AddPlaceholderChunk("statements");
1100 Pattern->AddChunk(CodeCompletionString::CK_VerticalSpace);
1101 Pattern->AddChunk(CodeCompletionString::CK_RightBrace);
1102 Results.MaybeAddResult(Result(Pattern, Rank));
1103
1104 // switch (condition) { }
1105 Pattern = new CodeCompletionString;
1106 Pattern->AddTypedTextChunk("switch");
1107 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
1108 if (SemaRef.getLangOptions().CPlusPlus)
1109 Pattern->AddPlaceholderChunk("condition");
1110 else
1111 Pattern->AddPlaceholderChunk("expression");
1112 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
1113 Pattern->AddChunk(CodeCompletionString::CK_LeftBrace);
1114 Pattern->AddChunk(CodeCompletionString::CK_VerticalSpace);
1115 Pattern->AddChunk(CodeCompletionString::CK_RightBrace);
1116 Results.MaybeAddResult(Result(Pattern, Rank));
1117
1118 // Switch-specific statements.
1119 if (!SemaRef.getSwitchStack().empty()) {
1120 // case expression:
1121 Pattern = new CodeCompletionString;
1122 Pattern->AddTypedTextChunk("case");
1123 Pattern->AddPlaceholderChunk("expression");
1124 Pattern->AddChunk(CodeCompletionString::CK_Colon);
1125 Results.MaybeAddResult(Result(Pattern, Rank));
1126
1127 // default:
1128 Pattern = new CodeCompletionString;
1129 Pattern->AddTypedTextChunk("default");
1130 Pattern->AddChunk(CodeCompletionString::CK_Colon);
1131 Results.MaybeAddResult(Result(Pattern, Rank));
1132 }
1133
1134 /// while (condition) { statements }
1135 Pattern = new CodeCompletionString;
1136 Pattern->AddTypedTextChunk("while");
1137 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
1138 if (SemaRef.getLangOptions().CPlusPlus)
1139 Pattern->AddPlaceholderChunk("condition");
1140 else
1141 Pattern->AddPlaceholderChunk("expression");
1142 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
1143 Pattern->AddChunk(CodeCompletionString::CK_LeftBrace);
1144 Pattern->AddPlaceholderChunk("statements");
1145 Pattern->AddChunk(CodeCompletionString::CK_VerticalSpace);
1146 Pattern->AddChunk(CodeCompletionString::CK_RightBrace);
1147 Results.MaybeAddResult(Result(Pattern, Rank));
1148
1149 // do { statements } while ( expression );
1150 Pattern = new CodeCompletionString;
1151 Pattern->AddTypedTextChunk("do");
1152 Pattern->AddChunk(CodeCompletionString::CK_LeftBrace);
1153 Pattern->AddPlaceholderChunk("statements");
1154 Pattern->AddChunk(CodeCompletionString::CK_VerticalSpace);
1155 Pattern->AddChunk(CodeCompletionString::CK_RightBrace);
1156 Pattern->AddTextChunk("while");
1157 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
1158 Pattern->AddPlaceholderChunk("expression");
1159 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
1160 Pattern->AddChunk(CodeCompletionString::CK_SemiColon);
1161 Results.MaybeAddResult(Result(Pattern, Rank));
1162
1163 // for ( for-init-statement ; condition ; expression ) { statements }
1164 Pattern = new CodeCompletionString;
1165 Pattern->AddTypedTextChunk("for");
1166 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
1167 if (SemaRef.getLangOptions().CPlusPlus || SemaRef.getLangOptions().C99)
1168 Pattern->AddPlaceholderChunk("init-statement");
1169 else
1170 Pattern->AddPlaceholderChunk("init-expression");
1171 Pattern->AddChunk(CodeCompletionString::CK_SemiColon);
1172 Pattern->AddPlaceholderChunk("condition");
1173 Pattern->AddChunk(CodeCompletionString::CK_SemiColon);
1174 Pattern->AddPlaceholderChunk("inc-expression");
1175 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
1176 Pattern->AddChunk(CodeCompletionString::CK_LeftBrace);
1177 Pattern->AddPlaceholderChunk("statements");
1178 Pattern->AddChunk(CodeCompletionString::CK_VerticalSpace);
1179 Pattern->AddChunk(CodeCompletionString::CK_RightBrace);
1180 Results.MaybeAddResult(Result(Pattern, Rank));
1181
1182 if (S->getContinueParent()) {
1183 // continue ;
1184 Pattern = new CodeCompletionString;
1185 Pattern->AddTypedTextChunk("continue");
1186 Pattern->AddChunk(CodeCompletionString::CK_SemiColon);
1187 Results.MaybeAddResult(Result(Pattern, Rank));
1188 }
1189
1190 if (S->getBreakParent()) {
1191 // break ;
1192 Pattern = new CodeCompletionString;
1193 Pattern->AddTypedTextChunk("break");
1194 Pattern->AddChunk(CodeCompletionString::CK_SemiColon);
1195 Results.MaybeAddResult(Result(Pattern, Rank));
1196 }
1197
1198 // "return expression ;" or "return ;", depending on whether we
1199 // know the function is void or not.
1200 bool isVoid = false;
1201 if (FunctionDecl *Function = dyn_cast<FunctionDecl>(SemaRef.CurContext))
1202 isVoid = Function->getResultType()->isVoidType();
1203 else if (ObjCMethodDecl *Method
1204 = dyn_cast<ObjCMethodDecl>(SemaRef.CurContext))
1205 isVoid = Method->getResultType()->isVoidType();
1206 else if (SemaRef.CurBlock && !SemaRef.CurBlock->ReturnType.isNull())
1207 isVoid = SemaRef.CurBlock->ReturnType->isVoidType();
1208 Pattern = new CodeCompletionString;
1209 Pattern->AddTypedTextChunk("return");
1210 if (!isVoid)
1211 Pattern->AddPlaceholderChunk("expression");
1212 Pattern->AddChunk(CodeCompletionString::CK_SemiColon);
1213 Results.MaybeAddResult(Result(Pattern, Rank));
1214
1215 // goto identifier ;
1216 Pattern = new CodeCompletionString;
1217 Pattern->AddTypedTextChunk("goto");
1218 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
1219 Pattern->AddPlaceholderChunk("identifier");
1220 Pattern->AddChunk(CodeCompletionString::CK_SemiColon);
1221 Results.MaybeAddResult(Result(Pattern, Rank));
1222
1223 // Using directives
1224 Pattern = new CodeCompletionString;
1225 Pattern->AddTypedTextChunk("using");
1226 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
1227 Pattern->AddTextChunk("namespace");
1228 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
1229 Pattern->AddPlaceholderChunk("identifier");
1230 Pattern->AddChunk(CodeCompletionString::CK_SemiColon);
1231 Results.MaybeAddResult(Result(Pattern, Rank));
1232 }
1233
1234 // Fall through (for statement expressions).
1235 case Action::CCC_ForInit:
1236 case Action::CCC_Condition:
1237 AddStorageSpecifiers(CCC, SemaRef.getLangOptions(), Rank, Results);
1238 // Fall through: conditions and statements can have expressions.
1239
1240 case Action::CCC_Expression: {
1241 CodeCompletionString *Pattern = 0;
1242 if (SemaRef.getLangOptions().CPlusPlus) {
1243 // 'this', if we're in a non-static member function.
1244 if (CXXMethodDecl *Method = dyn_cast<CXXMethodDecl>(SemaRef.CurContext))
1245 if (!Method->isStatic())
1246 Results.MaybeAddResult(Result("this", Rank));
1247
1248 // true, false
1249 Results.MaybeAddResult(Result("true", Rank));
1250 Results.MaybeAddResult(Result("false", Rank));
1251
1252 // dynamic_cast < type-id > ( expression )
1253 Pattern = new CodeCompletionString;
1254 Pattern->AddTypedTextChunk("dynamic_cast");
1255 Pattern->AddChunk(CodeCompletionString::CK_LeftAngle);
1256 Pattern->AddPlaceholderChunk("type-id");
1257 Pattern->AddChunk(CodeCompletionString::CK_RightAngle);
1258 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
1259 Pattern->AddPlaceholderChunk("expression");
1260 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
1261 Results.MaybeAddResult(Result(Pattern, Rank));
1262
1263 // static_cast < type-id > ( expression )
1264 Pattern = new CodeCompletionString;
1265 Pattern->AddTypedTextChunk("static_cast");
1266 Pattern->AddChunk(CodeCompletionString::CK_LeftAngle);
1267 Pattern->AddPlaceholderChunk("type-id");
1268 Pattern->AddChunk(CodeCompletionString::CK_RightAngle);
1269 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
1270 Pattern->AddPlaceholderChunk("expression");
1271 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
1272 Results.MaybeAddResult(Result(Pattern, Rank));
1273
1274 // reinterpret_cast < type-id > ( expression )
1275 Pattern = new CodeCompletionString;
1276 Pattern->AddTypedTextChunk("reinterpret_cast");
1277 Pattern->AddChunk(CodeCompletionString::CK_LeftAngle);
1278 Pattern->AddPlaceholderChunk("type-id");
1279 Pattern->AddChunk(CodeCompletionString::CK_RightAngle);
1280 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
1281 Pattern->AddPlaceholderChunk("expression");
1282 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
1283 Results.MaybeAddResult(Result(Pattern, Rank));
1284
1285 // const_cast < type-id > ( expression )
1286 Pattern = new CodeCompletionString;
1287 Pattern->AddTypedTextChunk("const_cast");
1288 Pattern->AddChunk(CodeCompletionString::CK_LeftAngle);
1289 Pattern->AddPlaceholderChunk("type-id");
1290 Pattern->AddChunk(CodeCompletionString::CK_RightAngle);
1291 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
1292 Pattern->AddPlaceholderChunk("expression");
1293 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
1294 Results.MaybeAddResult(Result(Pattern, Rank));
1295
1296 // typeid ( expression-or-type )
1297 Pattern = new CodeCompletionString;
1298 Pattern->AddTypedTextChunk("typeid");
1299 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
1300 Pattern->AddPlaceholderChunk("expression-or-type");
1301 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
1302 Results.MaybeAddResult(Result(Pattern, Rank));
1303
1304 // new T ( ... )
1305 Pattern = new CodeCompletionString;
1306 Pattern->AddTypedTextChunk("new");
1307 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
1308 Pattern->AddPlaceholderChunk("type-id");
1309 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
1310 Pattern->AddPlaceholderChunk("expressions");
1311 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
1312 Results.MaybeAddResult(Result(Pattern, Rank));
1313
1314 // new T [ ] ( ... )
1315 Pattern = new CodeCompletionString;
1316 Pattern->AddTypedTextChunk("new");
1317 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
1318 Pattern->AddPlaceholderChunk("type-id");
1319 Pattern->AddChunk(CodeCompletionString::CK_LeftBracket);
1320 Pattern->AddPlaceholderChunk("size");
1321 Pattern->AddChunk(CodeCompletionString::CK_RightBracket);
1322 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
1323 Pattern->AddPlaceholderChunk("expressions");
1324 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
1325 Results.MaybeAddResult(Result(Pattern, Rank));
1326
1327 // delete expression
1328 Pattern = new CodeCompletionString;
1329 Pattern->AddTypedTextChunk("delete");
1330 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
1331 Pattern->AddPlaceholderChunk("expression");
1332 Results.MaybeAddResult(Result(Pattern, Rank));
1333
1334 // delete [] expression
1335 Pattern = new CodeCompletionString;
1336 Pattern->AddTypedTextChunk("delete");
1337 Pattern->AddChunk(CodeCompletionString::CK_LeftBracket);
1338 Pattern->AddChunk(CodeCompletionString::CK_RightBracket);
1339 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
1340 Pattern->AddPlaceholderChunk("expression");
1341 Results.MaybeAddResult(Result(Pattern, Rank));
1342
1343 // throw expression
1344 Pattern = new CodeCompletionString;
1345 Pattern->AddTypedTextChunk("throw");
1346 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
1347 Pattern->AddPlaceholderChunk("expression");
1348 Results.MaybeAddResult(Result(Pattern, Rank));
1349 }
1350
1351 if (SemaRef.getLangOptions().ObjC1) {
1352 // Add "super", if we're in an Objective-C class with a superclass.
1353 if (ObjCMethodDecl *Method = SemaRef.getCurMethodDecl())
1354 if (Method->getClassInterface()->getSuperClass())
1355 Results.MaybeAddResult(Result("super", Rank));
Douglas Gregorb6ac2452010-01-13 21:24:21 +00001356
1357 AddObjCExpressionResults(Rank, Results, true);
Douglas Gregor01dfea02010-01-10 23:08:15 +00001358 }
1359
1360 // sizeof expression
1361 Pattern = new CodeCompletionString;
1362 Pattern->AddTypedTextChunk("sizeof");
1363 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
1364 Pattern->AddPlaceholderChunk("expression-or-type");
1365 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
1366 Results.MaybeAddResult(Result(Pattern, Rank));
1367 break;
1368 }
1369 }
1370
1371 AddTypeSpecifierResults(SemaRef.getLangOptions(), Rank, Results);
1372
1373 if (SemaRef.getLangOptions().CPlusPlus)
1374 Results.MaybeAddResult(Result("operator", Rank));
1375}
1376
Douglas Gregorff5ce6e2009-12-18 18:53:37 +00001377/// \brief If the given declaration has an associated type, add it as a result
1378/// type chunk.
1379static void AddResultTypeChunk(ASTContext &Context,
1380 NamedDecl *ND,
1381 CodeCompletionString *Result) {
1382 if (!ND)
1383 return;
1384
1385 // Determine the type of the declaration (if it has a type).
1386 QualType T;
1387 if (FunctionDecl *Function = dyn_cast<FunctionDecl>(ND))
1388 T = Function->getResultType();
1389 else if (ObjCMethodDecl *Method = dyn_cast<ObjCMethodDecl>(ND))
1390 T = Method->getResultType();
1391 else if (FunctionTemplateDecl *FunTmpl = dyn_cast<FunctionTemplateDecl>(ND))
1392 T = FunTmpl->getTemplatedDecl()->getResultType();
1393 else if (EnumConstantDecl *Enumerator = dyn_cast<EnumConstantDecl>(ND))
1394 T = Context.getTypeDeclType(cast<TypeDecl>(Enumerator->getDeclContext()));
1395 else if (isa<UnresolvedUsingValueDecl>(ND)) {
1396 /* Do nothing: ignore unresolved using declarations*/
1397 } else if (ValueDecl *Value = dyn_cast<ValueDecl>(ND))
1398 T = Value->getType();
1399 else if (ObjCPropertyDecl *Property = dyn_cast<ObjCPropertyDecl>(ND))
1400 T = Property->getType();
1401
1402 if (T.isNull() || Context.hasSameType(T, Context.DependentTy))
1403 return;
1404
1405 std::string TypeStr;
1406 T.getAsStringInternal(TypeStr, Context.PrintingPolicy);
1407 Result->AddResultTypeChunk(TypeStr);
1408}
1409
Douglas Gregor86d9a522009-09-21 16:56:56 +00001410/// \brief Add function parameter chunks to the given code completion string.
1411static void AddFunctionParameterChunks(ASTContext &Context,
1412 FunctionDecl *Function,
1413 CodeCompletionString *Result) {
Douglas Gregor0c8296d2009-11-07 00:00:49 +00001414 typedef CodeCompletionString::Chunk Chunk;
1415
Douglas Gregor86d9a522009-09-21 16:56:56 +00001416 CodeCompletionString *CCStr = Result;
1417
1418 for (unsigned P = 0, N = Function->getNumParams(); P != N; ++P) {
1419 ParmVarDecl *Param = Function->getParamDecl(P);
1420
1421 if (Param->hasDefaultArg()) {
1422 // When we see an optional default argument, put that argument and
1423 // the remaining default arguments into a new, optional string.
1424 CodeCompletionString *Opt = new CodeCompletionString;
1425 CCStr->AddOptionalChunk(std::auto_ptr<CodeCompletionString>(Opt));
1426 CCStr = Opt;
1427 }
1428
1429 if (P != 0)
Douglas Gregor0c8296d2009-11-07 00:00:49 +00001430 CCStr->AddChunk(Chunk(CodeCompletionString::CK_Comma));
Douglas Gregor86d9a522009-09-21 16:56:56 +00001431
1432 // Format the placeholder string.
1433 std::string PlaceholderStr;
1434 if (Param->getIdentifier())
1435 PlaceholderStr = Param->getIdentifier()->getName();
1436
1437 Param->getType().getAsStringInternal(PlaceholderStr,
1438 Context.PrintingPolicy);
1439
1440 // Add the placeholder string.
Benjamin Kramer660cc182009-11-29 20:18:50 +00001441 CCStr->AddPlaceholderChunk(PlaceholderStr);
Douglas Gregor86d9a522009-09-21 16:56:56 +00001442 }
Douglas Gregorb3d45252009-09-22 21:42:17 +00001443
1444 if (const FunctionProtoType *Proto
1445 = Function->getType()->getAs<FunctionProtoType>())
1446 if (Proto->isVariadic())
1447 CCStr->AddPlaceholderChunk(", ...");
Douglas Gregor86d9a522009-09-21 16:56:56 +00001448}
1449
1450/// \brief Add template parameter chunks to the given code completion string.
1451static void AddTemplateParameterChunks(ASTContext &Context,
1452 TemplateDecl *Template,
1453 CodeCompletionString *Result,
1454 unsigned MaxParameters = 0) {
Douglas Gregor0c8296d2009-11-07 00:00:49 +00001455 typedef CodeCompletionString::Chunk Chunk;
1456
Douglas Gregor86d9a522009-09-21 16:56:56 +00001457 CodeCompletionString *CCStr = Result;
1458 bool FirstParameter = true;
1459
1460 TemplateParameterList *Params = Template->getTemplateParameters();
1461 TemplateParameterList::iterator PEnd = Params->end();
1462 if (MaxParameters)
1463 PEnd = Params->begin() + MaxParameters;
1464 for (TemplateParameterList::iterator P = Params->begin(); P != PEnd; ++P) {
1465 bool HasDefaultArg = false;
1466 std::string PlaceholderStr;
1467 if (TemplateTypeParmDecl *TTP = dyn_cast<TemplateTypeParmDecl>(*P)) {
1468 if (TTP->wasDeclaredWithTypename())
1469 PlaceholderStr = "typename";
1470 else
1471 PlaceholderStr = "class";
1472
1473 if (TTP->getIdentifier()) {
1474 PlaceholderStr += ' ';
1475 PlaceholderStr += TTP->getIdentifier()->getName();
1476 }
1477
1478 HasDefaultArg = TTP->hasDefaultArgument();
1479 } else if (NonTypeTemplateParmDecl *NTTP
1480 = dyn_cast<NonTypeTemplateParmDecl>(*P)) {
1481 if (NTTP->getIdentifier())
1482 PlaceholderStr = NTTP->getIdentifier()->getName();
1483 NTTP->getType().getAsStringInternal(PlaceholderStr,
1484 Context.PrintingPolicy);
1485 HasDefaultArg = NTTP->hasDefaultArgument();
1486 } else {
1487 assert(isa<TemplateTemplateParmDecl>(*P));
1488 TemplateTemplateParmDecl *TTP = cast<TemplateTemplateParmDecl>(*P);
1489
1490 // Since putting the template argument list into the placeholder would
1491 // be very, very long, we just use an abbreviation.
1492 PlaceholderStr = "template<...> class";
1493 if (TTP->getIdentifier()) {
1494 PlaceholderStr += ' ';
1495 PlaceholderStr += TTP->getIdentifier()->getName();
1496 }
1497
1498 HasDefaultArg = TTP->hasDefaultArgument();
1499 }
1500
1501 if (HasDefaultArg) {
1502 // When we see an optional default argument, put that argument and
1503 // the remaining default arguments into a new, optional string.
1504 CodeCompletionString *Opt = new CodeCompletionString;
1505 CCStr->AddOptionalChunk(std::auto_ptr<CodeCompletionString>(Opt));
1506 CCStr = Opt;
1507 }
1508
1509 if (FirstParameter)
1510 FirstParameter = false;
1511 else
Douglas Gregor0c8296d2009-11-07 00:00:49 +00001512 CCStr->AddChunk(Chunk(CodeCompletionString::CK_Comma));
Douglas Gregor86d9a522009-09-21 16:56:56 +00001513
1514 // Add the placeholder string.
Benjamin Kramer660cc182009-11-29 20:18:50 +00001515 CCStr->AddPlaceholderChunk(PlaceholderStr);
Douglas Gregor86d9a522009-09-21 16:56:56 +00001516 }
1517}
1518
Douglas Gregorb9d0ef72009-09-21 19:57:38 +00001519/// \brief Add a qualifier to the given code-completion string, if the
1520/// provided nested-name-specifier is non-NULL.
Douglas Gregora61a8792009-12-11 18:44:16 +00001521static void
1522AddQualifierToCompletionString(CodeCompletionString *Result,
1523 NestedNameSpecifier *Qualifier,
1524 bool QualifierIsInformative,
1525 ASTContext &Context) {
Douglas Gregorb9d0ef72009-09-21 19:57:38 +00001526 if (!Qualifier)
1527 return;
1528
1529 std::string PrintedNNS;
1530 {
1531 llvm::raw_string_ostream OS(PrintedNNS);
1532 Qualifier->print(OS, Context.PrintingPolicy);
1533 }
Douglas Gregor0563c262009-09-22 23:15:58 +00001534 if (QualifierIsInformative)
Benjamin Kramer660cc182009-11-29 20:18:50 +00001535 Result->AddInformativeChunk(PrintedNNS);
Douglas Gregor0563c262009-09-22 23:15:58 +00001536 else
Benjamin Kramer660cc182009-11-29 20:18:50 +00001537 Result->AddTextChunk(PrintedNNS);
Douglas Gregorb9d0ef72009-09-21 19:57:38 +00001538}
1539
Douglas Gregora61a8792009-12-11 18:44:16 +00001540static void AddFunctionTypeQualsToCompletionString(CodeCompletionString *Result,
1541 FunctionDecl *Function) {
1542 const FunctionProtoType *Proto
1543 = Function->getType()->getAs<FunctionProtoType>();
1544 if (!Proto || !Proto->getTypeQuals())
1545 return;
1546
1547 std::string QualsStr;
1548 if (Proto->getTypeQuals() & Qualifiers::Const)
1549 QualsStr += " const";
1550 if (Proto->getTypeQuals() & Qualifiers::Volatile)
1551 QualsStr += " volatile";
1552 if (Proto->getTypeQuals() & Qualifiers::Restrict)
1553 QualsStr += " restrict";
1554 Result->AddInformativeChunk(QualsStr);
1555}
1556
Douglas Gregor86d9a522009-09-21 16:56:56 +00001557/// \brief If possible, create a new code completion string for the given
1558/// result.
1559///
1560/// \returns Either a new, heap-allocated code completion string describing
1561/// how to use this result, or NULL to indicate that the string or name of the
1562/// result is all that is needed.
1563CodeCompletionString *
1564CodeCompleteConsumer::Result::CreateCodeCompletionString(Sema &S) {
Douglas Gregor0c8296d2009-11-07 00:00:49 +00001565 typedef CodeCompletionString::Chunk Chunk;
1566
Douglas Gregor2b4074f2009-12-01 05:55:20 +00001567 if (Kind == RK_Pattern)
1568 return Pattern->Clone();
1569
1570 CodeCompletionString *Result = new CodeCompletionString;
1571
1572 if (Kind == RK_Keyword) {
1573 Result->AddTypedTextChunk(Keyword);
1574 return Result;
1575 }
Douglas Gregor86d9a522009-09-21 16:56:56 +00001576
Douglas Gregor3f7c7f42009-10-30 16:50:04 +00001577 if (Kind == RK_Macro) {
1578 MacroInfo *MI = S.PP.getMacroInfo(Macro);
Douglas Gregor2b4074f2009-12-01 05:55:20 +00001579 assert(MI && "Not a macro?");
1580
1581 Result->AddTypedTextChunk(Macro->getName());
1582
1583 if (!MI->isFunctionLike())
1584 return Result;
Douglas Gregor3f7c7f42009-10-30 16:50:04 +00001585
1586 // Format a function-like macro with placeholders for the arguments.
Douglas Gregor0c8296d2009-11-07 00:00:49 +00001587 Result->AddChunk(Chunk(CodeCompletionString::CK_LeftParen));
Douglas Gregor3f7c7f42009-10-30 16:50:04 +00001588 for (MacroInfo::arg_iterator A = MI->arg_begin(), AEnd = MI->arg_end();
1589 A != AEnd; ++A) {
1590 if (A != MI->arg_begin())
Douglas Gregor0c8296d2009-11-07 00:00:49 +00001591 Result->AddChunk(Chunk(CodeCompletionString::CK_Comma));
Douglas Gregor3f7c7f42009-10-30 16:50:04 +00001592
1593 if (!MI->isVariadic() || A != AEnd - 1) {
1594 // Non-variadic argument.
Benjamin Kramer660cc182009-11-29 20:18:50 +00001595 Result->AddPlaceholderChunk((*A)->getName());
Douglas Gregor3f7c7f42009-10-30 16:50:04 +00001596 continue;
1597 }
1598
1599 // Variadic argument; cope with the different between GNU and C99
1600 // variadic macros, providing a single placeholder for the rest of the
1601 // arguments.
1602 if ((*A)->isStr("__VA_ARGS__"))
1603 Result->AddPlaceholderChunk("...");
1604 else {
1605 std::string Arg = (*A)->getName();
1606 Arg += "...";
Benjamin Kramer660cc182009-11-29 20:18:50 +00001607 Result->AddPlaceholderChunk(Arg);
Douglas Gregor3f7c7f42009-10-30 16:50:04 +00001608 }
1609 }
Douglas Gregor0c8296d2009-11-07 00:00:49 +00001610 Result->AddChunk(Chunk(CodeCompletionString::CK_RightParen));
Douglas Gregor3f7c7f42009-10-30 16:50:04 +00001611 return Result;
1612 }
1613
1614 assert(Kind == RK_Declaration && "Missed a macro kind?");
Douglas Gregor86d9a522009-09-21 16:56:56 +00001615 NamedDecl *ND = Declaration;
1616
Douglas Gregor0c8296d2009-11-07 00:00:49 +00001617 if (StartsNestedNameSpecifier) {
Benjamin Kramer660cc182009-11-29 20:18:50 +00001618 Result->AddTypedTextChunk(ND->getNameAsString());
Douglas Gregor0c8296d2009-11-07 00:00:49 +00001619 Result->AddTextChunk("::");
1620 return Result;
1621 }
1622
Douglas Gregorff5ce6e2009-12-18 18:53:37 +00001623 AddResultTypeChunk(S.Context, ND, Result);
1624
Douglas Gregor86d9a522009-09-21 16:56:56 +00001625 if (FunctionDecl *Function = dyn_cast<FunctionDecl>(ND)) {
Douglas Gregor0563c262009-09-22 23:15:58 +00001626 AddQualifierToCompletionString(Result, Qualifier, QualifierIsInformative,
1627 S.Context);
Benjamin Kramer660cc182009-11-29 20:18:50 +00001628 Result->AddTypedTextChunk(Function->getNameAsString());
Douglas Gregor0c8296d2009-11-07 00:00:49 +00001629 Result->AddChunk(Chunk(CodeCompletionString::CK_LeftParen));
Douglas Gregor86d9a522009-09-21 16:56:56 +00001630 AddFunctionParameterChunks(S.Context, Function, Result);
Douglas Gregor0c8296d2009-11-07 00:00:49 +00001631 Result->AddChunk(Chunk(CodeCompletionString::CK_RightParen));
Douglas Gregora61a8792009-12-11 18:44:16 +00001632 AddFunctionTypeQualsToCompletionString(Result, Function);
Douglas Gregor86d9a522009-09-21 16:56:56 +00001633 return Result;
1634 }
1635
1636 if (FunctionTemplateDecl *FunTmpl = dyn_cast<FunctionTemplateDecl>(ND)) {
Douglas Gregor0563c262009-09-22 23:15:58 +00001637 AddQualifierToCompletionString(Result, Qualifier, QualifierIsInformative,
1638 S.Context);
Douglas Gregor86d9a522009-09-21 16:56:56 +00001639 FunctionDecl *Function = FunTmpl->getTemplatedDecl();
Benjamin Kramer660cc182009-11-29 20:18:50 +00001640 Result->AddTypedTextChunk(Function->getNameAsString());
Douglas Gregor86d9a522009-09-21 16:56:56 +00001641
1642 // Figure out which template parameters are deduced (or have default
1643 // arguments).
1644 llvm::SmallVector<bool, 16> Deduced;
1645 S.MarkDeducedTemplateParameters(FunTmpl, Deduced);
1646 unsigned LastDeducibleArgument;
1647 for (LastDeducibleArgument = Deduced.size(); LastDeducibleArgument > 0;
1648 --LastDeducibleArgument) {
1649 if (!Deduced[LastDeducibleArgument - 1]) {
1650 // C++0x: Figure out if the template argument has a default. If so,
1651 // the user doesn't need to type this argument.
1652 // FIXME: We need to abstract template parameters better!
1653 bool HasDefaultArg = false;
1654 NamedDecl *Param = FunTmpl->getTemplateParameters()->getParam(
1655 LastDeducibleArgument - 1);
1656 if (TemplateTypeParmDecl *TTP = dyn_cast<TemplateTypeParmDecl>(Param))
1657 HasDefaultArg = TTP->hasDefaultArgument();
1658 else if (NonTypeTemplateParmDecl *NTTP
1659 = dyn_cast<NonTypeTemplateParmDecl>(Param))
1660 HasDefaultArg = NTTP->hasDefaultArgument();
1661 else {
1662 assert(isa<TemplateTemplateParmDecl>(Param));
1663 HasDefaultArg
Douglas Gregor0c8296d2009-11-07 00:00:49 +00001664 = cast<TemplateTemplateParmDecl>(Param)->hasDefaultArgument();
Douglas Gregor86d9a522009-09-21 16:56:56 +00001665 }
1666
1667 if (!HasDefaultArg)
1668 break;
1669 }
1670 }
1671
1672 if (LastDeducibleArgument) {
1673 // Some of the function template arguments cannot be deduced from a
1674 // function call, so we introduce an explicit template argument list
1675 // containing all of the arguments up to the first deducible argument.
Douglas Gregor0c8296d2009-11-07 00:00:49 +00001676 Result->AddChunk(Chunk(CodeCompletionString::CK_LeftAngle));
Douglas Gregor86d9a522009-09-21 16:56:56 +00001677 AddTemplateParameterChunks(S.Context, FunTmpl, Result,
1678 LastDeducibleArgument);
Douglas Gregor0c8296d2009-11-07 00:00:49 +00001679 Result->AddChunk(Chunk(CodeCompletionString::CK_RightAngle));
Douglas Gregor86d9a522009-09-21 16:56:56 +00001680 }
1681
1682 // Add the function parameters
Douglas Gregor0c8296d2009-11-07 00:00:49 +00001683 Result->AddChunk(Chunk(CodeCompletionString::CK_LeftParen));
Douglas Gregor86d9a522009-09-21 16:56:56 +00001684 AddFunctionParameterChunks(S.Context, Function, Result);
Douglas Gregor0c8296d2009-11-07 00:00:49 +00001685 Result->AddChunk(Chunk(CodeCompletionString::CK_RightParen));
Douglas Gregora61a8792009-12-11 18:44:16 +00001686 AddFunctionTypeQualsToCompletionString(Result, Function);
Douglas Gregor86d9a522009-09-21 16:56:56 +00001687 return Result;
1688 }
1689
1690 if (TemplateDecl *Template = dyn_cast<TemplateDecl>(ND)) {
Douglas Gregor0563c262009-09-22 23:15:58 +00001691 AddQualifierToCompletionString(Result, Qualifier, QualifierIsInformative,
1692 S.Context);
Benjamin Kramer660cc182009-11-29 20:18:50 +00001693 Result->AddTypedTextChunk(Template->getNameAsString());
Douglas Gregor0c8296d2009-11-07 00:00:49 +00001694 Result->AddChunk(Chunk(CodeCompletionString::CK_LeftAngle));
Douglas Gregor86d9a522009-09-21 16:56:56 +00001695 AddTemplateParameterChunks(S.Context, Template, Result);
Douglas Gregor0c8296d2009-11-07 00:00:49 +00001696 Result->AddChunk(Chunk(CodeCompletionString::CK_RightAngle));
Douglas Gregor86d9a522009-09-21 16:56:56 +00001697 return Result;
1698 }
1699
Douglas Gregor9630eb62009-11-17 16:44:22 +00001700 if (ObjCMethodDecl *Method = dyn_cast<ObjCMethodDecl>(ND)) {
Douglas Gregor9630eb62009-11-17 16:44:22 +00001701 Selector Sel = Method->getSelector();
1702 if (Sel.isUnarySelector()) {
1703 Result->AddTypedTextChunk(Sel.getIdentifierInfoForSlot(0)->getName());
1704 return Result;
1705 }
1706
Douglas Gregord3c68542009-11-19 01:08:35 +00001707 std::string SelName = Sel.getIdentifierInfoForSlot(0)->getName().str();
1708 SelName += ':';
1709 if (StartParameter == 0)
1710 Result->AddTypedTextChunk(SelName);
1711 else {
1712 Result->AddInformativeChunk(SelName);
1713
1714 // If there is only one parameter, and we're past it, add an empty
1715 // typed-text chunk since there is nothing to type.
1716 if (Method->param_size() == 1)
1717 Result->AddTypedTextChunk("");
1718 }
Douglas Gregor9630eb62009-11-17 16:44:22 +00001719 unsigned Idx = 0;
1720 for (ObjCMethodDecl::param_iterator P = Method->param_begin(),
1721 PEnd = Method->param_end();
1722 P != PEnd; (void)++P, ++Idx) {
1723 if (Idx > 0) {
Douglas Gregord3c68542009-11-19 01:08:35 +00001724 std::string Keyword;
1725 if (Idx > StartParameter)
Douglas Gregor834389b2010-01-12 06:38:28 +00001726 Result->AddChunk(CodeCompletionString::CK_HorizontalSpace);
Douglas Gregor9630eb62009-11-17 16:44:22 +00001727 if (IdentifierInfo *II = Sel.getIdentifierInfoForSlot(Idx))
1728 Keyword += II->getName().str();
1729 Keyword += ":";
Douglas Gregor4ad96852009-11-19 07:41:15 +00001730 if (Idx < StartParameter || AllParametersAreInformative) {
Douglas Gregord3c68542009-11-19 01:08:35 +00001731 Result->AddInformativeChunk(Keyword);
1732 } else if (Idx == StartParameter)
1733 Result->AddTypedTextChunk(Keyword);
1734 else
1735 Result->AddTextChunk(Keyword);
Douglas Gregor9630eb62009-11-17 16:44:22 +00001736 }
Douglas Gregord3c68542009-11-19 01:08:35 +00001737
1738 // If we're before the starting parameter, skip the placeholder.
1739 if (Idx < StartParameter)
1740 continue;
Douglas Gregor9630eb62009-11-17 16:44:22 +00001741
1742 std::string Arg;
1743 (*P)->getType().getAsStringInternal(Arg, S.Context.PrintingPolicy);
1744 Arg = "(" + Arg + ")";
1745 if (IdentifierInfo *II = (*P)->getIdentifier())
1746 Arg += II->getName().str();
Douglas Gregor4ad96852009-11-19 07:41:15 +00001747 if (AllParametersAreInformative)
1748 Result->AddInformativeChunk(Arg);
1749 else
1750 Result->AddPlaceholderChunk(Arg);
Douglas Gregor9630eb62009-11-17 16:44:22 +00001751 }
1752
Douglas Gregor2a17af02009-12-23 00:21:46 +00001753 if (Method->isVariadic()) {
1754 if (AllParametersAreInformative)
1755 Result->AddInformativeChunk(", ...");
1756 else
1757 Result->AddPlaceholderChunk(", ...");
1758 }
1759
Douglas Gregor9630eb62009-11-17 16:44:22 +00001760 return Result;
1761 }
1762
Douglas Gregor2b4074f2009-12-01 05:55:20 +00001763 if (Qualifier)
Douglas Gregor0563c262009-09-22 23:15:58 +00001764 AddQualifierToCompletionString(Result, Qualifier, QualifierIsInformative,
1765 S.Context);
Douglas Gregor2b4074f2009-12-01 05:55:20 +00001766
1767 Result->AddTypedTextChunk(ND->getNameAsString());
1768 return Result;
Douglas Gregor86d9a522009-09-21 16:56:56 +00001769}
1770
Douglas Gregor86d802e2009-09-23 00:34:09 +00001771CodeCompletionString *
1772CodeCompleteConsumer::OverloadCandidate::CreateSignatureString(
1773 unsigned CurrentArg,
1774 Sema &S) const {
Douglas Gregor0c8296d2009-11-07 00:00:49 +00001775 typedef CodeCompletionString::Chunk Chunk;
1776
Douglas Gregor86d802e2009-09-23 00:34:09 +00001777 CodeCompletionString *Result = new CodeCompletionString;
1778 FunctionDecl *FDecl = getFunction();
Douglas Gregorff5ce6e2009-12-18 18:53:37 +00001779 AddResultTypeChunk(S.Context, FDecl, Result);
Douglas Gregor86d802e2009-09-23 00:34:09 +00001780 const FunctionProtoType *Proto
1781 = dyn_cast<FunctionProtoType>(getFunctionType());
1782 if (!FDecl && !Proto) {
1783 // Function without a prototype. Just give the return type and a
1784 // highlighted ellipsis.
1785 const FunctionType *FT = getFunctionType();
1786 Result->AddTextChunk(
Benjamin Kramer660cc182009-11-29 20:18:50 +00001787 FT->getResultType().getAsString(S.Context.PrintingPolicy));
Douglas Gregor0c8296d2009-11-07 00:00:49 +00001788 Result->AddChunk(Chunk(CodeCompletionString::CK_LeftParen));
1789 Result->AddChunk(Chunk(CodeCompletionString::CK_CurrentParameter, "..."));
1790 Result->AddChunk(Chunk(CodeCompletionString::CK_RightParen));
Douglas Gregor86d802e2009-09-23 00:34:09 +00001791 return Result;
1792 }
1793
1794 if (FDecl)
Benjamin Kramer660cc182009-11-29 20:18:50 +00001795 Result->AddTextChunk(FDecl->getNameAsString());
Douglas Gregor86d802e2009-09-23 00:34:09 +00001796 else
1797 Result->AddTextChunk(
Benjamin Kramer660cc182009-11-29 20:18:50 +00001798 Proto->getResultType().getAsString(S.Context.PrintingPolicy));
Douglas Gregor86d802e2009-09-23 00:34:09 +00001799
Douglas Gregor0c8296d2009-11-07 00:00:49 +00001800 Result->AddChunk(Chunk(CodeCompletionString::CK_LeftParen));
Douglas Gregor86d802e2009-09-23 00:34:09 +00001801 unsigned NumParams = FDecl? FDecl->getNumParams() : Proto->getNumArgs();
1802 for (unsigned I = 0; I != NumParams; ++I) {
1803 if (I)
Douglas Gregor0c8296d2009-11-07 00:00:49 +00001804 Result->AddChunk(Chunk(CodeCompletionString::CK_Comma));
Douglas Gregor86d802e2009-09-23 00:34:09 +00001805
1806 std::string ArgString;
1807 QualType ArgType;
1808
1809 if (FDecl) {
1810 ArgString = FDecl->getParamDecl(I)->getNameAsString();
1811 ArgType = FDecl->getParamDecl(I)->getOriginalType();
1812 } else {
1813 ArgType = Proto->getArgType(I);
1814 }
1815
1816 ArgType.getAsStringInternal(ArgString, S.Context.PrintingPolicy);
1817
1818 if (I == CurrentArg)
Douglas Gregor0c8296d2009-11-07 00:00:49 +00001819 Result->AddChunk(Chunk(CodeCompletionString::CK_CurrentParameter,
Benjamin Kramer660cc182009-11-29 20:18:50 +00001820 ArgString));
Douglas Gregor86d802e2009-09-23 00:34:09 +00001821 else
Benjamin Kramer660cc182009-11-29 20:18:50 +00001822 Result->AddTextChunk(ArgString);
Douglas Gregor86d802e2009-09-23 00:34:09 +00001823 }
1824
1825 if (Proto && Proto->isVariadic()) {
Douglas Gregor0c8296d2009-11-07 00:00:49 +00001826 Result->AddChunk(Chunk(CodeCompletionString::CK_Comma));
Douglas Gregor86d802e2009-09-23 00:34:09 +00001827 if (CurrentArg < NumParams)
1828 Result->AddTextChunk("...");
1829 else
Douglas Gregor0c8296d2009-11-07 00:00:49 +00001830 Result->AddChunk(Chunk(CodeCompletionString::CK_CurrentParameter, "..."));
Douglas Gregor86d802e2009-09-23 00:34:09 +00001831 }
Douglas Gregor0c8296d2009-11-07 00:00:49 +00001832 Result->AddChunk(Chunk(CodeCompletionString::CK_RightParen));
Douglas Gregor86d802e2009-09-23 00:34:09 +00001833
1834 return Result;
1835}
1836
Douglas Gregor86d9a522009-09-21 16:56:56 +00001837namespace {
1838 struct SortCodeCompleteResult {
1839 typedef CodeCompleteConsumer::Result Result;
1840
Douglas Gregor6a684032009-09-28 03:51:44 +00001841 bool isEarlierDeclarationName(DeclarationName X, DeclarationName Y) const {
Douglas Gregor2b0cc122009-12-05 09:08:56 +00001842 Selector XSel = X.getObjCSelector();
1843 Selector YSel = Y.getObjCSelector();
1844 if (!XSel.isNull() && !YSel.isNull()) {
1845 // We are comparing two selectors.
1846 unsigned N = std::min(XSel.getNumArgs(), YSel.getNumArgs());
1847 if (N == 0)
1848 ++N;
1849 for (unsigned I = 0; I != N; ++I) {
1850 IdentifierInfo *XId = XSel.getIdentifierInfoForSlot(I);
1851 IdentifierInfo *YId = YSel.getIdentifierInfoForSlot(I);
1852 if (!XId || !YId)
1853 return XId && !YId;
1854
1855 switch (XId->getName().compare_lower(YId->getName())) {
1856 case -1: return true;
1857 case 1: return false;
1858 default: break;
1859 }
1860 }
1861
1862 return XSel.getNumArgs() < YSel.getNumArgs();
1863 }
1864
1865 // For non-selectors, order by kind.
1866 if (X.getNameKind() != Y.getNameKind())
Douglas Gregor6a684032009-09-28 03:51:44 +00001867 return X.getNameKind() < Y.getNameKind();
1868
Douglas Gregor2b0cc122009-12-05 09:08:56 +00001869 // Order identifiers by comparison of their lowercased names.
1870 if (IdentifierInfo *XId = X.getAsIdentifierInfo())
1871 return XId->getName().compare_lower(
1872 Y.getAsIdentifierInfo()->getName()) < 0;
1873
1874 // Order overloaded operators by the order in which they appear
1875 // in our list of operators.
1876 if (OverloadedOperatorKind XOp = X.getCXXOverloadedOperator())
1877 return XOp < Y.getCXXOverloadedOperator();
1878
1879 // Order C++0x user-defined literal operators lexically by their
1880 // lowercased suffixes.
1881 if (IdentifierInfo *XLit = X.getCXXLiteralIdentifier())
1882 return XLit->getName().compare_lower(
1883 Y.getCXXLiteralIdentifier()->getName()) < 0;
1884
1885 // The only stable ordering we have is to turn the name into a
1886 // string and then compare the lower-case strings. This is
1887 // inefficient, but thankfully does not happen too often.
Benjamin Kramer0e7049f2009-12-05 10:22:15 +00001888 return llvm::StringRef(X.getAsString()).compare_lower(
1889 Y.getAsString()) < 0;
Douglas Gregor6a684032009-09-28 03:51:44 +00001890 }
1891
Douglas Gregor86d9a522009-09-21 16:56:56 +00001892 bool operator()(const Result &X, const Result &Y) const {
1893 // Sort first by rank.
1894 if (X.Rank < Y.Rank)
1895 return true;
1896 else if (X.Rank > Y.Rank)
1897 return false;
1898
Douglas Gregor54f01612009-11-19 00:01:57 +00001899 // We use a special ordering for keywords and patterns, based on the
1900 // typed text.
1901 if ((X.Kind == Result::RK_Keyword || X.Kind == Result::RK_Pattern) &&
1902 (Y.Kind == Result::RK_Keyword || Y.Kind == Result::RK_Pattern)) {
1903 const char *XStr = (X.Kind == Result::RK_Keyword)? X.Keyword
1904 : X.Pattern->getTypedText();
1905 const char *YStr = (Y.Kind == Result::RK_Keyword)? Y.Keyword
1906 : Y.Pattern->getTypedText();
Benjamin Kramerf42d4882009-12-05 10:07:04 +00001907 return llvm::StringRef(XStr).compare_lower(YStr) < 0;
Douglas Gregor54f01612009-11-19 00:01:57 +00001908 }
1909
Douglas Gregor86d9a522009-09-21 16:56:56 +00001910 // Result kinds are ordered by decreasing importance.
1911 if (X.Kind < Y.Kind)
1912 return true;
1913 else if (X.Kind > Y.Kind)
1914 return false;
1915
1916 // Non-hidden names precede hidden names.
1917 if (X.Hidden != Y.Hidden)
1918 return !X.Hidden;
1919
Douglas Gregoreb5758b2009-09-23 22:26:46 +00001920 // Non-nested-name-specifiers precede nested-name-specifiers.
1921 if (X.StartsNestedNameSpecifier != Y.StartsNestedNameSpecifier)
1922 return !X.StartsNestedNameSpecifier;
1923
Douglas Gregor86d9a522009-09-21 16:56:56 +00001924 // Ordering depends on the kind of result.
1925 switch (X.Kind) {
1926 case Result::RK_Declaration:
1927 // Order based on the declaration names.
Douglas Gregor6a684032009-09-28 03:51:44 +00001928 return isEarlierDeclarationName(X.Declaration->getDeclName(),
1929 Y.Declaration->getDeclName());
Douglas Gregor86d9a522009-09-21 16:56:56 +00001930
Douglas Gregor3f7c7f42009-10-30 16:50:04 +00001931 case Result::RK_Macro:
Douglas Gregor2b0cc122009-12-05 09:08:56 +00001932 return X.Macro->getName().compare_lower(Y.Macro->getName()) < 0;
Douglas Gregor54f01612009-11-19 00:01:57 +00001933
1934 case Result::RK_Keyword:
1935 case Result::RK_Pattern:
Jeffrey Yasskin9f61aa92009-12-12 05:05:38 +00001936 llvm_unreachable("Result kinds handled above");
Douglas Gregor54f01612009-11-19 00:01:57 +00001937 break;
Douglas Gregor86d9a522009-09-21 16:56:56 +00001938 }
1939
1940 // Silence GCC warning.
1941 return false;
1942 }
1943 };
1944}
1945
Douglas Gregor3f7c7f42009-10-30 16:50:04 +00001946static void AddMacroResults(Preprocessor &PP, unsigned Rank,
1947 ResultBuilder &Results) {
1948 Results.EnterNewScope();
Douglas Gregor0c8296d2009-11-07 00:00:49 +00001949 for (Preprocessor::macro_iterator M = PP.macro_begin(),
1950 MEnd = PP.macro_end();
Douglas Gregor3f7c7f42009-10-30 16:50:04 +00001951 M != MEnd; ++M)
1952 Results.MaybeAddResult(CodeCompleteConsumer::Result(M->first, Rank));
1953 Results.ExitScope();
1954}
1955
Daniel Dunbar3a2838d2009-11-13 08:58:20 +00001956static void HandleCodeCompleteResults(Sema *S,
1957 CodeCompleteConsumer *CodeCompleter,
1958 CodeCompleteConsumer::Result *Results,
1959 unsigned NumResults) {
Douglas Gregor86d9a522009-09-21 16:56:56 +00001960 // Sort the results by rank/kind/etc.
1961 std::stable_sort(Results, Results + NumResults, SortCodeCompleteResult());
1962
1963 if (CodeCompleter)
Daniel Dunbar3a2838d2009-11-13 08:58:20 +00001964 CodeCompleter->ProcessCodeCompleteResults(*S, Results, NumResults);
Douglas Gregor54f01612009-11-19 00:01:57 +00001965
1966 for (unsigned I = 0; I != NumResults; ++I)
1967 Results[I].Destroy();
Douglas Gregor86d9a522009-09-21 16:56:56 +00001968}
1969
Douglas Gregor01dfea02010-01-10 23:08:15 +00001970void Sema::CodeCompleteOrdinaryName(Scope *S,
1971 CodeCompletionContext CompletionContext) {
Douglas Gregor2a7925c2009-12-07 09:54:55 +00001972 typedef CodeCompleteConsumer::Result Result;
Douglas Gregor01dfea02010-01-10 23:08:15 +00001973 ResultBuilder Results(*this);
1974
1975 // Determine how to filter results, e.g., so that the names of
1976 // values (functions, enumerators, function templates, etc.) are
1977 // only allowed where we can have an expression.
1978 switch (CompletionContext) {
1979 case CCC_Namespace:
1980 case CCC_Class:
Douglas Gregorb6ac2452010-01-13 21:24:21 +00001981 case CCC_ObjCInterface:
1982 case CCC_ObjCImplementation:
Douglas Gregorc38c3e12010-01-13 21:54:15 +00001983 case CCC_ObjCInstanceVariableList:
Douglas Gregor01dfea02010-01-10 23:08:15 +00001984 case CCC_Template:
1985 case CCC_MemberTemplate:
1986 Results.setFilter(&ResultBuilder::IsOrdinaryNonValueName);
1987 break;
1988
1989 case CCC_Expression:
1990 case CCC_Statement:
1991 case CCC_ForInit:
1992 case CCC_Condition:
1993 Results.setFilter(&ResultBuilder::IsOrdinaryName);
1994 break;
1995 }
1996
Douglas Gregor3f7c7f42009-10-30 16:50:04 +00001997 unsigned NextRank = CollectLookupResults(S, Context.getTranslationUnitDecl(),
1998 0, CurContext, Results);
Douglas Gregor2a7925c2009-12-07 09:54:55 +00001999
2000 Results.EnterNewScope();
Douglas Gregor01dfea02010-01-10 23:08:15 +00002001 AddOrdinaryNameResults(CompletionContext, S, *this, NextRank, Results);
Douglas Gregor2a7925c2009-12-07 09:54:55 +00002002 Results.ExitScope();
2003
Douglas Gregor0c8296d2009-11-07 00:00:49 +00002004 if (CodeCompleter->includeMacros())
2005 AddMacroResults(PP, NextRank, Results);
Daniel Dunbar3a2838d2009-11-13 08:58:20 +00002006 HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
Douglas Gregor791215b2009-09-21 20:51:25 +00002007}
2008
Douglas Gregor95ac6552009-11-18 01:29:26 +00002009static void AddObjCProperties(ObjCContainerDecl *Container,
Douglas Gregor322328b2009-11-18 22:32:06 +00002010 bool AllowCategories,
Douglas Gregor95ac6552009-11-18 01:29:26 +00002011 DeclContext *CurContext,
2012 ResultBuilder &Results) {
2013 typedef CodeCompleteConsumer::Result Result;
2014
2015 // Add properties in this container.
2016 for (ObjCContainerDecl::prop_iterator P = Container->prop_begin(),
2017 PEnd = Container->prop_end();
2018 P != PEnd;
2019 ++P)
2020 Results.MaybeAddResult(Result(*P, 0), CurContext);
2021
2022 // Add properties in referenced protocols.
2023 if (ObjCProtocolDecl *Protocol = dyn_cast<ObjCProtocolDecl>(Container)) {
2024 for (ObjCProtocolDecl::protocol_iterator P = Protocol->protocol_begin(),
2025 PEnd = Protocol->protocol_end();
2026 P != PEnd; ++P)
Douglas Gregor322328b2009-11-18 22:32:06 +00002027 AddObjCProperties(*P, AllowCategories, CurContext, Results);
Douglas Gregor95ac6552009-11-18 01:29:26 +00002028 } else if (ObjCInterfaceDecl *IFace = dyn_cast<ObjCInterfaceDecl>(Container)){
Douglas Gregor322328b2009-11-18 22:32:06 +00002029 if (AllowCategories) {
2030 // Look through categories.
2031 for (ObjCCategoryDecl *Category = IFace->getCategoryList();
2032 Category; Category = Category->getNextClassCategory())
2033 AddObjCProperties(Category, AllowCategories, CurContext, Results);
2034 }
Douglas Gregor95ac6552009-11-18 01:29:26 +00002035
2036 // Look through protocols.
2037 for (ObjCInterfaceDecl::protocol_iterator I = IFace->protocol_begin(),
2038 E = IFace->protocol_end();
2039 I != E; ++I)
Douglas Gregor322328b2009-11-18 22:32:06 +00002040 AddObjCProperties(*I, AllowCategories, CurContext, Results);
Douglas Gregor95ac6552009-11-18 01:29:26 +00002041
2042 // Look in the superclass.
2043 if (IFace->getSuperClass())
Douglas Gregor322328b2009-11-18 22:32:06 +00002044 AddObjCProperties(IFace->getSuperClass(), AllowCategories, CurContext,
2045 Results);
Douglas Gregor95ac6552009-11-18 01:29:26 +00002046 } else if (const ObjCCategoryDecl *Category
2047 = dyn_cast<ObjCCategoryDecl>(Container)) {
2048 // Look through protocols.
2049 for (ObjCInterfaceDecl::protocol_iterator P = Category->protocol_begin(),
2050 PEnd = Category->protocol_end();
2051 P != PEnd; ++P)
Douglas Gregor322328b2009-11-18 22:32:06 +00002052 AddObjCProperties(*P, AllowCategories, CurContext, Results);
Douglas Gregor95ac6552009-11-18 01:29:26 +00002053 }
2054}
2055
Douglas Gregor81b747b2009-09-17 21:32:03 +00002056void Sema::CodeCompleteMemberReferenceExpr(Scope *S, ExprTy *BaseE,
2057 SourceLocation OpLoc,
2058 bool IsArrow) {
2059 if (!BaseE || !CodeCompleter)
2060 return;
2061
Douglas Gregor86d9a522009-09-21 16:56:56 +00002062 typedef CodeCompleteConsumer::Result Result;
2063
Douglas Gregor81b747b2009-09-17 21:32:03 +00002064 Expr *Base = static_cast<Expr *>(BaseE);
2065 QualType BaseType = Base->getType();
Douglas Gregor86d9a522009-09-21 16:56:56 +00002066
2067 if (IsArrow) {
2068 if (const PointerType *Ptr = BaseType->getAs<PointerType>())
2069 BaseType = Ptr->getPointeeType();
2070 else if (BaseType->isObjCObjectPointerType())
2071 /*Do nothing*/ ;
2072 else
2073 return;
2074 }
2075
Douglas Gregoreb5758b2009-09-23 22:26:46 +00002076 ResultBuilder Results(*this, &ResultBuilder::IsMember);
Douglas Gregor86d9a522009-09-21 16:56:56 +00002077 unsigned NextRank = 0;
Daniel Dunbar3a2838d2009-11-13 08:58:20 +00002078
Douglas Gregor95ac6552009-11-18 01:29:26 +00002079 Results.EnterNewScope();
2080 if (const RecordType *Record = BaseType->getAs<RecordType>()) {
2081 // Access to a C/C++ class, struct, or union.
2082 NextRank = CollectMemberLookupResults(Record->getDecl(), NextRank,
2083 Record->getDecl(), Results);
Daniel Dunbar3a2838d2009-11-13 08:58:20 +00002084
Douglas Gregor95ac6552009-11-18 01:29:26 +00002085 if (getLangOptions().CPlusPlus) {
2086 if (!Results.empty()) {
2087 // The "template" keyword can follow "->" or "." in the grammar.
2088 // However, we only want to suggest the template keyword if something
2089 // is dependent.
2090 bool IsDependent = BaseType->isDependentType();
2091 if (!IsDependent) {
2092 for (Scope *DepScope = S; DepScope; DepScope = DepScope->getParent())
2093 if (DeclContext *Ctx = (DeclContext *)DepScope->getEntity()) {
2094 IsDependent = Ctx->isDependentContext();
2095 break;
2096 }
2097 }
Daniel Dunbar3a2838d2009-11-13 08:58:20 +00002098
Douglas Gregor95ac6552009-11-18 01:29:26 +00002099 if (IsDependent)
2100 Results.MaybeAddResult(Result("template", NextRank++));
Daniel Dunbar3a2838d2009-11-13 08:58:20 +00002101 }
2102
Douglas Gregor95ac6552009-11-18 01:29:26 +00002103 // We could have the start of a nested-name-specifier. Add those
2104 // results as well.
Douglas Gregor76282942009-12-11 17:31:05 +00002105 // FIXME: We should really walk base classes to produce
2106 // nested-name-specifiers so that we produce more-precise results.
Douglas Gregor95ac6552009-11-18 01:29:26 +00002107 Results.setFilter(&ResultBuilder::IsNestedNameSpecifier);
2108 CollectLookupResults(S, Context.getTranslationUnitDecl(), NextRank,
2109 CurContext, Results);
Daniel Dunbar3a2838d2009-11-13 08:58:20 +00002110 }
Douglas Gregor95ac6552009-11-18 01:29:26 +00002111 } else if (!IsArrow && BaseType->getAsObjCInterfacePointerType()) {
2112 // Objective-C property reference.
2113
2114 // Add property results based on our interface.
2115 const ObjCObjectPointerType *ObjCPtr
2116 = BaseType->getAsObjCInterfacePointerType();
2117 assert(ObjCPtr && "Non-NULL pointer guaranteed above!");
Douglas Gregor322328b2009-11-18 22:32:06 +00002118 AddObjCProperties(ObjCPtr->getInterfaceDecl(), true, CurContext, Results);
Douglas Gregor95ac6552009-11-18 01:29:26 +00002119
2120 // Add properties from the protocols in a qualified interface.
2121 for (ObjCObjectPointerType::qual_iterator I = ObjCPtr->qual_begin(),
2122 E = ObjCPtr->qual_end();
2123 I != E; ++I)
Douglas Gregor322328b2009-11-18 22:32:06 +00002124 AddObjCProperties(*I, true, CurContext, Results);
Douglas Gregor95ac6552009-11-18 01:29:26 +00002125 } else if ((IsArrow && BaseType->isObjCObjectPointerType()) ||
2126 (!IsArrow && BaseType->isObjCInterfaceType())) {
2127 // Objective-C instance variable access.
2128 ObjCInterfaceDecl *Class = 0;
2129 if (const ObjCObjectPointerType *ObjCPtr
2130 = BaseType->getAs<ObjCObjectPointerType>())
2131 Class = ObjCPtr->getInterfaceDecl();
2132 else
2133 Class = BaseType->getAs<ObjCInterfaceType>()->getDecl();
2134
2135 // Add all ivars from this class and its superclasses.
2136 for (; Class; Class = Class->getSuperClass()) {
2137 for (ObjCInterfaceDecl::ivar_iterator IVar = Class->ivar_begin(),
2138 IVarEnd = Class->ivar_end();
2139 IVar != IVarEnd; ++IVar)
2140 Results.MaybeAddResult(Result(*IVar, 0), CurContext);
2141 }
Douglas Gregor86d9a522009-09-21 16:56:56 +00002142 }
Douglas Gregor95ac6552009-11-18 01:29:26 +00002143
2144 // FIXME: How do we cope with isa?
2145
2146 Results.ExitScope();
Daniel Dunbar3a2838d2009-11-13 08:58:20 +00002147
2148 // Add macros
2149 if (CodeCompleter->includeMacros())
2150 AddMacroResults(PP, NextRank, Results);
2151
2152 // Hand off the results found for code completion.
2153 HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
Douglas Gregor81b747b2009-09-17 21:32:03 +00002154}
2155
Douglas Gregor374929f2009-09-18 15:37:17 +00002156void Sema::CodeCompleteTag(Scope *S, unsigned TagSpec) {
2157 if (!CodeCompleter)
2158 return;
2159
Douglas Gregor86d9a522009-09-21 16:56:56 +00002160 typedef CodeCompleteConsumer::Result Result;
2161 ResultBuilder::LookupFilter Filter = 0;
Douglas Gregor374929f2009-09-18 15:37:17 +00002162 switch ((DeclSpec::TST)TagSpec) {
2163 case DeclSpec::TST_enum:
Douglas Gregor86d9a522009-09-21 16:56:56 +00002164 Filter = &ResultBuilder::IsEnum;
Douglas Gregor374929f2009-09-18 15:37:17 +00002165 break;
2166
2167 case DeclSpec::TST_union:
Douglas Gregor86d9a522009-09-21 16:56:56 +00002168 Filter = &ResultBuilder::IsUnion;
Douglas Gregor374929f2009-09-18 15:37:17 +00002169 break;
2170
2171 case DeclSpec::TST_struct:
Douglas Gregor374929f2009-09-18 15:37:17 +00002172 case DeclSpec::TST_class:
Douglas Gregor86d9a522009-09-21 16:56:56 +00002173 Filter = &ResultBuilder::IsClassOrStruct;
Douglas Gregor374929f2009-09-18 15:37:17 +00002174 break;
2175
2176 default:
2177 assert(false && "Unknown type specifier kind in CodeCompleteTag");
2178 return;
2179 }
Douglas Gregor86d9a522009-09-21 16:56:56 +00002180
2181 ResultBuilder Results(*this, Filter);
2182 unsigned NextRank = CollectLookupResults(S, Context.getTranslationUnitDecl(),
Douglas Gregor456c4a12009-09-21 20:12:40 +00002183 0, CurContext, Results);
Douglas Gregor86d9a522009-09-21 16:56:56 +00002184
2185 if (getLangOptions().CPlusPlus) {
2186 // We could have the start of a nested-name-specifier. Add those
2187 // results as well.
2188 Results.setFilter(&ResultBuilder::IsNestedNameSpecifier);
Douglas Gregor3f7c7f42009-10-30 16:50:04 +00002189 NextRank = CollectLookupResults(S, Context.getTranslationUnitDecl(),
2190 NextRank, CurContext, Results);
Douglas Gregor86d9a522009-09-21 16:56:56 +00002191 }
2192
Douglas Gregor0c8296d2009-11-07 00:00:49 +00002193 if (CodeCompleter->includeMacros())
2194 AddMacroResults(PP, NextRank, Results);
Daniel Dunbar3a2838d2009-11-13 08:58:20 +00002195 HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
Douglas Gregor374929f2009-09-18 15:37:17 +00002196}
2197
Douglas Gregor3e1005f2009-09-21 18:10:23 +00002198void Sema::CodeCompleteCase(Scope *S) {
2199 if (getSwitchStack().empty() || !CodeCompleter)
2200 return;
2201
2202 SwitchStmt *Switch = getSwitchStack().back();
2203 if (!Switch->getCond()->getType()->isEnumeralType())
2204 return;
2205
2206 // Code-complete the cases of a switch statement over an enumeration type
2207 // by providing the list of
2208 EnumDecl *Enum = Switch->getCond()->getType()->getAs<EnumType>()->getDecl();
2209
2210 // Determine which enumerators we have already seen in the switch statement.
2211 // FIXME: Ideally, we would also be able to look *past* the code-completion
2212 // token, in case we are code-completing in the middle of the switch and not
2213 // at the end. However, we aren't able to do so at the moment.
2214 llvm::SmallPtrSet<EnumConstantDecl *, 8> EnumeratorsSeen;
Douglas Gregorb9d0ef72009-09-21 19:57:38 +00002215 NestedNameSpecifier *Qualifier = 0;
Douglas Gregor3e1005f2009-09-21 18:10:23 +00002216 for (SwitchCase *SC = Switch->getSwitchCaseList(); SC;
2217 SC = SC->getNextSwitchCase()) {
2218 CaseStmt *Case = dyn_cast<CaseStmt>(SC);
2219 if (!Case)
2220 continue;
2221
2222 Expr *CaseVal = Case->getLHS()->IgnoreParenCasts();
2223 if (DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(CaseVal))
2224 if (EnumConstantDecl *Enumerator
2225 = dyn_cast<EnumConstantDecl>(DRE->getDecl())) {
2226 // We look into the AST of the case statement to determine which
2227 // enumerator was named. Alternatively, we could compute the value of
2228 // the integral constant expression, then compare it against the
2229 // values of each enumerator. However, value-based approach would not
2230 // work as well with C++ templates where enumerators declared within a
2231 // template are type- and value-dependent.
2232 EnumeratorsSeen.insert(Enumerator);
2233
Douglas Gregorb9d0ef72009-09-21 19:57:38 +00002234 // If this is a qualified-id, keep track of the nested-name-specifier
2235 // so that we can reproduce it as part of code completion, e.g.,
Douglas Gregor3e1005f2009-09-21 18:10:23 +00002236 //
2237 // switch (TagD.getKind()) {
2238 // case TagDecl::TK_enum:
2239 // break;
2240 // case XXX
2241 //
Douglas Gregorb9d0ef72009-09-21 19:57:38 +00002242 // At the XXX, our completions are TagDecl::TK_union,
Douglas Gregor3e1005f2009-09-21 18:10:23 +00002243 // TagDecl::TK_struct, and TagDecl::TK_class, rather than TK_union,
2244 // TK_struct, and TK_class.
Douglas Gregora2813ce2009-10-23 18:54:35 +00002245 Qualifier = DRE->getQualifier();
Douglas Gregor3e1005f2009-09-21 18:10:23 +00002246 }
2247 }
2248
Douglas Gregorb9d0ef72009-09-21 19:57:38 +00002249 if (getLangOptions().CPlusPlus && !Qualifier && EnumeratorsSeen.empty()) {
2250 // If there are no prior enumerators in C++, check whether we have to
2251 // qualify the names of the enumerators that we suggest, because they
2252 // may not be visible in this scope.
2253 Qualifier = getRequiredQualification(Context, CurContext,
2254 Enum->getDeclContext());
2255
2256 // FIXME: Scoped enums need to start with "EnumDecl" as the context!
2257 }
2258
Douglas Gregor3e1005f2009-09-21 18:10:23 +00002259 // Add any enumerators that have not yet been mentioned.
2260 ResultBuilder Results(*this);
2261 Results.EnterNewScope();
2262 for (EnumDecl::enumerator_iterator E = Enum->enumerator_begin(),
2263 EEnd = Enum->enumerator_end();
2264 E != EEnd; ++E) {
2265 if (EnumeratorsSeen.count(*E))
2266 continue;
2267
Douglas Gregorb9d0ef72009-09-21 19:57:38 +00002268 Results.MaybeAddResult(CodeCompleteConsumer::Result(*E, 0, Qualifier));
Douglas Gregor3e1005f2009-09-21 18:10:23 +00002269 }
2270 Results.ExitScope();
2271
Douglas Gregor0c8296d2009-11-07 00:00:49 +00002272 if (CodeCompleter->includeMacros())
2273 AddMacroResults(PP, 1, Results);
Daniel Dunbar3a2838d2009-11-13 08:58:20 +00002274 HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
Douglas Gregor3e1005f2009-09-21 18:10:23 +00002275}
2276
Douglas Gregor9c6a0e92009-09-22 15:41:20 +00002277namespace {
2278 struct IsBetterOverloadCandidate {
2279 Sema &S;
2280
2281 public:
2282 explicit IsBetterOverloadCandidate(Sema &S) : S(S) { }
2283
2284 bool
2285 operator()(const OverloadCandidate &X, const OverloadCandidate &Y) const {
2286 return S.isBetterOverloadCandidate(X, Y);
2287 }
2288 };
2289}
2290
2291void Sema::CodeCompleteCall(Scope *S, ExprTy *FnIn,
2292 ExprTy **ArgsIn, unsigned NumArgs) {
2293 if (!CodeCompleter)
2294 return;
Douglas Gregoref96eac2009-12-11 19:06:04 +00002295
2296 // When we're code-completing for a call, we fall back to ordinary
2297 // name code-completion whenever we can't produce specific
2298 // results. We may want to revisit this strategy in the future,
2299 // e.g., by merging the two kinds of results.
2300
Douglas Gregor9c6a0e92009-09-22 15:41:20 +00002301 Expr *Fn = (Expr *)FnIn;
2302 Expr **Args = (Expr **)ArgsIn;
Douglas Gregoref96eac2009-12-11 19:06:04 +00002303
Douglas Gregor9c6a0e92009-09-22 15:41:20 +00002304 // Ignore type-dependent call expressions entirely.
2305 if (Fn->isTypeDependent() ||
Douglas Gregoref96eac2009-12-11 19:06:04 +00002306 Expr::hasAnyTypeDependentArguments(Args, NumArgs)) {
Douglas Gregor01dfea02010-01-10 23:08:15 +00002307 CodeCompleteOrdinaryName(S, CCC_Expression);
Douglas Gregor9c6a0e92009-09-22 15:41:20 +00002308 return;
Douglas Gregoref96eac2009-12-11 19:06:04 +00002309 }
Douglas Gregor9c6a0e92009-09-22 15:41:20 +00002310
John McCall3b4294e2009-12-16 12:17:52 +00002311 // Build an overload candidate set based on the functions we find.
2312 OverloadCandidateSet CandidateSet;
2313
Douglas Gregor9c6a0e92009-09-22 15:41:20 +00002314 // FIXME: What if we're calling something that isn't a function declaration?
2315 // FIXME: What if we're calling a pseudo-destructor?
2316 // FIXME: What if we're calling a member function?
2317
John McCall3b4294e2009-12-16 12:17:52 +00002318 Expr *NakedFn = Fn->IgnoreParenCasts();
2319 if (UnresolvedLookupExpr *ULE = dyn_cast<UnresolvedLookupExpr>(NakedFn))
2320 AddOverloadedCallCandidates(ULE, Args, NumArgs, CandidateSet,
2321 /*PartialOverloading=*/ true);
2322 else if (DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(NakedFn)) {
2323 FunctionDecl *FDecl = dyn_cast<FunctionDecl>(DRE->getDecl());
2324 if (FDecl)
2325 AddOverloadCandidate(FDecl, Args, NumArgs, CandidateSet,
2326 false, false, /*PartialOverloading*/ true);
2327 }
Douglas Gregor9c6a0e92009-09-22 15:41:20 +00002328
2329 // Sort the overload candidate set by placing the best overloads first.
2330 std::stable_sort(CandidateSet.begin(), CandidateSet.end(),
2331 IsBetterOverloadCandidate(*this));
2332
2333 // Add the remaining viable overload candidates as code-completion reslults.
Douglas Gregor05944382009-09-23 00:16:58 +00002334 typedef CodeCompleteConsumer::OverloadCandidate ResultCandidate;
2335 llvm::SmallVector<ResultCandidate, 8> Results;
Anders Carlsson90756302009-09-22 17:29:51 +00002336
Douglas Gregor9c6a0e92009-09-22 15:41:20 +00002337 for (OverloadCandidateSet::iterator Cand = CandidateSet.begin(),
2338 CandEnd = CandidateSet.end();
2339 Cand != CandEnd; ++Cand) {
2340 if (Cand->Viable)
Douglas Gregor05944382009-09-23 00:16:58 +00002341 Results.push_back(ResultCandidate(Cand->Function));
Douglas Gregor9c6a0e92009-09-22 15:41:20 +00002342 }
Douglas Gregoref96eac2009-12-11 19:06:04 +00002343
2344 if (Results.empty())
Douglas Gregor01dfea02010-01-10 23:08:15 +00002345 CodeCompleteOrdinaryName(S, CCC_Expression);
Douglas Gregoref96eac2009-12-11 19:06:04 +00002346 else
2347 CodeCompleter->ProcessOverloadCandidates(*this, NumArgs, Results.data(),
2348 Results.size());
Douglas Gregor9c6a0e92009-09-22 15:41:20 +00002349}
2350
Douglas Gregor81b747b2009-09-17 21:32:03 +00002351void Sema::CodeCompleteQualifiedId(Scope *S, const CXXScopeSpec &SS,
2352 bool EnteringContext) {
2353 if (!SS.getScopeRep() || !CodeCompleter)
2354 return;
2355
Douglas Gregor86d9a522009-09-21 16:56:56 +00002356 DeclContext *Ctx = computeDeclContext(SS, EnteringContext);
2357 if (!Ctx)
2358 return;
Douglas Gregord1cd31a2009-12-11 18:28:39 +00002359
2360 // Try to instantiate any non-dependent declaration contexts before
2361 // we look in them.
2362 if (!isDependentScopeSpecifier(SS) && RequireCompleteDeclContext(SS))
2363 return;
2364
Douglas Gregor86d9a522009-09-21 16:56:56 +00002365 ResultBuilder Results(*this);
Douglas Gregor456c4a12009-09-21 20:12:40 +00002366 unsigned NextRank = CollectMemberLookupResults(Ctx, 0, Ctx, Results);
Douglas Gregor86d9a522009-09-21 16:56:56 +00002367
2368 // The "template" keyword can follow "::" in the grammar, but only
2369 // put it into the grammar if the nested-name-specifier is dependent.
2370 NestedNameSpecifier *NNS = (NestedNameSpecifier *)SS.getScopeRep();
2371 if (!Results.empty() && NNS->isDependent())
2372 Results.MaybeAddResult(CodeCompleteConsumer::Result("template", NextRank));
2373
Douglas Gregor0c8296d2009-11-07 00:00:49 +00002374 if (CodeCompleter->includeMacros())
2375 AddMacroResults(PP, NextRank + 1, Results);
Daniel Dunbar3a2838d2009-11-13 08:58:20 +00002376 HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
Douglas Gregor81b747b2009-09-17 21:32:03 +00002377}
Douglas Gregor49f40bd2009-09-18 19:03:04 +00002378
2379void Sema::CodeCompleteUsing(Scope *S) {
2380 if (!CodeCompleter)
2381 return;
2382
Douglas Gregor86d9a522009-09-21 16:56:56 +00002383 ResultBuilder Results(*this, &ResultBuilder::IsNestedNameSpecifier);
Douglas Gregor8e0a0e42009-09-22 23:31:26 +00002384 Results.EnterNewScope();
Douglas Gregor86d9a522009-09-21 16:56:56 +00002385
2386 // If we aren't in class scope, we could see the "namespace" keyword.
2387 if (!S->isClassScope())
2388 Results.MaybeAddResult(CodeCompleteConsumer::Result("namespace", 0));
2389
2390 // After "using", we can see anything that would start a
2391 // nested-name-specifier.
Douglas Gregor3f7c7f42009-10-30 16:50:04 +00002392 unsigned NextRank = CollectLookupResults(S, Context.getTranslationUnitDecl(),
2393 0, CurContext, Results);
Douglas Gregor8e0a0e42009-09-22 23:31:26 +00002394 Results.ExitScope();
Douglas Gregor86d9a522009-09-21 16:56:56 +00002395
Douglas Gregor0c8296d2009-11-07 00:00:49 +00002396 if (CodeCompleter->includeMacros())
2397 AddMacroResults(PP, NextRank, Results);
Daniel Dunbar3a2838d2009-11-13 08:58:20 +00002398 HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
Douglas Gregor49f40bd2009-09-18 19:03:04 +00002399}
2400
2401void Sema::CodeCompleteUsingDirective(Scope *S) {
2402 if (!CodeCompleter)
2403 return;
2404
Douglas Gregor86d9a522009-09-21 16:56:56 +00002405 // After "using namespace", we expect to see a namespace name or namespace
2406 // alias.
2407 ResultBuilder Results(*this, &ResultBuilder::IsNamespaceOrAlias);
Douglas Gregor8e0a0e42009-09-22 23:31:26 +00002408 Results.EnterNewScope();
Douglas Gregor3f7c7f42009-10-30 16:50:04 +00002409 unsigned NextRank = CollectLookupResults(S, Context.getTranslationUnitDecl(),
2410 0, CurContext, Results);
Douglas Gregor8e0a0e42009-09-22 23:31:26 +00002411 Results.ExitScope();
Douglas Gregor0c8296d2009-11-07 00:00:49 +00002412 if (CodeCompleter->includeMacros())
2413 AddMacroResults(PP, NextRank, Results);
Daniel Dunbar3a2838d2009-11-13 08:58:20 +00002414 HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
Douglas Gregor49f40bd2009-09-18 19:03:04 +00002415}
2416
2417void Sema::CodeCompleteNamespaceDecl(Scope *S) {
2418 if (!CodeCompleter)
2419 return;
2420
Douglas Gregor86d9a522009-09-21 16:56:56 +00002421 ResultBuilder Results(*this, &ResultBuilder::IsNamespace);
2422 DeclContext *Ctx = (DeclContext *)S->getEntity();
2423 if (!S->getParent())
2424 Ctx = Context.getTranslationUnitDecl();
2425
2426 if (Ctx && Ctx->isFileContext()) {
2427 // We only want to see those namespaces that have already been defined
2428 // within this scope, because its likely that the user is creating an
2429 // extended namespace declaration. Keep track of the most recent
2430 // definition of each namespace.
2431 std::map<NamespaceDecl *, NamespaceDecl *> OrigToLatest;
2432 for (DeclContext::specific_decl_iterator<NamespaceDecl>
2433 NS(Ctx->decls_begin()), NSEnd(Ctx->decls_end());
2434 NS != NSEnd; ++NS)
2435 OrigToLatest[NS->getOriginalNamespace()] = *NS;
2436
2437 // Add the most recent definition (or extended definition) of each
2438 // namespace to the list of results.
Douglas Gregor8e0a0e42009-09-22 23:31:26 +00002439 Results.EnterNewScope();
Douglas Gregor86d9a522009-09-21 16:56:56 +00002440 for (std::map<NamespaceDecl *, NamespaceDecl *>::iterator
2441 NS = OrigToLatest.begin(), NSEnd = OrigToLatest.end();
2442 NS != NSEnd; ++NS)
Douglas Gregor456c4a12009-09-21 20:12:40 +00002443 Results.MaybeAddResult(CodeCompleteConsumer::Result(NS->second, 0),
2444 CurContext);
Douglas Gregor8e0a0e42009-09-22 23:31:26 +00002445 Results.ExitScope();
Douglas Gregor86d9a522009-09-21 16:56:56 +00002446 }
2447
Douglas Gregor0c8296d2009-11-07 00:00:49 +00002448 if (CodeCompleter->includeMacros())
2449 AddMacroResults(PP, 1, Results);
Daniel Dunbar3a2838d2009-11-13 08:58:20 +00002450 HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
Douglas Gregor49f40bd2009-09-18 19:03:04 +00002451}
2452
2453void Sema::CodeCompleteNamespaceAliasDecl(Scope *S) {
2454 if (!CodeCompleter)
2455 return;
2456
Douglas Gregor86d9a522009-09-21 16:56:56 +00002457 // After "namespace", we expect to see a namespace or alias.
2458 ResultBuilder Results(*this, &ResultBuilder::IsNamespaceOrAlias);
Douglas Gregor3f7c7f42009-10-30 16:50:04 +00002459 unsigned NextRank = CollectLookupResults(S, Context.getTranslationUnitDecl(),
2460 0, CurContext, Results);
Douglas Gregor0c8296d2009-11-07 00:00:49 +00002461 if (CodeCompleter->includeMacros())
2462 AddMacroResults(PP, NextRank, Results);
Daniel Dunbar3a2838d2009-11-13 08:58:20 +00002463 HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
Douglas Gregor49f40bd2009-09-18 19:03:04 +00002464}
2465
Douglas Gregored8d3222009-09-18 20:05:18 +00002466void Sema::CodeCompleteOperatorName(Scope *S) {
2467 if (!CodeCompleter)
2468 return;
Douglas Gregor86d9a522009-09-21 16:56:56 +00002469
2470 typedef CodeCompleteConsumer::Result Result;
2471 ResultBuilder Results(*this, &ResultBuilder::IsType);
Douglas Gregor8e0a0e42009-09-22 23:31:26 +00002472 Results.EnterNewScope();
Douglas Gregored8d3222009-09-18 20:05:18 +00002473
Douglas Gregor86d9a522009-09-21 16:56:56 +00002474 // Add the names of overloadable operators.
2475#define OVERLOADED_OPERATOR(Name,Spelling,Token,Unary,Binary,MemberOnly) \
2476 if (std::strcmp(Spelling, "?")) \
2477 Results.MaybeAddResult(Result(Spelling, 0));
2478#include "clang/Basic/OperatorKinds.def"
2479
2480 // Add any type names visible from the current scope
2481 unsigned NextRank = CollectLookupResults(S, Context.getTranslationUnitDecl(),
Douglas Gregor456c4a12009-09-21 20:12:40 +00002482 0, CurContext, Results);
Douglas Gregor86d9a522009-09-21 16:56:56 +00002483
2484 // Add any type specifiers
2485 AddTypeSpecifierResults(getLangOptions(), 0, Results);
2486
2487 // Add any nested-name-specifiers
2488 Results.setFilter(&ResultBuilder::IsNestedNameSpecifier);
Douglas Gregor3f7c7f42009-10-30 16:50:04 +00002489 NextRank = CollectLookupResults(S, Context.getTranslationUnitDecl(),
2490 NextRank + 1, CurContext, Results);
Douglas Gregor8e0a0e42009-09-22 23:31:26 +00002491 Results.ExitScope();
Douglas Gregor86d9a522009-09-21 16:56:56 +00002492
Douglas Gregor0c8296d2009-11-07 00:00:49 +00002493 if (CodeCompleter->includeMacros())
2494 AddMacroResults(PP, NextRank, Results);
Daniel Dunbar3a2838d2009-11-13 08:58:20 +00002495 HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
Douglas Gregored8d3222009-09-18 20:05:18 +00002496}
Douglas Gregor49f40bd2009-09-18 19:03:04 +00002497
Douglas Gregorb6ac2452010-01-13 21:24:21 +00002498// Macro that expands to @Keyword or Keyword, depending on whether NeedAt is
2499// true or false.
2500#define OBJC_AT_KEYWORD_NAME(NeedAt,Keyword) NeedAt? "@" #Keyword : #Keyword
2501static void AddObjCImplementationResults(unsigned Rank,
2502 const LangOptions &LangOpts,
2503 ResultBuilder &Results,
2504 bool NeedAt) {
2505 typedef CodeCompleteConsumer::Result Result;
2506 // Since we have an implementation, we can end it.
2507 Results.MaybeAddResult(Result(OBJC_AT_KEYWORD_NAME(NeedAt,end), 0));
2508
2509 CodeCompletionString *Pattern = 0;
2510 if (LangOpts.ObjC2) {
2511 // @dynamic
2512 Pattern = new CodeCompletionString;
2513 Pattern->AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt,dynamic));
2514 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
2515 Pattern->AddPlaceholderChunk("property");
2516 Results.MaybeAddResult(Result(Pattern, 0));
2517
2518 // @synthesize
2519 Pattern = new CodeCompletionString;
2520 Pattern->AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt,synthesize));
2521 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
2522 Pattern->AddPlaceholderChunk("property");
2523 Results.MaybeAddResult(Result(Pattern, 0));
2524 }
2525}
2526
2527static void AddObjCInterfaceResults(unsigned Rank,
2528 const LangOptions &LangOpts,
2529 ResultBuilder &Results,
2530 bool NeedAt) {
2531 typedef CodeCompleteConsumer::Result Result;
2532
2533 // Since we have an interface or protocol, we can end it.
2534 Results.MaybeAddResult(Result(OBJC_AT_KEYWORD_NAME(NeedAt,end), 0));
2535
2536 if (LangOpts.ObjC2) {
2537 // @property
2538 Results.MaybeAddResult(Result(OBJC_AT_KEYWORD_NAME(NeedAt,property), 0));
2539
2540 // @required
2541 Results.MaybeAddResult(Result(OBJC_AT_KEYWORD_NAME(NeedAt,required), 0));
2542
2543 // @optional
2544 Results.MaybeAddResult(Result(OBJC_AT_KEYWORD_NAME(NeedAt,optional), 0));
2545 }
2546}
2547
2548static void AddObjCTopLevelResults(unsigned Rank, ResultBuilder &Results,
2549 bool NeedAt) {
2550 typedef CodeCompleteConsumer::Result Result;
2551 CodeCompletionString *Pattern = 0;
2552
2553 // @class name ;
2554 Pattern = new CodeCompletionString;
2555 Pattern->AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt,class));
2556 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
2557 Pattern->AddPlaceholderChunk("identifier");
2558 Pattern->AddChunk(CodeCompletionString::CK_SemiColon);
2559 Results.MaybeAddResult(Result(Pattern, 0));
2560
2561 // @interface name
2562 // FIXME: Could introduce the whole pattern, including superclasses and
2563 // such.
2564 Pattern = new CodeCompletionString;
2565 Pattern->AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt,interface));
2566 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
2567 Pattern->AddPlaceholderChunk("class");
2568 Results.MaybeAddResult(Result(Pattern, 0));
2569
2570 // @protocol name
2571 Pattern = new CodeCompletionString;
2572 Pattern->AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt,protocol));
2573 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
2574 Pattern->AddPlaceholderChunk("protocol");
2575 Results.MaybeAddResult(Result(Pattern, 0));
2576
2577 // @implementation name
2578 Pattern = new CodeCompletionString;
2579 Pattern->AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt,implementation));
2580 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
2581 Pattern->AddPlaceholderChunk("class");
2582 Results.MaybeAddResult(Result(Pattern, 0));
2583
2584 // @compatibility_alias name
2585 Pattern = new CodeCompletionString;
2586 Pattern->AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt,compatibility_alias));
2587 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
2588 Pattern->AddPlaceholderChunk("alias");
2589 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
2590 Pattern->AddPlaceholderChunk("class");
2591 Results.MaybeAddResult(Result(Pattern, 0));
2592}
2593
Douglas Gregorc464ae82009-12-07 09:27:33 +00002594void Sema::CodeCompleteObjCAtDirective(Scope *S, DeclPtrTy ObjCImpDecl,
2595 bool InInterface) {
2596 typedef CodeCompleteConsumer::Result Result;
2597 ResultBuilder Results(*this);
2598 Results.EnterNewScope();
Douglas Gregorb6ac2452010-01-13 21:24:21 +00002599 if (ObjCImpDecl)
2600 AddObjCImplementationResults(0, getLangOptions(), Results, false);
2601 else if (InInterface)
2602 AddObjCInterfaceResults(0, getLangOptions(), Results, false);
2603 else
2604 AddObjCTopLevelResults(0, Results, false);
Douglas Gregorc464ae82009-12-07 09:27:33 +00002605 Results.ExitScope();
2606 HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
2607}
2608
Douglas Gregorb6ac2452010-01-13 21:24:21 +00002609static void AddObjCExpressionResults(unsigned Rank, ResultBuilder &Results,
2610 bool NeedAt) {
Douglas Gregor9a0c85e2009-12-07 09:51:25 +00002611 typedef CodeCompleteConsumer::Result Result;
2612 CodeCompletionString *Pattern = 0;
2613
2614 // @encode ( type-name )
2615 Pattern = new CodeCompletionString;
Douglas Gregorb6ac2452010-01-13 21:24:21 +00002616 Pattern->AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt,encode));
Douglas Gregor9a0c85e2009-12-07 09:51:25 +00002617 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
2618 Pattern->AddPlaceholderChunk("type-name");
2619 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
2620 Results.MaybeAddResult(Result(Pattern, Rank));
2621
2622 // @protocol ( protocol-name )
2623 Pattern = new CodeCompletionString;
Douglas Gregorb6ac2452010-01-13 21:24:21 +00002624 Pattern->AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt,protocol));
Douglas Gregor9a0c85e2009-12-07 09:51:25 +00002625 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
2626 Pattern->AddPlaceholderChunk("protocol-name");
2627 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
2628 Results.MaybeAddResult(Result(Pattern, Rank));
2629
2630 // @selector ( selector )
2631 Pattern = new CodeCompletionString;
Douglas Gregorb6ac2452010-01-13 21:24:21 +00002632 Pattern->AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt,selector));
Douglas Gregor9a0c85e2009-12-07 09:51:25 +00002633 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
2634 Pattern->AddPlaceholderChunk("selector");
2635 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
2636 Results.MaybeAddResult(Result(Pattern, Rank));
2637}
2638
Douglas Gregorb6ac2452010-01-13 21:24:21 +00002639static void AddObjCStatementResults(unsigned Rank, ResultBuilder &Results,
2640 bool NeedAt) {
Douglas Gregor9a0c85e2009-12-07 09:51:25 +00002641 typedef CodeCompleteConsumer::Result Result;
Douglas Gregor9a0c85e2009-12-07 09:51:25 +00002642 CodeCompletionString *Pattern = 0;
Douglas Gregorb6ac2452010-01-13 21:24:21 +00002643
Douglas Gregor9a0c85e2009-12-07 09:51:25 +00002644 // @try { statements } @catch ( declaration ) { statements } @finally
2645 // { statements }
2646 Pattern = new CodeCompletionString;
Douglas Gregorb6ac2452010-01-13 21:24:21 +00002647 Pattern->AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt,try));
Douglas Gregor9a0c85e2009-12-07 09:51:25 +00002648 Pattern->AddChunk(CodeCompletionString::CK_LeftBrace);
2649 Pattern->AddPlaceholderChunk("statements");
2650 Pattern->AddChunk(CodeCompletionString::CK_RightBrace);
2651 Pattern->AddTextChunk("@catch");
2652 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
2653 Pattern->AddPlaceholderChunk("parameter");
2654 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
2655 Pattern->AddChunk(CodeCompletionString::CK_LeftBrace);
2656 Pattern->AddPlaceholderChunk("statements");
2657 Pattern->AddChunk(CodeCompletionString::CK_RightBrace);
2658 Pattern->AddTextChunk("@finally");
2659 Pattern->AddChunk(CodeCompletionString::CK_LeftBrace);
2660 Pattern->AddPlaceholderChunk("statements");
2661 Pattern->AddChunk(CodeCompletionString::CK_RightBrace);
2662 Results.MaybeAddResult(Result(Pattern, 0));
Douglas Gregorb6ac2452010-01-13 21:24:21 +00002663
Douglas Gregor9a0c85e2009-12-07 09:51:25 +00002664 // @throw
2665 Pattern = new CodeCompletionString;
Douglas Gregorb6ac2452010-01-13 21:24:21 +00002666 Pattern->AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt,throw));
Douglas Gregor834389b2010-01-12 06:38:28 +00002667 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
Douglas Gregor9a0c85e2009-12-07 09:51:25 +00002668 Pattern->AddPlaceholderChunk("expression");
Douglas Gregor834389b2010-01-12 06:38:28 +00002669 Pattern->AddChunk(CodeCompletionString::CK_SemiColon);
2670 Results.MaybeAddResult(Result(Pattern, 0));
Douglas Gregorb6ac2452010-01-13 21:24:21 +00002671
Douglas Gregor9a0c85e2009-12-07 09:51:25 +00002672 // @synchronized ( expression ) { statements }
2673 Pattern = new CodeCompletionString;
Douglas Gregorb6ac2452010-01-13 21:24:21 +00002674 Pattern->AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt,synchronized));
Douglas Gregor834389b2010-01-12 06:38:28 +00002675 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
Douglas Gregor9a0c85e2009-12-07 09:51:25 +00002676 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
2677 Pattern->AddPlaceholderChunk("expression");
2678 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
2679 Pattern->AddChunk(CodeCompletionString::CK_LeftBrace);
2680 Pattern->AddPlaceholderChunk("statements");
2681 Pattern->AddChunk(CodeCompletionString::CK_RightBrace);
Douglas Gregorb6ac2452010-01-13 21:24:21 +00002682 Results.MaybeAddResult(Result(Pattern, 0));
2683}
Douglas Gregor9a0c85e2009-12-07 09:51:25 +00002684
Douglas Gregorc38c3e12010-01-13 21:54:15 +00002685static void AddObjCVisibilityResults(unsigned Rank,
2686 const LangOptions &LangOpts,
2687 ResultBuilder &Results,
2688 bool NeedAt) {
Douglas Gregorb6ac2452010-01-13 21:24:21 +00002689 typedef CodeCompleteConsumer::Result Result;
Douglas Gregorc38c3e12010-01-13 21:54:15 +00002690 Results.MaybeAddResult(Result(OBJC_AT_KEYWORD_NAME(NeedAt,private), Rank));
2691 Results.MaybeAddResult(Result(OBJC_AT_KEYWORD_NAME(NeedAt,protected), Rank));
2692 Results.MaybeAddResult(Result(OBJC_AT_KEYWORD_NAME(NeedAt,public), Rank));
2693 if (LangOpts.ObjC2)
2694 Results.MaybeAddResult(Result(OBJC_AT_KEYWORD_NAME(NeedAt,package), Rank));
2695}
2696
2697void Sema::CodeCompleteObjCAtVisibility(Scope *S) {
2698 ResultBuilder Results(*this);
2699 Results.EnterNewScope();
2700 AddObjCVisibilityResults(0, getLangOptions(), Results, false);
2701 Results.ExitScope();
2702 HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
2703}
2704
2705void Sema::CodeCompleteObjCAtStatement(Scope *S) {
Douglas Gregorb6ac2452010-01-13 21:24:21 +00002706 ResultBuilder Results(*this);
2707 Results.EnterNewScope();
2708 AddObjCStatementResults(0, Results, false);
2709 AddObjCExpressionResults(0, Results, false);
Douglas Gregor9a0c85e2009-12-07 09:51:25 +00002710 Results.ExitScope();
2711 HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
2712}
2713
2714void Sema::CodeCompleteObjCAtExpression(Scope *S) {
2715 ResultBuilder Results(*this);
2716 Results.EnterNewScope();
Douglas Gregorb6ac2452010-01-13 21:24:21 +00002717 AddObjCExpressionResults(0, Results, false);
Douglas Gregor9a0c85e2009-12-07 09:51:25 +00002718 Results.ExitScope();
2719 HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
2720}
2721
Douglas Gregor988358f2009-11-19 00:14:45 +00002722/// \brief Determine whether the addition of the given flag to an Objective-C
2723/// property's attributes will cause a conflict.
2724static bool ObjCPropertyFlagConflicts(unsigned Attributes, unsigned NewFlag) {
2725 // Check if we've already added this flag.
2726 if (Attributes & NewFlag)
2727 return true;
2728
2729 Attributes |= NewFlag;
2730
2731 // Check for collisions with "readonly".
2732 if ((Attributes & ObjCDeclSpec::DQ_PR_readonly) &&
2733 (Attributes & (ObjCDeclSpec::DQ_PR_readwrite |
2734 ObjCDeclSpec::DQ_PR_assign |
2735 ObjCDeclSpec::DQ_PR_copy |
2736 ObjCDeclSpec::DQ_PR_retain)))
2737 return true;
2738
2739 // Check for more than one of { assign, copy, retain }.
2740 unsigned AssignCopyRetMask = Attributes & (ObjCDeclSpec::DQ_PR_assign |
2741 ObjCDeclSpec::DQ_PR_copy |
2742 ObjCDeclSpec::DQ_PR_retain);
2743 if (AssignCopyRetMask &&
2744 AssignCopyRetMask != ObjCDeclSpec::DQ_PR_assign &&
2745 AssignCopyRetMask != ObjCDeclSpec::DQ_PR_copy &&
2746 AssignCopyRetMask != ObjCDeclSpec::DQ_PR_retain)
2747 return true;
2748
2749 return false;
2750}
2751
Douglas Gregora93b1082009-11-18 23:08:07 +00002752void Sema::CodeCompleteObjCPropertyFlags(Scope *S, ObjCDeclSpec &ODS) {
Steve Naroffece8e712009-10-08 21:55:05 +00002753 if (!CodeCompleter)
2754 return;
Douglas Gregord3c68542009-11-19 01:08:35 +00002755
Steve Naroffece8e712009-10-08 21:55:05 +00002756 unsigned Attributes = ODS.getPropertyAttributes();
2757
2758 typedef CodeCompleteConsumer::Result Result;
2759 ResultBuilder Results(*this);
2760 Results.EnterNewScope();
Douglas Gregor988358f2009-11-19 00:14:45 +00002761 if (!ObjCPropertyFlagConflicts(Attributes, ObjCDeclSpec::DQ_PR_readonly))
Steve Naroffece8e712009-10-08 21:55:05 +00002762 Results.MaybeAddResult(CodeCompleteConsumer::Result("readonly", 0));
Douglas Gregor988358f2009-11-19 00:14:45 +00002763 if (!ObjCPropertyFlagConflicts(Attributes, ObjCDeclSpec::DQ_PR_assign))
Steve Naroffece8e712009-10-08 21:55:05 +00002764 Results.MaybeAddResult(CodeCompleteConsumer::Result("assign", 0));
Douglas Gregor988358f2009-11-19 00:14:45 +00002765 if (!ObjCPropertyFlagConflicts(Attributes, ObjCDeclSpec::DQ_PR_readwrite))
Steve Naroffece8e712009-10-08 21:55:05 +00002766 Results.MaybeAddResult(CodeCompleteConsumer::Result("readwrite", 0));
Douglas Gregor988358f2009-11-19 00:14:45 +00002767 if (!ObjCPropertyFlagConflicts(Attributes, ObjCDeclSpec::DQ_PR_retain))
Steve Naroffece8e712009-10-08 21:55:05 +00002768 Results.MaybeAddResult(CodeCompleteConsumer::Result("retain", 0));
Douglas Gregor988358f2009-11-19 00:14:45 +00002769 if (!ObjCPropertyFlagConflicts(Attributes, ObjCDeclSpec::DQ_PR_copy))
Steve Naroffece8e712009-10-08 21:55:05 +00002770 Results.MaybeAddResult(CodeCompleteConsumer::Result("copy", 0));
Douglas Gregor988358f2009-11-19 00:14:45 +00002771 if (!ObjCPropertyFlagConflicts(Attributes, ObjCDeclSpec::DQ_PR_nonatomic))
Steve Naroffece8e712009-10-08 21:55:05 +00002772 Results.MaybeAddResult(CodeCompleteConsumer::Result("nonatomic", 0));
Douglas Gregor988358f2009-11-19 00:14:45 +00002773 if (!ObjCPropertyFlagConflicts(Attributes, ObjCDeclSpec::DQ_PR_setter)) {
Douglas Gregor54f01612009-11-19 00:01:57 +00002774 CodeCompletionString *Setter = new CodeCompletionString;
2775 Setter->AddTypedTextChunk("setter");
2776 Setter->AddTextChunk(" = ");
2777 Setter->AddPlaceholderChunk("method");
2778 Results.MaybeAddResult(CodeCompleteConsumer::Result(Setter, 0));
2779 }
Douglas Gregor988358f2009-11-19 00:14:45 +00002780 if (!ObjCPropertyFlagConflicts(Attributes, ObjCDeclSpec::DQ_PR_getter)) {
Douglas Gregor54f01612009-11-19 00:01:57 +00002781 CodeCompletionString *Getter = new CodeCompletionString;
2782 Getter->AddTypedTextChunk("getter");
2783 Getter->AddTextChunk(" = ");
2784 Getter->AddPlaceholderChunk("method");
2785 Results.MaybeAddResult(CodeCompleteConsumer::Result(Getter, 0));
2786 }
Steve Naroffece8e712009-10-08 21:55:05 +00002787 Results.ExitScope();
Daniel Dunbar3a2838d2009-11-13 08:58:20 +00002788 HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
Steve Naroffece8e712009-10-08 21:55:05 +00002789}
Steve Naroffc4df6d22009-11-07 02:08:14 +00002790
Douglas Gregor4ad96852009-11-19 07:41:15 +00002791/// \brief Descripts the kind of Objective-C method that we want to find
2792/// via code completion.
2793enum ObjCMethodKind {
2794 MK_Any, //< Any kind of method, provided it means other specified criteria.
2795 MK_ZeroArgSelector, //< Zero-argument (unary) selector.
2796 MK_OneArgSelector //< One-argument selector.
2797};
2798
2799static bool isAcceptableObjCMethod(ObjCMethodDecl *Method,
2800 ObjCMethodKind WantKind,
2801 IdentifierInfo **SelIdents,
2802 unsigned NumSelIdents) {
2803 Selector Sel = Method->getSelector();
2804 if (NumSelIdents > Sel.getNumArgs())
2805 return false;
2806
2807 switch (WantKind) {
2808 case MK_Any: break;
2809 case MK_ZeroArgSelector: return Sel.isUnarySelector();
2810 case MK_OneArgSelector: return Sel.getNumArgs() == 1;
2811 }
2812
2813 for (unsigned I = 0; I != NumSelIdents; ++I)
2814 if (SelIdents[I] != Sel.getIdentifierInfoForSlot(I))
2815 return false;
2816
2817 return true;
2818}
2819
Douglas Gregor36ecb042009-11-17 23:22:23 +00002820/// \brief Add all of the Objective-C methods in the given Objective-C
2821/// container to the set of results.
2822///
2823/// The container will be a class, protocol, category, or implementation of
2824/// any of the above. This mether will recurse to include methods from
2825/// the superclasses of classes along with their categories, protocols, and
2826/// implementations.
2827///
2828/// \param Container the container in which we'll look to find methods.
2829///
2830/// \param WantInstance whether to add instance methods (only); if false, this
2831/// routine will add factory methods (only).
2832///
2833/// \param CurContext the context in which we're performing the lookup that
2834/// finds methods.
2835///
2836/// \param Results the structure into which we'll add results.
2837static void AddObjCMethods(ObjCContainerDecl *Container,
2838 bool WantInstanceMethods,
Douglas Gregor4ad96852009-11-19 07:41:15 +00002839 ObjCMethodKind WantKind,
Douglas Gregord3c68542009-11-19 01:08:35 +00002840 IdentifierInfo **SelIdents,
2841 unsigned NumSelIdents,
Douglas Gregor36ecb042009-11-17 23:22:23 +00002842 DeclContext *CurContext,
2843 ResultBuilder &Results) {
2844 typedef CodeCompleteConsumer::Result Result;
2845 for (ObjCContainerDecl::method_iterator M = Container->meth_begin(),
2846 MEnd = Container->meth_end();
2847 M != MEnd; ++M) {
Douglas Gregord3c68542009-11-19 01:08:35 +00002848 if ((*M)->isInstanceMethod() == WantInstanceMethods) {
2849 // Check whether the selector identifiers we've been given are a
2850 // subset of the identifiers for this particular method.
Douglas Gregor4ad96852009-11-19 07:41:15 +00002851 if (!isAcceptableObjCMethod(*M, WantKind, SelIdents, NumSelIdents))
Douglas Gregord3c68542009-11-19 01:08:35 +00002852 continue;
Douglas Gregor4ad96852009-11-19 07:41:15 +00002853
Douglas Gregord3c68542009-11-19 01:08:35 +00002854 Result R = Result(*M, 0);
2855 R.StartParameter = NumSelIdents;
Douglas Gregor4ad96852009-11-19 07:41:15 +00002856 R.AllParametersAreInformative = (WantKind != MK_Any);
Douglas Gregord3c68542009-11-19 01:08:35 +00002857 Results.MaybeAddResult(R, CurContext);
2858 }
Douglas Gregor36ecb042009-11-17 23:22:23 +00002859 }
2860
2861 ObjCInterfaceDecl *IFace = dyn_cast<ObjCInterfaceDecl>(Container);
2862 if (!IFace)
2863 return;
2864
2865 // Add methods in protocols.
2866 const ObjCList<ObjCProtocolDecl> &Protocols= IFace->getReferencedProtocols();
2867 for (ObjCList<ObjCProtocolDecl>::iterator I = Protocols.begin(),
2868 E = Protocols.end();
2869 I != E; ++I)
Douglas Gregor4ad96852009-11-19 07:41:15 +00002870 AddObjCMethods(*I, WantInstanceMethods, WantKind, SelIdents, NumSelIdents,
Douglas Gregord3c68542009-11-19 01:08:35 +00002871 CurContext, Results);
Douglas Gregor36ecb042009-11-17 23:22:23 +00002872
2873 // Add methods in categories.
2874 for (ObjCCategoryDecl *CatDecl = IFace->getCategoryList(); CatDecl;
2875 CatDecl = CatDecl->getNextClassCategory()) {
Douglas Gregor4ad96852009-11-19 07:41:15 +00002876 AddObjCMethods(CatDecl, WantInstanceMethods, WantKind, SelIdents,
2877 NumSelIdents, CurContext, Results);
Douglas Gregor36ecb042009-11-17 23:22:23 +00002878
2879 // Add a categories protocol methods.
2880 const ObjCList<ObjCProtocolDecl> &Protocols
2881 = CatDecl->getReferencedProtocols();
2882 for (ObjCList<ObjCProtocolDecl>::iterator I = Protocols.begin(),
2883 E = Protocols.end();
2884 I != E; ++I)
Douglas Gregor4ad96852009-11-19 07:41:15 +00002885 AddObjCMethods(*I, WantInstanceMethods, WantKind, SelIdents,
2886 NumSelIdents, CurContext, Results);
Douglas Gregor36ecb042009-11-17 23:22:23 +00002887
2888 // Add methods in category implementations.
2889 if (ObjCCategoryImplDecl *Impl = CatDecl->getImplementation())
Douglas Gregor4ad96852009-11-19 07:41:15 +00002890 AddObjCMethods(Impl, WantInstanceMethods, WantKind, SelIdents,
2891 NumSelIdents, CurContext, Results);
Douglas Gregor36ecb042009-11-17 23:22:23 +00002892 }
2893
2894 // Add methods in superclass.
2895 if (IFace->getSuperClass())
Douglas Gregor4ad96852009-11-19 07:41:15 +00002896 AddObjCMethods(IFace->getSuperClass(), WantInstanceMethods, WantKind,
2897 SelIdents, NumSelIdents, CurContext, Results);
Douglas Gregor36ecb042009-11-17 23:22:23 +00002898
2899 // Add methods in our implementation, if any.
2900 if (ObjCImplementationDecl *Impl = IFace->getImplementation())
Douglas Gregor4ad96852009-11-19 07:41:15 +00002901 AddObjCMethods(Impl, WantInstanceMethods, WantKind, SelIdents,
2902 NumSelIdents, CurContext, Results);
2903}
2904
2905
2906void Sema::CodeCompleteObjCPropertyGetter(Scope *S, DeclPtrTy ClassDecl,
2907 DeclPtrTy *Methods,
2908 unsigned NumMethods) {
2909 typedef CodeCompleteConsumer::Result Result;
2910
2911 // Try to find the interface where getters might live.
2912 ObjCInterfaceDecl *Class
2913 = dyn_cast_or_null<ObjCInterfaceDecl>(ClassDecl.getAs<Decl>());
2914 if (!Class) {
2915 if (ObjCCategoryDecl *Category
2916 = dyn_cast_or_null<ObjCCategoryDecl>(ClassDecl.getAs<Decl>()))
2917 Class = Category->getClassInterface();
2918
2919 if (!Class)
2920 return;
2921 }
2922
2923 // Find all of the potential getters.
2924 ResultBuilder Results(*this);
2925 Results.EnterNewScope();
2926
2927 // FIXME: We need to do this because Objective-C methods don't get
2928 // pushed into DeclContexts early enough. Argh!
2929 for (unsigned I = 0; I != NumMethods; ++I) {
2930 if (ObjCMethodDecl *Method
2931 = dyn_cast_or_null<ObjCMethodDecl>(Methods[I].getAs<Decl>()))
2932 if (Method->isInstanceMethod() &&
2933 isAcceptableObjCMethod(Method, MK_ZeroArgSelector, 0, 0)) {
2934 Result R = Result(Method, 0);
2935 R.AllParametersAreInformative = true;
2936 Results.MaybeAddResult(R, CurContext);
2937 }
2938 }
2939
2940 AddObjCMethods(Class, true, MK_ZeroArgSelector, 0, 0, CurContext, Results);
2941 Results.ExitScope();
2942 HandleCodeCompleteResults(this, CodeCompleter,Results.data(),Results.size());
2943}
2944
2945void Sema::CodeCompleteObjCPropertySetter(Scope *S, DeclPtrTy ObjCImplDecl,
2946 DeclPtrTy *Methods,
2947 unsigned NumMethods) {
2948 typedef CodeCompleteConsumer::Result Result;
2949
2950 // Try to find the interface where setters might live.
2951 ObjCInterfaceDecl *Class
2952 = dyn_cast_or_null<ObjCInterfaceDecl>(ObjCImplDecl.getAs<Decl>());
2953 if (!Class) {
2954 if (ObjCCategoryDecl *Category
2955 = dyn_cast_or_null<ObjCCategoryDecl>(ObjCImplDecl.getAs<Decl>()))
2956 Class = Category->getClassInterface();
2957
2958 if (!Class)
2959 return;
2960 }
2961
2962 // Find all of the potential getters.
2963 ResultBuilder Results(*this);
2964 Results.EnterNewScope();
2965
2966 // FIXME: We need to do this because Objective-C methods don't get
2967 // pushed into DeclContexts early enough. Argh!
2968 for (unsigned I = 0; I != NumMethods; ++I) {
2969 if (ObjCMethodDecl *Method
2970 = dyn_cast_or_null<ObjCMethodDecl>(Methods[I].getAs<Decl>()))
2971 if (Method->isInstanceMethod() &&
2972 isAcceptableObjCMethod(Method, MK_OneArgSelector, 0, 0)) {
2973 Result R = Result(Method, 0);
2974 R.AllParametersAreInformative = true;
2975 Results.MaybeAddResult(R, CurContext);
2976 }
2977 }
2978
2979 AddObjCMethods(Class, true, MK_OneArgSelector, 0, 0, CurContext, Results);
2980
2981 Results.ExitScope();
2982 HandleCodeCompleteResults(this, CodeCompleter,Results.data(),Results.size());
Douglas Gregor36ecb042009-11-17 23:22:23 +00002983}
2984
Douglas Gregor60b01cc2009-11-17 23:31:36 +00002985void Sema::CodeCompleteObjCClassMessage(Scope *S, IdentifierInfo *FName,
Douglas Gregord3c68542009-11-19 01:08:35 +00002986 SourceLocation FNameLoc,
2987 IdentifierInfo **SelIdents,
2988 unsigned NumSelIdents) {
Steve Naroffc4df6d22009-11-07 02:08:14 +00002989 typedef CodeCompleteConsumer::Result Result;
Douglas Gregor24a069f2009-11-17 17:59:40 +00002990 ObjCInterfaceDecl *CDecl = 0;
2991
Douglas Gregor24a069f2009-11-17 17:59:40 +00002992 if (FName->isStr("super")) {
2993 // We're sending a message to "super".
2994 if (ObjCMethodDecl *CurMethod = getCurMethodDecl()) {
2995 // Figure out which interface we're in.
2996 CDecl = CurMethod->getClassInterface();
2997 if (!CDecl)
2998 return;
2999
3000 // Find the superclass of this class.
3001 CDecl = CDecl->getSuperClass();
3002 if (!CDecl)
3003 return;
3004
3005 if (CurMethod->isInstanceMethod()) {
3006 // We are inside an instance method, which means that the message
3007 // send [super ...] is actually calling an instance method on the
3008 // current object. Build the super expression and handle this like
3009 // an instance method.
3010 QualType SuperTy = Context.getObjCInterfaceType(CDecl);
3011 SuperTy = Context.getObjCObjectPointerType(SuperTy);
3012 OwningExprResult Super
Douglas Gregor60b01cc2009-11-17 23:31:36 +00003013 = Owned(new (Context) ObjCSuperExpr(FNameLoc, SuperTy));
Douglas Gregord3c68542009-11-19 01:08:35 +00003014 return CodeCompleteObjCInstanceMessage(S, (Expr *)Super.get(),
3015 SelIdents, NumSelIdents);
Douglas Gregor24a069f2009-11-17 17:59:40 +00003016 }
3017
3018 // Okay, we're calling a factory method in our superclass.
3019 }
3020 }
3021
3022 // If the given name refers to an interface type, retrieve the
3023 // corresponding declaration.
3024 if (!CDecl)
Douglas Gregor60b01cc2009-11-17 23:31:36 +00003025 if (TypeTy *Ty = getTypeName(*FName, FNameLoc, S, 0, false)) {
Douglas Gregor24a069f2009-11-17 17:59:40 +00003026 QualType T = GetTypeFromParser(Ty, 0);
3027 if (!T.isNull())
3028 if (const ObjCInterfaceType *Interface = T->getAs<ObjCInterfaceType>())
3029 CDecl = Interface->getDecl();
3030 }
3031
3032 if (!CDecl && FName->isStr("super")) {
3033 // "super" may be the name of a variable, in which case we are
3034 // probably calling an instance method.
John McCallf7a1a742009-11-24 19:00:30 +00003035 CXXScopeSpec SS;
3036 UnqualifiedId id;
3037 id.setIdentifier(FName, FNameLoc);
3038 OwningExprResult Super = ActOnIdExpression(S, SS, id, false, false);
Douglas Gregord3c68542009-11-19 01:08:35 +00003039 return CodeCompleteObjCInstanceMessage(S, (Expr *)Super.get(),
3040 SelIdents, NumSelIdents);
Douglas Gregor24a069f2009-11-17 17:59:40 +00003041 }
3042
Douglas Gregor36ecb042009-11-17 23:22:23 +00003043 // Add all of the factory methods in this Objective-C class, its protocols,
3044 // superclasses, categories, implementation, etc.
Steve Naroffc4df6d22009-11-07 02:08:14 +00003045 ResultBuilder Results(*this);
3046 Results.EnterNewScope();
Douglas Gregor4ad96852009-11-19 07:41:15 +00003047 AddObjCMethods(CDecl, false, MK_Any, SelIdents, NumSelIdents, CurContext,
3048 Results);
Steve Naroffc4df6d22009-11-07 02:08:14 +00003049 Results.ExitScope();
Douglas Gregor36ecb042009-11-17 23:22:23 +00003050
Steve Naroffc4df6d22009-11-07 02:08:14 +00003051 // This also suppresses remaining diagnostics.
Daniel Dunbar3a2838d2009-11-13 08:58:20 +00003052 HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
Steve Naroffc4df6d22009-11-07 02:08:14 +00003053}
3054
Douglas Gregord3c68542009-11-19 01:08:35 +00003055void Sema::CodeCompleteObjCInstanceMessage(Scope *S, ExprTy *Receiver,
3056 IdentifierInfo **SelIdents,
3057 unsigned NumSelIdents) {
Steve Naroffc4df6d22009-11-07 02:08:14 +00003058 typedef CodeCompleteConsumer::Result Result;
Steve Naroffc4df6d22009-11-07 02:08:14 +00003059
3060 Expr *RecExpr = static_cast<Expr *>(Receiver);
Steve Naroffc4df6d22009-11-07 02:08:14 +00003061
Douglas Gregor36ecb042009-11-17 23:22:23 +00003062 // If necessary, apply function/array conversion to the receiver.
3063 // C99 6.7.5.3p[7,8].
3064 DefaultFunctionArrayConversion(RecExpr);
3065 QualType ReceiverType = RecExpr->getType();
Steve Naroffc4df6d22009-11-07 02:08:14 +00003066
Douglas Gregor36ecb042009-11-17 23:22:23 +00003067 if (ReceiverType->isObjCIdType() || ReceiverType->isBlockPointerType()) {
3068 // FIXME: We're messaging 'id'. Do we actually want to look up every method
3069 // in the universe?
3070 return;
3071 }
3072
Douglas Gregor36ecb042009-11-17 23:22:23 +00003073 // Build the set of methods we can see.
3074 ResultBuilder Results(*this);
3075 Results.EnterNewScope();
Douglas Gregor36ecb042009-11-17 23:22:23 +00003076
Douglas Gregorf74a4192009-11-18 00:06:18 +00003077 // Handle messages to Class. This really isn't a message to an instance
3078 // method, so we treat it the same way we would treat a message send to a
3079 // class method.
3080 if (ReceiverType->isObjCClassType() ||
3081 ReceiverType->isObjCQualifiedClassType()) {
3082 if (ObjCMethodDecl *CurMethod = getCurMethodDecl()) {
3083 if (ObjCInterfaceDecl *ClassDecl = CurMethod->getClassInterface())
Douglas Gregor4ad96852009-11-19 07:41:15 +00003084 AddObjCMethods(ClassDecl, false, MK_Any, SelIdents, NumSelIdents,
3085 CurContext, Results);
Douglas Gregorf74a4192009-11-18 00:06:18 +00003086 }
3087 }
3088 // Handle messages to a qualified ID ("id<foo>").
3089 else if (const ObjCObjectPointerType *QualID
3090 = ReceiverType->getAsObjCQualifiedIdType()) {
3091 // Search protocols for instance methods.
3092 for (ObjCObjectPointerType::qual_iterator I = QualID->qual_begin(),
3093 E = QualID->qual_end();
3094 I != E; ++I)
Douglas Gregor4ad96852009-11-19 07:41:15 +00003095 AddObjCMethods(*I, true, MK_Any, SelIdents, NumSelIdents, CurContext,
3096 Results);
Douglas Gregorf74a4192009-11-18 00:06:18 +00003097 }
3098 // Handle messages to a pointer to interface type.
3099 else if (const ObjCObjectPointerType *IFacePtr
3100 = ReceiverType->getAsObjCInterfacePointerType()) {
3101 // Search the class, its superclasses, etc., for instance methods.
Douglas Gregor4ad96852009-11-19 07:41:15 +00003102 AddObjCMethods(IFacePtr->getInterfaceDecl(), true, MK_Any, SelIdents,
3103 NumSelIdents, CurContext, Results);
Douglas Gregorf74a4192009-11-18 00:06:18 +00003104
3105 // Search protocols for instance methods.
3106 for (ObjCObjectPointerType::qual_iterator I = IFacePtr->qual_begin(),
3107 E = IFacePtr->qual_end();
3108 I != E; ++I)
Douglas Gregor4ad96852009-11-19 07:41:15 +00003109 AddObjCMethods(*I, true, MK_Any, SelIdents, NumSelIdents, CurContext,
3110 Results);
Douglas Gregorf74a4192009-11-18 00:06:18 +00003111 }
3112
Steve Naroffc4df6d22009-11-07 02:08:14 +00003113 Results.ExitScope();
Daniel Dunbar3a2838d2009-11-13 08:58:20 +00003114 HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
Steve Naroffc4df6d22009-11-07 02:08:14 +00003115}
Douglas Gregor55385fe2009-11-18 04:19:12 +00003116
3117/// \brief Add all of the protocol declarations that we find in the given
3118/// (translation unit) context.
3119static void AddProtocolResults(DeclContext *Ctx, DeclContext *CurContext,
Douglas Gregor083128f2009-11-18 04:49:41 +00003120 bool OnlyForwardDeclarations,
Douglas Gregor55385fe2009-11-18 04:19:12 +00003121 ResultBuilder &Results) {
3122 typedef CodeCompleteConsumer::Result Result;
3123
3124 for (DeclContext::decl_iterator D = Ctx->decls_begin(),
3125 DEnd = Ctx->decls_end();
3126 D != DEnd; ++D) {
3127 // Record any protocols we find.
3128 if (ObjCProtocolDecl *Proto = dyn_cast<ObjCProtocolDecl>(*D))
Douglas Gregor083128f2009-11-18 04:49:41 +00003129 if (!OnlyForwardDeclarations || Proto->isForwardDecl())
3130 Results.MaybeAddResult(Result(Proto, 0), CurContext);
Douglas Gregor55385fe2009-11-18 04:19:12 +00003131
3132 // Record any forward-declared protocols we find.
3133 if (ObjCForwardProtocolDecl *Forward
3134 = dyn_cast<ObjCForwardProtocolDecl>(*D)) {
3135 for (ObjCForwardProtocolDecl::protocol_iterator
3136 P = Forward->protocol_begin(),
3137 PEnd = Forward->protocol_end();
3138 P != PEnd; ++P)
Douglas Gregor083128f2009-11-18 04:49:41 +00003139 if (!OnlyForwardDeclarations || (*P)->isForwardDecl())
3140 Results.MaybeAddResult(Result(*P, 0), CurContext);
Douglas Gregor55385fe2009-11-18 04:19:12 +00003141 }
3142 }
3143}
3144
3145void Sema::CodeCompleteObjCProtocolReferences(IdentifierLocPair *Protocols,
3146 unsigned NumProtocols) {
3147 ResultBuilder Results(*this);
3148 Results.EnterNewScope();
3149
3150 // Tell the result set to ignore all of the protocols we have
3151 // already seen.
3152 for (unsigned I = 0; I != NumProtocols; ++I)
3153 if (ObjCProtocolDecl *Protocol = LookupProtocol(Protocols[I].first))
3154 Results.Ignore(Protocol);
3155
3156 // Add all protocols.
Douglas Gregor083128f2009-11-18 04:49:41 +00003157 AddProtocolResults(Context.getTranslationUnitDecl(), CurContext, false,
3158 Results);
3159
3160 Results.ExitScope();
3161 HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
3162}
3163
3164void Sema::CodeCompleteObjCProtocolDecl(Scope *) {
3165 ResultBuilder Results(*this);
3166 Results.EnterNewScope();
3167
3168 // Add all protocols.
3169 AddProtocolResults(Context.getTranslationUnitDecl(), CurContext, true,
3170 Results);
Douglas Gregor55385fe2009-11-18 04:19:12 +00003171
3172 Results.ExitScope();
3173 HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
3174}
Douglas Gregor3b49aca2009-11-18 16:26:39 +00003175
3176/// \brief Add all of the Objective-C interface declarations that we find in
3177/// the given (translation unit) context.
3178static void AddInterfaceResults(DeclContext *Ctx, DeclContext *CurContext,
3179 bool OnlyForwardDeclarations,
3180 bool OnlyUnimplemented,
3181 ResultBuilder &Results) {
3182 typedef CodeCompleteConsumer::Result Result;
3183
3184 for (DeclContext::decl_iterator D = Ctx->decls_begin(),
3185 DEnd = Ctx->decls_end();
3186 D != DEnd; ++D) {
3187 // Record any interfaces we find.
3188 if (ObjCInterfaceDecl *Class = dyn_cast<ObjCInterfaceDecl>(*D))
3189 if ((!OnlyForwardDeclarations || Class->isForwardDecl()) &&
3190 (!OnlyUnimplemented || !Class->getImplementation()))
3191 Results.MaybeAddResult(Result(Class, 0), CurContext);
3192
3193 // Record any forward-declared interfaces we find.
3194 if (ObjCClassDecl *Forward = dyn_cast<ObjCClassDecl>(*D)) {
3195 for (ObjCClassDecl::iterator C = Forward->begin(), CEnd = Forward->end();
3196 C != CEnd; ++C)
3197 if ((!OnlyForwardDeclarations || C->getInterface()->isForwardDecl()) &&
3198 (!OnlyUnimplemented || !C->getInterface()->getImplementation()))
3199 Results.MaybeAddResult(Result(C->getInterface(), 0), CurContext);
3200 }
3201 }
3202}
3203
3204void Sema::CodeCompleteObjCInterfaceDecl(Scope *S) {
3205 ResultBuilder Results(*this);
3206 Results.EnterNewScope();
3207
3208 // Add all classes.
3209 AddInterfaceResults(Context.getTranslationUnitDecl(), CurContext, true,
3210 false, Results);
3211
3212 Results.ExitScope();
3213 HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
3214}
3215
3216void Sema::CodeCompleteObjCSuperclass(Scope *S, IdentifierInfo *ClassName) {
3217 ResultBuilder Results(*this);
3218 Results.EnterNewScope();
3219
3220 // Make sure that we ignore the class we're currently defining.
3221 NamedDecl *CurClass
3222 = LookupSingleName(TUScope, ClassName, LookupOrdinaryName);
Douglas Gregor33ced0b2009-11-18 19:08:43 +00003223 if (CurClass && isa<ObjCInterfaceDecl>(CurClass))
Douglas Gregor3b49aca2009-11-18 16:26:39 +00003224 Results.Ignore(CurClass);
3225
3226 // Add all classes.
3227 AddInterfaceResults(Context.getTranslationUnitDecl(), CurContext, false,
3228 false, Results);
3229
3230 Results.ExitScope();
3231 HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
3232}
3233
3234void Sema::CodeCompleteObjCImplementationDecl(Scope *S) {
3235 ResultBuilder Results(*this);
3236 Results.EnterNewScope();
3237
3238 // Add all unimplemented classes.
3239 AddInterfaceResults(Context.getTranslationUnitDecl(), CurContext, false,
3240 true, Results);
3241
3242 Results.ExitScope();
3243 HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
3244}
Douglas Gregor33ced0b2009-11-18 19:08:43 +00003245
3246void Sema::CodeCompleteObjCInterfaceCategory(Scope *S,
3247 IdentifierInfo *ClassName) {
3248 typedef CodeCompleteConsumer::Result Result;
3249
3250 ResultBuilder Results(*this);
3251
3252 // Ignore any categories we find that have already been implemented by this
3253 // interface.
3254 llvm::SmallPtrSet<IdentifierInfo *, 16> CategoryNames;
3255 NamedDecl *CurClass
3256 = LookupSingleName(TUScope, ClassName, LookupOrdinaryName);
3257 if (ObjCInterfaceDecl *Class = dyn_cast_or_null<ObjCInterfaceDecl>(CurClass))
3258 for (ObjCCategoryDecl *Category = Class->getCategoryList(); Category;
3259 Category = Category->getNextClassCategory())
3260 CategoryNames.insert(Category->getIdentifier());
3261
3262 // Add all of the categories we know about.
3263 Results.EnterNewScope();
3264 TranslationUnitDecl *TU = Context.getTranslationUnitDecl();
3265 for (DeclContext::decl_iterator D = TU->decls_begin(),
3266 DEnd = TU->decls_end();
3267 D != DEnd; ++D)
3268 if (ObjCCategoryDecl *Category = dyn_cast<ObjCCategoryDecl>(*D))
3269 if (CategoryNames.insert(Category->getIdentifier()))
3270 Results.MaybeAddResult(Result(Category, 0), CurContext);
3271 Results.ExitScope();
3272
3273 HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
3274}
3275
3276void Sema::CodeCompleteObjCImplementationCategory(Scope *S,
3277 IdentifierInfo *ClassName) {
3278 typedef CodeCompleteConsumer::Result Result;
3279
3280 // Find the corresponding interface. If we couldn't find the interface, the
3281 // program itself is ill-formed. However, we'll try to be helpful still by
3282 // providing the list of all of the categories we know about.
3283 NamedDecl *CurClass
3284 = LookupSingleName(TUScope, ClassName, LookupOrdinaryName);
3285 ObjCInterfaceDecl *Class = dyn_cast_or_null<ObjCInterfaceDecl>(CurClass);
3286 if (!Class)
3287 return CodeCompleteObjCInterfaceCategory(S, ClassName);
3288
3289 ResultBuilder Results(*this);
3290
3291 // Add all of the categories that have have corresponding interface
3292 // declarations in this class and any of its superclasses, except for
3293 // already-implemented categories in the class itself.
3294 llvm::SmallPtrSet<IdentifierInfo *, 16> CategoryNames;
3295 Results.EnterNewScope();
3296 bool IgnoreImplemented = true;
3297 while (Class) {
3298 for (ObjCCategoryDecl *Category = Class->getCategoryList(); Category;
3299 Category = Category->getNextClassCategory())
3300 if ((!IgnoreImplemented || !Category->getImplementation()) &&
3301 CategoryNames.insert(Category->getIdentifier()))
3302 Results.MaybeAddResult(Result(Category, 0), CurContext);
3303
3304 Class = Class->getSuperClass();
3305 IgnoreImplemented = false;
3306 }
3307 Results.ExitScope();
3308
3309 HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
3310}
Douglas Gregor322328b2009-11-18 22:32:06 +00003311
Douglas Gregor424b2a52009-11-18 22:56:13 +00003312void Sema::CodeCompleteObjCPropertyDefinition(Scope *S, DeclPtrTy ObjCImpDecl) {
Douglas Gregor322328b2009-11-18 22:32:06 +00003313 typedef CodeCompleteConsumer::Result Result;
3314 ResultBuilder Results(*this);
3315
3316 // Figure out where this @synthesize lives.
3317 ObjCContainerDecl *Container
3318 = dyn_cast_or_null<ObjCContainerDecl>(ObjCImpDecl.getAs<Decl>());
3319 if (!Container ||
3320 (!isa<ObjCImplementationDecl>(Container) &&
3321 !isa<ObjCCategoryImplDecl>(Container)))
3322 return;
3323
3324 // Ignore any properties that have already been implemented.
3325 for (DeclContext::decl_iterator D = Container->decls_begin(),
3326 DEnd = Container->decls_end();
3327 D != DEnd; ++D)
3328 if (ObjCPropertyImplDecl *PropertyImpl = dyn_cast<ObjCPropertyImplDecl>(*D))
3329 Results.Ignore(PropertyImpl->getPropertyDecl());
3330
3331 // Add any properties that we find.
3332 Results.EnterNewScope();
3333 if (ObjCImplementationDecl *ClassImpl
3334 = dyn_cast<ObjCImplementationDecl>(Container))
3335 AddObjCProperties(ClassImpl->getClassInterface(), false, CurContext,
3336 Results);
3337 else
3338 AddObjCProperties(cast<ObjCCategoryImplDecl>(Container)->getCategoryDecl(),
3339 false, CurContext, Results);
3340 Results.ExitScope();
3341
3342 HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
3343}
3344
3345void Sema::CodeCompleteObjCPropertySynthesizeIvar(Scope *S,
3346 IdentifierInfo *PropertyName,
3347 DeclPtrTy ObjCImpDecl) {
3348 typedef CodeCompleteConsumer::Result Result;
3349 ResultBuilder Results(*this);
3350
3351 // Figure out where this @synthesize lives.
3352 ObjCContainerDecl *Container
3353 = dyn_cast_or_null<ObjCContainerDecl>(ObjCImpDecl.getAs<Decl>());
3354 if (!Container ||
3355 (!isa<ObjCImplementationDecl>(Container) &&
3356 !isa<ObjCCategoryImplDecl>(Container)))
3357 return;
3358
3359 // Figure out which interface we're looking into.
3360 ObjCInterfaceDecl *Class = 0;
3361 if (ObjCImplementationDecl *ClassImpl
3362 = dyn_cast<ObjCImplementationDecl>(Container))
3363 Class = ClassImpl->getClassInterface();
3364 else
3365 Class = cast<ObjCCategoryImplDecl>(Container)->getCategoryDecl()
3366 ->getClassInterface();
3367
3368 // Add all of the instance variables in this class and its superclasses.
3369 Results.EnterNewScope();
3370 for(; Class; Class = Class->getSuperClass()) {
3371 // FIXME: We could screen the type of each ivar for compatibility with
3372 // the property, but is that being too paternal?
3373 for (ObjCInterfaceDecl::ivar_iterator IVar = Class->ivar_begin(),
3374 IVarEnd = Class->ivar_end();
3375 IVar != IVarEnd; ++IVar)
3376 Results.MaybeAddResult(Result(*IVar, 0), CurContext);
3377 }
3378 Results.ExitScope();
3379
3380 HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
3381}