blob: 66b04a25bcfdd0cc5d27c4ceda2551fe870fc3ce [file] [log] [blame]
Douglas Gregor81b747b2009-09-17 21:32:03 +00001//===---------------- SemaCodeComplete.cpp - Code Completion ----*- C++ -*-===//
2//
3// The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9//
10// This file defines the code-completion semantic actions.
11//
12//===----------------------------------------------------------------------===//
13#include "Sema.h"
Douglas Gregor1ca6ae82010-01-14 01:09:38 +000014#include "Lookup.h"
Douglas Gregor81b747b2009-09-17 21:32:03 +000015#include "clang/Sema/CodeCompleteConsumer.h"
Douglas Gregor719770d2010-04-06 17:30:22 +000016#include "clang/Sema/ExternalSemaSource.h"
Douglas Gregorb9d0ef72009-09-21 19:57:38 +000017#include "clang/AST/ExprCXX.h"
Douglas Gregor24a069f2009-11-17 17:59:40 +000018#include "clang/AST/ExprObjC.h"
Douglas Gregor3f7c7f42009-10-30 16:50:04 +000019#include "clang/Lex/MacroInfo.h"
20#include "clang/Lex/Preprocessor.h"
Douglas Gregor86d9a522009-09-21 16:56:56 +000021#include "llvm/ADT/SmallPtrSet.h"
Douglas Gregor6a684032009-09-28 03:51:44 +000022#include "llvm/ADT/StringExtras.h"
Douglas Gregor22f56992010-04-06 19:22:33 +000023#include "llvm/ADT/StringSwitch.h"
Douglas Gregor86d9a522009-09-21 16:56:56 +000024#include <list>
25#include <map>
26#include <vector>
Douglas Gregor81b747b2009-09-17 21:32:03 +000027
28using namespace clang;
29
Douglas Gregor86d9a522009-09-21 16:56:56 +000030namespace {
31 /// \brief A container of code-completion results.
32 class ResultBuilder {
33 public:
34 /// \brief The type of a name-lookup filter, which can be provided to the
35 /// name-lookup routines to specify which declarations should be included in
36 /// the result set (when it returns true) and which declarations should be
37 /// filtered out (returns false).
38 typedef bool (ResultBuilder::*LookupFilter)(NamedDecl *) const;
39
40 typedef CodeCompleteConsumer::Result Result;
41
42 private:
43 /// \brief The actual results we have found.
44 std::vector<Result> Results;
45
46 /// \brief A record of all of the declarations we have found and placed
47 /// into the result set, used to ensure that no declaration ever gets into
48 /// the result set twice.
49 llvm::SmallPtrSet<Decl*, 16> AllDeclsFound;
50
Douglas Gregorfbcb5d62009-12-06 20:23:50 +000051 typedef std::pair<NamedDecl *, unsigned> DeclIndexPair;
52
53 /// \brief An entry in the shadow map, which is optimized to store
54 /// a single (declaration, index) mapping (the common case) but
55 /// can also store a list of (declaration, index) mappings.
56 class ShadowMapEntry {
57 typedef llvm::SmallVector<DeclIndexPair, 4> DeclIndexPairVector;
58
59 /// \brief Contains either the solitary NamedDecl * or a vector
60 /// of (declaration, index) pairs.
61 llvm::PointerUnion<NamedDecl *, DeclIndexPairVector*> DeclOrVector;
62
63 /// \brief When the entry contains a single declaration, this is
64 /// the index associated with that entry.
65 unsigned SingleDeclIndex;
66
67 public:
68 ShadowMapEntry() : DeclOrVector(), SingleDeclIndex(0) { }
69
70 void Add(NamedDecl *ND, unsigned Index) {
71 if (DeclOrVector.isNull()) {
72 // 0 - > 1 elements: just set the single element information.
73 DeclOrVector = ND;
74 SingleDeclIndex = Index;
75 return;
76 }
77
78 if (NamedDecl *PrevND = DeclOrVector.dyn_cast<NamedDecl *>()) {
79 // 1 -> 2 elements: create the vector of results and push in the
80 // existing declaration.
81 DeclIndexPairVector *Vec = new DeclIndexPairVector;
82 Vec->push_back(DeclIndexPair(PrevND, SingleDeclIndex));
83 DeclOrVector = Vec;
84 }
85
86 // Add the new element to the end of the vector.
87 DeclOrVector.get<DeclIndexPairVector*>()->push_back(
88 DeclIndexPair(ND, Index));
89 }
90
91 void Destroy() {
92 if (DeclIndexPairVector *Vec
93 = DeclOrVector.dyn_cast<DeclIndexPairVector *>()) {
94 delete Vec;
95 DeclOrVector = ((NamedDecl *)0);
96 }
97 }
98
99 // Iteration.
100 class iterator;
101 iterator begin() const;
102 iterator end() const;
103 };
104
Douglas Gregor86d9a522009-09-21 16:56:56 +0000105 /// \brief A mapping from declaration names to the declarations that have
106 /// this name within a particular scope and their index within the list of
107 /// results.
Douglas Gregorfbcb5d62009-12-06 20:23:50 +0000108 typedef llvm::DenseMap<DeclarationName, ShadowMapEntry> ShadowMap;
Douglas Gregor86d9a522009-09-21 16:56:56 +0000109
110 /// \brief The semantic analysis object for which results are being
111 /// produced.
112 Sema &SemaRef;
113
114 /// \brief If non-NULL, a filter function used to remove any code-completion
115 /// results that are not desirable.
116 LookupFilter Filter;
Douglas Gregor45bcd432010-01-14 03:21:49 +0000117
118 /// \brief Whether we should allow declarations as
119 /// nested-name-specifiers that would otherwise be filtered out.
120 bool AllowNestedNameSpecifiers;
121
Douglas Gregor86d9a522009-09-21 16:56:56 +0000122 /// \brief A list of shadow maps, which is used to model name hiding at
123 /// different levels of, e.g., the inheritance hierarchy.
124 std::list<ShadowMap> ShadowMaps;
125
126 public:
127 explicit ResultBuilder(Sema &SemaRef, LookupFilter Filter = 0)
Douglas Gregor45bcd432010-01-14 03:21:49 +0000128 : SemaRef(SemaRef), Filter(Filter), AllowNestedNameSpecifiers(false) { }
Douglas Gregor86d9a522009-09-21 16:56:56 +0000129
130 /// \brief Set the filter used for code-completion results.
131 void setFilter(LookupFilter Filter) {
132 this->Filter = Filter;
133 }
134
135 typedef std::vector<Result>::iterator iterator;
136 iterator begin() { return Results.begin(); }
137 iterator end() { return Results.end(); }
138
139 Result *data() { return Results.empty()? 0 : &Results.front(); }
140 unsigned size() const { return Results.size(); }
141 bool empty() const { return Results.empty(); }
142
Douglas Gregor45bcd432010-01-14 03:21:49 +0000143 /// \brief Specify whether nested-name-specifiers are allowed.
144 void allowNestedNameSpecifiers(bool Allow = true) {
145 AllowNestedNameSpecifiers = Allow;
146 }
147
Douglas Gregore495b7f2010-01-14 00:20:49 +0000148 /// \brief Determine whether the given declaration is at all interesting
149 /// as a code-completion result.
Douglas Gregor45bcd432010-01-14 03:21:49 +0000150 ///
151 /// \param ND the declaration that we are inspecting.
152 ///
153 /// \param AsNestedNameSpecifier will be set true if this declaration is
154 /// only interesting when it is a nested-name-specifier.
155 bool isInterestingDecl(NamedDecl *ND, bool &AsNestedNameSpecifier) const;
Douglas Gregor6660d842010-01-14 00:41:07 +0000156
157 /// \brief Check whether the result is hidden by the Hiding declaration.
158 ///
159 /// \returns true if the result is hidden and cannot be found, false if
160 /// the hidden result could still be found. When false, \p R may be
161 /// modified to describe how the result can be found (e.g., via extra
162 /// qualification).
163 bool CheckHiddenResult(Result &R, DeclContext *CurContext,
164 NamedDecl *Hiding);
165
Douglas Gregor86d9a522009-09-21 16:56:56 +0000166 /// \brief Add a new result to this result set (if it isn't already in one
167 /// of the shadow maps), or replace an existing result (for, e.g., a
168 /// redeclaration).
Douglas Gregor456c4a12009-09-21 20:12:40 +0000169 ///
Douglas Gregor1ca6ae82010-01-14 01:09:38 +0000170 /// \param CurContext the result to add (if it is unique).
Douglas Gregor456c4a12009-09-21 20:12:40 +0000171 ///
172 /// \param R the context in which this result will be named.
173 void MaybeAddResult(Result R, DeclContext *CurContext = 0);
Douglas Gregor86d9a522009-09-21 16:56:56 +0000174
Douglas Gregor1ca6ae82010-01-14 01:09:38 +0000175 /// \brief Add a new result to this result set, where we already know
176 /// the hiding declation (if any).
177 ///
178 /// \param R the result to add (if it is unique).
179 ///
180 /// \param CurContext the context in which this result will be named.
181 ///
182 /// \param Hiding the declaration that hides the result.
Douglas Gregor0cc84042010-01-14 15:47:35 +0000183 ///
184 /// \param InBaseClass whether the result was found in a base
185 /// class of the searched context.
186 void AddResult(Result R, DeclContext *CurContext, NamedDecl *Hiding,
187 bool InBaseClass);
Douglas Gregor1ca6ae82010-01-14 01:09:38 +0000188
Douglas Gregora4477812010-01-14 16:01:26 +0000189 /// \brief Add a new non-declaration result to this result set.
190 void AddResult(Result R);
191
Douglas Gregor86d9a522009-09-21 16:56:56 +0000192 /// \brief Enter into a new scope.
193 void EnterNewScope();
194
195 /// \brief Exit from the current scope.
196 void ExitScope();
197
Douglas Gregor55385fe2009-11-18 04:19:12 +0000198 /// \brief Ignore this declaration, if it is seen again.
199 void Ignore(Decl *D) { AllDeclsFound.insert(D->getCanonicalDecl()); }
200
Douglas Gregor86d9a522009-09-21 16:56:56 +0000201 /// \name Name lookup predicates
202 ///
203 /// These predicates can be passed to the name lookup functions to filter the
204 /// results of name lookup. All of the predicates have the same type, so that
205 ///
206 //@{
Douglas Gregor791215b2009-09-21 20:51:25 +0000207 bool IsOrdinaryName(NamedDecl *ND) const;
Douglas Gregor01dfea02010-01-10 23:08:15 +0000208 bool IsOrdinaryNonValueName(NamedDecl *ND) const;
Douglas Gregor86d9a522009-09-21 16:56:56 +0000209 bool IsNestedNameSpecifier(NamedDecl *ND) const;
210 bool IsEnum(NamedDecl *ND) const;
211 bool IsClassOrStruct(NamedDecl *ND) const;
212 bool IsUnion(NamedDecl *ND) const;
213 bool IsNamespace(NamedDecl *ND) const;
214 bool IsNamespaceOrAlias(NamedDecl *ND) const;
215 bool IsType(NamedDecl *ND) const;
Douglas Gregoreb5758b2009-09-23 22:26:46 +0000216 bool IsMember(NamedDecl *ND) const;
Douglas Gregor80f4f4c2010-01-14 16:08:12 +0000217 bool IsObjCIvar(NamedDecl *ND) const;
Douglas Gregor86d9a522009-09-21 16:56:56 +0000218 //@}
219 };
220}
221
Douglas Gregorfbcb5d62009-12-06 20:23:50 +0000222class ResultBuilder::ShadowMapEntry::iterator {
223 llvm::PointerUnion<NamedDecl*, const DeclIndexPair*> DeclOrIterator;
224 unsigned SingleDeclIndex;
225
226public:
227 typedef DeclIndexPair value_type;
228 typedef value_type reference;
229 typedef std::ptrdiff_t difference_type;
230 typedef std::input_iterator_tag iterator_category;
231
232 class pointer {
233 DeclIndexPair Value;
234
235 public:
236 pointer(const DeclIndexPair &Value) : Value(Value) { }
237
238 const DeclIndexPair *operator->() const {
239 return &Value;
240 }
241 };
242
243 iterator() : DeclOrIterator((NamedDecl *)0), SingleDeclIndex(0) { }
244
245 iterator(NamedDecl *SingleDecl, unsigned Index)
246 : DeclOrIterator(SingleDecl), SingleDeclIndex(Index) { }
247
248 iterator(const DeclIndexPair *Iterator)
249 : DeclOrIterator(Iterator), SingleDeclIndex(0) { }
250
251 iterator &operator++() {
252 if (DeclOrIterator.is<NamedDecl *>()) {
253 DeclOrIterator = (NamedDecl *)0;
254 SingleDeclIndex = 0;
255 return *this;
256 }
257
258 const DeclIndexPair *I = DeclOrIterator.get<const DeclIndexPair*>();
259 ++I;
260 DeclOrIterator = I;
261 return *this;
262 }
263
264 iterator operator++(int) {
265 iterator tmp(*this);
266 ++(*this);
267 return tmp;
268 }
269
270 reference operator*() const {
271 if (NamedDecl *ND = DeclOrIterator.dyn_cast<NamedDecl *>())
272 return reference(ND, SingleDeclIndex);
273
Douglas Gregord490f952009-12-06 21:27:58 +0000274 return *DeclOrIterator.get<const DeclIndexPair*>();
Douglas Gregorfbcb5d62009-12-06 20:23:50 +0000275 }
276
277 pointer operator->() const {
278 return pointer(**this);
279 }
280
281 friend bool operator==(const iterator &X, const iterator &Y) {
Douglas Gregord490f952009-12-06 21:27:58 +0000282 return X.DeclOrIterator.getOpaqueValue()
283 == Y.DeclOrIterator.getOpaqueValue() &&
Douglas Gregorfbcb5d62009-12-06 20:23:50 +0000284 X.SingleDeclIndex == Y.SingleDeclIndex;
285 }
286
287 friend bool operator!=(const iterator &X, const iterator &Y) {
Douglas Gregord490f952009-12-06 21:27:58 +0000288 return !(X == Y);
Douglas Gregorfbcb5d62009-12-06 20:23:50 +0000289 }
290};
291
Douglas Gregorfbcb5d62009-12-06 20:23:50 +0000292ResultBuilder::ShadowMapEntry::iterator
293ResultBuilder::ShadowMapEntry::begin() const {
294 if (DeclOrVector.isNull())
295 return iterator();
296
297 if (NamedDecl *ND = DeclOrVector.dyn_cast<NamedDecl *>())
298 return iterator(ND, SingleDeclIndex);
299
300 return iterator(DeclOrVector.get<DeclIndexPairVector *>()->begin());
301}
302
303ResultBuilder::ShadowMapEntry::iterator
304ResultBuilder::ShadowMapEntry::end() const {
305 if (DeclOrVector.is<NamedDecl *>() || DeclOrVector.isNull())
306 return iterator();
307
308 return iterator(DeclOrVector.get<DeclIndexPairVector *>()->end());
309}
310
Douglas Gregor456c4a12009-09-21 20:12:40 +0000311/// \brief Compute the qualification required to get from the current context
312/// (\p CurContext) to the target context (\p TargetContext).
313///
314/// \param Context the AST context in which the qualification will be used.
315///
316/// \param CurContext the context where an entity is being named, which is
317/// typically based on the current scope.
318///
319/// \param TargetContext the context in which the named entity actually
320/// resides.
321///
322/// \returns a nested name specifier that refers into the target context, or
323/// NULL if no qualification is needed.
324static NestedNameSpecifier *
325getRequiredQualification(ASTContext &Context,
326 DeclContext *CurContext,
327 DeclContext *TargetContext) {
328 llvm::SmallVector<DeclContext *, 4> TargetParents;
329
330 for (DeclContext *CommonAncestor = TargetContext;
331 CommonAncestor && !CommonAncestor->Encloses(CurContext);
332 CommonAncestor = CommonAncestor->getLookupParent()) {
333 if (CommonAncestor->isTransparentContext() ||
334 CommonAncestor->isFunctionOrMethod())
335 continue;
336
337 TargetParents.push_back(CommonAncestor);
338 }
339
340 NestedNameSpecifier *Result = 0;
341 while (!TargetParents.empty()) {
342 DeclContext *Parent = TargetParents.back();
343 TargetParents.pop_back();
344
345 if (NamespaceDecl *Namespace = dyn_cast<NamespaceDecl>(Parent))
346 Result = NestedNameSpecifier::Create(Context, Result, Namespace);
347 else if (TagDecl *TD = dyn_cast<TagDecl>(Parent))
348 Result = NestedNameSpecifier::Create(Context, Result,
349 false,
350 Context.getTypeDeclType(TD).getTypePtr());
351 else
352 assert(Parent->isTranslationUnit());
Douglas Gregor0c8296d2009-11-07 00:00:49 +0000353 }
Douglas Gregor456c4a12009-09-21 20:12:40 +0000354 return Result;
355}
356
Douglas Gregor45bcd432010-01-14 03:21:49 +0000357bool ResultBuilder::isInterestingDecl(NamedDecl *ND,
358 bool &AsNestedNameSpecifier) const {
359 AsNestedNameSpecifier = false;
360
Douglas Gregore495b7f2010-01-14 00:20:49 +0000361 ND = ND->getUnderlyingDecl();
362 unsigned IDNS = ND->getIdentifierNamespace();
Douglas Gregorf52cede2009-10-09 22:16:47 +0000363
364 // Skip unnamed entities.
Douglas Gregore495b7f2010-01-14 00:20:49 +0000365 if (!ND->getDeclName())
366 return false;
Douglas Gregor86d9a522009-09-21 16:56:56 +0000367
368 // Friend declarations and declarations introduced due to friends are never
369 // added as results.
John McCall92b7f702010-03-11 07:50:04 +0000370 if (IDNS & (Decl::IDNS_OrdinaryFriend | Decl::IDNS_TagFriend))
Douglas Gregore495b7f2010-01-14 00:20:49 +0000371 return false;
372
Douglas Gregor76282942009-12-11 17:31:05 +0000373 // Class template (partial) specializations are never added as results.
Douglas Gregore495b7f2010-01-14 00:20:49 +0000374 if (isa<ClassTemplateSpecializationDecl>(ND) ||
375 isa<ClassTemplatePartialSpecializationDecl>(ND))
376 return false;
Douglas Gregor86d9a522009-09-21 16:56:56 +0000377
Douglas Gregor76282942009-12-11 17:31:05 +0000378 // Using declarations themselves are never added as results.
Douglas Gregore495b7f2010-01-14 00:20:49 +0000379 if (isa<UsingDecl>(ND))
380 return false;
381
382 // Some declarations have reserved names that we don't want to ever show.
383 if (const IdentifierInfo *Id = ND->getIdentifier()) {
Douglas Gregor86d9a522009-09-21 16:56:56 +0000384 // __va_list_tag is a freak of nature. Find it and skip it.
385 if (Id->isStr("__va_list_tag") || Id->isStr("__builtin_va_list"))
Douglas Gregore495b7f2010-01-14 00:20:49 +0000386 return false;
Douglas Gregor86d9a522009-09-21 16:56:56 +0000387
Douglas Gregorf52cede2009-10-09 22:16:47 +0000388 // Filter out names reserved for the implementation (C99 7.1.3,
389 // C++ [lib.global.names]). Users don't need to see those.
Daniel Dunbare013d682009-10-18 20:26:12 +0000390 //
391 // FIXME: Add predicate for this.
Douglas Gregorf52cede2009-10-09 22:16:47 +0000392 if (Id->getLength() >= 2) {
Daniel Dunbare013d682009-10-18 20:26:12 +0000393 const char *Name = Id->getNameStart();
Douglas Gregorf52cede2009-10-09 22:16:47 +0000394 if (Name[0] == '_' &&
395 (Name[1] == '_' || (Name[1] >= 'A' && Name[1] <= 'Z')))
Douglas Gregore495b7f2010-01-14 00:20:49 +0000396 return false;
Douglas Gregorf52cede2009-10-09 22:16:47 +0000397 }
Douglas Gregor86d9a522009-09-21 16:56:56 +0000398 }
Douglas Gregore495b7f2010-01-14 00:20:49 +0000399
Douglas Gregor86d9a522009-09-21 16:56:56 +0000400 // C++ constructors are never found by name lookup.
Douglas Gregore495b7f2010-01-14 00:20:49 +0000401 if (isa<CXXConstructorDecl>(ND))
402 return false;
Douglas Gregor86d9a522009-09-21 16:56:56 +0000403
404 // Filter out any unwanted results.
Douglas Gregor45bcd432010-01-14 03:21:49 +0000405 if (Filter && !(this->*Filter)(ND)) {
406 // Check whether it is interesting as a nested-name-specifier.
407 if (AllowNestedNameSpecifiers && SemaRef.getLangOptions().CPlusPlus &&
408 IsNestedNameSpecifier(ND) &&
409 (Filter != &ResultBuilder::IsMember ||
410 (isa<CXXRecordDecl>(ND) &&
411 cast<CXXRecordDecl>(ND)->isInjectedClassName()))) {
412 AsNestedNameSpecifier = true;
413 return true;
414 }
415
Douglas Gregore495b7f2010-01-14 00:20:49 +0000416 return false;
Douglas Gregor45bcd432010-01-14 03:21:49 +0000417 }
Douglas Gregor86d9a522009-09-21 16:56:56 +0000418
Douglas Gregore495b7f2010-01-14 00:20:49 +0000419 // ... then it must be interesting!
420 return true;
421}
422
Douglas Gregor6660d842010-01-14 00:41:07 +0000423bool ResultBuilder::CheckHiddenResult(Result &R, DeclContext *CurContext,
424 NamedDecl *Hiding) {
425 // In C, there is no way to refer to a hidden name.
426 // FIXME: This isn't true; we can find a tag name hidden by an ordinary
427 // name if we introduce the tag type.
428 if (!SemaRef.getLangOptions().CPlusPlus)
429 return true;
430
431 DeclContext *HiddenCtx = R.Declaration->getDeclContext()->getLookupContext();
432
433 // There is no way to qualify a name declared in a function or method.
434 if (HiddenCtx->isFunctionOrMethod())
435 return true;
436
437 if (HiddenCtx == Hiding->getDeclContext()->getLookupContext())
438 return true;
439
440 // We can refer to the result with the appropriate qualification. Do it.
441 R.Hidden = true;
442 R.QualifierIsInformative = false;
443
444 if (!R.Qualifier)
445 R.Qualifier = getRequiredQualification(SemaRef.Context,
446 CurContext,
447 R.Declaration->getDeclContext());
448 return false;
449}
450
Douglas Gregore495b7f2010-01-14 00:20:49 +0000451void ResultBuilder::MaybeAddResult(Result R, DeclContext *CurContext) {
452 assert(!ShadowMaps.empty() && "Must enter into a results scope");
453
454 if (R.Kind != Result::RK_Declaration) {
455 // For non-declaration results, just add the result.
456 Results.push_back(R);
457 return;
458 }
459
460 // Look through using declarations.
461 if (UsingShadowDecl *Using = dyn_cast<UsingShadowDecl>(R.Declaration)) {
462 MaybeAddResult(Result(Using->getTargetDecl(), R.Qualifier), CurContext);
463 return;
464 }
465
466 Decl *CanonDecl = R.Declaration->getCanonicalDecl();
467 unsigned IDNS = CanonDecl->getIdentifierNamespace();
468
Douglas Gregor45bcd432010-01-14 03:21:49 +0000469 bool AsNestedNameSpecifier = false;
470 if (!isInterestingDecl(R.Declaration, AsNestedNameSpecifier))
Douglas Gregore495b7f2010-01-14 00:20:49 +0000471 return;
472
Douglas Gregor86d9a522009-09-21 16:56:56 +0000473 ShadowMap &SMap = ShadowMaps.back();
Douglas Gregorfbcb5d62009-12-06 20:23:50 +0000474 ShadowMapEntry::iterator I, IEnd;
475 ShadowMap::iterator NamePos = SMap.find(R.Declaration->getDeclName());
476 if (NamePos != SMap.end()) {
477 I = NamePos->second.begin();
478 IEnd = NamePos->second.end();
479 }
480
481 for (; I != IEnd; ++I) {
482 NamedDecl *ND = I->first;
483 unsigned Index = I->second;
Douglas Gregor86d9a522009-09-21 16:56:56 +0000484 if (ND->getCanonicalDecl() == CanonDecl) {
485 // This is a redeclaration. Always pick the newer declaration.
Douglas Gregor86d9a522009-09-21 16:56:56 +0000486 Results[Index].Declaration = R.Declaration;
487
Douglas Gregor86d9a522009-09-21 16:56:56 +0000488 // We're done.
489 return;
490 }
491 }
492
493 // This is a new declaration in this scope. However, check whether this
494 // declaration name is hidden by a similarly-named declaration in an outer
495 // scope.
496 std::list<ShadowMap>::iterator SM, SMEnd = ShadowMaps.end();
497 --SMEnd;
498 for (SM = ShadowMaps.begin(); SM != SMEnd; ++SM) {
Douglas Gregorfbcb5d62009-12-06 20:23:50 +0000499 ShadowMapEntry::iterator I, IEnd;
500 ShadowMap::iterator NamePos = SM->find(R.Declaration->getDeclName());
501 if (NamePos != SM->end()) {
502 I = NamePos->second.begin();
503 IEnd = NamePos->second.end();
504 }
505 for (; I != IEnd; ++I) {
Douglas Gregor86d9a522009-09-21 16:56:56 +0000506 // A tag declaration does not hide a non-tag declaration.
Douglas Gregorfbcb5d62009-12-06 20:23:50 +0000507 if (I->first->getIdentifierNamespace() == Decl::IDNS_Tag &&
Douglas Gregor86d9a522009-09-21 16:56:56 +0000508 (IDNS & (Decl::IDNS_Member | Decl::IDNS_Ordinary |
509 Decl::IDNS_ObjCProtocol)))
510 continue;
511
512 // Protocols are in distinct namespaces from everything else.
Douglas Gregorfbcb5d62009-12-06 20:23:50 +0000513 if (((I->first->getIdentifierNamespace() & Decl::IDNS_ObjCProtocol)
Douglas Gregor86d9a522009-09-21 16:56:56 +0000514 || (IDNS & Decl::IDNS_ObjCProtocol)) &&
Douglas Gregorfbcb5d62009-12-06 20:23:50 +0000515 I->first->getIdentifierNamespace() != IDNS)
Douglas Gregor86d9a522009-09-21 16:56:56 +0000516 continue;
517
518 // The newly-added result is hidden by an entry in the shadow map.
Douglas Gregor6660d842010-01-14 00:41:07 +0000519 if (CheckHiddenResult(R, CurContext, I->first))
Douglas Gregor86d9a522009-09-21 16:56:56 +0000520 return;
Douglas Gregor86d9a522009-09-21 16:56:56 +0000521
522 break;
523 }
524 }
525
526 // Make sure that any given declaration only shows up in the result set once.
527 if (!AllDeclsFound.insert(CanonDecl))
528 return;
529
Douglas Gregoreb5758b2009-09-23 22:26:46 +0000530 // If the filter is for nested-name-specifiers, then this result starts a
531 // nested-name-specifier.
Douglas Gregor45bcd432010-01-14 03:21:49 +0000532 if (AsNestedNameSpecifier)
Douglas Gregoreb5758b2009-09-23 22:26:46 +0000533 R.StartsNestedNameSpecifier = true;
534
Douglas Gregor0563c262009-09-22 23:15:58 +0000535 // If this result is supposed to have an informative qualifier, add one.
Douglas Gregoreb5758b2009-09-23 22:26:46 +0000536 if (R.QualifierIsInformative && !R.Qualifier &&
537 !R.StartsNestedNameSpecifier) {
Douglas Gregor0563c262009-09-22 23:15:58 +0000538 DeclContext *Ctx = R.Declaration->getDeclContext();
539 if (NamespaceDecl *Namespace = dyn_cast<NamespaceDecl>(Ctx))
540 R.Qualifier = NestedNameSpecifier::Create(SemaRef.Context, 0, Namespace);
541 else if (TagDecl *Tag = dyn_cast<TagDecl>(Ctx))
542 R.Qualifier = NestedNameSpecifier::Create(SemaRef.Context, 0, false,
543 SemaRef.Context.getTypeDeclType(Tag).getTypePtr());
544 else
545 R.QualifierIsInformative = false;
546 }
Douglas Gregoreb5758b2009-09-23 22:26:46 +0000547
Douglas Gregor86d9a522009-09-21 16:56:56 +0000548 // Insert this result into the set of results and into the current shadow
549 // map.
Douglas Gregorfbcb5d62009-12-06 20:23:50 +0000550 SMap[R.Declaration->getDeclName()].Add(R.Declaration, Results.size());
Douglas Gregor86d9a522009-09-21 16:56:56 +0000551 Results.push_back(R);
552}
553
Douglas Gregor1ca6ae82010-01-14 01:09:38 +0000554void ResultBuilder::AddResult(Result R, DeclContext *CurContext,
Douglas Gregor0cc84042010-01-14 15:47:35 +0000555 NamedDecl *Hiding, bool InBaseClass = false) {
Douglas Gregora4477812010-01-14 16:01:26 +0000556 if (R.Kind != Result::RK_Declaration) {
557 // For non-declaration results, just add the result.
558 Results.push_back(R);
559 return;
560 }
561
Douglas Gregor1ca6ae82010-01-14 01:09:38 +0000562 // Look through using declarations.
563 if (UsingShadowDecl *Using = dyn_cast<UsingShadowDecl>(R.Declaration)) {
564 AddResult(Result(Using->getTargetDecl(), R.Qualifier), CurContext, Hiding);
565 return;
566 }
567
Douglas Gregor45bcd432010-01-14 03:21:49 +0000568 bool AsNestedNameSpecifier = false;
569 if (!isInterestingDecl(R.Declaration, AsNestedNameSpecifier))
Douglas Gregor1ca6ae82010-01-14 01:09:38 +0000570 return;
571
572 if (Hiding && CheckHiddenResult(R, CurContext, Hiding))
573 return;
574
575 // Make sure that any given declaration only shows up in the result set once.
576 if (!AllDeclsFound.insert(R.Declaration->getCanonicalDecl()))
577 return;
578
579 // If the filter is for nested-name-specifiers, then this result starts a
580 // nested-name-specifier.
Douglas Gregor45bcd432010-01-14 03:21:49 +0000581 if (AsNestedNameSpecifier)
Douglas Gregor1ca6ae82010-01-14 01:09:38 +0000582 R.StartsNestedNameSpecifier = true;
Douglas Gregor0cc84042010-01-14 15:47:35 +0000583 else if (Filter == &ResultBuilder::IsMember && !R.Qualifier && InBaseClass &&
584 isa<CXXRecordDecl>(R.Declaration->getDeclContext()
585 ->getLookupContext()))
586 R.QualifierIsInformative = true;
587
Douglas Gregor1ca6ae82010-01-14 01:09:38 +0000588 // If this result is supposed to have an informative qualifier, add one.
589 if (R.QualifierIsInformative && !R.Qualifier &&
590 !R.StartsNestedNameSpecifier) {
591 DeclContext *Ctx = R.Declaration->getDeclContext();
592 if (NamespaceDecl *Namespace = dyn_cast<NamespaceDecl>(Ctx))
593 R.Qualifier = NestedNameSpecifier::Create(SemaRef.Context, 0, Namespace);
594 else if (TagDecl *Tag = dyn_cast<TagDecl>(Ctx))
595 R.Qualifier = NestedNameSpecifier::Create(SemaRef.Context, 0, false,
Douglas Gregor45bcd432010-01-14 03:21:49 +0000596 SemaRef.Context.getTypeDeclType(Tag).getTypePtr());
Douglas Gregor1ca6ae82010-01-14 01:09:38 +0000597 else
598 R.QualifierIsInformative = false;
599 }
600
601 // Insert this result into the set of results.
602 Results.push_back(R);
603}
604
Douglas Gregora4477812010-01-14 16:01:26 +0000605void ResultBuilder::AddResult(Result R) {
606 assert(R.Kind != Result::RK_Declaration &&
607 "Declaration results need more context");
608 Results.push_back(R);
609}
610
Douglas Gregor86d9a522009-09-21 16:56:56 +0000611/// \brief Enter into a new scope.
612void ResultBuilder::EnterNewScope() {
613 ShadowMaps.push_back(ShadowMap());
614}
615
616/// \brief Exit from the current scope.
617void ResultBuilder::ExitScope() {
Douglas Gregorfbcb5d62009-12-06 20:23:50 +0000618 for (ShadowMap::iterator E = ShadowMaps.back().begin(),
619 EEnd = ShadowMaps.back().end();
620 E != EEnd;
621 ++E)
622 E->second.Destroy();
623
Douglas Gregor86d9a522009-09-21 16:56:56 +0000624 ShadowMaps.pop_back();
625}
626
Douglas Gregor791215b2009-09-21 20:51:25 +0000627/// \brief Determines whether this given declaration will be found by
628/// ordinary name lookup.
629bool ResultBuilder::IsOrdinaryName(NamedDecl *ND) const {
630 unsigned IDNS = Decl::IDNS_Ordinary;
631 if (SemaRef.getLangOptions().CPlusPlus)
632 IDNS |= Decl::IDNS_Tag;
Douglas Gregor1ca6ae82010-01-14 01:09:38 +0000633 else if (SemaRef.getLangOptions().ObjC1 && isa<ObjCIvarDecl>(ND))
634 return true;
635
Douglas Gregor791215b2009-09-21 20:51:25 +0000636 return ND->getIdentifierNamespace() & IDNS;
637}
638
Douglas Gregor01dfea02010-01-10 23:08:15 +0000639/// \brief Determines whether this given declaration will be found by
640/// ordinary name lookup.
641bool ResultBuilder::IsOrdinaryNonValueName(NamedDecl *ND) const {
642 unsigned IDNS = Decl::IDNS_Ordinary;
643 if (SemaRef.getLangOptions().CPlusPlus)
644 IDNS |= Decl::IDNS_Tag;
645
646 return (ND->getIdentifierNamespace() & IDNS) &&
647 !isa<ValueDecl>(ND) && !isa<FunctionTemplateDecl>(ND);
648}
649
Douglas Gregor86d9a522009-09-21 16:56:56 +0000650/// \brief Determines whether the given declaration is suitable as the
651/// start of a C++ nested-name-specifier, e.g., a class or namespace.
652bool ResultBuilder::IsNestedNameSpecifier(NamedDecl *ND) const {
653 // Allow us to find class templates, too.
654 if (ClassTemplateDecl *ClassTemplate = dyn_cast<ClassTemplateDecl>(ND))
655 ND = ClassTemplate->getTemplatedDecl();
656
657 return SemaRef.isAcceptableNestedNameSpecifier(ND);
658}
659
660/// \brief Determines whether the given declaration is an enumeration.
661bool ResultBuilder::IsEnum(NamedDecl *ND) const {
662 return isa<EnumDecl>(ND);
663}
664
665/// \brief Determines whether the given declaration is a class or struct.
666bool ResultBuilder::IsClassOrStruct(NamedDecl *ND) const {
667 // Allow us to find class templates, too.
668 if (ClassTemplateDecl *ClassTemplate = dyn_cast<ClassTemplateDecl>(ND))
669 ND = ClassTemplate->getTemplatedDecl();
670
671 if (RecordDecl *RD = dyn_cast<RecordDecl>(ND))
672 return RD->getTagKind() == TagDecl::TK_class ||
673 RD->getTagKind() == TagDecl::TK_struct;
674
675 return false;
676}
677
678/// \brief Determines whether the given declaration is a union.
679bool ResultBuilder::IsUnion(NamedDecl *ND) const {
680 // Allow us to find class templates, too.
681 if (ClassTemplateDecl *ClassTemplate = dyn_cast<ClassTemplateDecl>(ND))
682 ND = ClassTemplate->getTemplatedDecl();
683
684 if (RecordDecl *RD = dyn_cast<RecordDecl>(ND))
685 return RD->getTagKind() == TagDecl::TK_union;
686
687 return false;
688}
689
690/// \brief Determines whether the given declaration is a namespace.
691bool ResultBuilder::IsNamespace(NamedDecl *ND) const {
692 return isa<NamespaceDecl>(ND);
693}
694
695/// \brief Determines whether the given declaration is a namespace or
696/// namespace alias.
697bool ResultBuilder::IsNamespaceOrAlias(NamedDecl *ND) const {
698 return isa<NamespaceDecl>(ND) || isa<NamespaceAliasDecl>(ND);
699}
700
Douglas Gregor76282942009-12-11 17:31:05 +0000701/// \brief Determines whether the given declaration is a type.
Douglas Gregor86d9a522009-09-21 16:56:56 +0000702bool ResultBuilder::IsType(NamedDecl *ND) const {
703 return isa<TypeDecl>(ND);
704}
705
Douglas Gregor76282942009-12-11 17:31:05 +0000706/// \brief Determines which members of a class should be visible via
707/// "." or "->". Only value declarations, nested name specifiers, and
708/// using declarations thereof should show up.
Douglas Gregoreb5758b2009-09-23 22:26:46 +0000709bool ResultBuilder::IsMember(NamedDecl *ND) const {
Douglas Gregor76282942009-12-11 17:31:05 +0000710 if (UsingShadowDecl *Using = dyn_cast<UsingShadowDecl>(ND))
711 ND = Using->getTargetDecl();
712
Douglas Gregorce821962009-12-11 18:14:22 +0000713 return isa<ValueDecl>(ND) || isa<FunctionTemplateDecl>(ND) ||
714 isa<ObjCPropertyDecl>(ND);
Douglas Gregoreb5758b2009-09-23 22:26:46 +0000715}
716
Douglas Gregor80f4f4c2010-01-14 16:08:12 +0000717/// \rief Determines whether the given declaration is an Objective-C
718/// instance variable.
719bool ResultBuilder::IsObjCIvar(NamedDecl *ND) const {
720 return isa<ObjCIvarDecl>(ND);
721}
722
Douglas Gregor1ca6ae82010-01-14 01:09:38 +0000723namespace {
724 /// \brief Visible declaration consumer that adds a code-completion result
725 /// for each visible declaration.
726 class CodeCompletionDeclConsumer : public VisibleDeclConsumer {
727 ResultBuilder &Results;
728 DeclContext *CurContext;
729
730 public:
731 CodeCompletionDeclConsumer(ResultBuilder &Results, DeclContext *CurContext)
732 : Results(Results), CurContext(CurContext) { }
733
Douglas Gregor0cc84042010-01-14 15:47:35 +0000734 virtual void FoundDecl(NamedDecl *ND, NamedDecl *Hiding, bool InBaseClass) {
735 Results.AddResult(ND, CurContext, Hiding, InBaseClass);
Douglas Gregor1ca6ae82010-01-14 01:09:38 +0000736 }
737 };
738}
739
Douglas Gregor86d9a522009-09-21 16:56:56 +0000740/// \brief Add type specifiers for the current language as keyword results.
Douglas Gregorbca403c2010-01-13 23:51:12 +0000741static void AddTypeSpecifierResults(const LangOptions &LangOpts,
Douglas Gregor86d9a522009-09-21 16:56:56 +0000742 ResultBuilder &Results) {
743 typedef CodeCompleteConsumer::Result Result;
Douglas Gregora4477812010-01-14 16:01:26 +0000744 Results.AddResult(Result("short"));
745 Results.AddResult(Result("long"));
746 Results.AddResult(Result("signed"));
747 Results.AddResult(Result("unsigned"));
748 Results.AddResult(Result("void"));
749 Results.AddResult(Result("char"));
750 Results.AddResult(Result("int"));
751 Results.AddResult(Result("float"));
752 Results.AddResult(Result("double"));
753 Results.AddResult(Result("enum"));
754 Results.AddResult(Result("struct"));
755 Results.AddResult(Result("union"));
756 Results.AddResult(Result("const"));
757 Results.AddResult(Result("volatile"));
Douglas Gregor01dfea02010-01-10 23:08:15 +0000758
Douglas Gregor86d9a522009-09-21 16:56:56 +0000759 if (LangOpts.C99) {
760 // C99-specific
Douglas Gregora4477812010-01-14 16:01:26 +0000761 Results.AddResult(Result("_Complex"));
762 Results.AddResult(Result("_Imaginary"));
763 Results.AddResult(Result("_Bool"));
764 Results.AddResult(Result("restrict"));
Douglas Gregor86d9a522009-09-21 16:56:56 +0000765 }
766
767 if (LangOpts.CPlusPlus) {
768 // C++-specific
Douglas Gregora4477812010-01-14 16:01:26 +0000769 Results.AddResult(Result("bool"));
770 Results.AddResult(Result("class"));
771 Results.AddResult(Result("wchar_t"));
Douglas Gregor86d9a522009-09-21 16:56:56 +0000772
Douglas Gregor01dfea02010-01-10 23:08:15 +0000773 // typename qualified-id
774 CodeCompletionString *Pattern = new CodeCompletionString;
775 Pattern->AddTypedTextChunk("typename");
776 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
777 Pattern->AddPlaceholderChunk("qualified-id");
Douglas Gregora4477812010-01-14 16:01:26 +0000778 Results.AddResult(Result(Pattern));
Douglas Gregor01dfea02010-01-10 23:08:15 +0000779
Douglas Gregor86d9a522009-09-21 16:56:56 +0000780 if (LangOpts.CPlusPlus0x) {
Douglas Gregora4477812010-01-14 16:01:26 +0000781 Results.AddResult(Result("auto"));
782 Results.AddResult(Result("char16_t"));
783 Results.AddResult(Result("char32_t"));
784 Results.AddResult(Result("decltype"));
Douglas Gregor86d9a522009-09-21 16:56:56 +0000785 }
786 }
787
788 // GNU extensions
789 if (LangOpts.GNUMode) {
790 // FIXME: Enable when we actually support decimal floating point.
Douglas Gregora4477812010-01-14 16:01:26 +0000791 // Results.AddResult(Result("_Decimal32"));
792 // Results.AddResult(Result("_Decimal64"));
793 // Results.AddResult(Result("_Decimal128"));
Douglas Gregor01dfea02010-01-10 23:08:15 +0000794
795 CodeCompletionString *Pattern = new CodeCompletionString;
796 Pattern->AddTypedTextChunk("typeof");
797 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
798 Pattern->AddPlaceholderChunk("expression-or-type");
799 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
Douglas Gregora4477812010-01-14 16:01:26 +0000800 Results.AddResult(Result(Pattern));
Douglas Gregor86d9a522009-09-21 16:56:56 +0000801 }
802}
803
Douglas Gregor01dfea02010-01-10 23:08:15 +0000804static void AddStorageSpecifiers(Action::CodeCompletionContext CCC,
805 const LangOptions &LangOpts,
Douglas Gregor01dfea02010-01-10 23:08:15 +0000806 ResultBuilder &Results) {
807 typedef CodeCompleteConsumer::Result Result;
808 // Note: we don't suggest either "auto" or "register", because both
809 // are pointless as storage specifiers. Elsewhere, we suggest "auto"
810 // in C++0x as a type specifier.
Douglas Gregora4477812010-01-14 16:01:26 +0000811 Results.AddResult(Result("extern"));
812 Results.AddResult(Result("static"));
Douglas Gregor01dfea02010-01-10 23:08:15 +0000813}
814
815static void AddFunctionSpecifiers(Action::CodeCompletionContext CCC,
816 const LangOptions &LangOpts,
Douglas Gregor01dfea02010-01-10 23:08:15 +0000817 ResultBuilder &Results) {
818 typedef CodeCompleteConsumer::Result Result;
819 switch (CCC) {
820 case Action::CCC_Class:
821 case Action::CCC_MemberTemplate:
822 if (LangOpts.CPlusPlus) {
Douglas Gregora4477812010-01-14 16:01:26 +0000823 Results.AddResult(Result("explicit"));
824 Results.AddResult(Result("friend"));
825 Results.AddResult(Result("mutable"));
826 Results.AddResult(Result("virtual"));
Douglas Gregor01dfea02010-01-10 23:08:15 +0000827 }
828 // Fall through
829
Douglas Gregorb6ac2452010-01-13 21:24:21 +0000830 case Action::CCC_ObjCInterface:
831 case Action::CCC_ObjCImplementation:
Douglas Gregor01dfea02010-01-10 23:08:15 +0000832 case Action::CCC_Namespace:
833 case Action::CCC_Template:
834 if (LangOpts.CPlusPlus || LangOpts.C99)
Douglas Gregora4477812010-01-14 16:01:26 +0000835 Results.AddResult(Result("inline"));
Douglas Gregor01dfea02010-01-10 23:08:15 +0000836 break;
837
Douglas Gregorc38c3e12010-01-13 21:54:15 +0000838 case Action::CCC_ObjCInstanceVariableList:
Douglas Gregor01dfea02010-01-10 23:08:15 +0000839 case Action::CCC_Expression:
840 case Action::CCC_Statement:
841 case Action::CCC_ForInit:
842 case Action::CCC_Condition:
843 break;
844 }
845}
846
Douglas Gregorbca403c2010-01-13 23:51:12 +0000847static void AddObjCExpressionResults(ResultBuilder &Results, bool NeedAt);
848static void AddObjCStatementResults(ResultBuilder &Results, bool NeedAt);
849static void AddObjCVisibilityResults(const LangOptions &LangOpts,
Douglas Gregorc38c3e12010-01-13 21:54:15 +0000850 ResultBuilder &Results,
851 bool NeedAt);
Douglas Gregorbca403c2010-01-13 23:51:12 +0000852static void AddObjCImplementationResults(const LangOptions &LangOpts,
Douglas Gregorb6ac2452010-01-13 21:24:21 +0000853 ResultBuilder &Results,
854 bool NeedAt);
Douglas Gregorbca403c2010-01-13 23:51:12 +0000855static void AddObjCInterfaceResults(const LangOptions &LangOpts,
Douglas Gregorb6ac2452010-01-13 21:24:21 +0000856 ResultBuilder &Results,
857 bool NeedAt);
Douglas Gregorbca403c2010-01-13 23:51:12 +0000858static void AddObjCTopLevelResults(ResultBuilder &Results, bool NeedAt);
Douglas Gregorb6ac2452010-01-13 21:24:21 +0000859
Douglas Gregor01dfea02010-01-10 23:08:15 +0000860/// \brief Add language constructs that show up for "ordinary" names.
861static void AddOrdinaryNameResults(Action::CodeCompletionContext CCC,
862 Scope *S,
863 Sema &SemaRef,
Douglas Gregor01dfea02010-01-10 23:08:15 +0000864 ResultBuilder &Results) {
865 typedef CodeCompleteConsumer::Result Result;
866 switch (CCC) {
867 case Action::CCC_Namespace:
868 if (SemaRef.getLangOptions().CPlusPlus) {
869 // namespace <identifier> { }
870 CodeCompletionString *Pattern = new CodeCompletionString;
871 Pattern->AddTypedTextChunk("namespace");
872 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
873 Pattern->AddPlaceholderChunk("identifier");
874 Pattern->AddChunk(CodeCompletionString::CK_LeftBrace);
875 Pattern->AddPlaceholderChunk("declarations");
876 Pattern->AddChunk(CodeCompletionString::CK_VerticalSpace);
877 Pattern->AddChunk(CodeCompletionString::CK_RightBrace);
Douglas Gregora4477812010-01-14 16:01:26 +0000878 Results.AddResult(Result(Pattern));
Douglas Gregor01dfea02010-01-10 23:08:15 +0000879
880 // namespace identifier = identifier ;
881 Pattern = new CodeCompletionString;
882 Pattern->AddTypedTextChunk("namespace");
883 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
884 Pattern->AddPlaceholderChunk("identifier");
885 Pattern->AddChunk(CodeCompletionString::CK_Equal);
886 Pattern->AddPlaceholderChunk("identifier");
Douglas Gregora4477812010-01-14 16:01:26 +0000887 Results.AddResult(Result(Pattern));
Douglas Gregor01dfea02010-01-10 23:08:15 +0000888
889 // Using directives
890 Pattern = new CodeCompletionString;
891 Pattern->AddTypedTextChunk("using");
892 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
893 Pattern->AddTextChunk("namespace");
894 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
895 Pattern->AddPlaceholderChunk("identifier");
Douglas Gregora4477812010-01-14 16:01:26 +0000896 Results.AddResult(Result(Pattern));
Douglas Gregor01dfea02010-01-10 23:08:15 +0000897
898 // asm(string-literal)
899 Pattern = new CodeCompletionString;
900 Pattern->AddTypedTextChunk("asm");
901 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
902 Pattern->AddPlaceholderChunk("string-literal");
903 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
Douglas Gregora4477812010-01-14 16:01:26 +0000904 Results.AddResult(Result(Pattern));
Douglas Gregor01dfea02010-01-10 23:08:15 +0000905
906 // Explicit template instantiation
907 Pattern = new CodeCompletionString;
908 Pattern->AddTypedTextChunk("template");
909 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
910 Pattern->AddPlaceholderChunk("declaration");
Douglas Gregora4477812010-01-14 16:01:26 +0000911 Results.AddResult(Result(Pattern));
Douglas Gregor01dfea02010-01-10 23:08:15 +0000912 }
Douglas Gregorb6ac2452010-01-13 21:24:21 +0000913
914 if (SemaRef.getLangOptions().ObjC1)
Douglas Gregorbca403c2010-01-13 23:51:12 +0000915 AddObjCTopLevelResults(Results, true);
Douglas Gregorb6ac2452010-01-13 21:24:21 +0000916
Douglas Gregor01dfea02010-01-10 23:08:15 +0000917 // Fall through
918
919 case Action::CCC_Class:
Douglas Gregora4477812010-01-14 16:01:26 +0000920 Results.AddResult(Result("typedef"));
Douglas Gregor01dfea02010-01-10 23:08:15 +0000921 if (SemaRef.getLangOptions().CPlusPlus) {
922 // Using declaration
923 CodeCompletionString *Pattern = new CodeCompletionString;
924 Pattern->AddTypedTextChunk("using");
925 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
926 Pattern->AddPlaceholderChunk("qualified-id");
Douglas Gregora4477812010-01-14 16:01:26 +0000927 Results.AddResult(Result(Pattern));
Douglas Gregor01dfea02010-01-10 23:08:15 +0000928
929 // using typename qualified-id; (only in a dependent context)
930 if (SemaRef.CurContext->isDependentContext()) {
931 Pattern = new CodeCompletionString;
932 Pattern->AddTypedTextChunk("using");
933 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
934 Pattern->AddTextChunk("typename");
935 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
936 Pattern->AddPlaceholderChunk("qualified-id");
Douglas Gregora4477812010-01-14 16:01:26 +0000937 Results.AddResult(Result(Pattern));
Douglas Gregor01dfea02010-01-10 23:08:15 +0000938 }
939
940 if (CCC == Action::CCC_Class) {
941 // public:
942 Pattern = new CodeCompletionString;
943 Pattern->AddTypedTextChunk("public");
944 Pattern->AddChunk(CodeCompletionString::CK_Colon);
Douglas Gregora4477812010-01-14 16:01:26 +0000945 Results.AddResult(Result(Pattern));
Douglas Gregor01dfea02010-01-10 23:08:15 +0000946
947 // protected:
948 Pattern = new CodeCompletionString;
949 Pattern->AddTypedTextChunk("protected");
950 Pattern->AddChunk(CodeCompletionString::CK_Colon);
Douglas Gregora4477812010-01-14 16:01:26 +0000951 Results.AddResult(Result(Pattern));
Douglas Gregor01dfea02010-01-10 23:08:15 +0000952
953 // private:
954 Pattern = new CodeCompletionString;
955 Pattern->AddTypedTextChunk("private");
956 Pattern->AddChunk(CodeCompletionString::CK_Colon);
Douglas Gregora4477812010-01-14 16:01:26 +0000957 Results.AddResult(Result(Pattern));
Douglas Gregor01dfea02010-01-10 23:08:15 +0000958 }
959 }
960 // Fall through
961
962 case Action::CCC_Template:
963 case Action::CCC_MemberTemplate:
964 if (SemaRef.getLangOptions().CPlusPlus) {
965 // template < parameters >
966 CodeCompletionString *Pattern = new CodeCompletionString;
967 Pattern->AddTypedTextChunk("template");
968 Pattern->AddChunk(CodeCompletionString::CK_LeftAngle);
969 Pattern->AddPlaceholderChunk("parameters");
970 Pattern->AddChunk(CodeCompletionString::CK_RightAngle);
Douglas Gregora4477812010-01-14 16:01:26 +0000971 Results.AddResult(Result(Pattern));
Douglas Gregor01dfea02010-01-10 23:08:15 +0000972 }
973
Douglas Gregorbca403c2010-01-13 23:51:12 +0000974 AddStorageSpecifiers(CCC, SemaRef.getLangOptions(), Results);
975 AddFunctionSpecifiers(CCC, SemaRef.getLangOptions(), Results);
Douglas Gregor01dfea02010-01-10 23:08:15 +0000976 break;
977
Douglas Gregorb6ac2452010-01-13 21:24:21 +0000978 case Action::CCC_ObjCInterface:
Douglas Gregorbca403c2010-01-13 23:51:12 +0000979 AddObjCInterfaceResults(SemaRef.getLangOptions(), Results, true);
980 AddStorageSpecifiers(CCC, SemaRef.getLangOptions(), Results);
981 AddFunctionSpecifiers(CCC, SemaRef.getLangOptions(), Results);
Douglas Gregorb6ac2452010-01-13 21:24:21 +0000982 break;
983
984 case Action::CCC_ObjCImplementation:
Douglas Gregorbca403c2010-01-13 23:51:12 +0000985 AddObjCImplementationResults(SemaRef.getLangOptions(), Results, true);
986 AddStorageSpecifiers(CCC, SemaRef.getLangOptions(), Results);
987 AddFunctionSpecifiers(CCC, SemaRef.getLangOptions(), Results);
Douglas Gregorb6ac2452010-01-13 21:24:21 +0000988 break;
989
Douglas Gregorc38c3e12010-01-13 21:54:15 +0000990 case Action::CCC_ObjCInstanceVariableList:
Douglas Gregorbca403c2010-01-13 23:51:12 +0000991 AddObjCVisibilityResults(SemaRef.getLangOptions(), Results, true);
Douglas Gregorc38c3e12010-01-13 21:54:15 +0000992 break;
993
Douglas Gregor01dfea02010-01-10 23:08:15 +0000994 case Action::CCC_Statement: {
Douglas Gregora4477812010-01-14 16:01:26 +0000995 Results.AddResult(Result("typedef"));
Douglas Gregor01dfea02010-01-10 23:08:15 +0000996
997 CodeCompletionString *Pattern = 0;
998 if (SemaRef.getLangOptions().CPlusPlus) {
999 Pattern = new CodeCompletionString;
1000 Pattern->AddTypedTextChunk("try");
1001 Pattern->AddChunk(CodeCompletionString::CK_LeftBrace);
1002 Pattern->AddPlaceholderChunk("statements");
1003 Pattern->AddChunk(CodeCompletionString::CK_VerticalSpace);
1004 Pattern->AddChunk(CodeCompletionString::CK_RightBrace);
1005 Pattern->AddTextChunk("catch");
1006 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
1007 Pattern->AddPlaceholderChunk("declaration");
1008 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
1009 Pattern->AddChunk(CodeCompletionString::CK_LeftBrace);
1010 Pattern->AddPlaceholderChunk("statements");
1011 Pattern->AddChunk(CodeCompletionString::CK_VerticalSpace);
1012 Pattern->AddChunk(CodeCompletionString::CK_RightBrace);
Douglas Gregora4477812010-01-14 16:01:26 +00001013 Results.AddResult(Result(Pattern));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001014 }
Douglas Gregorb6ac2452010-01-13 21:24:21 +00001015 if (SemaRef.getLangOptions().ObjC1)
Douglas Gregorbca403c2010-01-13 23:51:12 +00001016 AddObjCStatementResults(Results, true);
Douglas Gregorb6ac2452010-01-13 21:24:21 +00001017
Douglas Gregor01dfea02010-01-10 23:08:15 +00001018 // if (condition) { statements }
1019 Pattern = new CodeCompletionString;
1020 Pattern->AddTypedTextChunk("if");
1021 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
1022 if (SemaRef.getLangOptions().CPlusPlus)
1023 Pattern->AddPlaceholderChunk("condition");
1024 else
1025 Pattern->AddPlaceholderChunk("expression");
1026 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
1027 Pattern->AddChunk(CodeCompletionString::CK_LeftBrace);
1028 Pattern->AddPlaceholderChunk("statements");
1029 Pattern->AddChunk(CodeCompletionString::CK_VerticalSpace);
1030 Pattern->AddChunk(CodeCompletionString::CK_RightBrace);
Douglas Gregora4477812010-01-14 16:01:26 +00001031 Results.AddResult(Result(Pattern));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001032
1033 // switch (condition) { }
1034 Pattern = new CodeCompletionString;
1035 Pattern->AddTypedTextChunk("switch");
1036 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
1037 if (SemaRef.getLangOptions().CPlusPlus)
1038 Pattern->AddPlaceholderChunk("condition");
1039 else
1040 Pattern->AddPlaceholderChunk("expression");
1041 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
1042 Pattern->AddChunk(CodeCompletionString::CK_LeftBrace);
1043 Pattern->AddChunk(CodeCompletionString::CK_VerticalSpace);
1044 Pattern->AddChunk(CodeCompletionString::CK_RightBrace);
Douglas Gregora4477812010-01-14 16:01:26 +00001045 Results.AddResult(Result(Pattern));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001046
1047 // Switch-specific statements.
1048 if (!SemaRef.getSwitchStack().empty()) {
1049 // case expression:
1050 Pattern = new CodeCompletionString;
1051 Pattern->AddTypedTextChunk("case");
1052 Pattern->AddPlaceholderChunk("expression");
1053 Pattern->AddChunk(CodeCompletionString::CK_Colon);
Douglas Gregora4477812010-01-14 16:01:26 +00001054 Results.AddResult(Result(Pattern));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001055
1056 // default:
1057 Pattern = new CodeCompletionString;
1058 Pattern->AddTypedTextChunk("default");
1059 Pattern->AddChunk(CodeCompletionString::CK_Colon);
Douglas Gregora4477812010-01-14 16:01:26 +00001060 Results.AddResult(Result(Pattern));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001061 }
1062
1063 /// while (condition) { statements }
1064 Pattern = new CodeCompletionString;
1065 Pattern->AddTypedTextChunk("while");
1066 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
1067 if (SemaRef.getLangOptions().CPlusPlus)
1068 Pattern->AddPlaceholderChunk("condition");
1069 else
1070 Pattern->AddPlaceholderChunk("expression");
1071 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
1072 Pattern->AddChunk(CodeCompletionString::CK_LeftBrace);
1073 Pattern->AddPlaceholderChunk("statements");
1074 Pattern->AddChunk(CodeCompletionString::CK_VerticalSpace);
1075 Pattern->AddChunk(CodeCompletionString::CK_RightBrace);
Douglas Gregora4477812010-01-14 16:01:26 +00001076 Results.AddResult(Result(Pattern));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001077
1078 // do { statements } while ( expression );
1079 Pattern = new CodeCompletionString;
1080 Pattern->AddTypedTextChunk("do");
1081 Pattern->AddChunk(CodeCompletionString::CK_LeftBrace);
1082 Pattern->AddPlaceholderChunk("statements");
1083 Pattern->AddChunk(CodeCompletionString::CK_VerticalSpace);
1084 Pattern->AddChunk(CodeCompletionString::CK_RightBrace);
1085 Pattern->AddTextChunk("while");
1086 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
1087 Pattern->AddPlaceholderChunk("expression");
1088 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
Douglas Gregora4477812010-01-14 16:01:26 +00001089 Results.AddResult(Result(Pattern));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001090
1091 // for ( for-init-statement ; condition ; expression ) { statements }
1092 Pattern = new CodeCompletionString;
1093 Pattern->AddTypedTextChunk("for");
1094 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
1095 if (SemaRef.getLangOptions().CPlusPlus || SemaRef.getLangOptions().C99)
1096 Pattern->AddPlaceholderChunk("init-statement");
1097 else
1098 Pattern->AddPlaceholderChunk("init-expression");
1099 Pattern->AddChunk(CodeCompletionString::CK_SemiColon);
1100 Pattern->AddPlaceholderChunk("condition");
1101 Pattern->AddChunk(CodeCompletionString::CK_SemiColon);
1102 Pattern->AddPlaceholderChunk("inc-expression");
1103 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
1104 Pattern->AddChunk(CodeCompletionString::CK_LeftBrace);
1105 Pattern->AddPlaceholderChunk("statements");
1106 Pattern->AddChunk(CodeCompletionString::CK_VerticalSpace);
1107 Pattern->AddChunk(CodeCompletionString::CK_RightBrace);
Douglas Gregora4477812010-01-14 16:01:26 +00001108 Results.AddResult(Result(Pattern));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001109
1110 if (S->getContinueParent()) {
1111 // continue ;
1112 Pattern = new CodeCompletionString;
1113 Pattern->AddTypedTextChunk("continue");
Douglas Gregora4477812010-01-14 16:01:26 +00001114 Results.AddResult(Result(Pattern));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001115 }
1116
1117 if (S->getBreakParent()) {
1118 // break ;
1119 Pattern = new CodeCompletionString;
1120 Pattern->AddTypedTextChunk("break");
Douglas Gregora4477812010-01-14 16:01:26 +00001121 Results.AddResult(Result(Pattern));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001122 }
1123
1124 // "return expression ;" or "return ;", depending on whether we
1125 // know the function is void or not.
1126 bool isVoid = false;
1127 if (FunctionDecl *Function = dyn_cast<FunctionDecl>(SemaRef.CurContext))
1128 isVoid = Function->getResultType()->isVoidType();
1129 else if (ObjCMethodDecl *Method
1130 = dyn_cast<ObjCMethodDecl>(SemaRef.CurContext))
1131 isVoid = Method->getResultType()->isVoidType();
Douglas Gregor9ea9bdb2010-03-01 23:15:13 +00001132 else if (SemaRef.getCurBlock() &&
1133 !SemaRef.getCurBlock()->ReturnType.isNull())
1134 isVoid = SemaRef.getCurBlock()->ReturnType->isVoidType();
Douglas Gregor01dfea02010-01-10 23:08:15 +00001135 Pattern = new CodeCompletionString;
1136 Pattern->AddTypedTextChunk("return");
Douglas Gregor93298002010-02-18 04:06:48 +00001137 if (!isVoid) {
1138 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
Douglas Gregor01dfea02010-01-10 23:08:15 +00001139 Pattern->AddPlaceholderChunk("expression");
Douglas Gregor93298002010-02-18 04:06:48 +00001140 }
Douglas Gregora4477812010-01-14 16:01:26 +00001141 Results.AddResult(Result(Pattern));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001142
1143 // goto identifier ;
1144 Pattern = new CodeCompletionString;
1145 Pattern->AddTypedTextChunk("goto");
1146 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
1147 Pattern->AddPlaceholderChunk("identifier");
Douglas Gregora4477812010-01-14 16:01:26 +00001148 Results.AddResult(Result(Pattern));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001149
1150 // Using directives
1151 Pattern = new CodeCompletionString;
1152 Pattern->AddTypedTextChunk("using");
1153 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
1154 Pattern->AddTextChunk("namespace");
1155 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
1156 Pattern->AddPlaceholderChunk("identifier");
Douglas Gregora4477812010-01-14 16:01:26 +00001157 Results.AddResult(Result(Pattern));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001158 }
1159
1160 // Fall through (for statement expressions).
1161 case Action::CCC_ForInit:
1162 case Action::CCC_Condition:
Douglas Gregorbca403c2010-01-13 23:51:12 +00001163 AddStorageSpecifiers(CCC, SemaRef.getLangOptions(), Results);
Douglas Gregor01dfea02010-01-10 23:08:15 +00001164 // Fall through: conditions and statements can have expressions.
1165
1166 case Action::CCC_Expression: {
1167 CodeCompletionString *Pattern = 0;
1168 if (SemaRef.getLangOptions().CPlusPlus) {
1169 // 'this', if we're in a non-static member function.
1170 if (CXXMethodDecl *Method = dyn_cast<CXXMethodDecl>(SemaRef.CurContext))
1171 if (!Method->isStatic())
Douglas Gregora4477812010-01-14 16:01:26 +00001172 Results.AddResult(Result("this"));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001173
1174 // true, false
Douglas Gregora4477812010-01-14 16:01:26 +00001175 Results.AddResult(Result("true"));
1176 Results.AddResult(Result("false"));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001177
1178 // dynamic_cast < type-id > ( expression )
1179 Pattern = new CodeCompletionString;
1180 Pattern->AddTypedTextChunk("dynamic_cast");
1181 Pattern->AddChunk(CodeCompletionString::CK_LeftAngle);
1182 Pattern->AddPlaceholderChunk("type-id");
1183 Pattern->AddChunk(CodeCompletionString::CK_RightAngle);
1184 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
1185 Pattern->AddPlaceholderChunk("expression");
1186 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
Douglas Gregora4477812010-01-14 16:01:26 +00001187 Results.AddResult(Result(Pattern));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001188
1189 // static_cast < type-id > ( expression )
1190 Pattern = new CodeCompletionString;
1191 Pattern->AddTypedTextChunk("static_cast");
1192 Pattern->AddChunk(CodeCompletionString::CK_LeftAngle);
1193 Pattern->AddPlaceholderChunk("type-id");
1194 Pattern->AddChunk(CodeCompletionString::CK_RightAngle);
1195 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
1196 Pattern->AddPlaceholderChunk("expression");
1197 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
Douglas Gregora4477812010-01-14 16:01:26 +00001198 Results.AddResult(Result(Pattern));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001199
1200 // reinterpret_cast < type-id > ( expression )
1201 Pattern = new CodeCompletionString;
1202 Pattern->AddTypedTextChunk("reinterpret_cast");
1203 Pattern->AddChunk(CodeCompletionString::CK_LeftAngle);
1204 Pattern->AddPlaceholderChunk("type-id");
1205 Pattern->AddChunk(CodeCompletionString::CK_RightAngle);
1206 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
1207 Pattern->AddPlaceholderChunk("expression");
1208 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
Douglas Gregora4477812010-01-14 16:01:26 +00001209 Results.AddResult(Result(Pattern));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001210
1211 // const_cast < type-id > ( expression )
1212 Pattern = new CodeCompletionString;
1213 Pattern->AddTypedTextChunk("const_cast");
1214 Pattern->AddChunk(CodeCompletionString::CK_LeftAngle);
1215 Pattern->AddPlaceholderChunk("type-id");
1216 Pattern->AddChunk(CodeCompletionString::CK_RightAngle);
1217 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
1218 Pattern->AddPlaceholderChunk("expression");
1219 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
Douglas Gregora4477812010-01-14 16:01:26 +00001220 Results.AddResult(Result(Pattern));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001221
1222 // typeid ( expression-or-type )
1223 Pattern = new CodeCompletionString;
1224 Pattern->AddTypedTextChunk("typeid");
1225 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
1226 Pattern->AddPlaceholderChunk("expression-or-type");
1227 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
Douglas Gregora4477812010-01-14 16:01:26 +00001228 Results.AddResult(Result(Pattern));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001229
1230 // new T ( ... )
1231 Pattern = new CodeCompletionString;
1232 Pattern->AddTypedTextChunk("new");
1233 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
1234 Pattern->AddPlaceholderChunk("type-id");
1235 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
1236 Pattern->AddPlaceholderChunk("expressions");
1237 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
Douglas Gregora4477812010-01-14 16:01:26 +00001238 Results.AddResult(Result(Pattern));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001239
1240 // new T [ ] ( ... )
1241 Pattern = new CodeCompletionString;
1242 Pattern->AddTypedTextChunk("new");
1243 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
1244 Pattern->AddPlaceholderChunk("type-id");
1245 Pattern->AddChunk(CodeCompletionString::CK_LeftBracket);
1246 Pattern->AddPlaceholderChunk("size");
1247 Pattern->AddChunk(CodeCompletionString::CK_RightBracket);
1248 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
1249 Pattern->AddPlaceholderChunk("expressions");
1250 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
Douglas Gregora4477812010-01-14 16:01:26 +00001251 Results.AddResult(Result(Pattern));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001252
1253 // delete expression
1254 Pattern = new CodeCompletionString;
1255 Pattern->AddTypedTextChunk("delete");
1256 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
1257 Pattern->AddPlaceholderChunk("expression");
Douglas Gregora4477812010-01-14 16:01:26 +00001258 Results.AddResult(Result(Pattern));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001259
1260 // delete [] expression
1261 Pattern = new CodeCompletionString;
1262 Pattern->AddTypedTextChunk("delete");
1263 Pattern->AddChunk(CodeCompletionString::CK_LeftBracket);
1264 Pattern->AddChunk(CodeCompletionString::CK_RightBracket);
1265 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
1266 Pattern->AddPlaceholderChunk("expression");
Douglas Gregora4477812010-01-14 16:01:26 +00001267 Results.AddResult(Result(Pattern));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001268
1269 // throw expression
1270 Pattern = new CodeCompletionString;
1271 Pattern->AddTypedTextChunk("throw");
1272 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
1273 Pattern->AddPlaceholderChunk("expression");
Douglas Gregora4477812010-01-14 16:01:26 +00001274 Results.AddResult(Result(Pattern));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001275 }
1276
1277 if (SemaRef.getLangOptions().ObjC1) {
1278 // Add "super", if we're in an Objective-C class with a superclass.
1279 if (ObjCMethodDecl *Method = SemaRef.getCurMethodDecl())
1280 if (Method->getClassInterface()->getSuperClass())
Douglas Gregora4477812010-01-14 16:01:26 +00001281 Results.AddResult(Result("super"));
Douglas Gregorb6ac2452010-01-13 21:24:21 +00001282
Douglas Gregorbca403c2010-01-13 23:51:12 +00001283 AddObjCExpressionResults(Results, true);
Douglas Gregor01dfea02010-01-10 23:08:15 +00001284 }
1285
1286 // sizeof expression
1287 Pattern = new CodeCompletionString;
1288 Pattern->AddTypedTextChunk("sizeof");
1289 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
1290 Pattern->AddPlaceholderChunk("expression-or-type");
1291 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
Douglas Gregora4477812010-01-14 16:01:26 +00001292 Results.AddResult(Result(Pattern));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001293 break;
1294 }
1295 }
1296
Douglas Gregorbca403c2010-01-13 23:51:12 +00001297 AddTypeSpecifierResults(SemaRef.getLangOptions(), Results);
Douglas Gregor01dfea02010-01-10 23:08:15 +00001298
1299 if (SemaRef.getLangOptions().CPlusPlus)
Douglas Gregora4477812010-01-14 16:01:26 +00001300 Results.AddResult(Result("operator"));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001301}
1302
Douglas Gregorff5ce6e2009-12-18 18:53:37 +00001303/// \brief If the given declaration has an associated type, add it as a result
1304/// type chunk.
1305static void AddResultTypeChunk(ASTContext &Context,
1306 NamedDecl *ND,
1307 CodeCompletionString *Result) {
1308 if (!ND)
1309 return;
1310
1311 // Determine the type of the declaration (if it has a type).
1312 QualType T;
1313 if (FunctionDecl *Function = dyn_cast<FunctionDecl>(ND))
1314 T = Function->getResultType();
1315 else if (ObjCMethodDecl *Method = dyn_cast<ObjCMethodDecl>(ND))
1316 T = Method->getResultType();
1317 else if (FunctionTemplateDecl *FunTmpl = dyn_cast<FunctionTemplateDecl>(ND))
1318 T = FunTmpl->getTemplatedDecl()->getResultType();
1319 else if (EnumConstantDecl *Enumerator = dyn_cast<EnumConstantDecl>(ND))
1320 T = Context.getTypeDeclType(cast<TypeDecl>(Enumerator->getDeclContext()));
1321 else if (isa<UnresolvedUsingValueDecl>(ND)) {
1322 /* Do nothing: ignore unresolved using declarations*/
1323 } else if (ValueDecl *Value = dyn_cast<ValueDecl>(ND))
1324 T = Value->getType();
1325 else if (ObjCPropertyDecl *Property = dyn_cast<ObjCPropertyDecl>(ND))
1326 T = Property->getType();
1327
1328 if (T.isNull() || Context.hasSameType(T, Context.DependentTy))
1329 return;
1330
Douglas Gregor84139d62010-04-05 21:25:31 +00001331 PrintingPolicy Policy(Context.PrintingPolicy);
1332 Policy.AnonymousTagLocations = false;
1333
Douglas Gregorff5ce6e2009-12-18 18:53:37 +00001334 std::string TypeStr;
Douglas Gregor84139d62010-04-05 21:25:31 +00001335 T.getAsStringInternal(TypeStr, Policy);
Douglas Gregorff5ce6e2009-12-18 18:53:37 +00001336 Result->AddResultTypeChunk(TypeStr);
1337}
1338
Douglas Gregor86d9a522009-09-21 16:56:56 +00001339/// \brief Add function parameter chunks to the given code completion string.
1340static void AddFunctionParameterChunks(ASTContext &Context,
1341 FunctionDecl *Function,
1342 CodeCompletionString *Result) {
Douglas Gregor0c8296d2009-11-07 00:00:49 +00001343 typedef CodeCompletionString::Chunk Chunk;
1344
Douglas Gregor86d9a522009-09-21 16:56:56 +00001345 CodeCompletionString *CCStr = Result;
1346
1347 for (unsigned P = 0, N = Function->getNumParams(); P != N; ++P) {
1348 ParmVarDecl *Param = Function->getParamDecl(P);
1349
1350 if (Param->hasDefaultArg()) {
1351 // When we see an optional default argument, put that argument and
1352 // the remaining default arguments into a new, optional string.
1353 CodeCompletionString *Opt = new CodeCompletionString;
1354 CCStr->AddOptionalChunk(std::auto_ptr<CodeCompletionString>(Opt));
1355 CCStr = Opt;
1356 }
1357
1358 if (P != 0)
Douglas Gregor0c8296d2009-11-07 00:00:49 +00001359 CCStr->AddChunk(Chunk(CodeCompletionString::CK_Comma));
Douglas Gregor86d9a522009-09-21 16:56:56 +00001360
1361 // Format the placeholder string.
1362 std::string PlaceholderStr;
1363 if (Param->getIdentifier())
1364 PlaceholderStr = Param->getIdentifier()->getName();
1365
1366 Param->getType().getAsStringInternal(PlaceholderStr,
1367 Context.PrintingPolicy);
1368
1369 // Add the placeholder string.
Benjamin Kramer660cc182009-11-29 20:18:50 +00001370 CCStr->AddPlaceholderChunk(PlaceholderStr);
Douglas Gregor86d9a522009-09-21 16:56:56 +00001371 }
Douglas Gregorb3d45252009-09-22 21:42:17 +00001372
1373 if (const FunctionProtoType *Proto
1374 = Function->getType()->getAs<FunctionProtoType>())
1375 if (Proto->isVariadic())
1376 CCStr->AddPlaceholderChunk(", ...");
Douglas Gregor86d9a522009-09-21 16:56:56 +00001377}
1378
1379/// \brief Add template parameter chunks to the given code completion string.
1380static void AddTemplateParameterChunks(ASTContext &Context,
1381 TemplateDecl *Template,
1382 CodeCompletionString *Result,
1383 unsigned MaxParameters = 0) {
Douglas Gregor0c8296d2009-11-07 00:00:49 +00001384 typedef CodeCompletionString::Chunk Chunk;
1385
Douglas Gregor86d9a522009-09-21 16:56:56 +00001386 CodeCompletionString *CCStr = Result;
1387 bool FirstParameter = true;
1388
1389 TemplateParameterList *Params = Template->getTemplateParameters();
1390 TemplateParameterList::iterator PEnd = Params->end();
1391 if (MaxParameters)
1392 PEnd = Params->begin() + MaxParameters;
1393 for (TemplateParameterList::iterator P = Params->begin(); P != PEnd; ++P) {
1394 bool HasDefaultArg = false;
1395 std::string PlaceholderStr;
1396 if (TemplateTypeParmDecl *TTP = dyn_cast<TemplateTypeParmDecl>(*P)) {
1397 if (TTP->wasDeclaredWithTypename())
1398 PlaceholderStr = "typename";
1399 else
1400 PlaceholderStr = "class";
1401
1402 if (TTP->getIdentifier()) {
1403 PlaceholderStr += ' ';
1404 PlaceholderStr += TTP->getIdentifier()->getName();
1405 }
1406
1407 HasDefaultArg = TTP->hasDefaultArgument();
1408 } else if (NonTypeTemplateParmDecl *NTTP
1409 = dyn_cast<NonTypeTemplateParmDecl>(*P)) {
1410 if (NTTP->getIdentifier())
1411 PlaceholderStr = NTTP->getIdentifier()->getName();
1412 NTTP->getType().getAsStringInternal(PlaceholderStr,
1413 Context.PrintingPolicy);
1414 HasDefaultArg = NTTP->hasDefaultArgument();
1415 } else {
1416 assert(isa<TemplateTemplateParmDecl>(*P));
1417 TemplateTemplateParmDecl *TTP = cast<TemplateTemplateParmDecl>(*P);
1418
1419 // Since putting the template argument list into the placeholder would
1420 // be very, very long, we just use an abbreviation.
1421 PlaceholderStr = "template<...> class";
1422 if (TTP->getIdentifier()) {
1423 PlaceholderStr += ' ';
1424 PlaceholderStr += TTP->getIdentifier()->getName();
1425 }
1426
1427 HasDefaultArg = TTP->hasDefaultArgument();
1428 }
1429
1430 if (HasDefaultArg) {
1431 // When we see an optional default argument, put that argument and
1432 // the remaining default arguments into a new, optional string.
1433 CodeCompletionString *Opt = new CodeCompletionString;
1434 CCStr->AddOptionalChunk(std::auto_ptr<CodeCompletionString>(Opt));
1435 CCStr = Opt;
1436 }
1437
1438 if (FirstParameter)
1439 FirstParameter = false;
1440 else
Douglas Gregor0c8296d2009-11-07 00:00:49 +00001441 CCStr->AddChunk(Chunk(CodeCompletionString::CK_Comma));
Douglas Gregor86d9a522009-09-21 16:56:56 +00001442
1443 // Add the placeholder string.
Benjamin Kramer660cc182009-11-29 20:18:50 +00001444 CCStr->AddPlaceholderChunk(PlaceholderStr);
Douglas Gregor86d9a522009-09-21 16:56:56 +00001445 }
1446}
1447
Douglas Gregorb9d0ef72009-09-21 19:57:38 +00001448/// \brief Add a qualifier to the given code-completion string, if the
1449/// provided nested-name-specifier is non-NULL.
Douglas Gregora61a8792009-12-11 18:44:16 +00001450static void
1451AddQualifierToCompletionString(CodeCompletionString *Result,
1452 NestedNameSpecifier *Qualifier,
1453 bool QualifierIsInformative,
1454 ASTContext &Context) {
Douglas Gregorb9d0ef72009-09-21 19:57:38 +00001455 if (!Qualifier)
1456 return;
1457
1458 std::string PrintedNNS;
1459 {
1460 llvm::raw_string_ostream OS(PrintedNNS);
1461 Qualifier->print(OS, Context.PrintingPolicy);
1462 }
Douglas Gregor0563c262009-09-22 23:15:58 +00001463 if (QualifierIsInformative)
Benjamin Kramer660cc182009-11-29 20:18:50 +00001464 Result->AddInformativeChunk(PrintedNNS);
Douglas Gregor0563c262009-09-22 23:15:58 +00001465 else
Benjamin Kramer660cc182009-11-29 20:18:50 +00001466 Result->AddTextChunk(PrintedNNS);
Douglas Gregorb9d0ef72009-09-21 19:57:38 +00001467}
1468
Douglas Gregora61a8792009-12-11 18:44:16 +00001469static void AddFunctionTypeQualsToCompletionString(CodeCompletionString *Result,
1470 FunctionDecl *Function) {
1471 const FunctionProtoType *Proto
1472 = Function->getType()->getAs<FunctionProtoType>();
1473 if (!Proto || !Proto->getTypeQuals())
1474 return;
1475
1476 std::string QualsStr;
1477 if (Proto->getTypeQuals() & Qualifiers::Const)
1478 QualsStr += " const";
1479 if (Proto->getTypeQuals() & Qualifiers::Volatile)
1480 QualsStr += " volatile";
1481 if (Proto->getTypeQuals() & Qualifiers::Restrict)
1482 QualsStr += " restrict";
1483 Result->AddInformativeChunk(QualsStr);
1484}
1485
Douglas Gregor86d9a522009-09-21 16:56:56 +00001486/// \brief If possible, create a new code completion string for the given
1487/// result.
1488///
1489/// \returns Either a new, heap-allocated code completion string describing
1490/// how to use this result, or NULL to indicate that the string or name of the
1491/// result is all that is needed.
1492CodeCompletionString *
1493CodeCompleteConsumer::Result::CreateCodeCompletionString(Sema &S) {
Douglas Gregor0c8296d2009-11-07 00:00:49 +00001494 typedef CodeCompletionString::Chunk Chunk;
1495
Douglas Gregor2b4074f2009-12-01 05:55:20 +00001496 if (Kind == RK_Pattern)
1497 return Pattern->Clone();
1498
1499 CodeCompletionString *Result = new CodeCompletionString;
1500
1501 if (Kind == RK_Keyword) {
1502 Result->AddTypedTextChunk(Keyword);
1503 return Result;
1504 }
Douglas Gregor86d9a522009-09-21 16:56:56 +00001505
Douglas Gregor3f7c7f42009-10-30 16:50:04 +00001506 if (Kind == RK_Macro) {
1507 MacroInfo *MI = S.PP.getMacroInfo(Macro);
Douglas Gregor2b4074f2009-12-01 05:55:20 +00001508 assert(MI && "Not a macro?");
1509
1510 Result->AddTypedTextChunk(Macro->getName());
1511
1512 if (!MI->isFunctionLike())
1513 return Result;
Douglas Gregor3f7c7f42009-10-30 16:50:04 +00001514
1515 // Format a function-like macro with placeholders for the arguments.
Douglas Gregor0c8296d2009-11-07 00:00:49 +00001516 Result->AddChunk(Chunk(CodeCompletionString::CK_LeftParen));
Douglas Gregor3f7c7f42009-10-30 16:50:04 +00001517 for (MacroInfo::arg_iterator A = MI->arg_begin(), AEnd = MI->arg_end();
1518 A != AEnd; ++A) {
1519 if (A != MI->arg_begin())
Douglas Gregor0c8296d2009-11-07 00:00:49 +00001520 Result->AddChunk(Chunk(CodeCompletionString::CK_Comma));
Douglas Gregor3f7c7f42009-10-30 16:50:04 +00001521
1522 if (!MI->isVariadic() || A != AEnd - 1) {
1523 // Non-variadic argument.
Benjamin Kramer660cc182009-11-29 20:18:50 +00001524 Result->AddPlaceholderChunk((*A)->getName());
Douglas Gregor3f7c7f42009-10-30 16:50:04 +00001525 continue;
1526 }
1527
1528 // Variadic argument; cope with the different between GNU and C99
1529 // variadic macros, providing a single placeholder for the rest of the
1530 // arguments.
1531 if ((*A)->isStr("__VA_ARGS__"))
1532 Result->AddPlaceholderChunk("...");
1533 else {
1534 std::string Arg = (*A)->getName();
1535 Arg += "...";
Benjamin Kramer660cc182009-11-29 20:18:50 +00001536 Result->AddPlaceholderChunk(Arg);
Douglas Gregor3f7c7f42009-10-30 16:50:04 +00001537 }
1538 }
Douglas Gregor0c8296d2009-11-07 00:00:49 +00001539 Result->AddChunk(Chunk(CodeCompletionString::CK_RightParen));
Douglas Gregor3f7c7f42009-10-30 16:50:04 +00001540 return Result;
1541 }
1542
1543 assert(Kind == RK_Declaration && "Missed a macro kind?");
Douglas Gregor86d9a522009-09-21 16:56:56 +00001544 NamedDecl *ND = Declaration;
1545
Douglas Gregor0c8296d2009-11-07 00:00:49 +00001546 if (StartsNestedNameSpecifier) {
Benjamin Kramer660cc182009-11-29 20:18:50 +00001547 Result->AddTypedTextChunk(ND->getNameAsString());
Douglas Gregor0c8296d2009-11-07 00:00:49 +00001548 Result->AddTextChunk("::");
1549 return Result;
1550 }
1551
Douglas Gregorff5ce6e2009-12-18 18:53:37 +00001552 AddResultTypeChunk(S.Context, ND, Result);
1553
Douglas Gregor86d9a522009-09-21 16:56:56 +00001554 if (FunctionDecl *Function = dyn_cast<FunctionDecl>(ND)) {
Douglas Gregor0563c262009-09-22 23:15:58 +00001555 AddQualifierToCompletionString(Result, Qualifier, QualifierIsInformative,
1556 S.Context);
Benjamin Kramer660cc182009-11-29 20:18:50 +00001557 Result->AddTypedTextChunk(Function->getNameAsString());
Douglas Gregor0c8296d2009-11-07 00:00:49 +00001558 Result->AddChunk(Chunk(CodeCompletionString::CK_LeftParen));
Douglas Gregor86d9a522009-09-21 16:56:56 +00001559 AddFunctionParameterChunks(S.Context, Function, Result);
Douglas Gregor0c8296d2009-11-07 00:00:49 +00001560 Result->AddChunk(Chunk(CodeCompletionString::CK_RightParen));
Douglas Gregora61a8792009-12-11 18:44:16 +00001561 AddFunctionTypeQualsToCompletionString(Result, Function);
Douglas Gregor86d9a522009-09-21 16:56:56 +00001562 return Result;
1563 }
1564
1565 if (FunctionTemplateDecl *FunTmpl = dyn_cast<FunctionTemplateDecl>(ND)) {
Douglas Gregor0563c262009-09-22 23:15:58 +00001566 AddQualifierToCompletionString(Result, Qualifier, QualifierIsInformative,
1567 S.Context);
Douglas Gregor86d9a522009-09-21 16:56:56 +00001568 FunctionDecl *Function = FunTmpl->getTemplatedDecl();
Benjamin Kramer660cc182009-11-29 20:18:50 +00001569 Result->AddTypedTextChunk(Function->getNameAsString());
Douglas Gregor86d9a522009-09-21 16:56:56 +00001570
1571 // Figure out which template parameters are deduced (or have default
1572 // arguments).
1573 llvm::SmallVector<bool, 16> Deduced;
1574 S.MarkDeducedTemplateParameters(FunTmpl, Deduced);
1575 unsigned LastDeducibleArgument;
1576 for (LastDeducibleArgument = Deduced.size(); LastDeducibleArgument > 0;
1577 --LastDeducibleArgument) {
1578 if (!Deduced[LastDeducibleArgument - 1]) {
1579 // C++0x: Figure out if the template argument has a default. If so,
1580 // the user doesn't need to type this argument.
1581 // FIXME: We need to abstract template parameters better!
1582 bool HasDefaultArg = false;
1583 NamedDecl *Param = FunTmpl->getTemplateParameters()->getParam(
1584 LastDeducibleArgument - 1);
1585 if (TemplateTypeParmDecl *TTP = dyn_cast<TemplateTypeParmDecl>(Param))
1586 HasDefaultArg = TTP->hasDefaultArgument();
1587 else if (NonTypeTemplateParmDecl *NTTP
1588 = dyn_cast<NonTypeTemplateParmDecl>(Param))
1589 HasDefaultArg = NTTP->hasDefaultArgument();
1590 else {
1591 assert(isa<TemplateTemplateParmDecl>(Param));
1592 HasDefaultArg
Douglas Gregor0c8296d2009-11-07 00:00:49 +00001593 = cast<TemplateTemplateParmDecl>(Param)->hasDefaultArgument();
Douglas Gregor86d9a522009-09-21 16:56:56 +00001594 }
1595
1596 if (!HasDefaultArg)
1597 break;
1598 }
1599 }
1600
1601 if (LastDeducibleArgument) {
1602 // Some of the function template arguments cannot be deduced from a
1603 // function call, so we introduce an explicit template argument list
1604 // containing all of the arguments up to the first deducible argument.
Douglas Gregor0c8296d2009-11-07 00:00:49 +00001605 Result->AddChunk(Chunk(CodeCompletionString::CK_LeftAngle));
Douglas Gregor86d9a522009-09-21 16:56:56 +00001606 AddTemplateParameterChunks(S.Context, FunTmpl, Result,
1607 LastDeducibleArgument);
Douglas Gregor0c8296d2009-11-07 00:00:49 +00001608 Result->AddChunk(Chunk(CodeCompletionString::CK_RightAngle));
Douglas Gregor86d9a522009-09-21 16:56:56 +00001609 }
1610
1611 // Add the function parameters
Douglas Gregor0c8296d2009-11-07 00:00:49 +00001612 Result->AddChunk(Chunk(CodeCompletionString::CK_LeftParen));
Douglas Gregor86d9a522009-09-21 16:56:56 +00001613 AddFunctionParameterChunks(S.Context, Function, Result);
Douglas Gregor0c8296d2009-11-07 00:00:49 +00001614 Result->AddChunk(Chunk(CodeCompletionString::CK_RightParen));
Douglas Gregora61a8792009-12-11 18:44:16 +00001615 AddFunctionTypeQualsToCompletionString(Result, Function);
Douglas Gregor86d9a522009-09-21 16:56:56 +00001616 return Result;
1617 }
1618
1619 if (TemplateDecl *Template = dyn_cast<TemplateDecl>(ND)) {
Douglas Gregor0563c262009-09-22 23:15:58 +00001620 AddQualifierToCompletionString(Result, Qualifier, QualifierIsInformative,
1621 S.Context);
Benjamin Kramer660cc182009-11-29 20:18:50 +00001622 Result->AddTypedTextChunk(Template->getNameAsString());
Douglas Gregor0c8296d2009-11-07 00:00:49 +00001623 Result->AddChunk(Chunk(CodeCompletionString::CK_LeftAngle));
Douglas Gregor86d9a522009-09-21 16:56:56 +00001624 AddTemplateParameterChunks(S.Context, Template, Result);
Douglas Gregor0c8296d2009-11-07 00:00:49 +00001625 Result->AddChunk(Chunk(CodeCompletionString::CK_RightAngle));
Douglas Gregor86d9a522009-09-21 16:56:56 +00001626 return Result;
1627 }
1628
Douglas Gregor9630eb62009-11-17 16:44:22 +00001629 if (ObjCMethodDecl *Method = dyn_cast<ObjCMethodDecl>(ND)) {
Douglas Gregor9630eb62009-11-17 16:44:22 +00001630 Selector Sel = Method->getSelector();
1631 if (Sel.isUnarySelector()) {
1632 Result->AddTypedTextChunk(Sel.getIdentifierInfoForSlot(0)->getName());
1633 return Result;
1634 }
1635
Douglas Gregord3c68542009-11-19 01:08:35 +00001636 std::string SelName = Sel.getIdentifierInfoForSlot(0)->getName().str();
1637 SelName += ':';
1638 if (StartParameter == 0)
1639 Result->AddTypedTextChunk(SelName);
1640 else {
1641 Result->AddInformativeChunk(SelName);
1642
1643 // If there is only one parameter, and we're past it, add an empty
1644 // typed-text chunk since there is nothing to type.
1645 if (Method->param_size() == 1)
1646 Result->AddTypedTextChunk("");
1647 }
Douglas Gregor9630eb62009-11-17 16:44:22 +00001648 unsigned Idx = 0;
1649 for (ObjCMethodDecl::param_iterator P = Method->param_begin(),
1650 PEnd = Method->param_end();
1651 P != PEnd; (void)++P, ++Idx) {
1652 if (Idx > 0) {
Douglas Gregord3c68542009-11-19 01:08:35 +00001653 std::string Keyword;
1654 if (Idx > StartParameter)
Douglas Gregor834389b2010-01-12 06:38:28 +00001655 Result->AddChunk(CodeCompletionString::CK_HorizontalSpace);
Douglas Gregor9630eb62009-11-17 16:44:22 +00001656 if (IdentifierInfo *II = Sel.getIdentifierInfoForSlot(Idx))
1657 Keyword += II->getName().str();
1658 Keyword += ":";
Douglas Gregor4ad96852009-11-19 07:41:15 +00001659 if (Idx < StartParameter || AllParametersAreInformative) {
Douglas Gregord3c68542009-11-19 01:08:35 +00001660 Result->AddInformativeChunk(Keyword);
1661 } else if (Idx == StartParameter)
1662 Result->AddTypedTextChunk(Keyword);
1663 else
1664 Result->AddTextChunk(Keyword);
Douglas Gregor9630eb62009-11-17 16:44:22 +00001665 }
Douglas Gregord3c68542009-11-19 01:08:35 +00001666
1667 // If we're before the starting parameter, skip the placeholder.
1668 if (Idx < StartParameter)
1669 continue;
Douglas Gregor9630eb62009-11-17 16:44:22 +00001670
1671 std::string Arg;
1672 (*P)->getType().getAsStringInternal(Arg, S.Context.PrintingPolicy);
1673 Arg = "(" + Arg + ")";
1674 if (IdentifierInfo *II = (*P)->getIdentifier())
1675 Arg += II->getName().str();
Douglas Gregor4ad96852009-11-19 07:41:15 +00001676 if (AllParametersAreInformative)
1677 Result->AddInformativeChunk(Arg);
1678 else
1679 Result->AddPlaceholderChunk(Arg);
Douglas Gregor9630eb62009-11-17 16:44:22 +00001680 }
1681
Douglas Gregor2a17af02009-12-23 00:21:46 +00001682 if (Method->isVariadic()) {
1683 if (AllParametersAreInformative)
1684 Result->AddInformativeChunk(", ...");
1685 else
1686 Result->AddPlaceholderChunk(", ...");
1687 }
1688
Douglas Gregor9630eb62009-11-17 16:44:22 +00001689 return Result;
1690 }
1691
Douglas Gregor2b4074f2009-12-01 05:55:20 +00001692 if (Qualifier)
Douglas Gregor0563c262009-09-22 23:15:58 +00001693 AddQualifierToCompletionString(Result, Qualifier, QualifierIsInformative,
1694 S.Context);
Douglas Gregor2b4074f2009-12-01 05:55:20 +00001695
1696 Result->AddTypedTextChunk(ND->getNameAsString());
1697 return Result;
Douglas Gregor86d9a522009-09-21 16:56:56 +00001698}
1699
Douglas Gregor86d802e2009-09-23 00:34:09 +00001700CodeCompletionString *
1701CodeCompleteConsumer::OverloadCandidate::CreateSignatureString(
1702 unsigned CurrentArg,
1703 Sema &S) const {
Douglas Gregor0c8296d2009-11-07 00:00:49 +00001704 typedef CodeCompletionString::Chunk Chunk;
1705
Douglas Gregor86d802e2009-09-23 00:34:09 +00001706 CodeCompletionString *Result = new CodeCompletionString;
1707 FunctionDecl *FDecl = getFunction();
Douglas Gregorff5ce6e2009-12-18 18:53:37 +00001708 AddResultTypeChunk(S.Context, FDecl, Result);
Douglas Gregor86d802e2009-09-23 00:34:09 +00001709 const FunctionProtoType *Proto
1710 = dyn_cast<FunctionProtoType>(getFunctionType());
1711 if (!FDecl && !Proto) {
1712 // Function without a prototype. Just give the return type and a
1713 // highlighted ellipsis.
1714 const FunctionType *FT = getFunctionType();
1715 Result->AddTextChunk(
Benjamin Kramer660cc182009-11-29 20:18:50 +00001716 FT->getResultType().getAsString(S.Context.PrintingPolicy));
Douglas Gregor0c8296d2009-11-07 00:00:49 +00001717 Result->AddChunk(Chunk(CodeCompletionString::CK_LeftParen));
1718 Result->AddChunk(Chunk(CodeCompletionString::CK_CurrentParameter, "..."));
1719 Result->AddChunk(Chunk(CodeCompletionString::CK_RightParen));
Douglas Gregor86d802e2009-09-23 00:34:09 +00001720 return Result;
1721 }
1722
1723 if (FDecl)
Benjamin Kramer660cc182009-11-29 20:18:50 +00001724 Result->AddTextChunk(FDecl->getNameAsString());
Douglas Gregor86d802e2009-09-23 00:34:09 +00001725 else
1726 Result->AddTextChunk(
Benjamin Kramer660cc182009-11-29 20:18:50 +00001727 Proto->getResultType().getAsString(S.Context.PrintingPolicy));
Douglas Gregor86d802e2009-09-23 00:34:09 +00001728
Douglas Gregor0c8296d2009-11-07 00:00:49 +00001729 Result->AddChunk(Chunk(CodeCompletionString::CK_LeftParen));
Douglas Gregor86d802e2009-09-23 00:34:09 +00001730 unsigned NumParams = FDecl? FDecl->getNumParams() : Proto->getNumArgs();
1731 for (unsigned I = 0; I != NumParams; ++I) {
1732 if (I)
Douglas Gregor0c8296d2009-11-07 00:00:49 +00001733 Result->AddChunk(Chunk(CodeCompletionString::CK_Comma));
Douglas Gregor86d802e2009-09-23 00:34:09 +00001734
1735 std::string ArgString;
1736 QualType ArgType;
1737
1738 if (FDecl) {
1739 ArgString = FDecl->getParamDecl(I)->getNameAsString();
1740 ArgType = FDecl->getParamDecl(I)->getOriginalType();
1741 } else {
1742 ArgType = Proto->getArgType(I);
1743 }
1744
1745 ArgType.getAsStringInternal(ArgString, S.Context.PrintingPolicy);
1746
1747 if (I == CurrentArg)
Douglas Gregor0c8296d2009-11-07 00:00:49 +00001748 Result->AddChunk(Chunk(CodeCompletionString::CK_CurrentParameter,
Benjamin Kramer660cc182009-11-29 20:18:50 +00001749 ArgString));
Douglas Gregor86d802e2009-09-23 00:34:09 +00001750 else
Benjamin Kramer660cc182009-11-29 20:18:50 +00001751 Result->AddTextChunk(ArgString);
Douglas Gregor86d802e2009-09-23 00:34:09 +00001752 }
1753
1754 if (Proto && Proto->isVariadic()) {
Douglas Gregor0c8296d2009-11-07 00:00:49 +00001755 Result->AddChunk(Chunk(CodeCompletionString::CK_Comma));
Douglas Gregor86d802e2009-09-23 00:34:09 +00001756 if (CurrentArg < NumParams)
1757 Result->AddTextChunk("...");
1758 else
Douglas Gregor0c8296d2009-11-07 00:00:49 +00001759 Result->AddChunk(Chunk(CodeCompletionString::CK_CurrentParameter, "..."));
Douglas Gregor86d802e2009-09-23 00:34:09 +00001760 }
Douglas Gregor0c8296d2009-11-07 00:00:49 +00001761 Result->AddChunk(Chunk(CodeCompletionString::CK_RightParen));
Douglas Gregor86d802e2009-09-23 00:34:09 +00001762
1763 return Result;
1764}
1765
Douglas Gregor86d9a522009-09-21 16:56:56 +00001766namespace {
1767 struct SortCodeCompleteResult {
1768 typedef CodeCompleteConsumer::Result Result;
1769
Douglas Gregor6a684032009-09-28 03:51:44 +00001770 bool isEarlierDeclarationName(DeclarationName X, DeclarationName Y) const {
Douglas Gregor2b0cc122009-12-05 09:08:56 +00001771 Selector XSel = X.getObjCSelector();
1772 Selector YSel = Y.getObjCSelector();
1773 if (!XSel.isNull() && !YSel.isNull()) {
1774 // We are comparing two selectors.
1775 unsigned N = std::min(XSel.getNumArgs(), YSel.getNumArgs());
1776 if (N == 0)
1777 ++N;
1778 for (unsigned I = 0; I != N; ++I) {
1779 IdentifierInfo *XId = XSel.getIdentifierInfoForSlot(I);
1780 IdentifierInfo *YId = YSel.getIdentifierInfoForSlot(I);
1781 if (!XId || !YId)
1782 return XId && !YId;
1783
1784 switch (XId->getName().compare_lower(YId->getName())) {
1785 case -1: return true;
1786 case 1: return false;
1787 default: break;
1788 }
1789 }
1790
1791 return XSel.getNumArgs() < YSel.getNumArgs();
1792 }
1793
1794 // For non-selectors, order by kind.
1795 if (X.getNameKind() != Y.getNameKind())
Douglas Gregor6a684032009-09-28 03:51:44 +00001796 return X.getNameKind() < Y.getNameKind();
1797
Douglas Gregor2b0cc122009-12-05 09:08:56 +00001798 // Order identifiers by comparison of their lowercased names.
1799 if (IdentifierInfo *XId = X.getAsIdentifierInfo())
1800 return XId->getName().compare_lower(
1801 Y.getAsIdentifierInfo()->getName()) < 0;
1802
1803 // Order overloaded operators by the order in which they appear
1804 // in our list of operators.
1805 if (OverloadedOperatorKind XOp = X.getCXXOverloadedOperator())
1806 return XOp < Y.getCXXOverloadedOperator();
1807
1808 // Order C++0x user-defined literal operators lexically by their
1809 // lowercased suffixes.
1810 if (IdentifierInfo *XLit = X.getCXXLiteralIdentifier())
1811 return XLit->getName().compare_lower(
1812 Y.getCXXLiteralIdentifier()->getName()) < 0;
1813
1814 // The only stable ordering we have is to turn the name into a
1815 // string and then compare the lower-case strings. This is
1816 // inefficient, but thankfully does not happen too often.
Benjamin Kramer0e7049f2009-12-05 10:22:15 +00001817 return llvm::StringRef(X.getAsString()).compare_lower(
1818 Y.getAsString()) < 0;
Douglas Gregor6a684032009-09-28 03:51:44 +00001819 }
1820
Douglas Gregorab0b4f12010-01-13 23:24:38 +00001821 /// \brief Retrieve the name that should be used to order a result.
1822 ///
1823 /// If the name needs to be constructed as a string, that string will be
1824 /// saved into Saved and the returned StringRef will refer to it.
1825 static llvm::StringRef getOrderedName(const Result &R,
1826 std::string &Saved) {
1827 switch (R.Kind) {
1828 case Result::RK_Keyword:
1829 return R.Keyword;
1830
1831 case Result::RK_Pattern:
1832 return R.Pattern->getTypedText();
1833
1834 case Result::RK_Macro:
1835 return R.Macro->getName();
1836
1837 case Result::RK_Declaration:
1838 // Handle declarations below.
1839 break;
Douglas Gregor54f01612009-11-19 00:01:57 +00001840 }
Douglas Gregorab0b4f12010-01-13 23:24:38 +00001841
1842 DeclarationName Name = R.Declaration->getDeclName();
Douglas Gregor54f01612009-11-19 00:01:57 +00001843
Douglas Gregorab0b4f12010-01-13 23:24:38 +00001844 // If the name is a simple identifier (by far the common case), or a
1845 // zero-argument selector, just return a reference to that identifier.
1846 if (IdentifierInfo *Id = Name.getAsIdentifierInfo())
1847 return Id->getName();
1848 if (Name.isObjCZeroArgSelector())
1849 if (IdentifierInfo *Id
1850 = Name.getObjCSelector().getIdentifierInfoForSlot(0))
1851 return Id->getName();
1852
1853 Saved = Name.getAsString();
1854 return Saved;
1855 }
1856
1857 bool operator()(const Result &X, const Result &Y) const {
1858 std::string XSaved, YSaved;
1859 llvm::StringRef XStr = getOrderedName(X, XSaved);
1860 llvm::StringRef YStr = getOrderedName(Y, YSaved);
1861 int cmp = XStr.compare_lower(YStr);
1862 if (cmp)
1863 return cmp < 0;
Douglas Gregor86d9a522009-09-21 16:56:56 +00001864
1865 // Non-hidden names precede hidden names.
1866 if (X.Hidden != Y.Hidden)
1867 return !X.Hidden;
1868
Douglas Gregoreb5758b2009-09-23 22:26:46 +00001869 // Non-nested-name-specifiers precede nested-name-specifiers.
1870 if (X.StartsNestedNameSpecifier != Y.StartsNestedNameSpecifier)
1871 return !X.StartsNestedNameSpecifier;
1872
Douglas Gregor86d9a522009-09-21 16:56:56 +00001873 return false;
1874 }
1875 };
1876}
1877
Douglas Gregorbca403c2010-01-13 23:51:12 +00001878static void AddMacroResults(Preprocessor &PP, ResultBuilder &Results) {
Douglas Gregor3f7c7f42009-10-30 16:50:04 +00001879 Results.EnterNewScope();
Douglas Gregor0c8296d2009-11-07 00:00:49 +00001880 for (Preprocessor::macro_iterator M = PP.macro_begin(),
1881 MEnd = PP.macro_end();
Douglas Gregor3f7c7f42009-10-30 16:50:04 +00001882 M != MEnd; ++M)
Douglas Gregora4477812010-01-14 16:01:26 +00001883 Results.AddResult(M->first);
Douglas Gregor3f7c7f42009-10-30 16:50:04 +00001884 Results.ExitScope();
1885}
1886
Daniel Dunbar3a2838d2009-11-13 08:58:20 +00001887static void HandleCodeCompleteResults(Sema *S,
1888 CodeCompleteConsumer *CodeCompleter,
1889 CodeCompleteConsumer::Result *Results,
1890 unsigned NumResults) {
Douglas Gregor86d9a522009-09-21 16:56:56 +00001891 std::stable_sort(Results, Results + NumResults, SortCodeCompleteResult());
1892
1893 if (CodeCompleter)
Daniel Dunbar3a2838d2009-11-13 08:58:20 +00001894 CodeCompleter->ProcessCodeCompleteResults(*S, Results, NumResults);
Douglas Gregor54f01612009-11-19 00:01:57 +00001895
1896 for (unsigned I = 0; I != NumResults; ++I)
1897 Results[I].Destroy();
Douglas Gregor86d9a522009-09-21 16:56:56 +00001898}
1899
Douglas Gregor01dfea02010-01-10 23:08:15 +00001900void Sema::CodeCompleteOrdinaryName(Scope *S,
1901 CodeCompletionContext CompletionContext) {
Douglas Gregor2a7925c2009-12-07 09:54:55 +00001902 typedef CodeCompleteConsumer::Result Result;
Douglas Gregor01dfea02010-01-10 23:08:15 +00001903 ResultBuilder Results(*this);
1904
1905 // Determine how to filter results, e.g., so that the names of
1906 // values (functions, enumerators, function templates, etc.) are
1907 // only allowed where we can have an expression.
1908 switch (CompletionContext) {
1909 case CCC_Namespace:
1910 case CCC_Class:
Douglas Gregorb6ac2452010-01-13 21:24:21 +00001911 case CCC_ObjCInterface:
1912 case CCC_ObjCImplementation:
Douglas Gregorc38c3e12010-01-13 21:54:15 +00001913 case CCC_ObjCInstanceVariableList:
Douglas Gregor01dfea02010-01-10 23:08:15 +00001914 case CCC_Template:
1915 case CCC_MemberTemplate:
1916 Results.setFilter(&ResultBuilder::IsOrdinaryNonValueName);
1917 break;
1918
1919 case CCC_Expression:
1920 case CCC_Statement:
1921 case CCC_ForInit:
1922 case CCC_Condition:
1923 Results.setFilter(&ResultBuilder::IsOrdinaryName);
1924 break;
1925 }
1926
Douglas Gregor1ca6ae82010-01-14 01:09:38 +00001927 CodeCompletionDeclConsumer Consumer(Results, CurContext);
1928 LookupVisibleDecls(S, LookupOrdinaryName, Consumer);
Douglas Gregor2a7925c2009-12-07 09:54:55 +00001929
1930 Results.EnterNewScope();
Douglas Gregorbca403c2010-01-13 23:51:12 +00001931 AddOrdinaryNameResults(CompletionContext, S, *this, Results);
Douglas Gregor2a7925c2009-12-07 09:54:55 +00001932 Results.ExitScope();
1933
Douglas Gregor0c8296d2009-11-07 00:00:49 +00001934 if (CodeCompleter->includeMacros())
Douglas Gregorbca403c2010-01-13 23:51:12 +00001935 AddMacroResults(PP, Results);
Daniel Dunbar3a2838d2009-11-13 08:58:20 +00001936 HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
Douglas Gregor791215b2009-09-21 20:51:25 +00001937}
1938
Douglas Gregor95ac6552009-11-18 01:29:26 +00001939static void AddObjCProperties(ObjCContainerDecl *Container,
Douglas Gregor322328b2009-11-18 22:32:06 +00001940 bool AllowCategories,
Douglas Gregor95ac6552009-11-18 01:29:26 +00001941 DeclContext *CurContext,
1942 ResultBuilder &Results) {
1943 typedef CodeCompleteConsumer::Result Result;
1944
1945 // Add properties in this container.
1946 for (ObjCContainerDecl::prop_iterator P = Container->prop_begin(),
1947 PEnd = Container->prop_end();
1948 P != PEnd;
1949 ++P)
1950 Results.MaybeAddResult(Result(*P, 0), CurContext);
1951
1952 // Add properties in referenced protocols.
1953 if (ObjCProtocolDecl *Protocol = dyn_cast<ObjCProtocolDecl>(Container)) {
1954 for (ObjCProtocolDecl::protocol_iterator P = Protocol->protocol_begin(),
1955 PEnd = Protocol->protocol_end();
1956 P != PEnd; ++P)
Douglas Gregor322328b2009-11-18 22:32:06 +00001957 AddObjCProperties(*P, AllowCategories, CurContext, Results);
Douglas Gregor95ac6552009-11-18 01:29:26 +00001958 } else if (ObjCInterfaceDecl *IFace = dyn_cast<ObjCInterfaceDecl>(Container)){
Douglas Gregor322328b2009-11-18 22:32:06 +00001959 if (AllowCategories) {
1960 // Look through categories.
1961 for (ObjCCategoryDecl *Category = IFace->getCategoryList();
1962 Category; Category = Category->getNextClassCategory())
1963 AddObjCProperties(Category, AllowCategories, CurContext, Results);
1964 }
Douglas Gregor95ac6552009-11-18 01:29:26 +00001965
1966 // Look through protocols.
1967 for (ObjCInterfaceDecl::protocol_iterator I = IFace->protocol_begin(),
1968 E = IFace->protocol_end();
1969 I != E; ++I)
Douglas Gregor322328b2009-11-18 22:32:06 +00001970 AddObjCProperties(*I, AllowCategories, CurContext, Results);
Douglas Gregor95ac6552009-11-18 01:29:26 +00001971
1972 // Look in the superclass.
1973 if (IFace->getSuperClass())
Douglas Gregor322328b2009-11-18 22:32:06 +00001974 AddObjCProperties(IFace->getSuperClass(), AllowCategories, CurContext,
1975 Results);
Douglas Gregor95ac6552009-11-18 01:29:26 +00001976 } else if (const ObjCCategoryDecl *Category
1977 = dyn_cast<ObjCCategoryDecl>(Container)) {
1978 // Look through protocols.
1979 for (ObjCInterfaceDecl::protocol_iterator P = Category->protocol_begin(),
1980 PEnd = Category->protocol_end();
1981 P != PEnd; ++P)
Douglas Gregor322328b2009-11-18 22:32:06 +00001982 AddObjCProperties(*P, AllowCategories, CurContext, Results);
Douglas Gregor95ac6552009-11-18 01:29:26 +00001983 }
1984}
1985
Douglas Gregor81b747b2009-09-17 21:32:03 +00001986void Sema::CodeCompleteMemberReferenceExpr(Scope *S, ExprTy *BaseE,
1987 SourceLocation OpLoc,
1988 bool IsArrow) {
1989 if (!BaseE || !CodeCompleter)
1990 return;
1991
Douglas Gregor86d9a522009-09-21 16:56:56 +00001992 typedef CodeCompleteConsumer::Result Result;
1993
Douglas Gregor81b747b2009-09-17 21:32:03 +00001994 Expr *Base = static_cast<Expr *>(BaseE);
1995 QualType BaseType = Base->getType();
Douglas Gregor86d9a522009-09-21 16:56:56 +00001996
1997 if (IsArrow) {
1998 if (const PointerType *Ptr = BaseType->getAs<PointerType>())
1999 BaseType = Ptr->getPointeeType();
2000 else if (BaseType->isObjCObjectPointerType())
2001 /*Do nothing*/ ;
2002 else
2003 return;
2004 }
2005
Douglas Gregoreb5758b2009-09-23 22:26:46 +00002006 ResultBuilder Results(*this, &ResultBuilder::IsMember);
Douglas Gregor95ac6552009-11-18 01:29:26 +00002007 Results.EnterNewScope();
2008 if (const RecordType *Record = BaseType->getAs<RecordType>()) {
2009 // Access to a C/C++ class, struct, or union.
Douglas Gregor45bcd432010-01-14 03:21:49 +00002010 Results.allowNestedNameSpecifiers();
Douglas Gregor0cc84042010-01-14 15:47:35 +00002011 CodeCompletionDeclConsumer Consumer(Results, CurContext);
2012 LookupVisibleDecls(Record->getDecl(), LookupMemberName, Consumer);
Daniel Dunbar3a2838d2009-11-13 08:58:20 +00002013
Douglas Gregor95ac6552009-11-18 01:29:26 +00002014 if (getLangOptions().CPlusPlus) {
2015 if (!Results.empty()) {
2016 // The "template" keyword can follow "->" or "." in the grammar.
2017 // However, we only want to suggest the template keyword if something
2018 // is dependent.
2019 bool IsDependent = BaseType->isDependentType();
2020 if (!IsDependent) {
2021 for (Scope *DepScope = S; DepScope; DepScope = DepScope->getParent())
2022 if (DeclContext *Ctx = (DeclContext *)DepScope->getEntity()) {
2023 IsDependent = Ctx->isDependentContext();
2024 break;
2025 }
2026 }
Daniel Dunbar3a2838d2009-11-13 08:58:20 +00002027
Douglas Gregor95ac6552009-11-18 01:29:26 +00002028 if (IsDependent)
Douglas Gregora4477812010-01-14 16:01:26 +00002029 Results.AddResult(Result("template"));
Daniel Dunbar3a2838d2009-11-13 08:58:20 +00002030 }
Daniel Dunbar3a2838d2009-11-13 08:58:20 +00002031 }
Douglas Gregor95ac6552009-11-18 01:29:26 +00002032 } else if (!IsArrow && BaseType->getAsObjCInterfacePointerType()) {
2033 // Objective-C property reference.
2034
2035 // Add property results based on our interface.
2036 const ObjCObjectPointerType *ObjCPtr
2037 = BaseType->getAsObjCInterfacePointerType();
2038 assert(ObjCPtr && "Non-NULL pointer guaranteed above!");
Douglas Gregor322328b2009-11-18 22:32:06 +00002039 AddObjCProperties(ObjCPtr->getInterfaceDecl(), true, CurContext, Results);
Douglas Gregor95ac6552009-11-18 01:29:26 +00002040
2041 // Add properties from the protocols in a qualified interface.
2042 for (ObjCObjectPointerType::qual_iterator I = ObjCPtr->qual_begin(),
2043 E = ObjCPtr->qual_end();
2044 I != E; ++I)
Douglas Gregor322328b2009-11-18 22:32:06 +00002045 AddObjCProperties(*I, true, CurContext, Results);
Douglas Gregor95ac6552009-11-18 01:29:26 +00002046 } else if ((IsArrow && BaseType->isObjCObjectPointerType()) ||
2047 (!IsArrow && BaseType->isObjCInterfaceType())) {
2048 // Objective-C instance variable access.
2049 ObjCInterfaceDecl *Class = 0;
2050 if (const ObjCObjectPointerType *ObjCPtr
2051 = BaseType->getAs<ObjCObjectPointerType>())
2052 Class = ObjCPtr->getInterfaceDecl();
2053 else
2054 Class = BaseType->getAs<ObjCInterfaceType>()->getDecl();
2055
2056 // Add all ivars from this class and its superclasses.
Douglas Gregor80f4f4c2010-01-14 16:08:12 +00002057 if (Class) {
2058 CodeCompletionDeclConsumer Consumer(Results, CurContext);
2059 Results.setFilter(&ResultBuilder::IsObjCIvar);
2060 LookupVisibleDecls(Class, LookupMemberName, Consumer);
Douglas Gregor95ac6552009-11-18 01:29:26 +00002061 }
Douglas Gregor86d9a522009-09-21 16:56:56 +00002062 }
Douglas Gregor95ac6552009-11-18 01:29:26 +00002063
2064 // FIXME: How do we cope with isa?
2065
2066 Results.ExitScope();
Daniel Dunbar3a2838d2009-11-13 08:58:20 +00002067
Daniel Dunbar3a2838d2009-11-13 08:58:20 +00002068 // Hand off the results found for code completion.
2069 HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
Douglas Gregor81b747b2009-09-17 21:32:03 +00002070}
2071
Douglas Gregor374929f2009-09-18 15:37:17 +00002072void Sema::CodeCompleteTag(Scope *S, unsigned TagSpec) {
2073 if (!CodeCompleter)
2074 return;
2075
Douglas Gregor86d9a522009-09-21 16:56:56 +00002076 typedef CodeCompleteConsumer::Result Result;
2077 ResultBuilder::LookupFilter Filter = 0;
Douglas Gregor374929f2009-09-18 15:37:17 +00002078 switch ((DeclSpec::TST)TagSpec) {
2079 case DeclSpec::TST_enum:
Douglas Gregor86d9a522009-09-21 16:56:56 +00002080 Filter = &ResultBuilder::IsEnum;
Douglas Gregor374929f2009-09-18 15:37:17 +00002081 break;
2082
2083 case DeclSpec::TST_union:
Douglas Gregor86d9a522009-09-21 16:56:56 +00002084 Filter = &ResultBuilder::IsUnion;
Douglas Gregor374929f2009-09-18 15:37:17 +00002085 break;
2086
2087 case DeclSpec::TST_struct:
Douglas Gregor374929f2009-09-18 15:37:17 +00002088 case DeclSpec::TST_class:
Douglas Gregor86d9a522009-09-21 16:56:56 +00002089 Filter = &ResultBuilder::IsClassOrStruct;
Douglas Gregor374929f2009-09-18 15:37:17 +00002090 break;
2091
2092 default:
2093 assert(false && "Unknown type specifier kind in CodeCompleteTag");
2094 return;
2095 }
Douglas Gregor86d9a522009-09-21 16:56:56 +00002096
2097 ResultBuilder Results(*this, Filter);
Douglas Gregor45bcd432010-01-14 03:21:49 +00002098 Results.allowNestedNameSpecifiers();
Douglas Gregor5d2fc402010-01-14 03:27:13 +00002099 CodeCompletionDeclConsumer Consumer(Results, CurContext);
2100 LookupVisibleDecls(S, LookupTagName, Consumer);
Douglas Gregor86d9a522009-09-21 16:56:56 +00002101
Daniel Dunbar3a2838d2009-11-13 08:58:20 +00002102 HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
Douglas Gregor374929f2009-09-18 15:37:17 +00002103}
2104
Douglas Gregor3e1005f2009-09-21 18:10:23 +00002105void Sema::CodeCompleteCase(Scope *S) {
2106 if (getSwitchStack().empty() || !CodeCompleter)
2107 return;
2108
2109 SwitchStmt *Switch = getSwitchStack().back();
2110 if (!Switch->getCond()->getType()->isEnumeralType())
2111 return;
2112
2113 // Code-complete the cases of a switch statement over an enumeration type
2114 // by providing the list of
2115 EnumDecl *Enum = Switch->getCond()->getType()->getAs<EnumType>()->getDecl();
2116
2117 // Determine which enumerators we have already seen in the switch statement.
2118 // FIXME: Ideally, we would also be able to look *past* the code-completion
2119 // token, in case we are code-completing in the middle of the switch and not
2120 // at the end. However, we aren't able to do so at the moment.
2121 llvm::SmallPtrSet<EnumConstantDecl *, 8> EnumeratorsSeen;
Douglas Gregorb9d0ef72009-09-21 19:57:38 +00002122 NestedNameSpecifier *Qualifier = 0;
Douglas Gregor3e1005f2009-09-21 18:10:23 +00002123 for (SwitchCase *SC = Switch->getSwitchCaseList(); SC;
2124 SC = SC->getNextSwitchCase()) {
2125 CaseStmt *Case = dyn_cast<CaseStmt>(SC);
2126 if (!Case)
2127 continue;
2128
2129 Expr *CaseVal = Case->getLHS()->IgnoreParenCasts();
2130 if (DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(CaseVal))
2131 if (EnumConstantDecl *Enumerator
2132 = dyn_cast<EnumConstantDecl>(DRE->getDecl())) {
2133 // We look into the AST of the case statement to determine which
2134 // enumerator was named. Alternatively, we could compute the value of
2135 // the integral constant expression, then compare it against the
2136 // values of each enumerator. However, value-based approach would not
2137 // work as well with C++ templates where enumerators declared within a
2138 // template are type- and value-dependent.
2139 EnumeratorsSeen.insert(Enumerator);
2140
Douglas Gregorb9d0ef72009-09-21 19:57:38 +00002141 // If this is a qualified-id, keep track of the nested-name-specifier
2142 // so that we can reproduce it as part of code completion, e.g.,
Douglas Gregor3e1005f2009-09-21 18:10:23 +00002143 //
2144 // switch (TagD.getKind()) {
2145 // case TagDecl::TK_enum:
2146 // break;
2147 // case XXX
2148 //
Douglas Gregorb9d0ef72009-09-21 19:57:38 +00002149 // At the XXX, our completions are TagDecl::TK_union,
Douglas Gregor3e1005f2009-09-21 18:10:23 +00002150 // TagDecl::TK_struct, and TagDecl::TK_class, rather than TK_union,
2151 // TK_struct, and TK_class.
Douglas Gregora2813ce2009-10-23 18:54:35 +00002152 Qualifier = DRE->getQualifier();
Douglas Gregor3e1005f2009-09-21 18:10:23 +00002153 }
2154 }
2155
Douglas Gregorb9d0ef72009-09-21 19:57:38 +00002156 if (getLangOptions().CPlusPlus && !Qualifier && EnumeratorsSeen.empty()) {
2157 // If there are no prior enumerators in C++, check whether we have to
2158 // qualify the names of the enumerators that we suggest, because they
2159 // may not be visible in this scope.
2160 Qualifier = getRequiredQualification(Context, CurContext,
2161 Enum->getDeclContext());
2162
2163 // FIXME: Scoped enums need to start with "EnumDecl" as the context!
2164 }
2165
Douglas Gregor3e1005f2009-09-21 18:10:23 +00002166 // Add any enumerators that have not yet been mentioned.
2167 ResultBuilder Results(*this);
2168 Results.EnterNewScope();
2169 for (EnumDecl::enumerator_iterator E = Enum->enumerator_begin(),
2170 EEnd = Enum->enumerator_end();
2171 E != EEnd; ++E) {
2172 if (EnumeratorsSeen.count(*E))
2173 continue;
2174
Douglas Gregor608300b2010-01-14 16:14:35 +00002175 Results.AddResult(CodeCompleteConsumer::Result(*E, Qualifier),
2176 CurContext, 0, false);
Douglas Gregor3e1005f2009-09-21 18:10:23 +00002177 }
2178 Results.ExitScope();
Douglas Gregor2f880e42010-04-06 20:02:15 +00002179
Douglas Gregor0c8296d2009-11-07 00:00:49 +00002180 if (CodeCompleter->includeMacros())
Douglas Gregorbca403c2010-01-13 23:51:12 +00002181 AddMacroResults(PP, Results);
Daniel Dunbar3a2838d2009-11-13 08:58:20 +00002182 HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
Douglas Gregor3e1005f2009-09-21 18:10:23 +00002183}
2184
Douglas Gregor9c6a0e92009-09-22 15:41:20 +00002185namespace {
2186 struct IsBetterOverloadCandidate {
2187 Sema &S;
John McCall5769d612010-02-08 23:07:23 +00002188 SourceLocation Loc;
Douglas Gregor9c6a0e92009-09-22 15:41:20 +00002189
2190 public:
John McCall5769d612010-02-08 23:07:23 +00002191 explicit IsBetterOverloadCandidate(Sema &S, SourceLocation Loc)
2192 : S(S), Loc(Loc) { }
Douglas Gregor9c6a0e92009-09-22 15:41:20 +00002193
2194 bool
2195 operator()(const OverloadCandidate &X, const OverloadCandidate &Y) const {
John McCall5769d612010-02-08 23:07:23 +00002196 return S.isBetterOverloadCandidate(X, Y, Loc);
Douglas Gregor9c6a0e92009-09-22 15:41:20 +00002197 }
2198 };
2199}
2200
2201void Sema::CodeCompleteCall(Scope *S, ExprTy *FnIn,
2202 ExprTy **ArgsIn, unsigned NumArgs) {
2203 if (!CodeCompleter)
2204 return;
Douglas Gregoref96eac2009-12-11 19:06:04 +00002205
2206 // When we're code-completing for a call, we fall back to ordinary
2207 // name code-completion whenever we can't produce specific
2208 // results. We may want to revisit this strategy in the future,
2209 // e.g., by merging the two kinds of results.
2210
Douglas Gregor9c6a0e92009-09-22 15:41:20 +00002211 Expr *Fn = (Expr *)FnIn;
2212 Expr **Args = (Expr **)ArgsIn;
Douglas Gregoref96eac2009-12-11 19:06:04 +00002213
Douglas Gregor9c6a0e92009-09-22 15:41:20 +00002214 // Ignore type-dependent call expressions entirely.
2215 if (Fn->isTypeDependent() ||
Douglas Gregoref96eac2009-12-11 19:06:04 +00002216 Expr::hasAnyTypeDependentArguments(Args, NumArgs)) {
Douglas Gregor01dfea02010-01-10 23:08:15 +00002217 CodeCompleteOrdinaryName(S, CCC_Expression);
Douglas Gregor9c6a0e92009-09-22 15:41:20 +00002218 return;
Douglas Gregoref96eac2009-12-11 19:06:04 +00002219 }
Douglas Gregor9c6a0e92009-09-22 15:41:20 +00002220
John McCall3b4294e2009-12-16 12:17:52 +00002221 // Build an overload candidate set based on the functions we find.
John McCall5769d612010-02-08 23:07:23 +00002222 SourceLocation Loc = Fn->getExprLoc();
2223 OverloadCandidateSet CandidateSet(Loc);
John McCall3b4294e2009-12-16 12:17:52 +00002224
Douglas Gregor9c6a0e92009-09-22 15:41:20 +00002225 // FIXME: What if we're calling something that isn't a function declaration?
2226 // FIXME: What if we're calling a pseudo-destructor?
2227 // FIXME: What if we're calling a member function?
2228
Douglas Gregorc0265402010-01-21 15:46:19 +00002229 typedef CodeCompleteConsumer::OverloadCandidate ResultCandidate;
2230 llvm::SmallVector<ResultCandidate, 8> Results;
2231
John McCall3b4294e2009-12-16 12:17:52 +00002232 Expr *NakedFn = Fn->IgnoreParenCasts();
2233 if (UnresolvedLookupExpr *ULE = dyn_cast<UnresolvedLookupExpr>(NakedFn))
2234 AddOverloadedCallCandidates(ULE, Args, NumArgs, CandidateSet,
2235 /*PartialOverloading=*/ true);
2236 else if (DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(NakedFn)) {
2237 FunctionDecl *FDecl = dyn_cast<FunctionDecl>(DRE->getDecl());
Douglas Gregorc0265402010-01-21 15:46:19 +00002238 if (FDecl) {
2239 if (!FDecl->getType()->getAs<FunctionProtoType>())
2240 Results.push_back(ResultCandidate(FDecl));
2241 else
John McCall86820f52010-01-26 01:37:31 +00002242 // FIXME: access?
John McCall9aa472c2010-03-19 07:35:19 +00002243 AddOverloadCandidate(FDecl, DeclAccessPair::make(FDecl, AS_none),
2244 Args, NumArgs, CandidateSet,
Douglas Gregorc0265402010-01-21 15:46:19 +00002245 false, false, /*PartialOverloading*/ true);
2246 }
John McCall3b4294e2009-12-16 12:17:52 +00002247 }
Douglas Gregor9c6a0e92009-09-22 15:41:20 +00002248
Douglas Gregorc0265402010-01-21 15:46:19 +00002249 if (!CandidateSet.empty()) {
2250 // Sort the overload candidate set by placing the best overloads first.
2251 std::stable_sort(CandidateSet.begin(), CandidateSet.end(),
John McCall5769d612010-02-08 23:07:23 +00002252 IsBetterOverloadCandidate(*this, Loc));
Douglas Gregor9c6a0e92009-09-22 15:41:20 +00002253
Douglas Gregorc0265402010-01-21 15:46:19 +00002254 // Add the remaining viable overload candidates as code-completion reslults.
2255 for (OverloadCandidateSet::iterator Cand = CandidateSet.begin(),
2256 CandEnd = CandidateSet.end();
2257 Cand != CandEnd; ++Cand) {
2258 if (Cand->Viable)
2259 Results.push_back(ResultCandidate(Cand->Function));
2260 }
Douglas Gregor9c6a0e92009-09-22 15:41:20 +00002261 }
Douglas Gregoref96eac2009-12-11 19:06:04 +00002262
Douglas Gregor2e4c7a52010-04-06 20:19:47 +00002263 CodeCompleteOrdinaryName(S, CCC_Expression);
2264 if (!Results.empty())
Douglas Gregoref96eac2009-12-11 19:06:04 +00002265 CodeCompleter->ProcessOverloadCandidates(*this, NumArgs, Results.data(),
2266 Results.size());
Douglas Gregor9c6a0e92009-09-22 15:41:20 +00002267}
2268
Douglas Gregor81b747b2009-09-17 21:32:03 +00002269void Sema::CodeCompleteQualifiedId(Scope *S, const CXXScopeSpec &SS,
2270 bool EnteringContext) {
2271 if (!SS.getScopeRep() || !CodeCompleter)
2272 return;
2273
Douglas Gregor86d9a522009-09-21 16:56:56 +00002274 DeclContext *Ctx = computeDeclContext(SS, EnteringContext);
2275 if (!Ctx)
2276 return;
Douglas Gregord1cd31a2009-12-11 18:28:39 +00002277
2278 // Try to instantiate any non-dependent declaration contexts before
2279 // we look in them.
2280 if (!isDependentScopeSpecifier(SS) && RequireCompleteDeclContext(SS))
2281 return;
2282
Douglas Gregor86d9a522009-09-21 16:56:56 +00002283 ResultBuilder Results(*this);
Douglas Gregordef91072010-01-14 03:35:48 +00002284 CodeCompletionDeclConsumer Consumer(Results, CurContext);
2285 LookupVisibleDecls(Ctx, LookupOrdinaryName, Consumer);
Douglas Gregor86d9a522009-09-21 16:56:56 +00002286
2287 // The "template" keyword can follow "::" in the grammar, but only
2288 // put it into the grammar if the nested-name-specifier is dependent.
2289 NestedNameSpecifier *NNS = (NestedNameSpecifier *)SS.getScopeRep();
2290 if (!Results.empty() && NNS->isDependent())
Douglas Gregora4477812010-01-14 16:01:26 +00002291 Results.AddResult("template");
Douglas Gregor86d9a522009-09-21 16:56:56 +00002292
Daniel Dunbar3a2838d2009-11-13 08:58:20 +00002293 HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
Douglas Gregor81b747b2009-09-17 21:32:03 +00002294}
Douglas Gregor49f40bd2009-09-18 19:03:04 +00002295
2296void Sema::CodeCompleteUsing(Scope *S) {
2297 if (!CodeCompleter)
2298 return;
2299
Douglas Gregor86d9a522009-09-21 16:56:56 +00002300 ResultBuilder Results(*this, &ResultBuilder::IsNestedNameSpecifier);
Douglas Gregor8e0a0e42009-09-22 23:31:26 +00002301 Results.EnterNewScope();
Douglas Gregor86d9a522009-09-21 16:56:56 +00002302
2303 // If we aren't in class scope, we could see the "namespace" keyword.
2304 if (!S->isClassScope())
Douglas Gregora4477812010-01-14 16:01:26 +00002305 Results.AddResult(CodeCompleteConsumer::Result("namespace"));
Douglas Gregor86d9a522009-09-21 16:56:56 +00002306
2307 // After "using", we can see anything that would start a
2308 // nested-name-specifier.
Douglas Gregor5d2fc402010-01-14 03:27:13 +00002309 CodeCompletionDeclConsumer Consumer(Results, CurContext);
2310 LookupVisibleDecls(S, LookupOrdinaryName, Consumer);
Douglas Gregor8e0a0e42009-09-22 23:31:26 +00002311 Results.ExitScope();
Douglas Gregor86d9a522009-09-21 16:56:56 +00002312
Daniel Dunbar3a2838d2009-11-13 08:58:20 +00002313 HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
Douglas Gregor49f40bd2009-09-18 19:03:04 +00002314}
2315
2316void Sema::CodeCompleteUsingDirective(Scope *S) {
2317 if (!CodeCompleter)
2318 return;
2319
Douglas Gregor86d9a522009-09-21 16:56:56 +00002320 // After "using namespace", we expect to see a namespace name or namespace
2321 // alias.
2322 ResultBuilder Results(*this, &ResultBuilder::IsNamespaceOrAlias);
Douglas Gregor8e0a0e42009-09-22 23:31:26 +00002323 Results.EnterNewScope();
Douglas Gregor5d2fc402010-01-14 03:27:13 +00002324 CodeCompletionDeclConsumer Consumer(Results, CurContext);
2325 LookupVisibleDecls(S, LookupOrdinaryName, Consumer);
Douglas Gregor8e0a0e42009-09-22 23:31:26 +00002326 Results.ExitScope();
Daniel Dunbar3a2838d2009-11-13 08:58:20 +00002327 HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
Douglas Gregor49f40bd2009-09-18 19:03:04 +00002328}
2329
2330void Sema::CodeCompleteNamespaceDecl(Scope *S) {
2331 if (!CodeCompleter)
2332 return;
2333
Douglas Gregor86d9a522009-09-21 16:56:56 +00002334 ResultBuilder Results(*this, &ResultBuilder::IsNamespace);
2335 DeclContext *Ctx = (DeclContext *)S->getEntity();
2336 if (!S->getParent())
2337 Ctx = Context.getTranslationUnitDecl();
2338
2339 if (Ctx && Ctx->isFileContext()) {
2340 // We only want to see those namespaces that have already been defined
2341 // within this scope, because its likely that the user is creating an
2342 // extended namespace declaration. Keep track of the most recent
2343 // definition of each namespace.
2344 std::map<NamespaceDecl *, NamespaceDecl *> OrigToLatest;
2345 for (DeclContext::specific_decl_iterator<NamespaceDecl>
2346 NS(Ctx->decls_begin()), NSEnd(Ctx->decls_end());
2347 NS != NSEnd; ++NS)
2348 OrigToLatest[NS->getOriginalNamespace()] = *NS;
2349
2350 // Add the most recent definition (or extended definition) of each
2351 // namespace to the list of results.
Douglas Gregor8e0a0e42009-09-22 23:31:26 +00002352 Results.EnterNewScope();
Douglas Gregor86d9a522009-09-21 16:56:56 +00002353 for (std::map<NamespaceDecl *, NamespaceDecl *>::iterator
2354 NS = OrigToLatest.begin(), NSEnd = OrigToLatest.end();
2355 NS != NSEnd; ++NS)
Douglas Gregor608300b2010-01-14 16:14:35 +00002356 Results.AddResult(CodeCompleteConsumer::Result(NS->second, 0),
2357 CurContext, 0, false);
Douglas Gregor8e0a0e42009-09-22 23:31:26 +00002358 Results.ExitScope();
Douglas Gregor86d9a522009-09-21 16:56:56 +00002359 }
2360
Daniel Dunbar3a2838d2009-11-13 08:58:20 +00002361 HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
Douglas Gregor49f40bd2009-09-18 19:03:04 +00002362}
2363
2364void Sema::CodeCompleteNamespaceAliasDecl(Scope *S) {
2365 if (!CodeCompleter)
2366 return;
2367
Douglas Gregor86d9a522009-09-21 16:56:56 +00002368 // After "namespace", we expect to see a namespace or alias.
2369 ResultBuilder Results(*this, &ResultBuilder::IsNamespaceOrAlias);
Douglas Gregor5d2fc402010-01-14 03:27:13 +00002370 CodeCompletionDeclConsumer Consumer(Results, CurContext);
2371 LookupVisibleDecls(S, LookupOrdinaryName, Consumer);
Daniel Dunbar3a2838d2009-11-13 08:58:20 +00002372 HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
Douglas Gregor49f40bd2009-09-18 19:03:04 +00002373}
2374
Douglas Gregored8d3222009-09-18 20:05:18 +00002375void Sema::CodeCompleteOperatorName(Scope *S) {
2376 if (!CodeCompleter)
2377 return;
Douglas Gregor86d9a522009-09-21 16:56:56 +00002378
2379 typedef CodeCompleteConsumer::Result Result;
2380 ResultBuilder Results(*this, &ResultBuilder::IsType);
Douglas Gregor8e0a0e42009-09-22 23:31:26 +00002381 Results.EnterNewScope();
Douglas Gregored8d3222009-09-18 20:05:18 +00002382
Douglas Gregor86d9a522009-09-21 16:56:56 +00002383 // Add the names of overloadable operators.
2384#define OVERLOADED_OPERATOR(Name,Spelling,Token,Unary,Binary,MemberOnly) \
2385 if (std::strcmp(Spelling, "?")) \
Douglas Gregora4477812010-01-14 16:01:26 +00002386 Results.AddResult(Result(Spelling));
Douglas Gregor86d9a522009-09-21 16:56:56 +00002387#include "clang/Basic/OperatorKinds.def"
2388
2389 // Add any type names visible from the current scope
Douglas Gregor45bcd432010-01-14 03:21:49 +00002390 Results.allowNestedNameSpecifiers();
Douglas Gregor5d2fc402010-01-14 03:27:13 +00002391 CodeCompletionDeclConsumer Consumer(Results, CurContext);
2392 LookupVisibleDecls(S, LookupOrdinaryName, Consumer);
Douglas Gregor86d9a522009-09-21 16:56:56 +00002393
2394 // Add any type specifiers
Douglas Gregorbca403c2010-01-13 23:51:12 +00002395 AddTypeSpecifierResults(getLangOptions(), Results);
Douglas Gregor8e0a0e42009-09-22 23:31:26 +00002396 Results.ExitScope();
Douglas Gregor86d9a522009-09-21 16:56:56 +00002397
Daniel Dunbar3a2838d2009-11-13 08:58:20 +00002398 HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
Douglas Gregored8d3222009-09-18 20:05:18 +00002399}
Douglas Gregor49f40bd2009-09-18 19:03:04 +00002400
Douglas Gregorb6ac2452010-01-13 21:24:21 +00002401// Macro that expands to @Keyword or Keyword, depending on whether NeedAt is
2402// true or false.
2403#define OBJC_AT_KEYWORD_NAME(NeedAt,Keyword) NeedAt? "@" #Keyword : #Keyword
Douglas Gregorbca403c2010-01-13 23:51:12 +00002404static void AddObjCImplementationResults(const LangOptions &LangOpts,
Douglas Gregorb6ac2452010-01-13 21:24:21 +00002405 ResultBuilder &Results,
2406 bool NeedAt) {
2407 typedef CodeCompleteConsumer::Result Result;
2408 // Since we have an implementation, we can end it.
Douglas Gregora4477812010-01-14 16:01:26 +00002409 Results.AddResult(Result(OBJC_AT_KEYWORD_NAME(NeedAt,end)));
Douglas Gregorb6ac2452010-01-13 21:24:21 +00002410
2411 CodeCompletionString *Pattern = 0;
2412 if (LangOpts.ObjC2) {
2413 // @dynamic
2414 Pattern = new CodeCompletionString;
2415 Pattern->AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt,dynamic));
2416 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
2417 Pattern->AddPlaceholderChunk("property");
Douglas Gregora4477812010-01-14 16:01:26 +00002418 Results.AddResult(Result(Pattern));
Douglas Gregorb6ac2452010-01-13 21:24:21 +00002419
2420 // @synthesize
2421 Pattern = new CodeCompletionString;
2422 Pattern->AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt,synthesize));
2423 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
2424 Pattern->AddPlaceholderChunk("property");
Douglas Gregora4477812010-01-14 16:01:26 +00002425 Results.AddResult(Result(Pattern));
Douglas Gregorb6ac2452010-01-13 21:24:21 +00002426 }
2427}
2428
Douglas Gregorbca403c2010-01-13 23:51:12 +00002429static void AddObjCInterfaceResults(const LangOptions &LangOpts,
Douglas Gregorb6ac2452010-01-13 21:24:21 +00002430 ResultBuilder &Results,
2431 bool NeedAt) {
2432 typedef CodeCompleteConsumer::Result Result;
2433
2434 // Since we have an interface or protocol, we can end it.
Douglas Gregora4477812010-01-14 16:01:26 +00002435 Results.AddResult(Result(OBJC_AT_KEYWORD_NAME(NeedAt,end)));
Douglas Gregorb6ac2452010-01-13 21:24:21 +00002436
2437 if (LangOpts.ObjC2) {
2438 // @property
Douglas Gregora4477812010-01-14 16:01:26 +00002439 Results.AddResult(Result(OBJC_AT_KEYWORD_NAME(NeedAt,property)));
Douglas Gregorb6ac2452010-01-13 21:24:21 +00002440
2441 // @required
Douglas Gregora4477812010-01-14 16:01:26 +00002442 Results.AddResult(Result(OBJC_AT_KEYWORD_NAME(NeedAt,required)));
Douglas Gregorb6ac2452010-01-13 21:24:21 +00002443
2444 // @optional
Douglas Gregora4477812010-01-14 16:01:26 +00002445 Results.AddResult(Result(OBJC_AT_KEYWORD_NAME(NeedAt,optional)));
Douglas Gregorb6ac2452010-01-13 21:24:21 +00002446 }
2447}
2448
Douglas Gregorbca403c2010-01-13 23:51:12 +00002449static void AddObjCTopLevelResults(ResultBuilder &Results, bool NeedAt) {
Douglas Gregorb6ac2452010-01-13 21:24:21 +00002450 typedef CodeCompleteConsumer::Result Result;
2451 CodeCompletionString *Pattern = 0;
2452
2453 // @class name ;
2454 Pattern = new CodeCompletionString;
2455 Pattern->AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt,class));
2456 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
2457 Pattern->AddPlaceholderChunk("identifier");
Douglas Gregora4477812010-01-14 16:01:26 +00002458 Results.AddResult(Result(Pattern));
Douglas Gregorb6ac2452010-01-13 21:24:21 +00002459
2460 // @interface name
2461 // FIXME: Could introduce the whole pattern, including superclasses and
2462 // such.
2463 Pattern = new CodeCompletionString;
2464 Pattern->AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt,interface));
2465 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
2466 Pattern->AddPlaceholderChunk("class");
Douglas Gregora4477812010-01-14 16:01:26 +00002467 Results.AddResult(Result(Pattern));
Douglas Gregorb6ac2452010-01-13 21:24:21 +00002468
2469 // @protocol name
2470 Pattern = new CodeCompletionString;
2471 Pattern->AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt,protocol));
2472 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
2473 Pattern->AddPlaceholderChunk("protocol");
Douglas Gregora4477812010-01-14 16:01:26 +00002474 Results.AddResult(Result(Pattern));
Douglas Gregorb6ac2452010-01-13 21:24:21 +00002475
2476 // @implementation name
2477 Pattern = new CodeCompletionString;
2478 Pattern->AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt,implementation));
2479 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
2480 Pattern->AddPlaceholderChunk("class");
Douglas Gregora4477812010-01-14 16:01:26 +00002481 Results.AddResult(Result(Pattern));
Douglas Gregorb6ac2452010-01-13 21:24:21 +00002482
2483 // @compatibility_alias name
2484 Pattern = new CodeCompletionString;
2485 Pattern->AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt,compatibility_alias));
2486 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
2487 Pattern->AddPlaceholderChunk("alias");
2488 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
2489 Pattern->AddPlaceholderChunk("class");
Douglas Gregora4477812010-01-14 16:01:26 +00002490 Results.AddResult(Result(Pattern));
Douglas Gregorb6ac2452010-01-13 21:24:21 +00002491}
2492
Douglas Gregorc464ae82009-12-07 09:27:33 +00002493void Sema::CodeCompleteObjCAtDirective(Scope *S, DeclPtrTy ObjCImpDecl,
2494 bool InInterface) {
2495 typedef CodeCompleteConsumer::Result Result;
2496 ResultBuilder Results(*this);
2497 Results.EnterNewScope();
Douglas Gregorb6ac2452010-01-13 21:24:21 +00002498 if (ObjCImpDecl)
Douglas Gregorbca403c2010-01-13 23:51:12 +00002499 AddObjCImplementationResults(getLangOptions(), Results, false);
Douglas Gregorb6ac2452010-01-13 21:24:21 +00002500 else if (InInterface)
Douglas Gregorbca403c2010-01-13 23:51:12 +00002501 AddObjCInterfaceResults(getLangOptions(), Results, false);
Douglas Gregorb6ac2452010-01-13 21:24:21 +00002502 else
Douglas Gregorbca403c2010-01-13 23:51:12 +00002503 AddObjCTopLevelResults(Results, false);
Douglas Gregorc464ae82009-12-07 09:27:33 +00002504 Results.ExitScope();
2505 HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
2506}
2507
Douglas Gregorbca403c2010-01-13 23:51:12 +00002508static void AddObjCExpressionResults(ResultBuilder &Results, bool NeedAt) {
Douglas Gregor9a0c85e2009-12-07 09:51:25 +00002509 typedef CodeCompleteConsumer::Result Result;
2510 CodeCompletionString *Pattern = 0;
2511
2512 // @encode ( type-name )
2513 Pattern = new CodeCompletionString;
Douglas Gregorb6ac2452010-01-13 21:24:21 +00002514 Pattern->AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt,encode));
Douglas Gregor9a0c85e2009-12-07 09:51:25 +00002515 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
2516 Pattern->AddPlaceholderChunk("type-name");
2517 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
Douglas Gregora4477812010-01-14 16:01:26 +00002518 Results.AddResult(Result(Pattern));
Douglas Gregor9a0c85e2009-12-07 09:51:25 +00002519
2520 // @protocol ( protocol-name )
2521 Pattern = new CodeCompletionString;
Douglas Gregorb6ac2452010-01-13 21:24:21 +00002522 Pattern->AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt,protocol));
Douglas Gregor9a0c85e2009-12-07 09:51:25 +00002523 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
2524 Pattern->AddPlaceholderChunk("protocol-name");
2525 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
Douglas Gregora4477812010-01-14 16:01:26 +00002526 Results.AddResult(Result(Pattern));
Douglas Gregor9a0c85e2009-12-07 09:51:25 +00002527
2528 // @selector ( selector )
2529 Pattern = new CodeCompletionString;
Douglas Gregorb6ac2452010-01-13 21:24:21 +00002530 Pattern->AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt,selector));
Douglas Gregor9a0c85e2009-12-07 09:51:25 +00002531 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
2532 Pattern->AddPlaceholderChunk("selector");
2533 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
Douglas Gregora4477812010-01-14 16:01:26 +00002534 Results.AddResult(Result(Pattern));
Douglas Gregor9a0c85e2009-12-07 09:51:25 +00002535}
2536
Douglas Gregorbca403c2010-01-13 23:51:12 +00002537static void AddObjCStatementResults(ResultBuilder &Results, bool NeedAt) {
Douglas Gregor9a0c85e2009-12-07 09:51:25 +00002538 typedef CodeCompleteConsumer::Result Result;
Douglas Gregor9a0c85e2009-12-07 09:51:25 +00002539 CodeCompletionString *Pattern = 0;
Douglas Gregorb6ac2452010-01-13 21:24:21 +00002540
Douglas Gregor9a0c85e2009-12-07 09:51:25 +00002541 // @try { statements } @catch ( declaration ) { statements } @finally
2542 // { statements }
2543 Pattern = new CodeCompletionString;
Douglas Gregorb6ac2452010-01-13 21:24:21 +00002544 Pattern->AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt,try));
Douglas Gregor9a0c85e2009-12-07 09:51:25 +00002545 Pattern->AddChunk(CodeCompletionString::CK_LeftBrace);
2546 Pattern->AddPlaceholderChunk("statements");
2547 Pattern->AddChunk(CodeCompletionString::CK_RightBrace);
2548 Pattern->AddTextChunk("@catch");
2549 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
2550 Pattern->AddPlaceholderChunk("parameter");
2551 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
2552 Pattern->AddChunk(CodeCompletionString::CK_LeftBrace);
2553 Pattern->AddPlaceholderChunk("statements");
2554 Pattern->AddChunk(CodeCompletionString::CK_RightBrace);
2555 Pattern->AddTextChunk("@finally");
2556 Pattern->AddChunk(CodeCompletionString::CK_LeftBrace);
2557 Pattern->AddPlaceholderChunk("statements");
2558 Pattern->AddChunk(CodeCompletionString::CK_RightBrace);
Douglas Gregora4477812010-01-14 16:01:26 +00002559 Results.AddResult(Result(Pattern));
Douglas Gregorb6ac2452010-01-13 21:24:21 +00002560
Douglas Gregor9a0c85e2009-12-07 09:51:25 +00002561 // @throw
2562 Pattern = new CodeCompletionString;
Douglas Gregorb6ac2452010-01-13 21:24:21 +00002563 Pattern->AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt,throw));
Douglas Gregor834389b2010-01-12 06:38:28 +00002564 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
Douglas Gregor9a0c85e2009-12-07 09:51:25 +00002565 Pattern->AddPlaceholderChunk("expression");
Douglas Gregora4477812010-01-14 16:01:26 +00002566 Results.AddResult(Result(Pattern));
Douglas Gregorb6ac2452010-01-13 21:24:21 +00002567
Douglas Gregor9a0c85e2009-12-07 09:51:25 +00002568 // @synchronized ( expression ) { statements }
2569 Pattern = new CodeCompletionString;
Douglas Gregorb6ac2452010-01-13 21:24:21 +00002570 Pattern->AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt,synchronized));
Douglas Gregor834389b2010-01-12 06:38:28 +00002571 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
Douglas Gregor9a0c85e2009-12-07 09:51:25 +00002572 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
2573 Pattern->AddPlaceholderChunk("expression");
2574 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
2575 Pattern->AddChunk(CodeCompletionString::CK_LeftBrace);
2576 Pattern->AddPlaceholderChunk("statements");
2577 Pattern->AddChunk(CodeCompletionString::CK_RightBrace);
Douglas Gregora4477812010-01-14 16:01:26 +00002578 Results.AddResult(Result(Pattern));
Douglas Gregorb6ac2452010-01-13 21:24:21 +00002579}
Douglas Gregor9a0c85e2009-12-07 09:51:25 +00002580
Douglas Gregorbca403c2010-01-13 23:51:12 +00002581static void AddObjCVisibilityResults(const LangOptions &LangOpts,
Douglas Gregorc38c3e12010-01-13 21:54:15 +00002582 ResultBuilder &Results,
2583 bool NeedAt) {
Douglas Gregorb6ac2452010-01-13 21:24:21 +00002584 typedef CodeCompleteConsumer::Result Result;
Douglas Gregora4477812010-01-14 16:01:26 +00002585 Results.AddResult(Result(OBJC_AT_KEYWORD_NAME(NeedAt,private)));
2586 Results.AddResult(Result(OBJC_AT_KEYWORD_NAME(NeedAt,protected)));
2587 Results.AddResult(Result(OBJC_AT_KEYWORD_NAME(NeedAt,public)));
Douglas Gregorc38c3e12010-01-13 21:54:15 +00002588 if (LangOpts.ObjC2)
Douglas Gregora4477812010-01-14 16:01:26 +00002589 Results.AddResult(Result(OBJC_AT_KEYWORD_NAME(NeedAt,package)));
Douglas Gregorc38c3e12010-01-13 21:54:15 +00002590}
2591
2592void Sema::CodeCompleteObjCAtVisibility(Scope *S) {
2593 ResultBuilder Results(*this);
2594 Results.EnterNewScope();
Douglas Gregorbca403c2010-01-13 23:51:12 +00002595 AddObjCVisibilityResults(getLangOptions(), Results, false);
Douglas Gregorc38c3e12010-01-13 21:54:15 +00002596 Results.ExitScope();
2597 HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
2598}
2599
2600void Sema::CodeCompleteObjCAtStatement(Scope *S) {
Douglas Gregorb6ac2452010-01-13 21:24:21 +00002601 ResultBuilder Results(*this);
2602 Results.EnterNewScope();
Douglas Gregorbca403c2010-01-13 23:51:12 +00002603 AddObjCStatementResults(Results, false);
2604 AddObjCExpressionResults(Results, false);
Douglas Gregor9a0c85e2009-12-07 09:51:25 +00002605 Results.ExitScope();
2606 HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
2607}
2608
2609void Sema::CodeCompleteObjCAtExpression(Scope *S) {
2610 ResultBuilder Results(*this);
2611 Results.EnterNewScope();
Douglas Gregorbca403c2010-01-13 23:51:12 +00002612 AddObjCExpressionResults(Results, false);
Douglas Gregor9a0c85e2009-12-07 09:51:25 +00002613 Results.ExitScope();
2614 HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
2615}
2616
Douglas Gregor988358f2009-11-19 00:14:45 +00002617/// \brief Determine whether the addition of the given flag to an Objective-C
2618/// property's attributes will cause a conflict.
2619static bool ObjCPropertyFlagConflicts(unsigned Attributes, unsigned NewFlag) {
2620 // Check if we've already added this flag.
2621 if (Attributes & NewFlag)
2622 return true;
2623
2624 Attributes |= NewFlag;
2625
2626 // Check for collisions with "readonly".
2627 if ((Attributes & ObjCDeclSpec::DQ_PR_readonly) &&
2628 (Attributes & (ObjCDeclSpec::DQ_PR_readwrite |
2629 ObjCDeclSpec::DQ_PR_assign |
2630 ObjCDeclSpec::DQ_PR_copy |
2631 ObjCDeclSpec::DQ_PR_retain)))
2632 return true;
2633
2634 // Check for more than one of { assign, copy, retain }.
2635 unsigned AssignCopyRetMask = Attributes & (ObjCDeclSpec::DQ_PR_assign |
2636 ObjCDeclSpec::DQ_PR_copy |
2637 ObjCDeclSpec::DQ_PR_retain);
2638 if (AssignCopyRetMask &&
2639 AssignCopyRetMask != ObjCDeclSpec::DQ_PR_assign &&
2640 AssignCopyRetMask != ObjCDeclSpec::DQ_PR_copy &&
2641 AssignCopyRetMask != ObjCDeclSpec::DQ_PR_retain)
2642 return true;
2643
2644 return false;
2645}
2646
Douglas Gregora93b1082009-11-18 23:08:07 +00002647void Sema::CodeCompleteObjCPropertyFlags(Scope *S, ObjCDeclSpec &ODS) {
Steve Naroffece8e712009-10-08 21:55:05 +00002648 if (!CodeCompleter)
2649 return;
Douglas Gregord3c68542009-11-19 01:08:35 +00002650
Steve Naroffece8e712009-10-08 21:55:05 +00002651 unsigned Attributes = ODS.getPropertyAttributes();
2652
2653 typedef CodeCompleteConsumer::Result Result;
2654 ResultBuilder Results(*this);
2655 Results.EnterNewScope();
Douglas Gregor988358f2009-11-19 00:14:45 +00002656 if (!ObjCPropertyFlagConflicts(Attributes, ObjCDeclSpec::DQ_PR_readonly))
Douglas Gregora4477812010-01-14 16:01:26 +00002657 Results.AddResult(CodeCompleteConsumer::Result("readonly"));
Douglas Gregor988358f2009-11-19 00:14:45 +00002658 if (!ObjCPropertyFlagConflicts(Attributes, ObjCDeclSpec::DQ_PR_assign))
Douglas Gregora4477812010-01-14 16:01:26 +00002659 Results.AddResult(CodeCompleteConsumer::Result("assign"));
Douglas Gregor988358f2009-11-19 00:14:45 +00002660 if (!ObjCPropertyFlagConflicts(Attributes, ObjCDeclSpec::DQ_PR_readwrite))
Douglas Gregora4477812010-01-14 16:01:26 +00002661 Results.AddResult(CodeCompleteConsumer::Result("readwrite"));
Douglas Gregor988358f2009-11-19 00:14:45 +00002662 if (!ObjCPropertyFlagConflicts(Attributes, ObjCDeclSpec::DQ_PR_retain))
Douglas Gregora4477812010-01-14 16:01:26 +00002663 Results.AddResult(CodeCompleteConsumer::Result("retain"));
Douglas Gregor988358f2009-11-19 00:14:45 +00002664 if (!ObjCPropertyFlagConflicts(Attributes, ObjCDeclSpec::DQ_PR_copy))
Douglas Gregora4477812010-01-14 16:01:26 +00002665 Results.AddResult(CodeCompleteConsumer::Result("copy"));
Douglas Gregor988358f2009-11-19 00:14:45 +00002666 if (!ObjCPropertyFlagConflicts(Attributes, ObjCDeclSpec::DQ_PR_nonatomic))
Douglas Gregora4477812010-01-14 16:01:26 +00002667 Results.AddResult(CodeCompleteConsumer::Result("nonatomic"));
Douglas Gregor988358f2009-11-19 00:14:45 +00002668 if (!ObjCPropertyFlagConflicts(Attributes, ObjCDeclSpec::DQ_PR_setter)) {
Douglas Gregor54f01612009-11-19 00:01:57 +00002669 CodeCompletionString *Setter = new CodeCompletionString;
2670 Setter->AddTypedTextChunk("setter");
2671 Setter->AddTextChunk(" = ");
2672 Setter->AddPlaceholderChunk("method");
Douglas Gregora4477812010-01-14 16:01:26 +00002673 Results.AddResult(CodeCompleteConsumer::Result(Setter));
Douglas Gregor54f01612009-11-19 00:01:57 +00002674 }
Douglas Gregor988358f2009-11-19 00:14:45 +00002675 if (!ObjCPropertyFlagConflicts(Attributes, ObjCDeclSpec::DQ_PR_getter)) {
Douglas Gregor54f01612009-11-19 00:01:57 +00002676 CodeCompletionString *Getter = new CodeCompletionString;
2677 Getter->AddTypedTextChunk("getter");
2678 Getter->AddTextChunk(" = ");
2679 Getter->AddPlaceholderChunk("method");
Douglas Gregora4477812010-01-14 16:01:26 +00002680 Results.AddResult(CodeCompleteConsumer::Result(Getter));
Douglas Gregor54f01612009-11-19 00:01:57 +00002681 }
Steve Naroffece8e712009-10-08 21:55:05 +00002682 Results.ExitScope();
Daniel Dunbar3a2838d2009-11-13 08:58:20 +00002683 HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
Steve Naroffece8e712009-10-08 21:55:05 +00002684}
Steve Naroffc4df6d22009-11-07 02:08:14 +00002685
Douglas Gregor4ad96852009-11-19 07:41:15 +00002686/// \brief Descripts the kind of Objective-C method that we want to find
2687/// via code completion.
2688enum ObjCMethodKind {
2689 MK_Any, //< Any kind of method, provided it means other specified criteria.
2690 MK_ZeroArgSelector, //< Zero-argument (unary) selector.
2691 MK_OneArgSelector //< One-argument selector.
2692};
2693
2694static bool isAcceptableObjCMethod(ObjCMethodDecl *Method,
2695 ObjCMethodKind WantKind,
2696 IdentifierInfo **SelIdents,
2697 unsigned NumSelIdents) {
2698 Selector Sel = Method->getSelector();
2699 if (NumSelIdents > Sel.getNumArgs())
2700 return false;
2701
2702 switch (WantKind) {
2703 case MK_Any: break;
2704 case MK_ZeroArgSelector: return Sel.isUnarySelector();
2705 case MK_OneArgSelector: return Sel.getNumArgs() == 1;
2706 }
2707
2708 for (unsigned I = 0; I != NumSelIdents; ++I)
2709 if (SelIdents[I] != Sel.getIdentifierInfoForSlot(I))
2710 return false;
2711
2712 return true;
2713}
2714
Douglas Gregor36ecb042009-11-17 23:22:23 +00002715/// \brief Add all of the Objective-C methods in the given Objective-C
2716/// container to the set of results.
2717///
2718/// The container will be a class, protocol, category, or implementation of
2719/// any of the above. This mether will recurse to include methods from
2720/// the superclasses of classes along with their categories, protocols, and
2721/// implementations.
2722///
2723/// \param Container the container in which we'll look to find methods.
2724///
2725/// \param WantInstance whether to add instance methods (only); if false, this
2726/// routine will add factory methods (only).
2727///
2728/// \param CurContext the context in which we're performing the lookup that
2729/// finds methods.
2730///
2731/// \param Results the structure into which we'll add results.
2732static void AddObjCMethods(ObjCContainerDecl *Container,
2733 bool WantInstanceMethods,
Douglas Gregor4ad96852009-11-19 07:41:15 +00002734 ObjCMethodKind WantKind,
Douglas Gregord3c68542009-11-19 01:08:35 +00002735 IdentifierInfo **SelIdents,
2736 unsigned NumSelIdents,
Douglas Gregor36ecb042009-11-17 23:22:23 +00002737 DeclContext *CurContext,
2738 ResultBuilder &Results) {
2739 typedef CodeCompleteConsumer::Result Result;
2740 for (ObjCContainerDecl::method_iterator M = Container->meth_begin(),
2741 MEnd = Container->meth_end();
2742 M != MEnd; ++M) {
Douglas Gregord3c68542009-11-19 01:08:35 +00002743 if ((*M)->isInstanceMethod() == WantInstanceMethods) {
2744 // Check whether the selector identifiers we've been given are a
2745 // subset of the identifiers for this particular method.
Douglas Gregor4ad96852009-11-19 07:41:15 +00002746 if (!isAcceptableObjCMethod(*M, WantKind, SelIdents, NumSelIdents))
Douglas Gregord3c68542009-11-19 01:08:35 +00002747 continue;
Douglas Gregor4ad96852009-11-19 07:41:15 +00002748
Douglas Gregord3c68542009-11-19 01:08:35 +00002749 Result R = Result(*M, 0);
2750 R.StartParameter = NumSelIdents;
Douglas Gregor4ad96852009-11-19 07:41:15 +00002751 R.AllParametersAreInformative = (WantKind != MK_Any);
Douglas Gregord3c68542009-11-19 01:08:35 +00002752 Results.MaybeAddResult(R, CurContext);
2753 }
Douglas Gregor36ecb042009-11-17 23:22:23 +00002754 }
2755
2756 ObjCInterfaceDecl *IFace = dyn_cast<ObjCInterfaceDecl>(Container);
2757 if (!IFace)
2758 return;
2759
2760 // Add methods in protocols.
2761 const ObjCList<ObjCProtocolDecl> &Protocols= IFace->getReferencedProtocols();
2762 for (ObjCList<ObjCProtocolDecl>::iterator I = Protocols.begin(),
2763 E = Protocols.end();
2764 I != E; ++I)
Douglas Gregor4ad96852009-11-19 07:41:15 +00002765 AddObjCMethods(*I, WantInstanceMethods, WantKind, SelIdents, NumSelIdents,
Douglas Gregord3c68542009-11-19 01:08:35 +00002766 CurContext, Results);
Douglas Gregor36ecb042009-11-17 23:22:23 +00002767
2768 // Add methods in categories.
2769 for (ObjCCategoryDecl *CatDecl = IFace->getCategoryList(); CatDecl;
2770 CatDecl = CatDecl->getNextClassCategory()) {
Douglas Gregor4ad96852009-11-19 07:41:15 +00002771 AddObjCMethods(CatDecl, WantInstanceMethods, WantKind, SelIdents,
2772 NumSelIdents, CurContext, Results);
Douglas Gregor36ecb042009-11-17 23:22:23 +00002773
2774 // Add a categories protocol methods.
2775 const ObjCList<ObjCProtocolDecl> &Protocols
2776 = CatDecl->getReferencedProtocols();
2777 for (ObjCList<ObjCProtocolDecl>::iterator I = Protocols.begin(),
2778 E = Protocols.end();
2779 I != E; ++I)
Douglas Gregor4ad96852009-11-19 07:41:15 +00002780 AddObjCMethods(*I, WantInstanceMethods, WantKind, SelIdents,
2781 NumSelIdents, CurContext, Results);
Douglas Gregor36ecb042009-11-17 23:22:23 +00002782
2783 // Add methods in category implementations.
2784 if (ObjCCategoryImplDecl *Impl = CatDecl->getImplementation())
Douglas Gregor4ad96852009-11-19 07:41:15 +00002785 AddObjCMethods(Impl, WantInstanceMethods, WantKind, SelIdents,
2786 NumSelIdents, CurContext, Results);
Douglas Gregor36ecb042009-11-17 23:22:23 +00002787 }
2788
2789 // Add methods in superclass.
2790 if (IFace->getSuperClass())
Douglas Gregor4ad96852009-11-19 07:41:15 +00002791 AddObjCMethods(IFace->getSuperClass(), WantInstanceMethods, WantKind,
2792 SelIdents, NumSelIdents, CurContext, Results);
Douglas Gregor36ecb042009-11-17 23:22:23 +00002793
2794 // Add methods in our implementation, if any.
2795 if (ObjCImplementationDecl *Impl = IFace->getImplementation())
Douglas Gregor4ad96852009-11-19 07:41:15 +00002796 AddObjCMethods(Impl, WantInstanceMethods, WantKind, SelIdents,
2797 NumSelIdents, CurContext, Results);
2798}
2799
2800
2801void Sema::CodeCompleteObjCPropertyGetter(Scope *S, DeclPtrTy ClassDecl,
2802 DeclPtrTy *Methods,
2803 unsigned NumMethods) {
2804 typedef CodeCompleteConsumer::Result Result;
2805
2806 // Try to find the interface where getters might live.
2807 ObjCInterfaceDecl *Class
2808 = dyn_cast_or_null<ObjCInterfaceDecl>(ClassDecl.getAs<Decl>());
2809 if (!Class) {
2810 if (ObjCCategoryDecl *Category
2811 = dyn_cast_or_null<ObjCCategoryDecl>(ClassDecl.getAs<Decl>()))
2812 Class = Category->getClassInterface();
2813
2814 if (!Class)
2815 return;
2816 }
2817
2818 // Find all of the potential getters.
2819 ResultBuilder Results(*this);
2820 Results.EnterNewScope();
2821
2822 // FIXME: We need to do this because Objective-C methods don't get
2823 // pushed into DeclContexts early enough. Argh!
2824 for (unsigned I = 0; I != NumMethods; ++I) {
2825 if (ObjCMethodDecl *Method
2826 = dyn_cast_or_null<ObjCMethodDecl>(Methods[I].getAs<Decl>()))
2827 if (Method->isInstanceMethod() &&
2828 isAcceptableObjCMethod(Method, MK_ZeroArgSelector, 0, 0)) {
2829 Result R = Result(Method, 0);
2830 R.AllParametersAreInformative = true;
2831 Results.MaybeAddResult(R, CurContext);
2832 }
2833 }
2834
2835 AddObjCMethods(Class, true, MK_ZeroArgSelector, 0, 0, CurContext, Results);
2836 Results.ExitScope();
2837 HandleCodeCompleteResults(this, CodeCompleter,Results.data(),Results.size());
2838}
2839
2840void Sema::CodeCompleteObjCPropertySetter(Scope *S, DeclPtrTy ObjCImplDecl,
2841 DeclPtrTy *Methods,
2842 unsigned NumMethods) {
2843 typedef CodeCompleteConsumer::Result Result;
2844
2845 // Try to find the interface where setters might live.
2846 ObjCInterfaceDecl *Class
2847 = dyn_cast_or_null<ObjCInterfaceDecl>(ObjCImplDecl.getAs<Decl>());
2848 if (!Class) {
2849 if (ObjCCategoryDecl *Category
2850 = dyn_cast_or_null<ObjCCategoryDecl>(ObjCImplDecl.getAs<Decl>()))
2851 Class = Category->getClassInterface();
2852
2853 if (!Class)
2854 return;
2855 }
2856
2857 // Find all of the potential getters.
2858 ResultBuilder Results(*this);
2859 Results.EnterNewScope();
2860
2861 // FIXME: We need to do this because Objective-C methods don't get
2862 // pushed into DeclContexts early enough. Argh!
2863 for (unsigned I = 0; I != NumMethods; ++I) {
2864 if (ObjCMethodDecl *Method
2865 = dyn_cast_or_null<ObjCMethodDecl>(Methods[I].getAs<Decl>()))
2866 if (Method->isInstanceMethod() &&
2867 isAcceptableObjCMethod(Method, MK_OneArgSelector, 0, 0)) {
2868 Result R = Result(Method, 0);
2869 R.AllParametersAreInformative = true;
2870 Results.MaybeAddResult(R, CurContext);
2871 }
2872 }
2873
2874 AddObjCMethods(Class, true, MK_OneArgSelector, 0, 0, CurContext, Results);
2875
2876 Results.ExitScope();
2877 HandleCodeCompleteResults(this, CodeCompleter,Results.data(),Results.size());
Douglas Gregor36ecb042009-11-17 23:22:23 +00002878}
2879
Douglas Gregor22f56992010-04-06 19:22:33 +00002880/// \brief When we have an expression with type "id", we may assume
2881/// that it has some more-specific class type based on knowledge of
2882/// common uses of Objective-C. This routine returns that class type,
2883/// or NULL if no better result could be determined.
2884static ObjCInterfaceDecl *GetAssumedMessageSendExprType(Expr *E) {
2885 ObjCMessageExpr *Msg = dyn_cast<ObjCMessageExpr>(E);
2886 if (!Msg)
2887 return 0;
2888
2889 Selector Sel = Msg->getSelector();
2890 if (Sel.isNull())
2891 return 0;
2892
2893 IdentifierInfo *Id = Sel.getIdentifierInfoForSlot(0);
2894 if (!Id)
2895 return 0;
2896
2897 ObjCMethodDecl *Method = Msg->getMethodDecl();
2898 if (!Method)
2899 return 0;
2900
2901 // Determine the class that we're sending the message to.
2902 ObjCInterfaceDecl *IFace = Msg->getClassInfo().Decl;
2903 if (!IFace) {
2904 if (Expr *Receiver = Msg->getReceiver()) {
2905 QualType T = Receiver->getType();
2906 if (const ObjCObjectPointerType *Ptr = T->getAs<ObjCObjectPointerType>())
2907 IFace = Ptr->getInterfaceDecl();
2908 }
2909 }
2910
2911 if (!IFace)
2912 return 0;
2913
2914 ObjCInterfaceDecl *Super = IFace->getSuperClass();
2915 if (Method->isInstanceMethod())
2916 return llvm::StringSwitch<ObjCInterfaceDecl *>(Id->getName())
2917 .Case("retain", IFace)
2918 .Case("autorelease", IFace)
2919 .Case("copy", IFace)
2920 .Case("copyWithZone", IFace)
2921 .Case("mutableCopy", IFace)
2922 .Case("mutableCopyWithZone", IFace)
2923 .Case("awakeFromCoder", IFace)
2924 .Case("replacementObjectFromCoder", IFace)
2925 .Case("class", IFace)
2926 .Case("classForCoder", IFace)
2927 .Case("superclass", Super)
2928 .Default(0);
2929
2930 return llvm::StringSwitch<ObjCInterfaceDecl *>(Id->getName())
2931 .Case("new", IFace)
2932 .Case("alloc", IFace)
2933 .Case("allocWithZone", IFace)
2934 .Case("class", IFace)
2935 .Case("superclass", Super)
2936 .Default(0);
2937}
2938
Douglas Gregor60b01cc2009-11-17 23:31:36 +00002939void Sema::CodeCompleteObjCClassMessage(Scope *S, IdentifierInfo *FName,
Douglas Gregord3c68542009-11-19 01:08:35 +00002940 SourceLocation FNameLoc,
2941 IdentifierInfo **SelIdents,
2942 unsigned NumSelIdents) {
Steve Naroffc4df6d22009-11-07 02:08:14 +00002943 typedef CodeCompleteConsumer::Result Result;
Douglas Gregor24a069f2009-11-17 17:59:40 +00002944 ObjCInterfaceDecl *CDecl = 0;
2945
Douglas Gregor24a069f2009-11-17 17:59:40 +00002946 if (FName->isStr("super")) {
2947 // We're sending a message to "super".
2948 if (ObjCMethodDecl *CurMethod = getCurMethodDecl()) {
2949 // Figure out which interface we're in.
2950 CDecl = CurMethod->getClassInterface();
2951 if (!CDecl)
2952 return;
2953
2954 // Find the superclass of this class.
2955 CDecl = CDecl->getSuperClass();
2956 if (!CDecl)
2957 return;
2958
2959 if (CurMethod->isInstanceMethod()) {
2960 // We are inside an instance method, which means that the message
2961 // send [super ...] is actually calling an instance method on the
2962 // current object. Build the super expression and handle this like
2963 // an instance method.
2964 QualType SuperTy = Context.getObjCInterfaceType(CDecl);
2965 SuperTy = Context.getObjCObjectPointerType(SuperTy);
2966 OwningExprResult Super
Douglas Gregor60b01cc2009-11-17 23:31:36 +00002967 = Owned(new (Context) ObjCSuperExpr(FNameLoc, SuperTy));
Douglas Gregord3c68542009-11-19 01:08:35 +00002968 return CodeCompleteObjCInstanceMessage(S, (Expr *)Super.get(),
2969 SelIdents, NumSelIdents);
Douglas Gregor24a069f2009-11-17 17:59:40 +00002970 }
2971
2972 // Okay, we're calling a factory method in our superclass.
2973 }
2974 }
2975
2976 // If the given name refers to an interface type, retrieve the
2977 // corresponding declaration.
2978 if (!CDecl)
Douglas Gregor60b01cc2009-11-17 23:31:36 +00002979 if (TypeTy *Ty = getTypeName(*FName, FNameLoc, S, 0, false)) {
Douglas Gregor24a069f2009-11-17 17:59:40 +00002980 QualType T = GetTypeFromParser(Ty, 0);
2981 if (!T.isNull())
2982 if (const ObjCInterfaceType *Interface = T->getAs<ObjCInterfaceType>())
2983 CDecl = Interface->getDecl();
2984 }
2985
2986 if (!CDecl && FName->isStr("super")) {
2987 // "super" may be the name of a variable, in which case we are
2988 // probably calling an instance method.
John McCallf7a1a742009-11-24 19:00:30 +00002989 CXXScopeSpec SS;
2990 UnqualifiedId id;
2991 id.setIdentifier(FName, FNameLoc);
2992 OwningExprResult Super = ActOnIdExpression(S, SS, id, false, false);
Douglas Gregord3c68542009-11-19 01:08:35 +00002993 return CodeCompleteObjCInstanceMessage(S, (Expr *)Super.get(),
2994 SelIdents, NumSelIdents);
Douglas Gregor24a069f2009-11-17 17:59:40 +00002995 }
2996
Douglas Gregor36ecb042009-11-17 23:22:23 +00002997 // Add all of the factory methods in this Objective-C class, its protocols,
2998 // superclasses, categories, implementation, etc.
Steve Naroffc4df6d22009-11-07 02:08:14 +00002999 ResultBuilder Results(*this);
3000 Results.EnterNewScope();
Douglas Gregor13438f92010-04-06 16:40:00 +00003001
3002 if (CDecl)
3003 AddObjCMethods(CDecl, false, MK_Any, SelIdents, NumSelIdents, CurContext,
3004 Results);
3005 else if (FName->isStr("id")) {
3006 // We're messaging "id" as a type; provide all class/factory methods.
3007
Douglas Gregor719770d2010-04-06 17:30:22 +00003008 // If we have an external source, load the entire class method
3009 // pool from the PCH file.
3010 if (ExternalSource) {
3011 for (uint32_t I = 0, N = ExternalSource->GetNumKnownSelectors(); I != N;
3012 ++I) {
3013 Selector Sel = ExternalSource->GetSelector(I);
3014 if (Sel.isNull() || FactoryMethodPool.count(Sel) ||
3015 InstanceMethodPool.count(Sel))
3016 continue;
3017
3018 ReadMethodPool(Sel, /*isInstance=*/false);
3019 }
3020 }
3021
Douglas Gregor13438f92010-04-06 16:40:00 +00003022 for (llvm::DenseMap<Selector, ObjCMethodList>::iterator
3023 M = FactoryMethodPool.begin(),
3024 MEnd = FactoryMethodPool.end();
3025 M != MEnd;
3026 ++M) {
Douglas Gregor719770d2010-04-06 17:30:22 +00003027 for (ObjCMethodList *MethList = &M->second; MethList && MethList->Method;
Douglas Gregor13438f92010-04-06 16:40:00 +00003028 MethList = MethList->Next) {
3029 if (!isAcceptableObjCMethod(MethList->Method, MK_Any, SelIdents,
3030 NumSelIdents))
3031 continue;
3032
3033 Result R(MethList->Method, 0);
3034 R.StartParameter = NumSelIdents;
3035 R.AllParametersAreInformative = false;
3036 Results.MaybeAddResult(R, CurContext);
3037 }
3038 }
3039 }
3040
Steve Naroffc4df6d22009-11-07 02:08:14 +00003041 Results.ExitScope();
Douglas Gregor36ecb042009-11-17 23:22:23 +00003042
Steve Naroffc4df6d22009-11-07 02:08:14 +00003043 // This also suppresses remaining diagnostics.
Daniel Dunbar3a2838d2009-11-13 08:58:20 +00003044 HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
Steve Naroffc4df6d22009-11-07 02:08:14 +00003045}
3046
Douglas Gregord3c68542009-11-19 01:08:35 +00003047void Sema::CodeCompleteObjCInstanceMessage(Scope *S, ExprTy *Receiver,
3048 IdentifierInfo **SelIdents,
3049 unsigned NumSelIdents) {
Steve Naroffc4df6d22009-11-07 02:08:14 +00003050 typedef CodeCompleteConsumer::Result Result;
Steve Naroffc4df6d22009-11-07 02:08:14 +00003051
3052 Expr *RecExpr = static_cast<Expr *>(Receiver);
Steve Naroffc4df6d22009-11-07 02:08:14 +00003053
Douglas Gregor36ecb042009-11-17 23:22:23 +00003054 // If necessary, apply function/array conversion to the receiver.
3055 // C99 6.7.5.3p[7,8].
Douglas Gregora873dfc2010-02-03 00:27:59 +00003056 DefaultFunctionArrayLvalueConversion(RecExpr);
Douglas Gregor36ecb042009-11-17 23:22:23 +00003057 QualType ReceiverType = RecExpr->getType();
Steve Naroffc4df6d22009-11-07 02:08:14 +00003058
Douglas Gregor36ecb042009-11-17 23:22:23 +00003059 // Build the set of methods we can see.
3060 ResultBuilder Results(*this);
3061 Results.EnterNewScope();
Douglas Gregor22f56992010-04-06 19:22:33 +00003062
3063 // If we're messaging an expression with type "id" or "Class", check
3064 // whether we know something special about the receiver that allows
3065 // us to assume a more-specific receiver type.
3066 if (ReceiverType->isObjCIdType() || ReceiverType->isObjCClassType())
3067 if (ObjCInterfaceDecl *IFace = GetAssumedMessageSendExprType(RecExpr))
3068 ReceiverType = Context.getObjCObjectPointerType(
3069 Context.getObjCInterfaceType(IFace));
Douglas Gregor36ecb042009-11-17 23:22:23 +00003070
Douglas Gregorf74a4192009-11-18 00:06:18 +00003071 // Handle messages to Class. This really isn't a message to an instance
3072 // method, so we treat it the same way we would treat a message send to a
3073 // class method.
3074 if (ReceiverType->isObjCClassType() ||
3075 ReceiverType->isObjCQualifiedClassType()) {
3076 if (ObjCMethodDecl *CurMethod = getCurMethodDecl()) {
3077 if (ObjCInterfaceDecl *ClassDecl = CurMethod->getClassInterface())
Douglas Gregor4ad96852009-11-19 07:41:15 +00003078 AddObjCMethods(ClassDecl, false, MK_Any, SelIdents, NumSelIdents,
3079 CurContext, Results);
Douglas Gregorf74a4192009-11-18 00:06:18 +00003080 }
3081 }
3082 // Handle messages to a qualified ID ("id<foo>").
3083 else if (const ObjCObjectPointerType *QualID
3084 = ReceiverType->getAsObjCQualifiedIdType()) {
3085 // Search protocols for instance methods.
3086 for (ObjCObjectPointerType::qual_iterator I = QualID->qual_begin(),
3087 E = QualID->qual_end();
3088 I != E; ++I)
Douglas Gregor4ad96852009-11-19 07:41:15 +00003089 AddObjCMethods(*I, true, MK_Any, SelIdents, NumSelIdents, CurContext,
3090 Results);
Douglas Gregorf74a4192009-11-18 00:06:18 +00003091 }
3092 // Handle messages to a pointer to interface type.
3093 else if (const ObjCObjectPointerType *IFacePtr
3094 = ReceiverType->getAsObjCInterfacePointerType()) {
3095 // Search the class, its superclasses, etc., for instance methods.
Douglas Gregor4ad96852009-11-19 07:41:15 +00003096 AddObjCMethods(IFacePtr->getInterfaceDecl(), true, MK_Any, SelIdents,
3097 NumSelIdents, CurContext, Results);
Douglas Gregorf74a4192009-11-18 00:06:18 +00003098
3099 // Search protocols for instance methods.
3100 for (ObjCObjectPointerType::qual_iterator I = IFacePtr->qual_begin(),
3101 E = IFacePtr->qual_end();
3102 I != E; ++I)
Douglas Gregor4ad96852009-11-19 07:41:15 +00003103 AddObjCMethods(*I, true, MK_Any, SelIdents, NumSelIdents, CurContext,
3104 Results);
Douglas Gregorf74a4192009-11-18 00:06:18 +00003105 }
Douglas Gregor13438f92010-04-06 16:40:00 +00003106 // Handle messages to "id".
3107 else if (ReceiverType->isObjCIdType()) {
Douglas Gregor719770d2010-04-06 17:30:22 +00003108 // We're messaging "id", so provide all instance methods we know
3109 // about as code-completion results.
3110
3111 // If we have an external source, load the entire class method
3112 // pool from the PCH file.
3113 if (ExternalSource) {
3114 for (uint32_t I = 0, N = ExternalSource->GetNumKnownSelectors(); I != N;
3115 ++I) {
3116 Selector Sel = ExternalSource->GetSelector(I);
3117 if (Sel.isNull() || InstanceMethodPool.count(Sel) ||
3118 FactoryMethodPool.count(Sel))
3119 continue;
3120
3121 ReadMethodPool(Sel, /*isInstance=*/true);
3122 }
3123 }
3124
Douglas Gregor13438f92010-04-06 16:40:00 +00003125 for (llvm::DenseMap<Selector, ObjCMethodList>::iterator
3126 M = InstanceMethodPool.begin(),
3127 MEnd = InstanceMethodPool.end();
3128 M != MEnd;
3129 ++M) {
Douglas Gregor719770d2010-04-06 17:30:22 +00003130 for (ObjCMethodList *MethList = &M->second; MethList && MethList->Method;
Douglas Gregor13438f92010-04-06 16:40:00 +00003131 MethList = MethList->Next) {
3132 if (!isAcceptableObjCMethod(MethList->Method, MK_Any, SelIdents,
3133 NumSelIdents))
3134 continue;
3135
3136 Result R(MethList->Method, 0);
3137 R.StartParameter = NumSelIdents;
3138 R.AllParametersAreInformative = false;
3139 Results.MaybeAddResult(R, CurContext);
3140 }
3141 }
3142 }
3143
Steve Naroffc4df6d22009-11-07 02:08:14 +00003144 Results.ExitScope();
Daniel Dunbar3a2838d2009-11-13 08:58:20 +00003145 HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
Steve Naroffc4df6d22009-11-07 02:08:14 +00003146}
Douglas Gregor55385fe2009-11-18 04:19:12 +00003147
3148/// \brief Add all of the protocol declarations that we find in the given
3149/// (translation unit) context.
3150static void AddProtocolResults(DeclContext *Ctx, DeclContext *CurContext,
Douglas Gregor083128f2009-11-18 04:49:41 +00003151 bool OnlyForwardDeclarations,
Douglas Gregor55385fe2009-11-18 04:19:12 +00003152 ResultBuilder &Results) {
3153 typedef CodeCompleteConsumer::Result Result;
3154
3155 for (DeclContext::decl_iterator D = Ctx->decls_begin(),
3156 DEnd = Ctx->decls_end();
3157 D != DEnd; ++D) {
3158 // Record any protocols we find.
3159 if (ObjCProtocolDecl *Proto = dyn_cast<ObjCProtocolDecl>(*D))
Douglas Gregor083128f2009-11-18 04:49:41 +00003160 if (!OnlyForwardDeclarations || Proto->isForwardDecl())
Douglas Gregor608300b2010-01-14 16:14:35 +00003161 Results.AddResult(Result(Proto, 0), CurContext, 0, false);
Douglas Gregor55385fe2009-11-18 04:19:12 +00003162
3163 // Record any forward-declared protocols we find.
3164 if (ObjCForwardProtocolDecl *Forward
3165 = dyn_cast<ObjCForwardProtocolDecl>(*D)) {
3166 for (ObjCForwardProtocolDecl::protocol_iterator
3167 P = Forward->protocol_begin(),
3168 PEnd = Forward->protocol_end();
3169 P != PEnd; ++P)
Douglas Gregor083128f2009-11-18 04:49:41 +00003170 if (!OnlyForwardDeclarations || (*P)->isForwardDecl())
Douglas Gregor608300b2010-01-14 16:14:35 +00003171 Results.AddResult(Result(*P, 0), CurContext, 0, false);
Douglas Gregor55385fe2009-11-18 04:19:12 +00003172 }
3173 }
3174}
3175
3176void Sema::CodeCompleteObjCProtocolReferences(IdentifierLocPair *Protocols,
3177 unsigned NumProtocols) {
3178 ResultBuilder Results(*this);
3179 Results.EnterNewScope();
3180
3181 // Tell the result set to ignore all of the protocols we have
3182 // already seen.
3183 for (unsigned I = 0; I != NumProtocols; ++I)
3184 if (ObjCProtocolDecl *Protocol = LookupProtocol(Protocols[I].first))
3185 Results.Ignore(Protocol);
3186
3187 // Add all protocols.
Douglas Gregor083128f2009-11-18 04:49:41 +00003188 AddProtocolResults(Context.getTranslationUnitDecl(), CurContext, false,
3189 Results);
3190
3191 Results.ExitScope();
3192 HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
3193}
3194
3195void Sema::CodeCompleteObjCProtocolDecl(Scope *) {
3196 ResultBuilder Results(*this);
3197 Results.EnterNewScope();
3198
3199 // Add all protocols.
3200 AddProtocolResults(Context.getTranslationUnitDecl(), CurContext, true,
3201 Results);
Douglas Gregor55385fe2009-11-18 04:19:12 +00003202
3203 Results.ExitScope();
3204 HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
3205}
Douglas Gregor3b49aca2009-11-18 16:26:39 +00003206
3207/// \brief Add all of the Objective-C interface declarations that we find in
3208/// the given (translation unit) context.
3209static void AddInterfaceResults(DeclContext *Ctx, DeclContext *CurContext,
3210 bool OnlyForwardDeclarations,
3211 bool OnlyUnimplemented,
3212 ResultBuilder &Results) {
3213 typedef CodeCompleteConsumer::Result Result;
3214
3215 for (DeclContext::decl_iterator D = Ctx->decls_begin(),
3216 DEnd = Ctx->decls_end();
3217 D != DEnd; ++D) {
3218 // Record any interfaces we find.
3219 if (ObjCInterfaceDecl *Class = dyn_cast<ObjCInterfaceDecl>(*D))
3220 if ((!OnlyForwardDeclarations || Class->isForwardDecl()) &&
3221 (!OnlyUnimplemented || !Class->getImplementation()))
Douglas Gregor608300b2010-01-14 16:14:35 +00003222 Results.AddResult(Result(Class, 0), CurContext, 0, false);
Douglas Gregor3b49aca2009-11-18 16:26:39 +00003223
3224 // Record any forward-declared interfaces we find.
3225 if (ObjCClassDecl *Forward = dyn_cast<ObjCClassDecl>(*D)) {
3226 for (ObjCClassDecl::iterator C = Forward->begin(), CEnd = Forward->end();
3227 C != CEnd; ++C)
3228 if ((!OnlyForwardDeclarations || C->getInterface()->isForwardDecl()) &&
3229 (!OnlyUnimplemented || !C->getInterface()->getImplementation()))
Douglas Gregor608300b2010-01-14 16:14:35 +00003230 Results.AddResult(Result(C->getInterface(), 0), CurContext,
3231 0, false);
Douglas Gregor3b49aca2009-11-18 16:26:39 +00003232 }
3233 }
3234}
3235
3236void Sema::CodeCompleteObjCInterfaceDecl(Scope *S) {
3237 ResultBuilder Results(*this);
3238 Results.EnterNewScope();
3239
3240 // Add all classes.
3241 AddInterfaceResults(Context.getTranslationUnitDecl(), CurContext, true,
3242 false, Results);
3243
3244 Results.ExitScope();
3245 HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
3246}
3247
3248void Sema::CodeCompleteObjCSuperclass(Scope *S, IdentifierInfo *ClassName) {
3249 ResultBuilder Results(*this);
3250 Results.EnterNewScope();
3251
3252 // Make sure that we ignore the class we're currently defining.
3253 NamedDecl *CurClass
3254 = LookupSingleName(TUScope, ClassName, LookupOrdinaryName);
Douglas Gregor33ced0b2009-11-18 19:08:43 +00003255 if (CurClass && isa<ObjCInterfaceDecl>(CurClass))
Douglas Gregor3b49aca2009-11-18 16:26:39 +00003256 Results.Ignore(CurClass);
3257
3258 // Add all classes.
3259 AddInterfaceResults(Context.getTranslationUnitDecl(), CurContext, false,
3260 false, Results);
3261
3262 Results.ExitScope();
3263 HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
3264}
3265
3266void Sema::CodeCompleteObjCImplementationDecl(Scope *S) {
3267 ResultBuilder Results(*this);
3268 Results.EnterNewScope();
3269
3270 // Add all unimplemented classes.
3271 AddInterfaceResults(Context.getTranslationUnitDecl(), CurContext, false,
3272 true, Results);
3273
3274 Results.ExitScope();
3275 HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
3276}
Douglas Gregor33ced0b2009-11-18 19:08:43 +00003277
3278void Sema::CodeCompleteObjCInterfaceCategory(Scope *S,
3279 IdentifierInfo *ClassName) {
3280 typedef CodeCompleteConsumer::Result Result;
3281
3282 ResultBuilder Results(*this);
3283
3284 // Ignore any categories we find that have already been implemented by this
3285 // interface.
3286 llvm::SmallPtrSet<IdentifierInfo *, 16> CategoryNames;
3287 NamedDecl *CurClass
3288 = LookupSingleName(TUScope, ClassName, LookupOrdinaryName);
3289 if (ObjCInterfaceDecl *Class = dyn_cast_or_null<ObjCInterfaceDecl>(CurClass))
3290 for (ObjCCategoryDecl *Category = Class->getCategoryList(); Category;
3291 Category = Category->getNextClassCategory())
3292 CategoryNames.insert(Category->getIdentifier());
3293
3294 // Add all of the categories we know about.
3295 Results.EnterNewScope();
3296 TranslationUnitDecl *TU = Context.getTranslationUnitDecl();
3297 for (DeclContext::decl_iterator D = TU->decls_begin(),
3298 DEnd = TU->decls_end();
3299 D != DEnd; ++D)
3300 if (ObjCCategoryDecl *Category = dyn_cast<ObjCCategoryDecl>(*D))
3301 if (CategoryNames.insert(Category->getIdentifier()))
Douglas Gregor608300b2010-01-14 16:14:35 +00003302 Results.AddResult(Result(Category, 0), CurContext, 0, false);
Douglas Gregor33ced0b2009-11-18 19:08:43 +00003303 Results.ExitScope();
3304
3305 HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
3306}
3307
3308void Sema::CodeCompleteObjCImplementationCategory(Scope *S,
3309 IdentifierInfo *ClassName) {
3310 typedef CodeCompleteConsumer::Result Result;
3311
3312 // Find the corresponding interface. If we couldn't find the interface, the
3313 // program itself is ill-formed. However, we'll try to be helpful still by
3314 // providing the list of all of the categories we know about.
3315 NamedDecl *CurClass
3316 = LookupSingleName(TUScope, ClassName, LookupOrdinaryName);
3317 ObjCInterfaceDecl *Class = dyn_cast_or_null<ObjCInterfaceDecl>(CurClass);
3318 if (!Class)
3319 return CodeCompleteObjCInterfaceCategory(S, ClassName);
3320
3321 ResultBuilder Results(*this);
3322
3323 // Add all of the categories that have have corresponding interface
3324 // declarations in this class and any of its superclasses, except for
3325 // already-implemented categories in the class itself.
3326 llvm::SmallPtrSet<IdentifierInfo *, 16> CategoryNames;
3327 Results.EnterNewScope();
3328 bool IgnoreImplemented = true;
3329 while (Class) {
3330 for (ObjCCategoryDecl *Category = Class->getCategoryList(); Category;
3331 Category = Category->getNextClassCategory())
3332 if ((!IgnoreImplemented || !Category->getImplementation()) &&
3333 CategoryNames.insert(Category->getIdentifier()))
Douglas Gregor608300b2010-01-14 16:14:35 +00003334 Results.AddResult(Result(Category, 0), CurContext, 0, false);
Douglas Gregor33ced0b2009-11-18 19:08:43 +00003335
3336 Class = Class->getSuperClass();
3337 IgnoreImplemented = false;
3338 }
3339 Results.ExitScope();
3340
3341 HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
3342}
Douglas Gregor322328b2009-11-18 22:32:06 +00003343
Douglas Gregor424b2a52009-11-18 22:56:13 +00003344void Sema::CodeCompleteObjCPropertyDefinition(Scope *S, DeclPtrTy ObjCImpDecl) {
Douglas Gregor322328b2009-11-18 22:32:06 +00003345 typedef CodeCompleteConsumer::Result Result;
3346 ResultBuilder Results(*this);
3347
3348 // Figure out where this @synthesize lives.
3349 ObjCContainerDecl *Container
3350 = dyn_cast_or_null<ObjCContainerDecl>(ObjCImpDecl.getAs<Decl>());
3351 if (!Container ||
3352 (!isa<ObjCImplementationDecl>(Container) &&
3353 !isa<ObjCCategoryImplDecl>(Container)))
3354 return;
3355
3356 // Ignore any properties that have already been implemented.
3357 for (DeclContext::decl_iterator D = Container->decls_begin(),
3358 DEnd = Container->decls_end();
3359 D != DEnd; ++D)
3360 if (ObjCPropertyImplDecl *PropertyImpl = dyn_cast<ObjCPropertyImplDecl>(*D))
3361 Results.Ignore(PropertyImpl->getPropertyDecl());
3362
3363 // Add any properties that we find.
3364 Results.EnterNewScope();
3365 if (ObjCImplementationDecl *ClassImpl
3366 = dyn_cast<ObjCImplementationDecl>(Container))
3367 AddObjCProperties(ClassImpl->getClassInterface(), false, CurContext,
3368 Results);
3369 else
3370 AddObjCProperties(cast<ObjCCategoryImplDecl>(Container)->getCategoryDecl(),
3371 false, CurContext, Results);
3372 Results.ExitScope();
3373
3374 HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
3375}
3376
3377void Sema::CodeCompleteObjCPropertySynthesizeIvar(Scope *S,
3378 IdentifierInfo *PropertyName,
3379 DeclPtrTy ObjCImpDecl) {
3380 typedef CodeCompleteConsumer::Result Result;
3381 ResultBuilder Results(*this);
3382
3383 // Figure out where this @synthesize lives.
3384 ObjCContainerDecl *Container
3385 = dyn_cast_or_null<ObjCContainerDecl>(ObjCImpDecl.getAs<Decl>());
3386 if (!Container ||
3387 (!isa<ObjCImplementationDecl>(Container) &&
3388 !isa<ObjCCategoryImplDecl>(Container)))
3389 return;
3390
3391 // Figure out which interface we're looking into.
3392 ObjCInterfaceDecl *Class = 0;
3393 if (ObjCImplementationDecl *ClassImpl
3394 = dyn_cast<ObjCImplementationDecl>(Container))
3395 Class = ClassImpl->getClassInterface();
3396 else
3397 Class = cast<ObjCCategoryImplDecl>(Container)->getCategoryDecl()
3398 ->getClassInterface();
3399
3400 // Add all of the instance variables in this class and its superclasses.
3401 Results.EnterNewScope();
3402 for(; Class; Class = Class->getSuperClass()) {
3403 // FIXME: We could screen the type of each ivar for compatibility with
3404 // the property, but is that being too paternal?
3405 for (ObjCInterfaceDecl::ivar_iterator IVar = Class->ivar_begin(),
3406 IVarEnd = Class->ivar_end();
3407 IVar != IVarEnd; ++IVar)
Douglas Gregor608300b2010-01-14 16:14:35 +00003408 Results.AddResult(Result(*IVar, 0), CurContext, 0, false);
Douglas Gregor322328b2009-11-18 22:32:06 +00003409 }
3410 Results.ExitScope();
3411
3412 HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
3413}
Douglas Gregore8f5a172010-04-07 00:21:17 +00003414
3415typedef llvm::DenseMap<Selector, ObjCMethodDecl *> KnownMethodsMap;
3416
3417/// \brief Find all of the methods that reside in the given container
3418/// (and its superclasses, protocols, etc.) that meet the given
3419/// criteria. Insert those methods into the map of known methods,
3420/// indexed by selector so they can be easily found.
3421static void FindImplementableMethods(ASTContext &Context,
3422 ObjCContainerDecl *Container,
3423 bool WantInstanceMethods,
3424 QualType ReturnType,
3425 bool IsInImplementation,
3426 KnownMethodsMap &KnownMethods) {
3427 if (ObjCInterfaceDecl *IFace = dyn_cast<ObjCInterfaceDecl>(Container)) {
3428 // Recurse into protocols.
3429 const ObjCList<ObjCProtocolDecl> &Protocols
3430 = IFace->getReferencedProtocols();
3431 for (ObjCList<ObjCProtocolDecl>::iterator I = Protocols.begin(),
3432 E = Protocols.end();
3433 I != E; ++I)
3434 FindImplementableMethods(Context, *I, WantInstanceMethods, ReturnType,
3435 IsInImplementation, KnownMethods);
3436
3437 // If we're not in the implementation of a class, also visit the
3438 // superclass.
3439 if (!IsInImplementation && IFace->getSuperClass())
3440 FindImplementableMethods(Context, IFace->getSuperClass(),
3441 WantInstanceMethods, ReturnType,
3442 IsInImplementation, KnownMethods);
3443
3444 // Add methods from any class extensions (but not from categories;
3445 // those should go into category implementations).
3446 for (ObjCCategoryDecl *Cat = IFace->getCategoryList(); Cat;
3447 Cat = Cat->getNextClassCategory()) {
3448 if (!Cat->IsClassExtension())
3449 continue;
3450
3451 FindImplementableMethods(Context, Cat, WantInstanceMethods, ReturnType,
3452 IsInImplementation, KnownMethods);
3453 }
3454 }
3455
3456 if (ObjCCategoryDecl *Category = dyn_cast<ObjCCategoryDecl>(Container)) {
3457 // Recurse into protocols.
3458 const ObjCList<ObjCProtocolDecl> &Protocols
3459 = Category->getReferencedProtocols();
3460 for (ObjCList<ObjCProtocolDecl>::iterator I = Protocols.begin(),
3461 E = Protocols.end();
3462 I != E; ++I)
3463 FindImplementableMethods(Context, *I, WantInstanceMethods, ReturnType,
3464 IsInImplementation, KnownMethods);
3465 }
3466
3467 if (ObjCProtocolDecl *Protocol = dyn_cast<ObjCProtocolDecl>(Container)) {
3468 // Recurse into protocols.
3469 const ObjCList<ObjCProtocolDecl> &Protocols
3470 = Protocol->getReferencedProtocols();
3471 for (ObjCList<ObjCProtocolDecl>::iterator I = Protocols.begin(),
3472 E = Protocols.end();
3473 I != E; ++I)
3474 FindImplementableMethods(Context, *I, WantInstanceMethods, ReturnType,
3475 IsInImplementation, KnownMethods);
3476 }
3477
3478 // Add methods in this container. This operation occurs last because
3479 // we want the methods from this container to override any methods
3480 // we've previously seen with the same selector.
3481 for (ObjCContainerDecl::method_iterator M = Container->meth_begin(),
3482 MEnd = Container->meth_end();
3483 M != MEnd; ++M) {
3484 if ((*M)->isInstanceMethod() == WantInstanceMethods) {
3485 if (!ReturnType.isNull() &&
3486 !Context.hasSameUnqualifiedType(ReturnType, (*M)->getResultType()))
3487 continue;
3488
3489 KnownMethods[(*M)->getSelector()] = *M;
3490 }
3491 }
3492}
3493
3494void Sema::CodeCompleteObjCMethodDecl(Scope *S,
3495 bool IsInstanceMethod,
3496 TypeTy *ReturnTy,
3497 DeclPtrTy IDecl) {
3498 // Determine the return type of the method we're declaring, if
3499 // provided.
3500 QualType ReturnType = GetTypeFromParser(ReturnTy);
3501
3502 // Determine where we should start searching for methods, and where we
3503 ObjCContainerDecl *SearchDecl = 0, *CurrentDecl = 0;
3504 bool IsInImplementation = false;
3505 if (Decl *D = IDecl.getAs<Decl>()) {
3506 if (ObjCImplementationDecl *Impl = dyn_cast<ObjCImplementationDecl>(D)) {
3507 SearchDecl = Impl->getClassInterface();
3508 CurrentDecl = Impl;
3509 IsInImplementation = true;
3510 } else if (ObjCCategoryImplDecl *CatImpl
3511 = dyn_cast<ObjCCategoryImplDecl>(D)) {
3512 SearchDecl = CatImpl->getCategoryDecl();
3513 CurrentDecl = CatImpl;
3514 IsInImplementation = true;
3515 } else {
3516 SearchDecl = dyn_cast<ObjCContainerDecl>(D);
3517 CurrentDecl = SearchDecl;
3518 }
3519 }
3520
3521 if (!SearchDecl && S) {
3522 if (DeclContext *DC = static_cast<DeclContext *>(S->getEntity())) {
3523 SearchDecl = dyn_cast<ObjCContainerDecl>(DC);
3524 CurrentDecl = SearchDecl;
3525 }
3526 }
3527
3528 if (!SearchDecl || !CurrentDecl) {
3529 HandleCodeCompleteResults(this, CodeCompleter, 0, 0);
3530 return;
3531 }
3532
3533 // Find all of the methods that we could declare/implement here.
3534 KnownMethodsMap KnownMethods;
3535 FindImplementableMethods(Context, SearchDecl, IsInstanceMethod,
3536 ReturnType, IsInImplementation, KnownMethods);
3537
3538 // Erase any methods that have already been declared or
3539 // implemented here.
3540 for (ObjCContainerDecl::method_iterator M = CurrentDecl->meth_begin(),
3541 MEnd = CurrentDecl->meth_end();
3542 M != MEnd; ++M) {
3543 if ((*M)->isInstanceMethod() != IsInstanceMethod)
3544 continue;
3545
3546 KnownMethodsMap::iterator Pos = KnownMethods.find((*M)->getSelector());
3547 if (Pos != KnownMethods.end())
3548 KnownMethods.erase(Pos);
3549 }
3550
3551 // Add declarations or definitions for each of the known methods.
3552 typedef CodeCompleteConsumer::Result Result;
3553 ResultBuilder Results(*this);
3554 Results.EnterNewScope();
3555 PrintingPolicy Policy(Context.PrintingPolicy);
3556 Policy.AnonymousTagLocations = false;
3557 for (KnownMethodsMap::iterator M = KnownMethods.begin(),
3558 MEnd = KnownMethods.end();
3559 M != MEnd; ++M) {
3560 ObjCMethodDecl *Method = M->second;
3561 CodeCompletionString *Pattern = new CodeCompletionString;
3562
3563 // If the result type was not already provided, add it to the
3564 // pattern as (type).
3565 if (ReturnType.isNull()) {
3566 std::string TypeStr;
3567 Method->getResultType().getAsStringInternal(TypeStr, Policy);
3568 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
3569 Pattern->AddTextChunk(TypeStr);
3570 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
3571 }
3572
3573 Selector Sel = Method->getSelector();
3574
3575 // Add the first part of the selector to the pattern.
3576 Pattern->AddTypedTextChunk(Sel.getIdentifierInfoForSlot(0)->getName());
3577
3578 // Add parameters to the pattern.
3579 unsigned I = 0;
3580 for (ObjCMethodDecl::param_iterator P = Method->param_begin(),
3581 PEnd = Method->param_end();
3582 P != PEnd; (void)++P, ++I) {
3583 // Add the part of the selector name.
3584 if (I == 0)
3585 Pattern->AddChunk(CodeCompletionString::CK_Colon);
3586 else if (I < Sel.getNumArgs()) {
3587 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
3588 Pattern->AddTextChunk(Sel.getIdentifierInfoForSlot(1)->getName());
3589 Pattern->AddChunk(CodeCompletionString::CK_Colon);
3590 } else
3591 break;
3592
3593 // Add the parameter type.
3594 std::string TypeStr;
3595 (*P)->getOriginalType().getAsStringInternal(TypeStr, Policy);
3596 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
3597 Pattern->AddTextChunk(TypeStr);
3598 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
3599
3600 if (IdentifierInfo *Id = (*P)->getIdentifier())
3601 Pattern->AddTextChunk(Id->getName());
3602 }
3603
3604 if (Method->isVariadic()) {
3605 if (Method->param_size() > 0)
3606 Pattern->AddChunk(CodeCompletionString::CK_Comma);
3607 Pattern->AddTextChunk("...");
3608 }
3609
3610 if (IsInImplementation) {
3611 // We will be defining the method here, so add a compound statement.
3612 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
3613 Pattern->AddChunk(CodeCompletionString::CK_LeftBrace);
3614 Pattern->AddChunk(CodeCompletionString::CK_VerticalSpace);
3615 if (!Method->getResultType()->isVoidType()) {
3616 // If the result type is not void, add a return clause.
3617 Pattern->AddTextChunk("return");
3618 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
3619 Pattern->AddPlaceholderChunk("expression");
3620 Pattern->AddChunk(CodeCompletionString::CK_SemiColon);
3621 } else
3622 Pattern->AddPlaceholderChunk("statements");
3623
3624 Pattern->AddChunk(CodeCompletionString::CK_VerticalSpace);
3625 Pattern->AddChunk(CodeCompletionString::CK_RightBrace);
3626 }
3627
3628 Results.AddResult(Result(Pattern));
3629 }
3630
3631 Results.ExitScope();
3632
3633 HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
3634}