blob: 42a92b72d985120cf24647c50ffffc02f584b1f4 [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
Douglas Gregorf64acca2010-05-25 21:41:55 +0000130 /// \brief Whether we should include code patterns in the completion
131 /// results.
132 bool includeCodePatterns() const {
133 return SemaRef.CodeCompleter &&
134 SemaRef.CodeCompleter->includeCodePatterns();
135 }
136
Douglas Gregor3545ff42009-09-21 16:56:56 +0000137 /// \brief Set the filter used for code-completion results.
138 void setFilter(LookupFilter Filter) {
139 this->Filter = Filter;
140 }
141
142 typedef std::vector<Result>::iterator iterator;
143 iterator begin() { return Results.begin(); }
144 iterator end() { return Results.end(); }
145
146 Result *data() { return Results.empty()? 0 : &Results.front(); }
147 unsigned size() const { return Results.size(); }
148 bool empty() const { return Results.empty(); }
149
Douglas Gregor6ae4c522010-01-14 03:21:49 +0000150 /// \brief Specify whether nested-name-specifiers are allowed.
151 void allowNestedNameSpecifiers(bool Allow = true) {
152 AllowNestedNameSpecifiers = Allow;
153 }
154
Douglas Gregor7c208612010-01-14 00:20:49 +0000155 /// \brief Determine whether the given declaration is at all interesting
156 /// as a code-completion result.
Douglas Gregor6ae4c522010-01-14 03:21:49 +0000157 ///
158 /// \param ND the declaration that we are inspecting.
159 ///
160 /// \param AsNestedNameSpecifier will be set true if this declaration is
161 /// only interesting when it is a nested-name-specifier.
162 bool isInterestingDecl(NamedDecl *ND, bool &AsNestedNameSpecifier) const;
Douglas Gregore0717ab2010-01-14 00:41:07 +0000163
164 /// \brief Check whether the result is hidden by the Hiding declaration.
165 ///
166 /// \returns true if the result is hidden and cannot be found, false if
167 /// the hidden result could still be found. When false, \p R may be
168 /// modified to describe how the result can be found (e.g., via extra
169 /// qualification).
170 bool CheckHiddenResult(Result &R, DeclContext *CurContext,
171 NamedDecl *Hiding);
172
Douglas Gregor3545ff42009-09-21 16:56:56 +0000173 /// \brief Add a new result to this result set (if it isn't already in one
174 /// of the shadow maps), or replace an existing result (for, e.g., a
175 /// redeclaration).
Douglas Gregor2af2f672009-09-21 20:12:40 +0000176 ///
Douglas Gregorc580c522010-01-14 01:09:38 +0000177 /// \param CurContext the result to add (if it is unique).
Douglas Gregor2af2f672009-09-21 20:12:40 +0000178 ///
179 /// \param R the context in which this result will be named.
180 void MaybeAddResult(Result R, DeclContext *CurContext = 0);
Douglas Gregor3545ff42009-09-21 16:56:56 +0000181
Douglas Gregorc580c522010-01-14 01:09:38 +0000182 /// \brief Add a new result to this result set, where we already know
183 /// the hiding declation (if any).
184 ///
185 /// \param R the result to add (if it is unique).
186 ///
187 /// \param CurContext the context in which this result will be named.
188 ///
189 /// \param Hiding the declaration that hides the result.
Douglas Gregor09bbc652010-01-14 15:47:35 +0000190 ///
191 /// \param InBaseClass whether the result was found in a base
192 /// class of the searched context.
193 void AddResult(Result R, DeclContext *CurContext, NamedDecl *Hiding,
194 bool InBaseClass);
Douglas Gregorc580c522010-01-14 01:09:38 +0000195
Douglas Gregor78a21012010-01-14 16:01:26 +0000196 /// \brief Add a new non-declaration result to this result set.
197 void AddResult(Result R);
198
Douglas Gregor3545ff42009-09-21 16:56:56 +0000199 /// \brief Enter into a new scope.
200 void EnterNewScope();
201
202 /// \brief Exit from the current scope.
203 void ExitScope();
204
Douglas Gregorbaf69612009-11-18 04:19:12 +0000205 /// \brief Ignore this declaration, if it is seen again.
206 void Ignore(Decl *D) { AllDeclsFound.insert(D->getCanonicalDecl()); }
207
Douglas Gregor3545ff42009-09-21 16:56:56 +0000208 /// \name Name lookup predicates
209 ///
210 /// These predicates can be passed to the name lookup functions to filter the
211 /// results of name lookup. All of the predicates have the same type, so that
212 ///
213 //@{
Douglas Gregor9d64c5e2009-09-21 20:51:25 +0000214 bool IsOrdinaryName(NamedDecl *ND) const;
Douglas Gregor504a6ae2010-01-10 23:08:15 +0000215 bool IsOrdinaryNonValueName(NamedDecl *ND) const;
Douglas Gregor3545ff42009-09-21 16:56:56 +0000216 bool IsNestedNameSpecifier(NamedDecl *ND) const;
217 bool IsEnum(NamedDecl *ND) const;
218 bool IsClassOrStruct(NamedDecl *ND) const;
219 bool IsUnion(NamedDecl *ND) const;
220 bool IsNamespace(NamedDecl *ND) const;
221 bool IsNamespaceOrAlias(NamedDecl *ND) const;
222 bool IsType(NamedDecl *ND) const;
Douglas Gregore412a5a2009-09-23 22:26:46 +0000223 bool IsMember(NamedDecl *ND) const;
Douglas Gregor2b8162b2010-01-14 16:08:12 +0000224 bool IsObjCIvar(NamedDecl *ND) const;
Douglas Gregora817a192010-05-27 23:06:34 +0000225 bool IsObjCMessageReceiver(NamedDecl *ND) const;
Douglas Gregor3545ff42009-09-21 16:56:56 +0000226 //@}
227 };
228}
229
Douglas Gregor05e7ca32009-12-06 20:23:50 +0000230class ResultBuilder::ShadowMapEntry::iterator {
231 llvm::PointerUnion<NamedDecl*, const DeclIndexPair*> DeclOrIterator;
232 unsigned SingleDeclIndex;
233
234public:
235 typedef DeclIndexPair value_type;
236 typedef value_type reference;
237 typedef std::ptrdiff_t difference_type;
238 typedef std::input_iterator_tag iterator_category;
239
240 class pointer {
241 DeclIndexPair Value;
242
243 public:
244 pointer(const DeclIndexPair &Value) : Value(Value) { }
245
246 const DeclIndexPair *operator->() const {
247 return &Value;
248 }
249 };
250
251 iterator() : DeclOrIterator((NamedDecl *)0), SingleDeclIndex(0) { }
252
253 iterator(NamedDecl *SingleDecl, unsigned Index)
254 : DeclOrIterator(SingleDecl), SingleDeclIndex(Index) { }
255
256 iterator(const DeclIndexPair *Iterator)
257 : DeclOrIterator(Iterator), SingleDeclIndex(0) { }
258
259 iterator &operator++() {
260 if (DeclOrIterator.is<NamedDecl *>()) {
261 DeclOrIterator = (NamedDecl *)0;
262 SingleDeclIndex = 0;
263 return *this;
264 }
265
266 const DeclIndexPair *I = DeclOrIterator.get<const DeclIndexPair*>();
267 ++I;
268 DeclOrIterator = I;
269 return *this;
270 }
271
272 iterator operator++(int) {
273 iterator tmp(*this);
274 ++(*this);
275 return tmp;
276 }
277
278 reference operator*() const {
279 if (NamedDecl *ND = DeclOrIterator.dyn_cast<NamedDecl *>())
280 return reference(ND, SingleDeclIndex);
281
Douglas Gregor94bb5e82009-12-06 21:27:58 +0000282 return *DeclOrIterator.get<const DeclIndexPair*>();
Douglas Gregor05e7ca32009-12-06 20:23:50 +0000283 }
284
285 pointer operator->() const {
286 return pointer(**this);
287 }
288
289 friend bool operator==(const iterator &X, const iterator &Y) {
Douglas Gregor94bb5e82009-12-06 21:27:58 +0000290 return X.DeclOrIterator.getOpaqueValue()
291 == Y.DeclOrIterator.getOpaqueValue() &&
Douglas Gregor05e7ca32009-12-06 20:23:50 +0000292 X.SingleDeclIndex == Y.SingleDeclIndex;
293 }
294
295 friend bool operator!=(const iterator &X, const iterator &Y) {
Douglas Gregor94bb5e82009-12-06 21:27:58 +0000296 return !(X == Y);
Douglas Gregor05e7ca32009-12-06 20:23:50 +0000297 }
298};
299
Douglas Gregor05e7ca32009-12-06 20:23:50 +0000300ResultBuilder::ShadowMapEntry::iterator
301ResultBuilder::ShadowMapEntry::begin() const {
302 if (DeclOrVector.isNull())
303 return iterator();
304
305 if (NamedDecl *ND = DeclOrVector.dyn_cast<NamedDecl *>())
306 return iterator(ND, SingleDeclIndex);
307
308 return iterator(DeclOrVector.get<DeclIndexPairVector *>()->begin());
309}
310
311ResultBuilder::ShadowMapEntry::iterator
312ResultBuilder::ShadowMapEntry::end() const {
313 if (DeclOrVector.is<NamedDecl *>() || DeclOrVector.isNull())
314 return iterator();
315
316 return iterator(DeclOrVector.get<DeclIndexPairVector *>()->end());
317}
318
Douglas Gregor2af2f672009-09-21 20:12:40 +0000319/// \brief Compute the qualification required to get from the current context
320/// (\p CurContext) to the target context (\p TargetContext).
321///
322/// \param Context the AST context in which the qualification will be used.
323///
324/// \param CurContext the context where an entity is being named, which is
325/// typically based on the current scope.
326///
327/// \param TargetContext the context in which the named entity actually
328/// resides.
329///
330/// \returns a nested name specifier that refers into the target context, or
331/// NULL if no qualification is needed.
332static NestedNameSpecifier *
333getRequiredQualification(ASTContext &Context,
334 DeclContext *CurContext,
335 DeclContext *TargetContext) {
336 llvm::SmallVector<DeclContext *, 4> TargetParents;
337
338 for (DeclContext *CommonAncestor = TargetContext;
339 CommonAncestor && !CommonAncestor->Encloses(CurContext);
340 CommonAncestor = CommonAncestor->getLookupParent()) {
341 if (CommonAncestor->isTransparentContext() ||
342 CommonAncestor->isFunctionOrMethod())
343 continue;
344
345 TargetParents.push_back(CommonAncestor);
346 }
347
348 NestedNameSpecifier *Result = 0;
349 while (!TargetParents.empty()) {
350 DeclContext *Parent = TargetParents.back();
351 TargetParents.pop_back();
352
353 if (NamespaceDecl *Namespace = dyn_cast<NamespaceDecl>(Parent))
354 Result = NestedNameSpecifier::Create(Context, Result, Namespace);
355 else if (TagDecl *TD = dyn_cast<TagDecl>(Parent))
356 Result = NestedNameSpecifier::Create(Context, Result,
357 false,
358 Context.getTypeDeclType(TD).getTypePtr());
359 else
360 assert(Parent->isTranslationUnit());
Douglas Gregor9eb77012009-11-07 00:00:49 +0000361 }
Douglas Gregor2af2f672009-09-21 20:12:40 +0000362 return Result;
363}
364
Douglas Gregor6ae4c522010-01-14 03:21:49 +0000365bool ResultBuilder::isInterestingDecl(NamedDecl *ND,
366 bool &AsNestedNameSpecifier) const {
367 AsNestedNameSpecifier = false;
368
Douglas Gregor7c208612010-01-14 00:20:49 +0000369 ND = ND->getUnderlyingDecl();
370 unsigned IDNS = ND->getIdentifierNamespace();
Douglas Gregor58acf322009-10-09 22:16:47 +0000371
372 // Skip unnamed entities.
Douglas Gregor7c208612010-01-14 00:20:49 +0000373 if (!ND->getDeclName())
374 return false;
Douglas Gregor3545ff42009-09-21 16:56:56 +0000375
376 // Friend declarations and declarations introduced due to friends are never
377 // added as results.
John McCallbbbbe4e2010-03-11 07:50:04 +0000378 if (IDNS & (Decl::IDNS_OrdinaryFriend | Decl::IDNS_TagFriend))
Douglas Gregor7c208612010-01-14 00:20:49 +0000379 return false;
380
Douglas Gregor99fe2ad2009-12-11 17:31:05 +0000381 // Class template (partial) specializations are never added as results.
Douglas Gregor7c208612010-01-14 00:20:49 +0000382 if (isa<ClassTemplateSpecializationDecl>(ND) ||
383 isa<ClassTemplatePartialSpecializationDecl>(ND))
384 return false;
Douglas Gregor3545ff42009-09-21 16:56:56 +0000385
Douglas Gregor99fe2ad2009-12-11 17:31:05 +0000386 // Using declarations themselves are never added as results.
Douglas Gregor7c208612010-01-14 00:20:49 +0000387 if (isa<UsingDecl>(ND))
388 return false;
389
390 // Some declarations have reserved names that we don't want to ever show.
391 if (const IdentifierInfo *Id = ND->getIdentifier()) {
Douglas Gregor3545ff42009-09-21 16:56:56 +0000392 // __va_list_tag is a freak of nature. Find it and skip it.
393 if (Id->isStr("__va_list_tag") || Id->isStr("__builtin_va_list"))
Douglas Gregor7c208612010-01-14 00:20:49 +0000394 return false;
Douglas Gregor3545ff42009-09-21 16:56:56 +0000395
Douglas Gregor58acf322009-10-09 22:16:47 +0000396 // Filter out names reserved for the implementation (C99 7.1.3,
397 // C++ [lib.global.names]). Users don't need to see those.
Daniel Dunbar2c422dc92009-10-18 20:26:12 +0000398 //
399 // FIXME: Add predicate for this.
Douglas Gregor58acf322009-10-09 22:16:47 +0000400 if (Id->getLength() >= 2) {
Daniel Dunbar2c422dc92009-10-18 20:26:12 +0000401 const char *Name = Id->getNameStart();
Douglas Gregor58acf322009-10-09 22:16:47 +0000402 if (Name[0] == '_' &&
403 (Name[1] == '_' || (Name[1] >= 'A' && Name[1] <= 'Z')))
Douglas Gregor7c208612010-01-14 00:20:49 +0000404 return false;
Douglas Gregor58acf322009-10-09 22:16:47 +0000405 }
Douglas Gregor3545ff42009-09-21 16:56:56 +0000406 }
Douglas Gregor7c208612010-01-14 00:20:49 +0000407
Douglas Gregor3545ff42009-09-21 16:56:56 +0000408 // C++ constructors are never found by name lookup.
Douglas Gregor7c208612010-01-14 00:20:49 +0000409 if (isa<CXXConstructorDecl>(ND))
410 return false;
Douglas Gregor3545ff42009-09-21 16:56:56 +0000411
412 // Filter out any unwanted results.
Douglas Gregor6ae4c522010-01-14 03:21:49 +0000413 if (Filter && !(this->*Filter)(ND)) {
414 // Check whether it is interesting as a nested-name-specifier.
415 if (AllowNestedNameSpecifiers && SemaRef.getLangOptions().CPlusPlus &&
416 IsNestedNameSpecifier(ND) &&
417 (Filter != &ResultBuilder::IsMember ||
418 (isa<CXXRecordDecl>(ND) &&
419 cast<CXXRecordDecl>(ND)->isInjectedClassName()))) {
420 AsNestedNameSpecifier = true;
421 return true;
422 }
423
Douglas Gregor7c208612010-01-14 00:20:49 +0000424 return false;
Douglas Gregor6ae4c522010-01-14 03:21:49 +0000425 }
John McCalle87beb22010-04-23 18:46:30 +0000426
427 if (Filter == &ResultBuilder::IsNestedNameSpecifier)
428 AsNestedNameSpecifier = true;
Douglas Gregor3545ff42009-09-21 16:56:56 +0000429
Douglas Gregor7c208612010-01-14 00:20:49 +0000430 // ... then it must be interesting!
431 return true;
432}
433
Douglas Gregore0717ab2010-01-14 00:41:07 +0000434bool ResultBuilder::CheckHiddenResult(Result &R, DeclContext *CurContext,
435 NamedDecl *Hiding) {
436 // In C, there is no way to refer to a hidden name.
437 // FIXME: This isn't true; we can find a tag name hidden by an ordinary
438 // name if we introduce the tag type.
439 if (!SemaRef.getLangOptions().CPlusPlus)
440 return true;
441
442 DeclContext *HiddenCtx = R.Declaration->getDeclContext()->getLookupContext();
443
444 // There is no way to qualify a name declared in a function or method.
445 if (HiddenCtx->isFunctionOrMethod())
446 return true;
447
448 if (HiddenCtx == Hiding->getDeclContext()->getLookupContext())
449 return true;
450
451 // We can refer to the result with the appropriate qualification. Do it.
452 R.Hidden = true;
453 R.QualifierIsInformative = false;
454
455 if (!R.Qualifier)
456 R.Qualifier = getRequiredQualification(SemaRef.Context,
457 CurContext,
458 R.Declaration->getDeclContext());
459 return false;
460}
461
Douglas Gregor7c208612010-01-14 00:20:49 +0000462void ResultBuilder::MaybeAddResult(Result R, DeclContext *CurContext) {
463 assert(!ShadowMaps.empty() && "Must enter into a results scope");
464
465 if (R.Kind != Result::RK_Declaration) {
466 // For non-declaration results, just add the result.
467 Results.push_back(R);
468 return;
469 }
470
471 // Look through using declarations.
472 if (UsingShadowDecl *Using = dyn_cast<UsingShadowDecl>(R.Declaration)) {
473 MaybeAddResult(Result(Using->getTargetDecl(), R.Qualifier), CurContext);
474 return;
475 }
476
477 Decl *CanonDecl = R.Declaration->getCanonicalDecl();
478 unsigned IDNS = CanonDecl->getIdentifierNamespace();
479
Douglas Gregor6ae4c522010-01-14 03:21:49 +0000480 bool AsNestedNameSpecifier = false;
481 if (!isInterestingDecl(R.Declaration, AsNestedNameSpecifier))
Douglas Gregor7c208612010-01-14 00:20:49 +0000482 return;
483
Douglas Gregor3545ff42009-09-21 16:56:56 +0000484 ShadowMap &SMap = ShadowMaps.back();
Douglas Gregor05e7ca32009-12-06 20:23:50 +0000485 ShadowMapEntry::iterator I, IEnd;
486 ShadowMap::iterator NamePos = SMap.find(R.Declaration->getDeclName());
487 if (NamePos != SMap.end()) {
488 I = NamePos->second.begin();
489 IEnd = NamePos->second.end();
490 }
491
492 for (; I != IEnd; ++I) {
493 NamedDecl *ND = I->first;
494 unsigned Index = I->second;
Douglas Gregor3545ff42009-09-21 16:56:56 +0000495 if (ND->getCanonicalDecl() == CanonDecl) {
496 // This is a redeclaration. Always pick the newer declaration.
Douglas Gregor3545ff42009-09-21 16:56:56 +0000497 Results[Index].Declaration = R.Declaration;
498
Douglas Gregor3545ff42009-09-21 16:56:56 +0000499 // We're done.
500 return;
501 }
502 }
503
504 // This is a new declaration in this scope. However, check whether this
505 // declaration name is hidden by a similarly-named declaration in an outer
506 // scope.
507 std::list<ShadowMap>::iterator SM, SMEnd = ShadowMaps.end();
508 --SMEnd;
509 for (SM = ShadowMaps.begin(); SM != SMEnd; ++SM) {
Douglas Gregor05e7ca32009-12-06 20:23:50 +0000510 ShadowMapEntry::iterator I, IEnd;
511 ShadowMap::iterator NamePos = SM->find(R.Declaration->getDeclName());
512 if (NamePos != SM->end()) {
513 I = NamePos->second.begin();
514 IEnd = NamePos->second.end();
515 }
516 for (; I != IEnd; ++I) {
Douglas Gregor3545ff42009-09-21 16:56:56 +0000517 // A tag declaration does not hide a non-tag declaration.
John McCalle87beb22010-04-23 18:46:30 +0000518 if (I->first->hasTagIdentifierNamespace() &&
Douglas Gregor3545ff42009-09-21 16:56:56 +0000519 (IDNS & (Decl::IDNS_Member | Decl::IDNS_Ordinary |
520 Decl::IDNS_ObjCProtocol)))
521 continue;
522
523 // Protocols are in distinct namespaces from everything else.
Douglas Gregor05e7ca32009-12-06 20:23:50 +0000524 if (((I->first->getIdentifierNamespace() & Decl::IDNS_ObjCProtocol)
Douglas Gregor3545ff42009-09-21 16:56:56 +0000525 || (IDNS & Decl::IDNS_ObjCProtocol)) &&
Douglas Gregor05e7ca32009-12-06 20:23:50 +0000526 I->first->getIdentifierNamespace() != IDNS)
Douglas Gregor3545ff42009-09-21 16:56:56 +0000527 continue;
528
529 // The newly-added result is hidden by an entry in the shadow map.
Douglas Gregore0717ab2010-01-14 00:41:07 +0000530 if (CheckHiddenResult(R, CurContext, I->first))
Douglas Gregor3545ff42009-09-21 16:56:56 +0000531 return;
Douglas Gregor3545ff42009-09-21 16:56:56 +0000532
533 break;
534 }
535 }
536
537 // Make sure that any given declaration only shows up in the result set once.
538 if (!AllDeclsFound.insert(CanonDecl))
539 return;
540
Douglas Gregore412a5a2009-09-23 22:26:46 +0000541 // If the filter is for nested-name-specifiers, then this result starts a
542 // nested-name-specifier.
Douglas Gregora2db7932010-05-26 22:00:08 +0000543 if (AsNestedNameSpecifier) {
Douglas Gregore412a5a2009-09-23 22:26:46 +0000544 R.StartsNestedNameSpecifier = true;
Douglas Gregora2db7932010-05-26 22:00:08 +0000545 R.Priority = CCP_NestedNameSpecifier;
546 }
Douglas Gregore412a5a2009-09-23 22:26:46 +0000547
Douglas Gregor5bf52692009-09-22 23:15:58 +0000548 // If this result is supposed to have an informative qualifier, add one.
Douglas Gregore412a5a2009-09-23 22:26:46 +0000549 if (R.QualifierIsInformative && !R.Qualifier &&
550 !R.StartsNestedNameSpecifier) {
Douglas Gregor5bf52692009-09-22 23:15:58 +0000551 DeclContext *Ctx = R.Declaration->getDeclContext();
552 if (NamespaceDecl *Namespace = dyn_cast<NamespaceDecl>(Ctx))
553 R.Qualifier = NestedNameSpecifier::Create(SemaRef.Context, 0, Namespace);
554 else if (TagDecl *Tag = dyn_cast<TagDecl>(Ctx))
555 R.Qualifier = NestedNameSpecifier::Create(SemaRef.Context, 0, false,
556 SemaRef.Context.getTypeDeclType(Tag).getTypePtr());
557 else
558 R.QualifierIsInformative = false;
559 }
Douglas Gregore412a5a2009-09-23 22:26:46 +0000560
Douglas Gregor3545ff42009-09-21 16:56:56 +0000561 // Insert this result into the set of results and into the current shadow
562 // map.
Douglas Gregor05e7ca32009-12-06 20:23:50 +0000563 SMap[R.Declaration->getDeclName()].Add(R.Declaration, Results.size());
Douglas Gregor3545ff42009-09-21 16:56:56 +0000564 Results.push_back(R);
565}
566
Douglas Gregorc580c522010-01-14 01:09:38 +0000567void ResultBuilder::AddResult(Result R, DeclContext *CurContext,
Douglas Gregor09bbc652010-01-14 15:47:35 +0000568 NamedDecl *Hiding, bool InBaseClass = false) {
Douglas Gregor78a21012010-01-14 16:01:26 +0000569 if (R.Kind != Result::RK_Declaration) {
570 // For non-declaration results, just add the result.
571 Results.push_back(R);
572 return;
573 }
574
Douglas Gregorc580c522010-01-14 01:09:38 +0000575 // Look through using declarations.
576 if (UsingShadowDecl *Using = dyn_cast<UsingShadowDecl>(R.Declaration)) {
577 AddResult(Result(Using->getTargetDecl(), R.Qualifier), CurContext, Hiding);
578 return;
579 }
580
Douglas Gregor6ae4c522010-01-14 03:21:49 +0000581 bool AsNestedNameSpecifier = false;
582 if (!isInterestingDecl(R.Declaration, AsNestedNameSpecifier))
Douglas Gregorc580c522010-01-14 01:09:38 +0000583 return;
584
585 if (Hiding && CheckHiddenResult(R, CurContext, Hiding))
586 return;
587
588 // Make sure that any given declaration only shows up in the result set once.
589 if (!AllDeclsFound.insert(R.Declaration->getCanonicalDecl()))
590 return;
591
592 // If the filter is for nested-name-specifiers, then this result starts a
593 // nested-name-specifier.
Douglas Gregora2db7932010-05-26 22:00:08 +0000594 if (AsNestedNameSpecifier) {
Douglas Gregorc580c522010-01-14 01:09:38 +0000595 R.StartsNestedNameSpecifier = true;
Douglas Gregora2db7932010-05-26 22:00:08 +0000596 R.Priority = CCP_NestedNameSpecifier;
597 }
Douglas Gregor09bbc652010-01-14 15:47:35 +0000598 else if (Filter == &ResultBuilder::IsMember && !R.Qualifier && InBaseClass &&
599 isa<CXXRecordDecl>(R.Declaration->getDeclContext()
600 ->getLookupContext()))
601 R.QualifierIsInformative = true;
602
Douglas Gregorc580c522010-01-14 01:09:38 +0000603 // If this result is supposed to have an informative qualifier, add one.
604 if (R.QualifierIsInformative && !R.Qualifier &&
605 !R.StartsNestedNameSpecifier) {
606 DeclContext *Ctx = R.Declaration->getDeclContext();
607 if (NamespaceDecl *Namespace = dyn_cast<NamespaceDecl>(Ctx))
608 R.Qualifier = NestedNameSpecifier::Create(SemaRef.Context, 0, Namespace);
609 else if (TagDecl *Tag = dyn_cast<TagDecl>(Ctx))
610 R.Qualifier = NestedNameSpecifier::Create(SemaRef.Context, 0, false,
Douglas Gregor6ae4c522010-01-14 03:21:49 +0000611 SemaRef.Context.getTypeDeclType(Tag).getTypePtr());
Douglas Gregorc580c522010-01-14 01:09:38 +0000612 else
613 R.QualifierIsInformative = false;
614 }
615
Douglas Gregora2db7932010-05-26 22:00:08 +0000616 // Adjust the priority if this result comes from a base class.
617 if (InBaseClass)
618 R.Priority += CCD_InBaseClass;
619
Douglas Gregorc580c522010-01-14 01:09:38 +0000620 // Insert this result into the set of results.
621 Results.push_back(R);
622}
623
Douglas Gregor78a21012010-01-14 16:01:26 +0000624void ResultBuilder::AddResult(Result R) {
625 assert(R.Kind != Result::RK_Declaration &&
626 "Declaration results need more context");
627 Results.push_back(R);
628}
629
Douglas Gregor3545ff42009-09-21 16:56:56 +0000630/// \brief Enter into a new scope.
631void ResultBuilder::EnterNewScope() {
632 ShadowMaps.push_back(ShadowMap());
633}
634
635/// \brief Exit from the current scope.
636void ResultBuilder::ExitScope() {
Douglas Gregor05e7ca32009-12-06 20:23:50 +0000637 for (ShadowMap::iterator E = ShadowMaps.back().begin(),
638 EEnd = ShadowMaps.back().end();
639 E != EEnd;
640 ++E)
641 E->second.Destroy();
642
Douglas Gregor3545ff42009-09-21 16:56:56 +0000643 ShadowMaps.pop_back();
644}
645
Douglas Gregor9d64c5e2009-09-21 20:51:25 +0000646/// \brief Determines whether this given declaration will be found by
647/// ordinary name lookup.
648bool ResultBuilder::IsOrdinaryName(NamedDecl *ND) const {
649 unsigned IDNS = Decl::IDNS_Ordinary;
650 if (SemaRef.getLangOptions().CPlusPlus)
John McCalle87beb22010-04-23 18:46:30 +0000651 IDNS |= Decl::IDNS_Tag | Decl::IDNS_Namespace;
Douglas Gregorc580c522010-01-14 01:09:38 +0000652 else if (SemaRef.getLangOptions().ObjC1 && isa<ObjCIvarDecl>(ND))
653 return true;
654
Douglas Gregor9d64c5e2009-09-21 20:51:25 +0000655 return ND->getIdentifierNamespace() & IDNS;
656}
657
Douglas Gregor504a6ae2010-01-10 23:08:15 +0000658/// \brief Determines whether this given declaration will be found by
659/// ordinary name lookup.
660bool ResultBuilder::IsOrdinaryNonValueName(NamedDecl *ND) const {
661 unsigned IDNS = Decl::IDNS_Ordinary;
662 if (SemaRef.getLangOptions().CPlusPlus)
John McCalle87beb22010-04-23 18:46:30 +0000663 IDNS |= Decl::IDNS_Tag | Decl::IDNS_Namespace;
Douglas Gregor504a6ae2010-01-10 23:08:15 +0000664
665 return (ND->getIdentifierNamespace() & IDNS) &&
666 !isa<ValueDecl>(ND) && !isa<FunctionTemplateDecl>(ND);
667}
668
Douglas Gregor3545ff42009-09-21 16:56:56 +0000669/// \brief Determines whether the given declaration is suitable as the
670/// start of a C++ nested-name-specifier, e.g., a class or namespace.
671bool ResultBuilder::IsNestedNameSpecifier(NamedDecl *ND) const {
672 // Allow us to find class templates, too.
673 if (ClassTemplateDecl *ClassTemplate = dyn_cast<ClassTemplateDecl>(ND))
674 ND = ClassTemplate->getTemplatedDecl();
675
676 return SemaRef.isAcceptableNestedNameSpecifier(ND);
677}
678
679/// \brief Determines whether the given declaration is an enumeration.
680bool ResultBuilder::IsEnum(NamedDecl *ND) const {
681 return isa<EnumDecl>(ND);
682}
683
684/// \brief Determines whether the given declaration is a class or struct.
685bool ResultBuilder::IsClassOrStruct(NamedDecl *ND) const {
686 // Allow us to find class templates, too.
687 if (ClassTemplateDecl *ClassTemplate = dyn_cast<ClassTemplateDecl>(ND))
688 ND = ClassTemplate->getTemplatedDecl();
689
690 if (RecordDecl *RD = dyn_cast<RecordDecl>(ND))
Abramo Bagnara6150c882010-05-11 21:36:43 +0000691 return RD->getTagKind() == TTK_Class ||
692 RD->getTagKind() == TTK_Struct;
Douglas Gregor3545ff42009-09-21 16:56:56 +0000693
694 return false;
695}
696
697/// \brief Determines whether the given declaration is a union.
698bool ResultBuilder::IsUnion(NamedDecl *ND) const {
699 // Allow us to find class templates, too.
700 if (ClassTemplateDecl *ClassTemplate = dyn_cast<ClassTemplateDecl>(ND))
701 ND = ClassTemplate->getTemplatedDecl();
702
703 if (RecordDecl *RD = dyn_cast<RecordDecl>(ND))
Abramo Bagnara6150c882010-05-11 21:36:43 +0000704 return RD->getTagKind() == TTK_Union;
Douglas Gregor3545ff42009-09-21 16:56:56 +0000705
706 return false;
707}
708
709/// \brief Determines whether the given declaration is a namespace.
710bool ResultBuilder::IsNamespace(NamedDecl *ND) const {
711 return isa<NamespaceDecl>(ND);
712}
713
714/// \brief Determines whether the given declaration is a namespace or
715/// namespace alias.
716bool ResultBuilder::IsNamespaceOrAlias(NamedDecl *ND) const {
717 return isa<NamespaceDecl>(ND) || isa<NamespaceAliasDecl>(ND);
718}
719
Douglas Gregor99fe2ad2009-12-11 17:31:05 +0000720/// \brief Determines whether the given declaration is a type.
Douglas Gregor3545ff42009-09-21 16:56:56 +0000721bool ResultBuilder::IsType(NamedDecl *ND) const {
722 return isa<TypeDecl>(ND);
723}
724
Douglas Gregor99fe2ad2009-12-11 17:31:05 +0000725/// \brief Determines which members of a class should be visible via
726/// "." or "->". Only value declarations, nested name specifiers, and
727/// using declarations thereof should show up.
Douglas Gregore412a5a2009-09-23 22:26:46 +0000728bool ResultBuilder::IsMember(NamedDecl *ND) const {
Douglas Gregor99fe2ad2009-12-11 17:31:05 +0000729 if (UsingShadowDecl *Using = dyn_cast<UsingShadowDecl>(ND))
730 ND = Using->getTargetDecl();
731
Douglas Gregor70788392009-12-11 18:14:22 +0000732 return isa<ValueDecl>(ND) || isa<FunctionTemplateDecl>(ND) ||
733 isa<ObjCPropertyDecl>(ND);
Douglas Gregore412a5a2009-09-23 22:26:46 +0000734}
735
Douglas Gregora817a192010-05-27 23:06:34 +0000736/// \brief Get the type that a given expression will have if this declaration
737/// is used as an expression in its "typical" code-completion form.
738static QualType getDeclUsageType(ASTContext &C, NamedDecl *ND) {
739 ND = cast<NamedDecl>(ND->getUnderlyingDecl());
740
741 if (TypeDecl *Type = dyn_cast<TypeDecl>(ND))
742 return C.getTypeDeclType(Type);
743 if (ObjCInterfaceDecl *Iface = dyn_cast<ObjCInterfaceDecl>(ND))
744 return C.getObjCInterfaceType(Iface);
745
746 QualType T;
747 if (FunctionDecl *Function = dyn_cast<FunctionDecl>(ND))
748 T = Function->getResultType();
749 else if (ObjCMethodDecl *Method = dyn_cast<ObjCMethodDecl>(ND))
750 T = Method->getResultType();
751 else if (FunctionTemplateDecl *FunTmpl = dyn_cast<FunctionTemplateDecl>(ND))
752 T = FunTmpl->getTemplatedDecl()->getResultType();
753 else if (EnumConstantDecl *Enumerator = dyn_cast<EnumConstantDecl>(ND))
754 T = C.getTypeDeclType(cast<EnumDecl>(Enumerator->getDeclContext()));
755 else if (ObjCPropertyDecl *Property = dyn_cast<ObjCPropertyDecl>(ND))
756 T = Property->getType();
757 else if (ValueDecl *Value = dyn_cast<ValueDecl>(ND))
758 T = Value->getType();
759 else
760 return QualType();
761
762 return T.getNonReferenceType();
763}
764
765static bool isObjCReceiverType(ASTContext &C, QualType T) {
766 T = C.getCanonicalType(T);
767 switch (T->getTypeClass()) {
768 case Type::ObjCObject:
769 case Type::ObjCInterface:
770 case Type::ObjCObjectPointer:
771 return true;
772
773 case Type::Builtin:
774 switch (cast<BuiltinType>(T)->getKind()) {
775 case BuiltinType::ObjCId:
776 case BuiltinType::ObjCClass:
777 case BuiltinType::ObjCSel:
778 return true;
779
780 default:
781 break;
782 }
783 return false;
784
785 default:
786 break;
787 }
788
789 if (!C.getLangOptions().CPlusPlus)
790 return false;
791
792 // FIXME: We could perform more analysis here to determine whether a
793 // particular class type has any conversions to Objective-C types. For now,
794 // just accept all class types.
795 return T->isDependentType() || T->isRecordType();
796}
797
798bool ResultBuilder::IsObjCMessageReceiver(NamedDecl *ND) const {
799 QualType T = getDeclUsageType(SemaRef.Context, ND);
800 if (T.isNull())
801 return false;
802
803 T = SemaRef.Context.getBaseElementType(T);
804 return isObjCReceiverType(SemaRef.Context, T);
805}
806
807
Douglas Gregor2b8162b2010-01-14 16:08:12 +0000808/// \rief Determines whether the given declaration is an Objective-C
809/// instance variable.
810bool ResultBuilder::IsObjCIvar(NamedDecl *ND) const {
811 return isa<ObjCIvarDecl>(ND);
812}
813
Douglas Gregorc580c522010-01-14 01:09:38 +0000814namespace {
815 /// \brief Visible declaration consumer that adds a code-completion result
816 /// for each visible declaration.
817 class CodeCompletionDeclConsumer : public VisibleDeclConsumer {
818 ResultBuilder &Results;
819 DeclContext *CurContext;
820
821 public:
822 CodeCompletionDeclConsumer(ResultBuilder &Results, DeclContext *CurContext)
823 : Results(Results), CurContext(CurContext) { }
824
Douglas Gregor09bbc652010-01-14 15:47:35 +0000825 virtual void FoundDecl(NamedDecl *ND, NamedDecl *Hiding, bool InBaseClass) {
826 Results.AddResult(ND, CurContext, Hiding, InBaseClass);
Douglas Gregorc580c522010-01-14 01:09:38 +0000827 }
828 };
829}
830
Douglas Gregor3545ff42009-09-21 16:56:56 +0000831/// \brief Add type specifiers for the current language as keyword results.
Douglas Gregorf98e6a22010-01-13 23:51:12 +0000832static void AddTypeSpecifierResults(const LangOptions &LangOpts,
Douglas Gregor3545ff42009-09-21 16:56:56 +0000833 ResultBuilder &Results) {
834 typedef CodeCompleteConsumer::Result Result;
Douglas Gregora2db7932010-05-26 22:00:08 +0000835 Results.AddResult(Result("short", CCP_Type));
836 Results.AddResult(Result("long", CCP_Type));
837 Results.AddResult(Result("signed", CCP_Type));
838 Results.AddResult(Result("unsigned", CCP_Type));
839 Results.AddResult(Result("void", CCP_Type));
840 Results.AddResult(Result("char", CCP_Type));
841 Results.AddResult(Result("int", CCP_Type));
842 Results.AddResult(Result("float", CCP_Type));
843 Results.AddResult(Result("double", CCP_Type));
844 Results.AddResult(Result("enum", CCP_Type));
845 Results.AddResult(Result("struct", CCP_Type));
846 Results.AddResult(Result("union", CCP_Type));
847 Results.AddResult(Result("const", CCP_Type));
848 Results.AddResult(Result("volatile", CCP_Type));
Douglas Gregor504a6ae2010-01-10 23:08:15 +0000849
Douglas Gregor3545ff42009-09-21 16:56:56 +0000850 if (LangOpts.C99) {
851 // C99-specific
Douglas Gregora2db7932010-05-26 22:00:08 +0000852 Results.AddResult(Result("_Complex", CCP_Type));
853 Results.AddResult(Result("_Imaginary", CCP_Type));
854 Results.AddResult(Result("_Bool", CCP_Type));
855 Results.AddResult(Result("restrict", CCP_Type));
Douglas Gregor3545ff42009-09-21 16:56:56 +0000856 }
857
858 if (LangOpts.CPlusPlus) {
859 // C++-specific
Douglas Gregora2db7932010-05-26 22:00:08 +0000860 Results.AddResult(Result("bool", CCP_Type));
861 Results.AddResult(Result("class", CCP_Type));
862 Results.AddResult(Result("wchar_t", CCP_Type));
Douglas Gregor3545ff42009-09-21 16:56:56 +0000863
Douglas Gregorf4c33342010-05-28 00:22:41 +0000864 // typename qualified-id
865 CodeCompletionString *Pattern = new CodeCompletionString;
866 Pattern->AddTypedTextChunk("typename");
867 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
868 Pattern->AddPlaceholderChunk("qualifier");
869 Pattern->AddTextChunk("::");
870 Pattern->AddPlaceholderChunk("name");
871 Results.AddResult(Result(Pattern));
Douglas Gregorf64acca2010-05-25 21:41:55 +0000872
Douglas Gregor3545ff42009-09-21 16:56:56 +0000873 if (LangOpts.CPlusPlus0x) {
Douglas Gregora2db7932010-05-26 22:00:08 +0000874 Results.AddResult(Result("auto", CCP_Type));
875 Results.AddResult(Result("char16_t", CCP_Type));
876 Results.AddResult(Result("char32_t", CCP_Type));
Douglas Gregorf4c33342010-05-28 00:22:41 +0000877
878 CodeCompletionString *Pattern = new CodeCompletionString;
879 Pattern->AddTypedTextChunk("decltype");
880 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
881 Pattern->AddPlaceholderChunk("expression");
882 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
883 Results.AddResult(Result(Pattern));
Douglas Gregor3545ff42009-09-21 16:56:56 +0000884 }
885 }
886
887 // GNU extensions
888 if (LangOpts.GNUMode) {
889 // FIXME: Enable when we actually support decimal floating point.
Douglas Gregor78a21012010-01-14 16:01:26 +0000890 // Results.AddResult(Result("_Decimal32"));
891 // Results.AddResult(Result("_Decimal64"));
892 // Results.AddResult(Result("_Decimal128"));
Douglas Gregor504a6ae2010-01-10 23:08:15 +0000893
Douglas Gregorf4c33342010-05-28 00:22:41 +0000894 CodeCompletionString *Pattern = new CodeCompletionString;
895 Pattern->AddTypedTextChunk("typeof");
896 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
897 Pattern->AddPlaceholderChunk("expression");
898 Results.AddResult(Result(Pattern));
899
900 Pattern = new CodeCompletionString;
901 Pattern->AddTypedTextChunk("typeof");
902 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
903 Pattern->AddPlaceholderChunk("type");
904 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
905 Results.AddResult(Result(Pattern));
Douglas Gregor3545ff42009-09-21 16:56:56 +0000906 }
907}
908
Douglas Gregor504a6ae2010-01-10 23:08:15 +0000909static void AddStorageSpecifiers(Action::CodeCompletionContext CCC,
910 const LangOptions &LangOpts,
Douglas Gregor504a6ae2010-01-10 23:08:15 +0000911 ResultBuilder &Results) {
912 typedef CodeCompleteConsumer::Result Result;
913 // Note: we don't suggest either "auto" or "register", because both
914 // are pointless as storage specifiers. Elsewhere, we suggest "auto"
915 // in C++0x as a type specifier.
Douglas Gregor78a21012010-01-14 16:01:26 +0000916 Results.AddResult(Result("extern"));
917 Results.AddResult(Result("static"));
Douglas Gregor504a6ae2010-01-10 23:08:15 +0000918}
919
920static void AddFunctionSpecifiers(Action::CodeCompletionContext CCC,
921 const LangOptions &LangOpts,
Douglas Gregor504a6ae2010-01-10 23:08:15 +0000922 ResultBuilder &Results) {
923 typedef CodeCompleteConsumer::Result Result;
924 switch (CCC) {
925 case Action::CCC_Class:
926 case Action::CCC_MemberTemplate:
927 if (LangOpts.CPlusPlus) {
Douglas Gregor78a21012010-01-14 16:01:26 +0000928 Results.AddResult(Result("explicit"));
929 Results.AddResult(Result("friend"));
930 Results.AddResult(Result("mutable"));
931 Results.AddResult(Result("virtual"));
Douglas Gregor504a6ae2010-01-10 23:08:15 +0000932 }
933 // Fall through
934
Douglas Gregorf1934162010-01-13 21:24:21 +0000935 case Action::CCC_ObjCInterface:
936 case Action::CCC_ObjCImplementation:
Douglas Gregor504a6ae2010-01-10 23:08:15 +0000937 case Action::CCC_Namespace:
938 case Action::CCC_Template:
939 if (LangOpts.CPlusPlus || LangOpts.C99)
Douglas Gregor78a21012010-01-14 16:01:26 +0000940 Results.AddResult(Result("inline"));
Douglas Gregor504a6ae2010-01-10 23:08:15 +0000941 break;
942
Douglas Gregor48d46252010-01-13 21:54:15 +0000943 case Action::CCC_ObjCInstanceVariableList:
Douglas Gregor504a6ae2010-01-10 23:08:15 +0000944 case Action::CCC_Expression:
945 case Action::CCC_Statement:
946 case Action::CCC_ForInit:
947 case Action::CCC_Condition:
Douglas Gregor6da3db42010-05-25 05:58:43 +0000948 case Action::CCC_RecoveryInFunction:
Douglas Gregor504a6ae2010-01-10 23:08:15 +0000949 break;
950 }
951}
952
Douglas Gregorf98e6a22010-01-13 23:51:12 +0000953static void AddObjCExpressionResults(ResultBuilder &Results, bool NeedAt);
954static void AddObjCStatementResults(ResultBuilder &Results, bool NeedAt);
955static void AddObjCVisibilityResults(const LangOptions &LangOpts,
Douglas Gregor48d46252010-01-13 21:54:15 +0000956 ResultBuilder &Results,
957 bool NeedAt);
Douglas Gregorf98e6a22010-01-13 23:51:12 +0000958static void AddObjCImplementationResults(const LangOptions &LangOpts,
Douglas Gregorf1934162010-01-13 21:24:21 +0000959 ResultBuilder &Results,
960 bool NeedAt);
Douglas Gregorf98e6a22010-01-13 23:51:12 +0000961static void AddObjCInterfaceResults(const LangOptions &LangOpts,
Douglas Gregorf1934162010-01-13 21:24:21 +0000962 ResultBuilder &Results,
963 bool NeedAt);
Douglas Gregorf98e6a22010-01-13 23:51:12 +0000964static void AddObjCTopLevelResults(ResultBuilder &Results, bool NeedAt);
Douglas Gregorf1934162010-01-13 21:24:21 +0000965
Douglas Gregorf4c33342010-05-28 00:22:41 +0000966static void AddTypedefResult(ResultBuilder &Results) {
967 CodeCompletionString *Pattern = new CodeCompletionString;
968 Pattern->AddTypedTextChunk("typedef");
969 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
970 Pattern->AddPlaceholderChunk("type");
971 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
972 Pattern->AddPlaceholderChunk("name");
973 Results.AddResult(CodeCompleteConsumer::Result(Pattern));
974}
975
Douglas Gregor504a6ae2010-01-10 23:08:15 +0000976/// \brief Add language constructs that show up for "ordinary" names.
977static void AddOrdinaryNameResults(Action::CodeCompletionContext CCC,
978 Scope *S,
979 Sema &SemaRef,
Douglas Gregor504a6ae2010-01-10 23:08:15 +0000980 ResultBuilder &Results) {
981 typedef CodeCompleteConsumer::Result Result;
982 switch (CCC) {
983 case Action::CCC_Namespace:
Douglas Gregorf4c33342010-05-28 00:22:41 +0000984 if (SemaRef.getLangOptions().CPlusPlus) {
985 CodeCompletionString *Pattern = 0;
986
987 if (Results.includeCodePatterns()) {
988 // namespace <identifier> { declarations }
989 CodeCompletionString *Pattern = new CodeCompletionString;
990 Pattern->AddTypedTextChunk("namespace");
991 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
992 Pattern->AddPlaceholderChunk("identifier");
993 Pattern->AddChunk(CodeCompletionString::CK_LeftBrace);
994 Pattern->AddPlaceholderChunk("declarations");
995 Pattern->AddChunk(CodeCompletionString::CK_VerticalSpace);
996 Pattern->AddChunk(CodeCompletionString::CK_RightBrace);
997 Results.AddResult(Result(Pattern));
998 }
999
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001000 // namespace identifier = identifier ;
1001 Pattern = new CodeCompletionString;
1002 Pattern->AddTypedTextChunk("namespace");
1003 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
Douglas Gregorf4c33342010-05-28 00:22:41 +00001004 Pattern->AddPlaceholderChunk("name");
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001005 Pattern->AddChunk(CodeCompletionString::CK_Equal);
Douglas Gregorf4c33342010-05-28 00:22:41 +00001006 Pattern->AddPlaceholderChunk("namespace");
Douglas Gregor78a21012010-01-14 16:01:26 +00001007 Results.AddResult(Result(Pattern));
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001008
1009 // Using directives
1010 Pattern = new CodeCompletionString;
1011 Pattern->AddTypedTextChunk("using");
1012 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
1013 Pattern->AddTextChunk("namespace");
1014 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
1015 Pattern->AddPlaceholderChunk("identifier");
Douglas Gregor78a21012010-01-14 16:01:26 +00001016 Results.AddResult(Result(Pattern));
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001017
1018 // asm(string-literal)
1019 Pattern = new CodeCompletionString;
1020 Pattern->AddTypedTextChunk("asm");
1021 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
1022 Pattern->AddPlaceholderChunk("string-literal");
1023 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
Douglas Gregor78a21012010-01-14 16:01:26 +00001024 Results.AddResult(Result(Pattern));
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001025
Douglas Gregorf4c33342010-05-28 00:22:41 +00001026 if (Results.includeCodePatterns()) {
1027 // Explicit template instantiation
1028 Pattern = new CodeCompletionString;
1029 Pattern->AddTypedTextChunk("template");
1030 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
1031 Pattern->AddPlaceholderChunk("declaration");
1032 Results.AddResult(Result(Pattern));
1033 }
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001034 }
Douglas Gregorf1934162010-01-13 21:24:21 +00001035
1036 if (SemaRef.getLangOptions().ObjC1)
Douglas Gregorf98e6a22010-01-13 23:51:12 +00001037 AddObjCTopLevelResults(Results, true);
Douglas Gregorf1934162010-01-13 21:24:21 +00001038
Douglas Gregorf4c33342010-05-28 00:22:41 +00001039 AddTypedefResult(Results);
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001040 // Fall through
1041
1042 case Action::CCC_Class:
Douglas Gregorf4c33342010-05-28 00:22:41 +00001043 if (SemaRef.getLangOptions().CPlusPlus) {
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001044 // Using declaration
1045 CodeCompletionString *Pattern = new CodeCompletionString;
1046 Pattern->AddTypedTextChunk("using");
1047 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
Douglas Gregorf4c33342010-05-28 00:22:41 +00001048 Pattern->AddPlaceholderChunk("qualifier");
1049 Pattern->AddTextChunk("::");
1050 Pattern->AddPlaceholderChunk("name");
Douglas Gregor78a21012010-01-14 16:01:26 +00001051 Results.AddResult(Result(Pattern));
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001052
Douglas Gregorf4c33342010-05-28 00:22:41 +00001053 // using typename qualifier::name (only in a dependent context)
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001054 if (SemaRef.CurContext->isDependentContext()) {
1055 Pattern = new CodeCompletionString;
1056 Pattern->AddTypedTextChunk("using");
1057 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
1058 Pattern->AddTextChunk("typename");
1059 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
Douglas Gregorf4c33342010-05-28 00:22:41 +00001060 Pattern->AddPlaceholderChunk("qualifier");
1061 Pattern->AddTextChunk("::");
1062 Pattern->AddPlaceholderChunk("name");
Douglas Gregor78a21012010-01-14 16:01:26 +00001063 Results.AddResult(Result(Pattern));
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001064 }
1065
1066 if (CCC == Action::CCC_Class) {
Douglas Gregorf4c33342010-05-28 00:22:41 +00001067 AddTypedefResult(Results);
1068
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001069 // public:
1070 Pattern = new CodeCompletionString;
1071 Pattern->AddTypedTextChunk("public");
1072 Pattern->AddChunk(CodeCompletionString::CK_Colon);
Douglas Gregor78a21012010-01-14 16:01:26 +00001073 Results.AddResult(Result(Pattern));
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001074
1075 // protected:
1076 Pattern = new CodeCompletionString;
1077 Pattern->AddTypedTextChunk("protected");
1078 Pattern->AddChunk(CodeCompletionString::CK_Colon);
Douglas Gregor78a21012010-01-14 16:01:26 +00001079 Results.AddResult(Result(Pattern));
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001080
1081 // private:
1082 Pattern = new CodeCompletionString;
1083 Pattern->AddTypedTextChunk("private");
1084 Pattern->AddChunk(CodeCompletionString::CK_Colon);
Douglas Gregor78a21012010-01-14 16:01:26 +00001085 Results.AddResult(Result(Pattern));
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001086 }
1087 }
1088 // Fall through
1089
1090 case Action::CCC_Template:
1091 case Action::CCC_MemberTemplate:
Douglas Gregorf64acca2010-05-25 21:41:55 +00001092 if (SemaRef.getLangOptions().CPlusPlus && Results.includeCodePatterns()) {
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001093 // template < parameters >
1094 CodeCompletionString *Pattern = new CodeCompletionString;
1095 Pattern->AddTypedTextChunk("template");
1096 Pattern->AddChunk(CodeCompletionString::CK_LeftAngle);
1097 Pattern->AddPlaceholderChunk("parameters");
1098 Pattern->AddChunk(CodeCompletionString::CK_RightAngle);
Douglas Gregor78a21012010-01-14 16:01:26 +00001099 Results.AddResult(Result(Pattern));
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001100 }
1101
Douglas Gregorf98e6a22010-01-13 23:51:12 +00001102 AddStorageSpecifiers(CCC, SemaRef.getLangOptions(), Results);
1103 AddFunctionSpecifiers(CCC, SemaRef.getLangOptions(), Results);
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001104 break;
1105
Douglas Gregorf1934162010-01-13 21:24:21 +00001106 case Action::CCC_ObjCInterface:
Douglas Gregorf98e6a22010-01-13 23:51:12 +00001107 AddObjCInterfaceResults(SemaRef.getLangOptions(), Results, true);
1108 AddStorageSpecifiers(CCC, SemaRef.getLangOptions(), Results);
1109 AddFunctionSpecifiers(CCC, SemaRef.getLangOptions(), Results);
Douglas Gregorf1934162010-01-13 21:24:21 +00001110 break;
1111
1112 case Action::CCC_ObjCImplementation:
Douglas Gregorf98e6a22010-01-13 23:51:12 +00001113 AddObjCImplementationResults(SemaRef.getLangOptions(), Results, true);
1114 AddStorageSpecifiers(CCC, SemaRef.getLangOptions(), Results);
1115 AddFunctionSpecifiers(CCC, SemaRef.getLangOptions(), Results);
Douglas Gregorf1934162010-01-13 21:24:21 +00001116 break;
1117
Douglas Gregor48d46252010-01-13 21:54:15 +00001118 case Action::CCC_ObjCInstanceVariableList:
Douglas Gregorf98e6a22010-01-13 23:51:12 +00001119 AddObjCVisibilityResults(SemaRef.getLangOptions(), Results, true);
Douglas Gregor48d46252010-01-13 21:54:15 +00001120 break;
1121
Douglas Gregor6da3db42010-05-25 05:58:43 +00001122 case Action::CCC_RecoveryInFunction:
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001123 case Action::CCC_Statement: {
Douglas Gregorf4c33342010-05-28 00:22:41 +00001124 AddTypedefResult(Results);
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001125
1126 CodeCompletionString *Pattern = 0;
Douglas Gregorf64acca2010-05-25 21:41:55 +00001127 if (SemaRef.getLangOptions().CPlusPlus && Results.includeCodePatterns()) {
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001128 Pattern = new CodeCompletionString;
1129 Pattern->AddTypedTextChunk("try");
1130 Pattern->AddChunk(CodeCompletionString::CK_LeftBrace);
1131 Pattern->AddPlaceholderChunk("statements");
1132 Pattern->AddChunk(CodeCompletionString::CK_VerticalSpace);
1133 Pattern->AddChunk(CodeCompletionString::CK_RightBrace);
1134 Pattern->AddTextChunk("catch");
1135 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
1136 Pattern->AddPlaceholderChunk("declaration");
1137 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
1138 Pattern->AddChunk(CodeCompletionString::CK_LeftBrace);
1139 Pattern->AddPlaceholderChunk("statements");
1140 Pattern->AddChunk(CodeCompletionString::CK_VerticalSpace);
1141 Pattern->AddChunk(CodeCompletionString::CK_RightBrace);
Douglas Gregor78a21012010-01-14 16:01:26 +00001142 Results.AddResult(Result(Pattern));
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001143 }
Douglas Gregorf1934162010-01-13 21:24:21 +00001144 if (SemaRef.getLangOptions().ObjC1)
Douglas Gregorf98e6a22010-01-13 23:51:12 +00001145 AddObjCStatementResults(Results, true);
Douglas Gregorf1934162010-01-13 21:24:21 +00001146
Douglas Gregorf64acca2010-05-25 21:41:55 +00001147 if (Results.includeCodePatterns()) {
1148 // if (condition) { statements }
1149 Pattern = new CodeCompletionString;
1150 Pattern->AddTypedTextChunk("if");
1151 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
1152 if (SemaRef.getLangOptions().CPlusPlus)
1153 Pattern->AddPlaceholderChunk("condition");
1154 else
1155 Pattern->AddPlaceholderChunk("expression");
1156 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
1157 Pattern->AddChunk(CodeCompletionString::CK_LeftBrace);
1158 Pattern->AddPlaceholderChunk("statements");
1159 Pattern->AddChunk(CodeCompletionString::CK_VerticalSpace);
1160 Pattern->AddChunk(CodeCompletionString::CK_RightBrace);
1161 Results.AddResult(Result(Pattern));
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001162
Douglas Gregorf64acca2010-05-25 21:41:55 +00001163 // switch (condition) { }
1164 Pattern = new CodeCompletionString;
1165 Pattern->AddTypedTextChunk("switch");
1166 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
1167 if (SemaRef.getLangOptions().CPlusPlus)
1168 Pattern->AddPlaceholderChunk("condition");
1169 else
1170 Pattern->AddPlaceholderChunk("expression");
1171 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
1172 Pattern->AddChunk(CodeCompletionString::CK_LeftBrace);
1173 Pattern->AddChunk(CodeCompletionString::CK_VerticalSpace);
1174 Pattern->AddChunk(CodeCompletionString::CK_RightBrace);
1175 Results.AddResult(Result(Pattern));
1176 }
1177
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001178 // Switch-specific statements.
Douglas Gregorf4c33342010-05-28 00:22:41 +00001179 if (!SemaRef.getSwitchStack().empty()) {
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001180 // case expression:
1181 Pattern = new CodeCompletionString;
1182 Pattern->AddTypedTextChunk("case");
Douglas Gregorf4c33342010-05-28 00:22:41 +00001183 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001184 Pattern->AddPlaceholderChunk("expression");
1185 Pattern->AddChunk(CodeCompletionString::CK_Colon);
Douglas Gregor78a21012010-01-14 16:01:26 +00001186 Results.AddResult(Result(Pattern));
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001187
1188 // default:
1189 Pattern = new CodeCompletionString;
1190 Pattern->AddTypedTextChunk("default");
1191 Pattern->AddChunk(CodeCompletionString::CK_Colon);
Douglas Gregor78a21012010-01-14 16:01:26 +00001192 Results.AddResult(Result(Pattern));
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001193 }
1194
Douglas Gregorf64acca2010-05-25 21:41:55 +00001195 if (Results.includeCodePatterns()) {
1196 /// while (condition) { statements }
1197 Pattern = new CodeCompletionString;
1198 Pattern->AddTypedTextChunk("while");
1199 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
1200 if (SemaRef.getLangOptions().CPlusPlus)
1201 Pattern->AddPlaceholderChunk("condition");
1202 else
1203 Pattern->AddPlaceholderChunk("expression");
1204 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
1205 Pattern->AddChunk(CodeCompletionString::CK_LeftBrace);
1206 Pattern->AddPlaceholderChunk("statements");
1207 Pattern->AddChunk(CodeCompletionString::CK_VerticalSpace);
1208 Pattern->AddChunk(CodeCompletionString::CK_RightBrace);
1209 Results.AddResult(Result(Pattern));
1210
1211 // do { statements } while ( expression );
1212 Pattern = new CodeCompletionString;
1213 Pattern->AddTypedTextChunk("do");
1214 Pattern->AddChunk(CodeCompletionString::CK_LeftBrace);
1215 Pattern->AddPlaceholderChunk("statements");
1216 Pattern->AddChunk(CodeCompletionString::CK_VerticalSpace);
1217 Pattern->AddChunk(CodeCompletionString::CK_RightBrace);
1218 Pattern->AddTextChunk("while");
1219 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001220 Pattern->AddPlaceholderChunk("expression");
Douglas Gregorf64acca2010-05-25 21:41:55 +00001221 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
1222 Results.AddResult(Result(Pattern));
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001223
Douglas Gregorf64acca2010-05-25 21:41:55 +00001224 // for ( for-init-statement ; condition ; expression ) { statements }
1225 Pattern = new CodeCompletionString;
1226 Pattern->AddTypedTextChunk("for");
1227 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
1228 if (SemaRef.getLangOptions().CPlusPlus || SemaRef.getLangOptions().C99)
1229 Pattern->AddPlaceholderChunk("init-statement");
1230 else
1231 Pattern->AddPlaceholderChunk("init-expression");
1232 Pattern->AddChunk(CodeCompletionString::CK_SemiColon);
1233 Pattern->AddPlaceholderChunk("condition");
1234 Pattern->AddChunk(CodeCompletionString::CK_SemiColon);
1235 Pattern->AddPlaceholderChunk("inc-expression");
1236 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
1237 Pattern->AddChunk(CodeCompletionString::CK_LeftBrace);
1238 Pattern->AddPlaceholderChunk("statements");
1239 Pattern->AddChunk(CodeCompletionString::CK_VerticalSpace);
1240 Pattern->AddChunk(CodeCompletionString::CK_RightBrace);
1241 Results.AddResult(Result(Pattern));
1242 }
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001243
1244 if (S->getContinueParent()) {
1245 // continue ;
1246 Pattern = new CodeCompletionString;
1247 Pattern->AddTypedTextChunk("continue");
Douglas Gregor78a21012010-01-14 16:01:26 +00001248 Results.AddResult(Result(Pattern));
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001249 }
1250
1251 if (S->getBreakParent()) {
1252 // break ;
1253 Pattern = new CodeCompletionString;
1254 Pattern->AddTypedTextChunk("break");
Douglas Gregor78a21012010-01-14 16:01:26 +00001255 Results.AddResult(Result(Pattern));
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001256 }
1257
1258 // "return expression ;" or "return ;", depending on whether we
1259 // know the function is void or not.
1260 bool isVoid = false;
1261 if (FunctionDecl *Function = dyn_cast<FunctionDecl>(SemaRef.CurContext))
1262 isVoid = Function->getResultType()->isVoidType();
1263 else if (ObjCMethodDecl *Method
1264 = dyn_cast<ObjCMethodDecl>(SemaRef.CurContext))
1265 isVoid = Method->getResultType()->isVoidType();
Douglas Gregor9a28e842010-03-01 23:15:13 +00001266 else if (SemaRef.getCurBlock() &&
1267 !SemaRef.getCurBlock()->ReturnType.isNull())
1268 isVoid = SemaRef.getCurBlock()->ReturnType->isVoidType();
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001269 Pattern = new CodeCompletionString;
1270 Pattern->AddTypedTextChunk("return");
Douglas Gregor44272ca2010-02-18 04:06:48 +00001271 if (!isVoid) {
1272 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001273 Pattern->AddPlaceholderChunk("expression");
Douglas Gregor44272ca2010-02-18 04:06:48 +00001274 }
Douglas Gregor78a21012010-01-14 16:01:26 +00001275 Results.AddResult(Result(Pattern));
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001276
Douglas Gregorf4c33342010-05-28 00:22:41 +00001277 // goto identifier ;
1278 Pattern = new CodeCompletionString;
1279 Pattern->AddTypedTextChunk("goto");
1280 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
1281 Pattern->AddPlaceholderChunk("label");
1282 Results.AddResult(Result(Pattern));
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001283
Douglas Gregorf4c33342010-05-28 00:22:41 +00001284 // Using directives
1285 Pattern = new CodeCompletionString;
1286 Pattern->AddTypedTextChunk("using");
1287 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
1288 Pattern->AddTextChunk("namespace");
1289 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
1290 Pattern->AddPlaceholderChunk("identifier");
1291 Results.AddResult(Result(Pattern));
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001292 }
1293
1294 // Fall through (for statement expressions).
1295 case Action::CCC_ForInit:
1296 case Action::CCC_Condition:
Douglas Gregorf98e6a22010-01-13 23:51:12 +00001297 AddStorageSpecifiers(CCC, SemaRef.getLangOptions(), Results);
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001298 // Fall through: conditions and statements can have expressions.
1299
1300 case Action::CCC_Expression: {
1301 CodeCompletionString *Pattern = 0;
1302 if (SemaRef.getLangOptions().CPlusPlus) {
1303 // 'this', if we're in a non-static member function.
1304 if (CXXMethodDecl *Method = dyn_cast<CXXMethodDecl>(SemaRef.CurContext))
1305 if (!Method->isStatic())
Douglas Gregor78a21012010-01-14 16:01:26 +00001306 Results.AddResult(Result("this"));
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001307
1308 // true, false
Douglas Gregor78a21012010-01-14 16:01:26 +00001309 Results.AddResult(Result("true"));
1310 Results.AddResult(Result("false"));
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001311
Douglas Gregorf4c33342010-05-28 00:22:41 +00001312 // dynamic_cast < type-id > ( expression )
1313 Pattern = new CodeCompletionString;
1314 Pattern->AddTypedTextChunk("dynamic_cast");
1315 Pattern->AddChunk(CodeCompletionString::CK_LeftAngle);
1316 Pattern->AddPlaceholderChunk("type");
1317 Pattern->AddChunk(CodeCompletionString::CK_RightAngle);
1318 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
1319 Pattern->AddPlaceholderChunk("expression");
1320 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
1321 Results.AddResult(Result(Pattern));
1322
1323 // static_cast < type-id > ( expression )
1324 Pattern = new CodeCompletionString;
1325 Pattern->AddTypedTextChunk("static_cast");
1326 Pattern->AddChunk(CodeCompletionString::CK_LeftAngle);
1327 Pattern->AddPlaceholderChunk("type");
1328 Pattern->AddChunk(CodeCompletionString::CK_RightAngle);
1329 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
1330 Pattern->AddPlaceholderChunk("expression");
1331 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
1332 Results.AddResult(Result(Pattern));
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001333
Douglas Gregorf4c33342010-05-28 00:22:41 +00001334 // reinterpret_cast < type-id > ( expression )
1335 Pattern = new CodeCompletionString;
1336 Pattern->AddTypedTextChunk("reinterpret_cast");
1337 Pattern->AddChunk(CodeCompletionString::CK_LeftAngle);
1338 Pattern->AddPlaceholderChunk("type");
1339 Pattern->AddChunk(CodeCompletionString::CK_RightAngle);
1340 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
1341 Pattern->AddPlaceholderChunk("expression");
1342 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
1343 Results.AddResult(Result(Pattern));
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001344
Douglas Gregorf4c33342010-05-28 00:22:41 +00001345 // const_cast < type-id > ( expression )
1346 Pattern = new CodeCompletionString;
1347 Pattern->AddTypedTextChunk("const_cast");
1348 Pattern->AddChunk(CodeCompletionString::CK_LeftAngle);
1349 Pattern->AddPlaceholderChunk("type");
1350 Pattern->AddChunk(CodeCompletionString::CK_RightAngle);
1351 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
1352 Pattern->AddPlaceholderChunk("expression");
1353 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
1354 Results.AddResult(Result(Pattern));
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001355
Douglas Gregorf4c33342010-05-28 00:22:41 +00001356 // typeid ( expression-or-type )
1357 Pattern = new CodeCompletionString;
1358 Pattern->AddTypedTextChunk("typeid");
1359 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
1360 Pattern->AddPlaceholderChunk("expression-or-type");
1361 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
1362 Results.AddResult(Result(Pattern));
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001363
Douglas Gregorf4c33342010-05-28 00:22:41 +00001364 // new T ( ... )
1365 Pattern = new CodeCompletionString;
1366 Pattern->AddTypedTextChunk("new");
1367 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
1368 Pattern->AddPlaceholderChunk("type");
1369 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
1370 Pattern->AddPlaceholderChunk("expressions");
1371 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
1372 Results.AddResult(Result(Pattern));
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001373
Douglas Gregorf4c33342010-05-28 00:22:41 +00001374 // new T [ ] ( ... )
1375 Pattern = new CodeCompletionString;
1376 Pattern->AddTypedTextChunk("new");
1377 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
1378 Pattern->AddPlaceholderChunk("type");
1379 Pattern->AddChunk(CodeCompletionString::CK_LeftBracket);
1380 Pattern->AddPlaceholderChunk("size");
1381 Pattern->AddChunk(CodeCompletionString::CK_RightBracket);
1382 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
1383 Pattern->AddPlaceholderChunk("expressions");
1384 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
1385 Results.AddResult(Result(Pattern));
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001386
Douglas Gregorf4c33342010-05-28 00:22:41 +00001387 // delete expression
1388 Pattern = new CodeCompletionString;
1389 Pattern->AddTypedTextChunk("delete");
1390 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
1391 Pattern->AddPlaceholderChunk("expression");
1392 Results.AddResult(Result(Pattern));
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001393
Douglas Gregorf4c33342010-05-28 00:22:41 +00001394 // delete [] expression
1395 Pattern = new CodeCompletionString;
1396 Pattern->AddTypedTextChunk("delete");
1397 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
1398 Pattern->AddChunk(CodeCompletionString::CK_LeftBracket);
1399 Pattern->AddChunk(CodeCompletionString::CK_RightBracket);
1400 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
1401 Pattern->AddPlaceholderChunk("expression");
1402 Results.AddResult(Result(Pattern));
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001403
Douglas Gregorf4c33342010-05-28 00:22:41 +00001404 // throw expression
1405 Pattern = new CodeCompletionString;
1406 Pattern->AddTypedTextChunk("throw");
1407 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
1408 Pattern->AddPlaceholderChunk("expression");
1409 Results.AddResult(Result(Pattern));
Douglas Gregora2db7932010-05-26 22:00:08 +00001410
1411 // FIXME: Rethrow?
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001412 }
1413
1414 if (SemaRef.getLangOptions().ObjC1) {
1415 // Add "super", if we're in an Objective-C class with a superclass.
1416 if (ObjCMethodDecl *Method = SemaRef.getCurMethodDecl())
1417 if (Method->getClassInterface()->getSuperClass())
Douglas Gregor78a21012010-01-14 16:01:26 +00001418 Results.AddResult(Result("super"));
Douglas Gregorf1934162010-01-13 21:24:21 +00001419
Douglas Gregorf98e6a22010-01-13 23:51:12 +00001420 AddObjCExpressionResults(Results, true);
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001421 }
1422
Douglas Gregorf4c33342010-05-28 00:22:41 +00001423 // sizeof expression
1424 Pattern = new CodeCompletionString;
1425 Pattern->AddTypedTextChunk("sizeof");
1426 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
1427 Pattern->AddPlaceholderChunk("expression-or-type");
1428 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
1429 Results.AddResult(Result(Pattern));
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001430 break;
1431 }
1432 }
1433
Douglas Gregorf98e6a22010-01-13 23:51:12 +00001434 AddTypeSpecifierResults(SemaRef.getLangOptions(), Results);
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001435
1436 if (SemaRef.getLangOptions().CPlusPlus)
Douglas Gregor78a21012010-01-14 16:01:26 +00001437 Results.AddResult(Result("operator"));
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001438}
1439
Douglas Gregorb3fa9192009-12-18 18:53:37 +00001440/// \brief If the given declaration has an associated type, add it as a result
1441/// type chunk.
1442static void AddResultTypeChunk(ASTContext &Context,
1443 NamedDecl *ND,
1444 CodeCompletionString *Result) {
1445 if (!ND)
1446 return;
1447
1448 // Determine the type of the declaration (if it has a type).
1449 QualType T;
1450 if (FunctionDecl *Function = dyn_cast<FunctionDecl>(ND))
1451 T = Function->getResultType();
1452 else if (ObjCMethodDecl *Method = dyn_cast<ObjCMethodDecl>(ND))
1453 T = Method->getResultType();
1454 else if (FunctionTemplateDecl *FunTmpl = dyn_cast<FunctionTemplateDecl>(ND))
1455 T = FunTmpl->getTemplatedDecl()->getResultType();
1456 else if (EnumConstantDecl *Enumerator = dyn_cast<EnumConstantDecl>(ND))
1457 T = Context.getTypeDeclType(cast<TypeDecl>(Enumerator->getDeclContext()));
1458 else if (isa<UnresolvedUsingValueDecl>(ND)) {
1459 /* Do nothing: ignore unresolved using declarations*/
1460 } else if (ValueDecl *Value = dyn_cast<ValueDecl>(ND))
1461 T = Value->getType();
1462 else if (ObjCPropertyDecl *Property = dyn_cast<ObjCPropertyDecl>(ND))
1463 T = Property->getType();
1464
1465 if (T.isNull() || Context.hasSameType(T, Context.DependentTy))
1466 return;
1467
Douglas Gregorcf04b022010-04-05 21:25:31 +00001468 PrintingPolicy Policy(Context.PrintingPolicy);
1469 Policy.AnonymousTagLocations = false;
1470
Douglas Gregorb3fa9192009-12-18 18:53:37 +00001471 std::string TypeStr;
Douglas Gregorcf04b022010-04-05 21:25:31 +00001472 T.getAsStringInternal(TypeStr, Policy);
Douglas Gregorb3fa9192009-12-18 18:53:37 +00001473 Result->AddResultTypeChunk(TypeStr);
1474}
1475
Douglas Gregor3545ff42009-09-21 16:56:56 +00001476/// \brief Add function parameter chunks to the given code completion string.
1477static void AddFunctionParameterChunks(ASTContext &Context,
1478 FunctionDecl *Function,
1479 CodeCompletionString *Result) {
Douglas Gregor9eb77012009-11-07 00:00:49 +00001480 typedef CodeCompletionString::Chunk Chunk;
1481
Douglas Gregor3545ff42009-09-21 16:56:56 +00001482 CodeCompletionString *CCStr = Result;
1483
1484 for (unsigned P = 0, N = Function->getNumParams(); P != N; ++P) {
1485 ParmVarDecl *Param = Function->getParamDecl(P);
1486
1487 if (Param->hasDefaultArg()) {
1488 // When we see an optional default argument, put that argument and
1489 // the remaining default arguments into a new, optional string.
1490 CodeCompletionString *Opt = new CodeCompletionString;
1491 CCStr->AddOptionalChunk(std::auto_ptr<CodeCompletionString>(Opt));
1492 CCStr = Opt;
1493 }
1494
1495 if (P != 0)
Douglas Gregor9eb77012009-11-07 00:00:49 +00001496 CCStr->AddChunk(Chunk(CodeCompletionString::CK_Comma));
Douglas Gregor3545ff42009-09-21 16:56:56 +00001497
1498 // Format the placeholder string.
1499 std::string PlaceholderStr;
1500 if (Param->getIdentifier())
1501 PlaceholderStr = Param->getIdentifier()->getName();
1502
1503 Param->getType().getAsStringInternal(PlaceholderStr,
1504 Context.PrintingPolicy);
1505
1506 // Add the placeholder string.
Benjamin Kramerb33a97c2009-11-29 20:18:50 +00001507 CCStr->AddPlaceholderChunk(PlaceholderStr);
Douglas Gregor3545ff42009-09-21 16:56:56 +00001508 }
Douglas Gregorba449032009-09-22 21:42:17 +00001509
1510 if (const FunctionProtoType *Proto
1511 = Function->getType()->getAs<FunctionProtoType>())
1512 if (Proto->isVariadic())
1513 CCStr->AddPlaceholderChunk(", ...");
Douglas Gregor3545ff42009-09-21 16:56:56 +00001514}
1515
1516/// \brief Add template parameter chunks to the given code completion string.
1517static void AddTemplateParameterChunks(ASTContext &Context,
1518 TemplateDecl *Template,
1519 CodeCompletionString *Result,
1520 unsigned MaxParameters = 0) {
Douglas Gregor9eb77012009-11-07 00:00:49 +00001521 typedef CodeCompletionString::Chunk Chunk;
1522
Douglas Gregor3545ff42009-09-21 16:56:56 +00001523 CodeCompletionString *CCStr = Result;
1524 bool FirstParameter = true;
1525
1526 TemplateParameterList *Params = Template->getTemplateParameters();
1527 TemplateParameterList::iterator PEnd = Params->end();
1528 if (MaxParameters)
1529 PEnd = Params->begin() + MaxParameters;
1530 for (TemplateParameterList::iterator P = Params->begin(); P != PEnd; ++P) {
1531 bool HasDefaultArg = false;
1532 std::string PlaceholderStr;
1533 if (TemplateTypeParmDecl *TTP = dyn_cast<TemplateTypeParmDecl>(*P)) {
1534 if (TTP->wasDeclaredWithTypename())
1535 PlaceholderStr = "typename";
1536 else
1537 PlaceholderStr = "class";
1538
1539 if (TTP->getIdentifier()) {
1540 PlaceholderStr += ' ';
1541 PlaceholderStr += TTP->getIdentifier()->getName();
1542 }
1543
1544 HasDefaultArg = TTP->hasDefaultArgument();
1545 } else if (NonTypeTemplateParmDecl *NTTP
1546 = dyn_cast<NonTypeTemplateParmDecl>(*P)) {
1547 if (NTTP->getIdentifier())
1548 PlaceholderStr = NTTP->getIdentifier()->getName();
1549 NTTP->getType().getAsStringInternal(PlaceholderStr,
1550 Context.PrintingPolicy);
1551 HasDefaultArg = NTTP->hasDefaultArgument();
1552 } else {
1553 assert(isa<TemplateTemplateParmDecl>(*P));
1554 TemplateTemplateParmDecl *TTP = cast<TemplateTemplateParmDecl>(*P);
1555
1556 // Since putting the template argument list into the placeholder would
1557 // be very, very long, we just use an abbreviation.
1558 PlaceholderStr = "template<...> class";
1559 if (TTP->getIdentifier()) {
1560 PlaceholderStr += ' ';
1561 PlaceholderStr += TTP->getIdentifier()->getName();
1562 }
1563
1564 HasDefaultArg = TTP->hasDefaultArgument();
1565 }
1566
1567 if (HasDefaultArg) {
1568 // When we see an optional default argument, put that argument and
1569 // the remaining default arguments into a new, optional string.
1570 CodeCompletionString *Opt = new CodeCompletionString;
1571 CCStr->AddOptionalChunk(std::auto_ptr<CodeCompletionString>(Opt));
1572 CCStr = Opt;
1573 }
1574
1575 if (FirstParameter)
1576 FirstParameter = false;
1577 else
Douglas Gregor9eb77012009-11-07 00:00:49 +00001578 CCStr->AddChunk(Chunk(CodeCompletionString::CK_Comma));
Douglas Gregor3545ff42009-09-21 16:56:56 +00001579
1580 // Add the placeholder string.
Benjamin Kramerb33a97c2009-11-29 20:18:50 +00001581 CCStr->AddPlaceholderChunk(PlaceholderStr);
Douglas Gregor3545ff42009-09-21 16:56:56 +00001582 }
1583}
1584
Douglas Gregorf2510672009-09-21 19:57:38 +00001585/// \brief Add a qualifier to the given code-completion string, if the
1586/// provided nested-name-specifier is non-NULL.
Douglas Gregor0f622362009-12-11 18:44:16 +00001587static void
1588AddQualifierToCompletionString(CodeCompletionString *Result,
1589 NestedNameSpecifier *Qualifier,
1590 bool QualifierIsInformative,
1591 ASTContext &Context) {
Douglas Gregorf2510672009-09-21 19:57:38 +00001592 if (!Qualifier)
1593 return;
1594
1595 std::string PrintedNNS;
1596 {
1597 llvm::raw_string_ostream OS(PrintedNNS);
1598 Qualifier->print(OS, Context.PrintingPolicy);
1599 }
Douglas Gregor5bf52692009-09-22 23:15:58 +00001600 if (QualifierIsInformative)
Benjamin Kramerb33a97c2009-11-29 20:18:50 +00001601 Result->AddInformativeChunk(PrintedNNS);
Douglas Gregor5bf52692009-09-22 23:15:58 +00001602 else
Benjamin Kramerb33a97c2009-11-29 20:18:50 +00001603 Result->AddTextChunk(PrintedNNS);
Douglas Gregorf2510672009-09-21 19:57:38 +00001604}
1605
Douglas Gregor0f622362009-12-11 18:44:16 +00001606static void AddFunctionTypeQualsToCompletionString(CodeCompletionString *Result,
1607 FunctionDecl *Function) {
1608 const FunctionProtoType *Proto
1609 = Function->getType()->getAs<FunctionProtoType>();
1610 if (!Proto || !Proto->getTypeQuals())
1611 return;
1612
1613 std::string QualsStr;
1614 if (Proto->getTypeQuals() & Qualifiers::Const)
1615 QualsStr += " const";
1616 if (Proto->getTypeQuals() & Qualifiers::Volatile)
1617 QualsStr += " volatile";
1618 if (Proto->getTypeQuals() & Qualifiers::Restrict)
1619 QualsStr += " restrict";
1620 Result->AddInformativeChunk(QualsStr);
1621}
1622
Douglas Gregor3545ff42009-09-21 16:56:56 +00001623/// \brief If possible, create a new code completion string for the given
1624/// result.
1625///
1626/// \returns Either a new, heap-allocated code completion string describing
1627/// how to use this result, or NULL to indicate that the string or name of the
1628/// result is all that is needed.
1629CodeCompletionString *
1630CodeCompleteConsumer::Result::CreateCodeCompletionString(Sema &S) {
Douglas Gregor9eb77012009-11-07 00:00:49 +00001631 typedef CodeCompletionString::Chunk Chunk;
1632
Douglas Gregorf09935f2009-12-01 05:55:20 +00001633 if (Kind == RK_Pattern)
1634 return Pattern->Clone();
1635
1636 CodeCompletionString *Result = new CodeCompletionString;
1637
1638 if (Kind == RK_Keyword) {
1639 Result->AddTypedTextChunk(Keyword);
1640 return Result;
1641 }
Douglas Gregor3545ff42009-09-21 16:56:56 +00001642
Douglas Gregorf329c7c2009-10-30 16:50:04 +00001643 if (Kind == RK_Macro) {
1644 MacroInfo *MI = S.PP.getMacroInfo(Macro);
Douglas Gregorf09935f2009-12-01 05:55:20 +00001645 assert(MI && "Not a macro?");
1646
1647 Result->AddTypedTextChunk(Macro->getName());
1648
1649 if (!MI->isFunctionLike())
1650 return Result;
Douglas Gregorf329c7c2009-10-30 16:50:04 +00001651
1652 // Format a function-like macro with placeholders for the arguments.
Douglas Gregor9eb77012009-11-07 00:00:49 +00001653 Result->AddChunk(Chunk(CodeCompletionString::CK_LeftParen));
Douglas Gregorf329c7c2009-10-30 16:50:04 +00001654 for (MacroInfo::arg_iterator A = MI->arg_begin(), AEnd = MI->arg_end();
1655 A != AEnd; ++A) {
1656 if (A != MI->arg_begin())
Douglas Gregor9eb77012009-11-07 00:00:49 +00001657 Result->AddChunk(Chunk(CodeCompletionString::CK_Comma));
Douglas Gregorf329c7c2009-10-30 16:50:04 +00001658
1659 if (!MI->isVariadic() || A != AEnd - 1) {
1660 // Non-variadic argument.
Benjamin Kramerb33a97c2009-11-29 20:18:50 +00001661 Result->AddPlaceholderChunk((*A)->getName());
Douglas Gregorf329c7c2009-10-30 16:50:04 +00001662 continue;
1663 }
1664
1665 // Variadic argument; cope with the different between GNU and C99
1666 // variadic macros, providing a single placeholder for the rest of the
1667 // arguments.
1668 if ((*A)->isStr("__VA_ARGS__"))
1669 Result->AddPlaceholderChunk("...");
1670 else {
1671 std::string Arg = (*A)->getName();
1672 Arg += "...";
Benjamin Kramerb33a97c2009-11-29 20:18:50 +00001673 Result->AddPlaceholderChunk(Arg);
Douglas Gregorf329c7c2009-10-30 16:50:04 +00001674 }
1675 }
Douglas Gregor9eb77012009-11-07 00:00:49 +00001676 Result->AddChunk(Chunk(CodeCompletionString::CK_RightParen));
Douglas Gregorf329c7c2009-10-30 16:50:04 +00001677 return Result;
1678 }
1679
Douglas Gregorf64acca2010-05-25 21:41:55 +00001680 assert(Kind == RK_Declaration && "Missed a result kind?");
Douglas Gregor3545ff42009-09-21 16:56:56 +00001681 NamedDecl *ND = Declaration;
1682
Douglas Gregor9eb77012009-11-07 00:00:49 +00001683 if (StartsNestedNameSpecifier) {
Benjamin Kramerb33a97c2009-11-29 20:18:50 +00001684 Result->AddTypedTextChunk(ND->getNameAsString());
Douglas Gregor9eb77012009-11-07 00:00:49 +00001685 Result->AddTextChunk("::");
1686 return Result;
1687 }
1688
Douglas Gregorb3fa9192009-12-18 18:53:37 +00001689 AddResultTypeChunk(S.Context, ND, Result);
1690
Douglas Gregor3545ff42009-09-21 16:56:56 +00001691 if (FunctionDecl *Function = dyn_cast<FunctionDecl>(ND)) {
Douglas Gregor5bf52692009-09-22 23:15:58 +00001692 AddQualifierToCompletionString(Result, Qualifier, QualifierIsInformative,
1693 S.Context);
Benjamin Kramerb33a97c2009-11-29 20:18:50 +00001694 Result->AddTypedTextChunk(Function->getNameAsString());
Douglas Gregor9eb77012009-11-07 00:00:49 +00001695 Result->AddChunk(Chunk(CodeCompletionString::CK_LeftParen));
Douglas Gregor3545ff42009-09-21 16:56:56 +00001696 AddFunctionParameterChunks(S.Context, Function, Result);
Douglas Gregor9eb77012009-11-07 00:00:49 +00001697 Result->AddChunk(Chunk(CodeCompletionString::CK_RightParen));
Douglas Gregor0f622362009-12-11 18:44:16 +00001698 AddFunctionTypeQualsToCompletionString(Result, Function);
Douglas Gregor3545ff42009-09-21 16:56:56 +00001699 return Result;
1700 }
1701
1702 if (FunctionTemplateDecl *FunTmpl = dyn_cast<FunctionTemplateDecl>(ND)) {
Douglas Gregor5bf52692009-09-22 23:15:58 +00001703 AddQualifierToCompletionString(Result, Qualifier, QualifierIsInformative,
1704 S.Context);
Douglas Gregor3545ff42009-09-21 16:56:56 +00001705 FunctionDecl *Function = FunTmpl->getTemplatedDecl();
Benjamin Kramerb33a97c2009-11-29 20:18:50 +00001706 Result->AddTypedTextChunk(Function->getNameAsString());
Douglas Gregor3545ff42009-09-21 16:56:56 +00001707
1708 // Figure out which template parameters are deduced (or have default
1709 // arguments).
1710 llvm::SmallVector<bool, 16> Deduced;
1711 S.MarkDeducedTemplateParameters(FunTmpl, Deduced);
1712 unsigned LastDeducibleArgument;
1713 for (LastDeducibleArgument = Deduced.size(); LastDeducibleArgument > 0;
1714 --LastDeducibleArgument) {
1715 if (!Deduced[LastDeducibleArgument - 1]) {
1716 // C++0x: Figure out if the template argument has a default. If so,
1717 // the user doesn't need to type this argument.
1718 // FIXME: We need to abstract template parameters better!
1719 bool HasDefaultArg = false;
1720 NamedDecl *Param = FunTmpl->getTemplateParameters()->getParam(
1721 LastDeducibleArgument - 1);
1722 if (TemplateTypeParmDecl *TTP = dyn_cast<TemplateTypeParmDecl>(Param))
1723 HasDefaultArg = TTP->hasDefaultArgument();
1724 else if (NonTypeTemplateParmDecl *NTTP
1725 = dyn_cast<NonTypeTemplateParmDecl>(Param))
1726 HasDefaultArg = NTTP->hasDefaultArgument();
1727 else {
1728 assert(isa<TemplateTemplateParmDecl>(Param));
1729 HasDefaultArg
Douglas Gregor9eb77012009-11-07 00:00:49 +00001730 = cast<TemplateTemplateParmDecl>(Param)->hasDefaultArgument();
Douglas Gregor3545ff42009-09-21 16:56:56 +00001731 }
1732
1733 if (!HasDefaultArg)
1734 break;
1735 }
1736 }
1737
1738 if (LastDeducibleArgument) {
1739 // Some of the function template arguments cannot be deduced from a
1740 // function call, so we introduce an explicit template argument list
1741 // containing all of the arguments up to the first deducible argument.
Douglas Gregor9eb77012009-11-07 00:00:49 +00001742 Result->AddChunk(Chunk(CodeCompletionString::CK_LeftAngle));
Douglas Gregor3545ff42009-09-21 16:56:56 +00001743 AddTemplateParameterChunks(S.Context, FunTmpl, Result,
1744 LastDeducibleArgument);
Douglas Gregor9eb77012009-11-07 00:00:49 +00001745 Result->AddChunk(Chunk(CodeCompletionString::CK_RightAngle));
Douglas Gregor3545ff42009-09-21 16:56:56 +00001746 }
1747
1748 // Add the function parameters
Douglas Gregor9eb77012009-11-07 00:00:49 +00001749 Result->AddChunk(Chunk(CodeCompletionString::CK_LeftParen));
Douglas Gregor3545ff42009-09-21 16:56:56 +00001750 AddFunctionParameterChunks(S.Context, Function, Result);
Douglas Gregor9eb77012009-11-07 00:00:49 +00001751 Result->AddChunk(Chunk(CodeCompletionString::CK_RightParen));
Douglas Gregor0f622362009-12-11 18:44:16 +00001752 AddFunctionTypeQualsToCompletionString(Result, Function);
Douglas Gregor3545ff42009-09-21 16:56:56 +00001753 return Result;
1754 }
1755
1756 if (TemplateDecl *Template = dyn_cast<TemplateDecl>(ND)) {
Douglas Gregor5bf52692009-09-22 23:15:58 +00001757 AddQualifierToCompletionString(Result, Qualifier, QualifierIsInformative,
1758 S.Context);
Benjamin Kramerb33a97c2009-11-29 20:18:50 +00001759 Result->AddTypedTextChunk(Template->getNameAsString());
Douglas Gregor9eb77012009-11-07 00:00:49 +00001760 Result->AddChunk(Chunk(CodeCompletionString::CK_LeftAngle));
Douglas Gregor3545ff42009-09-21 16:56:56 +00001761 AddTemplateParameterChunks(S.Context, Template, Result);
Douglas Gregor9eb77012009-11-07 00:00:49 +00001762 Result->AddChunk(Chunk(CodeCompletionString::CK_RightAngle));
Douglas Gregor3545ff42009-09-21 16:56:56 +00001763 return Result;
1764 }
1765
Douglas Gregord3c5d792009-11-17 16:44:22 +00001766 if (ObjCMethodDecl *Method = dyn_cast<ObjCMethodDecl>(ND)) {
Douglas Gregord3c5d792009-11-17 16:44:22 +00001767 Selector Sel = Method->getSelector();
1768 if (Sel.isUnarySelector()) {
1769 Result->AddTypedTextChunk(Sel.getIdentifierInfoForSlot(0)->getName());
1770 return Result;
1771 }
1772
Douglas Gregor1b605f72009-11-19 01:08:35 +00001773 std::string SelName = Sel.getIdentifierInfoForSlot(0)->getName().str();
1774 SelName += ':';
1775 if (StartParameter == 0)
1776 Result->AddTypedTextChunk(SelName);
1777 else {
1778 Result->AddInformativeChunk(SelName);
1779
1780 // If there is only one parameter, and we're past it, add an empty
1781 // typed-text chunk since there is nothing to type.
1782 if (Method->param_size() == 1)
1783 Result->AddTypedTextChunk("");
1784 }
Douglas Gregord3c5d792009-11-17 16:44:22 +00001785 unsigned Idx = 0;
1786 for (ObjCMethodDecl::param_iterator P = Method->param_begin(),
1787 PEnd = Method->param_end();
1788 P != PEnd; (void)++P, ++Idx) {
1789 if (Idx > 0) {
Douglas Gregor1b605f72009-11-19 01:08:35 +00001790 std::string Keyword;
1791 if (Idx > StartParameter)
Douglas Gregor6a803932010-01-12 06:38:28 +00001792 Result->AddChunk(CodeCompletionString::CK_HorizontalSpace);
Douglas Gregord3c5d792009-11-17 16:44:22 +00001793 if (IdentifierInfo *II = Sel.getIdentifierInfoForSlot(Idx))
1794 Keyword += II->getName().str();
1795 Keyword += ":";
Douglas Gregorc8537c52009-11-19 07:41:15 +00001796 if (Idx < StartParameter || AllParametersAreInformative) {
Douglas Gregor1b605f72009-11-19 01:08:35 +00001797 Result->AddInformativeChunk(Keyword);
1798 } else if (Idx == StartParameter)
1799 Result->AddTypedTextChunk(Keyword);
1800 else
1801 Result->AddTextChunk(Keyword);
Douglas Gregord3c5d792009-11-17 16:44:22 +00001802 }
Douglas Gregor1b605f72009-11-19 01:08:35 +00001803
1804 // If we're before the starting parameter, skip the placeholder.
1805 if (Idx < StartParameter)
1806 continue;
Douglas Gregord3c5d792009-11-17 16:44:22 +00001807
1808 std::string Arg;
1809 (*P)->getType().getAsStringInternal(Arg, S.Context.PrintingPolicy);
1810 Arg = "(" + Arg + ")";
1811 if (IdentifierInfo *II = (*P)->getIdentifier())
1812 Arg += II->getName().str();
Douglas Gregorc8537c52009-11-19 07:41:15 +00001813 if (AllParametersAreInformative)
1814 Result->AddInformativeChunk(Arg);
1815 else
1816 Result->AddPlaceholderChunk(Arg);
Douglas Gregord3c5d792009-11-17 16:44:22 +00001817 }
1818
Douglas Gregor04c5f972009-12-23 00:21:46 +00001819 if (Method->isVariadic()) {
1820 if (AllParametersAreInformative)
1821 Result->AddInformativeChunk(", ...");
1822 else
1823 Result->AddPlaceholderChunk(", ...");
1824 }
1825
Douglas Gregord3c5d792009-11-17 16:44:22 +00001826 return Result;
1827 }
1828
Douglas Gregorf09935f2009-12-01 05:55:20 +00001829 if (Qualifier)
Douglas Gregor5bf52692009-09-22 23:15:58 +00001830 AddQualifierToCompletionString(Result, Qualifier, QualifierIsInformative,
1831 S.Context);
Douglas Gregorf09935f2009-12-01 05:55:20 +00001832
1833 Result->AddTypedTextChunk(ND->getNameAsString());
1834 return Result;
Douglas Gregor3545ff42009-09-21 16:56:56 +00001835}
1836
Douglas Gregorf0f51982009-09-23 00:34:09 +00001837CodeCompletionString *
1838CodeCompleteConsumer::OverloadCandidate::CreateSignatureString(
1839 unsigned CurrentArg,
1840 Sema &S) const {
Douglas Gregor9eb77012009-11-07 00:00:49 +00001841 typedef CodeCompletionString::Chunk Chunk;
1842
Douglas Gregorf0f51982009-09-23 00:34:09 +00001843 CodeCompletionString *Result = new CodeCompletionString;
1844 FunctionDecl *FDecl = getFunction();
Douglas Gregorb3fa9192009-12-18 18:53:37 +00001845 AddResultTypeChunk(S.Context, FDecl, Result);
Douglas Gregorf0f51982009-09-23 00:34:09 +00001846 const FunctionProtoType *Proto
1847 = dyn_cast<FunctionProtoType>(getFunctionType());
1848 if (!FDecl && !Proto) {
1849 // Function without a prototype. Just give the return type and a
1850 // highlighted ellipsis.
1851 const FunctionType *FT = getFunctionType();
1852 Result->AddTextChunk(
Benjamin Kramerb33a97c2009-11-29 20:18:50 +00001853 FT->getResultType().getAsString(S.Context.PrintingPolicy));
Douglas Gregor9eb77012009-11-07 00:00:49 +00001854 Result->AddChunk(Chunk(CodeCompletionString::CK_LeftParen));
1855 Result->AddChunk(Chunk(CodeCompletionString::CK_CurrentParameter, "..."));
1856 Result->AddChunk(Chunk(CodeCompletionString::CK_RightParen));
Douglas Gregorf0f51982009-09-23 00:34:09 +00001857 return Result;
1858 }
1859
1860 if (FDecl)
Benjamin Kramerb33a97c2009-11-29 20:18:50 +00001861 Result->AddTextChunk(FDecl->getNameAsString());
Douglas Gregorf0f51982009-09-23 00:34:09 +00001862 else
1863 Result->AddTextChunk(
Benjamin Kramerb33a97c2009-11-29 20:18:50 +00001864 Proto->getResultType().getAsString(S.Context.PrintingPolicy));
Douglas Gregorf0f51982009-09-23 00:34:09 +00001865
Douglas Gregor9eb77012009-11-07 00:00:49 +00001866 Result->AddChunk(Chunk(CodeCompletionString::CK_LeftParen));
Douglas Gregorf0f51982009-09-23 00:34:09 +00001867 unsigned NumParams = FDecl? FDecl->getNumParams() : Proto->getNumArgs();
1868 for (unsigned I = 0; I != NumParams; ++I) {
1869 if (I)
Douglas Gregor9eb77012009-11-07 00:00:49 +00001870 Result->AddChunk(Chunk(CodeCompletionString::CK_Comma));
Douglas Gregorf0f51982009-09-23 00:34:09 +00001871
1872 std::string ArgString;
1873 QualType ArgType;
1874
1875 if (FDecl) {
1876 ArgString = FDecl->getParamDecl(I)->getNameAsString();
1877 ArgType = FDecl->getParamDecl(I)->getOriginalType();
1878 } else {
1879 ArgType = Proto->getArgType(I);
1880 }
1881
1882 ArgType.getAsStringInternal(ArgString, S.Context.PrintingPolicy);
1883
1884 if (I == CurrentArg)
Douglas Gregor9eb77012009-11-07 00:00:49 +00001885 Result->AddChunk(Chunk(CodeCompletionString::CK_CurrentParameter,
Benjamin Kramerb33a97c2009-11-29 20:18:50 +00001886 ArgString));
Douglas Gregorf0f51982009-09-23 00:34:09 +00001887 else
Benjamin Kramerb33a97c2009-11-29 20:18:50 +00001888 Result->AddTextChunk(ArgString);
Douglas Gregorf0f51982009-09-23 00:34:09 +00001889 }
1890
1891 if (Proto && Proto->isVariadic()) {
Douglas Gregor9eb77012009-11-07 00:00:49 +00001892 Result->AddChunk(Chunk(CodeCompletionString::CK_Comma));
Douglas Gregorf0f51982009-09-23 00:34:09 +00001893 if (CurrentArg < NumParams)
1894 Result->AddTextChunk("...");
1895 else
Douglas Gregor9eb77012009-11-07 00:00:49 +00001896 Result->AddChunk(Chunk(CodeCompletionString::CK_CurrentParameter, "..."));
Douglas Gregorf0f51982009-09-23 00:34:09 +00001897 }
Douglas Gregor9eb77012009-11-07 00:00:49 +00001898 Result->AddChunk(Chunk(CodeCompletionString::CK_RightParen));
Douglas Gregorf0f51982009-09-23 00:34:09 +00001899
1900 return Result;
1901}
1902
Douglas Gregor3545ff42009-09-21 16:56:56 +00001903namespace {
1904 struct SortCodeCompleteResult {
1905 typedef CodeCompleteConsumer::Result Result;
1906
Douglas Gregore6688e62009-09-28 03:51:44 +00001907 bool isEarlierDeclarationName(DeclarationName X, DeclarationName Y) const {
Douglas Gregor249d6822009-12-05 09:08:56 +00001908 Selector XSel = X.getObjCSelector();
1909 Selector YSel = Y.getObjCSelector();
1910 if (!XSel.isNull() && !YSel.isNull()) {
1911 // We are comparing two selectors.
1912 unsigned N = std::min(XSel.getNumArgs(), YSel.getNumArgs());
1913 if (N == 0)
1914 ++N;
1915 for (unsigned I = 0; I != N; ++I) {
1916 IdentifierInfo *XId = XSel.getIdentifierInfoForSlot(I);
1917 IdentifierInfo *YId = YSel.getIdentifierInfoForSlot(I);
1918 if (!XId || !YId)
1919 return XId && !YId;
1920
1921 switch (XId->getName().compare_lower(YId->getName())) {
1922 case -1: return true;
1923 case 1: return false;
1924 default: break;
1925 }
1926 }
1927
1928 return XSel.getNumArgs() < YSel.getNumArgs();
1929 }
1930
1931 // For non-selectors, order by kind.
1932 if (X.getNameKind() != Y.getNameKind())
Douglas Gregore6688e62009-09-28 03:51:44 +00001933 return X.getNameKind() < Y.getNameKind();
1934
Douglas Gregor249d6822009-12-05 09:08:56 +00001935 // Order identifiers by comparison of their lowercased names.
1936 if (IdentifierInfo *XId = X.getAsIdentifierInfo())
1937 return XId->getName().compare_lower(
1938 Y.getAsIdentifierInfo()->getName()) < 0;
1939
1940 // Order overloaded operators by the order in which they appear
1941 // in our list of operators.
1942 if (OverloadedOperatorKind XOp = X.getCXXOverloadedOperator())
1943 return XOp < Y.getCXXOverloadedOperator();
1944
1945 // Order C++0x user-defined literal operators lexically by their
1946 // lowercased suffixes.
1947 if (IdentifierInfo *XLit = X.getCXXLiteralIdentifier())
1948 return XLit->getName().compare_lower(
1949 Y.getCXXLiteralIdentifier()->getName()) < 0;
1950
1951 // The only stable ordering we have is to turn the name into a
1952 // string and then compare the lower-case strings. This is
1953 // inefficient, but thankfully does not happen too often.
Benjamin Kramer4053e5d2009-12-05 10:22:15 +00001954 return llvm::StringRef(X.getAsString()).compare_lower(
1955 Y.getAsString()) < 0;
Douglas Gregore6688e62009-09-28 03:51:44 +00001956 }
1957
Douglas Gregor52ce62f2010-01-13 23:24:38 +00001958 /// \brief Retrieve the name that should be used to order a result.
1959 ///
1960 /// If the name needs to be constructed as a string, that string will be
1961 /// saved into Saved and the returned StringRef will refer to it.
1962 static llvm::StringRef getOrderedName(const Result &R,
1963 std::string &Saved) {
1964 switch (R.Kind) {
1965 case Result::RK_Keyword:
1966 return R.Keyword;
1967
1968 case Result::RK_Pattern:
1969 return R.Pattern->getTypedText();
1970
1971 case Result::RK_Macro:
1972 return R.Macro->getName();
1973
1974 case Result::RK_Declaration:
1975 // Handle declarations below.
1976 break;
Douglas Gregor45f83ee2009-11-19 00:01:57 +00001977 }
Douglas Gregor52ce62f2010-01-13 23:24:38 +00001978
1979 DeclarationName Name = R.Declaration->getDeclName();
Douglas Gregor45f83ee2009-11-19 00:01:57 +00001980
Douglas Gregor52ce62f2010-01-13 23:24:38 +00001981 // If the name is a simple identifier (by far the common case), or a
1982 // zero-argument selector, just return a reference to that identifier.
1983 if (IdentifierInfo *Id = Name.getAsIdentifierInfo())
1984 return Id->getName();
1985 if (Name.isObjCZeroArgSelector())
1986 if (IdentifierInfo *Id
1987 = Name.getObjCSelector().getIdentifierInfoForSlot(0))
1988 return Id->getName();
1989
1990 Saved = Name.getAsString();
1991 return Saved;
1992 }
1993
1994 bool operator()(const Result &X, const Result &Y) const {
1995 std::string XSaved, YSaved;
1996 llvm::StringRef XStr = getOrderedName(X, XSaved);
1997 llvm::StringRef YStr = getOrderedName(Y, YSaved);
1998 int cmp = XStr.compare_lower(YStr);
1999 if (cmp)
2000 return cmp < 0;
Douglas Gregor3545ff42009-09-21 16:56:56 +00002001
2002 // Non-hidden names precede hidden names.
2003 if (X.Hidden != Y.Hidden)
2004 return !X.Hidden;
2005
Douglas Gregore412a5a2009-09-23 22:26:46 +00002006 // Non-nested-name-specifiers precede nested-name-specifiers.
2007 if (X.StartsNestedNameSpecifier != Y.StartsNestedNameSpecifier)
2008 return !X.StartsNestedNameSpecifier;
2009
Douglas Gregor3545ff42009-09-21 16:56:56 +00002010 return false;
2011 }
2012 };
2013}
2014
Douglas Gregorf98e6a22010-01-13 23:51:12 +00002015static void AddMacroResults(Preprocessor &PP, ResultBuilder &Results) {
Douglas Gregorf329c7c2009-10-30 16:50:04 +00002016 Results.EnterNewScope();
Douglas Gregor9eb77012009-11-07 00:00:49 +00002017 for (Preprocessor::macro_iterator M = PP.macro_begin(),
2018 MEnd = PP.macro_end();
Douglas Gregorf329c7c2009-10-30 16:50:04 +00002019 M != MEnd; ++M)
Douglas Gregor78a21012010-01-14 16:01:26 +00002020 Results.AddResult(M->first);
Douglas Gregorf329c7c2009-10-30 16:50:04 +00002021 Results.ExitScope();
2022}
2023
Daniel Dunbar242ea9a2009-11-13 08:58:20 +00002024static void HandleCodeCompleteResults(Sema *S,
2025 CodeCompleteConsumer *CodeCompleter,
2026 CodeCompleteConsumer::Result *Results,
2027 unsigned NumResults) {
Douglas Gregor3545ff42009-09-21 16:56:56 +00002028 std::stable_sort(Results, Results + NumResults, SortCodeCompleteResult());
2029
2030 if (CodeCompleter)
Daniel Dunbar242ea9a2009-11-13 08:58:20 +00002031 CodeCompleter->ProcessCodeCompleteResults(*S, Results, NumResults);
Douglas Gregor45f83ee2009-11-19 00:01:57 +00002032
2033 for (unsigned I = 0; I != NumResults; ++I)
2034 Results[I].Destroy();
Douglas Gregor3545ff42009-09-21 16:56:56 +00002035}
2036
Douglas Gregor504a6ae2010-01-10 23:08:15 +00002037void Sema::CodeCompleteOrdinaryName(Scope *S,
2038 CodeCompletionContext CompletionContext) {
Douglas Gregor92253692009-12-07 09:54:55 +00002039 typedef CodeCompleteConsumer::Result Result;
Douglas Gregor504a6ae2010-01-10 23:08:15 +00002040 ResultBuilder Results(*this);
2041
2042 // Determine how to filter results, e.g., so that the names of
2043 // values (functions, enumerators, function templates, etc.) are
2044 // only allowed where we can have an expression.
2045 switch (CompletionContext) {
2046 case CCC_Namespace:
2047 case CCC_Class:
Douglas Gregorf1934162010-01-13 21:24:21 +00002048 case CCC_ObjCInterface:
2049 case CCC_ObjCImplementation:
Douglas Gregor48d46252010-01-13 21:54:15 +00002050 case CCC_ObjCInstanceVariableList:
Douglas Gregor504a6ae2010-01-10 23:08:15 +00002051 case CCC_Template:
2052 case CCC_MemberTemplate:
2053 Results.setFilter(&ResultBuilder::IsOrdinaryNonValueName);
2054 break;
2055
2056 case CCC_Expression:
2057 case CCC_Statement:
2058 case CCC_ForInit:
2059 case CCC_Condition:
2060 Results.setFilter(&ResultBuilder::IsOrdinaryName);
2061 break;
Douglas Gregor6da3db42010-05-25 05:58:43 +00002062
2063 case CCC_RecoveryInFunction:
2064 // Unfiltered
2065 break;
Douglas Gregor504a6ae2010-01-10 23:08:15 +00002066 }
2067
Douglas Gregorc580c522010-01-14 01:09:38 +00002068 CodeCompletionDeclConsumer Consumer(Results, CurContext);
2069 LookupVisibleDecls(S, LookupOrdinaryName, Consumer);
Douglas Gregor92253692009-12-07 09:54:55 +00002070
2071 Results.EnterNewScope();
Douglas Gregorf98e6a22010-01-13 23:51:12 +00002072 AddOrdinaryNameResults(CompletionContext, S, *this, Results);
Douglas Gregor92253692009-12-07 09:54:55 +00002073 Results.ExitScope();
2074
Douglas Gregor9eb77012009-11-07 00:00:49 +00002075 if (CodeCompleter->includeMacros())
Douglas Gregorf98e6a22010-01-13 23:51:12 +00002076 AddMacroResults(PP, Results);
Daniel Dunbar242ea9a2009-11-13 08:58:20 +00002077 HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
Douglas Gregor9d64c5e2009-09-21 20:51:25 +00002078}
2079
Douglas Gregor9291bad2009-11-18 01:29:26 +00002080static void AddObjCProperties(ObjCContainerDecl *Container,
Douglas Gregor5d649882009-11-18 22:32:06 +00002081 bool AllowCategories,
Douglas Gregor9291bad2009-11-18 01:29:26 +00002082 DeclContext *CurContext,
2083 ResultBuilder &Results) {
2084 typedef CodeCompleteConsumer::Result Result;
2085
2086 // Add properties in this container.
2087 for (ObjCContainerDecl::prop_iterator P = Container->prop_begin(),
2088 PEnd = Container->prop_end();
2089 P != PEnd;
2090 ++P)
2091 Results.MaybeAddResult(Result(*P, 0), CurContext);
2092
2093 // Add properties in referenced protocols.
2094 if (ObjCProtocolDecl *Protocol = dyn_cast<ObjCProtocolDecl>(Container)) {
2095 for (ObjCProtocolDecl::protocol_iterator P = Protocol->protocol_begin(),
2096 PEnd = Protocol->protocol_end();
2097 P != PEnd; ++P)
Douglas Gregor5d649882009-11-18 22:32:06 +00002098 AddObjCProperties(*P, AllowCategories, CurContext, Results);
Douglas Gregor9291bad2009-11-18 01:29:26 +00002099 } else if (ObjCInterfaceDecl *IFace = dyn_cast<ObjCInterfaceDecl>(Container)){
Douglas Gregor5d649882009-11-18 22:32:06 +00002100 if (AllowCategories) {
2101 // Look through categories.
2102 for (ObjCCategoryDecl *Category = IFace->getCategoryList();
2103 Category; Category = Category->getNextClassCategory())
2104 AddObjCProperties(Category, AllowCategories, CurContext, Results);
2105 }
Douglas Gregor9291bad2009-11-18 01:29:26 +00002106
2107 // Look through protocols.
2108 for (ObjCInterfaceDecl::protocol_iterator I = IFace->protocol_begin(),
2109 E = IFace->protocol_end();
2110 I != E; ++I)
Douglas Gregor5d649882009-11-18 22:32:06 +00002111 AddObjCProperties(*I, AllowCategories, CurContext, Results);
Douglas Gregor9291bad2009-11-18 01:29:26 +00002112
2113 // Look in the superclass.
2114 if (IFace->getSuperClass())
Douglas Gregor5d649882009-11-18 22:32:06 +00002115 AddObjCProperties(IFace->getSuperClass(), AllowCategories, CurContext,
2116 Results);
Douglas Gregor9291bad2009-11-18 01:29:26 +00002117 } else if (const ObjCCategoryDecl *Category
2118 = dyn_cast<ObjCCategoryDecl>(Container)) {
2119 // Look through protocols.
2120 for (ObjCInterfaceDecl::protocol_iterator P = Category->protocol_begin(),
2121 PEnd = Category->protocol_end();
2122 P != PEnd; ++P)
Douglas Gregor5d649882009-11-18 22:32:06 +00002123 AddObjCProperties(*P, AllowCategories, CurContext, Results);
Douglas Gregor9291bad2009-11-18 01:29:26 +00002124 }
2125}
2126
Douglas Gregor2436e712009-09-17 21:32:03 +00002127void Sema::CodeCompleteMemberReferenceExpr(Scope *S, ExprTy *BaseE,
2128 SourceLocation OpLoc,
2129 bool IsArrow) {
2130 if (!BaseE || !CodeCompleter)
2131 return;
2132
Douglas Gregor3545ff42009-09-21 16:56:56 +00002133 typedef CodeCompleteConsumer::Result Result;
2134
Douglas Gregor2436e712009-09-17 21:32:03 +00002135 Expr *Base = static_cast<Expr *>(BaseE);
2136 QualType BaseType = Base->getType();
Douglas Gregor3545ff42009-09-21 16:56:56 +00002137
2138 if (IsArrow) {
2139 if (const PointerType *Ptr = BaseType->getAs<PointerType>())
2140 BaseType = Ptr->getPointeeType();
2141 else if (BaseType->isObjCObjectPointerType())
2142 /*Do nothing*/ ;
2143 else
2144 return;
2145 }
2146
Douglas Gregore412a5a2009-09-23 22:26:46 +00002147 ResultBuilder Results(*this, &ResultBuilder::IsMember);
Douglas Gregor9291bad2009-11-18 01:29:26 +00002148 Results.EnterNewScope();
2149 if (const RecordType *Record = BaseType->getAs<RecordType>()) {
2150 // Access to a C/C++ class, struct, or union.
Douglas Gregor6ae4c522010-01-14 03:21:49 +00002151 Results.allowNestedNameSpecifiers();
Douglas Gregor09bbc652010-01-14 15:47:35 +00002152 CodeCompletionDeclConsumer Consumer(Results, CurContext);
2153 LookupVisibleDecls(Record->getDecl(), LookupMemberName, Consumer);
Daniel Dunbar242ea9a2009-11-13 08:58:20 +00002154
Douglas Gregor9291bad2009-11-18 01:29:26 +00002155 if (getLangOptions().CPlusPlus) {
2156 if (!Results.empty()) {
2157 // The "template" keyword can follow "->" or "." in the grammar.
2158 // However, we only want to suggest the template keyword if something
2159 // is dependent.
2160 bool IsDependent = BaseType->isDependentType();
2161 if (!IsDependent) {
2162 for (Scope *DepScope = S; DepScope; DepScope = DepScope->getParent())
2163 if (DeclContext *Ctx = (DeclContext *)DepScope->getEntity()) {
2164 IsDependent = Ctx->isDependentContext();
2165 break;
2166 }
2167 }
Daniel Dunbar242ea9a2009-11-13 08:58:20 +00002168
Douglas Gregor9291bad2009-11-18 01:29:26 +00002169 if (IsDependent)
Douglas Gregor78a21012010-01-14 16:01:26 +00002170 Results.AddResult(Result("template"));
Daniel Dunbar242ea9a2009-11-13 08:58:20 +00002171 }
Daniel Dunbar242ea9a2009-11-13 08:58:20 +00002172 }
Douglas Gregor9291bad2009-11-18 01:29:26 +00002173 } else if (!IsArrow && BaseType->getAsObjCInterfacePointerType()) {
2174 // Objective-C property reference.
2175
2176 // Add property results based on our interface.
2177 const ObjCObjectPointerType *ObjCPtr
2178 = BaseType->getAsObjCInterfacePointerType();
2179 assert(ObjCPtr && "Non-NULL pointer guaranteed above!");
Douglas Gregor5d649882009-11-18 22:32:06 +00002180 AddObjCProperties(ObjCPtr->getInterfaceDecl(), true, CurContext, Results);
Douglas Gregor9291bad2009-11-18 01:29:26 +00002181
2182 // Add properties from the protocols in a qualified interface.
2183 for (ObjCObjectPointerType::qual_iterator I = ObjCPtr->qual_begin(),
2184 E = ObjCPtr->qual_end();
2185 I != E; ++I)
Douglas Gregor5d649882009-11-18 22:32:06 +00002186 AddObjCProperties(*I, true, CurContext, Results);
Douglas Gregor9291bad2009-11-18 01:29:26 +00002187 } else if ((IsArrow && BaseType->isObjCObjectPointerType()) ||
John McCall8b07ec22010-05-15 11:32:37 +00002188 (!IsArrow && BaseType->isObjCObjectType())) {
Douglas Gregor9291bad2009-11-18 01:29:26 +00002189 // Objective-C instance variable access.
2190 ObjCInterfaceDecl *Class = 0;
2191 if (const ObjCObjectPointerType *ObjCPtr
2192 = BaseType->getAs<ObjCObjectPointerType>())
2193 Class = ObjCPtr->getInterfaceDecl();
2194 else
John McCall8b07ec22010-05-15 11:32:37 +00002195 Class = BaseType->getAs<ObjCObjectType>()->getInterface();
Douglas Gregor9291bad2009-11-18 01:29:26 +00002196
2197 // Add all ivars from this class and its superclasses.
Douglas Gregor2b8162b2010-01-14 16:08:12 +00002198 if (Class) {
2199 CodeCompletionDeclConsumer Consumer(Results, CurContext);
2200 Results.setFilter(&ResultBuilder::IsObjCIvar);
2201 LookupVisibleDecls(Class, LookupMemberName, Consumer);
Douglas Gregor9291bad2009-11-18 01:29:26 +00002202 }
Douglas Gregor3545ff42009-09-21 16:56:56 +00002203 }
Douglas Gregor9291bad2009-11-18 01:29:26 +00002204
2205 // FIXME: How do we cope with isa?
2206
2207 Results.ExitScope();
Daniel Dunbar242ea9a2009-11-13 08:58:20 +00002208
Daniel Dunbar242ea9a2009-11-13 08:58:20 +00002209 // Hand off the results found for code completion.
2210 HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
Douglas Gregor2436e712009-09-17 21:32:03 +00002211}
2212
Douglas Gregorf45b0cf2009-09-18 15:37:17 +00002213void Sema::CodeCompleteTag(Scope *S, unsigned TagSpec) {
2214 if (!CodeCompleter)
2215 return;
2216
Douglas Gregor3545ff42009-09-21 16:56:56 +00002217 typedef CodeCompleteConsumer::Result Result;
2218 ResultBuilder::LookupFilter Filter = 0;
Douglas Gregorf45b0cf2009-09-18 15:37:17 +00002219 switch ((DeclSpec::TST)TagSpec) {
2220 case DeclSpec::TST_enum:
Douglas Gregor3545ff42009-09-21 16:56:56 +00002221 Filter = &ResultBuilder::IsEnum;
Douglas Gregorf45b0cf2009-09-18 15:37:17 +00002222 break;
2223
2224 case DeclSpec::TST_union:
Douglas Gregor3545ff42009-09-21 16:56:56 +00002225 Filter = &ResultBuilder::IsUnion;
Douglas Gregorf45b0cf2009-09-18 15:37:17 +00002226 break;
2227
2228 case DeclSpec::TST_struct:
Douglas Gregorf45b0cf2009-09-18 15:37:17 +00002229 case DeclSpec::TST_class:
Douglas Gregor3545ff42009-09-21 16:56:56 +00002230 Filter = &ResultBuilder::IsClassOrStruct;
Douglas Gregorf45b0cf2009-09-18 15:37:17 +00002231 break;
2232
2233 default:
2234 assert(false && "Unknown type specifier kind in CodeCompleteTag");
2235 return;
2236 }
Douglas Gregor3545ff42009-09-21 16:56:56 +00002237
John McCalle87beb22010-04-23 18:46:30 +00002238 ResultBuilder Results(*this);
Douglas Gregora6e2edc2010-01-14 03:27:13 +00002239 CodeCompletionDeclConsumer Consumer(Results, CurContext);
John McCalle87beb22010-04-23 18:46:30 +00002240
2241 // First pass: look for tags.
2242 Results.setFilter(Filter);
Douglas Gregora6e2edc2010-01-14 03:27:13 +00002243 LookupVisibleDecls(S, LookupTagName, Consumer);
John McCalle87beb22010-04-23 18:46:30 +00002244
2245 // Second pass: look for nested name specifiers.
2246 Results.setFilter(&ResultBuilder::IsNestedNameSpecifier);
2247 LookupVisibleDecls(S, LookupNestedNameSpecifierName, Consumer);
Douglas Gregor3545ff42009-09-21 16:56:56 +00002248
Daniel Dunbar242ea9a2009-11-13 08:58:20 +00002249 HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
Douglas Gregorf45b0cf2009-09-18 15:37:17 +00002250}
2251
Douglas Gregord328d572009-09-21 18:10:23 +00002252void Sema::CodeCompleteCase(Scope *S) {
2253 if (getSwitchStack().empty() || !CodeCompleter)
2254 return;
2255
2256 SwitchStmt *Switch = getSwitchStack().back();
2257 if (!Switch->getCond()->getType()->isEnumeralType())
2258 return;
2259
2260 // Code-complete the cases of a switch statement over an enumeration type
2261 // by providing the list of
2262 EnumDecl *Enum = Switch->getCond()->getType()->getAs<EnumType>()->getDecl();
2263
2264 // Determine which enumerators we have already seen in the switch statement.
2265 // FIXME: Ideally, we would also be able to look *past* the code-completion
2266 // token, in case we are code-completing in the middle of the switch and not
2267 // at the end. However, we aren't able to do so at the moment.
2268 llvm::SmallPtrSet<EnumConstantDecl *, 8> EnumeratorsSeen;
Douglas Gregorf2510672009-09-21 19:57:38 +00002269 NestedNameSpecifier *Qualifier = 0;
Douglas Gregord328d572009-09-21 18:10:23 +00002270 for (SwitchCase *SC = Switch->getSwitchCaseList(); SC;
2271 SC = SC->getNextSwitchCase()) {
2272 CaseStmt *Case = dyn_cast<CaseStmt>(SC);
2273 if (!Case)
2274 continue;
2275
2276 Expr *CaseVal = Case->getLHS()->IgnoreParenCasts();
2277 if (DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(CaseVal))
2278 if (EnumConstantDecl *Enumerator
2279 = dyn_cast<EnumConstantDecl>(DRE->getDecl())) {
2280 // We look into the AST of the case statement to determine which
2281 // enumerator was named. Alternatively, we could compute the value of
2282 // the integral constant expression, then compare it against the
2283 // values of each enumerator. However, value-based approach would not
2284 // work as well with C++ templates where enumerators declared within a
2285 // template are type- and value-dependent.
2286 EnumeratorsSeen.insert(Enumerator);
2287
Douglas Gregorf2510672009-09-21 19:57:38 +00002288 // If this is a qualified-id, keep track of the nested-name-specifier
2289 // so that we can reproduce it as part of code completion, e.g.,
Douglas Gregord328d572009-09-21 18:10:23 +00002290 //
2291 // switch (TagD.getKind()) {
2292 // case TagDecl::TK_enum:
2293 // break;
2294 // case XXX
2295 //
Douglas Gregorf2510672009-09-21 19:57:38 +00002296 // At the XXX, our completions are TagDecl::TK_union,
Douglas Gregord328d572009-09-21 18:10:23 +00002297 // TagDecl::TK_struct, and TagDecl::TK_class, rather than TK_union,
2298 // TK_struct, and TK_class.
Douglas Gregor4bd90e52009-10-23 18:54:35 +00002299 Qualifier = DRE->getQualifier();
Douglas Gregord328d572009-09-21 18:10:23 +00002300 }
2301 }
2302
Douglas Gregorf2510672009-09-21 19:57:38 +00002303 if (getLangOptions().CPlusPlus && !Qualifier && EnumeratorsSeen.empty()) {
2304 // If there are no prior enumerators in C++, check whether we have to
2305 // qualify the names of the enumerators that we suggest, because they
2306 // may not be visible in this scope.
2307 Qualifier = getRequiredQualification(Context, CurContext,
2308 Enum->getDeclContext());
2309
2310 // FIXME: Scoped enums need to start with "EnumDecl" as the context!
2311 }
2312
Douglas Gregord328d572009-09-21 18:10:23 +00002313 // Add any enumerators that have not yet been mentioned.
2314 ResultBuilder Results(*this);
2315 Results.EnterNewScope();
2316 for (EnumDecl::enumerator_iterator E = Enum->enumerator_begin(),
2317 EEnd = Enum->enumerator_end();
2318 E != EEnd; ++E) {
2319 if (EnumeratorsSeen.count(*E))
2320 continue;
2321
Douglas Gregorfc59ce12010-01-14 16:14:35 +00002322 Results.AddResult(CodeCompleteConsumer::Result(*E, Qualifier),
2323 CurContext, 0, false);
Douglas Gregord328d572009-09-21 18:10:23 +00002324 }
2325 Results.ExitScope();
Douglas Gregor285560922010-04-06 20:02:15 +00002326
Douglas Gregor9eb77012009-11-07 00:00:49 +00002327 if (CodeCompleter->includeMacros())
Douglas Gregorf98e6a22010-01-13 23:51:12 +00002328 AddMacroResults(PP, Results);
Daniel Dunbar242ea9a2009-11-13 08:58:20 +00002329 HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
Douglas Gregord328d572009-09-21 18:10:23 +00002330}
2331
Douglas Gregorcabea402009-09-22 15:41:20 +00002332namespace {
2333 struct IsBetterOverloadCandidate {
2334 Sema &S;
John McCallbc077cf2010-02-08 23:07:23 +00002335 SourceLocation Loc;
Douglas Gregorcabea402009-09-22 15:41:20 +00002336
2337 public:
John McCallbc077cf2010-02-08 23:07:23 +00002338 explicit IsBetterOverloadCandidate(Sema &S, SourceLocation Loc)
2339 : S(S), Loc(Loc) { }
Douglas Gregorcabea402009-09-22 15:41:20 +00002340
2341 bool
2342 operator()(const OverloadCandidate &X, const OverloadCandidate &Y) const {
John McCallbc077cf2010-02-08 23:07:23 +00002343 return S.isBetterOverloadCandidate(X, Y, Loc);
Douglas Gregorcabea402009-09-22 15:41:20 +00002344 }
2345 };
2346}
2347
2348void Sema::CodeCompleteCall(Scope *S, ExprTy *FnIn,
2349 ExprTy **ArgsIn, unsigned NumArgs) {
2350 if (!CodeCompleter)
2351 return;
Douglas Gregor3ef59522009-12-11 19:06:04 +00002352
2353 // When we're code-completing for a call, we fall back to ordinary
2354 // name code-completion whenever we can't produce specific
2355 // results. We may want to revisit this strategy in the future,
2356 // e.g., by merging the two kinds of results.
2357
Douglas Gregorcabea402009-09-22 15:41:20 +00002358 Expr *Fn = (Expr *)FnIn;
2359 Expr **Args = (Expr **)ArgsIn;
Douglas Gregor3ef59522009-12-11 19:06:04 +00002360
Douglas Gregorcabea402009-09-22 15:41:20 +00002361 // Ignore type-dependent call expressions entirely.
2362 if (Fn->isTypeDependent() ||
Douglas Gregor3ef59522009-12-11 19:06:04 +00002363 Expr::hasAnyTypeDependentArguments(Args, NumArgs)) {
Douglas Gregor504a6ae2010-01-10 23:08:15 +00002364 CodeCompleteOrdinaryName(S, CCC_Expression);
Douglas Gregorcabea402009-09-22 15:41:20 +00002365 return;
Douglas Gregor3ef59522009-12-11 19:06:04 +00002366 }
Douglas Gregorcabea402009-09-22 15:41:20 +00002367
John McCall57500772009-12-16 12:17:52 +00002368 // Build an overload candidate set based on the functions we find.
John McCallbc077cf2010-02-08 23:07:23 +00002369 SourceLocation Loc = Fn->getExprLoc();
2370 OverloadCandidateSet CandidateSet(Loc);
John McCall57500772009-12-16 12:17:52 +00002371
Douglas Gregorcabea402009-09-22 15:41:20 +00002372 // FIXME: What if we're calling something that isn't a function declaration?
2373 // FIXME: What if we're calling a pseudo-destructor?
2374 // FIXME: What if we're calling a member function?
2375
Douglas Gregorff59f672010-01-21 15:46:19 +00002376 typedef CodeCompleteConsumer::OverloadCandidate ResultCandidate;
2377 llvm::SmallVector<ResultCandidate, 8> Results;
2378
John McCall57500772009-12-16 12:17:52 +00002379 Expr *NakedFn = Fn->IgnoreParenCasts();
2380 if (UnresolvedLookupExpr *ULE = dyn_cast<UnresolvedLookupExpr>(NakedFn))
2381 AddOverloadedCallCandidates(ULE, Args, NumArgs, CandidateSet,
2382 /*PartialOverloading=*/ true);
2383 else if (DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(NakedFn)) {
2384 FunctionDecl *FDecl = dyn_cast<FunctionDecl>(DRE->getDecl());
Douglas Gregorff59f672010-01-21 15:46:19 +00002385 if (FDecl) {
2386 if (!FDecl->getType()->getAs<FunctionProtoType>())
2387 Results.push_back(ResultCandidate(FDecl));
2388 else
John McCallb89836b2010-01-26 01:37:31 +00002389 // FIXME: access?
John McCalla0296f72010-03-19 07:35:19 +00002390 AddOverloadCandidate(FDecl, DeclAccessPair::make(FDecl, AS_none),
2391 Args, NumArgs, CandidateSet,
Douglas Gregorb05275a2010-04-16 17:41:49 +00002392 false, /*PartialOverloading*/true);
Douglas Gregorff59f672010-01-21 15:46:19 +00002393 }
John McCall57500772009-12-16 12:17:52 +00002394 }
Douglas Gregorcabea402009-09-22 15:41:20 +00002395
Douglas Gregorff59f672010-01-21 15:46:19 +00002396 if (!CandidateSet.empty()) {
2397 // Sort the overload candidate set by placing the best overloads first.
2398 std::stable_sort(CandidateSet.begin(), CandidateSet.end(),
John McCallbc077cf2010-02-08 23:07:23 +00002399 IsBetterOverloadCandidate(*this, Loc));
Douglas Gregorcabea402009-09-22 15:41:20 +00002400
Douglas Gregorff59f672010-01-21 15:46:19 +00002401 // Add the remaining viable overload candidates as code-completion reslults.
2402 for (OverloadCandidateSet::iterator Cand = CandidateSet.begin(),
2403 CandEnd = CandidateSet.end();
2404 Cand != CandEnd; ++Cand) {
2405 if (Cand->Viable)
2406 Results.push_back(ResultCandidate(Cand->Function));
2407 }
Douglas Gregorcabea402009-09-22 15:41:20 +00002408 }
Douglas Gregor3ef59522009-12-11 19:06:04 +00002409
Douglas Gregorc01890e2010-04-06 20:19:47 +00002410 CodeCompleteOrdinaryName(S, CCC_Expression);
2411 if (!Results.empty())
Douglas Gregor3ef59522009-12-11 19:06:04 +00002412 CodeCompleter->ProcessOverloadCandidates(*this, NumArgs, Results.data(),
2413 Results.size());
Douglas Gregorcabea402009-09-22 15:41:20 +00002414}
2415
Jeffrey Yasskinc76498d2010-04-08 16:38:48 +00002416void Sema::CodeCompleteQualifiedId(Scope *S, CXXScopeSpec &SS,
Douglas Gregor2436e712009-09-17 21:32:03 +00002417 bool EnteringContext) {
2418 if (!SS.getScopeRep() || !CodeCompleter)
2419 return;
2420
Douglas Gregor3545ff42009-09-21 16:56:56 +00002421 DeclContext *Ctx = computeDeclContext(SS, EnteringContext);
2422 if (!Ctx)
2423 return;
Douglas Gregor800f2f02009-12-11 18:28:39 +00002424
2425 // Try to instantiate any non-dependent declaration contexts before
2426 // we look in them.
John McCall0b66eb32010-05-01 00:40:08 +00002427 if (!isDependentScopeSpecifier(SS) && RequireCompleteDeclContext(SS, Ctx))
Douglas Gregor800f2f02009-12-11 18:28:39 +00002428 return;
2429
Douglas Gregor3545ff42009-09-21 16:56:56 +00002430 ResultBuilder Results(*this);
Douglas Gregor200c99d2010-01-14 03:35:48 +00002431 CodeCompletionDeclConsumer Consumer(Results, CurContext);
2432 LookupVisibleDecls(Ctx, LookupOrdinaryName, Consumer);
Douglas Gregor3545ff42009-09-21 16:56:56 +00002433
2434 // The "template" keyword can follow "::" in the grammar, but only
2435 // put it into the grammar if the nested-name-specifier is dependent.
2436 NestedNameSpecifier *NNS = (NestedNameSpecifier *)SS.getScopeRep();
2437 if (!Results.empty() && NNS->isDependent())
Douglas Gregor78a21012010-01-14 16:01:26 +00002438 Results.AddResult("template");
Douglas Gregor3545ff42009-09-21 16:56:56 +00002439
Daniel Dunbar242ea9a2009-11-13 08:58:20 +00002440 HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
Douglas Gregor2436e712009-09-17 21:32:03 +00002441}
Douglas Gregor7e90c6d2009-09-18 19:03:04 +00002442
2443void Sema::CodeCompleteUsing(Scope *S) {
2444 if (!CodeCompleter)
2445 return;
2446
Douglas Gregor3545ff42009-09-21 16:56:56 +00002447 ResultBuilder Results(*this, &ResultBuilder::IsNestedNameSpecifier);
Douglas Gregor64b12b52009-09-22 23:31:26 +00002448 Results.EnterNewScope();
Douglas Gregor3545ff42009-09-21 16:56:56 +00002449
2450 // If we aren't in class scope, we could see the "namespace" keyword.
2451 if (!S->isClassScope())
Douglas Gregor78a21012010-01-14 16:01:26 +00002452 Results.AddResult(CodeCompleteConsumer::Result("namespace"));
Douglas Gregor3545ff42009-09-21 16:56:56 +00002453
2454 // After "using", we can see anything that would start a
2455 // nested-name-specifier.
Douglas Gregora6e2edc2010-01-14 03:27:13 +00002456 CodeCompletionDeclConsumer Consumer(Results, CurContext);
2457 LookupVisibleDecls(S, LookupOrdinaryName, Consumer);
Douglas Gregor64b12b52009-09-22 23:31:26 +00002458 Results.ExitScope();
Douglas Gregor3545ff42009-09-21 16:56:56 +00002459
Daniel Dunbar242ea9a2009-11-13 08:58:20 +00002460 HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
Douglas Gregor7e90c6d2009-09-18 19:03:04 +00002461}
2462
2463void Sema::CodeCompleteUsingDirective(Scope *S) {
2464 if (!CodeCompleter)
2465 return;
2466
Douglas Gregor3545ff42009-09-21 16:56:56 +00002467 // After "using namespace", we expect to see a namespace name or namespace
2468 // alias.
2469 ResultBuilder Results(*this, &ResultBuilder::IsNamespaceOrAlias);
Douglas Gregor64b12b52009-09-22 23:31:26 +00002470 Results.EnterNewScope();
Douglas Gregora6e2edc2010-01-14 03:27:13 +00002471 CodeCompletionDeclConsumer Consumer(Results, CurContext);
2472 LookupVisibleDecls(S, LookupOrdinaryName, Consumer);
Douglas Gregor64b12b52009-09-22 23:31:26 +00002473 Results.ExitScope();
Daniel Dunbar242ea9a2009-11-13 08:58:20 +00002474 HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
Douglas Gregor7e90c6d2009-09-18 19:03:04 +00002475}
2476
2477void Sema::CodeCompleteNamespaceDecl(Scope *S) {
2478 if (!CodeCompleter)
2479 return;
2480
Douglas Gregor3545ff42009-09-21 16:56:56 +00002481 ResultBuilder Results(*this, &ResultBuilder::IsNamespace);
2482 DeclContext *Ctx = (DeclContext *)S->getEntity();
2483 if (!S->getParent())
2484 Ctx = Context.getTranslationUnitDecl();
2485
2486 if (Ctx && Ctx->isFileContext()) {
2487 // We only want to see those namespaces that have already been defined
2488 // within this scope, because its likely that the user is creating an
2489 // extended namespace declaration. Keep track of the most recent
2490 // definition of each namespace.
2491 std::map<NamespaceDecl *, NamespaceDecl *> OrigToLatest;
2492 for (DeclContext::specific_decl_iterator<NamespaceDecl>
2493 NS(Ctx->decls_begin()), NSEnd(Ctx->decls_end());
2494 NS != NSEnd; ++NS)
2495 OrigToLatest[NS->getOriginalNamespace()] = *NS;
2496
2497 // Add the most recent definition (or extended definition) of each
2498 // namespace to the list of results.
Douglas Gregor64b12b52009-09-22 23:31:26 +00002499 Results.EnterNewScope();
Douglas Gregor3545ff42009-09-21 16:56:56 +00002500 for (std::map<NamespaceDecl *, NamespaceDecl *>::iterator
2501 NS = OrigToLatest.begin(), NSEnd = OrigToLatest.end();
2502 NS != NSEnd; ++NS)
Douglas Gregorfc59ce12010-01-14 16:14:35 +00002503 Results.AddResult(CodeCompleteConsumer::Result(NS->second, 0),
2504 CurContext, 0, false);
Douglas Gregor64b12b52009-09-22 23:31:26 +00002505 Results.ExitScope();
Douglas Gregor3545ff42009-09-21 16:56:56 +00002506 }
2507
Daniel Dunbar242ea9a2009-11-13 08:58:20 +00002508 HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
Douglas Gregor7e90c6d2009-09-18 19:03:04 +00002509}
2510
2511void Sema::CodeCompleteNamespaceAliasDecl(Scope *S) {
2512 if (!CodeCompleter)
2513 return;
2514
Douglas Gregor3545ff42009-09-21 16:56:56 +00002515 // After "namespace", we expect to see a namespace or alias.
2516 ResultBuilder Results(*this, &ResultBuilder::IsNamespaceOrAlias);
Douglas Gregora6e2edc2010-01-14 03:27:13 +00002517 CodeCompletionDeclConsumer Consumer(Results, CurContext);
2518 LookupVisibleDecls(S, LookupOrdinaryName, Consumer);
Daniel Dunbar242ea9a2009-11-13 08:58:20 +00002519 HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
Douglas Gregor7e90c6d2009-09-18 19:03:04 +00002520}
2521
Douglas Gregorc811ede2009-09-18 20:05:18 +00002522void Sema::CodeCompleteOperatorName(Scope *S) {
2523 if (!CodeCompleter)
2524 return;
Douglas Gregor3545ff42009-09-21 16:56:56 +00002525
2526 typedef CodeCompleteConsumer::Result Result;
2527 ResultBuilder Results(*this, &ResultBuilder::IsType);
Douglas Gregor64b12b52009-09-22 23:31:26 +00002528 Results.EnterNewScope();
Douglas Gregorc811ede2009-09-18 20:05:18 +00002529
Douglas Gregor3545ff42009-09-21 16:56:56 +00002530 // Add the names of overloadable operators.
2531#define OVERLOADED_OPERATOR(Name,Spelling,Token,Unary,Binary,MemberOnly) \
2532 if (std::strcmp(Spelling, "?")) \
Douglas Gregor78a21012010-01-14 16:01:26 +00002533 Results.AddResult(Result(Spelling));
Douglas Gregor3545ff42009-09-21 16:56:56 +00002534#include "clang/Basic/OperatorKinds.def"
2535
2536 // Add any type names visible from the current scope
Douglas Gregor6ae4c522010-01-14 03:21:49 +00002537 Results.allowNestedNameSpecifiers();
Douglas Gregora6e2edc2010-01-14 03:27:13 +00002538 CodeCompletionDeclConsumer Consumer(Results, CurContext);
2539 LookupVisibleDecls(S, LookupOrdinaryName, Consumer);
Douglas Gregor3545ff42009-09-21 16:56:56 +00002540
2541 // Add any type specifiers
Douglas Gregorf98e6a22010-01-13 23:51:12 +00002542 AddTypeSpecifierResults(getLangOptions(), Results);
Douglas Gregor64b12b52009-09-22 23:31:26 +00002543 Results.ExitScope();
Douglas Gregor3545ff42009-09-21 16:56:56 +00002544
Daniel Dunbar242ea9a2009-11-13 08:58:20 +00002545 HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
Douglas Gregorc811ede2009-09-18 20:05:18 +00002546}
Douglas Gregor7e90c6d2009-09-18 19:03:04 +00002547
Douglas Gregorf1934162010-01-13 21:24:21 +00002548// Macro that expands to @Keyword or Keyword, depending on whether NeedAt is
2549// true or false.
2550#define OBJC_AT_KEYWORD_NAME(NeedAt,Keyword) NeedAt? "@" #Keyword : #Keyword
Douglas Gregorf98e6a22010-01-13 23:51:12 +00002551static void AddObjCImplementationResults(const LangOptions &LangOpts,
Douglas Gregorf1934162010-01-13 21:24:21 +00002552 ResultBuilder &Results,
2553 bool NeedAt) {
2554 typedef CodeCompleteConsumer::Result Result;
2555 // Since we have an implementation, we can end it.
Douglas Gregor78a21012010-01-14 16:01:26 +00002556 Results.AddResult(Result(OBJC_AT_KEYWORD_NAME(NeedAt,end)));
Douglas Gregorf1934162010-01-13 21:24:21 +00002557
2558 CodeCompletionString *Pattern = 0;
2559 if (LangOpts.ObjC2) {
2560 // @dynamic
2561 Pattern = new CodeCompletionString;
2562 Pattern->AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt,dynamic));
2563 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
2564 Pattern->AddPlaceholderChunk("property");
Douglas Gregor78a21012010-01-14 16:01:26 +00002565 Results.AddResult(Result(Pattern));
Douglas Gregorf1934162010-01-13 21:24:21 +00002566
2567 // @synthesize
2568 Pattern = new CodeCompletionString;
2569 Pattern->AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt,synthesize));
2570 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
2571 Pattern->AddPlaceholderChunk("property");
Douglas Gregor78a21012010-01-14 16:01:26 +00002572 Results.AddResult(Result(Pattern));
Douglas Gregorf1934162010-01-13 21:24:21 +00002573 }
2574}
2575
Douglas Gregorf98e6a22010-01-13 23:51:12 +00002576static void AddObjCInterfaceResults(const LangOptions &LangOpts,
Douglas Gregorf1934162010-01-13 21:24:21 +00002577 ResultBuilder &Results,
2578 bool NeedAt) {
2579 typedef CodeCompleteConsumer::Result Result;
2580
2581 // Since we have an interface or protocol, we can end it.
Douglas Gregor78a21012010-01-14 16:01:26 +00002582 Results.AddResult(Result(OBJC_AT_KEYWORD_NAME(NeedAt,end)));
Douglas Gregorf1934162010-01-13 21:24:21 +00002583
2584 if (LangOpts.ObjC2) {
2585 // @property
Douglas Gregor78a21012010-01-14 16:01:26 +00002586 Results.AddResult(Result(OBJC_AT_KEYWORD_NAME(NeedAt,property)));
Douglas Gregorf1934162010-01-13 21:24:21 +00002587
2588 // @required
Douglas Gregor78a21012010-01-14 16:01:26 +00002589 Results.AddResult(Result(OBJC_AT_KEYWORD_NAME(NeedAt,required)));
Douglas Gregorf1934162010-01-13 21:24:21 +00002590
2591 // @optional
Douglas Gregor78a21012010-01-14 16:01:26 +00002592 Results.AddResult(Result(OBJC_AT_KEYWORD_NAME(NeedAt,optional)));
Douglas Gregorf1934162010-01-13 21:24:21 +00002593 }
2594}
2595
Douglas Gregorf98e6a22010-01-13 23:51:12 +00002596static void AddObjCTopLevelResults(ResultBuilder &Results, bool NeedAt) {
Douglas Gregorf1934162010-01-13 21:24:21 +00002597 typedef CodeCompleteConsumer::Result Result;
2598 CodeCompletionString *Pattern = 0;
2599
2600 // @class name ;
2601 Pattern = new CodeCompletionString;
2602 Pattern->AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt,class));
2603 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
Douglas Gregorf4c33342010-05-28 00:22:41 +00002604 Pattern->AddPlaceholderChunk("name");
Douglas Gregor78a21012010-01-14 16:01:26 +00002605 Results.AddResult(Result(Pattern));
Douglas Gregorf1934162010-01-13 21:24:21 +00002606
Douglas Gregorf4c33342010-05-28 00:22:41 +00002607 if (Results.includeCodePatterns()) {
2608 // @interface name
2609 // FIXME: Could introduce the whole pattern, including superclasses and
2610 // such.
2611 Pattern = new CodeCompletionString;
2612 Pattern->AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt,interface));
2613 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
2614 Pattern->AddPlaceholderChunk("class");
2615 Results.AddResult(Result(Pattern));
Douglas Gregorf1934162010-01-13 21:24:21 +00002616
Douglas Gregorf4c33342010-05-28 00:22:41 +00002617 // @protocol name
2618 Pattern = new CodeCompletionString;
2619 Pattern->AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt,protocol));
2620 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
2621 Pattern->AddPlaceholderChunk("protocol");
2622 Results.AddResult(Result(Pattern));
2623
2624 // @implementation name
2625 Pattern = new CodeCompletionString;
2626 Pattern->AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt,implementation));
2627 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
2628 Pattern->AddPlaceholderChunk("class");
2629 Results.AddResult(Result(Pattern));
2630 }
Douglas Gregorf1934162010-01-13 21:24:21 +00002631
2632 // @compatibility_alias name
2633 Pattern = new CodeCompletionString;
2634 Pattern->AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt,compatibility_alias));
2635 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
2636 Pattern->AddPlaceholderChunk("alias");
2637 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
2638 Pattern->AddPlaceholderChunk("class");
Douglas Gregor78a21012010-01-14 16:01:26 +00002639 Results.AddResult(Result(Pattern));
Douglas Gregorf1934162010-01-13 21:24:21 +00002640}
2641
Douglas Gregorf48706c2009-12-07 09:27:33 +00002642void Sema::CodeCompleteObjCAtDirective(Scope *S, DeclPtrTy ObjCImpDecl,
2643 bool InInterface) {
2644 typedef CodeCompleteConsumer::Result Result;
2645 ResultBuilder Results(*this);
2646 Results.EnterNewScope();
Douglas Gregorf1934162010-01-13 21:24:21 +00002647 if (ObjCImpDecl)
Douglas Gregorf98e6a22010-01-13 23:51:12 +00002648 AddObjCImplementationResults(getLangOptions(), Results, false);
Douglas Gregorf1934162010-01-13 21:24:21 +00002649 else if (InInterface)
Douglas Gregorf98e6a22010-01-13 23:51:12 +00002650 AddObjCInterfaceResults(getLangOptions(), Results, false);
Douglas Gregorf1934162010-01-13 21:24:21 +00002651 else
Douglas Gregorf98e6a22010-01-13 23:51:12 +00002652 AddObjCTopLevelResults(Results, false);
Douglas Gregorf48706c2009-12-07 09:27:33 +00002653 Results.ExitScope();
2654 HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
2655}
2656
Douglas Gregorf98e6a22010-01-13 23:51:12 +00002657static void AddObjCExpressionResults(ResultBuilder &Results, bool NeedAt) {
Douglas Gregorbc7c5e42009-12-07 09:51:25 +00002658 typedef CodeCompleteConsumer::Result Result;
2659 CodeCompletionString *Pattern = 0;
2660
2661 // @encode ( type-name )
2662 Pattern = new CodeCompletionString;
Douglas Gregorf1934162010-01-13 21:24:21 +00002663 Pattern->AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt,encode));
Douglas Gregorbc7c5e42009-12-07 09:51:25 +00002664 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
2665 Pattern->AddPlaceholderChunk("type-name");
2666 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
Douglas Gregor78a21012010-01-14 16:01:26 +00002667 Results.AddResult(Result(Pattern));
Douglas Gregorbc7c5e42009-12-07 09:51:25 +00002668
2669 // @protocol ( protocol-name )
2670 Pattern = new CodeCompletionString;
Douglas Gregorf1934162010-01-13 21:24:21 +00002671 Pattern->AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt,protocol));
Douglas Gregorbc7c5e42009-12-07 09:51:25 +00002672 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
2673 Pattern->AddPlaceholderChunk("protocol-name");
2674 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
Douglas Gregor78a21012010-01-14 16:01:26 +00002675 Results.AddResult(Result(Pattern));
Douglas Gregorbc7c5e42009-12-07 09:51:25 +00002676
2677 // @selector ( selector )
2678 Pattern = new CodeCompletionString;
Douglas Gregorf1934162010-01-13 21:24:21 +00002679 Pattern->AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt,selector));
Douglas Gregorbc7c5e42009-12-07 09:51:25 +00002680 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
2681 Pattern->AddPlaceholderChunk("selector");
2682 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
Douglas Gregor78a21012010-01-14 16:01:26 +00002683 Results.AddResult(Result(Pattern));
Douglas Gregorbc7c5e42009-12-07 09:51:25 +00002684}
2685
Douglas Gregorf98e6a22010-01-13 23:51:12 +00002686static void AddObjCStatementResults(ResultBuilder &Results, bool NeedAt) {
Douglas Gregorbc7c5e42009-12-07 09:51:25 +00002687 typedef CodeCompleteConsumer::Result Result;
Douglas Gregorbc7c5e42009-12-07 09:51:25 +00002688 CodeCompletionString *Pattern = 0;
Douglas Gregorf1934162010-01-13 21:24:21 +00002689
Douglas Gregorf4c33342010-05-28 00:22:41 +00002690 if (Results.includeCodePatterns()) {
2691 // @try { statements } @catch ( declaration ) { statements } @finally
2692 // { statements }
2693 Pattern = new CodeCompletionString;
2694 Pattern->AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt,try));
2695 Pattern->AddChunk(CodeCompletionString::CK_LeftBrace);
2696 Pattern->AddPlaceholderChunk("statements");
2697 Pattern->AddChunk(CodeCompletionString::CK_RightBrace);
2698 Pattern->AddTextChunk("@catch");
2699 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
2700 Pattern->AddPlaceholderChunk("parameter");
2701 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
2702 Pattern->AddChunk(CodeCompletionString::CK_LeftBrace);
2703 Pattern->AddPlaceholderChunk("statements");
2704 Pattern->AddChunk(CodeCompletionString::CK_RightBrace);
2705 Pattern->AddTextChunk("@finally");
2706 Pattern->AddChunk(CodeCompletionString::CK_LeftBrace);
2707 Pattern->AddPlaceholderChunk("statements");
2708 Pattern->AddChunk(CodeCompletionString::CK_RightBrace);
2709 Results.AddResult(Result(Pattern));
2710 }
Douglas Gregorf1934162010-01-13 21:24:21 +00002711
Douglas Gregorbc7c5e42009-12-07 09:51:25 +00002712 // @throw
2713 Pattern = new CodeCompletionString;
Douglas Gregorf1934162010-01-13 21:24:21 +00002714 Pattern->AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt,throw));
Douglas Gregor6a803932010-01-12 06:38:28 +00002715 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
Douglas Gregorbc7c5e42009-12-07 09:51:25 +00002716 Pattern->AddPlaceholderChunk("expression");
Douglas Gregor78a21012010-01-14 16:01:26 +00002717 Results.AddResult(Result(Pattern));
Douglas Gregorf1934162010-01-13 21:24:21 +00002718
Douglas Gregorf4c33342010-05-28 00:22:41 +00002719 if (Results.includeCodePatterns()) {
2720 // @synchronized ( expression ) { statements }
2721 Pattern = new CodeCompletionString;
2722 Pattern->AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt,synchronized));
2723 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
2724 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
2725 Pattern->AddPlaceholderChunk("expression");
2726 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
2727 Pattern->AddChunk(CodeCompletionString::CK_LeftBrace);
2728 Pattern->AddPlaceholderChunk("statements");
2729 Pattern->AddChunk(CodeCompletionString::CK_RightBrace);
2730 Results.AddResult(Result(Pattern));
2731 }
Douglas Gregorf1934162010-01-13 21:24:21 +00002732}
Douglas Gregorbc7c5e42009-12-07 09:51:25 +00002733
Douglas Gregorf98e6a22010-01-13 23:51:12 +00002734static void AddObjCVisibilityResults(const LangOptions &LangOpts,
Douglas Gregor48d46252010-01-13 21:54:15 +00002735 ResultBuilder &Results,
2736 bool NeedAt) {
Douglas Gregorf1934162010-01-13 21:24:21 +00002737 typedef CodeCompleteConsumer::Result Result;
Douglas Gregor78a21012010-01-14 16:01:26 +00002738 Results.AddResult(Result(OBJC_AT_KEYWORD_NAME(NeedAt,private)));
2739 Results.AddResult(Result(OBJC_AT_KEYWORD_NAME(NeedAt,protected)));
2740 Results.AddResult(Result(OBJC_AT_KEYWORD_NAME(NeedAt,public)));
Douglas Gregor48d46252010-01-13 21:54:15 +00002741 if (LangOpts.ObjC2)
Douglas Gregor78a21012010-01-14 16:01:26 +00002742 Results.AddResult(Result(OBJC_AT_KEYWORD_NAME(NeedAt,package)));
Douglas Gregor48d46252010-01-13 21:54:15 +00002743}
2744
2745void Sema::CodeCompleteObjCAtVisibility(Scope *S) {
2746 ResultBuilder Results(*this);
2747 Results.EnterNewScope();
Douglas Gregorf98e6a22010-01-13 23:51:12 +00002748 AddObjCVisibilityResults(getLangOptions(), Results, false);
Douglas Gregor48d46252010-01-13 21:54:15 +00002749 Results.ExitScope();
2750 HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
2751}
2752
2753void Sema::CodeCompleteObjCAtStatement(Scope *S) {
Douglas Gregorf1934162010-01-13 21:24:21 +00002754 ResultBuilder Results(*this);
2755 Results.EnterNewScope();
Douglas Gregorf98e6a22010-01-13 23:51:12 +00002756 AddObjCStatementResults(Results, false);
2757 AddObjCExpressionResults(Results, false);
Douglas Gregorbc7c5e42009-12-07 09:51:25 +00002758 Results.ExitScope();
2759 HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
2760}
2761
2762void Sema::CodeCompleteObjCAtExpression(Scope *S) {
2763 ResultBuilder Results(*this);
2764 Results.EnterNewScope();
Douglas Gregorf98e6a22010-01-13 23:51:12 +00002765 AddObjCExpressionResults(Results, false);
Douglas Gregorbc7c5e42009-12-07 09:51:25 +00002766 Results.ExitScope();
2767 HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
2768}
2769
Douglas Gregore6078da2009-11-19 00:14:45 +00002770/// \brief Determine whether the addition of the given flag to an Objective-C
2771/// property's attributes will cause a conflict.
2772static bool ObjCPropertyFlagConflicts(unsigned Attributes, unsigned NewFlag) {
2773 // Check if we've already added this flag.
2774 if (Attributes & NewFlag)
2775 return true;
2776
2777 Attributes |= NewFlag;
2778
2779 // Check for collisions with "readonly".
2780 if ((Attributes & ObjCDeclSpec::DQ_PR_readonly) &&
2781 (Attributes & (ObjCDeclSpec::DQ_PR_readwrite |
2782 ObjCDeclSpec::DQ_PR_assign |
2783 ObjCDeclSpec::DQ_PR_copy |
2784 ObjCDeclSpec::DQ_PR_retain)))
2785 return true;
2786
2787 // Check for more than one of { assign, copy, retain }.
2788 unsigned AssignCopyRetMask = Attributes & (ObjCDeclSpec::DQ_PR_assign |
2789 ObjCDeclSpec::DQ_PR_copy |
2790 ObjCDeclSpec::DQ_PR_retain);
2791 if (AssignCopyRetMask &&
2792 AssignCopyRetMask != ObjCDeclSpec::DQ_PR_assign &&
2793 AssignCopyRetMask != ObjCDeclSpec::DQ_PR_copy &&
2794 AssignCopyRetMask != ObjCDeclSpec::DQ_PR_retain)
2795 return true;
2796
2797 return false;
2798}
2799
Douglas Gregor36029f42009-11-18 23:08:07 +00002800void Sema::CodeCompleteObjCPropertyFlags(Scope *S, ObjCDeclSpec &ODS) {
Steve Naroff936354c2009-10-08 21:55:05 +00002801 if (!CodeCompleter)
2802 return;
Douglas Gregor1b605f72009-11-19 01:08:35 +00002803
Steve Naroff936354c2009-10-08 21:55:05 +00002804 unsigned Attributes = ODS.getPropertyAttributes();
2805
2806 typedef CodeCompleteConsumer::Result Result;
2807 ResultBuilder Results(*this);
2808 Results.EnterNewScope();
Douglas Gregore6078da2009-11-19 00:14:45 +00002809 if (!ObjCPropertyFlagConflicts(Attributes, ObjCDeclSpec::DQ_PR_readonly))
Douglas Gregor78a21012010-01-14 16:01:26 +00002810 Results.AddResult(CodeCompleteConsumer::Result("readonly"));
Douglas Gregore6078da2009-11-19 00:14:45 +00002811 if (!ObjCPropertyFlagConflicts(Attributes, ObjCDeclSpec::DQ_PR_assign))
Douglas Gregor78a21012010-01-14 16:01:26 +00002812 Results.AddResult(CodeCompleteConsumer::Result("assign"));
Douglas Gregore6078da2009-11-19 00:14:45 +00002813 if (!ObjCPropertyFlagConflicts(Attributes, ObjCDeclSpec::DQ_PR_readwrite))
Douglas Gregor78a21012010-01-14 16:01:26 +00002814 Results.AddResult(CodeCompleteConsumer::Result("readwrite"));
Douglas Gregore6078da2009-11-19 00:14:45 +00002815 if (!ObjCPropertyFlagConflicts(Attributes, ObjCDeclSpec::DQ_PR_retain))
Douglas Gregor78a21012010-01-14 16:01:26 +00002816 Results.AddResult(CodeCompleteConsumer::Result("retain"));
Douglas Gregore6078da2009-11-19 00:14:45 +00002817 if (!ObjCPropertyFlagConflicts(Attributes, ObjCDeclSpec::DQ_PR_copy))
Douglas Gregor78a21012010-01-14 16:01:26 +00002818 Results.AddResult(CodeCompleteConsumer::Result("copy"));
Douglas Gregore6078da2009-11-19 00:14:45 +00002819 if (!ObjCPropertyFlagConflicts(Attributes, ObjCDeclSpec::DQ_PR_nonatomic))
Douglas Gregor78a21012010-01-14 16:01:26 +00002820 Results.AddResult(CodeCompleteConsumer::Result("nonatomic"));
Douglas Gregore6078da2009-11-19 00:14:45 +00002821 if (!ObjCPropertyFlagConflicts(Attributes, ObjCDeclSpec::DQ_PR_setter)) {
Douglas Gregor45f83ee2009-11-19 00:01:57 +00002822 CodeCompletionString *Setter = new CodeCompletionString;
2823 Setter->AddTypedTextChunk("setter");
2824 Setter->AddTextChunk(" = ");
2825 Setter->AddPlaceholderChunk("method");
Douglas Gregor78a21012010-01-14 16:01:26 +00002826 Results.AddResult(CodeCompleteConsumer::Result(Setter));
Douglas Gregor45f83ee2009-11-19 00:01:57 +00002827 }
Douglas Gregore6078da2009-11-19 00:14:45 +00002828 if (!ObjCPropertyFlagConflicts(Attributes, ObjCDeclSpec::DQ_PR_getter)) {
Douglas Gregor45f83ee2009-11-19 00:01:57 +00002829 CodeCompletionString *Getter = new CodeCompletionString;
2830 Getter->AddTypedTextChunk("getter");
2831 Getter->AddTextChunk(" = ");
2832 Getter->AddPlaceholderChunk("method");
Douglas Gregor78a21012010-01-14 16:01:26 +00002833 Results.AddResult(CodeCompleteConsumer::Result(Getter));
Douglas Gregor45f83ee2009-11-19 00:01:57 +00002834 }
Steve Naroff936354c2009-10-08 21:55:05 +00002835 Results.ExitScope();
Daniel Dunbar242ea9a2009-11-13 08:58:20 +00002836 HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
Steve Naroff936354c2009-10-08 21:55:05 +00002837}
Steve Naroffeae65032009-11-07 02:08:14 +00002838
Douglas Gregorc8537c52009-11-19 07:41:15 +00002839/// \brief Descripts the kind of Objective-C method that we want to find
2840/// via code completion.
2841enum ObjCMethodKind {
2842 MK_Any, //< Any kind of method, provided it means other specified criteria.
2843 MK_ZeroArgSelector, //< Zero-argument (unary) selector.
2844 MK_OneArgSelector //< One-argument selector.
2845};
2846
2847static bool isAcceptableObjCMethod(ObjCMethodDecl *Method,
2848 ObjCMethodKind WantKind,
2849 IdentifierInfo **SelIdents,
2850 unsigned NumSelIdents) {
2851 Selector Sel = Method->getSelector();
2852 if (NumSelIdents > Sel.getNumArgs())
2853 return false;
2854
2855 switch (WantKind) {
2856 case MK_Any: break;
2857 case MK_ZeroArgSelector: return Sel.isUnarySelector();
2858 case MK_OneArgSelector: return Sel.getNumArgs() == 1;
2859 }
2860
2861 for (unsigned I = 0; I != NumSelIdents; ++I)
2862 if (SelIdents[I] != Sel.getIdentifierInfoForSlot(I))
2863 return false;
2864
2865 return true;
2866}
2867
Douglas Gregorbab2b3c2009-11-17 23:22:23 +00002868/// \brief Add all of the Objective-C methods in the given Objective-C
2869/// container to the set of results.
2870///
2871/// The container will be a class, protocol, category, or implementation of
2872/// any of the above. This mether will recurse to include methods from
2873/// the superclasses of classes along with their categories, protocols, and
2874/// implementations.
2875///
2876/// \param Container the container in which we'll look to find methods.
2877///
2878/// \param WantInstance whether to add instance methods (only); if false, this
2879/// routine will add factory methods (only).
2880///
2881/// \param CurContext the context in which we're performing the lookup that
2882/// finds methods.
2883///
2884/// \param Results the structure into which we'll add results.
2885static void AddObjCMethods(ObjCContainerDecl *Container,
2886 bool WantInstanceMethods,
Douglas Gregorc8537c52009-11-19 07:41:15 +00002887 ObjCMethodKind WantKind,
Douglas Gregor1b605f72009-11-19 01:08:35 +00002888 IdentifierInfo **SelIdents,
2889 unsigned NumSelIdents,
Douglas Gregorbab2b3c2009-11-17 23:22:23 +00002890 DeclContext *CurContext,
2891 ResultBuilder &Results) {
2892 typedef CodeCompleteConsumer::Result Result;
2893 for (ObjCContainerDecl::method_iterator M = Container->meth_begin(),
2894 MEnd = Container->meth_end();
2895 M != MEnd; ++M) {
Douglas Gregor1b605f72009-11-19 01:08:35 +00002896 if ((*M)->isInstanceMethod() == WantInstanceMethods) {
2897 // Check whether the selector identifiers we've been given are a
2898 // subset of the identifiers for this particular method.
Douglas Gregorc8537c52009-11-19 07:41:15 +00002899 if (!isAcceptableObjCMethod(*M, WantKind, SelIdents, NumSelIdents))
Douglas Gregor1b605f72009-11-19 01:08:35 +00002900 continue;
Douglas Gregorc8537c52009-11-19 07:41:15 +00002901
Douglas Gregor1b605f72009-11-19 01:08:35 +00002902 Result R = Result(*M, 0);
2903 R.StartParameter = NumSelIdents;
Douglas Gregorc8537c52009-11-19 07:41:15 +00002904 R.AllParametersAreInformative = (WantKind != MK_Any);
Douglas Gregor1b605f72009-11-19 01:08:35 +00002905 Results.MaybeAddResult(R, CurContext);
2906 }
Douglas Gregorbab2b3c2009-11-17 23:22:23 +00002907 }
2908
2909 ObjCInterfaceDecl *IFace = dyn_cast<ObjCInterfaceDecl>(Container);
2910 if (!IFace)
2911 return;
2912
2913 // Add methods in protocols.
2914 const ObjCList<ObjCProtocolDecl> &Protocols= IFace->getReferencedProtocols();
2915 for (ObjCList<ObjCProtocolDecl>::iterator I = Protocols.begin(),
2916 E = Protocols.end();
2917 I != E; ++I)
Douglas Gregorc8537c52009-11-19 07:41:15 +00002918 AddObjCMethods(*I, WantInstanceMethods, WantKind, SelIdents, NumSelIdents,
Douglas Gregor1b605f72009-11-19 01:08:35 +00002919 CurContext, Results);
Douglas Gregorbab2b3c2009-11-17 23:22:23 +00002920
2921 // Add methods in categories.
2922 for (ObjCCategoryDecl *CatDecl = IFace->getCategoryList(); CatDecl;
2923 CatDecl = CatDecl->getNextClassCategory()) {
Douglas Gregorc8537c52009-11-19 07:41:15 +00002924 AddObjCMethods(CatDecl, WantInstanceMethods, WantKind, SelIdents,
2925 NumSelIdents, CurContext, Results);
Douglas Gregorbab2b3c2009-11-17 23:22:23 +00002926
2927 // Add a categories protocol methods.
2928 const ObjCList<ObjCProtocolDecl> &Protocols
2929 = CatDecl->getReferencedProtocols();
2930 for (ObjCList<ObjCProtocolDecl>::iterator I = Protocols.begin(),
2931 E = Protocols.end();
2932 I != E; ++I)
Douglas Gregorc8537c52009-11-19 07:41:15 +00002933 AddObjCMethods(*I, WantInstanceMethods, WantKind, SelIdents,
2934 NumSelIdents, CurContext, Results);
Douglas Gregorbab2b3c2009-11-17 23:22:23 +00002935
2936 // Add methods in category implementations.
2937 if (ObjCCategoryImplDecl *Impl = CatDecl->getImplementation())
Douglas Gregorc8537c52009-11-19 07:41:15 +00002938 AddObjCMethods(Impl, WantInstanceMethods, WantKind, SelIdents,
2939 NumSelIdents, CurContext, Results);
Douglas Gregorbab2b3c2009-11-17 23:22:23 +00002940 }
2941
2942 // Add methods in superclass.
2943 if (IFace->getSuperClass())
Douglas Gregorc8537c52009-11-19 07:41:15 +00002944 AddObjCMethods(IFace->getSuperClass(), WantInstanceMethods, WantKind,
2945 SelIdents, NumSelIdents, CurContext, Results);
Douglas Gregorbab2b3c2009-11-17 23:22:23 +00002946
2947 // Add methods in our implementation, if any.
2948 if (ObjCImplementationDecl *Impl = IFace->getImplementation())
Douglas Gregorc8537c52009-11-19 07:41:15 +00002949 AddObjCMethods(Impl, WantInstanceMethods, WantKind, SelIdents,
2950 NumSelIdents, CurContext, Results);
2951}
2952
2953
2954void Sema::CodeCompleteObjCPropertyGetter(Scope *S, DeclPtrTy ClassDecl,
2955 DeclPtrTy *Methods,
2956 unsigned NumMethods) {
2957 typedef CodeCompleteConsumer::Result Result;
2958
2959 // Try to find the interface where getters might live.
2960 ObjCInterfaceDecl *Class
2961 = dyn_cast_or_null<ObjCInterfaceDecl>(ClassDecl.getAs<Decl>());
2962 if (!Class) {
2963 if (ObjCCategoryDecl *Category
2964 = dyn_cast_or_null<ObjCCategoryDecl>(ClassDecl.getAs<Decl>()))
2965 Class = Category->getClassInterface();
2966
2967 if (!Class)
2968 return;
2969 }
2970
2971 // Find all of the potential getters.
2972 ResultBuilder Results(*this);
2973 Results.EnterNewScope();
2974
2975 // FIXME: We need to do this because Objective-C methods don't get
2976 // pushed into DeclContexts early enough. Argh!
2977 for (unsigned I = 0; I != NumMethods; ++I) {
2978 if (ObjCMethodDecl *Method
2979 = dyn_cast_or_null<ObjCMethodDecl>(Methods[I].getAs<Decl>()))
2980 if (Method->isInstanceMethod() &&
2981 isAcceptableObjCMethod(Method, MK_ZeroArgSelector, 0, 0)) {
2982 Result R = Result(Method, 0);
2983 R.AllParametersAreInformative = true;
2984 Results.MaybeAddResult(R, CurContext);
2985 }
2986 }
2987
2988 AddObjCMethods(Class, true, MK_ZeroArgSelector, 0, 0, CurContext, Results);
2989 Results.ExitScope();
2990 HandleCodeCompleteResults(this, CodeCompleter,Results.data(),Results.size());
2991}
2992
2993void Sema::CodeCompleteObjCPropertySetter(Scope *S, DeclPtrTy ObjCImplDecl,
2994 DeclPtrTy *Methods,
2995 unsigned NumMethods) {
2996 typedef CodeCompleteConsumer::Result Result;
2997
2998 // Try to find the interface where setters might live.
2999 ObjCInterfaceDecl *Class
3000 = dyn_cast_or_null<ObjCInterfaceDecl>(ObjCImplDecl.getAs<Decl>());
3001 if (!Class) {
3002 if (ObjCCategoryDecl *Category
3003 = dyn_cast_or_null<ObjCCategoryDecl>(ObjCImplDecl.getAs<Decl>()))
3004 Class = Category->getClassInterface();
3005
3006 if (!Class)
3007 return;
3008 }
3009
3010 // Find all of the potential getters.
3011 ResultBuilder Results(*this);
3012 Results.EnterNewScope();
3013
3014 // FIXME: We need to do this because Objective-C methods don't get
3015 // pushed into DeclContexts early enough. Argh!
3016 for (unsigned I = 0; I != NumMethods; ++I) {
3017 if (ObjCMethodDecl *Method
3018 = dyn_cast_or_null<ObjCMethodDecl>(Methods[I].getAs<Decl>()))
3019 if (Method->isInstanceMethod() &&
3020 isAcceptableObjCMethod(Method, MK_OneArgSelector, 0, 0)) {
3021 Result R = Result(Method, 0);
3022 R.AllParametersAreInformative = true;
3023 Results.MaybeAddResult(R, CurContext);
3024 }
3025 }
3026
3027 AddObjCMethods(Class, true, MK_OneArgSelector, 0, 0, CurContext, Results);
3028
3029 Results.ExitScope();
3030 HandleCodeCompleteResults(this, CodeCompleter,Results.data(),Results.size());
Douglas Gregorbab2b3c2009-11-17 23:22:23 +00003031}
3032
Douglas Gregor9d2ddb22010-04-06 19:22:33 +00003033/// \brief When we have an expression with type "id", we may assume
3034/// that it has some more-specific class type based on knowledge of
3035/// common uses of Objective-C. This routine returns that class type,
3036/// or NULL if no better result could be determined.
3037static ObjCInterfaceDecl *GetAssumedMessageSendExprType(Expr *E) {
3038 ObjCMessageExpr *Msg = dyn_cast<ObjCMessageExpr>(E);
3039 if (!Msg)
3040 return 0;
3041
3042 Selector Sel = Msg->getSelector();
3043 if (Sel.isNull())
3044 return 0;
3045
3046 IdentifierInfo *Id = Sel.getIdentifierInfoForSlot(0);
3047 if (!Id)
3048 return 0;
3049
3050 ObjCMethodDecl *Method = Msg->getMethodDecl();
3051 if (!Method)
3052 return 0;
3053
3054 // Determine the class that we're sending the message to.
Douglas Gregor9a129192010-04-21 00:45:42 +00003055 ObjCInterfaceDecl *IFace = 0;
3056 switch (Msg->getReceiverKind()) {
3057 case ObjCMessageExpr::Class:
John McCall8b07ec22010-05-15 11:32:37 +00003058 if (const ObjCObjectType *ObjType
3059 = Msg->getClassReceiver()->getAs<ObjCObjectType>())
3060 IFace = ObjType->getInterface();
Douglas Gregor9a129192010-04-21 00:45:42 +00003061 break;
3062
3063 case ObjCMessageExpr::Instance: {
3064 QualType T = Msg->getInstanceReceiver()->getType();
3065 if (const ObjCObjectPointerType *Ptr = T->getAs<ObjCObjectPointerType>())
3066 IFace = Ptr->getInterfaceDecl();
3067 break;
3068 }
3069
3070 case ObjCMessageExpr::SuperInstance:
3071 case ObjCMessageExpr::SuperClass:
3072 break;
Douglas Gregor9d2ddb22010-04-06 19:22:33 +00003073 }
3074
3075 if (!IFace)
3076 return 0;
3077
3078 ObjCInterfaceDecl *Super = IFace->getSuperClass();
3079 if (Method->isInstanceMethod())
3080 return llvm::StringSwitch<ObjCInterfaceDecl *>(Id->getName())
3081 .Case("retain", IFace)
3082 .Case("autorelease", IFace)
3083 .Case("copy", IFace)
3084 .Case("copyWithZone", IFace)
3085 .Case("mutableCopy", IFace)
3086 .Case("mutableCopyWithZone", IFace)
3087 .Case("awakeFromCoder", IFace)
3088 .Case("replacementObjectFromCoder", IFace)
3089 .Case("class", IFace)
3090 .Case("classForCoder", IFace)
3091 .Case("superclass", Super)
3092 .Default(0);
3093
3094 return llvm::StringSwitch<ObjCInterfaceDecl *>(Id->getName())
3095 .Case("new", IFace)
3096 .Case("alloc", IFace)
3097 .Case("allocWithZone", IFace)
3098 .Case("class", IFace)
3099 .Case("superclass", Super)
3100 .Default(0);
3101}
3102
Douglas Gregora817a192010-05-27 23:06:34 +00003103void Sema::CodeCompleteObjCMessageReceiver(Scope *S) {
3104 typedef CodeCompleteConsumer::Result Result;
3105 ResultBuilder Results(*this);
3106
3107 // Find anything that looks like it could be a message receiver.
3108 Results.setFilter(&ResultBuilder::IsObjCMessageReceiver);
3109 CodeCompletionDeclConsumer Consumer(Results, CurContext);
3110 Results.EnterNewScope();
3111 LookupVisibleDecls(S, LookupOrdinaryName, Consumer);
3112
3113 // If we are in an Objective-C method inside a class that has a superclass,
3114 // add "super" as an option.
3115 if (ObjCMethodDecl *Method = getCurMethodDecl())
3116 if (ObjCInterfaceDecl *Iface = Method->getClassInterface())
3117 if (Iface->getSuperClass())
3118 Results.AddResult(Result("super"));
3119
3120 Results.ExitScope();
3121
3122 if (CodeCompleter->includeMacros())
3123 AddMacroResults(PP, Results);
3124 HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
3125
3126}
3127
Douglas Gregor0c78ad92010-04-21 19:57:20 +00003128void Sema::CodeCompleteObjCSuperMessage(Scope *S, SourceLocation SuperLoc,
3129 IdentifierInfo **SelIdents,
3130 unsigned NumSelIdents) {
3131 ObjCInterfaceDecl *CDecl = 0;
3132 if (ObjCMethodDecl *CurMethod = getCurMethodDecl()) {
3133 // Figure out which interface we're in.
3134 CDecl = CurMethod->getClassInterface();
3135 if (!CDecl)
3136 return;
3137
3138 // Find the superclass of this class.
3139 CDecl = CDecl->getSuperClass();
3140 if (!CDecl)
3141 return;
3142
3143 if (CurMethod->isInstanceMethod()) {
3144 // We are inside an instance method, which means that the message
3145 // send [super ...] is actually calling an instance method on the
3146 // current object. Build the super expression and handle this like
3147 // an instance method.
3148 QualType SuperTy = Context.getObjCInterfaceType(CDecl);
3149 SuperTy = Context.getObjCObjectPointerType(SuperTy);
3150 OwningExprResult Super
3151 = Owned(new (Context) ObjCSuperExpr(SuperLoc, SuperTy));
3152 return CodeCompleteObjCInstanceMessage(S, (Expr *)Super.get(),
3153 SelIdents, NumSelIdents);
3154 }
3155
3156 // Fall through to send to the superclass in CDecl.
3157 } else {
3158 // "super" may be the name of a type or variable. Figure out which
3159 // it is.
3160 IdentifierInfo *Super = &Context.Idents.get("super");
3161 NamedDecl *ND = LookupSingleName(S, Super, SuperLoc,
3162 LookupOrdinaryName);
3163 if ((CDecl = dyn_cast_or_null<ObjCInterfaceDecl>(ND))) {
3164 // "super" names an interface. Use it.
3165 } else if (TypeDecl *TD = dyn_cast_or_null<TypeDecl>(ND)) {
John McCall8b07ec22010-05-15 11:32:37 +00003166 if (const ObjCObjectType *Iface
3167 = Context.getTypeDeclType(TD)->getAs<ObjCObjectType>())
3168 CDecl = Iface->getInterface();
Douglas Gregor0c78ad92010-04-21 19:57:20 +00003169 } else if (ND && isa<UnresolvedUsingTypenameDecl>(ND)) {
3170 // "super" names an unresolved type; we can't be more specific.
3171 } else {
3172 // Assume that "super" names some kind of value and parse that way.
3173 CXXScopeSpec SS;
3174 UnqualifiedId id;
3175 id.setIdentifier(Super, SuperLoc);
3176 OwningExprResult SuperExpr = ActOnIdExpression(S, SS, id, false, false);
3177 return CodeCompleteObjCInstanceMessage(S, (Expr *)SuperExpr.get(),
3178 SelIdents, NumSelIdents);
3179 }
3180
3181 // Fall through
3182 }
3183
3184 TypeTy *Receiver = 0;
3185 if (CDecl)
3186 Receiver = Context.getObjCInterfaceType(CDecl).getAsOpaquePtr();
3187 return CodeCompleteObjCClassMessage(S, Receiver, SelIdents,
3188 NumSelIdents);
3189}
3190
3191void Sema::CodeCompleteObjCClassMessage(Scope *S, TypeTy *Receiver,
Douglas Gregor1b605f72009-11-19 01:08:35 +00003192 IdentifierInfo **SelIdents,
3193 unsigned NumSelIdents) {
Steve Naroffeae65032009-11-07 02:08:14 +00003194 typedef CodeCompleteConsumer::Result Result;
Douglas Gregor8ce33212009-11-17 17:59:40 +00003195 ObjCInterfaceDecl *CDecl = 0;
3196
Douglas Gregor8ce33212009-11-17 17:59:40 +00003197 // If the given name refers to an interface type, retrieve the
3198 // corresponding declaration.
Douglas Gregor0c78ad92010-04-21 19:57:20 +00003199 if (Receiver) {
3200 QualType T = GetTypeFromParser(Receiver, 0);
3201 if (!T.isNull())
John McCall8b07ec22010-05-15 11:32:37 +00003202 if (const ObjCObjectType *Interface = T->getAs<ObjCObjectType>())
3203 CDecl = Interface->getInterface();
Douglas Gregor8ce33212009-11-17 17:59:40 +00003204 }
3205
Douglas Gregorbab2b3c2009-11-17 23:22:23 +00003206 // Add all of the factory methods in this Objective-C class, its protocols,
3207 // superclasses, categories, implementation, etc.
Steve Naroffeae65032009-11-07 02:08:14 +00003208 ResultBuilder Results(*this);
3209 Results.EnterNewScope();
Douglas Gregor6285f752010-04-06 16:40:00 +00003210
3211 if (CDecl)
3212 AddObjCMethods(CDecl, false, MK_Any, SelIdents, NumSelIdents, CurContext,
3213 Results);
Douglas Gregor0c78ad92010-04-21 19:57:20 +00003214 else {
Douglas Gregor6285f752010-04-06 16:40:00 +00003215 // We're messaging "id" as a type; provide all class/factory methods.
3216
Douglas Gregord720daf2010-04-06 17:30:22 +00003217 // If we have an external source, load the entire class method
3218 // pool from the PCH file.
3219 if (ExternalSource) {
3220 for (uint32_t I = 0, N = ExternalSource->GetNumKnownSelectors(); I != N;
3221 ++I) {
3222 Selector Sel = ExternalSource->GetSelector(I);
3223 if (Sel.isNull() || FactoryMethodPool.count(Sel) ||
3224 InstanceMethodPool.count(Sel))
3225 continue;
3226
3227 ReadMethodPool(Sel, /*isInstance=*/false);
3228 }
3229 }
3230
Douglas Gregor6285f752010-04-06 16:40:00 +00003231 for (llvm::DenseMap<Selector, ObjCMethodList>::iterator
3232 M = FactoryMethodPool.begin(),
3233 MEnd = FactoryMethodPool.end();
3234 M != MEnd;
3235 ++M) {
Douglas Gregord720daf2010-04-06 17:30:22 +00003236 for (ObjCMethodList *MethList = &M->second; MethList && MethList->Method;
Douglas Gregor6285f752010-04-06 16:40:00 +00003237 MethList = MethList->Next) {
3238 if (!isAcceptableObjCMethod(MethList->Method, MK_Any, SelIdents,
3239 NumSelIdents))
3240 continue;
3241
3242 Result R(MethList->Method, 0);
3243 R.StartParameter = NumSelIdents;
3244 R.AllParametersAreInformative = false;
3245 Results.MaybeAddResult(R, CurContext);
3246 }
3247 }
3248 }
3249
Steve Naroffeae65032009-11-07 02:08:14 +00003250 Results.ExitScope();
Daniel Dunbar242ea9a2009-11-13 08:58:20 +00003251 HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
Steve Naroffeae65032009-11-07 02:08:14 +00003252}
3253
Douglas Gregor1b605f72009-11-19 01:08:35 +00003254void Sema::CodeCompleteObjCInstanceMessage(Scope *S, ExprTy *Receiver,
3255 IdentifierInfo **SelIdents,
3256 unsigned NumSelIdents) {
Steve Naroffeae65032009-11-07 02:08:14 +00003257 typedef CodeCompleteConsumer::Result Result;
Steve Naroffeae65032009-11-07 02:08:14 +00003258
3259 Expr *RecExpr = static_cast<Expr *>(Receiver);
Steve Naroffeae65032009-11-07 02:08:14 +00003260
Douglas Gregorbab2b3c2009-11-17 23:22:23 +00003261 // If necessary, apply function/array conversion to the receiver.
3262 // C99 6.7.5.3p[7,8].
Douglas Gregorb92a1562010-02-03 00:27:59 +00003263 DefaultFunctionArrayLvalueConversion(RecExpr);
Douglas Gregorbab2b3c2009-11-17 23:22:23 +00003264 QualType ReceiverType = RecExpr->getType();
Steve Naroffeae65032009-11-07 02:08:14 +00003265
Douglas Gregorbab2b3c2009-11-17 23:22:23 +00003266 // Build the set of methods we can see.
3267 ResultBuilder Results(*this);
3268 Results.EnterNewScope();
Douglas Gregor9d2ddb22010-04-06 19:22:33 +00003269
3270 // If we're messaging an expression with type "id" or "Class", check
3271 // whether we know something special about the receiver that allows
3272 // us to assume a more-specific receiver type.
3273 if (ReceiverType->isObjCIdType() || ReceiverType->isObjCClassType())
3274 if (ObjCInterfaceDecl *IFace = GetAssumedMessageSendExprType(RecExpr))
3275 ReceiverType = Context.getObjCObjectPointerType(
3276 Context.getObjCInterfaceType(IFace));
Douglas Gregorbab2b3c2009-11-17 23:22:23 +00003277
Douglas Gregora3329fa2009-11-18 00:06:18 +00003278 // Handle messages to Class. This really isn't a message to an instance
3279 // method, so we treat it the same way we would treat a message send to a
3280 // class method.
3281 if (ReceiverType->isObjCClassType() ||
3282 ReceiverType->isObjCQualifiedClassType()) {
3283 if (ObjCMethodDecl *CurMethod = getCurMethodDecl()) {
3284 if (ObjCInterfaceDecl *ClassDecl = CurMethod->getClassInterface())
Douglas Gregorc8537c52009-11-19 07:41:15 +00003285 AddObjCMethods(ClassDecl, false, MK_Any, SelIdents, NumSelIdents,
3286 CurContext, Results);
Douglas Gregora3329fa2009-11-18 00:06:18 +00003287 }
3288 }
3289 // Handle messages to a qualified ID ("id<foo>").
3290 else if (const ObjCObjectPointerType *QualID
3291 = ReceiverType->getAsObjCQualifiedIdType()) {
3292 // Search protocols for instance methods.
3293 for (ObjCObjectPointerType::qual_iterator I = QualID->qual_begin(),
3294 E = QualID->qual_end();
3295 I != E; ++I)
Douglas Gregorc8537c52009-11-19 07:41:15 +00003296 AddObjCMethods(*I, true, MK_Any, SelIdents, NumSelIdents, CurContext,
3297 Results);
Douglas Gregora3329fa2009-11-18 00:06:18 +00003298 }
3299 // Handle messages to a pointer to interface type.
3300 else if (const ObjCObjectPointerType *IFacePtr
3301 = ReceiverType->getAsObjCInterfacePointerType()) {
3302 // Search the class, its superclasses, etc., for instance methods.
Douglas Gregorc8537c52009-11-19 07:41:15 +00003303 AddObjCMethods(IFacePtr->getInterfaceDecl(), true, MK_Any, SelIdents,
3304 NumSelIdents, CurContext, Results);
Douglas Gregora3329fa2009-11-18 00:06:18 +00003305
3306 // Search protocols for instance methods.
3307 for (ObjCObjectPointerType::qual_iterator I = IFacePtr->qual_begin(),
3308 E = IFacePtr->qual_end();
3309 I != E; ++I)
Douglas Gregorc8537c52009-11-19 07:41:15 +00003310 AddObjCMethods(*I, true, MK_Any, SelIdents, NumSelIdents, CurContext,
3311 Results);
Douglas Gregora3329fa2009-11-18 00:06:18 +00003312 }
Douglas Gregor6285f752010-04-06 16:40:00 +00003313 // Handle messages to "id".
3314 else if (ReceiverType->isObjCIdType()) {
Douglas Gregord720daf2010-04-06 17:30:22 +00003315 // We're messaging "id", so provide all instance methods we know
3316 // about as code-completion results.
3317
3318 // If we have an external source, load the entire class method
3319 // pool from the PCH file.
3320 if (ExternalSource) {
3321 for (uint32_t I = 0, N = ExternalSource->GetNumKnownSelectors(); I != N;
3322 ++I) {
3323 Selector Sel = ExternalSource->GetSelector(I);
3324 if (Sel.isNull() || InstanceMethodPool.count(Sel) ||
3325 FactoryMethodPool.count(Sel))
3326 continue;
3327
3328 ReadMethodPool(Sel, /*isInstance=*/true);
3329 }
3330 }
3331
Douglas Gregor6285f752010-04-06 16:40:00 +00003332 for (llvm::DenseMap<Selector, ObjCMethodList>::iterator
3333 M = InstanceMethodPool.begin(),
3334 MEnd = InstanceMethodPool.end();
3335 M != MEnd;
3336 ++M) {
Douglas Gregord720daf2010-04-06 17:30:22 +00003337 for (ObjCMethodList *MethList = &M->second; MethList && MethList->Method;
Douglas Gregor6285f752010-04-06 16:40:00 +00003338 MethList = MethList->Next) {
3339 if (!isAcceptableObjCMethod(MethList->Method, MK_Any, SelIdents,
3340 NumSelIdents))
3341 continue;
3342
3343 Result R(MethList->Method, 0);
3344 R.StartParameter = NumSelIdents;
3345 R.AllParametersAreInformative = false;
3346 Results.MaybeAddResult(R, CurContext);
3347 }
3348 }
3349 }
3350
Steve Naroffeae65032009-11-07 02:08:14 +00003351 Results.ExitScope();
Daniel Dunbar242ea9a2009-11-13 08:58:20 +00003352 HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
Steve Naroffeae65032009-11-07 02:08:14 +00003353}
Douglas Gregorbaf69612009-11-18 04:19:12 +00003354
3355/// \brief Add all of the protocol declarations that we find in the given
3356/// (translation unit) context.
3357static void AddProtocolResults(DeclContext *Ctx, DeclContext *CurContext,
Douglas Gregor5b4671c2009-11-18 04:49:41 +00003358 bool OnlyForwardDeclarations,
Douglas Gregorbaf69612009-11-18 04:19:12 +00003359 ResultBuilder &Results) {
3360 typedef CodeCompleteConsumer::Result Result;
3361
3362 for (DeclContext::decl_iterator D = Ctx->decls_begin(),
3363 DEnd = Ctx->decls_end();
3364 D != DEnd; ++D) {
3365 // Record any protocols we find.
3366 if (ObjCProtocolDecl *Proto = dyn_cast<ObjCProtocolDecl>(*D))
Douglas Gregor5b4671c2009-11-18 04:49:41 +00003367 if (!OnlyForwardDeclarations || Proto->isForwardDecl())
Douglas Gregorfc59ce12010-01-14 16:14:35 +00003368 Results.AddResult(Result(Proto, 0), CurContext, 0, false);
Douglas Gregorbaf69612009-11-18 04:19:12 +00003369
3370 // Record any forward-declared protocols we find.
3371 if (ObjCForwardProtocolDecl *Forward
3372 = dyn_cast<ObjCForwardProtocolDecl>(*D)) {
3373 for (ObjCForwardProtocolDecl::protocol_iterator
3374 P = Forward->protocol_begin(),
3375 PEnd = Forward->protocol_end();
3376 P != PEnd; ++P)
Douglas Gregor5b4671c2009-11-18 04:49:41 +00003377 if (!OnlyForwardDeclarations || (*P)->isForwardDecl())
Douglas Gregorfc59ce12010-01-14 16:14:35 +00003378 Results.AddResult(Result(*P, 0), CurContext, 0, false);
Douglas Gregorbaf69612009-11-18 04:19:12 +00003379 }
3380 }
3381}
3382
3383void Sema::CodeCompleteObjCProtocolReferences(IdentifierLocPair *Protocols,
3384 unsigned NumProtocols) {
3385 ResultBuilder Results(*this);
3386 Results.EnterNewScope();
3387
3388 // Tell the result set to ignore all of the protocols we have
3389 // already seen.
3390 for (unsigned I = 0; I != NumProtocols; ++I)
Douglas Gregorb2ccf012010-04-15 22:33:43 +00003391 if (ObjCProtocolDecl *Protocol = LookupProtocol(Protocols[I].first,
3392 Protocols[I].second))
Douglas Gregorbaf69612009-11-18 04:19:12 +00003393 Results.Ignore(Protocol);
3394
3395 // Add all protocols.
Douglas Gregor5b4671c2009-11-18 04:49:41 +00003396 AddProtocolResults(Context.getTranslationUnitDecl(), CurContext, false,
3397 Results);
3398
3399 Results.ExitScope();
3400 HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
3401}
3402
3403void Sema::CodeCompleteObjCProtocolDecl(Scope *) {
3404 ResultBuilder Results(*this);
3405 Results.EnterNewScope();
3406
3407 // Add all protocols.
3408 AddProtocolResults(Context.getTranslationUnitDecl(), CurContext, true,
3409 Results);
Douglas Gregorbaf69612009-11-18 04:19:12 +00003410
3411 Results.ExitScope();
3412 HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
3413}
Douglas Gregor49c22a72009-11-18 16:26:39 +00003414
3415/// \brief Add all of the Objective-C interface declarations that we find in
3416/// the given (translation unit) context.
3417static void AddInterfaceResults(DeclContext *Ctx, DeclContext *CurContext,
3418 bool OnlyForwardDeclarations,
3419 bool OnlyUnimplemented,
3420 ResultBuilder &Results) {
3421 typedef CodeCompleteConsumer::Result Result;
3422
3423 for (DeclContext::decl_iterator D = Ctx->decls_begin(),
3424 DEnd = Ctx->decls_end();
3425 D != DEnd; ++D) {
3426 // Record any interfaces we find.
3427 if (ObjCInterfaceDecl *Class = dyn_cast<ObjCInterfaceDecl>(*D))
3428 if ((!OnlyForwardDeclarations || Class->isForwardDecl()) &&
3429 (!OnlyUnimplemented || !Class->getImplementation()))
Douglas Gregorfc59ce12010-01-14 16:14:35 +00003430 Results.AddResult(Result(Class, 0), CurContext, 0, false);
Douglas Gregor49c22a72009-11-18 16:26:39 +00003431
3432 // Record any forward-declared interfaces we find.
3433 if (ObjCClassDecl *Forward = dyn_cast<ObjCClassDecl>(*D)) {
3434 for (ObjCClassDecl::iterator C = Forward->begin(), CEnd = Forward->end();
3435 C != CEnd; ++C)
3436 if ((!OnlyForwardDeclarations || C->getInterface()->isForwardDecl()) &&
3437 (!OnlyUnimplemented || !C->getInterface()->getImplementation()))
Douglas Gregorfc59ce12010-01-14 16:14:35 +00003438 Results.AddResult(Result(C->getInterface(), 0), CurContext,
3439 0, false);
Douglas Gregor49c22a72009-11-18 16:26:39 +00003440 }
3441 }
3442}
3443
3444void Sema::CodeCompleteObjCInterfaceDecl(Scope *S) {
3445 ResultBuilder Results(*this);
3446 Results.EnterNewScope();
3447
3448 // Add all classes.
3449 AddInterfaceResults(Context.getTranslationUnitDecl(), CurContext, true,
3450 false, Results);
3451
3452 Results.ExitScope();
3453 HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
3454}
3455
Douglas Gregorb2ccf012010-04-15 22:33:43 +00003456void Sema::CodeCompleteObjCSuperclass(Scope *S, IdentifierInfo *ClassName,
3457 SourceLocation ClassNameLoc) {
Douglas Gregor49c22a72009-11-18 16:26:39 +00003458 ResultBuilder Results(*this);
3459 Results.EnterNewScope();
3460
3461 // Make sure that we ignore the class we're currently defining.
3462 NamedDecl *CurClass
Douglas Gregorb2ccf012010-04-15 22:33:43 +00003463 = LookupSingleName(TUScope, ClassName, ClassNameLoc, LookupOrdinaryName);
Douglas Gregor5d34fd32009-11-18 19:08:43 +00003464 if (CurClass && isa<ObjCInterfaceDecl>(CurClass))
Douglas Gregor49c22a72009-11-18 16:26:39 +00003465 Results.Ignore(CurClass);
3466
3467 // Add all classes.
3468 AddInterfaceResults(Context.getTranslationUnitDecl(), CurContext, false,
3469 false, Results);
3470
3471 Results.ExitScope();
3472 HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
3473}
3474
3475void Sema::CodeCompleteObjCImplementationDecl(Scope *S) {
3476 ResultBuilder Results(*this);
3477 Results.EnterNewScope();
3478
3479 // Add all unimplemented classes.
3480 AddInterfaceResults(Context.getTranslationUnitDecl(), CurContext, false,
3481 true, Results);
3482
3483 Results.ExitScope();
3484 HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
3485}
Douglas Gregor5d34fd32009-11-18 19:08:43 +00003486
3487void Sema::CodeCompleteObjCInterfaceCategory(Scope *S,
Douglas Gregorb2ccf012010-04-15 22:33:43 +00003488 IdentifierInfo *ClassName,
3489 SourceLocation ClassNameLoc) {
Douglas Gregor5d34fd32009-11-18 19:08:43 +00003490 typedef CodeCompleteConsumer::Result Result;
3491
3492 ResultBuilder Results(*this);
3493
3494 // Ignore any categories we find that have already been implemented by this
3495 // interface.
3496 llvm::SmallPtrSet<IdentifierInfo *, 16> CategoryNames;
3497 NamedDecl *CurClass
Douglas Gregorb2ccf012010-04-15 22:33:43 +00003498 = LookupSingleName(TUScope, ClassName, ClassNameLoc, LookupOrdinaryName);
Douglas Gregor5d34fd32009-11-18 19:08:43 +00003499 if (ObjCInterfaceDecl *Class = dyn_cast_or_null<ObjCInterfaceDecl>(CurClass))
3500 for (ObjCCategoryDecl *Category = Class->getCategoryList(); Category;
3501 Category = Category->getNextClassCategory())
3502 CategoryNames.insert(Category->getIdentifier());
3503
3504 // Add all of the categories we know about.
3505 Results.EnterNewScope();
3506 TranslationUnitDecl *TU = Context.getTranslationUnitDecl();
3507 for (DeclContext::decl_iterator D = TU->decls_begin(),
3508 DEnd = TU->decls_end();
3509 D != DEnd; ++D)
3510 if (ObjCCategoryDecl *Category = dyn_cast<ObjCCategoryDecl>(*D))
3511 if (CategoryNames.insert(Category->getIdentifier()))
Douglas Gregorfc59ce12010-01-14 16:14:35 +00003512 Results.AddResult(Result(Category, 0), CurContext, 0, false);
Douglas Gregor5d34fd32009-11-18 19:08:43 +00003513 Results.ExitScope();
3514
3515 HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
3516}
3517
3518void Sema::CodeCompleteObjCImplementationCategory(Scope *S,
Douglas Gregorb2ccf012010-04-15 22:33:43 +00003519 IdentifierInfo *ClassName,
3520 SourceLocation ClassNameLoc) {
Douglas Gregor5d34fd32009-11-18 19:08:43 +00003521 typedef CodeCompleteConsumer::Result Result;
3522
3523 // Find the corresponding interface. If we couldn't find the interface, the
3524 // program itself is ill-formed. However, we'll try to be helpful still by
3525 // providing the list of all of the categories we know about.
3526 NamedDecl *CurClass
Douglas Gregorb2ccf012010-04-15 22:33:43 +00003527 = LookupSingleName(TUScope, ClassName, ClassNameLoc, LookupOrdinaryName);
Douglas Gregor5d34fd32009-11-18 19:08:43 +00003528 ObjCInterfaceDecl *Class = dyn_cast_or_null<ObjCInterfaceDecl>(CurClass);
3529 if (!Class)
Douglas Gregorb2ccf012010-04-15 22:33:43 +00003530 return CodeCompleteObjCInterfaceCategory(S, ClassName, ClassNameLoc);
Douglas Gregor5d34fd32009-11-18 19:08:43 +00003531
3532 ResultBuilder Results(*this);
3533
3534 // Add all of the categories that have have corresponding interface
3535 // declarations in this class and any of its superclasses, except for
3536 // already-implemented categories in the class itself.
3537 llvm::SmallPtrSet<IdentifierInfo *, 16> CategoryNames;
3538 Results.EnterNewScope();
3539 bool IgnoreImplemented = true;
3540 while (Class) {
3541 for (ObjCCategoryDecl *Category = Class->getCategoryList(); Category;
3542 Category = Category->getNextClassCategory())
3543 if ((!IgnoreImplemented || !Category->getImplementation()) &&
3544 CategoryNames.insert(Category->getIdentifier()))
Douglas Gregorfc59ce12010-01-14 16:14:35 +00003545 Results.AddResult(Result(Category, 0), CurContext, 0, false);
Douglas Gregor5d34fd32009-11-18 19:08:43 +00003546
3547 Class = Class->getSuperClass();
3548 IgnoreImplemented = false;
3549 }
3550 Results.ExitScope();
3551
3552 HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
3553}
Douglas Gregor5d649882009-11-18 22:32:06 +00003554
Douglas Gregor52e78bd2009-11-18 22:56:13 +00003555void Sema::CodeCompleteObjCPropertyDefinition(Scope *S, DeclPtrTy ObjCImpDecl) {
Douglas Gregor5d649882009-11-18 22:32:06 +00003556 typedef CodeCompleteConsumer::Result Result;
3557 ResultBuilder Results(*this);
3558
3559 // Figure out where this @synthesize lives.
3560 ObjCContainerDecl *Container
3561 = dyn_cast_or_null<ObjCContainerDecl>(ObjCImpDecl.getAs<Decl>());
3562 if (!Container ||
3563 (!isa<ObjCImplementationDecl>(Container) &&
3564 !isa<ObjCCategoryImplDecl>(Container)))
3565 return;
3566
3567 // Ignore any properties that have already been implemented.
3568 for (DeclContext::decl_iterator D = Container->decls_begin(),
3569 DEnd = Container->decls_end();
3570 D != DEnd; ++D)
3571 if (ObjCPropertyImplDecl *PropertyImpl = dyn_cast<ObjCPropertyImplDecl>(*D))
3572 Results.Ignore(PropertyImpl->getPropertyDecl());
3573
3574 // Add any properties that we find.
3575 Results.EnterNewScope();
3576 if (ObjCImplementationDecl *ClassImpl
3577 = dyn_cast<ObjCImplementationDecl>(Container))
3578 AddObjCProperties(ClassImpl->getClassInterface(), false, CurContext,
3579 Results);
3580 else
3581 AddObjCProperties(cast<ObjCCategoryImplDecl>(Container)->getCategoryDecl(),
3582 false, CurContext, Results);
3583 Results.ExitScope();
3584
3585 HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
3586}
3587
3588void Sema::CodeCompleteObjCPropertySynthesizeIvar(Scope *S,
3589 IdentifierInfo *PropertyName,
3590 DeclPtrTy ObjCImpDecl) {
3591 typedef CodeCompleteConsumer::Result Result;
3592 ResultBuilder Results(*this);
3593
3594 // Figure out where this @synthesize lives.
3595 ObjCContainerDecl *Container
3596 = dyn_cast_or_null<ObjCContainerDecl>(ObjCImpDecl.getAs<Decl>());
3597 if (!Container ||
3598 (!isa<ObjCImplementationDecl>(Container) &&
3599 !isa<ObjCCategoryImplDecl>(Container)))
3600 return;
3601
3602 // Figure out which interface we're looking into.
3603 ObjCInterfaceDecl *Class = 0;
3604 if (ObjCImplementationDecl *ClassImpl
3605 = dyn_cast<ObjCImplementationDecl>(Container))
3606 Class = ClassImpl->getClassInterface();
3607 else
3608 Class = cast<ObjCCategoryImplDecl>(Container)->getCategoryDecl()
3609 ->getClassInterface();
3610
3611 // Add all of the instance variables in this class and its superclasses.
3612 Results.EnterNewScope();
3613 for(; Class; Class = Class->getSuperClass()) {
3614 // FIXME: We could screen the type of each ivar for compatibility with
3615 // the property, but is that being too paternal?
3616 for (ObjCInterfaceDecl::ivar_iterator IVar = Class->ivar_begin(),
3617 IVarEnd = Class->ivar_end();
3618 IVar != IVarEnd; ++IVar)
Douglas Gregorfc59ce12010-01-14 16:14:35 +00003619 Results.AddResult(Result(*IVar, 0), CurContext, 0, false);
Douglas Gregor5d649882009-11-18 22:32:06 +00003620 }
3621 Results.ExitScope();
3622
3623 HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
3624}
Douglas Gregor636a61e2010-04-07 00:21:17 +00003625
3626typedef llvm::DenseMap<Selector, ObjCMethodDecl *> KnownMethodsMap;
3627
3628/// \brief Find all of the methods that reside in the given container
3629/// (and its superclasses, protocols, etc.) that meet the given
3630/// criteria. Insert those methods into the map of known methods,
3631/// indexed by selector so they can be easily found.
3632static void FindImplementableMethods(ASTContext &Context,
3633 ObjCContainerDecl *Container,
3634 bool WantInstanceMethods,
3635 QualType ReturnType,
3636 bool IsInImplementation,
3637 KnownMethodsMap &KnownMethods) {
3638 if (ObjCInterfaceDecl *IFace = dyn_cast<ObjCInterfaceDecl>(Container)) {
3639 // Recurse into protocols.
3640 const ObjCList<ObjCProtocolDecl> &Protocols
3641 = IFace->getReferencedProtocols();
3642 for (ObjCList<ObjCProtocolDecl>::iterator I = Protocols.begin(),
3643 E = Protocols.end();
3644 I != E; ++I)
3645 FindImplementableMethods(Context, *I, WantInstanceMethods, ReturnType,
3646 IsInImplementation, KnownMethods);
3647
3648 // If we're not in the implementation of a class, also visit the
3649 // superclass.
3650 if (!IsInImplementation && IFace->getSuperClass())
3651 FindImplementableMethods(Context, IFace->getSuperClass(),
3652 WantInstanceMethods, ReturnType,
3653 IsInImplementation, KnownMethods);
3654
3655 // Add methods from any class extensions (but not from categories;
3656 // those should go into category implementations).
3657 for (ObjCCategoryDecl *Cat = IFace->getCategoryList(); Cat;
3658 Cat = Cat->getNextClassCategory()) {
3659 if (!Cat->IsClassExtension())
3660 continue;
3661
3662 FindImplementableMethods(Context, Cat, WantInstanceMethods, ReturnType,
3663 IsInImplementation, KnownMethods);
3664 }
3665 }
3666
3667 if (ObjCCategoryDecl *Category = dyn_cast<ObjCCategoryDecl>(Container)) {
3668 // Recurse into protocols.
3669 const ObjCList<ObjCProtocolDecl> &Protocols
3670 = Category->getReferencedProtocols();
3671 for (ObjCList<ObjCProtocolDecl>::iterator I = Protocols.begin(),
3672 E = Protocols.end();
3673 I != E; ++I)
3674 FindImplementableMethods(Context, *I, WantInstanceMethods, ReturnType,
3675 IsInImplementation, KnownMethods);
3676 }
3677
3678 if (ObjCProtocolDecl *Protocol = dyn_cast<ObjCProtocolDecl>(Container)) {
3679 // Recurse into protocols.
3680 const ObjCList<ObjCProtocolDecl> &Protocols
3681 = Protocol->getReferencedProtocols();
3682 for (ObjCList<ObjCProtocolDecl>::iterator I = Protocols.begin(),
3683 E = Protocols.end();
3684 I != E; ++I)
3685 FindImplementableMethods(Context, *I, WantInstanceMethods, ReturnType,
3686 IsInImplementation, KnownMethods);
3687 }
3688
3689 // Add methods in this container. This operation occurs last because
3690 // we want the methods from this container to override any methods
3691 // we've previously seen with the same selector.
3692 for (ObjCContainerDecl::method_iterator M = Container->meth_begin(),
3693 MEnd = Container->meth_end();
3694 M != MEnd; ++M) {
3695 if ((*M)->isInstanceMethod() == WantInstanceMethods) {
3696 if (!ReturnType.isNull() &&
3697 !Context.hasSameUnqualifiedType(ReturnType, (*M)->getResultType()))
3698 continue;
3699
3700 KnownMethods[(*M)->getSelector()] = *M;
3701 }
3702 }
3703}
3704
3705void Sema::CodeCompleteObjCMethodDecl(Scope *S,
3706 bool IsInstanceMethod,
3707 TypeTy *ReturnTy,
3708 DeclPtrTy IDecl) {
3709 // Determine the return type of the method we're declaring, if
3710 // provided.
3711 QualType ReturnType = GetTypeFromParser(ReturnTy);
3712
3713 // Determine where we should start searching for methods, and where we
3714 ObjCContainerDecl *SearchDecl = 0, *CurrentDecl = 0;
3715 bool IsInImplementation = false;
3716 if (Decl *D = IDecl.getAs<Decl>()) {
3717 if (ObjCImplementationDecl *Impl = dyn_cast<ObjCImplementationDecl>(D)) {
3718 SearchDecl = Impl->getClassInterface();
3719 CurrentDecl = Impl;
3720 IsInImplementation = true;
3721 } else if (ObjCCategoryImplDecl *CatImpl
3722 = dyn_cast<ObjCCategoryImplDecl>(D)) {
3723 SearchDecl = CatImpl->getCategoryDecl();
3724 CurrentDecl = CatImpl;
3725 IsInImplementation = true;
3726 } else {
3727 SearchDecl = dyn_cast<ObjCContainerDecl>(D);
3728 CurrentDecl = SearchDecl;
3729 }
3730 }
3731
3732 if (!SearchDecl && S) {
3733 if (DeclContext *DC = static_cast<DeclContext *>(S->getEntity())) {
3734 SearchDecl = dyn_cast<ObjCContainerDecl>(DC);
3735 CurrentDecl = SearchDecl;
3736 }
3737 }
3738
3739 if (!SearchDecl || !CurrentDecl) {
3740 HandleCodeCompleteResults(this, CodeCompleter, 0, 0);
3741 return;
3742 }
3743
3744 // Find all of the methods that we could declare/implement here.
3745 KnownMethodsMap KnownMethods;
3746 FindImplementableMethods(Context, SearchDecl, IsInstanceMethod,
3747 ReturnType, IsInImplementation, KnownMethods);
3748
3749 // Erase any methods that have already been declared or
3750 // implemented here.
3751 for (ObjCContainerDecl::method_iterator M = CurrentDecl->meth_begin(),
3752 MEnd = CurrentDecl->meth_end();
3753 M != MEnd; ++M) {
3754 if ((*M)->isInstanceMethod() != IsInstanceMethod)
3755 continue;
3756
3757 KnownMethodsMap::iterator Pos = KnownMethods.find((*M)->getSelector());
3758 if (Pos != KnownMethods.end())
3759 KnownMethods.erase(Pos);
3760 }
3761
3762 // Add declarations or definitions for each of the known methods.
3763 typedef CodeCompleteConsumer::Result Result;
3764 ResultBuilder Results(*this);
3765 Results.EnterNewScope();
3766 PrintingPolicy Policy(Context.PrintingPolicy);
3767 Policy.AnonymousTagLocations = false;
3768 for (KnownMethodsMap::iterator M = KnownMethods.begin(),
3769 MEnd = KnownMethods.end();
3770 M != MEnd; ++M) {
3771 ObjCMethodDecl *Method = M->second;
3772 CodeCompletionString *Pattern = new CodeCompletionString;
3773
3774 // If the result type was not already provided, add it to the
3775 // pattern as (type).
3776 if (ReturnType.isNull()) {
3777 std::string TypeStr;
3778 Method->getResultType().getAsStringInternal(TypeStr, Policy);
3779 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
3780 Pattern->AddTextChunk(TypeStr);
3781 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
3782 }
3783
3784 Selector Sel = Method->getSelector();
3785
3786 // Add the first part of the selector to the pattern.
3787 Pattern->AddTypedTextChunk(Sel.getIdentifierInfoForSlot(0)->getName());
3788
3789 // Add parameters to the pattern.
3790 unsigned I = 0;
3791 for (ObjCMethodDecl::param_iterator P = Method->param_begin(),
3792 PEnd = Method->param_end();
3793 P != PEnd; (void)++P, ++I) {
3794 // Add the part of the selector name.
3795 if (I == 0)
3796 Pattern->AddChunk(CodeCompletionString::CK_Colon);
3797 else if (I < Sel.getNumArgs()) {
3798 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
3799 Pattern->AddTextChunk(Sel.getIdentifierInfoForSlot(1)->getName());
3800 Pattern->AddChunk(CodeCompletionString::CK_Colon);
3801 } else
3802 break;
3803
3804 // Add the parameter type.
3805 std::string TypeStr;
3806 (*P)->getOriginalType().getAsStringInternal(TypeStr, Policy);
3807 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
3808 Pattern->AddTextChunk(TypeStr);
3809 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
3810
3811 if (IdentifierInfo *Id = (*P)->getIdentifier())
3812 Pattern->AddTextChunk(Id->getName());
3813 }
3814
3815 if (Method->isVariadic()) {
3816 if (Method->param_size() > 0)
3817 Pattern->AddChunk(CodeCompletionString::CK_Comma);
3818 Pattern->AddTextChunk("...");
3819 }
3820
3821 if (IsInImplementation) {
3822 // We will be defining the method here, so add a compound statement.
3823 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
3824 Pattern->AddChunk(CodeCompletionString::CK_LeftBrace);
3825 Pattern->AddChunk(CodeCompletionString::CK_VerticalSpace);
3826 if (!Method->getResultType()->isVoidType()) {
3827 // If the result type is not void, add a return clause.
3828 Pattern->AddTextChunk("return");
3829 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
3830 Pattern->AddPlaceholderChunk("expression");
3831 Pattern->AddChunk(CodeCompletionString::CK_SemiColon);
3832 } else
3833 Pattern->AddPlaceholderChunk("statements");
3834
3835 Pattern->AddChunk(CodeCompletionString::CK_VerticalSpace);
3836 Pattern->AddChunk(CodeCompletionString::CK_RightBrace);
3837 }
3838
3839 Results.AddResult(Result(Pattern));
3840 }
3841
3842 Results.ExitScope();
3843
3844 HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
3845}