blob: e71f8c84ebc524a2ecb98c2a38ef087eb17a57d8 [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 Gregorc27d6c52010-04-16 17:41:49 +00002245 false, /*PartialOverloading*/true);
Douglas Gregorc0265402010-01-21 15:46:19 +00002246 }
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
Jeffrey Yasskin9ab14542010-04-08 16:38:48 +00002269void Sema::CodeCompleteQualifiedId(Scope *S, CXXScopeSpec &SS,
Douglas Gregor81b747b2009-09-17 21:32:03 +00002270 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.
Douglas Gregor04badcf2010-04-21 00:45:42 +00002902 ObjCInterfaceDecl *IFace = 0;
2903 switch (Msg->getReceiverKind()) {
2904 case ObjCMessageExpr::Class:
2905 if (const ObjCInterfaceType *IFaceType
2906 = Msg->getClassReceiver()->getAs<ObjCInterfaceType>())
2907 IFace = IFaceType->getDecl();
2908 break;
2909
2910 case ObjCMessageExpr::Instance: {
2911 QualType T = Msg->getInstanceReceiver()->getType();
2912 if (const ObjCObjectPointerType *Ptr = T->getAs<ObjCObjectPointerType>())
2913 IFace = Ptr->getInterfaceDecl();
2914 break;
2915 }
2916
2917 case ObjCMessageExpr::SuperInstance:
2918 case ObjCMessageExpr::SuperClass:
2919 break;
Douglas Gregor22f56992010-04-06 19:22:33 +00002920 }
2921
2922 if (!IFace)
2923 return 0;
2924
2925 ObjCInterfaceDecl *Super = IFace->getSuperClass();
2926 if (Method->isInstanceMethod())
2927 return llvm::StringSwitch<ObjCInterfaceDecl *>(Id->getName())
2928 .Case("retain", IFace)
2929 .Case("autorelease", IFace)
2930 .Case("copy", IFace)
2931 .Case("copyWithZone", IFace)
2932 .Case("mutableCopy", IFace)
2933 .Case("mutableCopyWithZone", IFace)
2934 .Case("awakeFromCoder", IFace)
2935 .Case("replacementObjectFromCoder", IFace)
2936 .Case("class", IFace)
2937 .Case("classForCoder", IFace)
2938 .Case("superclass", Super)
2939 .Default(0);
2940
2941 return llvm::StringSwitch<ObjCInterfaceDecl *>(Id->getName())
2942 .Case("new", IFace)
2943 .Case("alloc", IFace)
2944 .Case("allocWithZone", IFace)
2945 .Case("class", IFace)
2946 .Case("superclass", Super)
2947 .Default(0);
2948}
2949
Douglas Gregor2725ca82010-04-21 19:57:20 +00002950void Sema::CodeCompleteObjCSuperMessage(Scope *S, SourceLocation SuperLoc,
2951 IdentifierInfo **SelIdents,
2952 unsigned NumSelIdents) {
2953 ObjCInterfaceDecl *CDecl = 0;
2954 if (ObjCMethodDecl *CurMethod = getCurMethodDecl()) {
2955 // Figure out which interface we're in.
2956 CDecl = CurMethod->getClassInterface();
2957 if (!CDecl)
2958 return;
2959
2960 // Find the superclass of this class.
2961 CDecl = CDecl->getSuperClass();
2962 if (!CDecl)
2963 return;
2964
2965 if (CurMethod->isInstanceMethod()) {
2966 // We are inside an instance method, which means that the message
2967 // send [super ...] is actually calling an instance method on the
2968 // current object. Build the super expression and handle this like
2969 // an instance method.
2970 QualType SuperTy = Context.getObjCInterfaceType(CDecl);
2971 SuperTy = Context.getObjCObjectPointerType(SuperTy);
2972 OwningExprResult Super
2973 = Owned(new (Context) ObjCSuperExpr(SuperLoc, SuperTy));
2974 return CodeCompleteObjCInstanceMessage(S, (Expr *)Super.get(),
2975 SelIdents, NumSelIdents);
2976 }
2977
2978 // Fall through to send to the superclass in CDecl.
2979 } else {
2980 // "super" may be the name of a type or variable. Figure out which
2981 // it is.
2982 IdentifierInfo *Super = &Context.Idents.get("super");
2983 NamedDecl *ND = LookupSingleName(S, Super, SuperLoc,
2984 LookupOrdinaryName);
2985 if ((CDecl = dyn_cast_or_null<ObjCInterfaceDecl>(ND))) {
2986 // "super" names an interface. Use it.
2987 } else if (TypeDecl *TD = dyn_cast_or_null<TypeDecl>(ND)) {
2988 if (const ObjCInterfaceType *Iface
2989 = Context.getTypeDeclType(TD)->getAs<ObjCInterfaceType>())
2990 CDecl = Iface->getDecl();
2991 } else if (ND && isa<UnresolvedUsingTypenameDecl>(ND)) {
2992 // "super" names an unresolved type; we can't be more specific.
2993 } else {
2994 // Assume that "super" names some kind of value and parse that way.
2995 CXXScopeSpec SS;
2996 UnqualifiedId id;
2997 id.setIdentifier(Super, SuperLoc);
2998 OwningExprResult SuperExpr = ActOnIdExpression(S, SS, id, false, false);
2999 return CodeCompleteObjCInstanceMessage(S, (Expr *)SuperExpr.get(),
3000 SelIdents, NumSelIdents);
3001 }
3002
3003 // Fall through
3004 }
3005
3006 TypeTy *Receiver = 0;
3007 if (CDecl)
3008 Receiver = Context.getObjCInterfaceType(CDecl).getAsOpaquePtr();
3009 return CodeCompleteObjCClassMessage(S, Receiver, SelIdents,
3010 NumSelIdents);
3011}
3012
3013void Sema::CodeCompleteObjCClassMessage(Scope *S, TypeTy *Receiver,
Douglas Gregord3c68542009-11-19 01:08:35 +00003014 IdentifierInfo **SelIdents,
3015 unsigned NumSelIdents) {
Steve Naroffc4df6d22009-11-07 02:08:14 +00003016 typedef CodeCompleteConsumer::Result Result;
Douglas Gregor24a069f2009-11-17 17:59:40 +00003017 ObjCInterfaceDecl *CDecl = 0;
3018
Douglas Gregor24a069f2009-11-17 17:59:40 +00003019 // If the given name refers to an interface type, retrieve the
3020 // corresponding declaration.
Douglas Gregor2725ca82010-04-21 19:57:20 +00003021 if (Receiver) {
3022 QualType T = GetTypeFromParser(Receiver, 0);
3023 if (!T.isNull())
3024 if (const ObjCInterfaceType *Interface = T->getAs<ObjCInterfaceType>())
3025 CDecl = Interface->getDecl();
Douglas Gregor24a069f2009-11-17 17:59:40 +00003026 }
3027
Douglas Gregor36ecb042009-11-17 23:22:23 +00003028 // Add all of the factory methods in this Objective-C class, its protocols,
3029 // superclasses, categories, implementation, etc.
Steve Naroffc4df6d22009-11-07 02:08:14 +00003030 ResultBuilder Results(*this);
3031 Results.EnterNewScope();
Douglas Gregor13438f92010-04-06 16:40:00 +00003032
3033 if (CDecl)
3034 AddObjCMethods(CDecl, false, MK_Any, SelIdents, NumSelIdents, CurContext,
3035 Results);
Douglas Gregor2725ca82010-04-21 19:57:20 +00003036 else {
Douglas Gregor13438f92010-04-06 16:40:00 +00003037 // We're messaging "id" as a type; provide all class/factory methods.
3038
Douglas Gregor719770d2010-04-06 17:30:22 +00003039 // If we have an external source, load the entire class method
3040 // pool from the PCH file.
3041 if (ExternalSource) {
3042 for (uint32_t I = 0, N = ExternalSource->GetNumKnownSelectors(); I != N;
3043 ++I) {
3044 Selector Sel = ExternalSource->GetSelector(I);
3045 if (Sel.isNull() || FactoryMethodPool.count(Sel) ||
3046 InstanceMethodPool.count(Sel))
3047 continue;
3048
3049 ReadMethodPool(Sel, /*isInstance=*/false);
3050 }
3051 }
3052
Douglas Gregor13438f92010-04-06 16:40:00 +00003053 for (llvm::DenseMap<Selector, ObjCMethodList>::iterator
3054 M = FactoryMethodPool.begin(),
3055 MEnd = FactoryMethodPool.end();
3056 M != MEnd;
3057 ++M) {
Douglas Gregor719770d2010-04-06 17:30:22 +00003058 for (ObjCMethodList *MethList = &M->second; MethList && MethList->Method;
Douglas Gregor13438f92010-04-06 16:40:00 +00003059 MethList = MethList->Next) {
3060 if (!isAcceptableObjCMethod(MethList->Method, MK_Any, SelIdents,
3061 NumSelIdents))
3062 continue;
3063
3064 Result R(MethList->Method, 0);
3065 R.StartParameter = NumSelIdents;
3066 R.AllParametersAreInformative = false;
3067 Results.MaybeAddResult(R, CurContext);
3068 }
3069 }
3070 }
3071
Steve Naroffc4df6d22009-11-07 02:08:14 +00003072 Results.ExitScope();
Douglas Gregor36ecb042009-11-17 23:22:23 +00003073
Steve Naroffc4df6d22009-11-07 02:08:14 +00003074 // This also suppresses remaining diagnostics.
Daniel Dunbar3a2838d2009-11-13 08:58:20 +00003075 HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
Steve Naroffc4df6d22009-11-07 02:08:14 +00003076}
3077
Douglas Gregord3c68542009-11-19 01:08:35 +00003078void Sema::CodeCompleteObjCInstanceMessage(Scope *S, ExprTy *Receiver,
3079 IdentifierInfo **SelIdents,
3080 unsigned NumSelIdents) {
Steve Naroffc4df6d22009-11-07 02:08:14 +00003081 typedef CodeCompleteConsumer::Result Result;
Steve Naroffc4df6d22009-11-07 02:08:14 +00003082
3083 Expr *RecExpr = static_cast<Expr *>(Receiver);
Steve Naroffc4df6d22009-11-07 02:08:14 +00003084
Douglas Gregor36ecb042009-11-17 23:22:23 +00003085 // If necessary, apply function/array conversion to the receiver.
3086 // C99 6.7.5.3p[7,8].
Douglas Gregora873dfc2010-02-03 00:27:59 +00003087 DefaultFunctionArrayLvalueConversion(RecExpr);
Douglas Gregor36ecb042009-11-17 23:22:23 +00003088 QualType ReceiverType = RecExpr->getType();
Steve Naroffc4df6d22009-11-07 02:08:14 +00003089
Douglas Gregor36ecb042009-11-17 23:22:23 +00003090 // Build the set of methods we can see.
3091 ResultBuilder Results(*this);
3092 Results.EnterNewScope();
Douglas Gregor22f56992010-04-06 19:22:33 +00003093
3094 // If we're messaging an expression with type "id" or "Class", check
3095 // whether we know something special about the receiver that allows
3096 // us to assume a more-specific receiver type.
3097 if (ReceiverType->isObjCIdType() || ReceiverType->isObjCClassType())
3098 if (ObjCInterfaceDecl *IFace = GetAssumedMessageSendExprType(RecExpr))
3099 ReceiverType = Context.getObjCObjectPointerType(
3100 Context.getObjCInterfaceType(IFace));
Douglas Gregor36ecb042009-11-17 23:22:23 +00003101
Douglas Gregorf74a4192009-11-18 00:06:18 +00003102 // Handle messages to Class. This really isn't a message to an instance
3103 // method, so we treat it the same way we would treat a message send to a
3104 // class method.
3105 if (ReceiverType->isObjCClassType() ||
3106 ReceiverType->isObjCQualifiedClassType()) {
3107 if (ObjCMethodDecl *CurMethod = getCurMethodDecl()) {
3108 if (ObjCInterfaceDecl *ClassDecl = CurMethod->getClassInterface())
Douglas Gregor4ad96852009-11-19 07:41:15 +00003109 AddObjCMethods(ClassDecl, false, MK_Any, SelIdents, NumSelIdents,
3110 CurContext, Results);
Douglas Gregorf74a4192009-11-18 00:06:18 +00003111 }
3112 }
3113 // Handle messages to a qualified ID ("id<foo>").
3114 else if (const ObjCObjectPointerType *QualID
3115 = ReceiverType->getAsObjCQualifiedIdType()) {
3116 // Search protocols for instance methods.
3117 for (ObjCObjectPointerType::qual_iterator I = QualID->qual_begin(),
3118 E = QualID->qual_end();
3119 I != E; ++I)
Douglas Gregor4ad96852009-11-19 07:41:15 +00003120 AddObjCMethods(*I, true, MK_Any, SelIdents, NumSelIdents, CurContext,
3121 Results);
Douglas Gregorf74a4192009-11-18 00:06:18 +00003122 }
3123 // Handle messages to a pointer to interface type.
3124 else if (const ObjCObjectPointerType *IFacePtr
3125 = ReceiverType->getAsObjCInterfacePointerType()) {
3126 // Search the class, its superclasses, etc., for instance methods.
Douglas Gregor4ad96852009-11-19 07:41:15 +00003127 AddObjCMethods(IFacePtr->getInterfaceDecl(), true, MK_Any, SelIdents,
3128 NumSelIdents, CurContext, Results);
Douglas Gregorf74a4192009-11-18 00:06:18 +00003129
3130 // Search protocols for instance methods.
3131 for (ObjCObjectPointerType::qual_iterator I = IFacePtr->qual_begin(),
3132 E = IFacePtr->qual_end();
3133 I != E; ++I)
Douglas Gregor4ad96852009-11-19 07:41:15 +00003134 AddObjCMethods(*I, true, MK_Any, SelIdents, NumSelIdents, CurContext,
3135 Results);
Douglas Gregorf74a4192009-11-18 00:06:18 +00003136 }
Douglas Gregor13438f92010-04-06 16:40:00 +00003137 // Handle messages to "id".
3138 else if (ReceiverType->isObjCIdType()) {
Douglas Gregor719770d2010-04-06 17:30:22 +00003139 // We're messaging "id", so provide all instance methods we know
3140 // about as code-completion results.
3141
3142 // If we have an external source, load the entire class method
3143 // pool from the PCH file.
3144 if (ExternalSource) {
3145 for (uint32_t I = 0, N = ExternalSource->GetNumKnownSelectors(); I != N;
3146 ++I) {
3147 Selector Sel = ExternalSource->GetSelector(I);
3148 if (Sel.isNull() || InstanceMethodPool.count(Sel) ||
3149 FactoryMethodPool.count(Sel))
3150 continue;
3151
3152 ReadMethodPool(Sel, /*isInstance=*/true);
3153 }
3154 }
3155
Douglas Gregor13438f92010-04-06 16:40:00 +00003156 for (llvm::DenseMap<Selector, ObjCMethodList>::iterator
3157 M = InstanceMethodPool.begin(),
3158 MEnd = InstanceMethodPool.end();
3159 M != MEnd;
3160 ++M) {
Douglas Gregor719770d2010-04-06 17:30:22 +00003161 for (ObjCMethodList *MethList = &M->second; MethList && MethList->Method;
Douglas Gregor13438f92010-04-06 16:40:00 +00003162 MethList = MethList->Next) {
3163 if (!isAcceptableObjCMethod(MethList->Method, MK_Any, SelIdents,
3164 NumSelIdents))
3165 continue;
3166
3167 Result R(MethList->Method, 0);
3168 R.StartParameter = NumSelIdents;
3169 R.AllParametersAreInformative = false;
3170 Results.MaybeAddResult(R, CurContext);
3171 }
3172 }
3173 }
3174
Steve Naroffc4df6d22009-11-07 02:08:14 +00003175 Results.ExitScope();
Daniel Dunbar3a2838d2009-11-13 08:58:20 +00003176 HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
Steve Naroffc4df6d22009-11-07 02:08:14 +00003177}
Douglas Gregor55385fe2009-11-18 04:19:12 +00003178
3179/// \brief Add all of the protocol declarations that we find in the given
3180/// (translation unit) context.
3181static void AddProtocolResults(DeclContext *Ctx, DeclContext *CurContext,
Douglas Gregor083128f2009-11-18 04:49:41 +00003182 bool OnlyForwardDeclarations,
Douglas Gregor55385fe2009-11-18 04:19:12 +00003183 ResultBuilder &Results) {
3184 typedef CodeCompleteConsumer::Result Result;
3185
3186 for (DeclContext::decl_iterator D = Ctx->decls_begin(),
3187 DEnd = Ctx->decls_end();
3188 D != DEnd; ++D) {
3189 // Record any protocols we find.
3190 if (ObjCProtocolDecl *Proto = dyn_cast<ObjCProtocolDecl>(*D))
Douglas Gregor083128f2009-11-18 04:49:41 +00003191 if (!OnlyForwardDeclarations || Proto->isForwardDecl())
Douglas Gregor608300b2010-01-14 16:14:35 +00003192 Results.AddResult(Result(Proto, 0), CurContext, 0, false);
Douglas Gregor55385fe2009-11-18 04:19:12 +00003193
3194 // Record any forward-declared protocols we find.
3195 if (ObjCForwardProtocolDecl *Forward
3196 = dyn_cast<ObjCForwardProtocolDecl>(*D)) {
3197 for (ObjCForwardProtocolDecl::protocol_iterator
3198 P = Forward->protocol_begin(),
3199 PEnd = Forward->protocol_end();
3200 P != PEnd; ++P)
Douglas Gregor083128f2009-11-18 04:49:41 +00003201 if (!OnlyForwardDeclarations || (*P)->isForwardDecl())
Douglas Gregor608300b2010-01-14 16:14:35 +00003202 Results.AddResult(Result(*P, 0), CurContext, 0, false);
Douglas Gregor55385fe2009-11-18 04:19:12 +00003203 }
3204 }
3205}
3206
3207void Sema::CodeCompleteObjCProtocolReferences(IdentifierLocPair *Protocols,
3208 unsigned NumProtocols) {
3209 ResultBuilder Results(*this);
3210 Results.EnterNewScope();
3211
3212 // Tell the result set to ignore all of the protocols we have
3213 // already seen.
3214 for (unsigned I = 0; I != NumProtocols; ++I)
Douglas Gregorc83c6872010-04-15 22:33:43 +00003215 if (ObjCProtocolDecl *Protocol = LookupProtocol(Protocols[I].first,
3216 Protocols[I].second))
Douglas Gregor55385fe2009-11-18 04:19:12 +00003217 Results.Ignore(Protocol);
3218
3219 // Add all protocols.
Douglas Gregor083128f2009-11-18 04:49:41 +00003220 AddProtocolResults(Context.getTranslationUnitDecl(), CurContext, false,
3221 Results);
3222
3223 Results.ExitScope();
3224 HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
3225}
3226
3227void Sema::CodeCompleteObjCProtocolDecl(Scope *) {
3228 ResultBuilder Results(*this);
3229 Results.EnterNewScope();
3230
3231 // Add all protocols.
3232 AddProtocolResults(Context.getTranslationUnitDecl(), CurContext, true,
3233 Results);
Douglas Gregor55385fe2009-11-18 04:19:12 +00003234
3235 Results.ExitScope();
3236 HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
3237}
Douglas Gregor3b49aca2009-11-18 16:26:39 +00003238
3239/// \brief Add all of the Objective-C interface declarations that we find in
3240/// the given (translation unit) context.
3241static void AddInterfaceResults(DeclContext *Ctx, DeclContext *CurContext,
3242 bool OnlyForwardDeclarations,
3243 bool OnlyUnimplemented,
3244 ResultBuilder &Results) {
3245 typedef CodeCompleteConsumer::Result Result;
3246
3247 for (DeclContext::decl_iterator D = Ctx->decls_begin(),
3248 DEnd = Ctx->decls_end();
3249 D != DEnd; ++D) {
3250 // Record any interfaces we find.
3251 if (ObjCInterfaceDecl *Class = dyn_cast<ObjCInterfaceDecl>(*D))
3252 if ((!OnlyForwardDeclarations || Class->isForwardDecl()) &&
3253 (!OnlyUnimplemented || !Class->getImplementation()))
Douglas Gregor608300b2010-01-14 16:14:35 +00003254 Results.AddResult(Result(Class, 0), CurContext, 0, false);
Douglas Gregor3b49aca2009-11-18 16:26:39 +00003255
3256 // Record any forward-declared interfaces we find.
3257 if (ObjCClassDecl *Forward = dyn_cast<ObjCClassDecl>(*D)) {
3258 for (ObjCClassDecl::iterator C = Forward->begin(), CEnd = Forward->end();
3259 C != CEnd; ++C)
3260 if ((!OnlyForwardDeclarations || C->getInterface()->isForwardDecl()) &&
3261 (!OnlyUnimplemented || !C->getInterface()->getImplementation()))
Douglas Gregor608300b2010-01-14 16:14:35 +00003262 Results.AddResult(Result(C->getInterface(), 0), CurContext,
3263 0, false);
Douglas Gregor3b49aca2009-11-18 16:26:39 +00003264 }
3265 }
3266}
3267
3268void Sema::CodeCompleteObjCInterfaceDecl(Scope *S) {
3269 ResultBuilder Results(*this);
3270 Results.EnterNewScope();
3271
3272 // Add all classes.
3273 AddInterfaceResults(Context.getTranslationUnitDecl(), CurContext, true,
3274 false, Results);
3275
3276 Results.ExitScope();
3277 HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
3278}
3279
Douglas Gregorc83c6872010-04-15 22:33:43 +00003280void Sema::CodeCompleteObjCSuperclass(Scope *S, IdentifierInfo *ClassName,
3281 SourceLocation ClassNameLoc) {
Douglas Gregor3b49aca2009-11-18 16:26:39 +00003282 ResultBuilder Results(*this);
3283 Results.EnterNewScope();
3284
3285 // Make sure that we ignore the class we're currently defining.
3286 NamedDecl *CurClass
Douglas Gregorc83c6872010-04-15 22:33:43 +00003287 = LookupSingleName(TUScope, ClassName, ClassNameLoc, LookupOrdinaryName);
Douglas Gregor33ced0b2009-11-18 19:08:43 +00003288 if (CurClass && isa<ObjCInterfaceDecl>(CurClass))
Douglas Gregor3b49aca2009-11-18 16:26:39 +00003289 Results.Ignore(CurClass);
3290
3291 // Add all classes.
3292 AddInterfaceResults(Context.getTranslationUnitDecl(), CurContext, false,
3293 false, Results);
3294
3295 Results.ExitScope();
3296 HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
3297}
3298
3299void Sema::CodeCompleteObjCImplementationDecl(Scope *S) {
3300 ResultBuilder Results(*this);
3301 Results.EnterNewScope();
3302
3303 // Add all unimplemented classes.
3304 AddInterfaceResults(Context.getTranslationUnitDecl(), CurContext, false,
3305 true, Results);
3306
3307 Results.ExitScope();
3308 HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
3309}
Douglas Gregor33ced0b2009-11-18 19:08:43 +00003310
3311void Sema::CodeCompleteObjCInterfaceCategory(Scope *S,
Douglas Gregorc83c6872010-04-15 22:33:43 +00003312 IdentifierInfo *ClassName,
3313 SourceLocation ClassNameLoc) {
Douglas Gregor33ced0b2009-11-18 19:08:43 +00003314 typedef CodeCompleteConsumer::Result Result;
3315
3316 ResultBuilder Results(*this);
3317
3318 // Ignore any categories we find that have already been implemented by this
3319 // interface.
3320 llvm::SmallPtrSet<IdentifierInfo *, 16> CategoryNames;
3321 NamedDecl *CurClass
Douglas Gregorc83c6872010-04-15 22:33:43 +00003322 = LookupSingleName(TUScope, ClassName, ClassNameLoc, LookupOrdinaryName);
Douglas Gregor33ced0b2009-11-18 19:08:43 +00003323 if (ObjCInterfaceDecl *Class = dyn_cast_or_null<ObjCInterfaceDecl>(CurClass))
3324 for (ObjCCategoryDecl *Category = Class->getCategoryList(); Category;
3325 Category = Category->getNextClassCategory())
3326 CategoryNames.insert(Category->getIdentifier());
3327
3328 // Add all of the categories we know about.
3329 Results.EnterNewScope();
3330 TranslationUnitDecl *TU = Context.getTranslationUnitDecl();
3331 for (DeclContext::decl_iterator D = TU->decls_begin(),
3332 DEnd = TU->decls_end();
3333 D != DEnd; ++D)
3334 if (ObjCCategoryDecl *Category = dyn_cast<ObjCCategoryDecl>(*D))
3335 if (CategoryNames.insert(Category->getIdentifier()))
Douglas Gregor608300b2010-01-14 16:14:35 +00003336 Results.AddResult(Result(Category, 0), CurContext, 0, false);
Douglas Gregor33ced0b2009-11-18 19:08:43 +00003337 Results.ExitScope();
3338
3339 HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
3340}
3341
3342void Sema::CodeCompleteObjCImplementationCategory(Scope *S,
Douglas Gregorc83c6872010-04-15 22:33:43 +00003343 IdentifierInfo *ClassName,
3344 SourceLocation ClassNameLoc) {
Douglas Gregor33ced0b2009-11-18 19:08:43 +00003345 typedef CodeCompleteConsumer::Result Result;
3346
3347 // Find the corresponding interface. If we couldn't find the interface, the
3348 // program itself is ill-formed. However, we'll try to be helpful still by
3349 // providing the list of all of the categories we know about.
3350 NamedDecl *CurClass
Douglas Gregorc83c6872010-04-15 22:33:43 +00003351 = LookupSingleName(TUScope, ClassName, ClassNameLoc, LookupOrdinaryName);
Douglas Gregor33ced0b2009-11-18 19:08:43 +00003352 ObjCInterfaceDecl *Class = dyn_cast_or_null<ObjCInterfaceDecl>(CurClass);
3353 if (!Class)
Douglas Gregorc83c6872010-04-15 22:33:43 +00003354 return CodeCompleteObjCInterfaceCategory(S, ClassName, ClassNameLoc);
Douglas Gregor33ced0b2009-11-18 19:08:43 +00003355
3356 ResultBuilder Results(*this);
3357
3358 // Add all of the categories that have have corresponding interface
3359 // declarations in this class and any of its superclasses, except for
3360 // already-implemented categories in the class itself.
3361 llvm::SmallPtrSet<IdentifierInfo *, 16> CategoryNames;
3362 Results.EnterNewScope();
3363 bool IgnoreImplemented = true;
3364 while (Class) {
3365 for (ObjCCategoryDecl *Category = Class->getCategoryList(); Category;
3366 Category = Category->getNextClassCategory())
3367 if ((!IgnoreImplemented || !Category->getImplementation()) &&
3368 CategoryNames.insert(Category->getIdentifier()))
Douglas Gregor608300b2010-01-14 16:14:35 +00003369 Results.AddResult(Result(Category, 0), CurContext, 0, false);
Douglas Gregor33ced0b2009-11-18 19:08:43 +00003370
3371 Class = Class->getSuperClass();
3372 IgnoreImplemented = false;
3373 }
3374 Results.ExitScope();
3375
3376 HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
3377}
Douglas Gregor322328b2009-11-18 22:32:06 +00003378
Douglas Gregor424b2a52009-11-18 22:56:13 +00003379void Sema::CodeCompleteObjCPropertyDefinition(Scope *S, DeclPtrTy ObjCImpDecl) {
Douglas Gregor322328b2009-11-18 22:32:06 +00003380 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 // Ignore any properties that have already been implemented.
3392 for (DeclContext::decl_iterator D = Container->decls_begin(),
3393 DEnd = Container->decls_end();
3394 D != DEnd; ++D)
3395 if (ObjCPropertyImplDecl *PropertyImpl = dyn_cast<ObjCPropertyImplDecl>(*D))
3396 Results.Ignore(PropertyImpl->getPropertyDecl());
3397
3398 // Add any properties that we find.
3399 Results.EnterNewScope();
3400 if (ObjCImplementationDecl *ClassImpl
3401 = dyn_cast<ObjCImplementationDecl>(Container))
3402 AddObjCProperties(ClassImpl->getClassInterface(), false, CurContext,
3403 Results);
3404 else
3405 AddObjCProperties(cast<ObjCCategoryImplDecl>(Container)->getCategoryDecl(),
3406 false, CurContext, Results);
3407 Results.ExitScope();
3408
3409 HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
3410}
3411
3412void Sema::CodeCompleteObjCPropertySynthesizeIvar(Scope *S,
3413 IdentifierInfo *PropertyName,
3414 DeclPtrTy ObjCImpDecl) {
3415 typedef CodeCompleteConsumer::Result Result;
3416 ResultBuilder Results(*this);
3417
3418 // Figure out where this @synthesize lives.
3419 ObjCContainerDecl *Container
3420 = dyn_cast_or_null<ObjCContainerDecl>(ObjCImpDecl.getAs<Decl>());
3421 if (!Container ||
3422 (!isa<ObjCImplementationDecl>(Container) &&
3423 !isa<ObjCCategoryImplDecl>(Container)))
3424 return;
3425
3426 // Figure out which interface we're looking into.
3427 ObjCInterfaceDecl *Class = 0;
3428 if (ObjCImplementationDecl *ClassImpl
3429 = dyn_cast<ObjCImplementationDecl>(Container))
3430 Class = ClassImpl->getClassInterface();
3431 else
3432 Class = cast<ObjCCategoryImplDecl>(Container)->getCategoryDecl()
3433 ->getClassInterface();
3434
3435 // Add all of the instance variables in this class and its superclasses.
3436 Results.EnterNewScope();
3437 for(; Class; Class = Class->getSuperClass()) {
3438 // FIXME: We could screen the type of each ivar for compatibility with
3439 // the property, but is that being too paternal?
3440 for (ObjCInterfaceDecl::ivar_iterator IVar = Class->ivar_begin(),
3441 IVarEnd = Class->ivar_end();
3442 IVar != IVarEnd; ++IVar)
Douglas Gregor608300b2010-01-14 16:14:35 +00003443 Results.AddResult(Result(*IVar, 0), CurContext, 0, false);
Douglas Gregor322328b2009-11-18 22:32:06 +00003444 }
3445 Results.ExitScope();
3446
3447 HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
3448}
Douglas Gregore8f5a172010-04-07 00:21:17 +00003449
3450typedef llvm::DenseMap<Selector, ObjCMethodDecl *> KnownMethodsMap;
3451
3452/// \brief Find all of the methods that reside in the given container
3453/// (and its superclasses, protocols, etc.) that meet the given
3454/// criteria. Insert those methods into the map of known methods,
3455/// indexed by selector so they can be easily found.
3456static void FindImplementableMethods(ASTContext &Context,
3457 ObjCContainerDecl *Container,
3458 bool WantInstanceMethods,
3459 QualType ReturnType,
3460 bool IsInImplementation,
3461 KnownMethodsMap &KnownMethods) {
3462 if (ObjCInterfaceDecl *IFace = dyn_cast<ObjCInterfaceDecl>(Container)) {
3463 // Recurse into protocols.
3464 const ObjCList<ObjCProtocolDecl> &Protocols
3465 = IFace->getReferencedProtocols();
3466 for (ObjCList<ObjCProtocolDecl>::iterator I = Protocols.begin(),
3467 E = Protocols.end();
3468 I != E; ++I)
3469 FindImplementableMethods(Context, *I, WantInstanceMethods, ReturnType,
3470 IsInImplementation, KnownMethods);
3471
3472 // If we're not in the implementation of a class, also visit the
3473 // superclass.
3474 if (!IsInImplementation && IFace->getSuperClass())
3475 FindImplementableMethods(Context, IFace->getSuperClass(),
3476 WantInstanceMethods, ReturnType,
3477 IsInImplementation, KnownMethods);
3478
3479 // Add methods from any class extensions (but not from categories;
3480 // those should go into category implementations).
3481 for (ObjCCategoryDecl *Cat = IFace->getCategoryList(); Cat;
3482 Cat = Cat->getNextClassCategory()) {
3483 if (!Cat->IsClassExtension())
3484 continue;
3485
3486 FindImplementableMethods(Context, Cat, WantInstanceMethods, ReturnType,
3487 IsInImplementation, KnownMethods);
3488 }
3489 }
3490
3491 if (ObjCCategoryDecl *Category = dyn_cast<ObjCCategoryDecl>(Container)) {
3492 // Recurse into protocols.
3493 const ObjCList<ObjCProtocolDecl> &Protocols
3494 = Category->getReferencedProtocols();
3495 for (ObjCList<ObjCProtocolDecl>::iterator I = Protocols.begin(),
3496 E = Protocols.end();
3497 I != E; ++I)
3498 FindImplementableMethods(Context, *I, WantInstanceMethods, ReturnType,
3499 IsInImplementation, KnownMethods);
3500 }
3501
3502 if (ObjCProtocolDecl *Protocol = dyn_cast<ObjCProtocolDecl>(Container)) {
3503 // Recurse into protocols.
3504 const ObjCList<ObjCProtocolDecl> &Protocols
3505 = Protocol->getReferencedProtocols();
3506 for (ObjCList<ObjCProtocolDecl>::iterator I = Protocols.begin(),
3507 E = Protocols.end();
3508 I != E; ++I)
3509 FindImplementableMethods(Context, *I, WantInstanceMethods, ReturnType,
3510 IsInImplementation, KnownMethods);
3511 }
3512
3513 // Add methods in this container. This operation occurs last because
3514 // we want the methods from this container to override any methods
3515 // we've previously seen with the same selector.
3516 for (ObjCContainerDecl::method_iterator M = Container->meth_begin(),
3517 MEnd = Container->meth_end();
3518 M != MEnd; ++M) {
3519 if ((*M)->isInstanceMethod() == WantInstanceMethods) {
3520 if (!ReturnType.isNull() &&
3521 !Context.hasSameUnqualifiedType(ReturnType, (*M)->getResultType()))
3522 continue;
3523
3524 KnownMethods[(*M)->getSelector()] = *M;
3525 }
3526 }
3527}
3528
3529void Sema::CodeCompleteObjCMethodDecl(Scope *S,
3530 bool IsInstanceMethod,
3531 TypeTy *ReturnTy,
3532 DeclPtrTy IDecl) {
3533 // Determine the return type of the method we're declaring, if
3534 // provided.
3535 QualType ReturnType = GetTypeFromParser(ReturnTy);
3536
3537 // Determine where we should start searching for methods, and where we
3538 ObjCContainerDecl *SearchDecl = 0, *CurrentDecl = 0;
3539 bool IsInImplementation = false;
3540 if (Decl *D = IDecl.getAs<Decl>()) {
3541 if (ObjCImplementationDecl *Impl = dyn_cast<ObjCImplementationDecl>(D)) {
3542 SearchDecl = Impl->getClassInterface();
3543 CurrentDecl = Impl;
3544 IsInImplementation = true;
3545 } else if (ObjCCategoryImplDecl *CatImpl
3546 = dyn_cast<ObjCCategoryImplDecl>(D)) {
3547 SearchDecl = CatImpl->getCategoryDecl();
3548 CurrentDecl = CatImpl;
3549 IsInImplementation = true;
3550 } else {
3551 SearchDecl = dyn_cast<ObjCContainerDecl>(D);
3552 CurrentDecl = SearchDecl;
3553 }
3554 }
3555
3556 if (!SearchDecl && S) {
3557 if (DeclContext *DC = static_cast<DeclContext *>(S->getEntity())) {
3558 SearchDecl = dyn_cast<ObjCContainerDecl>(DC);
3559 CurrentDecl = SearchDecl;
3560 }
3561 }
3562
3563 if (!SearchDecl || !CurrentDecl) {
3564 HandleCodeCompleteResults(this, CodeCompleter, 0, 0);
3565 return;
3566 }
3567
3568 // Find all of the methods that we could declare/implement here.
3569 KnownMethodsMap KnownMethods;
3570 FindImplementableMethods(Context, SearchDecl, IsInstanceMethod,
3571 ReturnType, IsInImplementation, KnownMethods);
3572
3573 // Erase any methods that have already been declared or
3574 // implemented here.
3575 for (ObjCContainerDecl::method_iterator M = CurrentDecl->meth_begin(),
3576 MEnd = CurrentDecl->meth_end();
3577 M != MEnd; ++M) {
3578 if ((*M)->isInstanceMethod() != IsInstanceMethod)
3579 continue;
3580
3581 KnownMethodsMap::iterator Pos = KnownMethods.find((*M)->getSelector());
3582 if (Pos != KnownMethods.end())
3583 KnownMethods.erase(Pos);
3584 }
3585
3586 // Add declarations or definitions for each of the known methods.
3587 typedef CodeCompleteConsumer::Result Result;
3588 ResultBuilder Results(*this);
3589 Results.EnterNewScope();
3590 PrintingPolicy Policy(Context.PrintingPolicy);
3591 Policy.AnonymousTagLocations = false;
3592 for (KnownMethodsMap::iterator M = KnownMethods.begin(),
3593 MEnd = KnownMethods.end();
3594 M != MEnd; ++M) {
3595 ObjCMethodDecl *Method = M->second;
3596 CodeCompletionString *Pattern = new CodeCompletionString;
3597
3598 // If the result type was not already provided, add it to the
3599 // pattern as (type).
3600 if (ReturnType.isNull()) {
3601 std::string TypeStr;
3602 Method->getResultType().getAsStringInternal(TypeStr, Policy);
3603 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
3604 Pattern->AddTextChunk(TypeStr);
3605 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
3606 }
3607
3608 Selector Sel = Method->getSelector();
3609
3610 // Add the first part of the selector to the pattern.
3611 Pattern->AddTypedTextChunk(Sel.getIdentifierInfoForSlot(0)->getName());
3612
3613 // Add parameters to the pattern.
3614 unsigned I = 0;
3615 for (ObjCMethodDecl::param_iterator P = Method->param_begin(),
3616 PEnd = Method->param_end();
3617 P != PEnd; (void)++P, ++I) {
3618 // Add the part of the selector name.
3619 if (I == 0)
3620 Pattern->AddChunk(CodeCompletionString::CK_Colon);
3621 else if (I < Sel.getNumArgs()) {
3622 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
3623 Pattern->AddTextChunk(Sel.getIdentifierInfoForSlot(1)->getName());
3624 Pattern->AddChunk(CodeCompletionString::CK_Colon);
3625 } else
3626 break;
3627
3628 // Add the parameter type.
3629 std::string TypeStr;
3630 (*P)->getOriginalType().getAsStringInternal(TypeStr, Policy);
3631 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
3632 Pattern->AddTextChunk(TypeStr);
3633 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
3634
3635 if (IdentifierInfo *Id = (*P)->getIdentifier())
3636 Pattern->AddTextChunk(Id->getName());
3637 }
3638
3639 if (Method->isVariadic()) {
3640 if (Method->param_size() > 0)
3641 Pattern->AddChunk(CodeCompletionString::CK_Comma);
3642 Pattern->AddTextChunk("...");
3643 }
3644
3645 if (IsInImplementation) {
3646 // We will be defining the method here, so add a compound statement.
3647 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
3648 Pattern->AddChunk(CodeCompletionString::CK_LeftBrace);
3649 Pattern->AddChunk(CodeCompletionString::CK_VerticalSpace);
3650 if (!Method->getResultType()->isVoidType()) {
3651 // If the result type is not void, add a return clause.
3652 Pattern->AddTextChunk("return");
3653 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
3654 Pattern->AddPlaceholderChunk("expression");
3655 Pattern->AddChunk(CodeCompletionString::CK_SemiColon);
3656 } else
3657 Pattern->AddPlaceholderChunk("statements");
3658
3659 Pattern->AddChunk(CodeCompletionString::CK_VerticalSpace);
3660 Pattern->AddChunk(CodeCompletionString::CK_RightBrace);
3661 }
3662
3663 Results.AddResult(Result(Pattern));
3664 }
3665
3666 Results.ExitScope();
3667
3668 HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
3669}