blob: 49a32a6bddd393b96e0fed054edfd3f648e23e38 [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
2080 // Add macros
2081 if (CodeCompleter->includeMacros())
Douglas Gregorf98e6a22010-01-13 23:51:12 +00002082 AddMacroResults(PP, Results);
Daniel Dunbar242ea9a2009-11-13 08:58:20 +00002083
2084 // Hand off the results found for code completion.
2085 HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
Douglas Gregor2436e712009-09-17 21:32:03 +00002086}
2087
Douglas Gregorf45b0cf2009-09-18 15:37:17 +00002088void Sema::CodeCompleteTag(Scope *S, unsigned TagSpec) {
2089 if (!CodeCompleter)
2090 return;
2091
Douglas Gregor3545ff42009-09-21 16:56:56 +00002092 typedef CodeCompleteConsumer::Result Result;
2093 ResultBuilder::LookupFilter Filter = 0;
Douglas Gregorf45b0cf2009-09-18 15:37:17 +00002094 switch ((DeclSpec::TST)TagSpec) {
2095 case DeclSpec::TST_enum:
Douglas Gregor3545ff42009-09-21 16:56:56 +00002096 Filter = &ResultBuilder::IsEnum;
Douglas Gregorf45b0cf2009-09-18 15:37:17 +00002097 break;
2098
2099 case DeclSpec::TST_union:
Douglas Gregor3545ff42009-09-21 16:56:56 +00002100 Filter = &ResultBuilder::IsUnion;
Douglas Gregorf45b0cf2009-09-18 15:37:17 +00002101 break;
2102
2103 case DeclSpec::TST_struct:
Douglas Gregorf45b0cf2009-09-18 15:37:17 +00002104 case DeclSpec::TST_class:
Douglas Gregor3545ff42009-09-21 16:56:56 +00002105 Filter = &ResultBuilder::IsClassOrStruct;
Douglas Gregorf45b0cf2009-09-18 15:37:17 +00002106 break;
2107
2108 default:
2109 assert(false && "Unknown type specifier kind in CodeCompleteTag");
2110 return;
2111 }
Douglas Gregor3545ff42009-09-21 16:56:56 +00002112
2113 ResultBuilder Results(*this, Filter);
Douglas Gregor6ae4c522010-01-14 03:21:49 +00002114 Results.allowNestedNameSpecifiers();
Douglas Gregora6e2edc2010-01-14 03:27:13 +00002115 CodeCompletionDeclConsumer Consumer(Results, CurContext);
2116 LookupVisibleDecls(S, LookupTagName, Consumer);
Douglas Gregor3545ff42009-09-21 16:56:56 +00002117
Douglas Gregor9eb77012009-11-07 00:00:49 +00002118 if (CodeCompleter->includeMacros())
Douglas Gregorf98e6a22010-01-13 23:51:12 +00002119 AddMacroResults(PP, Results);
Daniel Dunbar242ea9a2009-11-13 08:58:20 +00002120 HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
Douglas Gregorf45b0cf2009-09-18 15:37:17 +00002121}
2122
Douglas Gregord328d572009-09-21 18:10:23 +00002123void Sema::CodeCompleteCase(Scope *S) {
2124 if (getSwitchStack().empty() || !CodeCompleter)
2125 return;
2126
2127 SwitchStmt *Switch = getSwitchStack().back();
2128 if (!Switch->getCond()->getType()->isEnumeralType())
2129 return;
2130
2131 // Code-complete the cases of a switch statement over an enumeration type
2132 // by providing the list of
2133 EnumDecl *Enum = Switch->getCond()->getType()->getAs<EnumType>()->getDecl();
2134
2135 // Determine which enumerators we have already seen in the switch statement.
2136 // FIXME: Ideally, we would also be able to look *past* the code-completion
2137 // token, in case we are code-completing in the middle of the switch and not
2138 // at the end. However, we aren't able to do so at the moment.
2139 llvm::SmallPtrSet<EnumConstantDecl *, 8> EnumeratorsSeen;
Douglas Gregorf2510672009-09-21 19:57:38 +00002140 NestedNameSpecifier *Qualifier = 0;
Douglas Gregord328d572009-09-21 18:10:23 +00002141 for (SwitchCase *SC = Switch->getSwitchCaseList(); SC;
2142 SC = SC->getNextSwitchCase()) {
2143 CaseStmt *Case = dyn_cast<CaseStmt>(SC);
2144 if (!Case)
2145 continue;
2146
2147 Expr *CaseVal = Case->getLHS()->IgnoreParenCasts();
2148 if (DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(CaseVal))
2149 if (EnumConstantDecl *Enumerator
2150 = dyn_cast<EnumConstantDecl>(DRE->getDecl())) {
2151 // We look into the AST of the case statement to determine which
2152 // enumerator was named. Alternatively, we could compute the value of
2153 // the integral constant expression, then compare it against the
2154 // values of each enumerator. However, value-based approach would not
2155 // work as well with C++ templates where enumerators declared within a
2156 // template are type- and value-dependent.
2157 EnumeratorsSeen.insert(Enumerator);
2158
Douglas Gregorf2510672009-09-21 19:57:38 +00002159 // If this is a qualified-id, keep track of the nested-name-specifier
2160 // so that we can reproduce it as part of code completion, e.g.,
Douglas Gregord328d572009-09-21 18:10:23 +00002161 //
2162 // switch (TagD.getKind()) {
2163 // case TagDecl::TK_enum:
2164 // break;
2165 // case XXX
2166 //
Douglas Gregorf2510672009-09-21 19:57:38 +00002167 // At the XXX, our completions are TagDecl::TK_union,
Douglas Gregord328d572009-09-21 18:10:23 +00002168 // TagDecl::TK_struct, and TagDecl::TK_class, rather than TK_union,
2169 // TK_struct, and TK_class.
Douglas Gregor4bd90e52009-10-23 18:54:35 +00002170 Qualifier = DRE->getQualifier();
Douglas Gregord328d572009-09-21 18:10:23 +00002171 }
2172 }
2173
Douglas Gregorf2510672009-09-21 19:57:38 +00002174 if (getLangOptions().CPlusPlus && !Qualifier && EnumeratorsSeen.empty()) {
2175 // If there are no prior enumerators in C++, check whether we have to
2176 // qualify the names of the enumerators that we suggest, because they
2177 // may not be visible in this scope.
2178 Qualifier = getRequiredQualification(Context, CurContext,
2179 Enum->getDeclContext());
2180
2181 // FIXME: Scoped enums need to start with "EnumDecl" as the context!
2182 }
2183
Douglas Gregord328d572009-09-21 18:10:23 +00002184 // Add any enumerators that have not yet been mentioned.
2185 ResultBuilder Results(*this);
2186 Results.EnterNewScope();
2187 for (EnumDecl::enumerator_iterator E = Enum->enumerator_begin(),
2188 EEnd = Enum->enumerator_end();
2189 E != EEnd; ++E) {
2190 if (EnumeratorsSeen.count(*E))
2191 continue;
2192
Douglas Gregorfc59ce12010-01-14 16:14:35 +00002193 Results.AddResult(CodeCompleteConsumer::Result(*E, Qualifier),
2194 CurContext, 0, false);
Douglas Gregord328d572009-09-21 18:10:23 +00002195 }
2196 Results.ExitScope();
2197
Douglas Gregor9eb77012009-11-07 00:00:49 +00002198 if (CodeCompleter->includeMacros())
Douglas Gregorf98e6a22010-01-13 23:51:12 +00002199 AddMacroResults(PP, Results);
Daniel Dunbar242ea9a2009-11-13 08:58:20 +00002200 HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
Douglas Gregord328d572009-09-21 18:10:23 +00002201}
2202
Douglas Gregorcabea402009-09-22 15:41:20 +00002203namespace {
2204 struct IsBetterOverloadCandidate {
2205 Sema &S;
John McCallbc077cf2010-02-08 23:07:23 +00002206 SourceLocation Loc;
Douglas Gregorcabea402009-09-22 15:41:20 +00002207
2208 public:
John McCallbc077cf2010-02-08 23:07:23 +00002209 explicit IsBetterOverloadCandidate(Sema &S, SourceLocation Loc)
2210 : S(S), Loc(Loc) { }
Douglas Gregorcabea402009-09-22 15:41:20 +00002211
2212 bool
2213 operator()(const OverloadCandidate &X, const OverloadCandidate &Y) const {
John McCallbc077cf2010-02-08 23:07:23 +00002214 return S.isBetterOverloadCandidate(X, Y, Loc);
Douglas Gregorcabea402009-09-22 15:41:20 +00002215 }
2216 };
2217}
2218
2219void Sema::CodeCompleteCall(Scope *S, ExprTy *FnIn,
2220 ExprTy **ArgsIn, unsigned NumArgs) {
2221 if (!CodeCompleter)
2222 return;
Douglas Gregor3ef59522009-12-11 19:06:04 +00002223
2224 // When we're code-completing for a call, we fall back to ordinary
2225 // name code-completion whenever we can't produce specific
2226 // results. We may want to revisit this strategy in the future,
2227 // e.g., by merging the two kinds of results.
2228
Douglas Gregorcabea402009-09-22 15:41:20 +00002229 Expr *Fn = (Expr *)FnIn;
2230 Expr **Args = (Expr **)ArgsIn;
Douglas Gregor3ef59522009-12-11 19:06:04 +00002231
Douglas Gregorcabea402009-09-22 15:41:20 +00002232 // Ignore type-dependent call expressions entirely.
2233 if (Fn->isTypeDependent() ||
Douglas Gregor3ef59522009-12-11 19:06:04 +00002234 Expr::hasAnyTypeDependentArguments(Args, NumArgs)) {
Douglas Gregor504a6ae2010-01-10 23:08:15 +00002235 CodeCompleteOrdinaryName(S, CCC_Expression);
Douglas Gregorcabea402009-09-22 15:41:20 +00002236 return;
Douglas Gregor3ef59522009-12-11 19:06:04 +00002237 }
Douglas Gregorcabea402009-09-22 15:41:20 +00002238
John McCall57500772009-12-16 12:17:52 +00002239 // Build an overload candidate set based on the functions we find.
John McCallbc077cf2010-02-08 23:07:23 +00002240 SourceLocation Loc = Fn->getExprLoc();
2241 OverloadCandidateSet CandidateSet(Loc);
John McCall57500772009-12-16 12:17:52 +00002242
Douglas Gregorcabea402009-09-22 15:41:20 +00002243 // FIXME: What if we're calling something that isn't a function declaration?
2244 // FIXME: What if we're calling a pseudo-destructor?
2245 // FIXME: What if we're calling a member function?
2246
Douglas Gregorff59f672010-01-21 15:46:19 +00002247 typedef CodeCompleteConsumer::OverloadCandidate ResultCandidate;
2248 llvm::SmallVector<ResultCandidate, 8> Results;
2249
John McCall57500772009-12-16 12:17:52 +00002250 Expr *NakedFn = Fn->IgnoreParenCasts();
2251 if (UnresolvedLookupExpr *ULE = dyn_cast<UnresolvedLookupExpr>(NakedFn))
2252 AddOverloadedCallCandidates(ULE, Args, NumArgs, CandidateSet,
2253 /*PartialOverloading=*/ true);
2254 else if (DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(NakedFn)) {
2255 FunctionDecl *FDecl = dyn_cast<FunctionDecl>(DRE->getDecl());
Douglas Gregorff59f672010-01-21 15:46:19 +00002256 if (FDecl) {
2257 if (!FDecl->getType()->getAs<FunctionProtoType>())
2258 Results.push_back(ResultCandidate(FDecl));
2259 else
John McCallb89836b2010-01-26 01:37:31 +00002260 // FIXME: access?
John McCalla0296f72010-03-19 07:35:19 +00002261 AddOverloadCandidate(FDecl, DeclAccessPair::make(FDecl, AS_none),
2262 Args, NumArgs, CandidateSet,
Douglas Gregorff59f672010-01-21 15:46:19 +00002263 false, false, /*PartialOverloading*/ true);
2264 }
John McCall57500772009-12-16 12:17:52 +00002265 }
Douglas Gregorcabea402009-09-22 15:41:20 +00002266
Douglas Gregorff59f672010-01-21 15:46:19 +00002267 if (!CandidateSet.empty()) {
2268 // Sort the overload candidate set by placing the best overloads first.
2269 std::stable_sort(CandidateSet.begin(), CandidateSet.end(),
John McCallbc077cf2010-02-08 23:07:23 +00002270 IsBetterOverloadCandidate(*this, Loc));
Douglas Gregorcabea402009-09-22 15:41:20 +00002271
Douglas Gregorff59f672010-01-21 15:46:19 +00002272 // Add the remaining viable overload candidates as code-completion reslults.
2273 for (OverloadCandidateSet::iterator Cand = CandidateSet.begin(),
2274 CandEnd = CandidateSet.end();
2275 Cand != CandEnd; ++Cand) {
2276 if (Cand->Viable)
2277 Results.push_back(ResultCandidate(Cand->Function));
2278 }
Douglas Gregorcabea402009-09-22 15:41:20 +00002279 }
Douglas Gregor3ef59522009-12-11 19:06:04 +00002280
2281 if (Results.empty())
Douglas Gregor504a6ae2010-01-10 23:08:15 +00002282 CodeCompleteOrdinaryName(S, CCC_Expression);
Douglas Gregor3ef59522009-12-11 19:06:04 +00002283 else
2284 CodeCompleter->ProcessOverloadCandidates(*this, NumArgs, Results.data(),
2285 Results.size());
Douglas Gregorcabea402009-09-22 15:41:20 +00002286}
2287
Douglas Gregor2436e712009-09-17 21:32:03 +00002288void Sema::CodeCompleteQualifiedId(Scope *S, const CXXScopeSpec &SS,
2289 bool EnteringContext) {
2290 if (!SS.getScopeRep() || !CodeCompleter)
2291 return;
2292
Douglas Gregor3545ff42009-09-21 16:56:56 +00002293 DeclContext *Ctx = computeDeclContext(SS, EnteringContext);
2294 if (!Ctx)
2295 return;
Douglas Gregor800f2f02009-12-11 18:28:39 +00002296
2297 // Try to instantiate any non-dependent declaration contexts before
2298 // we look in them.
2299 if (!isDependentScopeSpecifier(SS) && RequireCompleteDeclContext(SS))
2300 return;
2301
Douglas Gregor3545ff42009-09-21 16:56:56 +00002302 ResultBuilder Results(*this);
Douglas Gregor200c99d2010-01-14 03:35:48 +00002303 CodeCompletionDeclConsumer Consumer(Results, CurContext);
2304 LookupVisibleDecls(Ctx, LookupOrdinaryName, Consumer);
Douglas Gregor3545ff42009-09-21 16:56:56 +00002305
2306 // The "template" keyword can follow "::" in the grammar, but only
2307 // put it into the grammar if the nested-name-specifier is dependent.
2308 NestedNameSpecifier *NNS = (NestedNameSpecifier *)SS.getScopeRep();
2309 if (!Results.empty() && NNS->isDependent())
Douglas Gregor78a21012010-01-14 16:01:26 +00002310 Results.AddResult("template");
Douglas Gregor3545ff42009-09-21 16:56:56 +00002311
Douglas Gregor9eb77012009-11-07 00:00:49 +00002312 if (CodeCompleter->includeMacros())
Douglas Gregorf98e6a22010-01-13 23:51:12 +00002313 AddMacroResults(PP, Results);
Daniel Dunbar242ea9a2009-11-13 08:58:20 +00002314 HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
Douglas Gregor2436e712009-09-17 21:32:03 +00002315}
Douglas Gregor7e90c6d2009-09-18 19:03:04 +00002316
2317void Sema::CodeCompleteUsing(Scope *S) {
2318 if (!CodeCompleter)
2319 return;
2320
Douglas Gregor3545ff42009-09-21 16:56:56 +00002321 ResultBuilder Results(*this, &ResultBuilder::IsNestedNameSpecifier);
Douglas Gregor64b12b52009-09-22 23:31:26 +00002322 Results.EnterNewScope();
Douglas Gregor3545ff42009-09-21 16:56:56 +00002323
2324 // If we aren't in class scope, we could see the "namespace" keyword.
2325 if (!S->isClassScope())
Douglas Gregor78a21012010-01-14 16:01:26 +00002326 Results.AddResult(CodeCompleteConsumer::Result("namespace"));
Douglas Gregor3545ff42009-09-21 16:56:56 +00002327
2328 // After "using", we can see anything that would start a
2329 // nested-name-specifier.
Douglas Gregora6e2edc2010-01-14 03:27:13 +00002330 CodeCompletionDeclConsumer Consumer(Results, CurContext);
2331 LookupVisibleDecls(S, LookupOrdinaryName, Consumer);
Douglas Gregor64b12b52009-09-22 23:31:26 +00002332 Results.ExitScope();
Douglas Gregor3545ff42009-09-21 16:56:56 +00002333
Douglas Gregor9eb77012009-11-07 00:00:49 +00002334 if (CodeCompleter->includeMacros())
Douglas Gregorf98e6a22010-01-13 23:51:12 +00002335 AddMacroResults(PP, Results);
Daniel Dunbar242ea9a2009-11-13 08:58:20 +00002336 HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
Douglas Gregor7e90c6d2009-09-18 19:03:04 +00002337}
2338
2339void Sema::CodeCompleteUsingDirective(Scope *S) {
2340 if (!CodeCompleter)
2341 return;
2342
Douglas Gregor3545ff42009-09-21 16:56:56 +00002343 // After "using namespace", we expect to see a namespace name or namespace
2344 // alias.
2345 ResultBuilder Results(*this, &ResultBuilder::IsNamespaceOrAlias);
Douglas Gregor64b12b52009-09-22 23:31:26 +00002346 Results.EnterNewScope();
Douglas Gregora6e2edc2010-01-14 03:27:13 +00002347 CodeCompletionDeclConsumer Consumer(Results, CurContext);
2348 LookupVisibleDecls(S, LookupOrdinaryName, Consumer);
Douglas Gregor64b12b52009-09-22 23:31:26 +00002349 Results.ExitScope();
Douglas Gregor9eb77012009-11-07 00:00:49 +00002350 if (CodeCompleter->includeMacros())
Douglas Gregorf98e6a22010-01-13 23:51:12 +00002351 AddMacroResults(PP, Results);
Daniel Dunbar242ea9a2009-11-13 08:58:20 +00002352 HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
Douglas Gregor7e90c6d2009-09-18 19:03:04 +00002353}
2354
2355void Sema::CodeCompleteNamespaceDecl(Scope *S) {
2356 if (!CodeCompleter)
2357 return;
2358
Douglas Gregor3545ff42009-09-21 16:56:56 +00002359 ResultBuilder Results(*this, &ResultBuilder::IsNamespace);
2360 DeclContext *Ctx = (DeclContext *)S->getEntity();
2361 if (!S->getParent())
2362 Ctx = Context.getTranslationUnitDecl();
2363
2364 if (Ctx && Ctx->isFileContext()) {
2365 // We only want to see those namespaces that have already been defined
2366 // within this scope, because its likely that the user is creating an
2367 // extended namespace declaration. Keep track of the most recent
2368 // definition of each namespace.
2369 std::map<NamespaceDecl *, NamespaceDecl *> OrigToLatest;
2370 for (DeclContext::specific_decl_iterator<NamespaceDecl>
2371 NS(Ctx->decls_begin()), NSEnd(Ctx->decls_end());
2372 NS != NSEnd; ++NS)
2373 OrigToLatest[NS->getOriginalNamespace()] = *NS;
2374
2375 // Add the most recent definition (or extended definition) of each
2376 // namespace to the list of results.
Douglas Gregor64b12b52009-09-22 23:31:26 +00002377 Results.EnterNewScope();
Douglas Gregor3545ff42009-09-21 16:56:56 +00002378 for (std::map<NamespaceDecl *, NamespaceDecl *>::iterator
2379 NS = OrigToLatest.begin(), NSEnd = OrigToLatest.end();
2380 NS != NSEnd; ++NS)
Douglas Gregorfc59ce12010-01-14 16:14:35 +00002381 Results.AddResult(CodeCompleteConsumer::Result(NS->second, 0),
2382 CurContext, 0, false);
Douglas Gregor64b12b52009-09-22 23:31:26 +00002383 Results.ExitScope();
Douglas Gregor3545ff42009-09-21 16:56:56 +00002384 }
2385
Douglas Gregor9eb77012009-11-07 00:00:49 +00002386 if (CodeCompleter->includeMacros())
Douglas Gregorf98e6a22010-01-13 23:51:12 +00002387 AddMacroResults(PP, Results);
Daniel Dunbar242ea9a2009-11-13 08:58:20 +00002388 HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
Douglas Gregor7e90c6d2009-09-18 19:03:04 +00002389}
2390
2391void Sema::CodeCompleteNamespaceAliasDecl(Scope *S) {
2392 if (!CodeCompleter)
2393 return;
2394
Douglas Gregor3545ff42009-09-21 16:56:56 +00002395 // After "namespace", we expect to see a namespace or alias.
2396 ResultBuilder Results(*this, &ResultBuilder::IsNamespaceOrAlias);
Douglas Gregora6e2edc2010-01-14 03:27:13 +00002397 CodeCompletionDeclConsumer Consumer(Results, CurContext);
2398 LookupVisibleDecls(S, LookupOrdinaryName, Consumer);
Douglas Gregor9eb77012009-11-07 00:00:49 +00002399 if (CodeCompleter->includeMacros())
Douglas Gregorf98e6a22010-01-13 23:51:12 +00002400 AddMacroResults(PP, Results);
Daniel Dunbar242ea9a2009-11-13 08:58:20 +00002401 HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
Douglas Gregor7e90c6d2009-09-18 19:03:04 +00002402}
2403
Douglas Gregorc811ede2009-09-18 20:05:18 +00002404void Sema::CodeCompleteOperatorName(Scope *S) {
2405 if (!CodeCompleter)
2406 return;
Douglas Gregor3545ff42009-09-21 16:56:56 +00002407
2408 typedef CodeCompleteConsumer::Result Result;
2409 ResultBuilder Results(*this, &ResultBuilder::IsType);
Douglas Gregor64b12b52009-09-22 23:31:26 +00002410 Results.EnterNewScope();
Douglas Gregorc811ede2009-09-18 20:05:18 +00002411
Douglas Gregor3545ff42009-09-21 16:56:56 +00002412 // Add the names of overloadable operators.
2413#define OVERLOADED_OPERATOR(Name,Spelling,Token,Unary,Binary,MemberOnly) \
2414 if (std::strcmp(Spelling, "?")) \
Douglas Gregor78a21012010-01-14 16:01:26 +00002415 Results.AddResult(Result(Spelling));
Douglas Gregor3545ff42009-09-21 16:56:56 +00002416#include "clang/Basic/OperatorKinds.def"
2417
2418 // Add any type names visible from the current scope
Douglas Gregor6ae4c522010-01-14 03:21:49 +00002419 Results.allowNestedNameSpecifiers();
Douglas Gregora6e2edc2010-01-14 03:27:13 +00002420 CodeCompletionDeclConsumer Consumer(Results, CurContext);
2421 LookupVisibleDecls(S, LookupOrdinaryName, Consumer);
Douglas Gregor3545ff42009-09-21 16:56:56 +00002422
2423 // Add any type specifiers
Douglas Gregorf98e6a22010-01-13 23:51:12 +00002424 AddTypeSpecifierResults(getLangOptions(), Results);
Douglas Gregor64b12b52009-09-22 23:31:26 +00002425 Results.ExitScope();
Douglas Gregor3545ff42009-09-21 16:56:56 +00002426
Douglas Gregor9eb77012009-11-07 00:00:49 +00002427 if (CodeCompleter->includeMacros())
Douglas Gregorf98e6a22010-01-13 23:51:12 +00002428 AddMacroResults(PP, Results);
Daniel Dunbar242ea9a2009-11-13 08:58:20 +00002429 HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
Douglas Gregorc811ede2009-09-18 20:05:18 +00002430}
Douglas Gregor7e90c6d2009-09-18 19:03:04 +00002431
Douglas Gregorf1934162010-01-13 21:24:21 +00002432// Macro that expands to @Keyword or Keyword, depending on whether NeedAt is
2433// true or false.
2434#define OBJC_AT_KEYWORD_NAME(NeedAt,Keyword) NeedAt? "@" #Keyword : #Keyword
Douglas Gregorf98e6a22010-01-13 23:51:12 +00002435static void AddObjCImplementationResults(const LangOptions &LangOpts,
Douglas Gregorf1934162010-01-13 21:24:21 +00002436 ResultBuilder &Results,
2437 bool NeedAt) {
2438 typedef CodeCompleteConsumer::Result Result;
2439 // Since we have an implementation, we can end it.
Douglas Gregor78a21012010-01-14 16:01:26 +00002440 Results.AddResult(Result(OBJC_AT_KEYWORD_NAME(NeedAt,end)));
Douglas Gregorf1934162010-01-13 21:24:21 +00002441
2442 CodeCompletionString *Pattern = 0;
2443 if (LangOpts.ObjC2) {
2444 // @dynamic
2445 Pattern = new CodeCompletionString;
2446 Pattern->AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt,dynamic));
2447 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
2448 Pattern->AddPlaceholderChunk("property");
Douglas Gregor78a21012010-01-14 16:01:26 +00002449 Results.AddResult(Result(Pattern));
Douglas Gregorf1934162010-01-13 21:24:21 +00002450
2451 // @synthesize
2452 Pattern = new CodeCompletionString;
2453 Pattern->AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt,synthesize));
2454 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
2455 Pattern->AddPlaceholderChunk("property");
Douglas Gregor78a21012010-01-14 16:01:26 +00002456 Results.AddResult(Result(Pattern));
Douglas Gregorf1934162010-01-13 21:24:21 +00002457 }
2458}
2459
Douglas Gregorf98e6a22010-01-13 23:51:12 +00002460static void AddObjCInterfaceResults(const LangOptions &LangOpts,
Douglas Gregorf1934162010-01-13 21:24:21 +00002461 ResultBuilder &Results,
2462 bool NeedAt) {
2463 typedef CodeCompleteConsumer::Result Result;
2464
2465 // Since we have an interface or protocol, we can end it.
Douglas Gregor78a21012010-01-14 16:01:26 +00002466 Results.AddResult(Result(OBJC_AT_KEYWORD_NAME(NeedAt,end)));
Douglas Gregorf1934162010-01-13 21:24:21 +00002467
2468 if (LangOpts.ObjC2) {
2469 // @property
Douglas Gregor78a21012010-01-14 16:01:26 +00002470 Results.AddResult(Result(OBJC_AT_KEYWORD_NAME(NeedAt,property)));
Douglas Gregorf1934162010-01-13 21:24:21 +00002471
2472 // @required
Douglas Gregor78a21012010-01-14 16:01:26 +00002473 Results.AddResult(Result(OBJC_AT_KEYWORD_NAME(NeedAt,required)));
Douglas Gregorf1934162010-01-13 21:24:21 +00002474
2475 // @optional
Douglas Gregor78a21012010-01-14 16:01:26 +00002476 Results.AddResult(Result(OBJC_AT_KEYWORD_NAME(NeedAt,optional)));
Douglas Gregorf1934162010-01-13 21:24:21 +00002477 }
2478}
2479
Douglas Gregorf98e6a22010-01-13 23:51:12 +00002480static void AddObjCTopLevelResults(ResultBuilder &Results, bool NeedAt) {
Douglas Gregorf1934162010-01-13 21:24:21 +00002481 typedef CodeCompleteConsumer::Result Result;
2482 CodeCompletionString *Pattern = 0;
2483
2484 // @class name ;
2485 Pattern = new CodeCompletionString;
2486 Pattern->AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt,class));
2487 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
2488 Pattern->AddPlaceholderChunk("identifier");
2489 Pattern->AddChunk(CodeCompletionString::CK_SemiColon);
Douglas Gregor78a21012010-01-14 16:01:26 +00002490 Results.AddResult(Result(Pattern));
Douglas Gregorf1934162010-01-13 21:24:21 +00002491
2492 // @interface name
2493 // FIXME: Could introduce the whole pattern, including superclasses and
2494 // such.
2495 Pattern = new CodeCompletionString;
2496 Pattern->AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt,interface));
2497 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
2498 Pattern->AddPlaceholderChunk("class");
Douglas Gregor78a21012010-01-14 16:01:26 +00002499 Results.AddResult(Result(Pattern));
Douglas Gregorf1934162010-01-13 21:24:21 +00002500
2501 // @protocol name
2502 Pattern = new CodeCompletionString;
2503 Pattern->AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt,protocol));
2504 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
2505 Pattern->AddPlaceholderChunk("protocol");
Douglas Gregor78a21012010-01-14 16:01:26 +00002506 Results.AddResult(Result(Pattern));
Douglas Gregorf1934162010-01-13 21:24:21 +00002507
2508 // @implementation name
2509 Pattern = new CodeCompletionString;
2510 Pattern->AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt,implementation));
2511 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
2512 Pattern->AddPlaceholderChunk("class");
Douglas Gregor78a21012010-01-14 16:01:26 +00002513 Results.AddResult(Result(Pattern));
Douglas Gregorf1934162010-01-13 21:24:21 +00002514
2515 // @compatibility_alias name
2516 Pattern = new CodeCompletionString;
2517 Pattern->AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt,compatibility_alias));
2518 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
2519 Pattern->AddPlaceholderChunk("alias");
2520 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
2521 Pattern->AddPlaceholderChunk("class");
Douglas Gregor78a21012010-01-14 16:01:26 +00002522 Results.AddResult(Result(Pattern));
Douglas Gregorf1934162010-01-13 21:24:21 +00002523}
2524
Douglas Gregorf48706c2009-12-07 09:27:33 +00002525void Sema::CodeCompleteObjCAtDirective(Scope *S, DeclPtrTy ObjCImpDecl,
2526 bool InInterface) {
2527 typedef CodeCompleteConsumer::Result Result;
2528 ResultBuilder Results(*this);
2529 Results.EnterNewScope();
Douglas Gregorf1934162010-01-13 21:24:21 +00002530 if (ObjCImpDecl)
Douglas Gregorf98e6a22010-01-13 23:51:12 +00002531 AddObjCImplementationResults(getLangOptions(), Results, false);
Douglas Gregorf1934162010-01-13 21:24:21 +00002532 else if (InInterface)
Douglas Gregorf98e6a22010-01-13 23:51:12 +00002533 AddObjCInterfaceResults(getLangOptions(), Results, false);
Douglas Gregorf1934162010-01-13 21:24:21 +00002534 else
Douglas Gregorf98e6a22010-01-13 23:51:12 +00002535 AddObjCTopLevelResults(Results, false);
Douglas Gregorf48706c2009-12-07 09:27:33 +00002536 Results.ExitScope();
2537 HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
2538}
2539
Douglas Gregorf98e6a22010-01-13 23:51:12 +00002540static void AddObjCExpressionResults(ResultBuilder &Results, bool NeedAt) {
Douglas Gregorbc7c5e42009-12-07 09:51:25 +00002541 typedef CodeCompleteConsumer::Result Result;
2542 CodeCompletionString *Pattern = 0;
2543
2544 // @encode ( type-name )
2545 Pattern = new CodeCompletionString;
Douglas Gregorf1934162010-01-13 21:24:21 +00002546 Pattern->AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt,encode));
Douglas Gregorbc7c5e42009-12-07 09:51:25 +00002547 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
2548 Pattern->AddPlaceholderChunk("type-name");
2549 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
Douglas Gregor78a21012010-01-14 16:01:26 +00002550 Results.AddResult(Result(Pattern));
Douglas Gregorbc7c5e42009-12-07 09:51:25 +00002551
2552 // @protocol ( protocol-name )
2553 Pattern = new CodeCompletionString;
Douglas Gregorf1934162010-01-13 21:24:21 +00002554 Pattern->AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt,protocol));
Douglas Gregorbc7c5e42009-12-07 09:51:25 +00002555 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
2556 Pattern->AddPlaceholderChunk("protocol-name");
2557 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
Douglas Gregor78a21012010-01-14 16:01:26 +00002558 Results.AddResult(Result(Pattern));
Douglas Gregorbc7c5e42009-12-07 09:51:25 +00002559
2560 // @selector ( selector )
2561 Pattern = new CodeCompletionString;
Douglas Gregorf1934162010-01-13 21:24:21 +00002562 Pattern->AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt,selector));
Douglas Gregorbc7c5e42009-12-07 09:51:25 +00002563 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
2564 Pattern->AddPlaceholderChunk("selector");
2565 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
Douglas Gregor78a21012010-01-14 16:01:26 +00002566 Results.AddResult(Result(Pattern));
Douglas Gregorbc7c5e42009-12-07 09:51:25 +00002567}
2568
Douglas Gregorf98e6a22010-01-13 23:51:12 +00002569static void AddObjCStatementResults(ResultBuilder &Results, bool NeedAt) {
Douglas Gregorbc7c5e42009-12-07 09:51:25 +00002570 typedef CodeCompleteConsumer::Result Result;
Douglas Gregorbc7c5e42009-12-07 09:51:25 +00002571 CodeCompletionString *Pattern = 0;
Douglas Gregorf1934162010-01-13 21:24:21 +00002572
Douglas Gregorbc7c5e42009-12-07 09:51:25 +00002573 // @try { statements } @catch ( declaration ) { statements } @finally
2574 // { statements }
2575 Pattern = new CodeCompletionString;
Douglas Gregorf1934162010-01-13 21:24:21 +00002576 Pattern->AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt,try));
Douglas Gregorbc7c5e42009-12-07 09:51:25 +00002577 Pattern->AddChunk(CodeCompletionString::CK_LeftBrace);
2578 Pattern->AddPlaceholderChunk("statements");
2579 Pattern->AddChunk(CodeCompletionString::CK_RightBrace);
2580 Pattern->AddTextChunk("@catch");
2581 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
2582 Pattern->AddPlaceholderChunk("parameter");
2583 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
2584 Pattern->AddChunk(CodeCompletionString::CK_LeftBrace);
2585 Pattern->AddPlaceholderChunk("statements");
2586 Pattern->AddChunk(CodeCompletionString::CK_RightBrace);
2587 Pattern->AddTextChunk("@finally");
2588 Pattern->AddChunk(CodeCompletionString::CK_LeftBrace);
2589 Pattern->AddPlaceholderChunk("statements");
2590 Pattern->AddChunk(CodeCompletionString::CK_RightBrace);
Douglas Gregor78a21012010-01-14 16:01:26 +00002591 Results.AddResult(Result(Pattern));
Douglas Gregorf1934162010-01-13 21:24:21 +00002592
Douglas Gregorbc7c5e42009-12-07 09:51:25 +00002593 // @throw
2594 Pattern = new CodeCompletionString;
Douglas Gregorf1934162010-01-13 21:24:21 +00002595 Pattern->AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt,throw));
Douglas Gregor6a803932010-01-12 06:38:28 +00002596 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
Douglas Gregorbc7c5e42009-12-07 09:51:25 +00002597 Pattern->AddPlaceholderChunk("expression");
Douglas Gregor6a803932010-01-12 06:38:28 +00002598 Pattern->AddChunk(CodeCompletionString::CK_SemiColon);
Douglas Gregor78a21012010-01-14 16:01:26 +00002599 Results.AddResult(Result(Pattern));
Douglas Gregorf1934162010-01-13 21:24:21 +00002600
Douglas Gregorbc7c5e42009-12-07 09:51:25 +00002601 // @synchronized ( expression ) { statements }
2602 Pattern = new CodeCompletionString;
Douglas Gregorf1934162010-01-13 21:24:21 +00002603 Pattern->AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt,synchronized));
Douglas Gregor6a803932010-01-12 06:38:28 +00002604 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
Douglas Gregorbc7c5e42009-12-07 09:51:25 +00002605 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
2606 Pattern->AddPlaceholderChunk("expression");
2607 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
2608 Pattern->AddChunk(CodeCompletionString::CK_LeftBrace);
2609 Pattern->AddPlaceholderChunk("statements");
2610 Pattern->AddChunk(CodeCompletionString::CK_RightBrace);
Douglas Gregor78a21012010-01-14 16:01:26 +00002611 Results.AddResult(Result(Pattern));
Douglas Gregorf1934162010-01-13 21:24:21 +00002612}
Douglas Gregorbc7c5e42009-12-07 09:51:25 +00002613
Douglas Gregorf98e6a22010-01-13 23:51:12 +00002614static void AddObjCVisibilityResults(const LangOptions &LangOpts,
Douglas Gregor48d46252010-01-13 21:54:15 +00002615 ResultBuilder &Results,
2616 bool NeedAt) {
Douglas Gregorf1934162010-01-13 21:24:21 +00002617 typedef CodeCompleteConsumer::Result Result;
Douglas Gregor78a21012010-01-14 16:01:26 +00002618 Results.AddResult(Result(OBJC_AT_KEYWORD_NAME(NeedAt,private)));
2619 Results.AddResult(Result(OBJC_AT_KEYWORD_NAME(NeedAt,protected)));
2620 Results.AddResult(Result(OBJC_AT_KEYWORD_NAME(NeedAt,public)));
Douglas Gregor48d46252010-01-13 21:54:15 +00002621 if (LangOpts.ObjC2)
Douglas Gregor78a21012010-01-14 16:01:26 +00002622 Results.AddResult(Result(OBJC_AT_KEYWORD_NAME(NeedAt,package)));
Douglas Gregor48d46252010-01-13 21:54:15 +00002623}
2624
2625void Sema::CodeCompleteObjCAtVisibility(Scope *S) {
2626 ResultBuilder Results(*this);
2627 Results.EnterNewScope();
Douglas Gregorf98e6a22010-01-13 23:51:12 +00002628 AddObjCVisibilityResults(getLangOptions(), Results, false);
Douglas Gregor48d46252010-01-13 21:54:15 +00002629 Results.ExitScope();
2630 HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
2631}
2632
2633void Sema::CodeCompleteObjCAtStatement(Scope *S) {
Douglas Gregorf1934162010-01-13 21:24:21 +00002634 ResultBuilder Results(*this);
2635 Results.EnterNewScope();
Douglas Gregorf98e6a22010-01-13 23:51:12 +00002636 AddObjCStatementResults(Results, false);
2637 AddObjCExpressionResults(Results, false);
Douglas Gregorbc7c5e42009-12-07 09:51:25 +00002638 Results.ExitScope();
2639 HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
2640}
2641
2642void Sema::CodeCompleteObjCAtExpression(Scope *S) {
2643 ResultBuilder Results(*this);
2644 Results.EnterNewScope();
Douglas Gregorf98e6a22010-01-13 23:51:12 +00002645 AddObjCExpressionResults(Results, false);
Douglas Gregorbc7c5e42009-12-07 09:51:25 +00002646 Results.ExitScope();
2647 HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
2648}
2649
Douglas Gregore6078da2009-11-19 00:14:45 +00002650/// \brief Determine whether the addition of the given flag to an Objective-C
2651/// property's attributes will cause a conflict.
2652static bool ObjCPropertyFlagConflicts(unsigned Attributes, unsigned NewFlag) {
2653 // Check if we've already added this flag.
2654 if (Attributes & NewFlag)
2655 return true;
2656
2657 Attributes |= NewFlag;
2658
2659 // Check for collisions with "readonly".
2660 if ((Attributes & ObjCDeclSpec::DQ_PR_readonly) &&
2661 (Attributes & (ObjCDeclSpec::DQ_PR_readwrite |
2662 ObjCDeclSpec::DQ_PR_assign |
2663 ObjCDeclSpec::DQ_PR_copy |
2664 ObjCDeclSpec::DQ_PR_retain)))
2665 return true;
2666
2667 // Check for more than one of { assign, copy, retain }.
2668 unsigned AssignCopyRetMask = Attributes & (ObjCDeclSpec::DQ_PR_assign |
2669 ObjCDeclSpec::DQ_PR_copy |
2670 ObjCDeclSpec::DQ_PR_retain);
2671 if (AssignCopyRetMask &&
2672 AssignCopyRetMask != ObjCDeclSpec::DQ_PR_assign &&
2673 AssignCopyRetMask != ObjCDeclSpec::DQ_PR_copy &&
2674 AssignCopyRetMask != ObjCDeclSpec::DQ_PR_retain)
2675 return true;
2676
2677 return false;
2678}
2679
Douglas Gregor36029f42009-11-18 23:08:07 +00002680void Sema::CodeCompleteObjCPropertyFlags(Scope *S, ObjCDeclSpec &ODS) {
Steve Naroff936354c2009-10-08 21:55:05 +00002681 if (!CodeCompleter)
2682 return;
Douglas Gregor1b605f72009-11-19 01:08:35 +00002683
Steve Naroff936354c2009-10-08 21:55:05 +00002684 unsigned Attributes = ODS.getPropertyAttributes();
2685
2686 typedef CodeCompleteConsumer::Result Result;
2687 ResultBuilder Results(*this);
2688 Results.EnterNewScope();
Douglas Gregore6078da2009-11-19 00:14:45 +00002689 if (!ObjCPropertyFlagConflicts(Attributes, ObjCDeclSpec::DQ_PR_readonly))
Douglas Gregor78a21012010-01-14 16:01:26 +00002690 Results.AddResult(CodeCompleteConsumer::Result("readonly"));
Douglas Gregore6078da2009-11-19 00:14:45 +00002691 if (!ObjCPropertyFlagConflicts(Attributes, ObjCDeclSpec::DQ_PR_assign))
Douglas Gregor78a21012010-01-14 16:01:26 +00002692 Results.AddResult(CodeCompleteConsumer::Result("assign"));
Douglas Gregore6078da2009-11-19 00:14:45 +00002693 if (!ObjCPropertyFlagConflicts(Attributes, ObjCDeclSpec::DQ_PR_readwrite))
Douglas Gregor78a21012010-01-14 16:01:26 +00002694 Results.AddResult(CodeCompleteConsumer::Result("readwrite"));
Douglas Gregore6078da2009-11-19 00:14:45 +00002695 if (!ObjCPropertyFlagConflicts(Attributes, ObjCDeclSpec::DQ_PR_retain))
Douglas Gregor78a21012010-01-14 16:01:26 +00002696 Results.AddResult(CodeCompleteConsumer::Result("retain"));
Douglas Gregore6078da2009-11-19 00:14:45 +00002697 if (!ObjCPropertyFlagConflicts(Attributes, ObjCDeclSpec::DQ_PR_copy))
Douglas Gregor78a21012010-01-14 16:01:26 +00002698 Results.AddResult(CodeCompleteConsumer::Result("copy"));
Douglas Gregore6078da2009-11-19 00:14:45 +00002699 if (!ObjCPropertyFlagConflicts(Attributes, ObjCDeclSpec::DQ_PR_nonatomic))
Douglas Gregor78a21012010-01-14 16:01:26 +00002700 Results.AddResult(CodeCompleteConsumer::Result("nonatomic"));
Douglas Gregore6078da2009-11-19 00:14:45 +00002701 if (!ObjCPropertyFlagConflicts(Attributes, ObjCDeclSpec::DQ_PR_setter)) {
Douglas Gregor45f83ee2009-11-19 00:01:57 +00002702 CodeCompletionString *Setter = new CodeCompletionString;
2703 Setter->AddTypedTextChunk("setter");
2704 Setter->AddTextChunk(" = ");
2705 Setter->AddPlaceholderChunk("method");
Douglas Gregor78a21012010-01-14 16:01:26 +00002706 Results.AddResult(CodeCompleteConsumer::Result(Setter));
Douglas Gregor45f83ee2009-11-19 00:01:57 +00002707 }
Douglas Gregore6078da2009-11-19 00:14:45 +00002708 if (!ObjCPropertyFlagConflicts(Attributes, ObjCDeclSpec::DQ_PR_getter)) {
Douglas Gregor45f83ee2009-11-19 00:01:57 +00002709 CodeCompletionString *Getter = new CodeCompletionString;
2710 Getter->AddTypedTextChunk("getter");
2711 Getter->AddTextChunk(" = ");
2712 Getter->AddPlaceholderChunk("method");
Douglas Gregor78a21012010-01-14 16:01:26 +00002713 Results.AddResult(CodeCompleteConsumer::Result(Getter));
Douglas Gregor45f83ee2009-11-19 00:01:57 +00002714 }
Steve Naroff936354c2009-10-08 21:55:05 +00002715 Results.ExitScope();
Daniel Dunbar242ea9a2009-11-13 08:58:20 +00002716 HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
Steve Naroff936354c2009-10-08 21:55:05 +00002717}
Steve Naroffeae65032009-11-07 02:08:14 +00002718
Douglas Gregorc8537c52009-11-19 07:41:15 +00002719/// \brief Descripts the kind of Objective-C method that we want to find
2720/// via code completion.
2721enum ObjCMethodKind {
2722 MK_Any, //< Any kind of method, provided it means other specified criteria.
2723 MK_ZeroArgSelector, //< Zero-argument (unary) selector.
2724 MK_OneArgSelector //< One-argument selector.
2725};
2726
2727static bool isAcceptableObjCMethod(ObjCMethodDecl *Method,
2728 ObjCMethodKind WantKind,
2729 IdentifierInfo **SelIdents,
2730 unsigned NumSelIdents) {
2731 Selector Sel = Method->getSelector();
2732 if (NumSelIdents > Sel.getNumArgs())
2733 return false;
2734
2735 switch (WantKind) {
2736 case MK_Any: break;
2737 case MK_ZeroArgSelector: return Sel.isUnarySelector();
2738 case MK_OneArgSelector: return Sel.getNumArgs() == 1;
2739 }
2740
2741 for (unsigned I = 0; I != NumSelIdents; ++I)
2742 if (SelIdents[I] != Sel.getIdentifierInfoForSlot(I))
2743 return false;
2744
2745 return true;
2746}
2747
Douglas Gregorbab2b3c2009-11-17 23:22:23 +00002748/// \brief Add all of the Objective-C methods in the given Objective-C
2749/// container to the set of results.
2750///
2751/// The container will be a class, protocol, category, or implementation of
2752/// any of the above. This mether will recurse to include methods from
2753/// the superclasses of classes along with their categories, protocols, and
2754/// implementations.
2755///
2756/// \param Container the container in which we'll look to find methods.
2757///
2758/// \param WantInstance whether to add instance methods (only); if false, this
2759/// routine will add factory methods (only).
2760///
2761/// \param CurContext the context in which we're performing the lookup that
2762/// finds methods.
2763///
2764/// \param Results the structure into which we'll add results.
2765static void AddObjCMethods(ObjCContainerDecl *Container,
2766 bool WantInstanceMethods,
Douglas Gregorc8537c52009-11-19 07:41:15 +00002767 ObjCMethodKind WantKind,
Douglas Gregor1b605f72009-11-19 01:08:35 +00002768 IdentifierInfo **SelIdents,
2769 unsigned NumSelIdents,
Douglas Gregorbab2b3c2009-11-17 23:22:23 +00002770 DeclContext *CurContext,
2771 ResultBuilder &Results) {
2772 typedef CodeCompleteConsumer::Result Result;
2773 for (ObjCContainerDecl::method_iterator M = Container->meth_begin(),
2774 MEnd = Container->meth_end();
2775 M != MEnd; ++M) {
Douglas Gregor1b605f72009-11-19 01:08:35 +00002776 if ((*M)->isInstanceMethod() == WantInstanceMethods) {
2777 // Check whether the selector identifiers we've been given are a
2778 // subset of the identifiers for this particular method.
Douglas Gregorc8537c52009-11-19 07:41:15 +00002779 if (!isAcceptableObjCMethod(*M, WantKind, SelIdents, NumSelIdents))
Douglas Gregor1b605f72009-11-19 01:08:35 +00002780 continue;
Douglas Gregorc8537c52009-11-19 07:41:15 +00002781
Douglas Gregor1b605f72009-11-19 01:08:35 +00002782 Result R = Result(*M, 0);
2783 R.StartParameter = NumSelIdents;
Douglas Gregorc8537c52009-11-19 07:41:15 +00002784 R.AllParametersAreInformative = (WantKind != MK_Any);
Douglas Gregor1b605f72009-11-19 01:08:35 +00002785 Results.MaybeAddResult(R, CurContext);
2786 }
Douglas Gregorbab2b3c2009-11-17 23:22:23 +00002787 }
2788
2789 ObjCInterfaceDecl *IFace = dyn_cast<ObjCInterfaceDecl>(Container);
2790 if (!IFace)
2791 return;
2792
2793 // Add methods in protocols.
2794 const ObjCList<ObjCProtocolDecl> &Protocols= IFace->getReferencedProtocols();
2795 for (ObjCList<ObjCProtocolDecl>::iterator I = Protocols.begin(),
2796 E = Protocols.end();
2797 I != E; ++I)
Douglas Gregorc8537c52009-11-19 07:41:15 +00002798 AddObjCMethods(*I, WantInstanceMethods, WantKind, SelIdents, NumSelIdents,
Douglas Gregor1b605f72009-11-19 01:08:35 +00002799 CurContext, Results);
Douglas Gregorbab2b3c2009-11-17 23:22:23 +00002800
2801 // Add methods in categories.
2802 for (ObjCCategoryDecl *CatDecl = IFace->getCategoryList(); CatDecl;
2803 CatDecl = CatDecl->getNextClassCategory()) {
Douglas Gregorc8537c52009-11-19 07:41:15 +00002804 AddObjCMethods(CatDecl, WantInstanceMethods, WantKind, SelIdents,
2805 NumSelIdents, CurContext, Results);
Douglas Gregorbab2b3c2009-11-17 23:22:23 +00002806
2807 // Add a categories protocol methods.
2808 const ObjCList<ObjCProtocolDecl> &Protocols
2809 = CatDecl->getReferencedProtocols();
2810 for (ObjCList<ObjCProtocolDecl>::iterator I = Protocols.begin(),
2811 E = Protocols.end();
2812 I != E; ++I)
Douglas Gregorc8537c52009-11-19 07:41:15 +00002813 AddObjCMethods(*I, WantInstanceMethods, WantKind, SelIdents,
2814 NumSelIdents, CurContext, Results);
Douglas Gregorbab2b3c2009-11-17 23:22:23 +00002815
2816 // Add methods in category implementations.
2817 if (ObjCCategoryImplDecl *Impl = CatDecl->getImplementation())
Douglas Gregorc8537c52009-11-19 07:41:15 +00002818 AddObjCMethods(Impl, WantInstanceMethods, WantKind, SelIdents,
2819 NumSelIdents, CurContext, Results);
Douglas Gregorbab2b3c2009-11-17 23:22:23 +00002820 }
2821
2822 // Add methods in superclass.
2823 if (IFace->getSuperClass())
Douglas Gregorc8537c52009-11-19 07:41:15 +00002824 AddObjCMethods(IFace->getSuperClass(), WantInstanceMethods, WantKind,
2825 SelIdents, NumSelIdents, CurContext, Results);
Douglas Gregorbab2b3c2009-11-17 23:22:23 +00002826
2827 // Add methods in our implementation, if any.
2828 if (ObjCImplementationDecl *Impl = IFace->getImplementation())
Douglas Gregorc8537c52009-11-19 07:41:15 +00002829 AddObjCMethods(Impl, WantInstanceMethods, WantKind, SelIdents,
2830 NumSelIdents, CurContext, Results);
2831}
2832
2833
2834void Sema::CodeCompleteObjCPropertyGetter(Scope *S, DeclPtrTy ClassDecl,
2835 DeclPtrTy *Methods,
2836 unsigned NumMethods) {
2837 typedef CodeCompleteConsumer::Result Result;
2838
2839 // Try to find the interface where getters might live.
2840 ObjCInterfaceDecl *Class
2841 = dyn_cast_or_null<ObjCInterfaceDecl>(ClassDecl.getAs<Decl>());
2842 if (!Class) {
2843 if (ObjCCategoryDecl *Category
2844 = dyn_cast_or_null<ObjCCategoryDecl>(ClassDecl.getAs<Decl>()))
2845 Class = Category->getClassInterface();
2846
2847 if (!Class)
2848 return;
2849 }
2850
2851 // Find all of the potential getters.
2852 ResultBuilder Results(*this);
2853 Results.EnterNewScope();
2854
2855 // FIXME: We need to do this because Objective-C methods don't get
2856 // pushed into DeclContexts early enough. Argh!
2857 for (unsigned I = 0; I != NumMethods; ++I) {
2858 if (ObjCMethodDecl *Method
2859 = dyn_cast_or_null<ObjCMethodDecl>(Methods[I].getAs<Decl>()))
2860 if (Method->isInstanceMethod() &&
2861 isAcceptableObjCMethod(Method, MK_ZeroArgSelector, 0, 0)) {
2862 Result R = Result(Method, 0);
2863 R.AllParametersAreInformative = true;
2864 Results.MaybeAddResult(R, CurContext);
2865 }
2866 }
2867
2868 AddObjCMethods(Class, true, MK_ZeroArgSelector, 0, 0, CurContext, Results);
2869 Results.ExitScope();
2870 HandleCodeCompleteResults(this, CodeCompleter,Results.data(),Results.size());
2871}
2872
2873void Sema::CodeCompleteObjCPropertySetter(Scope *S, DeclPtrTy ObjCImplDecl,
2874 DeclPtrTy *Methods,
2875 unsigned NumMethods) {
2876 typedef CodeCompleteConsumer::Result Result;
2877
2878 // Try to find the interface where setters might live.
2879 ObjCInterfaceDecl *Class
2880 = dyn_cast_or_null<ObjCInterfaceDecl>(ObjCImplDecl.getAs<Decl>());
2881 if (!Class) {
2882 if (ObjCCategoryDecl *Category
2883 = dyn_cast_or_null<ObjCCategoryDecl>(ObjCImplDecl.getAs<Decl>()))
2884 Class = Category->getClassInterface();
2885
2886 if (!Class)
2887 return;
2888 }
2889
2890 // Find all of the potential getters.
2891 ResultBuilder Results(*this);
2892 Results.EnterNewScope();
2893
2894 // FIXME: We need to do this because Objective-C methods don't get
2895 // pushed into DeclContexts early enough. Argh!
2896 for (unsigned I = 0; I != NumMethods; ++I) {
2897 if (ObjCMethodDecl *Method
2898 = dyn_cast_or_null<ObjCMethodDecl>(Methods[I].getAs<Decl>()))
2899 if (Method->isInstanceMethod() &&
2900 isAcceptableObjCMethod(Method, MK_OneArgSelector, 0, 0)) {
2901 Result R = Result(Method, 0);
2902 R.AllParametersAreInformative = true;
2903 Results.MaybeAddResult(R, CurContext);
2904 }
2905 }
2906
2907 AddObjCMethods(Class, true, MK_OneArgSelector, 0, 0, CurContext, Results);
2908
2909 Results.ExitScope();
2910 HandleCodeCompleteResults(this, CodeCompleter,Results.data(),Results.size());
Douglas Gregorbab2b3c2009-11-17 23:22:23 +00002911}
2912
Douglas Gregor9d2ddb22010-04-06 19:22:33 +00002913/// \brief When we have an expression with type "id", we may assume
2914/// that it has some more-specific class type based on knowledge of
2915/// common uses of Objective-C. This routine returns that class type,
2916/// or NULL if no better result could be determined.
2917static ObjCInterfaceDecl *GetAssumedMessageSendExprType(Expr *E) {
2918 ObjCMessageExpr *Msg = dyn_cast<ObjCMessageExpr>(E);
2919 if (!Msg)
2920 return 0;
2921
2922 Selector Sel = Msg->getSelector();
2923 if (Sel.isNull())
2924 return 0;
2925
2926 IdentifierInfo *Id = Sel.getIdentifierInfoForSlot(0);
2927 if (!Id)
2928 return 0;
2929
2930 ObjCMethodDecl *Method = Msg->getMethodDecl();
2931 if (!Method)
2932 return 0;
2933
2934 // Determine the class that we're sending the message to.
2935 ObjCInterfaceDecl *IFace = Msg->getClassInfo().Decl;
2936 if (!IFace) {
2937 if (Expr *Receiver = Msg->getReceiver()) {
2938 QualType T = Receiver->getType();
2939 if (const ObjCObjectPointerType *Ptr = T->getAs<ObjCObjectPointerType>())
2940 IFace = Ptr->getInterfaceDecl();
2941 }
2942 }
2943
2944 if (!IFace)
2945 return 0;
2946
2947 ObjCInterfaceDecl *Super = IFace->getSuperClass();
2948 if (Method->isInstanceMethod())
2949 return llvm::StringSwitch<ObjCInterfaceDecl *>(Id->getName())
2950 .Case("retain", IFace)
2951 .Case("autorelease", IFace)
2952 .Case("copy", IFace)
2953 .Case("copyWithZone", IFace)
2954 .Case("mutableCopy", IFace)
2955 .Case("mutableCopyWithZone", IFace)
2956 .Case("awakeFromCoder", IFace)
2957 .Case("replacementObjectFromCoder", IFace)
2958 .Case("class", IFace)
2959 .Case("classForCoder", IFace)
2960 .Case("superclass", Super)
2961 .Default(0);
2962
2963 return llvm::StringSwitch<ObjCInterfaceDecl *>(Id->getName())
2964 .Case("new", IFace)
2965 .Case("alloc", IFace)
2966 .Case("allocWithZone", IFace)
2967 .Case("class", IFace)
2968 .Case("superclass", Super)
2969 .Default(0);
2970}
2971
Douglas Gregor090dd182009-11-17 23:31:36 +00002972void Sema::CodeCompleteObjCClassMessage(Scope *S, IdentifierInfo *FName,
Douglas Gregor1b605f72009-11-19 01:08:35 +00002973 SourceLocation FNameLoc,
2974 IdentifierInfo **SelIdents,
2975 unsigned NumSelIdents) {
Steve Naroffeae65032009-11-07 02:08:14 +00002976 typedef CodeCompleteConsumer::Result Result;
Douglas Gregor8ce33212009-11-17 17:59:40 +00002977 ObjCInterfaceDecl *CDecl = 0;
2978
Douglas Gregor8ce33212009-11-17 17:59:40 +00002979 if (FName->isStr("super")) {
2980 // We're sending a message to "super".
2981 if (ObjCMethodDecl *CurMethod = getCurMethodDecl()) {
2982 // Figure out which interface we're in.
2983 CDecl = CurMethod->getClassInterface();
2984 if (!CDecl)
2985 return;
2986
2987 // Find the superclass of this class.
2988 CDecl = CDecl->getSuperClass();
2989 if (!CDecl)
2990 return;
2991
2992 if (CurMethod->isInstanceMethod()) {
2993 // We are inside an instance method, which means that the message
2994 // send [super ...] is actually calling an instance method on the
2995 // current object. Build the super expression and handle this like
2996 // an instance method.
2997 QualType SuperTy = Context.getObjCInterfaceType(CDecl);
2998 SuperTy = Context.getObjCObjectPointerType(SuperTy);
2999 OwningExprResult Super
Douglas Gregor090dd182009-11-17 23:31:36 +00003000 = Owned(new (Context) ObjCSuperExpr(FNameLoc, SuperTy));
Douglas Gregor1b605f72009-11-19 01:08:35 +00003001 return CodeCompleteObjCInstanceMessage(S, (Expr *)Super.get(),
3002 SelIdents, NumSelIdents);
Douglas Gregor8ce33212009-11-17 17:59:40 +00003003 }
3004
3005 // Okay, we're calling a factory method in our superclass.
3006 }
3007 }
3008
3009 // If the given name refers to an interface type, retrieve the
3010 // corresponding declaration.
3011 if (!CDecl)
Douglas Gregor090dd182009-11-17 23:31:36 +00003012 if (TypeTy *Ty = getTypeName(*FName, FNameLoc, S, 0, false)) {
Douglas Gregor8ce33212009-11-17 17:59:40 +00003013 QualType T = GetTypeFromParser(Ty, 0);
3014 if (!T.isNull())
3015 if (const ObjCInterfaceType *Interface = T->getAs<ObjCInterfaceType>())
3016 CDecl = Interface->getDecl();
3017 }
3018
3019 if (!CDecl && FName->isStr("super")) {
3020 // "super" may be the name of a variable, in which case we are
3021 // probably calling an instance method.
John McCalle66edc12009-11-24 19:00:30 +00003022 CXXScopeSpec SS;
3023 UnqualifiedId id;
3024 id.setIdentifier(FName, FNameLoc);
3025 OwningExprResult Super = ActOnIdExpression(S, SS, id, false, false);
Douglas Gregor1b605f72009-11-19 01:08:35 +00003026 return CodeCompleteObjCInstanceMessage(S, (Expr *)Super.get(),
3027 SelIdents, NumSelIdents);
Douglas Gregor8ce33212009-11-17 17:59:40 +00003028 }
3029
Douglas Gregorbab2b3c2009-11-17 23:22:23 +00003030 // Add all of the factory methods in this Objective-C class, its protocols,
3031 // superclasses, categories, implementation, etc.
Steve Naroffeae65032009-11-07 02:08:14 +00003032 ResultBuilder Results(*this);
3033 Results.EnterNewScope();
Douglas Gregor6285f752010-04-06 16:40:00 +00003034
3035 if (CDecl)
3036 AddObjCMethods(CDecl, false, MK_Any, SelIdents, NumSelIdents, CurContext,
3037 Results);
3038 else if (FName->isStr("id")) {
3039 // We're messaging "id" as a type; provide all class/factory methods.
3040
Douglas Gregord720daf2010-04-06 17:30:22 +00003041 // If we have an external source, load the entire class method
3042 // pool from the PCH file.
3043 if (ExternalSource) {
3044 for (uint32_t I = 0, N = ExternalSource->GetNumKnownSelectors(); I != N;
3045 ++I) {
3046 Selector Sel = ExternalSource->GetSelector(I);
3047 if (Sel.isNull() || FactoryMethodPool.count(Sel) ||
3048 InstanceMethodPool.count(Sel))
3049 continue;
3050
3051 ReadMethodPool(Sel, /*isInstance=*/false);
3052 }
3053 }
3054
Douglas Gregor6285f752010-04-06 16:40:00 +00003055 for (llvm::DenseMap<Selector, ObjCMethodList>::iterator
3056 M = FactoryMethodPool.begin(),
3057 MEnd = FactoryMethodPool.end();
3058 M != MEnd;
3059 ++M) {
Douglas Gregord720daf2010-04-06 17:30:22 +00003060 for (ObjCMethodList *MethList = &M->second; MethList && MethList->Method;
Douglas Gregor6285f752010-04-06 16:40:00 +00003061 MethList = MethList->Next) {
3062 if (!isAcceptableObjCMethod(MethList->Method, MK_Any, SelIdents,
3063 NumSelIdents))
3064 continue;
3065
3066 Result R(MethList->Method, 0);
3067 R.StartParameter = NumSelIdents;
3068 R.AllParametersAreInformative = false;
3069 Results.MaybeAddResult(R, CurContext);
3070 }
3071 }
3072 }
3073
Steve Naroffeae65032009-11-07 02:08:14 +00003074 Results.ExitScope();
Douglas Gregorbab2b3c2009-11-17 23:22:23 +00003075
Steve Naroffeae65032009-11-07 02:08:14 +00003076 // This also suppresses remaining diagnostics.
Daniel Dunbar242ea9a2009-11-13 08:58:20 +00003077 HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
Steve Naroffeae65032009-11-07 02:08:14 +00003078}
3079
Douglas Gregor1b605f72009-11-19 01:08:35 +00003080void Sema::CodeCompleteObjCInstanceMessage(Scope *S, ExprTy *Receiver,
3081 IdentifierInfo **SelIdents,
3082 unsigned NumSelIdents) {
Steve Naroffeae65032009-11-07 02:08:14 +00003083 typedef CodeCompleteConsumer::Result Result;
Steve Naroffeae65032009-11-07 02:08:14 +00003084
3085 Expr *RecExpr = static_cast<Expr *>(Receiver);
Steve Naroffeae65032009-11-07 02:08:14 +00003086
Douglas Gregorbab2b3c2009-11-17 23:22:23 +00003087 // If necessary, apply function/array conversion to the receiver.
3088 // C99 6.7.5.3p[7,8].
Douglas Gregorb92a1562010-02-03 00:27:59 +00003089 DefaultFunctionArrayLvalueConversion(RecExpr);
Douglas Gregorbab2b3c2009-11-17 23:22:23 +00003090 QualType ReceiverType = RecExpr->getType();
Steve Naroffeae65032009-11-07 02:08:14 +00003091
Douglas Gregorbab2b3c2009-11-17 23:22:23 +00003092 // Build the set of methods we can see.
3093 ResultBuilder Results(*this);
3094 Results.EnterNewScope();
Douglas Gregor9d2ddb22010-04-06 19:22:33 +00003095
3096 // If we're messaging an expression with type "id" or "Class", check
3097 // whether we know something special about the receiver that allows
3098 // us to assume a more-specific receiver type.
3099 if (ReceiverType->isObjCIdType() || ReceiverType->isObjCClassType())
3100 if (ObjCInterfaceDecl *IFace = GetAssumedMessageSendExprType(RecExpr))
3101 ReceiverType = Context.getObjCObjectPointerType(
3102 Context.getObjCInterfaceType(IFace));
Douglas Gregorbab2b3c2009-11-17 23:22:23 +00003103
Douglas Gregora3329fa2009-11-18 00:06:18 +00003104 // Handle messages to Class. This really isn't a message to an instance
3105 // method, so we treat it the same way we would treat a message send to a
3106 // class method.
3107 if (ReceiverType->isObjCClassType() ||
3108 ReceiverType->isObjCQualifiedClassType()) {
3109 if (ObjCMethodDecl *CurMethod = getCurMethodDecl()) {
3110 if (ObjCInterfaceDecl *ClassDecl = CurMethod->getClassInterface())
Douglas Gregorc8537c52009-11-19 07:41:15 +00003111 AddObjCMethods(ClassDecl, false, MK_Any, SelIdents, NumSelIdents,
3112 CurContext, Results);
Douglas Gregora3329fa2009-11-18 00:06:18 +00003113 }
3114 }
3115 // Handle messages to a qualified ID ("id<foo>").
3116 else if (const ObjCObjectPointerType *QualID
3117 = ReceiverType->getAsObjCQualifiedIdType()) {
3118 // Search protocols for instance methods.
3119 for (ObjCObjectPointerType::qual_iterator I = QualID->qual_begin(),
3120 E = QualID->qual_end();
3121 I != E; ++I)
Douglas Gregorc8537c52009-11-19 07:41:15 +00003122 AddObjCMethods(*I, true, MK_Any, SelIdents, NumSelIdents, CurContext,
3123 Results);
Douglas Gregora3329fa2009-11-18 00:06:18 +00003124 }
3125 // Handle messages to a pointer to interface type.
3126 else if (const ObjCObjectPointerType *IFacePtr
3127 = ReceiverType->getAsObjCInterfacePointerType()) {
3128 // Search the class, its superclasses, etc., for instance methods.
Douglas Gregorc8537c52009-11-19 07:41:15 +00003129 AddObjCMethods(IFacePtr->getInterfaceDecl(), true, MK_Any, SelIdents,
3130 NumSelIdents, CurContext, Results);
Douglas Gregora3329fa2009-11-18 00:06:18 +00003131
3132 // Search protocols for instance methods.
3133 for (ObjCObjectPointerType::qual_iterator I = IFacePtr->qual_begin(),
3134 E = IFacePtr->qual_end();
3135 I != E; ++I)
Douglas Gregorc8537c52009-11-19 07:41:15 +00003136 AddObjCMethods(*I, true, MK_Any, SelIdents, NumSelIdents, CurContext,
3137 Results);
Douglas Gregora3329fa2009-11-18 00:06:18 +00003138 }
Douglas Gregor6285f752010-04-06 16:40:00 +00003139 // Handle messages to "id".
3140 else if (ReceiverType->isObjCIdType()) {
Douglas Gregord720daf2010-04-06 17:30:22 +00003141 // We're messaging "id", so provide all instance methods we know
3142 // about as code-completion results.
3143
3144 // If we have an external source, load the entire class method
3145 // pool from the PCH file.
3146 if (ExternalSource) {
3147 for (uint32_t I = 0, N = ExternalSource->GetNumKnownSelectors(); I != N;
3148 ++I) {
3149 Selector Sel = ExternalSource->GetSelector(I);
3150 if (Sel.isNull() || InstanceMethodPool.count(Sel) ||
3151 FactoryMethodPool.count(Sel))
3152 continue;
3153
3154 ReadMethodPool(Sel, /*isInstance=*/true);
3155 }
3156 }
3157
Douglas Gregor6285f752010-04-06 16:40:00 +00003158 for (llvm::DenseMap<Selector, ObjCMethodList>::iterator
3159 M = InstanceMethodPool.begin(),
3160 MEnd = InstanceMethodPool.end();
3161 M != MEnd;
3162 ++M) {
Douglas Gregord720daf2010-04-06 17:30:22 +00003163 for (ObjCMethodList *MethList = &M->second; MethList && MethList->Method;
Douglas Gregor6285f752010-04-06 16:40:00 +00003164 MethList = MethList->Next) {
3165 if (!isAcceptableObjCMethod(MethList->Method, MK_Any, SelIdents,
3166 NumSelIdents))
3167 continue;
3168
3169 Result R(MethList->Method, 0);
3170 R.StartParameter = NumSelIdents;
3171 R.AllParametersAreInformative = false;
3172 Results.MaybeAddResult(R, CurContext);
3173 }
3174 }
3175 }
3176
Steve Naroffeae65032009-11-07 02:08:14 +00003177 Results.ExitScope();
Daniel Dunbar242ea9a2009-11-13 08:58:20 +00003178 HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
Steve Naroffeae65032009-11-07 02:08:14 +00003179}
Douglas Gregorbaf69612009-11-18 04:19:12 +00003180
3181/// \brief Add all of the protocol declarations that we find in the given
3182/// (translation unit) context.
3183static void AddProtocolResults(DeclContext *Ctx, DeclContext *CurContext,
Douglas Gregor5b4671c2009-11-18 04:49:41 +00003184 bool OnlyForwardDeclarations,
Douglas Gregorbaf69612009-11-18 04:19:12 +00003185 ResultBuilder &Results) {
3186 typedef CodeCompleteConsumer::Result Result;
3187
3188 for (DeclContext::decl_iterator D = Ctx->decls_begin(),
3189 DEnd = Ctx->decls_end();
3190 D != DEnd; ++D) {
3191 // Record any protocols we find.
3192 if (ObjCProtocolDecl *Proto = dyn_cast<ObjCProtocolDecl>(*D))
Douglas Gregor5b4671c2009-11-18 04:49:41 +00003193 if (!OnlyForwardDeclarations || Proto->isForwardDecl())
Douglas Gregorfc59ce12010-01-14 16:14:35 +00003194 Results.AddResult(Result(Proto, 0), CurContext, 0, false);
Douglas Gregorbaf69612009-11-18 04:19:12 +00003195
3196 // Record any forward-declared protocols we find.
3197 if (ObjCForwardProtocolDecl *Forward
3198 = dyn_cast<ObjCForwardProtocolDecl>(*D)) {
3199 for (ObjCForwardProtocolDecl::protocol_iterator
3200 P = Forward->protocol_begin(),
3201 PEnd = Forward->protocol_end();
3202 P != PEnd; ++P)
Douglas Gregor5b4671c2009-11-18 04:49:41 +00003203 if (!OnlyForwardDeclarations || (*P)->isForwardDecl())
Douglas Gregorfc59ce12010-01-14 16:14:35 +00003204 Results.AddResult(Result(*P, 0), CurContext, 0, false);
Douglas Gregorbaf69612009-11-18 04:19:12 +00003205 }
3206 }
3207}
3208
3209void Sema::CodeCompleteObjCProtocolReferences(IdentifierLocPair *Protocols,
3210 unsigned NumProtocols) {
3211 ResultBuilder Results(*this);
3212 Results.EnterNewScope();
3213
3214 // Tell the result set to ignore all of the protocols we have
3215 // already seen.
3216 for (unsigned I = 0; I != NumProtocols; ++I)
3217 if (ObjCProtocolDecl *Protocol = LookupProtocol(Protocols[I].first))
3218 Results.Ignore(Protocol);
3219
3220 // Add all protocols.
Douglas Gregor5b4671c2009-11-18 04:49:41 +00003221 AddProtocolResults(Context.getTranslationUnitDecl(), CurContext, false,
3222 Results);
3223
3224 Results.ExitScope();
3225 HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
3226}
3227
3228void Sema::CodeCompleteObjCProtocolDecl(Scope *) {
3229 ResultBuilder Results(*this);
3230 Results.EnterNewScope();
3231
3232 // Add all protocols.
3233 AddProtocolResults(Context.getTranslationUnitDecl(), CurContext, true,
3234 Results);
Douglas Gregorbaf69612009-11-18 04:19:12 +00003235
3236 Results.ExitScope();
3237 HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
3238}
Douglas Gregor49c22a72009-11-18 16:26:39 +00003239
3240/// \brief Add all of the Objective-C interface declarations that we find in
3241/// the given (translation unit) context.
3242static void AddInterfaceResults(DeclContext *Ctx, DeclContext *CurContext,
3243 bool OnlyForwardDeclarations,
3244 bool OnlyUnimplemented,
3245 ResultBuilder &Results) {
3246 typedef CodeCompleteConsumer::Result Result;
3247
3248 for (DeclContext::decl_iterator D = Ctx->decls_begin(),
3249 DEnd = Ctx->decls_end();
3250 D != DEnd; ++D) {
3251 // Record any interfaces we find.
3252 if (ObjCInterfaceDecl *Class = dyn_cast<ObjCInterfaceDecl>(*D))
3253 if ((!OnlyForwardDeclarations || Class->isForwardDecl()) &&
3254 (!OnlyUnimplemented || !Class->getImplementation()))
Douglas Gregorfc59ce12010-01-14 16:14:35 +00003255 Results.AddResult(Result(Class, 0), CurContext, 0, false);
Douglas Gregor49c22a72009-11-18 16:26:39 +00003256
3257 // Record any forward-declared interfaces we find.
3258 if (ObjCClassDecl *Forward = dyn_cast<ObjCClassDecl>(*D)) {
3259 for (ObjCClassDecl::iterator C = Forward->begin(), CEnd = Forward->end();
3260 C != CEnd; ++C)
3261 if ((!OnlyForwardDeclarations || C->getInterface()->isForwardDecl()) &&
3262 (!OnlyUnimplemented || !C->getInterface()->getImplementation()))
Douglas Gregorfc59ce12010-01-14 16:14:35 +00003263 Results.AddResult(Result(C->getInterface(), 0), CurContext,
3264 0, false);
Douglas Gregor49c22a72009-11-18 16:26:39 +00003265 }
3266 }
3267}
3268
3269void Sema::CodeCompleteObjCInterfaceDecl(Scope *S) {
3270 ResultBuilder Results(*this);
3271 Results.EnterNewScope();
3272
3273 // Add all classes.
3274 AddInterfaceResults(Context.getTranslationUnitDecl(), CurContext, true,
3275 false, Results);
3276
3277 Results.ExitScope();
3278 HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
3279}
3280
3281void Sema::CodeCompleteObjCSuperclass(Scope *S, IdentifierInfo *ClassName) {
3282 ResultBuilder Results(*this);
3283 Results.EnterNewScope();
3284
3285 // Make sure that we ignore the class we're currently defining.
3286 NamedDecl *CurClass
3287 = LookupSingleName(TUScope, ClassName, LookupOrdinaryName);
Douglas Gregor5d34fd32009-11-18 19:08:43 +00003288 if (CurClass && isa<ObjCInterfaceDecl>(CurClass))
Douglas Gregor49c22a72009-11-18 16:26:39 +00003289 Results.Ignore(CurClass);
3290
3291 // Add all classes.
3292 AddInterfaceResults(Context.getTranslationUnitDecl(), CurContext, false,
3293 false, Results);
3294
3295 Results.ExitScope();
3296 HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
3297}
3298
3299void Sema::CodeCompleteObjCImplementationDecl(Scope *S) {
3300 ResultBuilder Results(*this);
3301 Results.EnterNewScope();
3302
3303 // Add all unimplemented classes.
3304 AddInterfaceResults(Context.getTranslationUnitDecl(), CurContext, false,
3305 true, Results);
3306
3307 Results.ExitScope();
3308 HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
3309}
Douglas Gregor5d34fd32009-11-18 19:08:43 +00003310
3311void Sema::CodeCompleteObjCInterfaceCategory(Scope *S,
3312 IdentifierInfo *ClassName) {
3313 typedef CodeCompleteConsumer::Result Result;
3314
3315 ResultBuilder Results(*this);
3316
3317 // Ignore any categories we find that have already been implemented by this
3318 // interface.
3319 llvm::SmallPtrSet<IdentifierInfo *, 16> CategoryNames;
3320 NamedDecl *CurClass
3321 = LookupSingleName(TUScope, ClassName, LookupOrdinaryName);
3322 if (ObjCInterfaceDecl *Class = dyn_cast_or_null<ObjCInterfaceDecl>(CurClass))
3323 for (ObjCCategoryDecl *Category = Class->getCategoryList(); Category;
3324 Category = Category->getNextClassCategory())
3325 CategoryNames.insert(Category->getIdentifier());
3326
3327 // Add all of the categories we know about.
3328 Results.EnterNewScope();
3329 TranslationUnitDecl *TU = Context.getTranslationUnitDecl();
3330 for (DeclContext::decl_iterator D = TU->decls_begin(),
3331 DEnd = TU->decls_end();
3332 D != DEnd; ++D)
3333 if (ObjCCategoryDecl *Category = dyn_cast<ObjCCategoryDecl>(*D))
3334 if (CategoryNames.insert(Category->getIdentifier()))
Douglas Gregorfc59ce12010-01-14 16:14:35 +00003335 Results.AddResult(Result(Category, 0), CurContext, 0, false);
Douglas Gregor5d34fd32009-11-18 19:08:43 +00003336 Results.ExitScope();
3337
3338 HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
3339}
3340
3341void Sema::CodeCompleteObjCImplementationCategory(Scope *S,
3342 IdentifierInfo *ClassName) {
3343 typedef CodeCompleteConsumer::Result Result;
3344
3345 // Find the corresponding interface. If we couldn't find the interface, the
3346 // program itself is ill-formed. However, we'll try to be helpful still by
3347 // providing the list of all of the categories we know about.
3348 NamedDecl *CurClass
3349 = LookupSingleName(TUScope, ClassName, LookupOrdinaryName);
3350 ObjCInterfaceDecl *Class = dyn_cast_or_null<ObjCInterfaceDecl>(CurClass);
3351 if (!Class)
3352 return CodeCompleteObjCInterfaceCategory(S, ClassName);
3353
3354 ResultBuilder Results(*this);
3355
3356 // Add all of the categories that have have corresponding interface
3357 // declarations in this class and any of its superclasses, except for
3358 // already-implemented categories in the class itself.
3359 llvm::SmallPtrSet<IdentifierInfo *, 16> CategoryNames;
3360 Results.EnterNewScope();
3361 bool IgnoreImplemented = true;
3362 while (Class) {
3363 for (ObjCCategoryDecl *Category = Class->getCategoryList(); Category;
3364 Category = Category->getNextClassCategory())
3365 if ((!IgnoreImplemented || !Category->getImplementation()) &&
3366 CategoryNames.insert(Category->getIdentifier()))
Douglas Gregorfc59ce12010-01-14 16:14:35 +00003367 Results.AddResult(Result(Category, 0), CurContext, 0, false);
Douglas Gregor5d34fd32009-11-18 19:08:43 +00003368
3369 Class = Class->getSuperClass();
3370 IgnoreImplemented = false;
3371 }
3372 Results.ExitScope();
3373
3374 HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
3375}
Douglas Gregor5d649882009-11-18 22:32:06 +00003376
Douglas Gregor52e78bd2009-11-18 22:56:13 +00003377void Sema::CodeCompleteObjCPropertyDefinition(Scope *S, DeclPtrTy ObjCImpDecl) {
Douglas Gregor5d649882009-11-18 22:32:06 +00003378 typedef CodeCompleteConsumer::Result Result;
3379 ResultBuilder Results(*this);
3380
3381 // Figure out where this @synthesize lives.
3382 ObjCContainerDecl *Container
3383 = dyn_cast_or_null<ObjCContainerDecl>(ObjCImpDecl.getAs<Decl>());
3384 if (!Container ||
3385 (!isa<ObjCImplementationDecl>(Container) &&
3386 !isa<ObjCCategoryImplDecl>(Container)))
3387 return;
3388
3389 // Ignore any properties that have already been implemented.
3390 for (DeclContext::decl_iterator D = Container->decls_begin(),
3391 DEnd = Container->decls_end();
3392 D != DEnd; ++D)
3393 if (ObjCPropertyImplDecl *PropertyImpl = dyn_cast<ObjCPropertyImplDecl>(*D))
3394 Results.Ignore(PropertyImpl->getPropertyDecl());
3395
3396 // Add any properties that we find.
3397 Results.EnterNewScope();
3398 if (ObjCImplementationDecl *ClassImpl
3399 = dyn_cast<ObjCImplementationDecl>(Container))
3400 AddObjCProperties(ClassImpl->getClassInterface(), false, CurContext,
3401 Results);
3402 else
3403 AddObjCProperties(cast<ObjCCategoryImplDecl>(Container)->getCategoryDecl(),
3404 false, CurContext, Results);
3405 Results.ExitScope();
3406
3407 HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
3408}
3409
3410void Sema::CodeCompleteObjCPropertySynthesizeIvar(Scope *S,
3411 IdentifierInfo *PropertyName,
3412 DeclPtrTy ObjCImpDecl) {
3413 typedef CodeCompleteConsumer::Result Result;
3414 ResultBuilder Results(*this);
3415
3416 // Figure out where this @synthesize lives.
3417 ObjCContainerDecl *Container
3418 = dyn_cast_or_null<ObjCContainerDecl>(ObjCImpDecl.getAs<Decl>());
3419 if (!Container ||
3420 (!isa<ObjCImplementationDecl>(Container) &&
3421 !isa<ObjCCategoryImplDecl>(Container)))
3422 return;
3423
3424 // Figure out which interface we're looking into.
3425 ObjCInterfaceDecl *Class = 0;
3426 if (ObjCImplementationDecl *ClassImpl
3427 = dyn_cast<ObjCImplementationDecl>(Container))
3428 Class = ClassImpl->getClassInterface();
3429 else
3430 Class = cast<ObjCCategoryImplDecl>(Container)->getCategoryDecl()
3431 ->getClassInterface();
3432
3433 // Add all of the instance variables in this class and its superclasses.
3434 Results.EnterNewScope();
3435 for(; Class; Class = Class->getSuperClass()) {
3436 // FIXME: We could screen the type of each ivar for compatibility with
3437 // the property, but is that being too paternal?
3438 for (ObjCInterfaceDecl::ivar_iterator IVar = Class->ivar_begin(),
3439 IVarEnd = Class->ivar_end();
3440 IVar != IVarEnd; ++IVar)
Douglas Gregorfc59ce12010-01-14 16:14:35 +00003441 Results.AddResult(Result(*IVar, 0), CurContext, 0, false);
Douglas Gregor5d649882009-11-18 22:32:06 +00003442 }
3443 Results.ExitScope();
3444
3445 HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
3446}