blob: 20621fdb6bc27c1146f5cc861ba65a56c92217fe [file] [log] [blame]
Douglas Gregor2436e712009-09-17 21:32:03 +00001//===---------------- SemaCodeComplete.cpp - Code Completion ----*- C++ -*-===//
2//
3// The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9//
10// This file defines the code-completion semantic actions.
11//
12//===----------------------------------------------------------------------===//
13#include "Sema.h"
Douglas Gregorc580c522010-01-14 01:09:38 +000014#include "Lookup.h"
Douglas Gregor2436e712009-09-17 21:32:03 +000015#include "clang/Sema/CodeCompleteConsumer.h"
Douglas Gregord720daf2010-04-06 17:30:22 +000016#include "clang/Sema/ExternalSemaSource.h"
Douglas Gregorf2510672009-09-21 19:57:38 +000017#include "clang/AST/ExprCXX.h"
Douglas Gregor8ce33212009-11-17 17:59:40 +000018#include "clang/AST/ExprObjC.h"
Douglas Gregorf329c7c2009-10-30 16:50:04 +000019#include "clang/Lex/MacroInfo.h"
20#include "clang/Lex/Preprocessor.h"
Douglas Gregor3545ff42009-09-21 16:56:56 +000021#include "llvm/ADT/SmallPtrSet.h"
Douglas Gregore6688e62009-09-28 03:51:44 +000022#include "llvm/ADT/StringExtras.h"
Douglas Gregor9d2ddb22010-04-06 19:22:33 +000023#include "llvm/ADT/StringSwitch.h"
Douglas Gregor3545ff42009-09-21 16:56:56 +000024#include <list>
25#include <map>
26#include <vector>
Douglas Gregor2436e712009-09-17 21:32:03 +000027
28using namespace clang;
29
Douglas Gregor3545ff42009-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 Gregor05e7ca32009-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 Gregor3545ff42009-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 Gregor05e7ca32009-12-06 20:23:50 +0000108 typedef llvm::DenseMap<DeclarationName, ShadowMapEntry> ShadowMap;
Douglas Gregor3545ff42009-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 Gregor6ae4c522010-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 Gregor3545ff42009-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 Gregor6ae4c522010-01-14 03:21:49 +0000128 : SemaRef(SemaRef), Filter(Filter), AllowNestedNameSpecifiers(false) { }
Douglas Gregor3545ff42009-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 Gregor6ae4c522010-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 Gregor7c208612010-01-14 00:20:49 +0000148 /// \brief Determine whether the given declaration is at all interesting
149 /// as a code-completion result.
Douglas Gregor6ae4c522010-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 Gregore0717ab2010-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 Gregor3545ff42009-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 Gregor2af2f672009-09-21 20:12:40 +0000169 ///
Douglas Gregorc580c522010-01-14 01:09:38 +0000170 /// \param CurContext the result to add (if it is unique).
Douglas Gregor2af2f672009-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 Gregor3545ff42009-09-21 16:56:56 +0000174
Douglas Gregorc580c522010-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 Gregor09bbc652010-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 Gregorc580c522010-01-14 01:09:38 +0000188
Douglas Gregor78a21012010-01-14 16:01:26 +0000189 /// \brief Add a new non-declaration result to this result set.
190 void AddResult(Result R);
191
Douglas Gregor3545ff42009-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 Gregorbaf69612009-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 Gregor3545ff42009-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 Gregor9d64c5e2009-09-21 20:51:25 +0000207 bool IsOrdinaryName(NamedDecl *ND) const;
Douglas Gregor504a6ae2010-01-10 23:08:15 +0000208 bool IsOrdinaryNonValueName(NamedDecl *ND) const;
Douglas Gregor3545ff42009-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 Gregore412a5a2009-09-23 22:26:46 +0000216 bool IsMember(NamedDecl *ND) const;
Douglas Gregor2b8162b2010-01-14 16:08:12 +0000217 bool IsObjCIvar(NamedDecl *ND) const;
Douglas Gregor3545ff42009-09-21 16:56:56 +0000218 //@}
219 };
220}
221
Douglas Gregor05e7ca32009-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 Gregor94bb5e82009-12-06 21:27:58 +0000274 return *DeclOrIterator.get<const DeclIndexPair*>();
Douglas Gregor05e7ca32009-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 Gregor94bb5e82009-12-06 21:27:58 +0000282 return X.DeclOrIterator.getOpaqueValue()
283 == Y.DeclOrIterator.getOpaqueValue() &&
Douglas Gregor05e7ca32009-12-06 20:23:50 +0000284 X.SingleDeclIndex == Y.SingleDeclIndex;
285 }
286
287 friend bool operator!=(const iterator &X, const iterator &Y) {
Douglas Gregor94bb5e82009-12-06 21:27:58 +0000288 return !(X == Y);
Douglas Gregor05e7ca32009-12-06 20:23:50 +0000289 }
290};
291
Douglas Gregor05e7ca32009-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 Gregor2af2f672009-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 Gregor9eb77012009-11-07 00:00:49 +0000353 }
Douglas Gregor2af2f672009-09-21 20:12:40 +0000354 return Result;
355}
356
Douglas Gregor6ae4c522010-01-14 03:21:49 +0000357bool ResultBuilder::isInterestingDecl(NamedDecl *ND,
358 bool &AsNestedNameSpecifier) const {
359 AsNestedNameSpecifier = false;
360
Douglas Gregor7c208612010-01-14 00:20:49 +0000361 ND = ND->getUnderlyingDecl();
362 unsigned IDNS = ND->getIdentifierNamespace();
Douglas Gregor58acf322009-10-09 22:16:47 +0000363
364 // Skip unnamed entities.
Douglas Gregor7c208612010-01-14 00:20:49 +0000365 if (!ND->getDeclName())
366 return false;
Douglas Gregor3545ff42009-09-21 16:56:56 +0000367
368 // Friend declarations and declarations introduced due to friends are never
369 // added as results.
John McCallbbbbe4e2010-03-11 07:50:04 +0000370 if (IDNS & (Decl::IDNS_OrdinaryFriend | Decl::IDNS_TagFriend))
Douglas Gregor7c208612010-01-14 00:20:49 +0000371 return false;
372
Douglas Gregor99fe2ad2009-12-11 17:31:05 +0000373 // Class template (partial) specializations are never added as results.
Douglas Gregor7c208612010-01-14 00:20:49 +0000374 if (isa<ClassTemplateSpecializationDecl>(ND) ||
375 isa<ClassTemplatePartialSpecializationDecl>(ND))
376 return false;
Douglas Gregor3545ff42009-09-21 16:56:56 +0000377
Douglas Gregor99fe2ad2009-12-11 17:31:05 +0000378 // Using declarations themselves are never added as results.
Douglas Gregor7c208612010-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 Gregor3545ff42009-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 Gregor7c208612010-01-14 00:20:49 +0000386 return false;
Douglas Gregor3545ff42009-09-21 16:56:56 +0000387
Douglas Gregor58acf322009-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 Dunbar2c422dc92009-10-18 20:26:12 +0000390 //
391 // FIXME: Add predicate for this.
Douglas Gregor58acf322009-10-09 22:16:47 +0000392 if (Id->getLength() >= 2) {
Daniel Dunbar2c422dc92009-10-18 20:26:12 +0000393 const char *Name = Id->getNameStart();
Douglas Gregor58acf322009-10-09 22:16:47 +0000394 if (Name[0] == '_' &&
395 (Name[1] == '_' || (Name[1] >= 'A' && Name[1] <= 'Z')))
Douglas Gregor7c208612010-01-14 00:20:49 +0000396 return false;
Douglas Gregor58acf322009-10-09 22:16:47 +0000397 }
Douglas Gregor3545ff42009-09-21 16:56:56 +0000398 }
Douglas Gregor7c208612010-01-14 00:20:49 +0000399
Douglas Gregor3545ff42009-09-21 16:56:56 +0000400 // C++ constructors are never found by name lookup.
Douglas Gregor7c208612010-01-14 00:20:49 +0000401 if (isa<CXXConstructorDecl>(ND))
402 return false;
Douglas Gregor3545ff42009-09-21 16:56:56 +0000403
404 // Filter out any unwanted results.
Douglas Gregor6ae4c522010-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 Gregor7c208612010-01-14 00:20:49 +0000416 return false;
Douglas Gregor6ae4c522010-01-14 03:21:49 +0000417 }
Douglas Gregor3545ff42009-09-21 16:56:56 +0000418
Douglas Gregor7c208612010-01-14 00:20:49 +0000419 // ... then it must be interesting!
420 return true;
421}
422
Douglas Gregore0717ab2010-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 Gregor7c208612010-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 Gregor6ae4c522010-01-14 03:21:49 +0000469 bool AsNestedNameSpecifier = false;
470 if (!isInterestingDecl(R.Declaration, AsNestedNameSpecifier))
Douglas Gregor7c208612010-01-14 00:20:49 +0000471 return;
472
Douglas Gregor3545ff42009-09-21 16:56:56 +0000473 ShadowMap &SMap = ShadowMaps.back();
Douglas Gregor05e7ca32009-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 Gregor3545ff42009-09-21 16:56:56 +0000484 if (ND->getCanonicalDecl() == CanonDecl) {
485 // This is a redeclaration. Always pick the newer declaration.
Douglas Gregor3545ff42009-09-21 16:56:56 +0000486 Results[Index].Declaration = R.Declaration;
487
Douglas Gregor3545ff42009-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 Gregor05e7ca32009-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 Gregor3545ff42009-09-21 16:56:56 +0000506 // A tag declaration does not hide a non-tag declaration.
Douglas Gregor05e7ca32009-12-06 20:23:50 +0000507 if (I->first->getIdentifierNamespace() == Decl::IDNS_Tag &&
Douglas Gregor3545ff42009-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 Gregor05e7ca32009-12-06 20:23:50 +0000513 if (((I->first->getIdentifierNamespace() & Decl::IDNS_ObjCProtocol)
Douglas Gregor3545ff42009-09-21 16:56:56 +0000514 || (IDNS & Decl::IDNS_ObjCProtocol)) &&
Douglas Gregor05e7ca32009-12-06 20:23:50 +0000515 I->first->getIdentifierNamespace() != IDNS)
Douglas Gregor3545ff42009-09-21 16:56:56 +0000516 continue;
517
518 // The newly-added result is hidden by an entry in the shadow map.
Douglas Gregore0717ab2010-01-14 00:41:07 +0000519 if (CheckHiddenResult(R, CurContext, I->first))
Douglas Gregor3545ff42009-09-21 16:56:56 +0000520 return;
Douglas Gregor3545ff42009-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 Gregore412a5a2009-09-23 22:26:46 +0000530 // If the filter is for nested-name-specifiers, then this result starts a
531 // nested-name-specifier.
Douglas Gregor6ae4c522010-01-14 03:21:49 +0000532 if (AsNestedNameSpecifier)
Douglas Gregore412a5a2009-09-23 22:26:46 +0000533 R.StartsNestedNameSpecifier = true;
534
Douglas Gregor5bf52692009-09-22 23:15:58 +0000535 // If this result is supposed to have an informative qualifier, add one.
Douglas Gregore412a5a2009-09-23 22:26:46 +0000536 if (R.QualifierIsInformative && !R.Qualifier &&
537 !R.StartsNestedNameSpecifier) {
Douglas Gregor5bf52692009-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 Gregore412a5a2009-09-23 22:26:46 +0000547
Douglas Gregor3545ff42009-09-21 16:56:56 +0000548 // Insert this result into the set of results and into the current shadow
549 // map.
Douglas Gregor05e7ca32009-12-06 20:23:50 +0000550 SMap[R.Declaration->getDeclName()].Add(R.Declaration, Results.size());
Douglas Gregor3545ff42009-09-21 16:56:56 +0000551 Results.push_back(R);
552}
553
Douglas Gregorc580c522010-01-14 01:09:38 +0000554void ResultBuilder::AddResult(Result R, DeclContext *CurContext,
Douglas Gregor09bbc652010-01-14 15:47:35 +0000555 NamedDecl *Hiding, bool InBaseClass = false) {
Douglas Gregor78a21012010-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 Gregorc580c522010-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 Gregor6ae4c522010-01-14 03:21:49 +0000568 bool AsNestedNameSpecifier = false;
569 if (!isInterestingDecl(R.Declaration, AsNestedNameSpecifier))
Douglas Gregorc580c522010-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 Gregor6ae4c522010-01-14 03:21:49 +0000581 if (AsNestedNameSpecifier)
Douglas Gregorc580c522010-01-14 01:09:38 +0000582 R.StartsNestedNameSpecifier = true;
Douglas Gregor09bbc652010-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 Gregorc580c522010-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 Gregor6ae4c522010-01-14 03:21:49 +0000596 SemaRef.Context.getTypeDeclType(Tag).getTypePtr());
Douglas Gregorc580c522010-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 Gregor78a21012010-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 Gregor3545ff42009-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 Gregor05e7ca32009-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 Gregor3545ff42009-09-21 16:56:56 +0000624 ShadowMaps.pop_back();
625}
626
Douglas Gregor9d64c5e2009-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 Gregorc580c522010-01-14 01:09:38 +0000633 else if (SemaRef.getLangOptions().ObjC1 && isa<ObjCIvarDecl>(ND))
634 return true;
635
Douglas Gregor9d64c5e2009-09-21 20:51:25 +0000636 return ND->getIdentifierNamespace() & IDNS;
637}
638
Douglas Gregor504a6ae2010-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 Gregor3545ff42009-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 Gregor99fe2ad2009-12-11 17:31:05 +0000701/// \brief Determines whether the given declaration is a type.
Douglas Gregor3545ff42009-09-21 16:56:56 +0000702bool ResultBuilder::IsType(NamedDecl *ND) const {
703 return isa<TypeDecl>(ND);
704}
705
Douglas Gregor99fe2ad2009-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 Gregore412a5a2009-09-23 22:26:46 +0000709bool ResultBuilder::IsMember(NamedDecl *ND) const {
Douglas Gregor99fe2ad2009-12-11 17:31:05 +0000710 if (UsingShadowDecl *Using = dyn_cast<UsingShadowDecl>(ND))
711 ND = Using->getTargetDecl();
712
Douglas Gregor70788392009-12-11 18:14:22 +0000713 return isa<ValueDecl>(ND) || isa<FunctionTemplateDecl>(ND) ||
714 isa<ObjCPropertyDecl>(ND);
Douglas Gregore412a5a2009-09-23 22:26:46 +0000715}
716
Douglas Gregor2b8162b2010-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 Gregorc580c522010-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 Gregor09bbc652010-01-14 15:47:35 +0000734 virtual void FoundDecl(NamedDecl *ND, NamedDecl *Hiding, bool InBaseClass) {
735 Results.AddResult(ND, CurContext, Hiding, InBaseClass);
Douglas Gregorc580c522010-01-14 01:09:38 +0000736 }
737 };
738}
739
Douglas Gregor3545ff42009-09-21 16:56:56 +0000740/// \brief Add type specifiers for the current language as keyword results.
Douglas Gregorf98e6a22010-01-13 23:51:12 +0000741static void AddTypeSpecifierResults(const LangOptions &LangOpts,
Douglas Gregor3545ff42009-09-21 16:56:56 +0000742 ResultBuilder &Results) {
743 typedef CodeCompleteConsumer::Result Result;
Douglas Gregor78a21012010-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 Gregor504a6ae2010-01-10 23:08:15 +0000758
Douglas Gregor3545ff42009-09-21 16:56:56 +0000759 if (LangOpts.C99) {
760 // C99-specific
Douglas Gregor78a21012010-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 Gregor3545ff42009-09-21 16:56:56 +0000765 }
766
767 if (LangOpts.CPlusPlus) {
768 // C++-specific
Douglas Gregor78a21012010-01-14 16:01:26 +0000769 Results.AddResult(Result("bool"));
770 Results.AddResult(Result("class"));
771 Results.AddResult(Result("wchar_t"));
Douglas Gregor3545ff42009-09-21 16:56:56 +0000772
Douglas Gregor504a6ae2010-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 Gregor78a21012010-01-14 16:01:26 +0000778 Results.AddResult(Result(Pattern));
Douglas Gregor504a6ae2010-01-10 23:08:15 +0000779
Douglas Gregor3545ff42009-09-21 16:56:56 +0000780 if (LangOpts.CPlusPlus0x) {
Douglas Gregor78a21012010-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 Gregor3545ff42009-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 Gregor78a21012010-01-14 16:01:26 +0000791 // Results.AddResult(Result("_Decimal32"));
792 // Results.AddResult(Result("_Decimal64"));
793 // Results.AddResult(Result("_Decimal128"));
Douglas Gregor504a6ae2010-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 Gregor78a21012010-01-14 16:01:26 +0000800 Results.AddResult(Result(Pattern));
Douglas Gregor3545ff42009-09-21 16:56:56 +0000801 }
802}
803
Douglas Gregor504a6ae2010-01-10 23:08:15 +0000804static void AddStorageSpecifiers(Action::CodeCompletionContext CCC,
805 const LangOptions &LangOpts,
Douglas Gregor504a6ae2010-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 Gregor78a21012010-01-14 16:01:26 +0000811 Results.AddResult(Result("extern"));
812 Results.AddResult(Result("static"));
Douglas Gregor504a6ae2010-01-10 23:08:15 +0000813}
814
815static void AddFunctionSpecifiers(Action::CodeCompletionContext CCC,
816 const LangOptions &LangOpts,
Douglas Gregor504a6ae2010-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 Gregor78a21012010-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 Gregor504a6ae2010-01-10 23:08:15 +0000827 }
828 // Fall through
829
Douglas Gregorf1934162010-01-13 21:24:21 +0000830 case Action::CCC_ObjCInterface:
831 case Action::CCC_ObjCImplementation:
Douglas Gregor504a6ae2010-01-10 23:08:15 +0000832 case Action::CCC_Namespace:
833 case Action::CCC_Template:
834 if (LangOpts.CPlusPlus || LangOpts.C99)
Douglas Gregor78a21012010-01-14 16:01:26 +0000835 Results.AddResult(Result("inline"));
Douglas Gregor504a6ae2010-01-10 23:08:15 +0000836 break;
837
Douglas Gregor48d46252010-01-13 21:54:15 +0000838 case Action::CCC_ObjCInstanceVariableList:
Douglas Gregor504a6ae2010-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 Gregorf98e6a22010-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 Gregor48d46252010-01-13 21:54:15 +0000850 ResultBuilder &Results,
851 bool NeedAt);
Douglas Gregorf98e6a22010-01-13 23:51:12 +0000852static void AddObjCImplementationResults(const LangOptions &LangOpts,
Douglas Gregorf1934162010-01-13 21:24:21 +0000853 ResultBuilder &Results,
854 bool NeedAt);
Douglas Gregorf98e6a22010-01-13 23:51:12 +0000855static void AddObjCInterfaceResults(const LangOptions &LangOpts,
Douglas Gregorf1934162010-01-13 21:24:21 +0000856 ResultBuilder &Results,
857 bool NeedAt);
Douglas Gregorf98e6a22010-01-13 23:51:12 +0000858static void AddObjCTopLevelResults(ResultBuilder &Results, bool NeedAt);
Douglas Gregorf1934162010-01-13 21:24:21 +0000859
Douglas Gregor504a6ae2010-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 Gregor504a6ae2010-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 Gregor78a21012010-01-14 16:01:26 +0000878 Results.AddResult(Result(Pattern));
Douglas Gregor504a6ae2010-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");
887 Pattern->AddChunk(CodeCompletionString::CK_SemiColon);
Douglas Gregor78a21012010-01-14 16:01:26 +0000888 Results.AddResult(Result(Pattern));
Douglas Gregor504a6ae2010-01-10 23:08:15 +0000889
890 // Using directives
891 Pattern = new CodeCompletionString;
892 Pattern->AddTypedTextChunk("using");
893 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
894 Pattern->AddTextChunk("namespace");
895 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
896 Pattern->AddPlaceholderChunk("identifier");
897 Pattern->AddChunk(CodeCompletionString::CK_SemiColon);
Douglas Gregor78a21012010-01-14 16:01:26 +0000898 Results.AddResult(Result(Pattern));
Douglas Gregor504a6ae2010-01-10 23:08:15 +0000899
900 // asm(string-literal)
901 Pattern = new CodeCompletionString;
902 Pattern->AddTypedTextChunk("asm");
903 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
904 Pattern->AddPlaceholderChunk("string-literal");
905 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
906 Pattern->AddChunk(CodeCompletionString::CK_SemiColon);
Douglas Gregor78a21012010-01-14 16:01:26 +0000907 Results.AddResult(Result(Pattern));
Douglas Gregor504a6ae2010-01-10 23:08:15 +0000908
909 // Explicit template instantiation
910 Pattern = new CodeCompletionString;
911 Pattern->AddTypedTextChunk("template");
912 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
913 Pattern->AddPlaceholderChunk("declaration");
914 Pattern->AddChunk(CodeCompletionString::CK_SemiColon);
Douglas Gregor78a21012010-01-14 16:01:26 +0000915 Results.AddResult(Result(Pattern));
Douglas Gregor504a6ae2010-01-10 23:08:15 +0000916 }
Douglas Gregorf1934162010-01-13 21:24:21 +0000917
918 if (SemaRef.getLangOptions().ObjC1)
Douglas Gregorf98e6a22010-01-13 23:51:12 +0000919 AddObjCTopLevelResults(Results, true);
Douglas Gregorf1934162010-01-13 21:24:21 +0000920
Douglas Gregor504a6ae2010-01-10 23:08:15 +0000921 // Fall through
922
923 case Action::CCC_Class:
Douglas Gregor78a21012010-01-14 16:01:26 +0000924 Results.AddResult(Result("typedef"));
Douglas Gregor504a6ae2010-01-10 23:08:15 +0000925 if (SemaRef.getLangOptions().CPlusPlus) {
926 // Using declaration
927 CodeCompletionString *Pattern = new CodeCompletionString;
928 Pattern->AddTypedTextChunk("using");
929 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
930 Pattern->AddPlaceholderChunk("qualified-id");
931 Pattern->AddChunk(CodeCompletionString::CK_SemiColon);
Douglas Gregor78a21012010-01-14 16:01:26 +0000932 Results.AddResult(Result(Pattern));
Douglas Gregor504a6ae2010-01-10 23:08:15 +0000933
934 // using typename qualified-id; (only in a dependent context)
935 if (SemaRef.CurContext->isDependentContext()) {
936 Pattern = new CodeCompletionString;
937 Pattern->AddTypedTextChunk("using");
938 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
939 Pattern->AddTextChunk("typename");
940 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
941 Pattern->AddPlaceholderChunk("qualified-id");
942 Pattern->AddChunk(CodeCompletionString::CK_SemiColon);
Douglas Gregor78a21012010-01-14 16:01:26 +0000943 Results.AddResult(Result(Pattern));
Douglas Gregor504a6ae2010-01-10 23:08:15 +0000944 }
945
946 if (CCC == Action::CCC_Class) {
947 // public:
948 Pattern = new CodeCompletionString;
949 Pattern->AddTypedTextChunk("public");
950 Pattern->AddChunk(CodeCompletionString::CK_Colon);
Douglas Gregor78a21012010-01-14 16:01:26 +0000951 Results.AddResult(Result(Pattern));
Douglas Gregor504a6ae2010-01-10 23:08:15 +0000952
953 // protected:
954 Pattern = new CodeCompletionString;
955 Pattern->AddTypedTextChunk("protected");
956 Pattern->AddChunk(CodeCompletionString::CK_Colon);
Douglas Gregor78a21012010-01-14 16:01:26 +0000957 Results.AddResult(Result(Pattern));
Douglas Gregor504a6ae2010-01-10 23:08:15 +0000958
959 // private:
960 Pattern = new CodeCompletionString;
961 Pattern->AddTypedTextChunk("private");
962 Pattern->AddChunk(CodeCompletionString::CK_Colon);
Douglas Gregor78a21012010-01-14 16:01:26 +0000963 Results.AddResult(Result(Pattern));
Douglas Gregor504a6ae2010-01-10 23:08:15 +0000964 }
965 }
966 // Fall through
967
968 case Action::CCC_Template:
969 case Action::CCC_MemberTemplate:
970 if (SemaRef.getLangOptions().CPlusPlus) {
971 // template < parameters >
972 CodeCompletionString *Pattern = new CodeCompletionString;
973 Pattern->AddTypedTextChunk("template");
974 Pattern->AddChunk(CodeCompletionString::CK_LeftAngle);
975 Pattern->AddPlaceholderChunk("parameters");
976 Pattern->AddChunk(CodeCompletionString::CK_RightAngle);
Douglas Gregor78a21012010-01-14 16:01:26 +0000977 Results.AddResult(Result(Pattern));
Douglas Gregor504a6ae2010-01-10 23:08:15 +0000978 }
979
Douglas Gregorf98e6a22010-01-13 23:51:12 +0000980 AddStorageSpecifiers(CCC, SemaRef.getLangOptions(), Results);
981 AddFunctionSpecifiers(CCC, SemaRef.getLangOptions(), Results);
Douglas Gregor504a6ae2010-01-10 23:08:15 +0000982 break;
983
Douglas Gregorf1934162010-01-13 21:24:21 +0000984 case Action::CCC_ObjCInterface:
Douglas Gregorf98e6a22010-01-13 23:51:12 +0000985 AddObjCInterfaceResults(SemaRef.getLangOptions(), Results, true);
986 AddStorageSpecifiers(CCC, SemaRef.getLangOptions(), Results);
987 AddFunctionSpecifiers(CCC, SemaRef.getLangOptions(), Results);
Douglas Gregorf1934162010-01-13 21:24:21 +0000988 break;
989
990 case Action::CCC_ObjCImplementation:
Douglas Gregorf98e6a22010-01-13 23:51:12 +0000991 AddObjCImplementationResults(SemaRef.getLangOptions(), Results, true);
992 AddStorageSpecifiers(CCC, SemaRef.getLangOptions(), Results);
993 AddFunctionSpecifiers(CCC, SemaRef.getLangOptions(), Results);
Douglas Gregorf1934162010-01-13 21:24:21 +0000994 break;
995
Douglas Gregor48d46252010-01-13 21:54:15 +0000996 case Action::CCC_ObjCInstanceVariableList:
Douglas Gregorf98e6a22010-01-13 23:51:12 +0000997 AddObjCVisibilityResults(SemaRef.getLangOptions(), Results, true);
Douglas Gregor48d46252010-01-13 21:54:15 +0000998 break;
999
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001000 case Action::CCC_Statement: {
Douglas Gregor78a21012010-01-14 16:01:26 +00001001 Results.AddResult(Result("typedef"));
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001002
1003 CodeCompletionString *Pattern = 0;
1004 if (SemaRef.getLangOptions().CPlusPlus) {
1005 Pattern = new CodeCompletionString;
1006 Pattern->AddTypedTextChunk("try");
1007 Pattern->AddChunk(CodeCompletionString::CK_LeftBrace);
1008 Pattern->AddPlaceholderChunk("statements");
1009 Pattern->AddChunk(CodeCompletionString::CK_VerticalSpace);
1010 Pattern->AddChunk(CodeCompletionString::CK_RightBrace);
1011 Pattern->AddTextChunk("catch");
1012 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
1013 Pattern->AddPlaceholderChunk("declaration");
1014 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
1015 Pattern->AddChunk(CodeCompletionString::CK_LeftBrace);
1016 Pattern->AddPlaceholderChunk("statements");
1017 Pattern->AddChunk(CodeCompletionString::CK_VerticalSpace);
1018 Pattern->AddChunk(CodeCompletionString::CK_RightBrace);
Douglas Gregor78a21012010-01-14 16:01:26 +00001019 Results.AddResult(Result(Pattern));
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001020 }
Douglas Gregorf1934162010-01-13 21:24:21 +00001021 if (SemaRef.getLangOptions().ObjC1)
Douglas Gregorf98e6a22010-01-13 23:51:12 +00001022 AddObjCStatementResults(Results, true);
Douglas Gregorf1934162010-01-13 21:24:21 +00001023
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001024 // if (condition) { statements }
1025 Pattern = new CodeCompletionString;
1026 Pattern->AddTypedTextChunk("if");
1027 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
1028 if (SemaRef.getLangOptions().CPlusPlus)
1029 Pattern->AddPlaceholderChunk("condition");
1030 else
1031 Pattern->AddPlaceholderChunk("expression");
1032 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
1033 Pattern->AddChunk(CodeCompletionString::CK_LeftBrace);
1034 Pattern->AddPlaceholderChunk("statements");
1035 Pattern->AddChunk(CodeCompletionString::CK_VerticalSpace);
1036 Pattern->AddChunk(CodeCompletionString::CK_RightBrace);
Douglas Gregor78a21012010-01-14 16:01:26 +00001037 Results.AddResult(Result(Pattern));
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001038
1039 // switch (condition) { }
1040 Pattern = new CodeCompletionString;
1041 Pattern->AddTypedTextChunk("switch");
1042 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
1043 if (SemaRef.getLangOptions().CPlusPlus)
1044 Pattern->AddPlaceholderChunk("condition");
1045 else
1046 Pattern->AddPlaceholderChunk("expression");
1047 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
1048 Pattern->AddChunk(CodeCompletionString::CK_LeftBrace);
1049 Pattern->AddChunk(CodeCompletionString::CK_VerticalSpace);
1050 Pattern->AddChunk(CodeCompletionString::CK_RightBrace);
Douglas Gregor78a21012010-01-14 16:01:26 +00001051 Results.AddResult(Result(Pattern));
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001052
1053 // Switch-specific statements.
1054 if (!SemaRef.getSwitchStack().empty()) {
1055 // case expression:
1056 Pattern = new CodeCompletionString;
1057 Pattern->AddTypedTextChunk("case");
1058 Pattern->AddPlaceholderChunk("expression");
1059 Pattern->AddChunk(CodeCompletionString::CK_Colon);
Douglas Gregor78a21012010-01-14 16:01:26 +00001060 Results.AddResult(Result(Pattern));
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001061
1062 // default:
1063 Pattern = new CodeCompletionString;
1064 Pattern->AddTypedTextChunk("default");
1065 Pattern->AddChunk(CodeCompletionString::CK_Colon);
Douglas Gregor78a21012010-01-14 16:01:26 +00001066 Results.AddResult(Result(Pattern));
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001067 }
1068
1069 /// while (condition) { statements }
1070 Pattern = new CodeCompletionString;
1071 Pattern->AddTypedTextChunk("while");
1072 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
1073 if (SemaRef.getLangOptions().CPlusPlus)
1074 Pattern->AddPlaceholderChunk("condition");
1075 else
1076 Pattern->AddPlaceholderChunk("expression");
1077 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
1078 Pattern->AddChunk(CodeCompletionString::CK_LeftBrace);
1079 Pattern->AddPlaceholderChunk("statements");
1080 Pattern->AddChunk(CodeCompletionString::CK_VerticalSpace);
1081 Pattern->AddChunk(CodeCompletionString::CK_RightBrace);
Douglas Gregor78a21012010-01-14 16:01:26 +00001082 Results.AddResult(Result(Pattern));
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001083
1084 // do { statements } while ( expression );
1085 Pattern = new CodeCompletionString;
1086 Pattern->AddTypedTextChunk("do");
1087 Pattern->AddChunk(CodeCompletionString::CK_LeftBrace);
1088 Pattern->AddPlaceholderChunk("statements");
1089 Pattern->AddChunk(CodeCompletionString::CK_VerticalSpace);
1090 Pattern->AddChunk(CodeCompletionString::CK_RightBrace);
1091 Pattern->AddTextChunk("while");
1092 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
1093 Pattern->AddPlaceholderChunk("expression");
1094 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
1095 Pattern->AddChunk(CodeCompletionString::CK_SemiColon);
Douglas Gregor78a21012010-01-14 16:01:26 +00001096 Results.AddResult(Result(Pattern));
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001097
1098 // for ( for-init-statement ; condition ; expression ) { statements }
1099 Pattern = new CodeCompletionString;
1100 Pattern->AddTypedTextChunk("for");
1101 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
1102 if (SemaRef.getLangOptions().CPlusPlus || SemaRef.getLangOptions().C99)
1103 Pattern->AddPlaceholderChunk("init-statement");
1104 else
1105 Pattern->AddPlaceholderChunk("init-expression");
1106 Pattern->AddChunk(CodeCompletionString::CK_SemiColon);
1107 Pattern->AddPlaceholderChunk("condition");
1108 Pattern->AddChunk(CodeCompletionString::CK_SemiColon);
1109 Pattern->AddPlaceholderChunk("inc-expression");
1110 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
1111 Pattern->AddChunk(CodeCompletionString::CK_LeftBrace);
1112 Pattern->AddPlaceholderChunk("statements");
1113 Pattern->AddChunk(CodeCompletionString::CK_VerticalSpace);
1114 Pattern->AddChunk(CodeCompletionString::CK_RightBrace);
Douglas Gregor78a21012010-01-14 16:01:26 +00001115 Results.AddResult(Result(Pattern));
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001116
1117 if (S->getContinueParent()) {
1118 // continue ;
1119 Pattern = new CodeCompletionString;
1120 Pattern->AddTypedTextChunk("continue");
1121 Pattern->AddChunk(CodeCompletionString::CK_SemiColon);
Douglas Gregor78a21012010-01-14 16:01:26 +00001122 Results.AddResult(Result(Pattern));
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001123 }
1124
1125 if (S->getBreakParent()) {
1126 // break ;
1127 Pattern = new CodeCompletionString;
1128 Pattern->AddTypedTextChunk("break");
1129 Pattern->AddChunk(CodeCompletionString::CK_SemiColon);
Douglas Gregor78a21012010-01-14 16:01:26 +00001130 Results.AddResult(Result(Pattern));
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001131 }
1132
1133 // "return expression ;" or "return ;", depending on whether we
1134 // know the function is void or not.
1135 bool isVoid = false;
1136 if (FunctionDecl *Function = dyn_cast<FunctionDecl>(SemaRef.CurContext))
1137 isVoid = Function->getResultType()->isVoidType();
1138 else if (ObjCMethodDecl *Method
1139 = dyn_cast<ObjCMethodDecl>(SemaRef.CurContext))
1140 isVoid = Method->getResultType()->isVoidType();
Douglas Gregor9a28e842010-03-01 23:15:13 +00001141 else if (SemaRef.getCurBlock() &&
1142 !SemaRef.getCurBlock()->ReturnType.isNull())
1143 isVoid = SemaRef.getCurBlock()->ReturnType->isVoidType();
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001144 Pattern = new CodeCompletionString;
1145 Pattern->AddTypedTextChunk("return");
Douglas Gregor44272ca2010-02-18 04:06:48 +00001146 if (!isVoid) {
1147 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001148 Pattern->AddPlaceholderChunk("expression");
Douglas Gregor44272ca2010-02-18 04:06:48 +00001149 }
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001150 Pattern->AddChunk(CodeCompletionString::CK_SemiColon);
Douglas Gregor78a21012010-01-14 16:01:26 +00001151 Results.AddResult(Result(Pattern));
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001152
1153 // goto identifier ;
1154 Pattern = new CodeCompletionString;
1155 Pattern->AddTypedTextChunk("goto");
1156 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
1157 Pattern->AddPlaceholderChunk("identifier");
1158 Pattern->AddChunk(CodeCompletionString::CK_SemiColon);
Douglas Gregor78a21012010-01-14 16:01:26 +00001159 Results.AddResult(Result(Pattern));
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001160
1161 // Using directives
1162 Pattern = new CodeCompletionString;
1163 Pattern->AddTypedTextChunk("using");
1164 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
1165 Pattern->AddTextChunk("namespace");
1166 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
1167 Pattern->AddPlaceholderChunk("identifier");
1168 Pattern->AddChunk(CodeCompletionString::CK_SemiColon);
Douglas Gregor78a21012010-01-14 16:01:26 +00001169 Results.AddResult(Result(Pattern));
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001170 }
1171
1172 // Fall through (for statement expressions).
1173 case Action::CCC_ForInit:
1174 case Action::CCC_Condition:
Douglas Gregorf98e6a22010-01-13 23:51:12 +00001175 AddStorageSpecifiers(CCC, SemaRef.getLangOptions(), Results);
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001176 // Fall through: conditions and statements can have expressions.
1177
1178 case Action::CCC_Expression: {
1179 CodeCompletionString *Pattern = 0;
1180 if (SemaRef.getLangOptions().CPlusPlus) {
1181 // 'this', if we're in a non-static member function.
1182 if (CXXMethodDecl *Method = dyn_cast<CXXMethodDecl>(SemaRef.CurContext))
1183 if (!Method->isStatic())
Douglas Gregor78a21012010-01-14 16:01:26 +00001184 Results.AddResult(Result("this"));
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001185
1186 // true, false
Douglas Gregor78a21012010-01-14 16:01:26 +00001187 Results.AddResult(Result("true"));
1188 Results.AddResult(Result("false"));
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001189
1190 // dynamic_cast < type-id > ( expression )
1191 Pattern = new CodeCompletionString;
1192 Pattern->AddTypedTextChunk("dynamic_cast");
1193 Pattern->AddChunk(CodeCompletionString::CK_LeftAngle);
1194 Pattern->AddPlaceholderChunk("type-id");
1195 Pattern->AddChunk(CodeCompletionString::CK_RightAngle);
1196 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
1197 Pattern->AddPlaceholderChunk("expression");
1198 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
Douglas Gregor78a21012010-01-14 16:01:26 +00001199 Results.AddResult(Result(Pattern));
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001200
1201 // static_cast < type-id > ( expression )
1202 Pattern = new CodeCompletionString;
1203 Pattern->AddTypedTextChunk("static_cast");
1204 Pattern->AddChunk(CodeCompletionString::CK_LeftAngle);
1205 Pattern->AddPlaceholderChunk("type-id");
1206 Pattern->AddChunk(CodeCompletionString::CK_RightAngle);
1207 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
1208 Pattern->AddPlaceholderChunk("expression");
1209 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
Douglas Gregor78a21012010-01-14 16:01:26 +00001210 Results.AddResult(Result(Pattern));
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001211
1212 // reinterpret_cast < type-id > ( expression )
1213 Pattern = new CodeCompletionString;
1214 Pattern->AddTypedTextChunk("reinterpret_cast");
1215 Pattern->AddChunk(CodeCompletionString::CK_LeftAngle);
1216 Pattern->AddPlaceholderChunk("type-id");
1217 Pattern->AddChunk(CodeCompletionString::CK_RightAngle);
1218 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
1219 Pattern->AddPlaceholderChunk("expression");
1220 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
Douglas Gregor78a21012010-01-14 16:01:26 +00001221 Results.AddResult(Result(Pattern));
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001222
1223 // const_cast < type-id > ( expression )
1224 Pattern = new CodeCompletionString;
1225 Pattern->AddTypedTextChunk("const_cast");
1226 Pattern->AddChunk(CodeCompletionString::CK_LeftAngle);
1227 Pattern->AddPlaceholderChunk("type-id");
1228 Pattern->AddChunk(CodeCompletionString::CK_RightAngle);
1229 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
1230 Pattern->AddPlaceholderChunk("expression");
1231 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
Douglas Gregor78a21012010-01-14 16:01:26 +00001232 Results.AddResult(Result(Pattern));
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001233
1234 // typeid ( expression-or-type )
1235 Pattern = new CodeCompletionString;
1236 Pattern->AddTypedTextChunk("typeid");
1237 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
1238 Pattern->AddPlaceholderChunk("expression-or-type");
1239 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
Douglas Gregor78a21012010-01-14 16:01:26 +00001240 Results.AddResult(Result(Pattern));
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001241
1242 // new T ( ... )
1243 Pattern = new CodeCompletionString;
1244 Pattern->AddTypedTextChunk("new");
1245 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
1246 Pattern->AddPlaceholderChunk("type-id");
1247 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
1248 Pattern->AddPlaceholderChunk("expressions");
1249 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
Douglas Gregor78a21012010-01-14 16:01:26 +00001250 Results.AddResult(Result(Pattern));
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001251
1252 // new T [ ] ( ... )
1253 Pattern = new CodeCompletionString;
1254 Pattern->AddTypedTextChunk("new");
1255 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
1256 Pattern->AddPlaceholderChunk("type-id");
1257 Pattern->AddChunk(CodeCompletionString::CK_LeftBracket);
1258 Pattern->AddPlaceholderChunk("size");
1259 Pattern->AddChunk(CodeCompletionString::CK_RightBracket);
1260 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
1261 Pattern->AddPlaceholderChunk("expressions");
1262 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
Douglas Gregor78a21012010-01-14 16:01:26 +00001263 Results.AddResult(Result(Pattern));
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001264
1265 // delete expression
1266 Pattern = new CodeCompletionString;
1267 Pattern->AddTypedTextChunk("delete");
1268 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
1269 Pattern->AddPlaceholderChunk("expression");
Douglas Gregor78a21012010-01-14 16:01:26 +00001270 Results.AddResult(Result(Pattern));
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001271
1272 // delete [] expression
1273 Pattern = new CodeCompletionString;
1274 Pattern->AddTypedTextChunk("delete");
1275 Pattern->AddChunk(CodeCompletionString::CK_LeftBracket);
1276 Pattern->AddChunk(CodeCompletionString::CK_RightBracket);
1277 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
1278 Pattern->AddPlaceholderChunk("expression");
Douglas Gregor78a21012010-01-14 16:01:26 +00001279 Results.AddResult(Result(Pattern));
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001280
1281 // throw expression
1282 Pattern = new CodeCompletionString;
1283 Pattern->AddTypedTextChunk("throw");
1284 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
1285 Pattern->AddPlaceholderChunk("expression");
Douglas Gregor78a21012010-01-14 16:01:26 +00001286 Results.AddResult(Result(Pattern));
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001287 }
1288
1289 if (SemaRef.getLangOptions().ObjC1) {
1290 // Add "super", if we're in an Objective-C class with a superclass.
1291 if (ObjCMethodDecl *Method = SemaRef.getCurMethodDecl())
1292 if (Method->getClassInterface()->getSuperClass())
Douglas Gregor78a21012010-01-14 16:01:26 +00001293 Results.AddResult(Result("super"));
Douglas Gregorf1934162010-01-13 21:24:21 +00001294
Douglas Gregorf98e6a22010-01-13 23:51:12 +00001295 AddObjCExpressionResults(Results, true);
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001296 }
1297
1298 // sizeof expression
1299 Pattern = new CodeCompletionString;
1300 Pattern->AddTypedTextChunk("sizeof");
1301 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
1302 Pattern->AddPlaceholderChunk("expression-or-type");
1303 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
Douglas Gregor78a21012010-01-14 16:01:26 +00001304 Results.AddResult(Result(Pattern));
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001305 break;
1306 }
1307 }
1308
Douglas Gregorf98e6a22010-01-13 23:51:12 +00001309 AddTypeSpecifierResults(SemaRef.getLangOptions(), Results);
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001310
1311 if (SemaRef.getLangOptions().CPlusPlus)
Douglas Gregor78a21012010-01-14 16:01:26 +00001312 Results.AddResult(Result("operator"));
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001313}
1314
Douglas Gregorb3fa9192009-12-18 18:53:37 +00001315/// \brief If the given declaration has an associated type, add it as a result
1316/// type chunk.
1317static void AddResultTypeChunk(ASTContext &Context,
1318 NamedDecl *ND,
1319 CodeCompletionString *Result) {
1320 if (!ND)
1321 return;
1322
1323 // Determine the type of the declaration (if it has a type).
1324 QualType T;
1325 if (FunctionDecl *Function = dyn_cast<FunctionDecl>(ND))
1326 T = Function->getResultType();
1327 else if (ObjCMethodDecl *Method = dyn_cast<ObjCMethodDecl>(ND))
1328 T = Method->getResultType();
1329 else if (FunctionTemplateDecl *FunTmpl = dyn_cast<FunctionTemplateDecl>(ND))
1330 T = FunTmpl->getTemplatedDecl()->getResultType();
1331 else if (EnumConstantDecl *Enumerator = dyn_cast<EnumConstantDecl>(ND))
1332 T = Context.getTypeDeclType(cast<TypeDecl>(Enumerator->getDeclContext()));
1333 else if (isa<UnresolvedUsingValueDecl>(ND)) {
1334 /* Do nothing: ignore unresolved using declarations*/
1335 } else if (ValueDecl *Value = dyn_cast<ValueDecl>(ND))
1336 T = Value->getType();
1337 else if (ObjCPropertyDecl *Property = dyn_cast<ObjCPropertyDecl>(ND))
1338 T = Property->getType();
1339
1340 if (T.isNull() || Context.hasSameType(T, Context.DependentTy))
1341 return;
1342
Douglas Gregorcf04b022010-04-05 21:25:31 +00001343 PrintingPolicy Policy(Context.PrintingPolicy);
1344 Policy.AnonymousTagLocations = false;
1345
Douglas Gregorb3fa9192009-12-18 18:53:37 +00001346 std::string TypeStr;
Douglas Gregorcf04b022010-04-05 21:25:31 +00001347 T.getAsStringInternal(TypeStr, Policy);
Douglas Gregorb3fa9192009-12-18 18:53:37 +00001348 Result->AddResultTypeChunk(TypeStr);
1349}
1350
Douglas Gregor3545ff42009-09-21 16:56:56 +00001351/// \brief Add function parameter chunks to the given code completion string.
1352static void AddFunctionParameterChunks(ASTContext &Context,
1353 FunctionDecl *Function,
1354 CodeCompletionString *Result) {
Douglas Gregor9eb77012009-11-07 00:00:49 +00001355 typedef CodeCompletionString::Chunk Chunk;
1356
Douglas Gregor3545ff42009-09-21 16:56:56 +00001357 CodeCompletionString *CCStr = Result;
1358
1359 for (unsigned P = 0, N = Function->getNumParams(); P != N; ++P) {
1360 ParmVarDecl *Param = Function->getParamDecl(P);
1361
1362 if (Param->hasDefaultArg()) {
1363 // When we see an optional default argument, put that argument and
1364 // the remaining default arguments into a new, optional string.
1365 CodeCompletionString *Opt = new CodeCompletionString;
1366 CCStr->AddOptionalChunk(std::auto_ptr<CodeCompletionString>(Opt));
1367 CCStr = Opt;
1368 }
1369
1370 if (P != 0)
Douglas Gregor9eb77012009-11-07 00:00:49 +00001371 CCStr->AddChunk(Chunk(CodeCompletionString::CK_Comma));
Douglas Gregor3545ff42009-09-21 16:56:56 +00001372
1373 // Format the placeholder string.
1374 std::string PlaceholderStr;
1375 if (Param->getIdentifier())
1376 PlaceholderStr = Param->getIdentifier()->getName();
1377
1378 Param->getType().getAsStringInternal(PlaceholderStr,
1379 Context.PrintingPolicy);
1380
1381 // Add the placeholder string.
Benjamin Kramerb33a97c2009-11-29 20:18:50 +00001382 CCStr->AddPlaceholderChunk(PlaceholderStr);
Douglas Gregor3545ff42009-09-21 16:56:56 +00001383 }
Douglas Gregorba449032009-09-22 21:42:17 +00001384
1385 if (const FunctionProtoType *Proto
1386 = Function->getType()->getAs<FunctionProtoType>())
1387 if (Proto->isVariadic())
1388 CCStr->AddPlaceholderChunk(", ...");
Douglas Gregor3545ff42009-09-21 16:56:56 +00001389}
1390
1391/// \brief Add template parameter chunks to the given code completion string.
1392static void AddTemplateParameterChunks(ASTContext &Context,
1393 TemplateDecl *Template,
1394 CodeCompletionString *Result,
1395 unsigned MaxParameters = 0) {
Douglas Gregor9eb77012009-11-07 00:00:49 +00001396 typedef CodeCompletionString::Chunk Chunk;
1397
Douglas Gregor3545ff42009-09-21 16:56:56 +00001398 CodeCompletionString *CCStr = Result;
1399 bool FirstParameter = true;
1400
1401 TemplateParameterList *Params = Template->getTemplateParameters();
1402 TemplateParameterList::iterator PEnd = Params->end();
1403 if (MaxParameters)
1404 PEnd = Params->begin() + MaxParameters;
1405 for (TemplateParameterList::iterator P = Params->begin(); P != PEnd; ++P) {
1406 bool HasDefaultArg = false;
1407 std::string PlaceholderStr;
1408 if (TemplateTypeParmDecl *TTP = dyn_cast<TemplateTypeParmDecl>(*P)) {
1409 if (TTP->wasDeclaredWithTypename())
1410 PlaceholderStr = "typename";
1411 else
1412 PlaceholderStr = "class";
1413
1414 if (TTP->getIdentifier()) {
1415 PlaceholderStr += ' ';
1416 PlaceholderStr += TTP->getIdentifier()->getName();
1417 }
1418
1419 HasDefaultArg = TTP->hasDefaultArgument();
1420 } else if (NonTypeTemplateParmDecl *NTTP
1421 = dyn_cast<NonTypeTemplateParmDecl>(*P)) {
1422 if (NTTP->getIdentifier())
1423 PlaceholderStr = NTTP->getIdentifier()->getName();
1424 NTTP->getType().getAsStringInternal(PlaceholderStr,
1425 Context.PrintingPolicy);
1426 HasDefaultArg = NTTP->hasDefaultArgument();
1427 } else {
1428 assert(isa<TemplateTemplateParmDecl>(*P));
1429 TemplateTemplateParmDecl *TTP = cast<TemplateTemplateParmDecl>(*P);
1430
1431 // Since putting the template argument list into the placeholder would
1432 // be very, very long, we just use an abbreviation.
1433 PlaceholderStr = "template<...> class";
1434 if (TTP->getIdentifier()) {
1435 PlaceholderStr += ' ';
1436 PlaceholderStr += TTP->getIdentifier()->getName();
1437 }
1438
1439 HasDefaultArg = TTP->hasDefaultArgument();
1440 }
1441
1442 if (HasDefaultArg) {
1443 // When we see an optional default argument, put that argument and
1444 // the remaining default arguments into a new, optional string.
1445 CodeCompletionString *Opt = new CodeCompletionString;
1446 CCStr->AddOptionalChunk(std::auto_ptr<CodeCompletionString>(Opt));
1447 CCStr = Opt;
1448 }
1449
1450 if (FirstParameter)
1451 FirstParameter = false;
1452 else
Douglas Gregor9eb77012009-11-07 00:00:49 +00001453 CCStr->AddChunk(Chunk(CodeCompletionString::CK_Comma));
Douglas Gregor3545ff42009-09-21 16:56:56 +00001454
1455 // Add the placeholder string.
Benjamin Kramerb33a97c2009-11-29 20:18:50 +00001456 CCStr->AddPlaceholderChunk(PlaceholderStr);
Douglas Gregor3545ff42009-09-21 16:56:56 +00001457 }
1458}
1459
Douglas Gregorf2510672009-09-21 19:57:38 +00001460/// \brief Add a qualifier to the given code-completion string, if the
1461/// provided nested-name-specifier is non-NULL.
Douglas Gregor0f622362009-12-11 18:44:16 +00001462static void
1463AddQualifierToCompletionString(CodeCompletionString *Result,
1464 NestedNameSpecifier *Qualifier,
1465 bool QualifierIsInformative,
1466 ASTContext &Context) {
Douglas Gregorf2510672009-09-21 19:57:38 +00001467 if (!Qualifier)
1468 return;
1469
1470 std::string PrintedNNS;
1471 {
1472 llvm::raw_string_ostream OS(PrintedNNS);
1473 Qualifier->print(OS, Context.PrintingPolicy);
1474 }
Douglas Gregor5bf52692009-09-22 23:15:58 +00001475 if (QualifierIsInformative)
Benjamin Kramerb33a97c2009-11-29 20:18:50 +00001476 Result->AddInformativeChunk(PrintedNNS);
Douglas Gregor5bf52692009-09-22 23:15:58 +00001477 else
Benjamin Kramerb33a97c2009-11-29 20:18:50 +00001478 Result->AddTextChunk(PrintedNNS);
Douglas Gregorf2510672009-09-21 19:57:38 +00001479}
1480
Douglas Gregor0f622362009-12-11 18:44:16 +00001481static void AddFunctionTypeQualsToCompletionString(CodeCompletionString *Result,
1482 FunctionDecl *Function) {
1483 const FunctionProtoType *Proto
1484 = Function->getType()->getAs<FunctionProtoType>();
1485 if (!Proto || !Proto->getTypeQuals())
1486 return;
1487
1488 std::string QualsStr;
1489 if (Proto->getTypeQuals() & Qualifiers::Const)
1490 QualsStr += " const";
1491 if (Proto->getTypeQuals() & Qualifiers::Volatile)
1492 QualsStr += " volatile";
1493 if (Proto->getTypeQuals() & Qualifiers::Restrict)
1494 QualsStr += " restrict";
1495 Result->AddInformativeChunk(QualsStr);
1496}
1497
Douglas Gregor3545ff42009-09-21 16:56:56 +00001498/// \brief If possible, create a new code completion string for the given
1499/// result.
1500///
1501/// \returns Either a new, heap-allocated code completion string describing
1502/// how to use this result, or NULL to indicate that the string or name of the
1503/// result is all that is needed.
1504CodeCompletionString *
1505CodeCompleteConsumer::Result::CreateCodeCompletionString(Sema &S) {
Douglas Gregor9eb77012009-11-07 00:00:49 +00001506 typedef CodeCompletionString::Chunk Chunk;
1507
Douglas Gregorf09935f2009-12-01 05:55:20 +00001508 if (Kind == RK_Pattern)
1509 return Pattern->Clone();
1510
1511 CodeCompletionString *Result = new CodeCompletionString;
1512
1513 if (Kind == RK_Keyword) {
1514 Result->AddTypedTextChunk(Keyword);
1515 return Result;
1516 }
Douglas Gregor3545ff42009-09-21 16:56:56 +00001517
Douglas Gregorf329c7c2009-10-30 16:50:04 +00001518 if (Kind == RK_Macro) {
1519 MacroInfo *MI = S.PP.getMacroInfo(Macro);
Douglas Gregorf09935f2009-12-01 05:55:20 +00001520 assert(MI && "Not a macro?");
1521
1522 Result->AddTypedTextChunk(Macro->getName());
1523
1524 if (!MI->isFunctionLike())
1525 return Result;
Douglas Gregorf329c7c2009-10-30 16:50:04 +00001526
1527 // Format a function-like macro with placeholders for the arguments.
Douglas Gregor9eb77012009-11-07 00:00:49 +00001528 Result->AddChunk(Chunk(CodeCompletionString::CK_LeftParen));
Douglas Gregorf329c7c2009-10-30 16:50:04 +00001529 for (MacroInfo::arg_iterator A = MI->arg_begin(), AEnd = MI->arg_end();
1530 A != AEnd; ++A) {
1531 if (A != MI->arg_begin())
Douglas Gregor9eb77012009-11-07 00:00:49 +00001532 Result->AddChunk(Chunk(CodeCompletionString::CK_Comma));
Douglas Gregorf329c7c2009-10-30 16:50:04 +00001533
1534 if (!MI->isVariadic() || A != AEnd - 1) {
1535 // Non-variadic argument.
Benjamin Kramerb33a97c2009-11-29 20:18:50 +00001536 Result->AddPlaceholderChunk((*A)->getName());
Douglas Gregorf329c7c2009-10-30 16:50:04 +00001537 continue;
1538 }
1539
1540 // Variadic argument; cope with the different between GNU and C99
1541 // variadic macros, providing a single placeholder for the rest of the
1542 // arguments.
1543 if ((*A)->isStr("__VA_ARGS__"))
1544 Result->AddPlaceholderChunk("...");
1545 else {
1546 std::string Arg = (*A)->getName();
1547 Arg += "...";
Benjamin Kramerb33a97c2009-11-29 20:18:50 +00001548 Result->AddPlaceholderChunk(Arg);
Douglas Gregorf329c7c2009-10-30 16:50:04 +00001549 }
1550 }
Douglas Gregor9eb77012009-11-07 00:00:49 +00001551 Result->AddChunk(Chunk(CodeCompletionString::CK_RightParen));
Douglas Gregorf329c7c2009-10-30 16:50:04 +00001552 return Result;
1553 }
1554
1555 assert(Kind == RK_Declaration && "Missed a macro kind?");
Douglas Gregor3545ff42009-09-21 16:56:56 +00001556 NamedDecl *ND = Declaration;
1557
Douglas Gregor9eb77012009-11-07 00:00:49 +00001558 if (StartsNestedNameSpecifier) {
Benjamin Kramerb33a97c2009-11-29 20:18:50 +00001559 Result->AddTypedTextChunk(ND->getNameAsString());
Douglas Gregor9eb77012009-11-07 00:00:49 +00001560 Result->AddTextChunk("::");
1561 return Result;
1562 }
1563
Douglas Gregorb3fa9192009-12-18 18:53:37 +00001564 AddResultTypeChunk(S.Context, ND, Result);
1565
Douglas Gregor3545ff42009-09-21 16:56:56 +00001566 if (FunctionDecl *Function = dyn_cast<FunctionDecl>(ND)) {
Douglas Gregor5bf52692009-09-22 23:15:58 +00001567 AddQualifierToCompletionString(Result, Qualifier, QualifierIsInformative,
1568 S.Context);
Benjamin Kramerb33a97c2009-11-29 20:18:50 +00001569 Result->AddTypedTextChunk(Function->getNameAsString());
Douglas Gregor9eb77012009-11-07 00:00:49 +00001570 Result->AddChunk(Chunk(CodeCompletionString::CK_LeftParen));
Douglas Gregor3545ff42009-09-21 16:56:56 +00001571 AddFunctionParameterChunks(S.Context, Function, Result);
Douglas Gregor9eb77012009-11-07 00:00:49 +00001572 Result->AddChunk(Chunk(CodeCompletionString::CK_RightParen));
Douglas Gregor0f622362009-12-11 18:44:16 +00001573 AddFunctionTypeQualsToCompletionString(Result, Function);
Douglas Gregor3545ff42009-09-21 16:56:56 +00001574 return Result;
1575 }
1576
1577 if (FunctionTemplateDecl *FunTmpl = dyn_cast<FunctionTemplateDecl>(ND)) {
Douglas Gregor5bf52692009-09-22 23:15:58 +00001578 AddQualifierToCompletionString(Result, Qualifier, QualifierIsInformative,
1579 S.Context);
Douglas Gregor3545ff42009-09-21 16:56:56 +00001580 FunctionDecl *Function = FunTmpl->getTemplatedDecl();
Benjamin Kramerb33a97c2009-11-29 20:18:50 +00001581 Result->AddTypedTextChunk(Function->getNameAsString());
Douglas Gregor3545ff42009-09-21 16:56:56 +00001582
1583 // Figure out which template parameters are deduced (or have default
1584 // arguments).
1585 llvm::SmallVector<bool, 16> Deduced;
1586 S.MarkDeducedTemplateParameters(FunTmpl, Deduced);
1587 unsigned LastDeducibleArgument;
1588 for (LastDeducibleArgument = Deduced.size(); LastDeducibleArgument > 0;
1589 --LastDeducibleArgument) {
1590 if (!Deduced[LastDeducibleArgument - 1]) {
1591 // C++0x: Figure out if the template argument has a default. If so,
1592 // the user doesn't need to type this argument.
1593 // FIXME: We need to abstract template parameters better!
1594 bool HasDefaultArg = false;
1595 NamedDecl *Param = FunTmpl->getTemplateParameters()->getParam(
1596 LastDeducibleArgument - 1);
1597 if (TemplateTypeParmDecl *TTP = dyn_cast<TemplateTypeParmDecl>(Param))
1598 HasDefaultArg = TTP->hasDefaultArgument();
1599 else if (NonTypeTemplateParmDecl *NTTP
1600 = dyn_cast<NonTypeTemplateParmDecl>(Param))
1601 HasDefaultArg = NTTP->hasDefaultArgument();
1602 else {
1603 assert(isa<TemplateTemplateParmDecl>(Param));
1604 HasDefaultArg
Douglas Gregor9eb77012009-11-07 00:00:49 +00001605 = cast<TemplateTemplateParmDecl>(Param)->hasDefaultArgument();
Douglas Gregor3545ff42009-09-21 16:56:56 +00001606 }
1607
1608 if (!HasDefaultArg)
1609 break;
1610 }
1611 }
1612
1613 if (LastDeducibleArgument) {
1614 // Some of the function template arguments cannot be deduced from a
1615 // function call, so we introduce an explicit template argument list
1616 // containing all of the arguments up to the first deducible argument.
Douglas Gregor9eb77012009-11-07 00:00:49 +00001617 Result->AddChunk(Chunk(CodeCompletionString::CK_LeftAngle));
Douglas Gregor3545ff42009-09-21 16:56:56 +00001618 AddTemplateParameterChunks(S.Context, FunTmpl, Result,
1619 LastDeducibleArgument);
Douglas Gregor9eb77012009-11-07 00:00:49 +00001620 Result->AddChunk(Chunk(CodeCompletionString::CK_RightAngle));
Douglas Gregor3545ff42009-09-21 16:56:56 +00001621 }
1622
1623 // Add the function parameters
Douglas Gregor9eb77012009-11-07 00:00:49 +00001624 Result->AddChunk(Chunk(CodeCompletionString::CK_LeftParen));
Douglas Gregor3545ff42009-09-21 16:56:56 +00001625 AddFunctionParameterChunks(S.Context, Function, Result);
Douglas Gregor9eb77012009-11-07 00:00:49 +00001626 Result->AddChunk(Chunk(CodeCompletionString::CK_RightParen));
Douglas Gregor0f622362009-12-11 18:44:16 +00001627 AddFunctionTypeQualsToCompletionString(Result, Function);
Douglas Gregor3545ff42009-09-21 16:56:56 +00001628 return Result;
1629 }
1630
1631 if (TemplateDecl *Template = dyn_cast<TemplateDecl>(ND)) {
Douglas Gregor5bf52692009-09-22 23:15:58 +00001632 AddQualifierToCompletionString(Result, Qualifier, QualifierIsInformative,
1633 S.Context);
Benjamin Kramerb33a97c2009-11-29 20:18:50 +00001634 Result->AddTypedTextChunk(Template->getNameAsString());
Douglas Gregor9eb77012009-11-07 00:00:49 +00001635 Result->AddChunk(Chunk(CodeCompletionString::CK_LeftAngle));
Douglas Gregor3545ff42009-09-21 16:56:56 +00001636 AddTemplateParameterChunks(S.Context, Template, Result);
Douglas Gregor9eb77012009-11-07 00:00:49 +00001637 Result->AddChunk(Chunk(CodeCompletionString::CK_RightAngle));
Douglas Gregor3545ff42009-09-21 16:56:56 +00001638 return Result;
1639 }
1640
Douglas Gregord3c5d792009-11-17 16:44:22 +00001641 if (ObjCMethodDecl *Method = dyn_cast<ObjCMethodDecl>(ND)) {
Douglas Gregord3c5d792009-11-17 16:44:22 +00001642 Selector Sel = Method->getSelector();
1643 if (Sel.isUnarySelector()) {
1644 Result->AddTypedTextChunk(Sel.getIdentifierInfoForSlot(0)->getName());
1645 return Result;
1646 }
1647
Douglas Gregor1b605f72009-11-19 01:08:35 +00001648 std::string SelName = Sel.getIdentifierInfoForSlot(0)->getName().str();
1649 SelName += ':';
1650 if (StartParameter == 0)
1651 Result->AddTypedTextChunk(SelName);
1652 else {
1653 Result->AddInformativeChunk(SelName);
1654
1655 // If there is only one parameter, and we're past it, add an empty
1656 // typed-text chunk since there is nothing to type.
1657 if (Method->param_size() == 1)
1658 Result->AddTypedTextChunk("");
1659 }
Douglas Gregord3c5d792009-11-17 16:44:22 +00001660 unsigned Idx = 0;
1661 for (ObjCMethodDecl::param_iterator P = Method->param_begin(),
1662 PEnd = Method->param_end();
1663 P != PEnd; (void)++P, ++Idx) {
1664 if (Idx > 0) {
Douglas Gregor1b605f72009-11-19 01:08:35 +00001665 std::string Keyword;
1666 if (Idx > StartParameter)
Douglas Gregor6a803932010-01-12 06:38:28 +00001667 Result->AddChunk(CodeCompletionString::CK_HorizontalSpace);
Douglas Gregord3c5d792009-11-17 16:44:22 +00001668 if (IdentifierInfo *II = Sel.getIdentifierInfoForSlot(Idx))
1669 Keyword += II->getName().str();
1670 Keyword += ":";
Douglas Gregorc8537c52009-11-19 07:41:15 +00001671 if (Idx < StartParameter || AllParametersAreInformative) {
Douglas Gregor1b605f72009-11-19 01:08:35 +00001672 Result->AddInformativeChunk(Keyword);
1673 } else if (Idx == StartParameter)
1674 Result->AddTypedTextChunk(Keyword);
1675 else
1676 Result->AddTextChunk(Keyword);
Douglas Gregord3c5d792009-11-17 16:44:22 +00001677 }
Douglas Gregor1b605f72009-11-19 01:08:35 +00001678
1679 // If we're before the starting parameter, skip the placeholder.
1680 if (Idx < StartParameter)
1681 continue;
Douglas Gregord3c5d792009-11-17 16:44:22 +00001682
1683 std::string Arg;
1684 (*P)->getType().getAsStringInternal(Arg, S.Context.PrintingPolicy);
1685 Arg = "(" + Arg + ")";
1686 if (IdentifierInfo *II = (*P)->getIdentifier())
1687 Arg += II->getName().str();
Douglas Gregorc8537c52009-11-19 07:41:15 +00001688 if (AllParametersAreInformative)
1689 Result->AddInformativeChunk(Arg);
1690 else
1691 Result->AddPlaceholderChunk(Arg);
Douglas Gregord3c5d792009-11-17 16:44:22 +00001692 }
1693
Douglas Gregor04c5f972009-12-23 00:21:46 +00001694 if (Method->isVariadic()) {
1695 if (AllParametersAreInformative)
1696 Result->AddInformativeChunk(", ...");
1697 else
1698 Result->AddPlaceholderChunk(", ...");
1699 }
1700
Douglas Gregord3c5d792009-11-17 16:44:22 +00001701 return Result;
1702 }
1703
Douglas Gregorf09935f2009-12-01 05:55:20 +00001704 if (Qualifier)
Douglas Gregor5bf52692009-09-22 23:15:58 +00001705 AddQualifierToCompletionString(Result, Qualifier, QualifierIsInformative,
1706 S.Context);
Douglas Gregorf09935f2009-12-01 05:55:20 +00001707
1708 Result->AddTypedTextChunk(ND->getNameAsString());
1709 return Result;
Douglas Gregor3545ff42009-09-21 16:56:56 +00001710}
1711
Douglas Gregorf0f51982009-09-23 00:34:09 +00001712CodeCompletionString *
1713CodeCompleteConsumer::OverloadCandidate::CreateSignatureString(
1714 unsigned CurrentArg,
1715 Sema &S) const {
Douglas Gregor9eb77012009-11-07 00:00:49 +00001716 typedef CodeCompletionString::Chunk Chunk;
1717
Douglas Gregorf0f51982009-09-23 00:34:09 +00001718 CodeCompletionString *Result = new CodeCompletionString;
1719 FunctionDecl *FDecl = getFunction();
Douglas Gregorb3fa9192009-12-18 18:53:37 +00001720 AddResultTypeChunk(S.Context, FDecl, Result);
Douglas Gregorf0f51982009-09-23 00:34:09 +00001721 const FunctionProtoType *Proto
1722 = dyn_cast<FunctionProtoType>(getFunctionType());
1723 if (!FDecl && !Proto) {
1724 // Function without a prototype. Just give the return type and a
1725 // highlighted ellipsis.
1726 const FunctionType *FT = getFunctionType();
1727 Result->AddTextChunk(
Benjamin Kramerb33a97c2009-11-29 20:18:50 +00001728 FT->getResultType().getAsString(S.Context.PrintingPolicy));
Douglas Gregor9eb77012009-11-07 00:00:49 +00001729 Result->AddChunk(Chunk(CodeCompletionString::CK_LeftParen));
1730 Result->AddChunk(Chunk(CodeCompletionString::CK_CurrentParameter, "..."));
1731 Result->AddChunk(Chunk(CodeCompletionString::CK_RightParen));
Douglas Gregorf0f51982009-09-23 00:34:09 +00001732 return Result;
1733 }
1734
1735 if (FDecl)
Benjamin Kramerb33a97c2009-11-29 20:18:50 +00001736 Result->AddTextChunk(FDecl->getNameAsString());
Douglas Gregorf0f51982009-09-23 00:34:09 +00001737 else
1738 Result->AddTextChunk(
Benjamin Kramerb33a97c2009-11-29 20:18:50 +00001739 Proto->getResultType().getAsString(S.Context.PrintingPolicy));
Douglas Gregorf0f51982009-09-23 00:34:09 +00001740
Douglas Gregor9eb77012009-11-07 00:00:49 +00001741 Result->AddChunk(Chunk(CodeCompletionString::CK_LeftParen));
Douglas Gregorf0f51982009-09-23 00:34:09 +00001742 unsigned NumParams = FDecl? FDecl->getNumParams() : Proto->getNumArgs();
1743 for (unsigned I = 0; I != NumParams; ++I) {
1744 if (I)
Douglas Gregor9eb77012009-11-07 00:00:49 +00001745 Result->AddChunk(Chunk(CodeCompletionString::CK_Comma));
Douglas Gregorf0f51982009-09-23 00:34:09 +00001746
1747 std::string ArgString;
1748 QualType ArgType;
1749
1750 if (FDecl) {
1751 ArgString = FDecl->getParamDecl(I)->getNameAsString();
1752 ArgType = FDecl->getParamDecl(I)->getOriginalType();
1753 } else {
1754 ArgType = Proto->getArgType(I);
1755 }
1756
1757 ArgType.getAsStringInternal(ArgString, S.Context.PrintingPolicy);
1758
1759 if (I == CurrentArg)
Douglas Gregor9eb77012009-11-07 00:00:49 +00001760 Result->AddChunk(Chunk(CodeCompletionString::CK_CurrentParameter,
Benjamin Kramerb33a97c2009-11-29 20:18:50 +00001761 ArgString));
Douglas Gregorf0f51982009-09-23 00:34:09 +00001762 else
Benjamin Kramerb33a97c2009-11-29 20:18:50 +00001763 Result->AddTextChunk(ArgString);
Douglas Gregorf0f51982009-09-23 00:34:09 +00001764 }
1765
1766 if (Proto && Proto->isVariadic()) {
Douglas Gregor9eb77012009-11-07 00:00:49 +00001767 Result->AddChunk(Chunk(CodeCompletionString::CK_Comma));
Douglas Gregorf0f51982009-09-23 00:34:09 +00001768 if (CurrentArg < NumParams)
1769 Result->AddTextChunk("...");
1770 else
Douglas Gregor9eb77012009-11-07 00:00:49 +00001771 Result->AddChunk(Chunk(CodeCompletionString::CK_CurrentParameter, "..."));
Douglas Gregorf0f51982009-09-23 00:34:09 +00001772 }
Douglas Gregor9eb77012009-11-07 00:00:49 +00001773 Result->AddChunk(Chunk(CodeCompletionString::CK_RightParen));
Douglas Gregorf0f51982009-09-23 00:34:09 +00001774
1775 return Result;
1776}
1777
Douglas Gregor3545ff42009-09-21 16:56:56 +00001778namespace {
1779 struct SortCodeCompleteResult {
1780 typedef CodeCompleteConsumer::Result Result;
1781
Douglas Gregore6688e62009-09-28 03:51:44 +00001782 bool isEarlierDeclarationName(DeclarationName X, DeclarationName Y) const {
Douglas Gregor249d6822009-12-05 09:08:56 +00001783 Selector XSel = X.getObjCSelector();
1784 Selector YSel = Y.getObjCSelector();
1785 if (!XSel.isNull() && !YSel.isNull()) {
1786 // We are comparing two selectors.
1787 unsigned N = std::min(XSel.getNumArgs(), YSel.getNumArgs());
1788 if (N == 0)
1789 ++N;
1790 for (unsigned I = 0; I != N; ++I) {
1791 IdentifierInfo *XId = XSel.getIdentifierInfoForSlot(I);
1792 IdentifierInfo *YId = YSel.getIdentifierInfoForSlot(I);
1793 if (!XId || !YId)
1794 return XId && !YId;
1795
1796 switch (XId->getName().compare_lower(YId->getName())) {
1797 case -1: return true;
1798 case 1: return false;
1799 default: break;
1800 }
1801 }
1802
1803 return XSel.getNumArgs() < YSel.getNumArgs();
1804 }
1805
1806 // For non-selectors, order by kind.
1807 if (X.getNameKind() != Y.getNameKind())
Douglas Gregore6688e62009-09-28 03:51:44 +00001808 return X.getNameKind() < Y.getNameKind();
1809
Douglas Gregor249d6822009-12-05 09:08:56 +00001810 // Order identifiers by comparison of their lowercased names.
1811 if (IdentifierInfo *XId = X.getAsIdentifierInfo())
1812 return XId->getName().compare_lower(
1813 Y.getAsIdentifierInfo()->getName()) < 0;
1814
1815 // Order overloaded operators by the order in which they appear
1816 // in our list of operators.
1817 if (OverloadedOperatorKind XOp = X.getCXXOverloadedOperator())
1818 return XOp < Y.getCXXOverloadedOperator();
1819
1820 // Order C++0x user-defined literal operators lexically by their
1821 // lowercased suffixes.
1822 if (IdentifierInfo *XLit = X.getCXXLiteralIdentifier())
1823 return XLit->getName().compare_lower(
1824 Y.getCXXLiteralIdentifier()->getName()) < 0;
1825
1826 // The only stable ordering we have is to turn the name into a
1827 // string and then compare the lower-case strings. This is
1828 // inefficient, but thankfully does not happen too often.
Benjamin Kramer4053e5d2009-12-05 10:22:15 +00001829 return llvm::StringRef(X.getAsString()).compare_lower(
1830 Y.getAsString()) < 0;
Douglas Gregore6688e62009-09-28 03:51:44 +00001831 }
1832
Douglas Gregor52ce62f2010-01-13 23:24:38 +00001833 /// \brief Retrieve the name that should be used to order a result.
1834 ///
1835 /// If the name needs to be constructed as a string, that string will be
1836 /// saved into Saved and the returned StringRef will refer to it.
1837 static llvm::StringRef getOrderedName(const Result &R,
1838 std::string &Saved) {
1839 switch (R.Kind) {
1840 case Result::RK_Keyword:
1841 return R.Keyword;
1842
1843 case Result::RK_Pattern:
1844 return R.Pattern->getTypedText();
1845
1846 case Result::RK_Macro:
1847 return R.Macro->getName();
1848
1849 case Result::RK_Declaration:
1850 // Handle declarations below.
1851 break;
Douglas Gregor45f83ee2009-11-19 00:01:57 +00001852 }
Douglas Gregor52ce62f2010-01-13 23:24:38 +00001853
1854 DeclarationName Name = R.Declaration->getDeclName();
Douglas Gregor45f83ee2009-11-19 00:01:57 +00001855
Douglas Gregor52ce62f2010-01-13 23:24:38 +00001856 // If the name is a simple identifier (by far the common case), or a
1857 // zero-argument selector, just return a reference to that identifier.
1858 if (IdentifierInfo *Id = Name.getAsIdentifierInfo())
1859 return Id->getName();
1860 if (Name.isObjCZeroArgSelector())
1861 if (IdentifierInfo *Id
1862 = Name.getObjCSelector().getIdentifierInfoForSlot(0))
1863 return Id->getName();
1864
1865 Saved = Name.getAsString();
1866 return Saved;
1867 }
1868
1869 bool operator()(const Result &X, const Result &Y) const {
1870 std::string XSaved, YSaved;
1871 llvm::StringRef XStr = getOrderedName(X, XSaved);
1872 llvm::StringRef YStr = getOrderedName(Y, YSaved);
1873 int cmp = XStr.compare_lower(YStr);
1874 if (cmp)
1875 return cmp < 0;
Douglas Gregor3545ff42009-09-21 16:56:56 +00001876
1877 // Non-hidden names precede hidden names.
1878 if (X.Hidden != Y.Hidden)
1879 return !X.Hidden;
1880
Douglas Gregore412a5a2009-09-23 22:26:46 +00001881 // Non-nested-name-specifiers precede nested-name-specifiers.
1882 if (X.StartsNestedNameSpecifier != Y.StartsNestedNameSpecifier)
1883 return !X.StartsNestedNameSpecifier;
1884
Douglas Gregor3545ff42009-09-21 16:56:56 +00001885 return false;
1886 }
1887 };
1888}
1889
Douglas Gregorf98e6a22010-01-13 23:51:12 +00001890static void AddMacroResults(Preprocessor &PP, ResultBuilder &Results) {
Douglas Gregorf329c7c2009-10-30 16:50:04 +00001891 Results.EnterNewScope();
Douglas Gregor9eb77012009-11-07 00:00:49 +00001892 for (Preprocessor::macro_iterator M = PP.macro_begin(),
1893 MEnd = PP.macro_end();
Douglas Gregorf329c7c2009-10-30 16:50:04 +00001894 M != MEnd; ++M)
Douglas Gregor78a21012010-01-14 16:01:26 +00001895 Results.AddResult(M->first);
Douglas Gregorf329c7c2009-10-30 16:50:04 +00001896 Results.ExitScope();
1897}
1898
Daniel Dunbar242ea9a2009-11-13 08:58:20 +00001899static void HandleCodeCompleteResults(Sema *S,
1900 CodeCompleteConsumer *CodeCompleter,
1901 CodeCompleteConsumer::Result *Results,
1902 unsigned NumResults) {
Douglas Gregor3545ff42009-09-21 16:56:56 +00001903 std::stable_sort(Results, Results + NumResults, SortCodeCompleteResult());
1904
1905 if (CodeCompleter)
Daniel Dunbar242ea9a2009-11-13 08:58:20 +00001906 CodeCompleter->ProcessCodeCompleteResults(*S, Results, NumResults);
Douglas Gregor45f83ee2009-11-19 00:01:57 +00001907
1908 for (unsigned I = 0; I != NumResults; ++I)
1909 Results[I].Destroy();
Douglas Gregor3545ff42009-09-21 16:56:56 +00001910}
1911
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001912void Sema::CodeCompleteOrdinaryName(Scope *S,
1913 CodeCompletionContext CompletionContext) {
Douglas Gregor92253692009-12-07 09:54:55 +00001914 typedef CodeCompleteConsumer::Result Result;
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001915 ResultBuilder Results(*this);
1916
1917 // Determine how to filter results, e.g., so that the names of
1918 // values (functions, enumerators, function templates, etc.) are
1919 // only allowed where we can have an expression.
1920 switch (CompletionContext) {
1921 case CCC_Namespace:
1922 case CCC_Class:
Douglas Gregorf1934162010-01-13 21:24:21 +00001923 case CCC_ObjCInterface:
1924 case CCC_ObjCImplementation:
Douglas Gregor48d46252010-01-13 21:54:15 +00001925 case CCC_ObjCInstanceVariableList:
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001926 case CCC_Template:
1927 case CCC_MemberTemplate:
1928 Results.setFilter(&ResultBuilder::IsOrdinaryNonValueName);
1929 break;
1930
1931 case CCC_Expression:
1932 case CCC_Statement:
1933 case CCC_ForInit:
1934 case CCC_Condition:
1935 Results.setFilter(&ResultBuilder::IsOrdinaryName);
1936 break;
1937 }
1938
Douglas Gregorc580c522010-01-14 01:09:38 +00001939 CodeCompletionDeclConsumer Consumer(Results, CurContext);
1940 LookupVisibleDecls(S, LookupOrdinaryName, Consumer);
Douglas Gregor92253692009-12-07 09:54:55 +00001941
1942 Results.EnterNewScope();
Douglas Gregorf98e6a22010-01-13 23:51:12 +00001943 AddOrdinaryNameResults(CompletionContext, S, *this, Results);
Douglas Gregor92253692009-12-07 09:54:55 +00001944 Results.ExitScope();
1945
Douglas Gregor9eb77012009-11-07 00:00:49 +00001946 if (CodeCompleter->includeMacros())
Douglas Gregorf98e6a22010-01-13 23:51:12 +00001947 AddMacroResults(PP, Results);
Daniel Dunbar242ea9a2009-11-13 08:58:20 +00001948 HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
Douglas Gregor9d64c5e2009-09-21 20:51:25 +00001949}
1950
Douglas Gregor9291bad2009-11-18 01:29:26 +00001951static void AddObjCProperties(ObjCContainerDecl *Container,
Douglas Gregor5d649882009-11-18 22:32:06 +00001952 bool AllowCategories,
Douglas Gregor9291bad2009-11-18 01:29:26 +00001953 DeclContext *CurContext,
1954 ResultBuilder &Results) {
1955 typedef CodeCompleteConsumer::Result Result;
1956
1957 // Add properties in this container.
1958 for (ObjCContainerDecl::prop_iterator P = Container->prop_begin(),
1959 PEnd = Container->prop_end();
1960 P != PEnd;
1961 ++P)
1962 Results.MaybeAddResult(Result(*P, 0), CurContext);
1963
1964 // Add properties in referenced protocols.
1965 if (ObjCProtocolDecl *Protocol = dyn_cast<ObjCProtocolDecl>(Container)) {
1966 for (ObjCProtocolDecl::protocol_iterator P = Protocol->protocol_begin(),
1967 PEnd = Protocol->protocol_end();
1968 P != PEnd; ++P)
Douglas Gregor5d649882009-11-18 22:32:06 +00001969 AddObjCProperties(*P, AllowCategories, CurContext, Results);
Douglas Gregor9291bad2009-11-18 01:29:26 +00001970 } else if (ObjCInterfaceDecl *IFace = dyn_cast<ObjCInterfaceDecl>(Container)){
Douglas Gregor5d649882009-11-18 22:32:06 +00001971 if (AllowCategories) {
1972 // Look through categories.
1973 for (ObjCCategoryDecl *Category = IFace->getCategoryList();
1974 Category; Category = Category->getNextClassCategory())
1975 AddObjCProperties(Category, AllowCategories, CurContext, Results);
1976 }
Douglas Gregor9291bad2009-11-18 01:29:26 +00001977
1978 // Look through protocols.
1979 for (ObjCInterfaceDecl::protocol_iterator I = IFace->protocol_begin(),
1980 E = IFace->protocol_end();
1981 I != E; ++I)
Douglas Gregor5d649882009-11-18 22:32:06 +00001982 AddObjCProperties(*I, AllowCategories, CurContext, Results);
Douglas Gregor9291bad2009-11-18 01:29:26 +00001983
1984 // Look in the superclass.
1985 if (IFace->getSuperClass())
Douglas Gregor5d649882009-11-18 22:32:06 +00001986 AddObjCProperties(IFace->getSuperClass(), AllowCategories, CurContext,
1987 Results);
Douglas Gregor9291bad2009-11-18 01:29:26 +00001988 } else if (const ObjCCategoryDecl *Category
1989 = dyn_cast<ObjCCategoryDecl>(Container)) {
1990 // Look through protocols.
1991 for (ObjCInterfaceDecl::protocol_iterator P = Category->protocol_begin(),
1992 PEnd = Category->protocol_end();
1993 P != PEnd; ++P)
Douglas Gregor5d649882009-11-18 22:32:06 +00001994 AddObjCProperties(*P, AllowCategories, CurContext, Results);
Douglas Gregor9291bad2009-11-18 01:29:26 +00001995 }
1996}
1997
Douglas Gregor2436e712009-09-17 21:32:03 +00001998void Sema::CodeCompleteMemberReferenceExpr(Scope *S, ExprTy *BaseE,
1999 SourceLocation OpLoc,
2000 bool IsArrow) {
2001 if (!BaseE || !CodeCompleter)
2002 return;
2003
Douglas Gregor3545ff42009-09-21 16:56:56 +00002004 typedef CodeCompleteConsumer::Result Result;
2005
Douglas Gregor2436e712009-09-17 21:32:03 +00002006 Expr *Base = static_cast<Expr *>(BaseE);
2007 QualType BaseType = Base->getType();
Douglas Gregor3545ff42009-09-21 16:56:56 +00002008
2009 if (IsArrow) {
2010 if (const PointerType *Ptr = BaseType->getAs<PointerType>())
2011 BaseType = Ptr->getPointeeType();
2012 else if (BaseType->isObjCObjectPointerType())
2013 /*Do nothing*/ ;
2014 else
2015 return;
2016 }
2017
Douglas Gregore412a5a2009-09-23 22:26:46 +00002018 ResultBuilder Results(*this, &ResultBuilder::IsMember);
Douglas Gregor9291bad2009-11-18 01:29:26 +00002019 Results.EnterNewScope();
2020 if (const RecordType *Record = BaseType->getAs<RecordType>()) {
2021 // Access to a C/C++ class, struct, or union.
Douglas Gregor6ae4c522010-01-14 03:21:49 +00002022 Results.allowNestedNameSpecifiers();
Douglas Gregor09bbc652010-01-14 15:47:35 +00002023 CodeCompletionDeclConsumer Consumer(Results, CurContext);
2024 LookupVisibleDecls(Record->getDecl(), LookupMemberName, Consumer);
Daniel Dunbar242ea9a2009-11-13 08:58:20 +00002025
Douglas Gregor9291bad2009-11-18 01:29:26 +00002026 if (getLangOptions().CPlusPlus) {
2027 if (!Results.empty()) {
2028 // The "template" keyword can follow "->" or "." in the grammar.
2029 // However, we only want to suggest the template keyword if something
2030 // is dependent.
2031 bool IsDependent = BaseType->isDependentType();
2032 if (!IsDependent) {
2033 for (Scope *DepScope = S; DepScope; DepScope = DepScope->getParent())
2034 if (DeclContext *Ctx = (DeclContext *)DepScope->getEntity()) {
2035 IsDependent = Ctx->isDependentContext();
2036 break;
2037 }
2038 }
Daniel Dunbar242ea9a2009-11-13 08:58:20 +00002039
Douglas Gregor9291bad2009-11-18 01:29:26 +00002040 if (IsDependent)
Douglas Gregor78a21012010-01-14 16:01:26 +00002041 Results.AddResult(Result("template"));
Daniel Dunbar242ea9a2009-11-13 08:58:20 +00002042 }
Daniel Dunbar242ea9a2009-11-13 08:58:20 +00002043 }
Douglas Gregor9291bad2009-11-18 01:29:26 +00002044 } else if (!IsArrow && BaseType->getAsObjCInterfacePointerType()) {
2045 // Objective-C property reference.
2046
2047 // Add property results based on our interface.
2048 const ObjCObjectPointerType *ObjCPtr
2049 = BaseType->getAsObjCInterfacePointerType();
2050 assert(ObjCPtr && "Non-NULL pointer guaranteed above!");
Douglas Gregor5d649882009-11-18 22:32:06 +00002051 AddObjCProperties(ObjCPtr->getInterfaceDecl(), true, CurContext, Results);
Douglas Gregor9291bad2009-11-18 01:29:26 +00002052
2053 // Add properties from the protocols in a qualified interface.
2054 for (ObjCObjectPointerType::qual_iterator I = ObjCPtr->qual_begin(),
2055 E = ObjCPtr->qual_end();
2056 I != E; ++I)
Douglas Gregor5d649882009-11-18 22:32:06 +00002057 AddObjCProperties(*I, true, CurContext, Results);
Douglas Gregor9291bad2009-11-18 01:29:26 +00002058 } else if ((IsArrow && BaseType->isObjCObjectPointerType()) ||
2059 (!IsArrow && BaseType->isObjCInterfaceType())) {
2060 // Objective-C instance variable access.
2061 ObjCInterfaceDecl *Class = 0;
2062 if (const ObjCObjectPointerType *ObjCPtr
2063 = BaseType->getAs<ObjCObjectPointerType>())
2064 Class = ObjCPtr->getInterfaceDecl();
2065 else
2066 Class = BaseType->getAs<ObjCInterfaceType>()->getDecl();
2067
2068 // Add all ivars from this class and its superclasses.
Douglas Gregor2b8162b2010-01-14 16:08:12 +00002069 if (Class) {
2070 CodeCompletionDeclConsumer Consumer(Results, CurContext);
2071 Results.setFilter(&ResultBuilder::IsObjCIvar);
2072 LookupVisibleDecls(Class, LookupMemberName, Consumer);
Douglas Gregor9291bad2009-11-18 01:29:26 +00002073 }
Douglas Gregor3545ff42009-09-21 16:56:56 +00002074 }
Douglas Gregor9291bad2009-11-18 01:29:26 +00002075
2076 // FIXME: How do we cope with isa?
2077
2078 Results.ExitScope();
Daniel Dunbar242ea9a2009-11-13 08:58:20 +00002079
Daniel Dunbar242ea9a2009-11-13 08:58:20 +00002080 // Hand off the results found for code completion.
2081 HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
Douglas Gregor2436e712009-09-17 21:32:03 +00002082}
2083
Douglas Gregorf45b0cf2009-09-18 15:37:17 +00002084void Sema::CodeCompleteTag(Scope *S, unsigned TagSpec) {
2085 if (!CodeCompleter)
2086 return;
2087
Douglas Gregor3545ff42009-09-21 16:56:56 +00002088 typedef CodeCompleteConsumer::Result Result;
2089 ResultBuilder::LookupFilter Filter = 0;
Douglas Gregorf45b0cf2009-09-18 15:37:17 +00002090 switch ((DeclSpec::TST)TagSpec) {
2091 case DeclSpec::TST_enum:
Douglas Gregor3545ff42009-09-21 16:56:56 +00002092 Filter = &ResultBuilder::IsEnum;
Douglas Gregorf45b0cf2009-09-18 15:37:17 +00002093 break;
2094
2095 case DeclSpec::TST_union:
Douglas Gregor3545ff42009-09-21 16:56:56 +00002096 Filter = &ResultBuilder::IsUnion;
Douglas Gregorf45b0cf2009-09-18 15:37:17 +00002097 break;
2098
2099 case DeclSpec::TST_struct:
Douglas Gregorf45b0cf2009-09-18 15:37:17 +00002100 case DeclSpec::TST_class:
Douglas Gregor3545ff42009-09-21 16:56:56 +00002101 Filter = &ResultBuilder::IsClassOrStruct;
Douglas Gregorf45b0cf2009-09-18 15:37:17 +00002102 break;
2103
2104 default:
2105 assert(false && "Unknown type specifier kind in CodeCompleteTag");
2106 return;
2107 }
Douglas Gregor3545ff42009-09-21 16:56:56 +00002108
2109 ResultBuilder Results(*this, Filter);
Douglas Gregor6ae4c522010-01-14 03:21:49 +00002110 Results.allowNestedNameSpecifiers();
Douglas Gregora6e2edc2010-01-14 03:27:13 +00002111 CodeCompletionDeclConsumer Consumer(Results, CurContext);
2112 LookupVisibleDecls(S, LookupTagName, Consumer);
Douglas Gregor3545ff42009-09-21 16:56:56 +00002113
Daniel Dunbar242ea9a2009-11-13 08:58:20 +00002114 HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
Douglas Gregorf45b0cf2009-09-18 15:37:17 +00002115}
2116
Douglas Gregord328d572009-09-21 18:10:23 +00002117void Sema::CodeCompleteCase(Scope *S) {
2118 if (getSwitchStack().empty() || !CodeCompleter)
2119 return;
2120
2121 SwitchStmt *Switch = getSwitchStack().back();
2122 if (!Switch->getCond()->getType()->isEnumeralType())
2123 return;
2124
2125 // Code-complete the cases of a switch statement over an enumeration type
2126 // by providing the list of
2127 EnumDecl *Enum = Switch->getCond()->getType()->getAs<EnumType>()->getDecl();
2128
2129 // Determine which enumerators we have already seen in the switch statement.
2130 // FIXME: Ideally, we would also be able to look *past* the code-completion
2131 // token, in case we are code-completing in the middle of the switch and not
2132 // at the end. However, we aren't able to do so at the moment.
2133 llvm::SmallPtrSet<EnumConstantDecl *, 8> EnumeratorsSeen;
Douglas Gregorf2510672009-09-21 19:57:38 +00002134 NestedNameSpecifier *Qualifier = 0;
Douglas Gregord328d572009-09-21 18:10:23 +00002135 for (SwitchCase *SC = Switch->getSwitchCaseList(); SC;
2136 SC = SC->getNextSwitchCase()) {
2137 CaseStmt *Case = dyn_cast<CaseStmt>(SC);
2138 if (!Case)
2139 continue;
2140
2141 Expr *CaseVal = Case->getLHS()->IgnoreParenCasts();
2142 if (DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(CaseVal))
2143 if (EnumConstantDecl *Enumerator
2144 = dyn_cast<EnumConstantDecl>(DRE->getDecl())) {
2145 // We look into the AST of the case statement to determine which
2146 // enumerator was named. Alternatively, we could compute the value of
2147 // the integral constant expression, then compare it against the
2148 // values of each enumerator. However, value-based approach would not
2149 // work as well with C++ templates where enumerators declared within a
2150 // template are type- and value-dependent.
2151 EnumeratorsSeen.insert(Enumerator);
2152
Douglas Gregorf2510672009-09-21 19:57:38 +00002153 // If this is a qualified-id, keep track of the nested-name-specifier
2154 // so that we can reproduce it as part of code completion, e.g.,
Douglas Gregord328d572009-09-21 18:10:23 +00002155 //
2156 // switch (TagD.getKind()) {
2157 // case TagDecl::TK_enum:
2158 // break;
2159 // case XXX
2160 //
Douglas Gregorf2510672009-09-21 19:57:38 +00002161 // At the XXX, our completions are TagDecl::TK_union,
Douglas Gregord328d572009-09-21 18:10:23 +00002162 // TagDecl::TK_struct, and TagDecl::TK_class, rather than TK_union,
2163 // TK_struct, and TK_class.
Douglas Gregor4bd90e52009-10-23 18:54:35 +00002164 Qualifier = DRE->getQualifier();
Douglas Gregord328d572009-09-21 18:10:23 +00002165 }
2166 }
2167
Douglas Gregorf2510672009-09-21 19:57:38 +00002168 if (getLangOptions().CPlusPlus && !Qualifier && EnumeratorsSeen.empty()) {
2169 // If there are no prior enumerators in C++, check whether we have to
2170 // qualify the names of the enumerators that we suggest, because they
2171 // may not be visible in this scope.
2172 Qualifier = getRequiredQualification(Context, CurContext,
2173 Enum->getDeclContext());
2174
2175 // FIXME: Scoped enums need to start with "EnumDecl" as the context!
2176 }
2177
Douglas Gregord328d572009-09-21 18:10:23 +00002178 // Add any enumerators that have not yet been mentioned.
2179 ResultBuilder Results(*this);
2180 Results.EnterNewScope();
2181 for (EnumDecl::enumerator_iterator E = Enum->enumerator_begin(),
2182 EEnd = Enum->enumerator_end();
2183 E != EEnd; ++E) {
2184 if (EnumeratorsSeen.count(*E))
2185 continue;
2186
Douglas Gregorfc59ce12010-01-14 16:14:35 +00002187 Results.AddResult(CodeCompleteConsumer::Result(*E, Qualifier),
2188 CurContext, 0, false);
Douglas Gregord328d572009-09-21 18:10:23 +00002189 }
2190 Results.ExitScope();
Douglas Gregor285560922010-04-06 20:02:15 +00002191
Douglas Gregor9eb77012009-11-07 00:00:49 +00002192 if (CodeCompleter->includeMacros())
Douglas Gregorf98e6a22010-01-13 23:51:12 +00002193 AddMacroResults(PP, Results);
Daniel Dunbar242ea9a2009-11-13 08:58:20 +00002194 HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
Douglas Gregord328d572009-09-21 18:10:23 +00002195}
2196
Douglas Gregorcabea402009-09-22 15:41:20 +00002197namespace {
2198 struct IsBetterOverloadCandidate {
2199 Sema &S;
John McCallbc077cf2010-02-08 23:07:23 +00002200 SourceLocation Loc;
Douglas Gregorcabea402009-09-22 15:41:20 +00002201
2202 public:
John McCallbc077cf2010-02-08 23:07:23 +00002203 explicit IsBetterOverloadCandidate(Sema &S, SourceLocation Loc)
2204 : S(S), Loc(Loc) { }
Douglas Gregorcabea402009-09-22 15:41:20 +00002205
2206 bool
2207 operator()(const OverloadCandidate &X, const OverloadCandidate &Y) const {
John McCallbc077cf2010-02-08 23:07:23 +00002208 return S.isBetterOverloadCandidate(X, Y, Loc);
Douglas Gregorcabea402009-09-22 15:41:20 +00002209 }
2210 };
2211}
2212
2213void Sema::CodeCompleteCall(Scope *S, ExprTy *FnIn,
2214 ExprTy **ArgsIn, unsigned NumArgs) {
2215 if (!CodeCompleter)
2216 return;
Douglas Gregor3ef59522009-12-11 19:06:04 +00002217
2218 // When we're code-completing for a call, we fall back to ordinary
2219 // name code-completion whenever we can't produce specific
2220 // results. We may want to revisit this strategy in the future,
2221 // e.g., by merging the two kinds of results.
2222
Douglas Gregorcabea402009-09-22 15:41:20 +00002223 Expr *Fn = (Expr *)FnIn;
2224 Expr **Args = (Expr **)ArgsIn;
Douglas Gregor3ef59522009-12-11 19:06:04 +00002225
Douglas Gregorcabea402009-09-22 15:41:20 +00002226 // Ignore type-dependent call expressions entirely.
2227 if (Fn->isTypeDependent() ||
Douglas Gregor3ef59522009-12-11 19:06:04 +00002228 Expr::hasAnyTypeDependentArguments(Args, NumArgs)) {
Douglas Gregor504a6ae2010-01-10 23:08:15 +00002229 CodeCompleteOrdinaryName(S, CCC_Expression);
Douglas Gregorcabea402009-09-22 15:41:20 +00002230 return;
Douglas Gregor3ef59522009-12-11 19:06:04 +00002231 }
Douglas Gregorcabea402009-09-22 15:41:20 +00002232
John McCall57500772009-12-16 12:17:52 +00002233 // Build an overload candidate set based on the functions we find.
John McCallbc077cf2010-02-08 23:07:23 +00002234 SourceLocation Loc = Fn->getExprLoc();
2235 OverloadCandidateSet CandidateSet(Loc);
John McCall57500772009-12-16 12:17:52 +00002236
Douglas Gregorcabea402009-09-22 15:41:20 +00002237 // FIXME: What if we're calling something that isn't a function declaration?
2238 // FIXME: What if we're calling a pseudo-destructor?
2239 // FIXME: What if we're calling a member function?
2240
Douglas Gregorff59f672010-01-21 15:46:19 +00002241 typedef CodeCompleteConsumer::OverloadCandidate ResultCandidate;
2242 llvm::SmallVector<ResultCandidate, 8> Results;
2243
John McCall57500772009-12-16 12:17:52 +00002244 Expr *NakedFn = Fn->IgnoreParenCasts();
2245 if (UnresolvedLookupExpr *ULE = dyn_cast<UnresolvedLookupExpr>(NakedFn))
2246 AddOverloadedCallCandidates(ULE, Args, NumArgs, CandidateSet,
2247 /*PartialOverloading=*/ true);
2248 else if (DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(NakedFn)) {
2249 FunctionDecl *FDecl = dyn_cast<FunctionDecl>(DRE->getDecl());
Douglas Gregorff59f672010-01-21 15:46:19 +00002250 if (FDecl) {
2251 if (!FDecl->getType()->getAs<FunctionProtoType>())
2252 Results.push_back(ResultCandidate(FDecl));
2253 else
John McCallb89836b2010-01-26 01:37:31 +00002254 // FIXME: access?
John McCalla0296f72010-03-19 07:35:19 +00002255 AddOverloadCandidate(FDecl, DeclAccessPair::make(FDecl, AS_none),
2256 Args, NumArgs, CandidateSet,
Douglas Gregorff59f672010-01-21 15:46:19 +00002257 false, false, /*PartialOverloading*/ true);
2258 }
John McCall57500772009-12-16 12:17:52 +00002259 }
Douglas Gregorcabea402009-09-22 15:41:20 +00002260
Douglas Gregorff59f672010-01-21 15:46:19 +00002261 if (!CandidateSet.empty()) {
2262 // Sort the overload candidate set by placing the best overloads first.
2263 std::stable_sort(CandidateSet.begin(), CandidateSet.end(),
John McCallbc077cf2010-02-08 23:07:23 +00002264 IsBetterOverloadCandidate(*this, Loc));
Douglas Gregorcabea402009-09-22 15:41:20 +00002265
Douglas Gregorff59f672010-01-21 15:46:19 +00002266 // Add the remaining viable overload candidates as code-completion reslults.
2267 for (OverloadCandidateSet::iterator Cand = CandidateSet.begin(),
2268 CandEnd = CandidateSet.end();
2269 Cand != CandEnd; ++Cand) {
2270 if (Cand->Viable)
2271 Results.push_back(ResultCandidate(Cand->Function));
2272 }
Douglas Gregorcabea402009-09-22 15:41:20 +00002273 }
Douglas Gregor3ef59522009-12-11 19:06:04 +00002274
2275 if (Results.empty())
Douglas Gregor504a6ae2010-01-10 23:08:15 +00002276 CodeCompleteOrdinaryName(S, CCC_Expression);
Douglas Gregor3ef59522009-12-11 19:06:04 +00002277 else
2278 CodeCompleter->ProcessOverloadCandidates(*this, NumArgs, Results.data(),
2279 Results.size());
Douglas Gregorcabea402009-09-22 15:41:20 +00002280}
2281
Douglas Gregor2436e712009-09-17 21:32:03 +00002282void Sema::CodeCompleteQualifiedId(Scope *S, const CXXScopeSpec &SS,
2283 bool EnteringContext) {
2284 if (!SS.getScopeRep() || !CodeCompleter)
2285 return;
2286
Douglas Gregor3545ff42009-09-21 16:56:56 +00002287 DeclContext *Ctx = computeDeclContext(SS, EnteringContext);
2288 if (!Ctx)
2289 return;
Douglas Gregor800f2f02009-12-11 18:28:39 +00002290
2291 // Try to instantiate any non-dependent declaration contexts before
2292 // we look in them.
2293 if (!isDependentScopeSpecifier(SS) && RequireCompleteDeclContext(SS))
2294 return;
2295
Douglas Gregor3545ff42009-09-21 16:56:56 +00002296 ResultBuilder Results(*this);
Douglas Gregor200c99d2010-01-14 03:35:48 +00002297 CodeCompletionDeclConsumer Consumer(Results, CurContext);
2298 LookupVisibleDecls(Ctx, LookupOrdinaryName, Consumer);
Douglas Gregor3545ff42009-09-21 16:56:56 +00002299
2300 // The "template" keyword can follow "::" in the grammar, but only
2301 // put it into the grammar if the nested-name-specifier is dependent.
2302 NestedNameSpecifier *NNS = (NestedNameSpecifier *)SS.getScopeRep();
2303 if (!Results.empty() && NNS->isDependent())
Douglas Gregor78a21012010-01-14 16:01:26 +00002304 Results.AddResult("template");
Douglas Gregor3545ff42009-09-21 16:56:56 +00002305
Daniel Dunbar242ea9a2009-11-13 08:58:20 +00002306 HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
Douglas Gregor2436e712009-09-17 21:32:03 +00002307}
Douglas Gregor7e90c6d2009-09-18 19:03:04 +00002308
2309void Sema::CodeCompleteUsing(Scope *S) {
2310 if (!CodeCompleter)
2311 return;
2312
Douglas Gregor3545ff42009-09-21 16:56:56 +00002313 ResultBuilder Results(*this, &ResultBuilder::IsNestedNameSpecifier);
Douglas Gregor64b12b52009-09-22 23:31:26 +00002314 Results.EnterNewScope();
Douglas Gregor3545ff42009-09-21 16:56:56 +00002315
2316 // If we aren't in class scope, we could see the "namespace" keyword.
2317 if (!S->isClassScope())
Douglas Gregor78a21012010-01-14 16:01:26 +00002318 Results.AddResult(CodeCompleteConsumer::Result("namespace"));
Douglas Gregor3545ff42009-09-21 16:56:56 +00002319
2320 // After "using", we can see anything that would start a
2321 // nested-name-specifier.
Douglas Gregora6e2edc2010-01-14 03:27:13 +00002322 CodeCompletionDeclConsumer Consumer(Results, CurContext);
2323 LookupVisibleDecls(S, LookupOrdinaryName, Consumer);
Douglas Gregor64b12b52009-09-22 23:31:26 +00002324 Results.ExitScope();
Douglas Gregor3545ff42009-09-21 16:56:56 +00002325
Daniel Dunbar242ea9a2009-11-13 08:58:20 +00002326 HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
Douglas Gregor7e90c6d2009-09-18 19:03:04 +00002327}
2328
2329void Sema::CodeCompleteUsingDirective(Scope *S) {
2330 if (!CodeCompleter)
2331 return;
2332
Douglas Gregor3545ff42009-09-21 16:56:56 +00002333 // After "using namespace", we expect to see a namespace name or namespace
2334 // alias.
2335 ResultBuilder Results(*this, &ResultBuilder::IsNamespaceOrAlias);
Douglas Gregor64b12b52009-09-22 23:31:26 +00002336 Results.EnterNewScope();
Douglas Gregora6e2edc2010-01-14 03:27:13 +00002337 CodeCompletionDeclConsumer Consumer(Results, CurContext);
2338 LookupVisibleDecls(S, LookupOrdinaryName, Consumer);
Douglas Gregor64b12b52009-09-22 23:31:26 +00002339 Results.ExitScope();
Daniel Dunbar242ea9a2009-11-13 08:58:20 +00002340 HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
Douglas Gregor7e90c6d2009-09-18 19:03:04 +00002341}
2342
2343void Sema::CodeCompleteNamespaceDecl(Scope *S) {
2344 if (!CodeCompleter)
2345 return;
2346
Douglas Gregor3545ff42009-09-21 16:56:56 +00002347 ResultBuilder Results(*this, &ResultBuilder::IsNamespace);
2348 DeclContext *Ctx = (DeclContext *)S->getEntity();
2349 if (!S->getParent())
2350 Ctx = Context.getTranslationUnitDecl();
2351
2352 if (Ctx && Ctx->isFileContext()) {
2353 // We only want to see those namespaces that have already been defined
2354 // within this scope, because its likely that the user is creating an
2355 // extended namespace declaration. Keep track of the most recent
2356 // definition of each namespace.
2357 std::map<NamespaceDecl *, NamespaceDecl *> OrigToLatest;
2358 for (DeclContext::specific_decl_iterator<NamespaceDecl>
2359 NS(Ctx->decls_begin()), NSEnd(Ctx->decls_end());
2360 NS != NSEnd; ++NS)
2361 OrigToLatest[NS->getOriginalNamespace()] = *NS;
2362
2363 // Add the most recent definition (or extended definition) of each
2364 // namespace to the list of results.
Douglas Gregor64b12b52009-09-22 23:31:26 +00002365 Results.EnterNewScope();
Douglas Gregor3545ff42009-09-21 16:56:56 +00002366 for (std::map<NamespaceDecl *, NamespaceDecl *>::iterator
2367 NS = OrigToLatest.begin(), NSEnd = OrigToLatest.end();
2368 NS != NSEnd; ++NS)
Douglas Gregorfc59ce12010-01-14 16:14:35 +00002369 Results.AddResult(CodeCompleteConsumer::Result(NS->second, 0),
2370 CurContext, 0, false);
Douglas Gregor64b12b52009-09-22 23:31:26 +00002371 Results.ExitScope();
Douglas Gregor3545ff42009-09-21 16:56:56 +00002372 }
2373
Daniel Dunbar242ea9a2009-11-13 08:58:20 +00002374 HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
Douglas Gregor7e90c6d2009-09-18 19:03:04 +00002375}
2376
2377void Sema::CodeCompleteNamespaceAliasDecl(Scope *S) {
2378 if (!CodeCompleter)
2379 return;
2380
Douglas Gregor3545ff42009-09-21 16:56:56 +00002381 // After "namespace", we expect to see a namespace or alias.
2382 ResultBuilder Results(*this, &ResultBuilder::IsNamespaceOrAlias);
Douglas Gregora6e2edc2010-01-14 03:27:13 +00002383 CodeCompletionDeclConsumer Consumer(Results, CurContext);
2384 LookupVisibleDecls(S, LookupOrdinaryName, Consumer);
Daniel Dunbar242ea9a2009-11-13 08:58:20 +00002385 HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
Douglas Gregor7e90c6d2009-09-18 19:03:04 +00002386}
2387
Douglas Gregorc811ede2009-09-18 20:05:18 +00002388void Sema::CodeCompleteOperatorName(Scope *S) {
2389 if (!CodeCompleter)
2390 return;
Douglas Gregor3545ff42009-09-21 16:56:56 +00002391
2392 typedef CodeCompleteConsumer::Result Result;
2393 ResultBuilder Results(*this, &ResultBuilder::IsType);
Douglas Gregor64b12b52009-09-22 23:31:26 +00002394 Results.EnterNewScope();
Douglas Gregorc811ede2009-09-18 20:05:18 +00002395
Douglas Gregor3545ff42009-09-21 16:56:56 +00002396 // Add the names of overloadable operators.
2397#define OVERLOADED_OPERATOR(Name,Spelling,Token,Unary,Binary,MemberOnly) \
2398 if (std::strcmp(Spelling, "?")) \
Douglas Gregor78a21012010-01-14 16:01:26 +00002399 Results.AddResult(Result(Spelling));
Douglas Gregor3545ff42009-09-21 16:56:56 +00002400#include "clang/Basic/OperatorKinds.def"
2401
2402 // Add any type names visible from the current scope
Douglas Gregor6ae4c522010-01-14 03:21:49 +00002403 Results.allowNestedNameSpecifiers();
Douglas Gregora6e2edc2010-01-14 03:27:13 +00002404 CodeCompletionDeclConsumer Consumer(Results, CurContext);
2405 LookupVisibleDecls(S, LookupOrdinaryName, Consumer);
Douglas Gregor3545ff42009-09-21 16:56:56 +00002406
2407 // Add any type specifiers
Douglas Gregorf98e6a22010-01-13 23:51:12 +00002408 AddTypeSpecifierResults(getLangOptions(), Results);
Douglas Gregor64b12b52009-09-22 23:31:26 +00002409 Results.ExitScope();
Douglas Gregor3545ff42009-09-21 16:56:56 +00002410
Daniel Dunbar242ea9a2009-11-13 08:58:20 +00002411 HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
Douglas Gregorc811ede2009-09-18 20:05:18 +00002412}
Douglas Gregor7e90c6d2009-09-18 19:03:04 +00002413
Douglas Gregorf1934162010-01-13 21:24:21 +00002414// Macro that expands to @Keyword or Keyword, depending on whether NeedAt is
2415// true or false.
2416#define OBJC_AT_KEYWORD_NAME(NeedAt,Keyword) NeedAt? "@" #Keyword : #Keyword
Douglas Gregorf98e6a22010-01-13 23:51:12 +00002417static void AddObjCImplementationResults(const LangOptions &LangOpts,
Douglas Gregorf1934162010-01-13 21:24:21 +00002418 ResultBuilder &Results,
2419 bool NeedAt) {
2420 typedef CodeCompleteConsumer::Result Result;
2421 // Since we have an implementation, we can end it.
Douglas Gregor78a21012010-01-14 16:01:26 +00002422 Results.AddResult(Result(OBJC_AT_KEYWORD_NAME(NeedAt,end)));
Douglas Gregorf1934162010-01-13 21:24:21 +00002423
2424 CodeCompletionString *Pattern = 0;
2425 if (LangOpts.ObjC2) {
2426 // @dynamic
2427 Pattern = new CodeCompletionString;
2428 Pattern->AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt,dynamic));
2429 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
2430 Pattern->AddPlaceholderChunk("property");
Douglas Gregor78a21012010-01-14 16:01:26 +00002431 Results.AddResult(Result(Pattern));
Douglas Gregorf1934162010-01-13 21:24:21 +00002432
2433 // @synthesize
2434 Pattern = new CodeCompletionString;
2435 Pattern->AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt,synthesize));
2436 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
2437 Pattern->AddPlaceholderChunk("property");
Douglas Gregor78a21012010-01-14 16:01:26 +00002438 Results.AddResult(Result(Pattern));
Douglas Gregorf1934162010-01-13 21:24:21 +00002439 }
2440}
2441
Douglas Gregorf98e6a22010-01-13 23:51:12 +00002442static void AddObjCInterfaceResults(const LangOptions &LangOpts,
Douglas Gregorf1934162010-01-13 21:24:21 +00002443 ResultBuilder &Results,
2444 bool NeedAt) {
2445 typedef CodeCompleteConsumer::Result Result;
2446
2447 // Since we have an interface or protocol, we can end it.
Douglas Gregor78a21012010-01-14 16:01:26 +00002448 Results.AddResult(Result(OBJC_AT_KEYWORD_NAME(NeedAt,end)));
Douglas Gregorf1934162010-01-13 21:24:21 +00002449
2450 if (LangOpts.ObjC2) {
2451 // @property
Douglas Gregor78a21012010-01-14 16:01:26 +00002452 Results.AddResult(Result(OBJC_AT_KEYWORD_NAME(NeedAt,property)));
Douglas Gregorf1934162010-01-13 21:24:21 +00002453
2454 // @required
Douglas Gregor78a21012010-01-14 16:01:26 +00002455 Results.AddResult(Result(OBJC_AT_KEYWORD_NAME(NeedAt,required)));
Douglas Gregorf1934162010-01-13 21:24:21 +00002456
2457 // @optional
Douglas Gregor78a21012010-01-14 16:01:26 +00002458 Results.AddResult(Result(OBJC_AT_KEYWORD_NAME(NeedAt,optional)));
Douglas Gregorf1934162010-01-13 21:24:21 +00002459 }
2460}
2461
Douglas Gregorf98e6a22010-01-13 23:51:12 +00002462static void AddObjCTopLevelResults(ResultBuilder &Results, bool NeedAt) {
Douglas Gregorf1934162010-01-13 21:24:21 +00002463 typedef CodeCompleteConsumer::Result Result;
2464 CodeCompletionString *Pattern = 0;
2465
2466 // @class name ;
2467 Pattern = new CodeCompletionString;
2468 Pattern->AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt,class));
2469 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
2470 Pattern->AddPlaceholderChunk("identifier");
2471 Pattern->AddChunk(CodeCompletionString::CK_SemiColon);
Douglas Gregor78a21012010-01-14 16:01:26 +00002472 Results.AddResult(Result(Pattern));
Douglas Gregorf1934162010-01-13 21:24:21 +00002473
2474 // @interface name
2475 // FIXME: Could introduce the whole pattern, including superclasses and
2476 // such.
2477 Pattern = new CodeCompletionString;
2478 Pattern->AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt,interface));
2479 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
2480 Pattern->AddPlaceholderChunk("class");
Douglas Gregor78a21012010-01-14 16:01:26 +00002481 Results.AddResult(Result(Pattern));
Douglas Gregorf1934162010-01-13 21:24:21 +00002482
2483 // @protocol name
2484 Pattern = new CodeCompletionString;
2485 Pattern->AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt,protocol));
2486 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
2487 Pattern->AddPlaceholderChunk("protocol");
Douglas Gregor78a21012010-01-14 16:01:26 +00002488 Results.AddResult(Result(Pattern));
Douglas Gregorf1934162010-01-13 21:24:21 +00002489
2490 // @implementation name
2491 Pattern = new CodeCompletionString;
2492 Pattern->AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt,implementation));
2493 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
2494 Pattern->AddPlaceholderChunk("class");
Douglas Gregor78a21012010-01-14 16:01:26 +00002495 Results.AddResult(Result(Pattern));
Douglas Gregorf1934162010-01-13 21:24:21 +00002496
2497 // @compatibility_alias name
2498 Pattern = new CodeCompletionString;
2499 Pattern->AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt,compatibility_alias));
2500 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
2501 Pattern->AddPlaceholderChunk("alias");
2502 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
2503 Pattern->AddPlaceholderChunk("class");
Douglas Gregor78a21012010-01-14 16:01:26 +00002504 Results.AddResult(Result(Pattern));
Douglas Gregorf1934162010-01-13 21:24:21 +00002505}
2506
Douglas Gregorf48706c2009-12-07 09:27:33 +00002507void Sema::CodeCompleteObjCAtDirective(Scope *S, DeclPtrTy ObjCImpDecl,
2508 bool InInterface) {
2509 typedef CodeCompleteConsumer::Result Result;
2510 ResultBuilder Results(*this);
2511 Results.EnterNewScope();
Douglas Gregorf1934162010-01-13 21:24:21 +00002512 if (ObjCImpDecl)
Douglas Gregorf98e6a22010-01-13 23:51:12 +00002513 AddObjCImplementationResults(getLangOptions(), Results, false);
Douglas Gregorf1934162010-01-13 21:24:21 +00002514 else if (InInterface)
Douglas Gregorf98e6a22010-01-13 23:51:12 +00002515 AddObjCInterfaceResults(getLangOptions(), Results, false);
Douglas Gregorf1934162010-01-13 21:24:21 +00002516 else
Douglas Gregorf98e6a22010-01-13 23:51:12 +00002517 AddObjCTopLevelResults(Results, false);
Douglas Gregorf48706c2009-12-07 09:27:33 +00002518 Results.ExitScope();
2519 HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
2520}
2521
Douglas Gregorf98e6a22010-01-13 23:51:12 +00002522static void AddObjCExpressionResults(ResultBuilder &Results, bool NeedAt) {
Douglas Gregorbc7c5e42009-12-07 09:51:25 +00002523 typedef CodeCompleteConsumer::Result Result;
2524 CodeCompletionString *Pattern = 0;
2525
2526 // @encode ( type-name )
2527 Pattern = new CodeCompletionString;
Douglas Gregorf1934162010-01-13 21:24:21 +00002528 Pattern->AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt,encode));
Douglas Gregorbc7c5e42009-12-07 09:51:25 +00002529 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
2530 Pattern->AddPlaceholderChunk("type-name");
2531 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
Douglas Gregor78a21012010-01-14 16:01:26 +00002532 Results.AddResult(Result(Pattern));
Douglas Gregorbc7c5e42009-12-07 09:51:25 +00002533
2534 // @protocol ( protocol-name )
2535 Pattern = new CodeCompletionString;
Douglas Gregorf1934162010-01-13 21:24:21 +00002536 Pattern->AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt,protocol));
Douglas Gregorbc7c5e42009-12-07 09:51:25 +00002537 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
2538 Pattern->AddPlaceholderChunk("protocol-name");
2539 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
Douglas Gregor78a21012010-01-14 16:01:26 +00002540 Results.AddResult(Result(Pattern));
Douglas Gregorbc7c5e42009-12-07 09:51:25 +00002541
2542 // @selector ( selector )
2543 Pattern = new CodeCompletionString;
Douglas Gregorf1934162010-01-13 21:24:21 +00002544 Pattern->AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt,selector));
Douglas Gregorbc7c5e42009-12-07 09:51:25 +00002545 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
2546 Pattern->AddPlaceholderChunk("selector");
2547 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
Douglas Gregor78a21012010-01-14 16:01:26 +00002548 Results.AddResult(Result(Pattern));
Douglas Gregorbc7c5e42009-12-07 09:51:25 +00002549}
2550
Douglas Gregorf98e6a22010-01-13 23:51:12 +00002551static void AddObjCStatementResults(ResultBuilder &Results, bool NeedAt) {
Douglas Gregorbc7c5e42009-12-07 09:51:25 +00002552 typedef CodeCompleteConsumer::Result Result;
Douglas Gregorbc7c5e42009-12-07 09:51:25 +00002553 CodeCompletionString *Pattern = 0;
Douglas Gregorf1934162010-01-13 21:24:21 +00002554
Douglas Gregorbc7c5e42009-12-07 09:51:25 +00002555 // @try { statements } @catch ( declaration ) { statements } @finally
2556 // { statements }
2557 Pattern = new CodeCompletionString;
Douglas Gregorf1934162010-01-13 21:24:21 +00002558 Pattern->AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt,try));
Douglas Gregorbc7c5e42009-12-07 09:51:25 +00002559 Pattern->AddChunk(CodeCompletionString::CK_LeftBrace);
2560 Pattern->AddPlaceholderChunk("statements");
2561 Pattern->AddChunk(CodeCompletionString::CK_RightBrace);
2562 Pattern->AddTextChunk("@catch");
2563 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
2564 Pattern->AddPlaceholderChunk("parameter");
2565 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
2566 Pattern->AddChunk(CodeCompletionString::CK_LeftBrace);
2567 Pattern->AddPlaceholderChunk("statements");
2568 Pattern->AddChunk(CodeCompletionString::CK_RightBrace);
2569 Pattern->AddTextChunk("@finally");
2570 Pattern->AddChunk(CodeCompletionString::CK_LeftBrace);
2571 Pattern->AddPlaceholderChunk("statements");
2572 Pattern->AddChunk(CodeCompletionString::CK_RightBrace);
Douglas Gregor78a21012010-01-14 16:01:26 +00002573 Results.AddResult(Result(Pattern));
Douglas Gregorf1934162010-01-13 21:24:21 +00002574
Douglas Gregorbc7c5e42009-12-07 09:51:25 +00002575 // @throw
2576 Pattern = new CodeCompletionString;
Douglas Gregorf1934162010-01-13 21:24:21 +00002577 Pattern->AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt,throw));
Douglas Gregor6a803932010-01-12 06:38:28 +00002578 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
Douglas Gregorbc7c5e42009-12-07 09:51:25 +00002579 Pattern->AddPlaceholderChunk("expression");
Douglas Gregor6a803932010-01-12 06:38:28 +00002580 Pattern->AddChunk(CodeCompletionString::CK_SemiColon);
Douglas Gregor78a21012010-01-14 16:01:26 +00002581 Results.AddResult(Result(Pattern));
Douglas Gregorf1934162010-01-13 21:24:21 +00002582
Douglas Gregorbc7c5e42009-12-07 09:51:25 +00002583 // @synchronized ( expression ) { statements }
2584 Pattern = new CodeCompletionString;
Douglas Gregorf1934162010-01-13 21:24:21 +00002585 Pattern->AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt,synchronized));
Douglas Gregor6a803932010-01-12 06:38:28 +00002586 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
Douglas Gregorbc7c5e42009-12-07 09:51:25 +00002587 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
2588 Pattern->AddPlaceholderChunk("expression");
2589 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
2590 Pattern->AddChunk(CodeCompletionString::CK_LeftBrace);
2591 Pattern->AddPlaceholderChunk("statements");
2592 Pattern->AddChunk(CodeCompletionString::CK_RightBrace);
Douglas Gregor78a21012010-01-14 16:01:26 +00002593 Results.AddResult(Result(Pattern));
Douglas Gregorf1934162010-01-13 21:24:21 +00002594}
Douglas Gregorbc7c5e42009-12-07 09:51:25 +00002595
Douglas Gregorf98e6a22010-01-13 23:51:12 +00002596static void AddObjCVisibilityResults(const LangOptions &LangOpts,
Douglas Gregor48d46252010-01-13 21:54:15 +00002597 ResultBuilder &Results,
2598 bool NeedAt) {
Douglas Gregorf1934162010-01-13 21:24:21 +00002599 typedef CodeCompleteConsumer::Result Result;
Douglas Gregor78a21012010-01-14 16:01:26 +00002600 Results.AddResult(Result(OBJC_AT_KEYWORD_NAME(NeedAt,private)));
2601 Results.AddResult(Result(OBJC_AT_KEYWORD_NAME(NeedAt,protected)));
2602 Results.AddResult(Result(OBJC_AT_KEYWORD_NAME(NeedAt,public)));
Douglas Gregor48d46252010-01-13 21:54:15 +00002603 if (LangOpts.ObjC2)
Douglas Gregor78a21012010-01-14 16:01:26 +00002604 Results.AddResult(Result(OBJC_AT_KEYWORD_NAME(NeedAt,package)));
Douglas Gregor48d46252010-01-13 21:54:15 +00002605}
2606
2607void Sema::CodeCompleteObjCAtVisibility(Scope *S) {
2608 ResultBuilder Results(*this);
2609 Results.EnterNewScope();
Douglas Gregorf98e6a22010-01-13 23:51:12 +00002610 AddObjCVisibilityResults(getLangOptions(), Results, false);
Douglas Gregor48d46252010-01-13 21:54:15 +00002611 Results.ExitScope();
2612 HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
2613}
2614
2615void Sema::CodeCompleteObjCAtStatement(Scope *S) {
Douglas Gregorf1934162010-01-13 21:24:21 +00002616 ResultBuilder Results(*this);
2617 Results.EnterNewScope();
Douglas Gregorf98e6a22010-01-13 23:51:12 +00002618 AddObjCStatementResults(Results, false);
2619 AddObjCExpressionResults(Results, false);
Douglas Gregorbc7c5e42009-12-07 09:51:25 +00002620 Results.ExitScope();
2621 HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
2622}
2623
2624void Sema::CodeCompleteObjCAtExpression(Scope *S) {
2625 ResultBuilder Results(*this);
2626 Results.EnterNewScope();
Douglas Gregorf98e6a22010-01-13 23:51:12 +00002627 AddObjCExpressionResults(Results, false);
Douglas Gregorbc7c5e42009-12-07 09:51:25 +00002628 Results.ExitScope();
2629 HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
2630}
2631
Douglas Gregore6078da2009-11-19 00:14:45 +00002632/// \brief Determine whether the addition of the given flag to an Objective-C
2633/// property's attributes will cause a conflict.
2634static bool ObjCPropertyFlagConflicts(unsigned Attributes, unsigned NewFlag) {
2635 // Check if we've already added this flag.
2636 if (Attributes & NewFlag)
2637 return true;
2638
2639 Attributes |= NewFlag;
2640
2641 // Check for collisions with "readonly".
2642 if ((Attributes & ObjCDeclSpec::DQ_PR_readonly) &&
2643 (Attributes & (ObjCDeclSpec::DQ_PR_readwrite |
2644 ObjCDeclSpec::DQ_PR_assign |
2645 ObjCDeclSpec::DQ_PR_copy |
2646 ObjCDeclSpec::DQ_PR_retain)))
2647 return true;
2648
2649 // Check for more than one of { assign, copy, retain }.
2650 unsigned AssignCopyRetMask = Attributes & (ObjCDeclSpec::DQ_PR_assign |
2651 ObjCDeclSpec::DQ_PR_copy |
2652 ObjCDeclSpec::DQ_PR_retain);
2653 if (AssignCopyRetMask &&
2654 AssignCopyRetMask != ObjCDeclSpec::DQ_PR_assign &&
2655 AssignCopyRetMask != ObjCDeclSpec::DQ_PR_copy &&
2656 AssignCopyRetMask != ObjCDeclSpec::DQ_PR_retain)
2657 return true;
2658
2659 return false;
2660}
2661
Douglas Gregor36029f42009-11-18 23:08:07 +00002662void Sema::CodeCompleteObjCPropertyFlags(Scope *S, ObjCDeclSpec &ODS) {
Steve Naroff936354c2009-10-08 21:55:05 +00002663 if (!CodeCompleter)
2664 return;
Douglas Gregor1b605f72009-11-19 01:08:35 +00002665
Steve Naroff936354c2009-10-08 21:55:05 +00002666 unsigned Attributes = ODS.getPropertyAttributes();
2667
2668 typedef CodeCompleteConsumer::Result Result;
2669 ResultBuilder Results(*this);
2670 Results.EnterNewScope();
Douglas Gregore6078da2009-11-19 00:14:45 +00002671 if (!ObjCPropertyFlagConflicts(Attributes, ObjCDeclSpec::DQ_PR_readonly))
Douglas Gregor78a21012010-01-14 16:01:26 +00002672 Results.AddResult(CodeCompleteConsumer::Result("readonly"));
Douglas Gregore6078da2009-11-19 00:14:45 +00002673 if (!ObjCPropertyFlagConflicts(Attributes, ObjCDeclSpec::DQ_PR_assign))
Douglas Gregor78a21012010-01-14 16:01:26 +00002674 Results.AddResult(CodeCompleteConsumer::Result("assign"));
Douglas Gregore6078da2009-11-19 00:14:45 +00002675 if (!ObjCPropertyFlagConflicts(Attributes, ObjCDeclSpec::DQ_PR_readwrite))
Douglas Gregor78a21012010-01-14 16:01:26 +00002676 Results.AddResult(CodeCompleteConsumer::Result("readwrite"));
Douglas Gregore6078da2009-11-19 00:14:45 +00002677 if (!ObjCPropertyFlagConflicts(Attributes, ObjCDeclSpec::DQ_PR_retain))
Douglas Gregor78a21012010-01-14 16:01:26 +00002678 Results.AddResult(CodeCompleteConsumer::Result("retain"));
Douglas Gregore6078da2009-11-19 00:14:45 +00002679 if (!ObjCPropertyFlagConflicts(Attributes, ObjCDeclSpec::DQ_PR_copy))
Douglas Gregor78a21012010-01-14 16:01:26 +00002680 Results.AddResult(CodeCompleteConsumer::Result("copy"));
Douglas Gregore6078da2009-11-19 00:14:45 +00002681 if (!ObjCPropertyFlagConflicts(Attributes, ObjCDeclSpec::DQ_PR_nonatomic))
Douglas Gregor78a21012010-01-14 16:01:26 +00002682 Results.AddResult(CodeCompleteConsumer::Result("nonatomic"));
Douglas Gregore6078da2009-11-19 00:14:45 +00002683 if (!ObjCPropertyFlagConflicts(Attributes, ObjCDeclSpec::DQ_PR_setter)) {
Douglas Gregor45f83ee2009-11-19 00:01:57 +00002684 CodeCompletionString *Setter = new CodeCompletionString;
2685 Setter->AddTypedTextChunk("setter");
2686 Setter->AddTextChunk(" = ");
2687 Setter->AddPlaceholderChunk("method");
Douglas Gregor78a21012010-01-14 16:01:26 +00002688 Results.AddResult(CodeCompleteConsumer::Result(Setter));
Douglas Gregor45f83ee2009-11-19 00:01:57 +00002689 }
Douglas Gregore6078da2009-11-19 00:14:45 +00002690 if (!ObjCPropertyFlagConflicts(Attributes, ObjCDeclSpec::DQ_PR_getter)) {
Douglas Gregor45f83ee2009-11-19 00:01:57 +00002691 CodeCompletionString *Getter = new CodeCompletionString;
2692 Getter->AddTypedTextChunk("getter");
2693 Getter->AddTextChunk(" = ");
2694 Getter->AddPlaceholderChunk("method");
Douglas Gregor78a21012010-01-14 16:01:26 +00002695 Results.AddResult(CodeCompleteConsumer::Result(Getter));
Douglas Gregor45f83ee2009-11-19 00:01:57 +00002696 }
Steve Naroff936354c2009-10-08 21:55:05 +00002697 Results.ExitScope();
Daniel Dunbar242ea9a2009-11-13 08:58:20 +00002698 HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
Steve Naroff936354c2009-10-08 21:55:05 +00002699}
Steve Naroffeae65032009-11-07 02:08:14 +00002700
Douglas Gregorc8537c52009-11-19 07:41:15 +00002701/// \brief Descripts the kind of Objective-C method that we want to find
2702/// via code completion.
2703enum ObjCMethodKind {
2704 MK_Any, //< Any kind of method, provided it means other specified criteria.
2705 MK_ZeroArgSelector, //< Zero-argument (unary) selector.
2706 MK_OneArgSelector //< One-argument selector.
2707};
2708
2709static bool isAcceptableObjCMethod(ObjCMethodDecl *Method,
2710 ObjCMethodKind WantKind,
2711 IdentifierInfo **SelIdents,
2712 unsigned NumSelIdents) {
2713 Selector Sel = Method->getSelector();
2714 if (NumSelIdents > Sel.getNumArgs())
2715 return false;
2716
2717 switch (WantKind) {
2718 case MK_Any: break;
2719 case MK_ZeroArgSelector: return Sel.isUnarySelector();
2720 case MK_OneArgSelector: return Sel.getNumArgs() == 1;
2721 }
2722
2723 for (unsigned I = 0; I != NumSelIdents; ++I)
2724 if (SelIdents[I] != Sel.getIdentifierInfoForSlot(I))
2725 return false;
2726
2727 return true;
2728}
2729
Douglas Gregorbab2b3c2009-11-17 23:22:23 +00002730/// \brief Add all of the Objective-C methods in the given Objective-C
2731/// container to the set of results.
2732///
2733/// The container will be a class, protocol, category, or implementation of
2734/// any of the above. This mether will recurse to include methods from
2735/// the superclasses of classes along with their categories, protocols, and
2736/// implementations.
2737///
2738/// \param Container the container in which we'll look to find methods.
2739///
2740/// \param WantInstance whether to add instance methods (only); if false, this
2741/// routine will add factory methods (only).
2742///
2743/// \param CurContext the context in which we're performing the lookup that
2744/// finds methods.
2745///
2746/// \param Results the structure into which we'll add results.
2747static void AddObjCMethods(ObjCContainerDecl *Container,
2748 bool WantInstanceMethods,
Douglas Gregorc8537c52009-11-19 07:41:15 +00002749 ObjCMethodKind WantKind,
Douglas Gregor1b605f72009-11-19 01:08:35 +00002750 IdentifierInfo **SelIdents,
2751 unsigned NumSelIdents,
Douglas Gregorbab2b3c2009-11-17 23:22:23 +00002752 DeclContext *CurContext,
2753 ResultBuilder &Results) {
2754 typedef CodeCompleteConsumer::Result Result;
2755 for (ObjCContainerDecl::method_iterator M = Container->meth_begin(),
2756 MEnd = Container->meth_end();
2757 M != MEnd; ++M) {
Douglas Gregor1b605f72009-11-19 01:08:35 +00002758 if ((*M)->isInstanceMethod() == WantInstanceMethods) {
2759 // Check whether the selector identifiers we've been given are a
2760 // subset of the identifiers for this particular method.
Douglas Gregorc8537c52009-11-19 07:41:15 +00002761 if (!isAcceptableObjCMethod(*M, WantKind, SelIdents, NumSelIdents))
Douglas Gregor1b605f72009-11-19 01:08:35 +00002762 continue;
Douglas Gregorc8537c52009-11-19 07:41:15 +00002763
Douglas Gregor1b605f72009-11-19 01:08:35 +00002764 Result R = Result(*M, 0);
2765 R.StartParameter = NumSelIdents;
Douglas Gregorc8537c52009-11-19 07:41:15 +00002766 R.AllParametersAreInformative = (WantKind != MK_Any);
Douglas Gregor1b605f72009-11-19 01:08:35 +00002767 Results.MaybeAddResult(R, CurContext);
2768 }
Douglas Gregorbab2b3c2009-11-17 23:22:23 +00002769 }
2770
2771 ObjCInterfaceDecl *IFace = dyn_cast<ObjCInterfaceDecl>(Container);
2772 if (!IFace)
2773 return;
2774
2775 // Add methods in protocols.
2776 const ObjCList<ObjCProtocolDecl> &Protocols= IFace->getReferencedProtocols();
2777 for (ObjCList<ObjCProtocolDecl>::iterator I = Protocols.begin(),
2778 E = Protocols.end();
2779 I != E; ++I)
Douglas Gregorc8537c52009-11-19 07:41:15 +00002780 AddObjCMethods(*I, WantInstanceMethods, WantKind, SelIdents, NumSelIdents,
Douglas Gregor1b605f72009-11-19 01:08:35 +00002781 CurContext, Results);
Douglas Gregorbab2b3c2009-11-17 23:22:23 +00002782
2783 // Add methods in categories.
2784 for (ObjCCategoryDecl *CatDecl = IFace->getCategoryList(); CatDecl;
2785 CatDecl = CatDecl->getNextClassCategory()) {
Douglas Gregorc8537c52009-11-19 07:41:15 +00002786 AddObjCMethods(CatDecl, WantInstanceMethods, WantKind, SelIdents,
2787 NumSelIdents, CurContext, Results);
Douglas Gregorbab2b3c2009-11-17 23:22:23 +00002788
2789 // Add a categories protocol methods.
2790 const ObjCList<ObjCProtocolDecl> &Protocols
2791 = CatDecl->getReferencedProtocols();
2792 for (ObjCList<ObjCProtocolDecl>::iterator I = Protocols.begin(),
2793 E = Protocols.end();
2794 I != E; ++I)
Douglas Gregorc8537c52009-11-19 07:41:15 +00002795 AddObjCMethods(*I, WantInstanceMethods, WantKind, SelIdents,
2796 NumSelIdents, CurContext, Results);
Douglas Gregorbab2b3c2009-11-17 23:22:23 +00002797
2798 // Add methods in category implementations.
2799 if (ObjCCategoryImplDecl *Impl = CatDecl->getImplementation())
Douglas Gregorc8537c52009-11-19 07:41:15 +00002800 AddObjCMethods(Impl, WantInstanceMethods, WantKind, SelIdents,
2801 NumSelIdents, CurContext, Results);
Douglas Gregorbab2b3c2009-11-17 23:22:23 +00002802 }
2803
2804 // Add methods in superclass.
2805 if (IFace->getSuperClass())
Douglas Gregorc8537c52009-11-19 07:41:15 +00002806 AddObjCMethods(IFace->getSuperClass(), WantInstanceMethods, WantKind,
2807 SelIdents, NumSelIdents, CurContext, Results);
Douglas Gregorbab2b3c2009-11-17 23:22:23 +00002808
2809 // Add methods in our implementation, if any.
2810 if (ObjCImplementationDecl *Impl = IFace->getImplementation())
Douglas Gregorc8537c52009-11-19 07:41:15 +00002811 AddObjCMethods(Impl, WantInstanceMethods, WantKind, SelIdents,
2812 NumSelIdents, CurContext, Results);
2813}
2814
2815
2816void Sema::CodeCompleteObjCPropertyGetter(Scope *S, DeclPtrTy ClassDecl,
2817 DeclPtrTy *Methods,
2818 unsigned NumMethods) {
2819 typedef CodeCompleteConsumer::Result Result;
2820
2821 // Try to find the interface where getters might live.
2822 ObjCInterfaceDecl *Class
2823 = dyn_cast_or_null<ObjCInterfaceDecl>(ClassDecl.getAs<Decl>());
2824 if (!Class) {
2825 if (ObjCCategoryDecl *Category
2826 = dyn_cast_or_null<ObjCCategoryDecl>(ClassDecl.getAs<Decl>()))
2827 Class = Category->getClassInterface();
2828
2829 if (!Class)
2830 return;
2831 }
2832
2833 // Find all of the potential getters.
2834 ResultBuilder Results(*this);
2835 Results.EnterNewScope();
2836
2837 // FIXME: We need to do this because Objective-C methods don't get
2838 // pushed into DeclContexts early enough. Argh!
2839 for (unsigned I = 0; I != NumMethods; ++I) {
2840 if (ObjCMethodDecl *Method
2841 = dyn_cast_or_null<ObjCMethodDecl>(Methods[I].getAs<Decl>()))
2842 if (Method->isInstanceMethod() &&
2843 isAcceptableObjCMethod(Method, MK_ZeroArgSelector, 0, 0)) {
2844 Result R = Result(Method, 0);
2845 R.AllParametersAreInformative = true;
2846 Results.MaybeAddResult(R, CurContext);
2847 }
2848 }
2849
2850 AddObjCMethods(Class, true, MK_ZeroArgSelector, 0, 0, CurContext, Results);
2851 Results.ExitScope();
2852 HandleCodeCompleteResults(this, CodeCompleter,Results.data(),Results.size());
2853}
2854
2855void Sema::CodeCompleteObjCPropertySetter(Scope *S, DeclPtrTy ObjCImplDecl,
2856 DeclPtrTy *Methods,
2857 unsigned NumMethods) {
2858 typedef CodeCompleteConsumer::Result Result;
2859
2860 // Try to find the interface where setters might live.
2861 ObjCInterfaceDecl *Class
2862 = dyn_cast_or_null<ObjCInterfaceDecl>(ObjCImplDecl.getAs<Decl>());
2863 if (!Class) {
2864 if (ObjCCategoryDecl *Category
2865 = dyn_cast_or_null<ObjCCategoryDecl>(ObjCImplDecl.getAs<Decl>()))
2866 Class = Category->getClassInterface();
2867
2868 if (!Class)
2869 return;
2870 }
2871
2872 // Find all of the potential getters.
2873 ResultBuilder Results(*this);
2874 Results.EnterNewScope();
2875
2876 // FIXME: We need to do this because Objective-C methods don't get
2877 // pushed into DeclContexts early enough. Argh!
2878 for (unsigned I = 0; I != NumMethods; ++I) {
2879 if (ObjCMethodDecl *Method
2880 = dyn_cast_or_null<ObjCMethodDecl>(Methods[I].getAs<Decl>()))
2881 if (Method->isInstanceMethod() &&
2882 isAcceptableObjCMethod(Method, MK_OneArgSelector, 0, 0)) {
2883 Result R = Result(Method, 0);
2884 R.AllParametersAreInformative = true;
2885 Results.MaybeAddResult(R, CurContext);
2886 }
2887 }
2888
2889 AddObjCMethods(Class, true, MK_OneArgSelector, 0, 0, CurContext, Results);
2890
2891 Results.ExitScope();
2892 HandleCodeCompleteResults(this, CodeCompleter,Results.data(),Results.size());
Douglas Gregorbab2b3c2009-11-17 23:22:23 +00002893}
2894
Douglas Gregor9d2ddb22010-04-06 19:22:33 +00002895/// \brief When we have an expression with type "id", we may assume
2896/// that it has some more-specific class type based on knowledge of
2897/// common uses of Objective-C. This routine returns that class type,
2898/// or NULL if no better result could be determined.
2899static ObjCInterfaceDecl *GetAssumedMessageSendExprType(Expr *E) {
2900 ObjCMessageExpr *Msg = dyn_cast<ObjCMessageExpr>(E);
2901 if (!Msg)
2902 return 0;
2903
2904 Selector Sel = Msg->getSelector();
2905 if (Sel.isNull())
2906 return 0;
2907
2908 IdentifierInfo *Id = Sel.getIdentifierInfoForSlot(0);
2909 if (!Id)
2910 return 0;
2911
2912 ObjCMethodDecl *Method = Msg->getMethodDecl();
2913 if (!Method)
2914 return 0;
2915
2916 // Determine the class that we're sending the message to.
2917 ObjCInterfaceDecl *IFace = Msg->getClassInfo().Decl;
2918 if (!IFace) {
2919 if (Expr *Receiver = Msg->getReceiver()) {
2920 QualType T = Receiver->getType();
2921 if (const ObjCObjectPointerType *Ptr = T->getAs<ObjCObjectPointerType>())
2922 IFace = Ptr->getInterfaceDecl();
2923 }
2924 }
2925
2926 if (!IFace)
2927 return 0;
2928
2929 ObjCInterfaceDecl *Super = IFace->getSuperClass();
2930 if (Method->isInstanceMethod())
2931 return llvm::StringSwitch<ObjCInterfaceDecl *>(Id->getName())
2932 .Case("retain", IFace)
2933 .Case("autorelease", IFace)
2934 .Case("copy", IFace)
2935 .Case("copyWithZone", IFace)
2936 .Case("mutableCopy", IFace)
2937 .Case("mutableCopyWithZone", IFace)
2938 .Case("awakeFromCoder", IFace)
2939 .Case("replacementObjectFromCoder", IFace)
2940 .Case("class", IFace)
2941 .Case("classForCoder", IFace)
2942 .Case("superclass", Super)
2943 .Default(0);
2944
2945 return llvm::StringSwitch<ObjCInterfaceDecl *>(Id->getName())
2946 .Case("new", IFace)
2947 .Case("alloc", IFace)
2948 .Case("allocWithZone", IFace)
2949 .Case("class", IFace)
2950 .Case("superclass", Super)
2951 .Default(0);
2952}
2953
Douglas Gregor090dd182009-11-17 23:31:36 +00002954void Sema::CodeCompleteObjCClassMessage(Scope *S, IdentifierInfo *FName,
Douglas Gregor1b605f72009-11-19 01:08:35 +00002955 SourceLocation FNameLoc,
2956 IdentifierInfo **SelIdents,
2957 unsigned NumSelIdents) {
Steve Naroffeae65032009-11-07 02:08:14 +00002958 typedef CodeCompleteConsumer::Result Result;
Douglas Gregor8ce33212009-11-17 17:59:40 +00002959 ObjCInterfaceDecl *CDecl = 0;
2960
Douglas Gregor8ce33212009-11-17 17:59:40 +00002961 if (FName->isStr("super")) {
2962 // We're sending a message to "super".
2963 if (ObjCMethodDecl *CurMethod = getCurMethodDecl()) {
2964 // Figure out which interface we're in.
2965 CDecl = CurMethod->getClassInterface();
2966 if (!CDecl)
2967 return;
2968
2969 // Find the superclass of this class.
2970 CDecl = CDecl->getSuperClass();
2971 if (!CDecl)
2972 return;
2973
2974 if (CurMethod->isInstanceMethod()) {
2975 // We are inside an instance method, which means that the message
2976 // send [super ...] is actually calling an instance method on the
2977 // current object. Build the super expression and handle this like
2978 // an instance method.
2979 QualType SuperTy = Context.getObjCInterfaceType(CDecl);
2980 SuperTy = Context.getObjCObjectPointerType(SuperTy);
2981 OwningExprResult Super
Douglas Gregor090dd182009-11-17 23:31:36 +00002982 = Owned(new (Context) ObjCSuperExpr(FNameLoc, SuperTy));
Douglas Gregor1b605f72009-11-19 01:08:35 +00002983 return CodeCompleteObjCInstanceMessage(S, (Expr *)Super.get(),
2984 SelIdents, NumSelIdents);
Douglas Gregor8ce33212009-11-17 17:59:40 +00002985 }
2986
2987 // Okay, we're calling a factory method in our superclass.
2988 }
2989 }
2990
2991 // If the given name refers to an interface type, retrieve the
2992 // corresponding declaration.
2993 if (!CDecl)
Douglas Gregor090dd182009-11-17 23:31:36 +00002994 if (TypeTy *Ty = getTypeName(*FName, FNameLoc, S, 0, false)) {
Douglas Gregor8ce33212009-11-17 17:59:40 +00002995 QualType T = GetTypeFromParser(Ty, 0);
2996 if (!T.isNull())
2997 if (const ObjCInterfaceType *Interface = T->getAs<ObjCInterfaceType>())
2998 CDecl = Interface->getDecl();
2999 }
3000
3001 if (!CDecl && FName->isStr("super")) {
3002 // "super" may be the name of a variable, in which case we are
3003 // probably calling an instance method.
John McCalle66edc12009-11-24 19:00:30 +00003004 CXXScopeSpec SS;
3005 UnqualifiedId id;
3006 id.setIdentifier(FName, FNameLoc);
3007 OwningExprResult Super = ActOnIdExpression(S, SS, id, false, false);
Douglas Gregor1b605f72009-11-19 01:08:35 +00003008 return CodeCompleteObjCInstanceMessage(S, (Expr *)Super.get(),
3009 SelIdents, NumSelIdents);
Douglas Gregor8ce33212009-11-17 17:59:40 +00003010 }
3011
Douglas Gregorbab2b3c2009-11-17 23:22:23 +00003012 // Add all of the factory methods in this Objective-C class, its protocols,
3013 // superclasses, categories, implementation, etc.
Steve Naroffeae65032009-11-07 02:08:14 +00003014 ResultBuilder Results(*this);
3015 Results.EnterNewScope();
Douglas Gregor6285f752010-04-06 16:40:00 +00003016
3017 if (CDecl)
3018 AddObjCMethods(CDecl, false, MK_Any, SelIdents, NumSelIdents, CurContext,
3019 Results);
3020 else if (FName->isStr("id")) {
3021 // We're messaging "id" as a type; provide all class/factory methods.
3022
Douglas Gregord720daf2010-04-06 17:30:22 +00003023 // If we have an external source, load the entire class method
3024 // pool from the PCH file.
3025 if (ExternalSource) {
3026 for (uint32_t I = 0, N = ExternalSource->GetNumKnownSelectors(); I != N;
3027 ++I) {
3028 Selector Sel = ExternalSource->GetSelector(I);
3029 if (Sel.isNull() || FactoryMethodPool.count(Sel) ||
3030 InstanceMethodPool.count(Sel))
3031 continue;
3032
3033 ReadMethodPool(Sel, /*isInstance=*/false);
3034 }
3035 }
3036
Douglas Gregor6285f752010-04-06 16:40:00 +00003037 for (llvm::DenseMap<Selector, ObjCMethodList>::iterator
3038 M = FactoryMethodPool.begin(),
3039 MEnd = FactoryMethodPool.end();
3040 M != MEnd;
3041 ++M) {
Douglas Gregord720daf2010-04-06 17:30:22 +00003042 for (ObjCMethodList *MethList = &M->second; MethList && MethList->Method;
Douglas Gregor6285f752010-04-06 16:40:00 +00003043 MethList = MethList->Next) {
3044 if (!isAcceptableObjCMethod(MethList->Method, MK_Any, SelIdents,
3045 NumSelIdents))
3046 continue;
3047
3048 Result R(MethList->Method, 0);
3049 R.StartParameter = NumSelIdents;
3050 R.AllParametersAreInformative = false;
3051 Results.MaybeAddResult(R, CurContext);
3052 }
3053 }
3054 }
3055
Steve Naroffeae65032009-11-07 02:08:14 +00003056 Results.ExitScope();
Douglas Gregorbab2b3c2009-11-17 23:22:23 +00003057
Steve Naroffeae65032009-11-07 02:08:14 +00003058 // This also suppresses remaining diagnostics.
Daniel Dunbar242ea9a2009-11-13 08:58:20 +00003059 HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
Steve Naroffeae65032009-11-07 02:08:14 +00003060}
3061
Douglas Gregor1b605f72009-11-19 01:08:35 +00003062void Sema::CodeCompleteObjCInstanceMessage(Scope *S, ExprTy *Receiver,
3063 IdentifierInfo **SelIdents,
3064 unsigned NumSelIdents) {
Steve Naroffeae65032009-11-07 02:08:14 +00003065 typedef CodeCompleteConsumer::Result Result;
Steve Naroffeae65032009-11-07 02:08:14 +00003066
3067 Expr *RecExpr = static_cast<Expr *>(Receiver);
Steve Naroffeae65032009-11-07 02:08:14 +00003068
Douglas Gregorbab2b3c2009-11-17 23:22:23 +00003069 // If necessary, apply function/array conversion to the receiver.
3070 // C99 6.7.5.3p[7,8].
Douglas Gregorb92a1562010-02-03 00:27:59 +00003071 DefaultFunctionArrayLvalueConversion(RecExpr);
Douglas Gregorbab2b3c2009-11-17 23:22:23 +00003072 QualType ReceiverType = RecExpr->getType();
Steve Naroffeae65032009-11-07 02:08:14 +00003073
Douglas Gregorbab2b3c2009-11-17 23:22:23 +00003074 // Build the set of methods we can see.
3075 ResultBuilder Results(*this);
3076 Results.EnterNewScope();
Douglas Gregor9d2ddb22010-04-06 19:22:33 +00003077
3078 // If we're messaging an expression with type "id" or "Class", check
3079 // whether we know something special about the receiver that allows
3080 // us to assume a more-specific receiver type.
3081 if (ReceiverType->isObjCIdType() || ReceiverType->isObjCClassType())
3082 if (ObjCInterfaceDecl *IFace = GetAssumedMessageSendExprType(RecExpr))
3083 ReceiverType = Context.getObjCObjectPointerType(
3084 Context.getObjCInterfaceType(IFace));
Douglas Gregorbab2b3c2009-11-17 23:22:23 +00003085
Douglas Gregora3329fa2009-11-18 00:06:18 +00003086 // Handle messages to Class. This really isn't a message to an instance
3087 // method, so we treat it the same way we would treat a message send to a
3088 // class method.
3089 if (ReceiverType->isObjCClassType() ||
3090 ReceiverType->isObjCQualifiedClassType()) {
3091 if (ObjCMethodDecl *CurMethod = getCurMethodDecl()) {
3092 if (ObjCInterfaceDecl *ClassDecl = CurMethod->getClassInterface())
Douglas Gregorc8537c52009-11-19 07:41:15 +00003093 AddObjCMethods(ClassDecl, false, MK_Any, SelIdents, NumSelIdents,
3094 CurContext, Results);
Douglas Gregora3329fa2009-11-18 00:06:18 +00003095 }
3096 }
3097 // Handle messages to a qualified ID ("id<foo>").
3098 else if (const ObjCObjectPointerType *QualID
3099 = ReceiverType->getAsObjCQualifiedIdType()) {
3100 // Search protocols for instance methods.
3101 for (ObjCObjectPointerType::qual_iterator I = QualID->qual_begin(),
3102 E = QualID->qual_end();
3103 I != E; ++I)
Douglas Gregorc8537c52009-11-19 07:41:15 +00003104 AddObjCMethods(*I, true, MK_Any, SelIdents, NumSelIdents, CurContext,
3105 Results);
Douglas Gregora3329fa2009-11-18 00:06:18 +00003106 }
3107 // Handle messages to a pointer to interface type.
3108 else if (const ObjCObjectPointerType *IFacePtr
3109 = ReceiverType->getAsObjCInterfacePointerType()) {
3110 // Search the class, its superclasses, etc., for instance methods.
Douglas Gregorc8537c52009-11-19 07:41:15 +00003111 AddObjCMethods(IFacePtr->getInterfaceDecl(), true, MK_Any, SelIdents,
3112 NumSelIdents, CurContext, Results);
Douglas Gregora3329fa2009-11-18 00:06:18 +00003113
3114 // Search protocols for instance methods.
3115 for (ObjCObjectPointerType::qual_iterator I = IFacePtr->qual_begin(),
3116 E = IFacePtr->qual_end();
3117 I != E; ++I)
Douglas Gregorc8537c52009-11-19 07:41:15 +00003118 AddObjCMethods(*I, true, MK_Any, SelIdents, NumSelIdents, CurContext,
3119 Results);
Douglas Gregora3329fa2009-11-18 00:06:18 +00003120 }
Douglas Gregor6285f752010-04-06 16:40:00 +00003121 // Handle messages to "id".
3122 else if (ReceiverType->isObjCIdType()) {
Douglas Gregord720daf2010-04-06 17:30:22 +00003123 // We're messaging "id", so provide all instance methods we know
3124 // about as code-completion results.
3125
3126 // If we have an external source, load the entire class method
3127 // pool from the PCH file.
3128 if (ExternalSource) {
3129 for (uint32_t I = 0, N = ExternalSource->GetNumKnownSelectors(); I != N;
3130 ++I) {
3131 Selector Sel = ExternalSource->GetSelector(I);
3132 if (Sel.isNull() || InstanceMethodPool.count(Sel) ||
3133 FactoryMethodPool.count(Sel))
3134 continue;
3135
3136 ReadMethodPool(Sel, /*isInstance=*/true);
3137 }
3138 }
3139
Douglas Gregor6285f752010-04-06 16:40:00 +00003140 for (llvm::DenseMap<Selector, ObjCMethodList>::iterator
3141 M = InstanceMethodPool.begin(),
3142 MEnd = InstanceMethodPool.end();
3143 M != MEnd;
3144 ++M) {
Douglas Gregord720daf2010-04-06 17:30:22 +00003145 for (ObjCMethodList *MethList = &M->second; MethList && MethList->Method;
Douglas Gregor6285f752010-04-06 16:40:00 +00003146 MethList = MethList->Next) {
3147 if (!isAcceptableObjCMethod(MethList->Method, MK_Any, SelIdents,
3148 NumSelIdents))
3149 continue;
3150
3151 Result R(MethList->Method, 0);
3152 R.StartParameter = NumSelIdents;
3153 R.AllParametersAreInformative = false;
3154 Results.MaybeAddResult(R, CurContext);
3155 }
3156 }
3157 }
3158
Steve Naroffeae65032009-11-07 02:08:14 +00003159 Results.ExitScope();
Daniel Dunbar242ea9a2009-11-13 08:58:20 +00003160 HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
Steve Naroffeae65032009-11-07 02:08:14 +00003161}
Douglas Gregorbaf69612009-11-18 04:19:12 +00003162
3163/// \brief Add all of the protocol declarations that we find in the given
3164/// (translation unit) context.
3165static void AddProtocolResults(DeclContext *Ctx, DeclContext *CurContext,
Douglas Gregor5b4671c2009-11-18 04:49:41 +00003166 bool OnlyForwardDeclarations,
Douglas Gregorbaf69612009-11-18 04:19:12 +00003167 ResultBuilder &Results) {
3168 typedef CodeCompleteConsumer::Result Result;
3169
3170 for (DeclContext::decl_iterator D = Ctx->decls_begin(),
3171 DEnd = Ctx->decls_end();
3172 D != DEnd; ++D) {
3173 // Record any protocols we find.
3174 if (ObjCProtocolDecl *Proto = dyn_cast<ObjCProtocolDecl>(*D))
Douglas Gregor5b4671c2009-11-18 04:49:41 +00003175 if (!OnlyForwardDeclarations || Proto->isForwardDecl())
Douglas Gregorfc59ce12010-01-14 16:14:35 +00003176 Results.AddResult(Result(Proto, 0), CurContext, 0, false);
Douglas Gregorbaf69612009-11-18 04:19:12 +00003177
3178 // Record any forward-declared protocols we find.
3179 if (ObjCForwardProtocolDecl *Forward
3180 = dyn_cast<ObjCForwardProtocolDecl>(*D)) {
3181 for (ObjCForwardProtocolDecl::protocol_iterator
3182 P = Forward->protocol_begin(),
3183 PEnd = Forward->protocol_end();
3184 P != PEnd; ++P)
Douglas Gregor5b4671c2009-11-18 04:49:41 +00003185 if (!OnlyForwardDeclarations || (*P)->isForwardDecl())
Douglas Gregorfc59ce12010-01-14 16:14:35 +00003186 Results.AddResult(Result(*P, 0), CurContext, 0, false);
Douglas Gregorbaf69612009-11-18 04:19:12 +00003187 }
3188 }
3189}
3190
3191void Sema::CodeCompleteObjCProtocolReferences(IdentifierLocPair *Protocols,
3192 unsigned NumProtocols) {
3193 ResultBuilder Results(*this);
3194 Results.EnterNewScope();
3195
3196 // Tell the result set to ignore all of the protocols we have
3197 // already seen.
3198 for (unsigned I = 0; I != NumProtocols; ++I)
3199 if (ObjCProtocolDecl *Protocol = LookupProtocol(Protocols[I].first))
3200 Results.Ignore(Protocol);
3201
3202 // Add all protocols.
Douglas Gregor5b4671c2009-11-18 04:49:41 +00003203 AddProtocolResults(Context.getTranslationUnitDecl(), CurContext, false,
3204 Results);
3205
3206 Results.ExitScope();
3207 HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
3208}
3209
3210void Sema::CodeCompleteObjCProtocolDecl(Scope *) {
3211 ResultBuilder Results(*this);
3212 Results.EnterNewScope();
3213
3214 // Add all protocols.
3215 AddProtocolResults(Context.getTranslationUnitDecl(), CurContext, true,
3216 Results);
Douglas Gregorbaf69612009-11-18 04:19:12 +00003217
3218 Results.ExitScope();
3219 HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
3220}
Douglas Gregor49c22a72009-11-18 16:26:39 +00003221
3222/// \brief Add all of the Objective-C interface declarations that we find in
3223/// the given (translation unit) context.
3224static void AddInterfaceResults(DeclContext *Ctx, DeclContext *CurContext,
3225 bool OnlyForwardDeclarations,
3226 bool OnlyUnimplemented,
3227 ResultBuilder &Results) {
3228 typedef CodeCompleteConsumer::Result Result;
3229
3230 for (DeclContext::decl_iterator D = Ctx->decls_begin(),
3231 DEnd = Ctx->decls_end();
3232 D != DEnd; ++D) {
3233 // Record any interfaces we find.
3234 if (ObjCInterfaceDecl *Class = dyn_cast<ObjCInterfaceDecl>(*D))
3235 if ((!OnlyForwardDeclarations || Class->isForwardDecl()) &&
3236 (!OnlyUnimplemented || !Class->getImplementation()))
Douglas Gregorfc59ce12010-01-14 16:14:35 +00003237 Results.AddResult(Result(Class, 0), CurContext, 0, false);
Douglas Gregor49c22a72009-11-18 16:26:39 +00003238
3239 // Record any forward-declared interfaces we find.
3240 if (ObjCClassDecl *Forward = dyn_cast<ObjCClassDecl>(*D)) {
3241 for (ObjCClassDecl::iterator C = Forward->begin(), CEnd = Forward->end();
3242 C != CEnd; ++C)
3243 if ((!OnlyForwardDeclarations || C->getInterface()->isForwardDecl()) &&
3244 (!OnlyUnimplemented || !C->getInterface()->getImplementation()))
Douglas Gregorfc59ce12010-01-14 16:14:35 +00003245 Results.AddResult(Result(C->getInterface(), 0), CurContext,
3246 0, false);
Douglas Gregor49c22a72009-11-18 16:26:39 +00003247 }
3248 }
3249}
3250
3251void Sema::CodeCompleteObjCInterfaceDecl(Scope *S) {
3252 ResultBuilder Results(*this);
3253 Results.EnterNewScope();
3254
3255 // Add all classes.
3256 AddInterfaceResults(Context.getTranslationUnitDecl(), CurContext, true,
3257 false, Results);
3258
3259 Results.ExitScope();
3260 HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
3261}
3262
3263void Sema::CodeCompleteObjCSuperclass(Scope *S, IdentifierInfo *ClassName) {
3264 ResultBuilder Results(*this);
3265 Results.EnterNewScope();
3266
3267 // Make sure that we ignore the class we're currently defining.
3268 NamedDecl *CurClass
3269 = LookupSingleName(TUScope, ClassName, LookupOrdinaryName);
Douglas Gregor5d34fd32009-11-18 19:08:43 +00003270 if (CurClass && isa<ObjCInterfaceDecl>(CurClass))
Douglas Gregor49c22a72009-11-18 16:26:39 +00003271 Results.Ignore(CurClass);
3272
3273 // Add all classes.
3274 AddInterfaceResults(Context.getTranslationUnitDecl(), CurContext, false,
3275 false, Results);
3276
3277 Results.ExitScope();
3278 HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
3279}
3280
3281void Sema::CodeCompleteObjCImplementationDecl(Scope *S) {
3282 ResultBuilder Results(*this);
3283 Results.EnterNewScope();
3284
3285 // Add all unimplemented classes.
3286 AddInterfaceResults(Context.getTranslationUnitDecl(), CurContext, false,
3287 true, Results);
3288
3289 Results.ExitScope();
3290 HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
3291}
Douglas Gregor5d34fd32009-11-18 19:08:43 +00003292
3293void Sema::CodeCompleteObjCInterfaceCategory(Scope *S,
3294 IdentifierInfo *ClassName) {
3295 typedef CodeCompleteConsumer::Result Result;
3296
3297 ResultBuilder Results(*this);
3298
3299 // Ignore any categories we find that have already been implemented by this
3300 // interface.
3301 llvm::SmallPtrSet<IdentifierInfo *, 16> CategoryNames;
3302 NamedDecl *CurClass
3303 = LookupSingleName(TUScope, ClassName, LookupOrdinaryName);
3304 if (ObjCInterfaceDecl *Class = dyn_cast_or_null<ObjCInterfaceDecl>(CurClass))
3305 for (ObjCCategoryDecl *Category = Class->getCategoryList(); Category;
3306 Category = Category->getNextClassCategory())
3307 CategoryNames.insert(Category->getIdentifier());
3308
3309 // Add all of the categories we know about.
3310 Results.EnterNewScope();
3311 TranslationUnitDecl *TU = Context.getTranslationUnitDecl();
3312 for (DeclContext::decl_iterator D = TU->decls_begin(),
3313 DEnd = TU->decls_end();
3314 D != DEnd; ++D)
3315 if (ObjCCategoryDecl *Category = dyn_cast<ObjCCategoryDecl>(*D))
3316 if (CategoryNames.insert(Category->getIdentifier()))
Douglas Gregorfc59ce12010-01-14 16:14:35 +00003317 Results.AddResult(Result(Category, 0), CurContext, 0, false);
Douglas Gregor5d34fd32009-11-18 19:08:43 +00003318 Results.ExitScope();
3319
3320 HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
3321}
3322
3323void Sema::CodeCompleteObjCImplementationCategory(Scope *S,
3324 IdentifierInfo *ClassName) {
3325 typedef CodeCompleteConsumer::Result Result;
3326
3327 // Find the corresponding interface. If we couldn't find the interface, the
3328 // program itself is ill-formed. However, we'll try to be helpful still by
3329 // providing the list of all of the categories we know about.
3330 NamedDecl *CurClass
3331 = LookupSingleName(TUScope, ClassName, LookupOrdinaryName);
3332 ObjCInterfaceDecl *Class = dyn_cast_or_null<ObjCInterfaceDecl>(CurClass);
3333 if (!Class)
3334 return CodeCompleteObjCInterfaceCategory(S, ClassName);
3335
3336 ResultBuilder Results(*this);
3337
3338 // Add all of the categories that have have corresponding interface
3339 // declarations in this class and any of its superclasses, except for
3340 // already-implemented categories in the class itself.
3341 llvm::SmallPtrSet<IdentifierInfo *, 16> CategoryNames;
3342 Results.EnterNewScope();
3343 bool IgnoreImplemented = true;
3344 while (Class) {
3345 for (ObjCCategoryDecl *Category = Class->getCategoryList(); Category;
3346 Category = Category->getNextClassCategory())
3347 if ((!IgnoreImplemented || !Category->getImplementation()) &&
3348 CategoryNames.insert(Category->getIdentifier()))
Douglas Gregorfc59ce12010-01-14 16:14:35 +00003349 Results.AddResult(Result(Category, 0), CurContext, 0, false);
Douglas Gregor5d34fd32009-11-18 19:08:43 +00003350
3351 Class = Class->getSuperClass();
3352 IgnoreImplemented = false;
3353 }
3354 Results.ExitScope();
3355
3356 HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
3357}
Douglas Gregor5d649882009-11-18 22:32:06 +00003358
Douglas Gregor52e78bd2009-11-18 22:56:13 +00003359void Sema::CodeCompleteObjCPropertyDefinition(Scope *S, DeclPtrTy ObjCImpDecl) {
Douglas Gregor5d649882009-11-18 22:32:06 +00003360 typedef CodeCompleteConsumer::Result Result;
3361 ResultBuilder Results(*this);
3362
3363 // Figure out where this @synthesize lives.
3364 ObjCContainerDecl *Container
3365 = dyn_cast_or_null<ObjCContainerDecl>(ObjCImpDecl.getAs<Decl>());
3366 if (!Container ||
3367 (!isa<ObjCImplementationDecl>(Container) &&
3368 !isa<ObjCCategoryImplDecl>(Container)))
3369 return;
3370
3371 // Ignore any properties that have already been implemented.
3372 for (DeclContext::decl_iterator D = Container->decls_begin(),
3373 DEnd = Container->decls_end();
3374 D != DEnd; ++D)
3375 if (ObjCPropertyImplDecl *PropertyImpl = dyn_cast<ObjCPropertyImplDecl>(*D))
3376 Results.Ignore(PropertyImpl->getPropertyDecl());
3377
3378 // Add any properties that we find.
3379 Results.EnterNewScope();
3380 if (ObjCImplementationDecl *ClassImpl
3381 = dyn_cast<ObjCImplementationDecl>(Container))
3382 AddObjCProperties(ClassImpl->getClassInterface(), false, CurContext,
3383 Results);
3384 else
3385 AddObjCProperties(cast<ObjCCategoryImplDecl>(Container)->getCategoryDecl(),
3386 false, CurContext, Results);
3387 Results.ExitScope();
3388
3389 HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
3390}
3391
3392void Sema::CodeCompleteObjCPropertySynthesizeIvar(Scope *S,
3393 IdentifierInfo *PropertyName,
3394 DeclPtrTy ObjCImpDecl) {
3395 typedef CodeCompleteConsumer::Result Result;
3396 ResultBuilder Results(*this);
3397
3398 // Figure out where this @synthesize lives.
3399 ObjCContainerDecl *Container
3400 = dyn_cast_or_null<ObjCContainerDecl>(ObjCImpDecl.getAs<Decl>());
3401 if (!Container ||
3402 (!isa<ObjCImplementationDecl>(Container) &&
3403 !isa<ObjCCategoryImplDecl>(Container)))
3404 return;
3405
3406 // Figure out which interface we're looking into.
3407 ObjCInterfaceDecl *Class = 0;
3408 if (ObjCImplementationDecl *ClassImpl
3409 = dyn_cast<ObjCImplementationDecl>(Container))
3410 Class = ClassImpl->getClassInterface();
3411 else
3412 Class = cast<ObjCCategoryImplDecl>(Container)->getCategoryDecl()
3413 ->getClassInterface();
3414
3415 // Add all of the instance variables in this class and its superclasses.
3416 Results.EnterNewScope();
3417 for(; Class; Class = Class->getSuperClass()) {
3418 // FIXME: We could screen the type of each ivar for compatibility with
3419 // the property, but is that being too paternal?
3420 for (ObjCInterfaceDecl::ivar_iterator IVar = Class->ivar_begin(),
3421 IVarEnd = Class->ivar_end();
3422 IVar != IVarEnd; ++IVar)
Douglas Gregorfc59ce12010-01-14 16:14:35 +00003423 Results.AddResult(Result(*IVar, 0), CurContext, 0, false);
Douglas Gregor5d649882009-11-18 22:32:06 +00003424 }
3425 Results.ExitScope();
3426
3427 HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
3428}