blob: bc0335556f9a32d9aae5a3fce7d066c12325003e [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 Gregor7aa6b222010-05-30 01:49:25 +0000122 /// \brief If set, the type that we would prefer our resulting value
123 /// declarations to have.
124 ///
125 /// Closely matching the preferred type gives a boost to a result's
126 /// priority.
127 CanQualType PreferredType;
128
Douglas Gregor3545ff42009-09-21 16:56:56 +0000129 /// \brief A list of shadow maps, which is used to model name hiding at
130 /// different levels of, e.g., the inheritance hierarchy.
131 std::list<ShadowMap> ShadowMaps;
132
Douglas Gregor95887f92010-07-08 23:20:03 +0000133 void AdjustResultPriorityForPreferredType(Result &R);
134
Douglas Gregor3545ff42009-09-21 16:56:56 +0000135 public:
136 explicit ResultBuilder(Sema &SemaRef, LookupFilter Filter = 0)
Douglas Gregor6ae4c522010-01-14 03:21:49 +0000137 : SemaRef(SemaRef), Filter(Filter), AllowNestedNameSpecifiers(false) { }
Douglas Gregor3545ff42009-09-21 16:56:56 +0000138
Douglas Gregorf64acca2010-05-25 21:41:55 +0000139 /// \brief Whether we should include code patterns in the completion
140 /// results.
141 bool includeCodePatterns() const {
142 return SemaRef.CodeCompleter &&
143 SemaRef.CodeCompleter->includeCodePatterns();
144 }
145
Douglas Gregor3545ff42009-09-21 16:56:56 +0000146 /// \brief Set the filter used for code-completion results.
147 void setFilter(LookupFilter Filter) {
148 this->Filter = Filter;
149 }
150
151 typedef std::vector<Result>::iterator iterator;
152 iterator begin() { return Results.begin(); }
153 iterator end() { return Results.end(); }
154
155 Result *data() { return Results.empty()? 0 : &Results.front(); }
156 unsigned size() const { return Results.size(); }
157 bool empty() const { return Results.empty(); }
158
Douglas Gregor7aa6b222010-05-30 01:49:25 +0000159 /// \brief Specify the preferred type.
160 void setPreferredType(QualType T) {
161 PreferredType = SemaRef.Context.getCanonicalType(T);
162 }
163
Douglas Gregor6ae4c522010-01-14 03:21:49 +0000164 /// \brief Specify whether nested-name-specifiers are allowed.
165 void allowNestedNameSpecifiers(bool Allow = true) {
166 AllowNestedNameSpecifiers = Allow;
167 }
168
Douglas Gregor7c208612010-01-14 00:20:49 +0000169 /// \brief Determine whether the given declaration is at all interesting
170 /// as a code-completion result.
Douglas Gregor6ae4c522010-01-14 03:21:49 +0000171 ///
172 /// \param ND the declaration that we are inspecting.
173 ///
174 /// \param AsNestedNameSpecifier will be set true if this declaration is
175 /// only interesting when it is a nested-name-specifier.
176 bool isInterestingDecl(NamedDecl *ND, bool &AsNestedNameSpecifier) const;
Douglas Gregore0717ab2010-01-14 00:41:07 +0000177
178 /// \brief Check whether the result is hidden by the Hiding declaration.
179 ///
180 /// \returns true if the result is hidden and cannot be found, false if
181 /// the hidden result could still be found. When false, \p R may be
182 /// modified to describe how the result can be found (e.g., via extra
183 /// qualification).
184 bool CheckHiddenResult(Result &R, DeclContext *CurContext,
185 NamedDecl *Hiding);
186
Douglas Gregor3545ff42009-09-21 16:56:56 +0000187 /// \brief Add a new result to this result set (if it isn't already in one
188 /// of the shadow maps), or replace an existing result (for, e.g., a
189 /// redeclaration).
Douglas Gregor2af2f672009-09-21 20:12:40 +0000190 ///
Douglas Gregorc580c522010-01-14 01:09:38 +0000191 /// \param CurContext the result to add (if it is unique).
Douglas Gregor2af2f672009-09-21 20:12:40 +0000192 ///
193 /// \param R the context in which this result will be named.
194 void MaybeAddResult(Result R, DeclContext *CurContext = 0);
Douglas Gregor3545ff42009-09-21 16:56:56 +0000195
Douglas Gregorc580c522010-01-14 01:09:38 +0000196 /// \brief Add a new result to this result set, where we already know
197 /// the hiding declation (if any).
198 ///
199 /// \param R the result to add (if it is unique).
200 ///
201 /// \param CurContext the context in which this result will be named.
202 ///
203 /// \param Hiding the declaration that hides the result.
Douglas Gregor09bbc652010-01-14 15:47:35 +0000204 ///
205 /// \param InBaseClass whether the result was found in a base
206 /// class of the searched context.
207 void AddResult(Result R, DeclContext *CurContext, NamedDecl *Hiding,
208 bool InBaseClass);
Douglas Gregorc580c522010-01-14 01:09:38 +0000209
Douglas Gregor78a21012010-01-14 16:01:26 +0000210 /// \brief Add a new non-declaration result to this result set.
211 void AddResult(Result R);
212
Douglas Gregor3545ff42009-09-21 16:56:56 +0000213 /// \brief Enter into a new scope.
214 void EnterNewScope();
215
216 /// \brief Exit from the current scope.
217 void ExitScope();
218
Douglas Gregorbaf69612009-11-18 04:19:12 +0000219 /// \brief Ignore this declaration, if it is seen again.
220 void Ignore(Decl *D) { AllDeclsFound.insert(D->getCanonicalDecl()); }
221
Douglas Gregor3545ff42009-09-21 16:56:56 +0000222 /// \name Name lookup predicates
223 ///
224 /// These predicates can be passed to the name lookup functions to filter the
225 /// results of name lookup. All of the predicates have the same type, so that
226 ///
227 //@{
Douglas Gregor9d64c5e2009-09-21 20:51:25 +0000228 bool IsOrdinaryName(NamedDecl *ND) const;
Douglas Gregor70febae2010-05-28 00:49:12 +0000229 bool IsOrdinaryNonTypeName(NamedDecl *ND) const;
Douglas Gregor85b50632010-07-28 21:50:18 +0000230 bool IsIntegralConstantValue(NamedDecl *ND) const;
Douglas Gregor504a6ae2010-01-10 23:08:15 +0000231 bool IsOrdinaryNonValueName(NamedDecl *ND) const;
Douglas Gregor3545ff42009-09-21 16:56:56 +0000232 bool IsNestedNameSpecifier(NamedDecl *ND) const;
233 bool IsEnum(NamedDecl *ND) const;
234 bool IsClassOrStruct(NamedDecl *ND) const;
235 bool IsUnion(NamedDecl *ND) const;
236 bool IsNamespace(NamedDecl *ND) const;
237 bool IsNamespaceOrAlias(NamedDecl *ND) const;
238 bool IsType(NamedDecl *ND) const;
Douglas Gregore412a5a2009-09-23 22:26:46 +0000239 bool IsMember(NamedDecl *ND) const;
Douglas Gregor2b8162b2010-01-14 16:08:12 +0000240 bool IsObjCIvar(NamedDecl *ND) const;
Douglas Gregora817a192010-05-27 23:06:34 +0000241 bool IsObjCMessageReceiver(NamedDecl *ND) const;
Douglas Gregor3545ff42009-09-21 16:56:56 +0000242 //@}
243 };
244}
245
Douglas Gregor05e7ca32009-12-06 20:23:50 +0000246class ResultBuilder::ShadowMapEntry::iterator {
247 llvm::PointerUnion<NamedDecl*, const DeclIndexPair*> DeclOrIterator;
248 unsigned SingleDeclIndex;
249
250public:
251 typedef DeclIndexPair value_type;
252 typedef value_type reference;
253 typedef std::ptrdiff_t difference_type;
254 typedef std::input_iterator_tag iterator_category;
255
256 class pointer {
257 DeclIndexPair Value;
258
259 public:
260 pointer(const DeclIndexPair &Value) : Value(Value) { }
261
262 const DeclIndexPair *operator->() const {
263 return &Value;
264 }
265 };
266
267 iterator() : DeclOrIterator((NamedDecl *)0), SingleDeclIndex(0) { }
268
269 iterator(NamedDecl *SingleDecl, unsigned Index)
270 : DeclOrIterator(SingleDecl), SingleDeclIndex(Index) { }
271
272 iterator(const DeclIndexPair *Iterator)
273 : DeclOrIterator(Iterator), SingleDeclIndex(0) { }
274
275 iterator &operator++() {
276 if (DeclOrIterator.is<NamedDecl *>()) {
277 DeclOrIterator = (NamedDecl *)0;
278 SingleDeclIndex = 0;
279 return *this;
280 }
281
282 const DeclIndexPair *I = DeclOrIterator.get<const DeclIndexPair*>();
283 ++I;
284 DeclOrIterator = I;
285 return *this;
286 }
287
288 iterator operator++(int) {
289 iterator tmp(*this);
290 ++(*this);
291 return tmp;
292 }
293
294 reference operator*() const {
295 if (NamedDecl *ND = DeclOrIterator.dyn_cast<NamedDecl *>())
296 return reference(ND, SingleDeclIndex);
297
Douglas Gregor94bb5e82009-12-06 21:27:58 +0000298 return *DeclOrIterator.get<const DeclIndexPair*>();
Douglas Gregor05e7ca32009-12-06 20:23:50 +0000299 }
300
301 pointer operator->() const {
302 return pointer(**this);
303 }
304
305 friend bool operator==(const iterator &X, const iterator &Y) {
Douglas Gregor94bb5e82009-12-06 21:27:58 +0000306 return X.DeclOrIterator.getOpaqueValue()
307 == Y.DeclOrIterator.getOpaqueValue() &&
Douglas Gregor05e7ca32009-12-06 20:23:50 +0000308 X.SingleDeclIndex == Y.SingleDeclIndex;
309 }
310
311 friend bool operator!=(const iterator &X, const iterator &Y) {
Douglas Gregor94bb5e82009-12-06 21:27:58 +0000312 return !(X == Y);
Douglas Gregor05e7ca32009-12-06 20:23:50 +0000313 }
314};
315
Douglas Gregor05e7ca32009-12-06 20:23:50 +0000316ResultBuilder::ShadowMapEntry::iterator
317ResultBuilder::ShadowMapEntry::begin() const {
318 if (DeclOrVector.isNull())
319 return iterator();
320
321 if (NamedDecl *ND = DeclOrVector.dyn_cast<NamedDecl *>())
322 return iterator(ND, SingleDeclIndex);
323
324 return iterator(DeclOrVector.get<DeclIndexPairVector *>()->begin());
325}
326
327ResultBuilder::ShadowMapEntry::iterator
328ResultBuilder::ShadowMapEntry::end() const {
329 if (DeclOrVector.is<NamedDecl *>() || DeclOrVector.isNull())
330 return iterator();
331
332 return iterator(DeclOrVector.get<DeclIndexPairVector *>()->end());
333}
334
Douglas Gregor2af2f672009-09-21 20:12:40 +0000335/// \brief Compute the qualification required to get from the current context
336/// (\p CurContext) to the target context (\p TargetContext).
337///
338/// \param Context the AST context in which the qualification will be used.
339///
340/// \param CurContext the context where an entity is being named, which is
341/// typically based on the current scope.
342///
343/// \param TargetContext the context in which the named entity actually
344/// resides.
345///
346/// \returns a nested name specifier that refers into the target context, or
347/// NULL if no qualification is needed.
348static NestedNameSpecifier *
349getRequiredQualification(ASTContext &Context,
350 DeclContext *CurContext,
351 DeclContext *TargetContext) {
352 llvm::SmallVector<DeclContext *, 4> TargetParents;
353
354 for (DeclContext *CommonAncestor = TargetContext;
355 CommonAncestor && !CommonAncestor->Encloses(CurContext);
356 CommonAncestor = CommonAncestor->getLookupParent()) {
357 if (CommonAncestor->isTransparentContext() ||
358 CommonAncestor->isFunctionOrMethod())
359 continue;
360
361 TargetParents.push_back(CommonAncestor);
362 }
363
364 NestedNameSpecifier *Result = 0;
365 while (!TargetParents.empty()) {
366 DeclContext *Parent = TargetParents.back();
367 TargetParents.pop_back();
368
369 if (NamespaceDecl *Namespace = dyn_cast<NamespaceDecl>(Parent))
370 Result = NestedNameSpecifier::Create(Context, Result, Namespace);
371 else if (TagDecl *TD = dyn_cast<TagDecl>(Parent))
372 Result = NestedNameSpecifier::Create(Context, Result,
373 false,
374 Context.getTypeDeclType(TD).getTypePtr());
Douglas Gregor9eb77012009-11-07 00:00:49 +0000375 }
Douglas Gregor2af2f672009-09-21 20:12:40 +0000376 return Result;
377}
378
Douglas Gregor6ae4c522010-01-14 03:21:49 +0000379bool ResultBuilder::isInterestingDecl(NamedDecl *ND,
380 bool &AsNestedNameSpecifier) const {
381 AsNestedNameSpecifier = false;
382
Douglas Gregor7c208612010-01-14 00:20:49 +0000383 ND = ND->getUnderlyingDecl();
384 unsigned IDNS = ND->getIdentifierNamespace();
Douglas Gregor58acf322009-10-09 22:16:47 +0000385
386 // Skip unnamed entities.
Douglas Gregor7c208612010-01-14 00:20:49 +0000387 if (!ND->getDeclName())
388 return false;
Douglas Gregor3545ff42009-09-21 16:56:56 +0000389
390 // Friend declarations and declarations introduced due to friends are never
391 // added as results.
John McCallbbbbe4e2010-03-11 07:50:04 +0000392 if (IDNS & (Decl::IDNS_OrdinaryFriend | Decl::IDNS_TagFriend))
Douglas Gregor7c208612010-01-14 00:20:49 +0000393 return false;
394
Douglas Gregor99fe2ad2009-12-11 17:31:05 +0000395 // Class template (partial) specializations are never added as results.
Douglas Gregor7c208612010-01-14 00:20:49 +0000396 if (isa<ClassTemplateSpecializationDecl>(ND) ||
397 isa<ClassTemplatePartialSpecializationDecl>(ND))
398 return false;
Douglas Gregor3545ff42009-09-21 16:56:56 +0000399
Douglas Gregor99fe2ad2009-12-11 17:31:05 +0000400 // Using declarations themselves are never added as results.
Douglas Gregor7c208612010-01-14 00:20:49 +0000401 if (isa<UsingDecl>(ND))
402 return false;
403
404 // Some declarations have reserved names that we don't want to ever show.
405 if (const IdentifierInfo *Id = ND->getIdentifier()) {
Douglas Gregor3545ff42009-09-21 16:56:56 +0000406 // __va_list_tag is a freak of nature. Find it and skip it.
407 if (Id->isStr("__va_list_tag") || Id->isStr("__builtin_va_list"))
Douglas Gregor7c208612010-01-14 00:20:49 +0000408 return false;
Douglas Gregor3545ff42009-09-21 16:56:56 +0000409
Douglas Gregor58acf322009-10-09 22:16:47 +0000410 // Filter out names reserved for the implementation (C99 7.1.3,
Douglas Gregor9f1570d2010-07-14 17:44:04 +0000411 // C++ [lib.global.names]) if they come from a system header.
Daniel Dunbar2c422dc92009-10-18 20:26:12 +0000412 //
413 // FIXME: Add predicate for this.
Douglas Gregor58acf322009-10-09 22:16:47 +0000414 if (Id->getLength() >= 2) {
Daniel Dunbar2c422dc92009-10-18 20:26:12 +0000415 const char *Name = Id->getNameStart();
Douglas Gregor58acf322009-10-09 22:16:47 +0000416 if (Name[0] == '_' &&
Douglas Gregor9f1570d2010-07-14 17:44:04 +0000417 (Name[1] == '_' || (Name[1] >= 'A' && Name[1] <= 'Z')) &&
418 (ND->getLocation().isInvalid() ||
419 SemaRef.SourceMgr.isInSystemHeader(
420 SemaRef.SourceMgr.getSpellingLoc(ND->getLocation()))))
Douglas Gregor7c208612010-01-14 00:20:49 +0000421 return false;
Douglas Gregor58acf322009-10-09 22:16:47 +0000422 }
Douglas Gregor3545ff42009-09-21 16:56:56 +0000423 }
Douglas Gregor7c208612010-01-14 00:20:49 +0000424
Douglas Gregor3545ff42009-09-21 16:56:56 +0000425 // C++ constructors are never found by name lookup.
Douglas Gregor7c208612010-01-14 00:20:49 +0000426 if (isa<CXXConstructorDecl>(ND))
427 return false;
Douglas Gregor3545ff42009-09-21 16:56:56 +0000428
429 // Filter out any unwanted results.
Douglas Gregor6ae4c522010-01-14 03:21:49 +0000430 if (Filter && !(this->*Filter)(ND)) {
431 // Check whether it is interesting as a nested-name-specifier.
432 if (AllowNestedNameSpecifiers && SemaRef.getLangOptions().CPlusPlus &&
433 IsNestedNameSpecifier(ND) &&
434 (Filter != &ResultBuilder::IsMember ||
435 (isa<CXXRecordDecl>(ND) &&
436 cast<CXXRecordDecl>(ND)->isInjectedClassName()))) {
437 AsNestedNameSpecifier = true;
438 return true;
439 }
440
Douglas Gregor7c208612010-01-14 00:20:49 +0000441 return false;
Douglas Gregor6ae4c522010-01-14 03:21:49 +0000442 }
John McCalle87beb22010-04-23 18:46:30 +0000443
444 if (Filter == &ResultBuilder::IsNestedNameSpecifier)
445 AsNestedNameSpecifier = true;
Douglas Gregor3545ff42009-09-21 16:56:56 +0000446
Douglas Gregor7c208612010-01-14 00:20:49 +0000447 // ... then it must be interesting!
448 return true;
449}
450
Douglas Gregore0717ab2010-01-14 00:41:07 +0000451bool ResultBuilder::CheckHiddenResult(Result &R, DeclContext *CurContext,
452 NamedDecl *Hiding) {
453 // In C, there is no way to refer to a hidden name.
454 // FIXME: This isn't true; we can find a tag name hidden by an ordinary
455 // name if we introduce the tag type.
456 if (!SemaRef.getLangOptions().CPlusPlus)
457 return true;
458
459 DeclContext *HiddenCtx = R.Declaration->getDeclContext()->getLookupContext();
460
461 // There is no way to qualify a name declared in a function or method.
462 if (HiddenCtx->isFunctionOrMethod())
463 return true;
464
465 if (HiddenCtx == Hiding->getDeclContext()->getLookupContext())
466 return true;
467
468 // We can refer to the result with the appropriate qualification. Do it.
469 R.Hidden = true;
470 R.QualifierIsInformative = false;
471
472 if (!R.Qualifier)
473 R.Qualifier = getRequiredQualification(SemaRef.Context,
474 CurContext,
475 R.Declaration->getDeclContext());
476 return false;
477}
478
Douglas Gregor95887f92010-07-08 23:20:03 +0000479enum SimplifiedTypeClass {
480 STC_Arithmetic,
481 STC_Array,
482 STC_Block,
483 STC_Function,
484 STC_ObjectiveC,
485 STC_Other,
486 STC_Pointer,
487 STC_Record,
488 STC_Void
489};
490
491/// \brief A simplified classification of types used to determine whether two
492/// types are "similar enough" when adjusting priorities.
493static SimplifiedTypeClass getSimplifiedTypeClass(CanQualType T) {
494 switch (T->getTypeClass()) {
495 case Type::Builtin:
496 switch (cast<BuiltinType>(T)->getKind()) {
497 case BuiltinType::Void:
498 return STC_Void;
499
500 case BuiltinType::NullPtr:
501 return STC_Pointer;
502
503 case BuiltinType::Overload:
504 case BuiltinType::Dependent:
505 case BuiltinType::UndeducedAuto:
506 return STC_Other;
507
508 case BuiltinType::ObjCId:
509 case BuiltinType::ObjCClass:
510 case BuiltinType::ObjCSel:
511 return STC_ObjectiveC;
512
513 default:
514 return STC_Arithmetic;
515 }
516 return STC_Other;
517
518 case Type::Complex:
519 return STC_Arithmetic;
520
521 case Type::Pointer:
522 return STC_Pointer;
523
524 case Type::BlockPointer:
525 return STC_Block;
526
527 case Type::LValueReference:
528 case Type::RValueReference:
529 return getSimplifiedTypeClass(T->getAs<ReferenceType>()->getPointeeType());
530
531 case Type::ConstantArray:
532 case Type::IncompleteArray:
533 case Type::VariableArray:
534 case Type::DependentSizedArray:
535 return STC_Array;
536
537 case Type::DependentSizedExtVector:
538 case Type::Vector:
539 case Type::ExtVector:
540 return STC_Arithmetic;
541
542 case Type::FunctionProto:
543 case Type::FunctionNoProto:
544 return STC_Function;
545
546 case Type::Record:
547 return STC_Record;
548
549 case Type::Enum:
550 return STC_Arithmetic;
551
552 case Type::ObjCObject:
553 case Type::ObjCInterface:
554 case Type::ObjCObjectPointer:
555 return STC_ObjectiveC;
556
557 default:
558 return STC_Other;
559 }
560}
561
562/// \brief Get the type that a given expression will have if this declaration
563/// is used as an expression in its "typical" code-completion form.
564static QualType getDeclUsageType(ASTContext &C, NamedDecl *ND) {
565 ND = cast<NamedDecl>(ND->getUnderlyingDecl());
566
567 if (TypeDecl *Type = dyn_cast<TypeDecl>(ND))
568 return C.getTypeDeclType(Type);
569 if (ObjCInterfaceDecl *Iface = dyn_cast<ObjCInterfaceDecl>(ND))
570 return C.getObjCInterfaceType(Iface);
571
572 QualType T;
573 if (FunctionDecl *Function = dyn_cast<FunctionDecl>(ND))
Douglas Gregor603d81b2010-07-13 08:18:22 +0000574 T = Function->getCallResultType();
Douglas Gregor95887f92010-07-08 23:20:03 +0000575 else if (ObjCMethodDecl *Method = dyn_cast<ObjCMethodDecl>(ND))
Douglas Gregor603d81b2010-07-13 08:18:22 +0000576 T = Method->getSendResultType();
Douglas Gregor95887f92010-07-08 23:20:03 +0000577 else if (FunctionTemplateDecl *FunTmpl = dyn_cast<FunctionTemplateDecl>(ND))
Douglas Gregor603d81b2010-07-13 08:18:22 +0000578 T = FunTmpl->getTemplatedDecl()->getCallResultType();
Douglas Gregor95887f92010-07-08 23:20:03 +0000579 else if (EnumConstantDecl *Enumerator = dyn_cast<EnumConstantDecl>(ND))
580 T = C.getTypeDeclType(cast<EnumDecl>(Enumerator->getDeclContext()));
581 else if (ObjCPropertyDecl *Property = dyn_cast<ObjCPropertyDecl>(ND))
582 T = Property->getType();
583 else if (ValueDecl *Value = dyn_cast<ValueDecl>(ND))
584 T = Value->getType();
585 else
586 return QualType();
587
588 return T.getNonReferenceType();
589}
590
591void ResultBuilder::AdjustResultPriorityForPreferredType(Result &R) {
592 QualType T = getDeclUsageType(SemaRef.Context, R.Declaration);
593 if (T.isNull())
594 return;
595
596 CanQualType TC = SemaRef.Context.getCanonicalType(T);
597 // Check for exactly-matching types (modulo qualifiers).
598 if (SemaRef.Context.hasSameUnqualifiedType(PreferredType, TC))
599 R.Priority /= CCF_ExactTypeMatch;
600 // Check for nearly-matching types, based on classification of each.
601 else if ((getSimplifiedTypeClass(PreferredType)
602 == getSimplifiedTypeClass(TC)) &&
603 !(PreferredType->isEnumeralType() && TC->isEnumeralType()))
604 R.Priority /= CCF_SimilarTypeMatch;
605}
606
Douglas Gregor7c208612010-01-14 00:20:49 +0000607void ResultBuilder::MaybeAddResult(Result R, DeclContext *CurContext) {
608 assert(!ShadowMaps.empty() && "Must enter into a results scope");
609
610 if (R.Kind != Result::RK_Declaration) {
611 // For non-declaration results, just add the result.
612 Results.push_back(R);
613 return;
614 }
615
616 // Look through using declarations.
617 if (UsingShadowDecl *Using = dyn_cast<UsingShadowDecl>(R.Declaration)) {
618 MaybeAddResult(Result(Using->getTargetDecl(), R.Qualifier), CurContext);
619 return;
620 }
621
622 Decl *CanonDecl = R.Declaration->getCanonicalDecl();
623 unsigned IDNS = CanonDecl->getIdentifierNamespace();
624
Douglas Gregor6ae4c522010-01-14 03:21:49 +0000625 bool AsNestedNameSpecifier = false;
626 if (!isInterestingDecl(R.Declaration, AsNestedNameSpecifier))
Douglas Gregor7c208612010-01-14 00:20:49 +0000627 return;
628
Douglas Gregor3545ff42009-09-21 16:56:56 +0000629 ShadowMap &SMap = ShadowMaps.back();
Douglas Gregor05e7ca32009-12-06 20:23:50 +0000630 ShadowMapEntry::iterator I, IEnd;
631 ShadowMap::iterator NamePos = SMap.find(R.Declaration->getDeclName());
632 if (NamePos != SMap.end()) {
633 I = NamePos->second.begin();
634 IEnd = NamePos->second.end();
635 }
636
637 for (; I != IEnd; ++I) {
638 NamedDecl *ND = I->first;
639 unsigned Index = I->second;
Douglas Gregor3545ff42009-09-21 16:56:56 +0000640 if (ND->getCanonicalDecl() == CanonDecl) {
641 // This is a redeclaration. Always pick the newer declaration.
Douglas Gregor3545ff42009-09-21 16:56:56 +0000642 Results[Index].Declaration = R.Declaration;
643
Douglas Gregor3545ff42009-09-21 16:56:56 +0000644 // We're done.
645 return;
646 }
647 }
648
649 // This is a new declaration in this scope. However, check whether this
650 // declaration name is hidden by a similarly-named declaration in an outer
651 // scope.
652 std::list<ShadowMap>::iterator SM, SMEnd = ShadowMaps.end();
653 --SMEnd;
654 for (SM = ShadowMaps.begin(); SM != SMEnd; ++SM) {
Douglas Gregor05e7ca32009-12-06 20:23:50 +0000655 ShadowMapEntry::iterator I, IEnd;
656 ShadowMap::iterator NamePos = SM->find(R.Declaration->getDeclName());
657 if (NamePos != SM->end()) {
658 I = NamePos->second.begin();
659 IEnd = NamePos->second.end();
660 }
661 for (; I != IEnd; ++I) {
Douglas Gregor3545ff42009-09-21 16:56:56 +0000662 // A tag declaration does not hide a non-tag declaration.
John McCalle87beb22010-04-23 18:46:30 +0000663 if (I->first->hasTagIdentifierNamespace() &&
Douglas Gregor3545ff42009-09-21 16:56:56 +0000664 (IDNS & (Decl::IDNS_Member | Decl::IDNS_Ordinary |
665 Decl::IDNS_ObjCProtocol)))
666 continue;
667
668 // Protocols are in distinct namespaces from everything else.
Douglas Gregor05e7ca32009-12-06 20:23:50 +0000669 if (((I->first->getIdentifierNamespace() & Decl::IDNS_ObjCProtocol)
Douglas Gregor3545ff42009-09-21 16:56:56 +0000670 || (IDNS & Decl::IDNS_ObjCProtocol)) &&
Douglas Gregor05e7ca32009-12-06 20:23:50 +0000671 I->first->getIdentifierNamespace() != IDNS)
Douglas Gregor3545ff42009-09-21 16:56:56 +0000672 continue;
673
674 // The newly-added result is hidden by an entry in the shadow map.
Douglas Gregore0717ab2010-01-14 00:41:07 +0000675 if (CheckHiddenResult(R, CurContext, I->first))
Douglas Gregor3545ff42009-09-21 16:56:56 +0000676 return;
Douglas Gregor3545ff42009-09-21 16:56:56 +0000677
678 break;
679 }
680 }
681
682 // Make sure that any given declaration only shows up in the result set once.
683 if (!AllDeclsFound.insert(CanonDecl))
684 return;
685
Douglas Gregore412a5a2009-09-23 22:26:46 +0000686 // If the filter is for nested-name-specifiers, then this result starts a
687 // nested-name-specifier.
Douglas Gregora2db7932010-05-26 22:00:08 +0000688 if (AsNestedNameSpecifier) {
Douglas Gregore412a5a2009-09-23 22:26:46 +0000689 R.StartsNestedNameSpecifier = true;
Douglas Gregora2db7932010-05-26 22:00:08 +0000690 R.Priority = CCP_NestedNameSpecifier;
Douglas Gregor95887f92010-07-08 23:20:03 +0000691 } else if (!PreferredType.isNull())
692 AdjustResultPriorityForPreferredType(R);
693
Douglas Gregor5bf52692009-09-22 23:15:58 +0000694 // If this result is supposed to have an informative qualifier, add one.
Douglas Gregore412a5a2009-09-23 22:26:46 +0000695 if (R.QualifierIsInformative && !R.Qualifier &&
696 !R.StartsNestedNameSpecifier) {
Douglas Gregor5bf52692009-09-22 23:15:58 +0000697 DeclContext *Ctx = R.Declaration->getDeclContext();
698 if (NamespaceDecl *Namespace = dyn_cast<NamespaceDecl>(Ctx))
699 R.Qualifier = NestedNameSpecifier::Create(SemaRef.Context, 0, Namespace);
700 else if (TagDecl *Tag = dyn_cast<TagDecl>(Ctx))
701 R.Qualifier = NestedNameSpecifier::Create(SemaRef.Context, 0, false,
702 SemaRef.Context.getTypeDeclType(Tag).getTypePtr());
703 else
704 R.QualifierIsInformative = false;
705 }
Douglas Gregore412a5a2009-09-23 22:26:46 +0000706
Douglas Gregor3545ff42009-09-21 16:56:56 +0000707 // Insert this result into the set of results and into the current shadow
708 // map.
Douglas Gregor05e7ca32009-12-06 20:23:50 +0000709 SMap[R.Declaration->getDeclName()].Add(R.Declaration, Results.size());
Douglas Gregor3545ff42009-09-21 16:56:56 +0000710 Results.push_back(R);
711}
712
Douglas Gregorc580c522010-01-14 01:09:38 +0000713void ResultBuilder::AddResult(Result R, DeclContext *CurContext,
Douglas Gregor09bbc652010-01-14 15:47:35 +0000714 NamedDecl *Hiding, bool InBaseClass = false) {
Douglas Gregor78a21012010-01-14 16:01:26 +0000715 if (R.Kind != Result::RK_Declaration) {
716 // For non-declaration results, just add the result.
717 Results.push_back(R);
718 return;
719 }
720
Douglas Gregorc580c522010-01-14 01:09:38 +0000721 // Look through using declarations.
722 if (UsingShadowDecl *Using = dyn_cast<UsingShadowDecl>(R.Declaration)) {
723 AddResult(Result(Using->getTargetDecl(), R.Qualifier), CurContext, Hiding);
724 return;
725 }
726
Douglas Gregor6ae4c522010-01-14 03:21:49 +0000727 bool AsNestedNameSpecifier = false;
728 if (!isInterestingDecl(R.Declaration, AsNestedNameSpecifier))
Douglas Gregorc580c522010-01-14 01:09:38 +0000729 return;
730
731 if (Hiding && CheckHiddenResult(R, CurContext, Hiding))
732 return;
733
734 // Make sure that any given declaration only shows up in the result set once.
735 if (!AllDeclsFound.insert(R.Declaration->getCanonicalDecl()))
736 return;
737
738 // If the filter is for nested-name-specifiers, then this result starts a
739 // nested-name-specifier.
Douglas Gregora2db7932010-05-26 22:00:08 +0000740 if (AsNestedNameSpecifier) {
Douglas Gregorc580c522010-01-14 01:09:38 +0000741 R.StartsNestedNameSpecifier = true;
Douglas Gregora2db7932010-05-26 22:00:08 +0000742 R.Priority = CCP_NestedNameSpecifier;
743 }
Douglas Gregor09bbc652010-01-14 15:47:35 +0000744 else if (Filter == &ResultBuilder::IsMember && !R.Qualifier && InBaseClass &&
745 isa<CXXRecordDecl>(R.Declaration->getDeclContext()
746 ->getLookupContext()))
747 R.QualifierIsInformative = true;
748
Douglas Gregorc580c522010-01-14 01:09:38 +0000749 // If this result is supposed to have an informative qualifier, add one.
750 if (R.QualifierIsInformative && !R.Qualifier &&
751 !R.StartsNestedNameSpecifier) {
752 DeclContext *Ctx = R.Declaration->getDeclContext();
753 if (NamespaceDecl *Namespace = dyn_cast<NamespaceDecl>(Ctx))
754 R.Qualifier = NestedNameSpecifier::Create(SemaRef.Context, 0, Namespace);
755 else if (TagDecl *Tag = dyn_cast<TagDecl>(Ctx))
756 R.Qualifier = NestedNameSpecifier::Create(SemaRef.Context, 0, false,
Douglas Gregor6ae4c522010-01-14 03:21:49 +0000757 SemaRef.Context.getTypeDeclType(Tag).getTypePtr());
Douglas Gregorc580c522010-01-14 01:09:38 +0000758 else
759 R.QualifierIsInformative = false;
760 }
761
Douglas Gregora2db7932010-05-26 22:00:08 +0000762 // Adjust the priority if this result comes from a base class.
763 if (InBaseClass)
764 R.Priority += CCD_InBaseClass;
765
Douglas Gregor95887f92010-07-08 23:20:03 +0000766 if (!PreferredType.isNull())
767 AdjustResultPriorityForPreferredType(R);
Douglas Gregor7aa6b222010-05-30 01:49:25 +0000768
Douglas Gregorc580c522010-01-14 01:09:38 +0000769 // Insert this result into the set of results.
770 Results.push_back(R);
771}
772
Douglas Gregor78a21012010-01-14 16:01:26 +0000773void ResultBuilder::AddResult(Result R) {
774 assert(R.Kind != Result::RK_Declaration &&
775 "Declaration results need more context");
776 Results.push_back(R);
777}
778
Douglas Gregor3545ff42009-09-21 16:56:56 +0000779/// \brief Enter into a new scope.
780void ResultBuilder::EnterNewScope() {
781 ShadowMaps.push_back(ShadowMap());
782}
783
784/// \brief Exit from the current scope.
785void ResultBuilder::ExitScope() {
Douglas Gregor05e7ca32009-12-06 20:23:50 +0000786 for (ShadowMap::iterator E = ShadowMaps.back().begin(),
787 EEnd = ShadowMaps.back().end();
788 E != EEnd;
789 ++E)
790 E->second.Destroy();
791
Douglas Gregor3545ff42009-09-21 16:56:56 +0000792 ShadowMaps.pop_back();
793}
794
Douglas Gregor9d64c5e2009-09-21 20:51:25 +0000795/// \brief Determines whether this given declaration will be found by
796/// ordinary name lookup.
797bool ResultBuilder::IsOrdinaryName(NamedDecl *ND) const {
Douglas Gregor70febae2010-05-28 00:49:12 +0000798 ND = cast<NamedDecl>(ND->getUnderlyingDecl());
799
Douglas Gregor9d64c5e2009-09-21 20:51:25 +0000800 unsigned IDNS = Decl::IDNS_Ordinary;
801 if (SemaRef.getLangOptions().CPlusPlus)
Douglas Gregor9858ed52010-06-15 20:26:51 +0000802 IDNS |= Decl::IDNS_Tag | Decl::IDNS_Namespace | Decl::IDNS_Member;
Douglas Gregorc580c522010-01-14 01:09:38 +0000803 else if (SemaRef.getLangOptions().ObjC1 && isa<ObjCIvarDecl>(ND))
804 return true;
805
Douglas Gregor9d64c5e2009-09-21 20:51:25 +0000806 return ND->getIdentifierNamespace() & IDNS;
807}
808
Douglas Gregor504a6ae2010-01-10 23:08:15 +0000809/// \brief Determines whether this given declaration will be found by
Douglas Gregor70febae2010-05-28 00:49:12 +0000810/// ordinary name lookup but is not a type name.
811bool ResultBuilder::IsOrdinaryNonTypeName(NamedDecl *ND) const {
812 ND = cast<NamedDecl>(ND->getUnderlyingDecl());
813 if (isa<TypeDecl>(ND) || isa<ObjCInterfaceDecl>(ND))
814 return false;
815
816 unsigned IDNS = Decl::IDNS_Ordinary;
817 if (SemaRef.getLangOptions().CPlusPlus)
Douglas Gregor9858ed52010-06-15 20:26:51 +0000818 IDNS |= Decl::IDNS_Tag | Decl::IDNS_Namespace | Decl::IDNS_Member;
Douglas Gregor70febae2010-05-28 00:49:12 +0000819 else if (SemaRef.getLangOptions().ObjC1 && isa<ObjCIvarDecl>(ND))
820 return true;
821
822 return ND->getIdentifierNamespace() & IDNS;
823}
824
Douglas Gregor85b50632010-07-28 21:50:18 +0000825bool ResultBuilder::IsIntegralConstantValue(NamedDecl *ND) const {
826 if (!IsOrdinaryNonTypeName(ND))
827 return 0;
828
829 if (ValueDecl *VD = dyn_cast<ValueDecl>(ND->getUnderlyingDecl()))
830 if (VD->getType()->isIntegralOrEnumerationType())
831 return true;
832
833 return false;
834}
835
Douglas Gregor70febae2010-05-28 00:49:12 +0000836/// \brief Determines whether this given declaration will be found by
Douglas Gregor504a6ae2010-01-10 23:08:15 +0000837/// ordinary name lookup.
838bool ResultBuilder::IsOrdinaryNonValueName(NamedDecl *ND) const {
Douglas Gregor70febae2010-05-28 00:49:12 +0000839 ND = cast<NamedDecl>(ND->getUnderlyingDecl());
840
Douglas Gregor504a6ae2010-01-10 23:08:15 +0000841 unsigned IDNS = Decl::IDNS_Ordinary;
842 if (SemaRef.getLangOptions().CPlusPlus)
John McCalle87beb22010-04-23 18:46:30 +0000843 IDNS |= Decl::IDNS_Tag | Decl::IDNS_Namespace;
Douglas Gregor504a6ae2010-01-10 23:08:15 +0000844
845 return (ND->getIdentifierNamespace() & IDNS) &&
Douglas Gregor70febae2010-05-28 00:49:12 +0000846 !isa<ValueDecl>(ND) && !isa<FunctionTemplateDecl>(ND) &&
847 !isa<ObjCPropertyDecl>(ND);
Douglas Gregor504a6ae2010-01-10 23:08:15 +0000848}
849
Douglas Gregor3545ff42009-09-21 16:56:56 +0000850/// \brief Determines whether the given declaration is suitable as the
851/// start of a C++ nested-name-specifier, e.g., a class or namespace.
852bool ResultBuilder::IsNestedNameSpecifier(NamedDecl *ND) const {
853 // Allow us to find class templates, too.
854 if (ClassTemplateDecl *ClassTemplate = dyn_cast<ClassTemplateDecl>(ND))
855 ND = ClassTemplate->getTemplatedDecl();
856
857 return SemaRef.isAcceptableNestedNameSpecifier(ND);
858}
859
860/// \brief Determines whether the given declaration is an enumeration.
861bool ResultBuilder::IsEnum(NamedDecl *ND) const {
862 return isa<EnumDecl>(ND);
863}
864
865/// \brief Determines whether the given declaration is a class or struct.
866bool ResultBuilder::IsClassOrStruct(NamedDecl *ND) const {
867 // Allow us to find class templates, too.
868 if (ClassTemplateDecl *ClassTemplate = dyn_cast<ClassTemplateDecl>(ND))
869 ND = ClassTemplate->getTemplatedDecl();
870
871 if (RecordDecl *RD = dyn_cast<RecordDecl>(ND))
Abramo Bagnara6150c882010-05-11 21:36:43 +0000872 return RD->getTagKind() == TTK_Class ||
873 RD->getTagKind() == TTK_Struct;
Douglas Gregor3545ff42009-09-21 16:56:56 +0000874
875 return false;
876}
877
878/// \brief Determines whether the given declaration is a union.
879bool ResultBuilder::IsUnion(NamedDecl *ND) const {
880 // Allow us to find class templates, too.
881 if (ClassTemplateDecl *ClassTemplate = dyn_cast<ClassTemplateDecl>(ND))
882 ND = ClassTemplate->getTemplatedDecl();
883
884 if (RecordDecl *RD = dyn_cast<RecordDecl>(ND))
Abramo Bagnara6150c882010-05-11 21:36:43 +0000885 return RD->getTagKind() == TTK_Union;
Douglas Gregor3545ff42009-09-21 16:56:56 +0000886
887 return false;
888}
889
890/// \brief Determines whether the given declaration is a namespace.
891bool ResultBuilder::IsNamespace(NamedDecl *ND) const {
892 return isa<NamespaceDecl>(ND);
893}
894
895/// \brief Determines whether the given declaration is a namespace or
896/// namespace alias.
897bool ResultBuilder::IsNamespaceOrAlias(NamedDecl *ND) const {
898 return isa<NamespaceDecl>(ND) || isa<NamespaceAliasDecl>(ND);
899}
900
Douglas Gregor99fe2ad2009-12-11 17:31:05 +0000901/// \brief Determines whether the given declaration is a type.
Douglas Gregor3545ff42009-09-21 16:56:56 +0000902bool ResultBuilder::IsType(NamedDecl *ND) const {
903 return isa<TypeDecl>(ND);
904}
905
Douglas Gregor99fe2ad2009-12-11 17:31:05 +0000906/// \brief Determines which members of a class should be visible via
907/// "." or "->". Only value declarations, nested name specifiers, and
908/// using declarations thereof should show up.
Douglas Gregore412a5a2009-09-23 22:26:46 +0000909bool ResultBuilder::IsMember(NamedDecl *ND) const {
Douglas Gregor99fe2ad2009-12-11 17:31:05 +0000910 if (UsingShadowDecl *Using = dyn_cast<UsingShadowDecl>(ND))
911 ND = Using->getTargetDecl();
912
Douglas Gregor70788392009-12-11 18:14:22 +0000913 return isa<ValueDecl>(ND) || isa<FunctionTemplateDecl>(ND) ||
914 isa<ObjCPropertyDecl>(ND);
Douglas Gregore412a5a2009-09-23 22:26:46 +0000915}
916
Douglas Gregora817a192010-05-27 23:06:34 +0000917static bool isObjCReceiverType(ASTContext &C, QualType T) {
918 T = C.getCanonicalType(T);
919 switch (T->getTypeClass()) {
920 case Type::ObjCObject:
921 case Type::ObjCInterface:
922 case Type::ObjCObjectPointer:
923 return true;
924
925 case Type::Builtin:
926 switch (cast<BuiltinType>(T)->getKind()) {
927 case BuiltinType::ObjCId:
928 case BuiltinType::ObjCClass:
929 case BuiltinType::ObjCSel:
930 return true;
931
932 default:
933 break;
934 }
935 return false;
936
937 default:
938 break;
939 }
940
941 if (!C.getLangOptions().CPlusPlus)
942 return false;
943
944 // FIXME: We could perform more analysis here to determine whether a
945 // particular class type has any conversions to Objective-C types. For now,
946 // just accept all class types.
947 return T->isDependentType() || T->isRecordType();
948}
949
950bool ResultBuilder::IsObjCMessageReceiver(NamedDecl *ND) const {
951 QualType T = getDeclUsageType(SemaRef.Context, ND);
952 if (T.isNull())
953 return false;
954
955 T = SemaRef.Context.getBaseElementType(T);
956 return isObjCReceiverType(SemaRef.Context, T);
957}
958
959
Douglas Gregor2b8162b2010-01-14 16:08:12 +0000960/// \rief Determines whether the given declaration is an Objective-C
961/// instance variable.
962bool ResultBuilder::IsObjCIvar(NamedDecl *ND) const {
963 return isa<ObjCIvarDecl>(ND);
964}
965
Douglas Gregorc580c522010-01-14 01:09:38 +0000966namespace {
967 /// \brief Visible declaration consumer that adds a code-completion result
968 /// for each visible declaration.
969 class CodeCompletionDeclConsumer : public VisibleDeclConsumer {
970 ResultBuilder &Results;
971 DeclContext *CurContext;
972
973 public:
974 CodeCompletionDeclConsumer(ResultBuilder &Results, DeclContext *CurContext)
975 : Results(Results), CurContext(CurContext) { }
976
Douglas Gregor09bbc652010-01-14 15:47:35 +0000977 virtual void FoundDecl(NamedDecl *ND, NamedDecl *Hiding, bool InBaseClass) {
978 Results.AddResult(ND, CurContext, Hiding, InBaseClass);
Douglas Gregorc580c522010-01-14 01:09:38 +0000979 }
980 };
981}
982
Douglas Gregor3545ff42009-09-21 16:56:56 +0000983/// \brief Add type specifiers for the current language as keyword results.
Douglas Gregorf98e6a22010-01-13 23:51:12 +0000984static void AddTypeSpecifierResults(const LangOptions &LangOpts,
Douglas Gregor3545ff42009-09-21 16:56:56 +0000985 ResultBuilder &Results) {
986 typedef CodeCompleteConsumer::Result Result;
Douglas Gregora2db7932010-05-26 22:00:08 +0000987 Results.AddResult(Result("short", CCP_Type));
988 Results.AddResult(Result("long", CCP_Type));
989 Results.AddResult(Result("signed", CCP_Type));
990 Results.AddResult(Result("unsigned", CCP_Type));
991 Results.AddResult(Result("void", CCP_Type));
992 Results.AddResult(Result("char", CCP_Type));
993 Results.AddResult(Result("int", CCP_Type));
994 Results.AddResult(Result("float", CCP_Type));
995 Results.AddResult(Result("double", CCP_Type));
996 Results.AddResult(Result("enum", CCP_Type));
997 Results.AddResult(Result("struct", CCP_Type));
998 Results.AddResult(Result("union", CCP_Type));
999 Results.AddResult(Result("const", CCP_Type));
1000 Results.AddResult(Result("volatile", CCP_Type));
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001001
Douglas Gregor3545ff42009-09-21 16:56:56 +00001002 if (LangOpts.C99) {
1003 // C99-specific
Douglas Gregora2db7932010-05-26 22:00:08 +00001004 Results.AddResult(Result("_Complex", CCP_Type));
1005 Results.AddResult(Result("_Imaginary", CCP_Type));
1006 Results.AddResult(Result("_Bool", CCP_Type));
1007 Results.AddResult(Result("restrict", CCP_Type));
Douglas Gregor3545ff42009-09-21 16:56:56 +00001008 }
1009
1010 if (LangOpts.CPlusPlus) {
1011 // C++-specific
Douglas Gregora2db7932010-05-26 22:00:08 +00001012 Results.AddResult(Result("bool", CCP_Type));
1013 Results.AddResult(Result("class", CCP_Type));
1014 Results.AddResult(Result("wchar_t", CCP_Type));
Douglas Gregor3545ff42009-09-21 16:56:56 +00001015
Douglas Gregorf4c33342010-05-28 00:22:41 +00001016 // typename qualified-id
1017 CodeCompletionString *Pattern = new CodeCompletionString;
1018 Pattern->AddTypedTextChunk("typename");
1019 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
1020 Pattern->AddPlaceholderChunk("qualifier");
1021 Pattern->AddTextChunk("::");
1022 Pattern->AddPlaceholderChunk("name");
1023 Results.AddResult(Result(Pattern));
Douglas Gregorf64acca2010-05-25 21:41:55 +00001024
Douglas Gregor3545ff42009-09-21 16:56:56 +00001025 if (LangOpts.CPlusPlus0x) {
Douglas Gregora2db7932010-05-26 22:00:08 +00001026 Results.AddResult(Result("auto", CCP_Type));
1027 Results.AddResult(Result("char16_t", CCP_Type));
1028 Results.AddResult(Result("char32_t", CCP_Type));
Douglas Gregorf4c33342010-05-28 00:22:41 +00001029
1030 CodeCompletionString *Pattern = new CodeCompletionString;
1031 Pattern->AddTypedTextChunk("decltype");
1032 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
1033 Pattern->AddPlaceholderChunk("expression");
1034 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
1035 Results.AddResult(Result(Pattern));
Douglas Gregor3545ff42009-09-21 16:56:56 +00001036 }
1037 }
1038
1039 // GNU extensions
1040 if (LangOpts.GNUMode) {
1041 // FIXME: Enable when we actually support decimal floating point.
Douglas Gregor78a21012010-01-14 16:01:26 +00001042 // Results.AddResult(Result("_Decimal32"));
1043 // Results.AddResult(Result("_Decimal64"));
1044 // Results.AddResult(Result("_Decimal128"));
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001045
Douglas Gregorf4c33342010-05-28 00:22:41 +00001046 CodeCompletionString *Pattern = new CodeCompletionString;
1047 Pattern->AddTypedTextChunk("typeof");
1048 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
1049 Pattern->AddPlaceholderChunk("expression");
1050 Results.AddResult(Result(Pattern));
1051
1052 Pattern = new CodeCompletionString;
1053 Pattern->AddTypedTextChunk("typeof");
1054 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
1055 Pattern->AddPlaceholderChunk("type");
1056 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
1057 Results.AddResult(Result(Pattern));
Douglas Gregor3545ff42009-09-21 16:56:56 +00001058 }
1059}
1060
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001061static void AddStorageSpecifiers(Action::CodeCompletionContext CCC,
1062 const LangOptions &LangOpts,
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001063 ResultBuilder &Results) {
1064 typedef CodeCompleteConsumer::Result Result;
1065 // Note: we don't suggest either "auto" or "register", because both
1066 // are pointless as storage specifiers. Elsewhere, we suggest "auto"
1067 // in C++0x as a type specifier.
Douglas Gregor78a21012010-01-14 16:01:26 +00001068 Results.AddResult(Result("extern"));
1069 Results.AddResult(Result("static"));
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001070}
1071
1072static void AddFunctionSpecifiers(Action::CodeCompletionContext CCC,
1073 const LangOptions &LangOpts,
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001074 ResultBuilder &Results) {
1075 typedef CodeCompleteConsumer::Result Result;
1076 switch (CCC) {
1077 case Action::CCC_Class:
1078 case Action::CCC_MemberTemplate:
1079 if (LangOpts.CPlusPlus) {
Douglas Gregor78a21012010-01-14 16:01:26 +00001080 Results.AddResult(Result("explicit"));
1081 Results.AddResult(Result("friend"));
1082 Results.AddResult(Result("mutable"));
1083 Results.AddResult(Result("virtual"));
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001084 }
1085 // Fall through
1086
Douglas Gregorf1934162010-01-13 21:24:21 +00001087 case Action::CCC_ObjCInterface:
1088 case Action::CCC_ObjCImplementation:
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001089 case Action::CCC_Namespace:
1090 case Action::CCC_Template:
1091 if (LangOpts.CPlusPlus || LangOpts.C99)
Douglas Gregor78a21012010-01-14 16:01:26 +00001092 Results.AddResult(Result("inline"));
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001093 break;
1094
Douglas Gregor48d46252010-01-13 21:54:15 +00001095 case Action::CCC_ObjCInstanceVariableList:
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001096 case Action::CCC_Expression:
1097 case Action::CCC_Statement:
1098 case Action::CCC_ForInit:
1099 case Action::CCC_Condition:
Douglas Gregor6da3db42010-05-25 05:58:43 +00001100 case Action::CCC_RecoveryInFunction:
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001101 break;
1102 }
1103}
1104
Douglas Gregorf98e6a22010-01-13 23:51:12 +00001105static void AddObjCExpressionResults(ResultBuilder &Results, bool NeedAt);
1106static void AddObjCStatementResults(ResultBuilder &Results, bool NeedAt);
1107static void AddObjCVisibilityResults(const LangOptions &LangOpts,
Douglas Gregor48d46252010-01-13 21:54:15 +00001108 ResultBuilder &Results,
1109 bool NeedAt);
Douglas Gregorf98e6a22010-01-13 23:51:12 +00001110static void AddObjCImplementationResults(const LangOptions &LangOpts,
Douglas Gregorf1934162010-01-13 21:24:21 +00001111 ResultBuilder &Results,
1112 bool NeedAt);
Douglas Gregorf98e6a22010-01-13 23:51:12 +00001113static void AddObjCInterfaceResults(const LangOptions &LangOpts,
Douglas Gregorf1934162010-01-13 21:24:21 +00001114 ResultBuilder &Results,
1115 bool NeedAt);
Douglas Gregorf98e6a22010-01-13 23:51:12 +00001116static void AddObjCTopLevelResults(ResultBuilder &Results, bool NeedAt);
Douglas Gregorf1934162010-01-13 21:24:21 +00001117
Douglas Gregorf4c33342010-05-28 00:22:41 +00001118static void AddTypedefResult(ResultBuilder &Results) {
1119 CodeCompletionString *Pattern = new CodeCompletionString;
1120 Pattern->AddTypedTextChunk("typedef");
1121 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
1122 Pattern->AddPlaceholderChunk("type");
1123 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
1124 Pattern->AddPlaceholderChunk("name");
1125 Results.AddResult(CodeCompleteConsumer::Result(Pattern));
1126}
1127
Douglas Gregor70febae2010-05-28 00:49:12 +00001128static bool WantTypesInContext(Action::CodeCompletionContext CCC,
1129 const LangOptions &LangOpts) {
1130 if (LangOpts.CPlusPlus)
1131 return true;
1132
1133 switch (CCC) {
1134 case Action::CCC_Namespace:
1135 case Action::CCC_Class:
1136 case Action::CCC_ObjCInstanceVariableList:
1137 case Action::CCC_Template:
1138 case Action::CCC_MemberTemplate:
1139 case Action::CCC_Statement:
1140 case Action::CCC_RecoveryInFunction:
1141 return true;
1142
1143 case Action::CCC_ObjCInterface:
1144 case Action::CCC_ObjCImplementation:
1145 case Action::CCC_Expression:
1146 case Action::CCC_Condition:
1147 return false;
1148
1149 case Action::CCC_ForInit:
1150 return LangOpts.ObjC1 || LangOpts.C99;
1151 }
1152
1153 return false;
1154}
1155
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001156/// \brief Add language constructs that show up for "ordinary" names.
1157static void AddOrdinaryNameResults(Action::CodeCompletionContext CCC,
1158 Scope *S,
1159 Sema &SemaRef,
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001160 ResultBuilder &Results) {
1161 typedef CodeCompleteConsumer::Result Result;
1162 switch (CCC) {
1163 case Action::CCC_Namespace:
Douglas Gregorf4c33342010-05-28 00:22:41 +00001164 if (SemaRef.getLangOptions().CPlusPlus) {
1165 CodeCompletionString *Pattern = 0;
1166
1167 if (Results.includeCodePatterns()) {
1168 // namespace <identifier> { declarations }
1169 CodeCompletionString *Pattern = new CodeCompletionString;
1170 Pattern->AddTypedTextChunk("namespace");
1171 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
1172 Pattern->AddPlaceholderChunk("identifier");
1173 Pattern->AddChunk(CodeCompletionString::CK_LeftBrace);
1174 Pattern->AddPlaceholderChunk("declarations");
1175 Pattern->AddChunk(CodeCompletionString::CK_VerticalSpace);
1176 Pattern->AddChunk(CodeCompletionString::CK_RightBrace);
1177 Results.AddResult(Result(Pattern));
1178 }
1179
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001180 // namespace identifier = identifier ;
1181 Pattern = new CodeCompletionString;
1182 Pattern->AddTypedTextChunk("namespace");
1183 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
Douglas Gregorf4c33342010-05-28 00:22:41 +00001184 Pattern->AddPlaceholderChunk("name");
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001185 Pattern->AddChunk(CodeCompletionString::CK_Equal);
Douglas Gregorf4c33342010-05-28 00:22:41 +00001186 Pattern->AddPlaceholderChunk("namespace");
Douglas Gregor78a21012010-01-14 16:01:26 +00001187 Results.AddResult(Result(Pattern));
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001188
1189 // Using directives
1190 Pattern = new CodeCompletionString;
1191 Pattern->AddTypedTextChunk("using");
1192 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
1193 Pattern->AddTextChunk("namespace");
1194 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
1195 Pattern->AddPlaceholderChunk("identifier");
Douglas Gregor78a21012010-01-14 16:01:26 +00001196 Results.AddResult(Result(Pattern));
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001197
1198 // asm(string-literal)
1199 Pattern = new CodeCompletionString;
1200 Pattern->AddTypedTextChunk("asm");
1201 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
1202 Pattern->AddPlaceholderChunk("string-literal");
1203 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
Douglas Gregor78a21012010-01-14 16:01:26 +00001204 Results.AddResult(Result(Pattern));
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001205
Douglas Gregorf4c33342010-05-28 00:22:41 +00001206 if (Results.includeCodePatterns()) {
1207 // Explicit template instantiation
1208 Pattern = new CodeCompletionString;
1209 Pattern->AddTypedTextChunk("template");
1210 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
1211 Pattern->AddPlaceholderChunk("declaration");
1212 Results.AddResult(Result(Pattern));
1213 }
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001214 }
Douglas Gregorf1934162010-01-13 21:24:21 +00001215
1216 if (SemaRef.getLangOptions().ObjC1)
Douglas Gregorf98e6a22010-01-13 23:51:12 +00001217 AddObjCTopLevelResults(Results, true);
Douglas Gregorf1934162010-01-13 21:24:21 +00001218
Douglas Gregorf4c33342010-05-28 00:22:41 +00001219 AddTypedefResult(Results);
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001220 // Fall through
1221
1222 case Action::CCC_Class:
Douglas Gregorf4c33342010-05-28 00:22:41 +00001223 if (SemaRef.getLangOptions().CPlusPlus) {
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001224 // Using declaration
1225 CodeCompletionString *Pattern = new CodeCompletionString;
1226 Pattern->AddTypedTextChunk("using");
1227 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
Douglas Gregorf4c33342010-05-28 00:22:41 +00001228 Pattern->AddPlaceholderChunk("qualifier");
1229 Pattern->AddTextChunk("::");
1230 Pattern->AddPlaceholderChunk("name");
Douglas Gregor78a21012010-01-14 16:01:26 +00001231 Results.AddResult(Result(Pattern));
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001232
Douglas Gregorf4c33342010-05-28 00:22:41 +00001233 // using typename qualifier::name (only in a dependent context)
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001234 if (SemaRef.CurContext->isDependentContext()) {
1235 Pattern = new CodeCompletionString;
1236 Pattern->AddTypedTextChunk("using");
1237 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
1238 Pattern->AddTextChunk("typename");
1239 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
Douglas Gregorf4c33342010-05-28 00:22:41 +00001240 Pattern->AddPlaceholderChunk("qualifier");
1241 Pattern->AddTextChunk("::");
1242 Pattern->AddPlaceholderChunk("name");
Douglas Gregor78a21012010-01-14 16:01:26 +00001243 Results.AddResult(Result(Pattern));
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001244 }
1245
1246 if (CCC == Action::CCC_Class) {
Douglas Gregorf4c33342010-05-28 00:22:41 +00001247 AddTypedefResult(Results);
1248
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001249 // public:
1250 Pattern = new CodeCompletionString;
1251 Pattern->AddTypedTextChunk("public");
1252 Pattern->AddChunk(CodeCompletionString::CK_Colon);
Douglas Gregor78a21012010-01-14 16:01:26 +00001253 Results.AddResult(Result(Pattern));
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001254
1255 // protected:
1256 Pattern = new CodeCompletionString;
1257 Pattern->AddTypedTextChunk("protected");
1258 Pattern->AddChunk(CodeCompletionString::CK_Colon);
Douglas Gregor78a21012010-01-14 16:01:26 +00001259 Results.AddResult(Result(Pattern));
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001260
1261 // private:
1262 Pattern = new CodeCompletionString;
1263 Pattern->AddTypedTextChunk("private");
1264 Pattern->AddChunk(CodeCompletionString::CK_Colon);
Douglas Gregor78a21012010-01-14 16:01:26 +00001265 Results.AddResult(Result(Pattern));
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001266 }
1267 }
1268 // Fall through
1269
1270 case Action::CCC_Template:
1271 case Action::CCC_MemberTemplate:
Douglas Gregorf64acca2010-05-25 21:41:55 +00001272 if (SemaRef.getLangOptions().CPlusPlus && Results.includeCodePatterns()) {
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001273 // template < parameters >
1274 CodeCompletionString *Pattern = new CodeCompletionString;
1275 Pattern->AddTypedTextChunk("template");
1276 Pattern->AddChunk(CodeCompletionString::CK_LeftAngle);
1277 Pattern->AddPlaceholderChunk("parameters");
1278 Pattern->AddChunk(CodeCompletionString::CK_RightAngle);
Douglas Gregor78a21012010-01-14 16:01:26 +00001279 Results.AddResult(Result(Pattern));
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001280 }
1281
Douglas Gregorf98e6a22010-01-13 23:51:12 +00001282 AddStorageSpecifiers(CCC, SemaRef.getLangOptions(), Results);
1283 AddFunctionSpecifiers(CCC, SemaRef.getLangOptions(), Results);
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001284 break;
1285
Douglas Gregorf1934162010-01-13 21:24:21 +00001286 case Action::CCC_ObjCInterface:
Douglas Gregorf98e6a22010-01-13 23:51:12 +00001287 AddObjCInterfaceResults(SemaRef.getLangOptions(), Results, true);
1288 AddStorageSpecifiers(CCC, SemaRef.getLangOptions(), Results);
1289 AddFunctionSpecifiers(CCC, SemaRef.getLangOptions(), Results);
Douglas Gregorf1934162010-01-13 21:24:21 +00001290 break;
1291
1292 case Action::CCC_ObjCImplementation:
Douglas Gregorf98e6a22010-01-13 23:51:12 +00001293 AddObjCImplementationResults(SemaRef.getLangOptions(), Results, true);
1294 AddStorageSpecifiers(CCC, SemaRef.getLangOptions(), Results);
1295 AddFunctionSpecifiers(CCC, SemaRef.getLangOptions(), Results);
Douglas Gregorf1934162010-01-13 21:24:21 +00001296 break;
1297
Douglas Gregor48d46252010-01-13 21:54:15 +00001298 case Action::CCC_ObjCInstanceVariableList:
Douglas Gregorf98e6a22010-01-13 23:51:12 +00001299 AddObjCVisibilityResults(SemaRef.getLangOptions(), Results, true);
Douglas Gregor48d46252010-01-13 21:54:15 +00001300 break;
1301
Douglas Gregor6da3db42010-05-25 05:58:43 +00001302 case Action::CCC_RecoveryInFunction:
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001303 case Action::CCC_Statement: {
Douglas Gregorf4c33342010-05-28 00:22:41 +00001304 AddTypedefResult(Results);
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001305
1306 CodeCompletionString *Pattern = 0;
Douglas Gregorf64acca2010-05-25 21:41:55 +00001307 if (SemaRef.getLangOptions().CPlusPlus && Results.includeCodePatterns()) {
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001308 Pattern = new CodeCompletionString;
1309 Pattern->AddTypedTextChunk("try");
1310 Pattern->AddChunk(CodeCompletionString::CK_LeftBrace);
1311 Pattern->AddPlaceholderChunk("statements");
1312 Pattern->AddChunk(CodeCompletionString::CK_VerticalSpace);
1313 Pattern->AddChunk(CodeCompletionString::CK_RightBrace);
1314 Pattern->AddTextChunk("catch");
1315 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
1316 Pattern->AddPlaceholderChunk("declaration");
1317 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
1318 Pattern->AddChunk(CodeCompletionString::CK_LeftBrace);
1319 Pattern->AddPlaceholderChunk("statements");
1320 Pattern->AddChunk(CodeCompletionString::CK_VerticalSpace);
1321 Pattern->AddChunk(CodeCompletionString::CK_RightBrace);
Douglas Gregor78a21012010-01-14 16:01:26 +00001322 Results.AddResult(Result(Pattern));
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001323 }
Douglas Gregorf1934162010-01-13 21:24:21 +00001324 if (SemaRef.getLangOptions().ObjC1)
Douglas Gregorf98e6a22010-01-13 23:51:12 +00001325 AddObjCStatementResults(Results, true);
Douglas Gregorf1934162010-01-13 21:24:21 +00001326
Douglas Gregorf64acca2010-05-25 21:41:55 +00001327 if (Results.includeCodePatterns()) {
1328 // if (condition) { statements }
1329 Pattern = new CodeCompletionString;
1330 Pattern->AddTypedTextChunk("if");
1331 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
1332 if (SemaRef.getLangOptions().CPlusPlus)
1333 Pattern->AddPlaceholderChunk("condition");
1334 else
1335 Pattern->AddPlaceholderChunk("expression");
1336 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
1337 Pattern->AddChunk(CodeCompletionString::CK_LeftBrace);
1338 Pattern->AddPlaceholderChunk("statements");
1339 Pattern->AddChunk(CodeCompletionString::CK_VerticalSpace);
1340 Pattern->AddChunk(CodeCompletionString::CK_RightBrace);
1341 Results.AddResult(Result(Pattern));
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001342
Douglas Gregorf64acca2010-05-25 21:41:55 +00001343 // switch (condition) { }
1344 Pattern = new CodeCompletionString;
1345 Pattern->AddTypedTextChunk("switch");
1346 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
1347 if (SemaRef.getLangOptions().CPlusPlus)
1348 Pattern->AddPlaceholderChunk("condition");
1349 else
1350 Pattern->AddPlaceholderChunk("expression");
1351 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
1352 Pattern->AddChunk(CodeCompletionString::CK_LeftBrace);
1353 Pattern->AddChunk(CodeCompletionString::CK_VerticalSpace);
1354 Pattern->AddChunk(CodeCompletionString::CK_RightBrace);
1355 Results.AddResult(Result(Pattern));
1356 }
1357
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001358 // Switch-specific statements.
Douglas Gregorf4c33342010-05-28 00:22:41 +00001359 if (!SemaRef.getSwitchStack().empty()) {
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001360 // case expression:
1361 Pattern = new CodeCompletionString;
1362 Pattern->AddTypedTextChunk("case");
Douglas Gregorf4c33342010-05-28 00:22:41 +00001363 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001364 Pattern->AddPlaceholderChunk("expression");
1365 Pattern->AddChunk(CodeCompletionString::CK_Colon);
Douglas Gregor78a21012010-01-14 16:01:26 +00001366 Results.AddResult(Result(Pattern));
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001367
1368 // default:
1369 Pattern = new CodeCompletionString;
1370 Pattern->AddTypedTextChunk("default");
1371 Pattern->AddChunk(CodeCompletionString::CK_Colon);
Douglas Gregor78a21012010-01-14 16:01:26 +00001372 Results.AddResult(Result(Pattern));
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001373 }
1374
Douglas Gregorf64acca2010-05-25 21:41:55 +00001375 if (Results.includeCodePatterns()) {
1376 /// while (condition) { statements }
1377 Pattern = new CodeCompletionString;
1378 Pattern->AddTypedTextChunk("while");
1379 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
1380 if (SemaRef.getLangOptions().CPlusPlus)
1381 Pattern->AddPlaceholderChunk("condition");
1382 else
1383 Pattern->AddPlaceholderChunk("expression");
1384 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
1385 Pattern->AddChunk(CodeCompletionString::CK_LeftBrace);
1386 Pattern->AddPlaceholderChunk("statements");
1387 Pattern->AddChunk(CodeCompletionString::CK_VerticalSpace);
1388 Pattern->AddChunk(CodeCompletionString::CK_RightBrace);
1389 Results.AddResult(Result(Pattern));
1390
1391 // do { statements } while ( expression );
1392 Pattern = new CodeCompletionString;
1393 Pattern->AddTypedTextChunk("do");
1394 Pattern->AddChunk(CodeCompletionString::CK_LeftBrace);
1395 Pattern->AddPlaceholderChunk("statements");
1396 Pattern->AddChunk(CodeCompletionString::CK_VerticalSpace);
1397 Pattern->AddChunk(CodeCompletionString::CK_RightBrace);
1398 Pattern->AddTextChunk("while");
1399 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001400 Pattern->AddPlaceholderChunk("expression");
Douglas Gregorf64acca2010-05-25 21:41:55 +00001401 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
1402 Results.AddResult(Result(Pattern));
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001403
Douglas Gregorf64acca2010-05-25 21:41:55 +00001404 // for ( for-init-statement ; condition ; expression ) { statements }
1405 Pattern = new CodeCompletionString;
1406 Pattern->AddTypedTextChunk("for");
1407 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
1408 if (SemaRef.getLangOptions().CPlusPlus || SemaRef.getLangOptions().C99)
1409 Pattern->AddPlaceholderChunk("init-statement");
1410 else
1411 Pattern->AddPlaceholderChunk("init-expression");
1412 Pattern->AddChunk(CodeCompletionString::CK_SemiColon);
1413 Pattern->AddPlaceholderChunk("condition");
1414 Pattern->AddChunk(CodeCompletionString::CK_SemiColon);
1415 Pattern->AddPlaceholderChunk("inc-expression");
1416 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
1417 Pattern->AddChunk(CodeCompletionString::CK_LeftBrace);
1418 Pattern->AddPlaceholderChunk("statements");
1419 Pattern->AddChunk(CodeCompletionString::CK_VerticalSpace);
1420 Pattern->AddChunk(CodeCompletionString::CK_RightBrace);
1421 Results.AddResult(Result(Pattern));
1422 }
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001423
1424 if (S->getContinueParent()) {
1425 // continue ;
1426 Pattern = new CodeCompletionString;
1427 Pattern->AddTypedTextChunk("continue");
Douglas Gregor78a21012010-01-14 16:01:26 +00001428 Results.AddResult(Result(Pattern));
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001429 }
1430
1431 if (S->getBreakParent()) {
1432 // break ;
1433 Pattern = new CodeCompletionString;
1434 Pattern->AddTypedTextChunk("break");
Douglas Gregor78a21012010-01-14 16:01:26 +00001435 Results.AddResult(Result(Pattern));
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001436 }
1437
1438 // "return expression ;" or "return ;", depending on whether we
1439 // know the function is void or not.
1440 bool isVoid = false;
1441 if (FunctionDecl *Function = dyn_cast<FunctionDecl>(SemaRef.CurContext))
1442 isVoid = Function->getResultType()->isVoidType();
1443 else if (ObjCMethodDecl *Method
1444 = dyn_cast<ObjCMethodDecl>(SemaRef.CurContext))
1445 isVoid = Method->getResultType()->isVoidType();
Douglas Gregor9a28e842010-03-01 23:15:13 +00001446 else if (SemaRef.getCurBlock() &&
1447 !SemaRef.getCurBlock()->ReturnType.isNull())
1448 isVoid = SemaRef.getCurBlock()->ReturnType->isVoidType();
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001449 Pattern = new CodeCompletionString;
1450 Pattern->AddTypedTextChunk("return");
Douglas Gregor44272ca2010-02-18 04:06:48 +00001451 if (!isVoid) {
1452 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001453 Pattern->AddPlaceholderChunk("expression");
Douglas Gregor44272ca2010-02-18 04:06:48 +00001454 }
Douglas Gregor78a21012010-01-14 16:01:26 +00001455 Results.AddResult(Result(Pattern));
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001456
Douglas Gregorf4c33342010-05-28 00:22:41 +00001457 // goto identifier ;
1458 Pattern = new CodeCompletionString;
1459 Pattern->AddTypedTextChunk("goto");
1460 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
1461 Pattern->AddPlaceholderChunk("label");
1462 Results.AddResult(Result(Pattern));
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001463
Douglas Gregorf4c33342010-05-28 00:22:41 +00001464 // Using directives
1465 Pattern = new CodeCompletionString;
1466 Pattern->AddTypedTextChunk("using");
1467 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
1468 Pattern->AddTextChunk("namespace");
1469 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
1470 Pattern->AddPlaceholderChunk("identifier");
1471 Results.AddResult(Result(Pattern));
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001472 }
1473
1474 // Fall through (for statement expressions).
1475 case Action::CCC_ForInit:
1476 case Action::CCC_Condition:
Douglas Gregorf98e6a22010-01-13 23:51:12 +00001477 AddStorageSpecifiers(CCC, SemaRef.getLangOptions(), Results);
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001478 // Fall through: conditions and statements can have expressions.
1479
1480 case Action::CCC_Expression: {
1481 CodeCompletionString *Pattern = 0;
1482 if (SemaRef.getLangOptions().CPlusPlus) {
1483 // 'this', if we're in a non-static member function.
1484 if (CXXMethodDecl *Method = dyn_cast<CXXMethodDecl>(SemaRef.CurContext))
1485 if (!Method->isStatic())
Douglas Gregor78a21012010-01-14 16:01:26 +00001486 Results.AddResult(Result("this"));
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001487
1488 // true, false
Douglas Gregor78a21012010-01-14 16:01:26 +00001489 Results.AddResult(Result("true"));
1490 Results.AddResult(Result("false"));
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001491
Douglas Gregorf4c33342010-05-28 00:22:41 +00001492 // dynamic_cast < type-id > ( expression )
1493 Pattern = new CodeCompletionString;
1494 Pattern->AddTypedTextChunk("dynamic_cast");
1495 Pattern->AddChunk(CodeCompletionString::CK_LeftAngle);
1496 Pattern->AddPlaceholderChunk("type");
1497 Pattern->AddChunk(CodeCompletionString::CK_RightAngle);
1498 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
1499 Pattern->AddPlaceholderChunk("expression");
1500 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
1501 Results.AddResult(Result(Pattern));
1502
1503 // static_cast < type-id > ( expression )
1504 Pattern = new CodeCompletionString;
1505 Pattern->AddTypedTextChunk("static_cast");
1506 Pattern->AddChunk(CodeCompletionString::CK_LeftAngle);
1507 Pattern->AddPlaceholderChunk("type");
1508 Pattern->AddChunk(CodeCompletionString::CK_RightAngle);
1509 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
1510 Pattern->AddPlaceholderChunk("expression");
1511 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
1512 Results.AddResult(Result(Pattern));
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001513
Douglas Gregorf4c33342010-05-28 00:22:41 +00001514 // reinterpret_cast < type-id > ( expression )
1515 Pattern = new CodeCompletionString;
1516 Pattern->AddTypedTextChunk("reinterpret_cast");
1517 Pattern->AddChunk(CodeCompletionString::CK_LeftAngle);
1518 Pattern->AddPlaceholderChunk("type");
1519 Pattern->AddChunk(CodeCompletionString::CK_RightAngle);
1520 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
1521 Pattern->AddPlaceholderChunk("expression");
1522 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
1523 Results.AddResult(Result(Pattern));
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001524
Douglas Gregorf4c33342010-05-28 00:22:41 +00001525 // const_cast < type-id > ( expression )
1526 Pattern = new CodeCompletionString;
1527 Pattern->AddTypedTextChunk("const_cast");
1528 Pattern->AddChunk(CodeCompletionString::CK_LeftAngle);
1529 Pattern->AddPlaceholderChunk("type");
1530 Pattern->AddChunk(CodeCompletionString::CK_RightAngle);
1531 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
1532 Pattern->AddPlaceholderChunk("expression");
1533 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
1534 Results.AddResult(Result(Pattern));
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001535
Douglas Gregorf4c33342010-05-28 00:22:41 +00001536 // typeid ( expression-or-type )
1537 Pattern = new CodeCompletionString;
1538 Pattern->AddTypedTextChunk("typeid");
1539 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
1540 Pattern->AddPlaceholderChunk("expression-or-type");
1541 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
1542 Results.AddResult(Result(Pattern));
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001543
Douglas Gregorf4c33342010-05-28 00:22:41 +00001544 // new T ( ... )
1545 Pattern = new CodeCompletionString;
1546 Pattern->AddTypedTextChunk("new");
1547 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
1548 Pattern->AddPlaceholderChunk("type");
1549 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
1550 Pattern->AddPlaceholderChunk("expressions");
1551 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
1552 Results.AddResult(Result(Pattern));
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001553
Douglas Gregorf4c33342010-05-28 00:22:41 +00001554 // new T [ ] ( ... )
1555 Pattern = new CodeCompletionString;
1556 Pattern->AddTypedTextChunk("new");
1557 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
1558 Pattern->AddPlaceholderChunk("type");
1559 Pattern->AddChunk(CodeCompletionString::CK_LeftBracket);
1560 Pattern->AddPlaceholderChunk("size");
1561 Pattern->AddChunk(CodeCompletionString::CK_RightBracket);
1562 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
1563 Pattern->AddPlaceholderChunk("expressions");
1564 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
1565 Results.AddResult(Result(Pattern));
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001566
Douglas Gregorf4c33342010-05-28 00:22:41 +00001567 // delete expression
1568 Pattern = new CodeCompletionString;
1569 Pattern->AddTypedTextChunk("delete");
1570 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
1571 Pattern->AddPlaceholderChunk("expression");
1572 Results.AddResult(Result(Pattern));
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001573
Douglas Gregorf4c33342010-05-28 00:22:41 +00001574 // delete [] expression
1575 Pattern = new CodeCompletionString;
1576 Pattern->AddTypedTextChunk("delete");
1577 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
1578 Pattern->AddChunk(CodeCompletionString::CK_LeftBracket);
1579 Pattern->AddChunk(CodeCompletionString::CK_RightBracket);
1580 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
1581 Pattern->AddPlaceholderChunk("expression");
1582 Results.AddResult(Result(Pattern));
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001583
Douglas Gregorf4c33342010-05-28 00:22:41 +00001584 // throw expression
1585 Pattern = new CodeCompletionString;
1586 Pattern->AddTypedTextChunk("throw");
1587 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
1588 Pattern->AddPlaceholderChunk("expression");
1589 Results.AddResult(Result(Pattern));
Douglas Gregora2db7932010-05-26 22:00:08 +00001590
1591 // FIXME: Rethrow?
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001592 }
1593
1594 if (SemaRef.getLangOptions().ObjC1) {
1595 // Add "super", if we're in an Objective-C class with a superclass.
Ted Kremenek305a0a72010-05-31 21:43:10 +00001596 if (ObjCMethodDecl *Method = SemaRef.getCurMethodDecl()) {
1597 // The interface can be NULL.
1598 if (ObjCInterfaceDecl *ID = Method->getClassInterface())
1599 if (ID->getSuperClass())
1600 Results.AddResult(Result("super"));
1601 }
1602
Douglas Gregorf98e6a22010-01-13 23:51:12 +00001603 AddObjCExpressionResults(Results, true);
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001604 }
1605
Douglas Gregorf4c33342010-05-28 00:22:41 +00001606 // sizeof expression
1607 Pattern = new CodeCompletionString;
1608 Pattern->AddTypedTextChunk("sizeof");
1609 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
1610 Pattern->AddPlaceholderChunk("expression-or-type");
1611 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
1612 Results.AddResult(Result(Pattern));
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001613 break;
1614 }
1615 }
1616
Douglas Gregor70febae2010-05-28 00:49:12 +00001617 if (WantTypesInContext(CCC, SemaRef.getLangOptions()))
1618 AddTypeSpecifierResults(SemaRef.getLangOptions(), Results);
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001619
1620 if (SemaRef.getLangOptions().CPlusPlus)
Douglas Gregor78a21012010-01-14 16:01:26 +00001621 Results.AddResult(Result("operator"));
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001622}
1623
Douglas Gregorb3fa9192009-12-18 18:53:37 +00001624/// \brief If the given declaration has an associated type, add it as a result
1625/// type chunk.
1626static void AddResultTypeChunk(ASTContext &Context,
1627 NamedDecl *ND,
1628 CodeCompletionString *Result) {
1629 if (!ND)
1630 return;
1631
1632 // Determine the type of the declaration (if it has a type).
1633 QualType T;
1634 if (FunctionDecl *Function = dyn_cast<FunctionDecl>(ND))
1635 T = Function->getResultType();
1636 else if (ObjCMethodDecl *Method = dyn_cast<ObjCMethodDecl>(ND))
1637 T = Method->getResultType();
1638 else if (FunctionTemplateDecl *FunTmpl = dyn_cast<FunctionTemplateDecl>(ND))
1639 T = FunTmpl->getTemplatedDecl()->getResultType();
1640 else if (EnumConstantDecl *Enumerator = dyn_cast<EnumConstantDecl>(ND))
1641 T = Context.getTypeDeclType(cast<TypeDecl>(Enumerator->getDeclContext()));
1642 else if (isa<UnresolvedUsingValueDecl>(ND)) {
1643 /* Do nothing: ignore unresolved using declarations*/
1644 } else if (ValueDecl *Value = dyn_cast<ValueDecl>(ND))
1645 T = Value->getType();
1646 else if (ObjCPropertyDecl *Property = dyn_cast<ObjCPropertyDecl>(ND))
1647 T = Property->getType();
1648
1649 if (T.isNull() || Context.hasSameType(T, Context.DependentTy))
1650 return;
1651
Douglas Gregorcf04b022010-04-05 21:25:31 +00001652 PrintingPolicy Policy(Context.PrintingPolicy);
1653 Policy.AnonymousTagLocations = false;
1654
Douglas Gregorb3fa9192009-12-18 18:53:37 +00001655 std::string TypeStr;
Douglas Gregorcf04b022010-04-05 21:25:31 +00001656 T.getAsStringInternal(TypeStr, Policy);
Douglas Gregorb3fa9192009-12-18 18:53:37 +00001657 Result->AddResultTypeChunk(TypeStr);
1658}
1659
Douglas Gregor3545ff42009-09-21 16:56:56 +00001660/// \brief Add function parameter chunks to the given code completion string.
1661static void AddFunctionParameterChunks(ASTContext &Context,
1662 FunctionDecl *Function,
1663 CodeCompletionString *Result) {
Douglas Gregor9eb77012009-11-07 00:00:49 +00001664 typedef CodeCompletionString::Chunk Chunk;
1665
Douglas Gregor3545ff42009-09-21 16:56:56 +00001666 CodeCompletionString *CCStr = Result;
1667
1668 for (unsigned P = 0, N = Function->getNumParams(); P != N; ++P) {
1669 ParmVarDecl *Param = Function->getParamDecl(P);
1670
1671 if (Param->hasDefaultArg()) {
1672 // When we see an optional default argument, put that argument and
1673 // the remaining default arguments into a new, optional string.
1674 CodeCompletionString *Opt = new CodeCompletionString;
1675 CCStr->AddOptionalChunk(std::auto_ptr<CodeCompletionString>(Opt));
1676 CCStr = Opt;
1677 }
1678
1679 if (P != 0)
Douglas Gregor9eb77012009-11-07 00:00:49 +00001680 CCStr->AddChunk(Chunk(CodeCompletionString::CK_Comma));
Douglas Gregor3545ff42009-09-21 16:56:56 +00001681
1682 // Format the placeholder string.
1683 std::string PlaceholderStr;
1684 if (Param->getIdentifier())
1685 PlaceholderStr = Param->getIdentifier()->getName();
1686
1687 Param->getType().getAsStringInternal(PlaceholderStr,
1688 Context.PrintingPolicy);
1689
1690 // Add the placeholder string.
Benjamin Kramerb33a97c2009-11-29 20:18:50 +00001691 CCStr->AddPlaceholderChunk(PlaceholderStr);
Douglas Gregor3545ff42009-09-21 16:56:56 +00001692 }
Douglas Gregorba449032009-09-22 21:42:17 +00001693
1694 if (const FunctionProtoType *Proto
1695 = Function->getType()->getAs<FunctionProtoType>())
1696 if (Proto->isVariadic())
1697 CCStr->AddPlaceholderChunk(", ...");
Douglas Gregor3545ff42009-09-21 16:56:56 +00001698}
1699
1700/// \brief Add template parameter chunks to the given code completion string.
1701static void AddTemplateParameterChunks(ASTContext &Context,
1702 TemplateDecl *Template,
1703 CodeCompletionString *Result,
1704 unsigned MaxParameters = 0) {
Douglas Gregor9eb77012009-11-07 00:00:49 +00001705 typedef CodeCompletionString::Chunk Chunk;
1706
Douglas Gregor3545ff42009-09-21 16:56:56 +00001707 CodeCompletionString *CCStr = Result;
1708 bool FirstParameter = true;
1709
1710 TemplateParameterList *Params = Template->getTemplateParameters();
1711 TemplateParameterList::iterator PEnd = Params->end();
1712 if (MaxParameters)
1713 PEnd = Params->begin() + MaxParameters;
1714 for (TemplateParameterList::iterator P = Params->begin(); P != PEnd; ++P) {
1715 bool HasDefaultArg = false;
1716 std::string PlaceholderStr;
1717 if (TemplateTypeParmDecl *TTP = dyn_cast<TemplateTypeParmDecl>(*P)) {
1718 if (TTP->wasDeclaredWithTypename())
1719 PlaceholderStr = "typename";
1720 else
1721 PlaceholderStr = "class";
1722
1723 if (TTP->getIdentifier()) {
1724 PlaceholderStr += ' ';
1725 PlaceholderStr += TTP->getIdentifier()->getName();
1726 }
1727
1728 HasDefaultArg = TTP->hasDefaultArgument();
1729 } else if (NonTypeTemplateParmDecl *NTTP
1730 = dyn_cast<NonTypeTemplateParmDecl>(*P)) {
1731 if (NTTP->getIdentifier())
1732 PlaceholderStr = NTTP->getIdentifier()->getName();
1733 NTTP->getType().getAsStringInternal(PlaceholderStr,
1734 Context.PrintingPolicy);
1735 HasDefaultArg = NTTP->hasDefaultArgument();
1736 } else {
1737 assert(isa<TemplateTemplateParmDecl>(*P));
1738 TemplateTemplateParmDecl *TTP = cast<TemplateTemplateParmDecl>(*P);
1739
1740 // Since putting the template argument list into the placeholder would
1741 // be very, very long, we just use an abbreviation.
1742 PlaceholderStr = "template<...> class";
1743 if (TTP->getIdentifier()) {
1744 PlaceholderStr += ' ';
1745 PlaceholderStr += TTP->getIdentifier()->getName();
1746 }
1747
1748 HasDefaultArg = TTP->hasDefaultArgument();
1749 }
1750
1751 if (HasDefaultArg) {
1752 // When we see an optional default argument, put that argument and
1753 // the remaining default arguments into a new, optional string.
1754 CodeCompletionString *Opt = new CodeCompletionString;
1755 CCStr->AddOptionalChunk(std::auto_ptr<CodeCompletionString>(Opt));
1756 CCStr = Opt;
1757 }
1758
1759 if (FirstParameter)
1760 FirstParameter = false;
1761 else
Douglas Gregor9eb77012009-11-07 00:00:49 +00001762 CCStr->AddChunk(Chunk(CodeCompletionString::CK_Comma));
Douglas Gregor3545ff42009-09-21 16:56:56 +00001763
1764 // Add the placeholder string.
Benjamin Kramerb33a97c2009-11-29 20:18:50 +00001765 CCStr->AddPlaceholderChunk(PlaceholderStr);
Douglas Gregor3545ff42009-09-21 16:56:56 +00001766 }
1767}
1768
Douglas Gregorf2510672009-09-21 19:57:38 +00001769/// \brief Add a qualifier to the given code-completion string, if the
1770/// provided nested-name-specifier is non-NULL.
Douglas Gregor0f622362009-12-11 18:44:16 +00001771static void
1772AddQualifierToCompletionString(CodeCompletionString *Result,
1773 NestedNameSpecifier *Qualifier,
1774 bool QualifierIsInformative,
1775 ASTContext &Context) {
Douglas Gregorf2510672009-09-21 19:57:38 +00001776 if (!Qualifier)
1777 return;
1778
1779 std::string PrintedNNS;
1780 {
1781 llvm::raw_string_ostream OS(PrintedNNS);
1782 Qualifier->print(OS, Context.PrintingPolicy);
1783 }
Douglas Gregor5bf52692009-09-22 23:15:58 +00001784 if (QualifierIsInformative)
Benjamin Kramerb33a97c2009-11-29 20:18:50 +00001785 Result->AddInformativeChunk(PrintedNNS);
Douglas Gregor5bf52692009-09-22 23:15:58 +00001786 else
Benjamin Kramerb33a97c2009-11-29 20:18:50 +00001787 Result->AddTextChunk(PrintedNNS);
Douglas Gregorf2510672009-09-21 19:57:38 +00001788}
1789
Douglas Gregor0f622362009-12-11 18:44:16 +00001790static void AddFunctionTypeQualsToCompletionString(CodeCompletionString *Result,
1791 FunctionDecl *Function) {
1792 const FunctionProtoType *Proto
1793 = Function->getType()->getAs<FunctionProtoType>();
1794 if (!Proto || !Proto->getTypeQuals())
1795 return;
1796
1797 std::string QualsStr;
1798 if (Proto->getTypeQuals() & Qualifiers::Const)
1799 QualsStr += " const";
1800 if (Proto->getTypeQuals() & Qualifiers::Volatile)
1801 QualsStr += " volatile";
1802 if (Proto->getTypeQuals() & Qualifiers::Restrict)
1803 QualsStr += " restrict";
1804 Result->AddInformativeChunk(QualsStr);
1805}
1806
Douglas Gregor3545ff42009-09-21 16:56:56 +00001807/// \brief If possible, create a new code completion string for the given
1808/// result.
1809///
1810/// \returns Either a new, heap-allocated code completion string describing
1811/// how to use this result, or NULL to indicate that the string or name of the
1812/// result is all that is needed.
1813CodeCompletionString *
1814CodeCompleteConsumer::Result::CreateCodeCompletionString(Sema &S) {
Douglas Gregor9eb77012009-11-07 00:00:49 +00001815 typedef CodeCompletionString::Chunk Chunk;
1816
Douglas Gregorf09935f2009-12-01 05:55:20 +00001817 if (Kind == RK_Pattern)
1818 return Pattern->Clone();
1819
1820 CodeCompletionString *Result = new CodeCompletionString;
1821
1822 if (Kind == RK_Keyword) {
1823 Result->AddTypedTextChunk(Keyword);
1824 return Result;
1825 }
Douglas Gregor3545ff42009-09-21 16:56:56 +00001826
Douglas Gregorf329c7c2009-10-30 16:50:04 +00001827 if (Kind == RK_Macro) {
1828 MacroInfo *MI = S.PP.getMacroInfo(Macro);
Douglas Gregorf09935f2009-12-01 05:55:20 +00001829 assert(MI && "Not a macro?");
1830
1831 Result->AddTypedTextChunk(Macro->getName());
1832
1833 if (!MI->isFunctionLike())
1834 return Result;
Douglas Gregorf329c7c2009-10-30 16:50:04 +00001835
1836 // Format a function-like macro with placeholders for the arguments.
Douglas Gregor9eb77012009-11-07 00:00:49 +00001837 Result->AddChunk(Chunk(CodeCompletionString::CK_LeftParen));
Douglas Gregorf329c7c2009-10-30 16:50:04 +00001838 for (MacroInfo::arg_iterator A = MI->arg_begin(), AEnd = MI->arg_end();
1839 A != AEnd; ++A) {
1840 if (A != MI->arg_begin())
Douglas Gregor9eb77012009-11-07 00:00:49 +00001841 Result->AddChunk(Chunk(CodeCompletionString::CK_Comma));
Douglas Gregorf329c7c2009-10-30 16:50:04 +00001842
1843 if (!MI->isVariadic() || A != AEnd - 1) {
1844 // Non-variadic argument.
Benjamin Kramerb33a97c2009-11-29 20:18:50 +00001845 Result->AddPlaceholderChunk((*A)->getName());
Douglas Gregorf329c7c2009-10-30 16:50:04 +00001846 continue;
1847 }
1848
1849 // Variadic argument; cope with the different between GNU and C99
1850 // variadic macros, providing a single placeholder for the rest of the
1851 // arguments.
1852 if ((*A)->isStr("__VA_ARGS__"))
1853 Result->AddPlaceholderChunk("...");
1854 else {
1855 std::string Arg = (*A)->getName();
1856 Arg += "...";
Benjamin Kramerb33a97c2009-11-29 20:18:50 +00001857 Result->AddPlaceholderChunk(Arg);
Douglas Gregorf329c7c2009-10-30 16:50:04 +00001858 }
1859 }
Douglas Gregor9eb77012009-11-07 00:00:49 +00001860 Result->AddChunk(Chunk(CodeCompletionString::CK_RightParen));
Douglas Gregorf329c7c2009-10-30 16:50:04 +00001861 return Result;
1862 }
1863
Douglas Gregorf64acca2010-05-25 21:41:55 +00001864 assert(Kind == RK_Declaration && "Missed a result kind?");
Douglas Gregor3545ff42009-09-21 16:56:56 +00001865 NamedDecl *ND = Declaration;
1866
Douglas Gregor9eb77012009-11-07 00:00:49 +00001867 if (StartsNestedNameSpecifier) {
Benjamin Kramerb33a97c2009-11-29 20:18:50 +00001868 Result->AddTypedTextChunk(ND->getNameAsString());
Douglas Gregor9eb77012009-11-07 00:00:49 +00001869 Result->AddTextChunk("::");
1870 return Result;
1871 }
1872
Douglas Gregorb3fa9192009-12-18 18:53:37 +00001873 AddResultTypeChunk(S.Context, ND, Result);
1874
Douglas Gregor3545ff42009-09-21 16:56:56 +00001875 if (FunctionDecl *Function = dyn_cast<FunctionDecl>(ND)) {
Douglas Gregor5bf52692009-09-22 23:15:58 +00001876 AddQualifierToCompletionString(Result, Qualifier, QualifierIsInformative,
1877 S.Context);
Benjamin Kramerb33a97c2009-11-29 20:18:50 +00001878 Result->AddTypedTextChunk(Function->getNameAsString());
Douglas Gregor9eb77012009-11-07 00:00:49 +00001879 Result->AddChunk(Chunk(CodeCompletionString::CK_LeftParen));
Douglas Gregor3545ff42009-09-21 16:56:56 +00001880 AddFunctionParameterChunks(S.Context, Function, Result);
Douglas Gregor9eb77012009-11-07 00:00:49 +00001881 Result->AddChunk(Chunk(CodeCompletionString::CK_RightParen));
Douglas Gregor0f622362009-12-11 18:44:16 +00001882 AddFunctionTypeQualsToCompletionString(Result, Function);
Douglas Gregor3545ff42009-09-21 16:56:56 +00001883 return Result;
1884 }
1885
1886 if (FunctionTemplateDecl *FunTmpl = dyn_cast<FunctionTemplateDecl>(ND)) {
Douglas Gregor5bf52692009-09-22 23:15:58 +00001887 AddQualifierToCompletionString(Result, Qualifier, QualifierIsInformative,
1888 S.Context);
Douglas Gregor3545ff42009-09-21 16:56:56 +00001889 FunctionDecl *Function = FunTmpl->getTemplatedDecl();
Benjamin Kramerb33a97c2009-11-29 20:18:50 +00001890 Result->AddTypedTextChunk(Function->getNameAsString());
Douglas Gregor3545ff42009-09-21 16:56:56 +00001891
1892 // Figure out which template parameters are deduced (or have default
1893 // arguments).
1894 llvm::SmallVector<bool, 16> Deduced;
1895 S.MarkDeducedTemplateParameters(FunTmpl, Deduced);
1896 unsigned LastDeducibleArgument;
1897 for (LastDeducibleArgument = Deduced.size(); LastDeducibleArgument > 0;
1898 --LastDeducibleArgument) {
1899 if (!Deduced[LastDeducibleArgument - 1]) {
1900 // C++0x: Figure out if the template argument has a default. If so,
1901 // the user doesn't need to type this argument.
1902 // FIXME: We need to abstract template parameters better!
1903 bool HasDefaultArg = false;
1904 NamedDecl *Param = FunTmpl->getTemplateParameters()->getParam(
1905 LastDeducibleArgument - 1);
1906 if (TemplateTypeParmDecl *TTP = dyn_cast<TemplateTypeParmDecl>(Param))
1907 HasDefaultArg = TTP->hasDefaultArgument();
1908 else if (NonTypeTemplateParmDecl *NTTP
1909 = dyn_cast<NonTypeTemplateParmDecl>(Param))
1910 HasDefaultArg = NTTP->hasDefaultArgument();
1911 else {
1912 assert(isa<TemplateTemplateParmDecl>(Param));
1913 HasDefaultArg
Douglas Gregor9eb77012009-11-07 00:00:49 +00001914 = cast<TemplateTemplateParmDecl>(Param)->hasDefaultArgument();
Douglas Gregor3545ff42009-09-21 16:56:56 +00001915 }
1916
1917 if (!HasDefaultArg)
1918 break;
1919 }
1920 }
1921
1922 if (LastDeducibleArgument) {
1923 // Some of the function template arguments cannot be deduced from a
1924 // function call, so we introduce an explicit template argument list
1925 // containing all of the arguments up to the first deducible argument.
Douglas Gregor9eb77012009-11-07 00:00:49 +00001926 Result->AddChunk(Chunk(CodeCompletionString::CK_LeftAngle));
Douglas Gregor3545ff42009-09-21 16:56:56 +00001927 AddTemplateParameterChunks(S.Context, FunTmpl, Result,
1928 LastDeducibleArgument);
Douglas Gregor9eb77012009-11-07 00:00:49 +00001929 Result->AddChunk(Chunk(CodeCompletionString::CK_RightAngle));
Douglas Gregor3545ff42009-09-21 16:56:56 +00001930 }
1931
1932 // Add the function parameters
Douglas Gregor9eb77012009-11-07 00:00:49 +00001933 Result->AddChunk(Chunk(CodeCompletionString::CK_LeftParen));
Douglas Gregor3545ff42009-09-21 16:56:56 +00001934 AddFunctionParameterChunks(S.Context, Function, Result);
Douglas Gregor9eb77012009-11-07 00:00:49 +00001935 Result->AddChunk(Chunk(CodeCompletionString::CK_RightParen));
Douglas Gregor0f622362009-12-11 18:44:16 +00001936 AddFunctionTypeQualsToCompletionString(Result, Function);
Douglas Gregor3545ff42009-09-21 16:56:56 +00001937 return Result;
1938 }
1939
1940 if (TemplateDecl *Template = dyn_cast<TemplateDecl>(ND)) {
Douglas Gregor5bf52692009-09-22 23:15:58 +00001941 AddQualifierToCompletionString(Result, Qualifier, QualifierIsInformative,
1942 S.Context);
Benjamin Kramerb33a97c2009-11-29 20:18:50 +00001943 Result->AddTypedTextChunk(Template->getNameAsString());
Douglas Gregor9eb77012009-11-07 00:00:49 +00001944 Result->AddChunk(Chunk(CodeCompletionString::CK_LeftAngle));
Douglas Gregor3545ff42009-09-21 16:56:56 +00001945 AddTemplateParameterChunks(S.Context, Template, Result);
Douglas Gregor9eb77012009-11-07 00:00:49 +00001946 Result->AddChunk(Chunk(CodeCompletionString::CK_RightAngle));
Douglas Gregor3545ff42009-09-21 16:56:56 +00001947 return Result;
1948 }
1949
Douglas Gregord3c5d792009-11-17 16:44:22 +00001950 if (ObjCMethodDecl *Method = dyn_cast<ObjCMethodDecl>(ND)) {
Douglas Gregord3c5d792009-11-17 16:44:22 +00001951 Selector Sel = Method->getSelector();
1952 if (Sel.isUnarySelector()) {
1953 Result->AddTypedTextChunk(Sel.getIdentifierInfoForSlot(0)->getName());
1954 return Result;
1955 }
1956
Douglas Gregor1b605f72009-11-19 01:08:35 +00001957 std::string SelName = Sel.getIdentifierInfoForSlot(0)->getName().str();
1958 SelName += ':';
1959 if (StartParameter == 0)
1960 Result->AddTypedTextChunk(SelName);
1961 else {
1962 Result->AddInformativeChunk(SelName);
1963
1964 // If there is only one parameter, and we're past it, add an empty
1965 // typed-text chunk since there is nothing to type.
1966 if (Method->param_size() == 1)
1967 Result->AddTypedTextChunk("");
1968 }
Douglas Gregord3c5d792009-11-17 16:44:22 +00001969 unsigned Idx = 0;
1970 for (ObjCMethodDecl::param_iterator P = Method->param_begin(),
1971 PEnd = Method->param_end();
1972 P != PEnd; (void)++P, ++Idx) {
1973 if (Idx > 0) {
Douglas Gregor1b605f72009-11-19 01:08:35 +00001974 std::string Keyword;
1975 if (Idx > StartParameter)
Douglas Gregor6a803932010-01-12 06:38:28 +00001976 Result->AddChunk(CodeCompletionString::CK_HorizontalSpace);
Douglas Gregord3c5d792009-11-17 16:44:22 +00001977 if (IdentifierInfo *II = Sel.getIdentifierInfoForSlot(Idx))
1978 Keyword += II->getName().str();
1979 Keyword += ":";
Douglas Gregor95887f92010-07-08 23:20:03 +00001980 if (Idx < StartParameter || AllParametersAreInformative)
Douglas Gregor1b605f72009-11-19 01:08:35 +00001981 Result->AddInformativeChunk(Keyword);
Douglas Gregor95887f92010-07-08 23:20:03 +00001982 else if (Idx == StartParameter)
Douglas Gregor1b605f72009-11-19 01:08:35 +00001983 Result->AddTypedTextChunk(Keyword);
1984 else
1985 Result->AddTextChunk(Keyword);
Douglas Gregord3c5d792009-11-17 16:44:22 +00001986 }
Douglas Gregor1b605f72009-11-19 01:08:35 +00001987
1988 // If we're before the starting parameter, skip the placeholder.
1989 if (Idx < StartParameter)
1990 continue;
Douglas Gregord3c5d792009-11-17 16:44:22 +00001991
1992 std::string Arg;
1993 (*P)->getType().getAsStringInternal(Arg, S.Context.PrintingPolicy);
1994 Arg = "(" + Arg + ")";
1995 if (IdentifierInfo *II = (*P)->getIdentifier())
1996 Arg += II->getName().str();
Douglas Gregor95887f92010-07-08 23:20:03 +00001997 if (DeclaringEntity)
1998 Result->AddTextChunk(Arg);
1999 else if (AllParametersAreInformative)
Douglas Gregorc8537c52009-11-19 07:41:15 +00002000 Result->AddInformativeChunk(Arg);
2001 else
2002 Result->AddPlaceholderChunk(Arg);
Douglas Gregord3c5d792009-11-17 16:44:22 +00002003 }
2004
Douglas Gregor04c5f972009-12-23 00:21:46 +00002005 if (Method->isVariadic()) {
Douglas Gregor95887f92010-07-08 23:20:03 +00002006 if (DeclaringEntity)
2007 Result->AddTextChunk(", ...");
2008 else if (AllParametersAreInformative)
Douglas Gregor04c5f972009-12-23 00:21:46 +00002009 Result->AddInformativeChunk(", ...");
2010 else
2011 Result->AddPlaceholderChunk(", ...");
2012 }
2013
Douglas Gregord3c5d792009-11-17 16:44:22 +00002014 return Result;
2015 }
2016
Douglas Gregorf09935f2009-12-01 05:55:20 +00002017 if (Qualifier)
Douglas Gregor5bf52692009-09-22 23:15:58 +00002018 AddQualifierToCompletionString(Result, Qualifier, QualifierIsInformative,
2019 S.Context);
Douglas Gregorf09935f2009-12-01 05:55:20 +00002020
2021 Result->AddTypedTextChunk(ND->getNameAsString());
2022 return Result;
Douglas Gregor3545ff42009-09-21 16:56:56 +00002023}
2024
Douglas Gregorf0f51982009-09-23 00:34:09 +00002025CodeCompletionString *
2026CodeCompleteConsumer::OverloadCandidate::CreateSignatureString(
2027 unsigned CurrentArg,
2028 Sema &S) const {
Douglas Gregor9eb77012009-11-07 00:00:49 +00002029 typedef CodeCompletionString::Chunk Chunk;
2030
Douglas Gregorf0f51982009-09-23 00:34:09 +00002031 CodeCompletionString *Result = new CodeCompletionString;
2032 FunctionDecl *FDecl = getFunction();
Douglas Gregorb3fa9192009-12-18 18:53:37 +00002033 AddResultTypeChunk(S.Context, FDecl, Result);
Douglas Gregorf0f51982009-09-23 00:34:09 +00002034 const FunctionProtoType *Proto
2035 = dyn_cast<FunctionProtoType>(getFunctionType());
2036 if (!FDecl && !Proto) {
2037 // Function without a prototype. Just give the return type and a
2038 // highlighted ellipsis.
2039 const FunctionType *FT = getFunctionType();
2040 Result->AddTextChunk(
Benjamin Kramerb33a97c2009-11-29 20:18:50 +00002041 FT->getResultType().getAsString(S.Context.PrintingPolicy));
Douglas Gregor9eb77012009-11-07 00:00:49 +00002042 Result->AddChunk(Chunk(CodeCompletionString::CK_LeftParen));
2043 Result->AddChunk(Chunk(CodeCompletionString::CK_CurrentParameter, "..."));
2044 Result->AddChunk(Chunk(CodeCompletionString::CK_RightParen));
Douglas Gregorf0f51982009-09-23 00:34:09 +00002045 return Result;
2046 }
2047
2048 if (FDecl)
Benjamin Kramerb33a97c2009-11-29 20:18:50 +00002049 Result->AddTextChunk(FDecl->getNameAsString());
Douglas Gregorf0f51982009-09-23 00:34:09 +00002050 else
2051 Result->AddTextChunk(
Benjamin Kramerb33a97c2009-11-29 20:18:50 +00002052 Proto->getResultType().getAsString(S.Context.PrintingPolicy));
Douglas Gregorf0f51982009-09-23 00:34:09 +00002053
Douglas Gregor9eb77012009-11-07 00:00:49 +00002054 Result->AddChunk(Chunk(CodeCompletionString::CK_LeftParen));
Douglas Gregorf0f51982009-09-23 00:34:09 +00002055 unsigned NumParams = FDecl? FDecl->getNumParams() : Proto->getNumArgs();
2056 for (unsigned I = 0; I != NumParams; ++I) {
2057 if (I)
Douglas Gregor9eb77012009-11-07 00:00:49 +00002058 Result->AddChunk(Chunk(CodeCompletionString::CK_Comma));
Douglas Gregorf0f51982009-09-23 00:34:09 +00002059
2060 std::string ArgString;
2061 QualType ArgType;
2062
2063 if (FDecl) {
2064 ArgString = FDecl->getParamDecl(I)->getNameAsString();
2065 ArgType = FDecl->getParamDecl(I)->getOriginalType();
2066 } else {
2067 ArgType = Proto->getArgType(I);
2068 }
2069
2070 ArgType.getAsStringInternal(ArgString, S.Context.PrintingPolicy);
2071
2072 if (I == CurrentArg)
Douglas Gregor9eb77012009-11-07 00:00:49 +00002073 Result->AddChunk(Chunk(CodeCompletionString::CK_CurrentParameter,
Benjamin Kramerb33a97c2009-11-29 20:18:50 +00002074 ArgString));
Douglas Gregorf0f51982009-09-23 00:34:09 +00002075 else
Benjamin Kramerb33a97c2009-11-29 20:18:50 +00002076 Result->AddTextChunk(ArgString);
Douglas Gregorf0f51982009-09-23 00:34:09 +00002077 }
2078
2079 if (Proto && Proto->isVariadic()) {
Douglas Gregor9eb77012009-11-07 00:00:49 +00002080 Result->AddChunk(Chunk(CodeCompletionString::CK_Comma));
Douglas Gregorf0f51982009-09-23 00:34:09 +00002081 if (CurrentArg < NumParams)
2082 Result->AddTextChunk("...");
2083 else
Douglas Gregor9eb77012009-11-07 00:00:49 +00002084 Result->AddChunk(Chunk(CodeCompletionString::CK_CurrentParameter, "..."));
Douglas Gregorf0f51982009-09-23 00:34:09 +00002085 }
Douglas Gregor9eb77012009-11-07 00:00:49 +00002086 Result->AddChunk(Chunk(CodeCompletionString::CK_RightParen));
Douglas Gregorf0f51982009-09-23 00:34:09 +00002087
2088 return Result;
2089}
2090
Douglas Gregor3545ff42009-09-21 16:56:56 +00002091namespace {
2092 struct SortCodeCompleteResult {
2093 typedef CodeCompleteConsumer::Result Result;
2094
Douglas Gregore6688e62009-09-28 03:51:44 +00002095 bool isEarlierDeclarationName(DeclarationName X, DeclarationName Y) const {
Douglas Gregor249d6822009-12-05 09:08:56 +00002096 Selector XSel = X.getObjCSelector();
2097 Selector YSel = Y.getObjCSelector();
2098 if (!XSel.isNull() && !YSel.isNull()) {
2099 // We are comparing two selectors.
2100 unsigned N = std::min(XSel.getNumArgs(), YSel.getNumArgs());
2101 if (N == 0)
2102 ++N;
2103 for (unsigned I = 0; I != N; ++I) {
2104 IdentifierInfo *XId = XSel.getIdentifierInfoForSlot(I);
2105 IdentifierInfo *YId = YSel.getIdentifierInfoForSlot(I);
2106 if (!XId || !YId)
2107 return XId && !YId;
2108
2109 switch (XId->getName().compare_lower(YId->getName())) {
2110 case -1: return true;
2111 case 1: return false;
2112 default: break;
2113 }
2114 }
2115
2116 return XSel.getNumArgs() < YSel.getNumArgs();
2117 }
2118
2119 // For non-selectors, order by kind.
2120 if (X.getNameKind() != Y.getNameKind())
Douglas Gregore6688e62009-09-28 03:51:44 +00002121 return X.getNameKind() < Y.getNameKind();
2122
Douglas Gregor249d6822009-12-05 09:08:56 +00002123 // Order identifiers by comparison of their lowercased names.
2124 if (IdentifierInfo *XId = X.getAsIdentifierInfo())
2125 return XId->getName().compare_lower(
2126 Y.getAsIdentifierInfo()->getName()) < 0;
2127
2128 // Order overloaded operators by the order in which they appear
2129 // in our list of operators.
2130 if (OverloadedOperatorKind XOp = X.getCXXOverloadedOperator())
2131 return XOp < Y.getCXXOverloadedOperator();
2132
2133 // Order C++0x user-defined literal operators lexically by their
2134 // lowercased suffixes.
2135 if (IdentifierInfo *XLit = X.getCXXLiteralIdentifier())
2136 return XLit->getName().compare_lower(
2137 Y.getCXXLiteralIdentifier()->getName()) < 0;
2138
2139 // The only stable ordering we have is to turn the name into a
2140 // string and then compare the lower-case strings. This is
2141 // inefficient, but thankfully does not happen too often.
Benjamin Kramer4053e5d2009-12-05 10:22:15 +00002142 return llvm::StringRef(X.getAsString()).compare_lower(
2143 Y.getAsString()) < 0;
Douglas Gregore6688e62009-09-28 03:51:44 +00002144 }
2145
Douglas Gregor52ce62f2010-01-13 23:24:38 +00002146 /// \brief Retrieve the name that should be used to order a result.
2147 ///
2148 /// If the name needs to be constructed as a string, that string will be
2149 /// saved into Saved and the returned StringRef will refer to it.
2150 static llvm::StringRef getOrderedName(const Result &R,
2151 std::string &Saved) {
2152 switch (R.Kind) {
2153 case Result::RK_Keyword:
2154 return R.Keyword;
2155
2156 case Result::RK_Pattern:
2157 return R.Pattern->getTypedText();
2158
2159 case Result::RK_Macro:
2160 return R.Macro->getName();
2161
2162 case Result::RK_Declaration:
2163 // Handle declarations below.
2164 break;
Douglas Gregor45f83ee2009-11-19 00:01:57 +00002165 }
Douglas Gregor52ce62f2010-01-13 23:24:38 +00002166
2167 DeclarationName Name = R.Declaration->getDeclName();
Douglas Gregor45f83ee2009-11-19 00:01:57 +00002168
Douglas Gregor52ce62f2010-01-13 23:24:38 +00002169 // If the name is a simple identifier (by far the common case), or a
2170 // zero-argument selector, just return a reference to that identifier.
2171 if (IdentifierInfo *Id = Name.getAsIdentifierInfo())
2172 return Id->getName();
2173 if (Name.isObjCZeroArgSelector())
2174 if (IdentifierInfo *Id
2175 = Name.getObjCSelector().getIdentifierInfoForSlot(0))
2176 return Id->getName();
2177
2178 Saved = Name.getAsString();
2179 return Saved;
2180 }
2181
2182 bool operator()(const Result &X, const Result &Y) const {
2183 std::string XSaved, YSaved;
2184 llvm::StringRef XStr = getOrderedName(X, XSaved);
2185 llvm::StringRef YStr = getOrderedName(Y, YSaved);
2186 int cmp = XStr.compare_lower(YStr);
2187 if (cmp)
2188 return cmp < 0;
Douglas Gregor3545ff42009-09-21 16:56:56 +00002189
2190 // Non-hidden names precede hidden names.
2191 if (X.Hidden != Y.Hidden)
2192 return !X.Hidden;
2193
Douglas Gregore412a5a2009-09-23 22:26:46 +00002194 // Non-nested-name-specifiers precede nested-name-specifiers.
2195 if (X.StartsNestedNameSpecifier != Y.StartsNestedNameSpecifier)
2196 return !X.StartsNestedNameSpecifier;
2197
Douglas Gregor3545ff42009-09-21 16:56:56 +00002198 return false;
2199 }
2200 };
2201}
2202
Douglas Gregor55b037b2010-07-08 20:55:51 +00002203static void AddMacroResults(Preprocessor &PP, ResultBuilder &Results,
2204 bool TargetTypeIsPointer = false) {
2205 typedef CodeCompleteConsumer::Result Result;
2206
Douglas Gregorf329c7c2009-10-30 16:50:04 +00002207 Results.EnterNewScope();
Douglas Gregor9eb77012009-11-07 00:00:49 +00002208 for (Preprocessor::macro_iterator M = PP.macro_begin(),
2209 MEnd = PP.macro_end();
Douglas Gregor55b037b2010-07-08 20:55:51 +00002210 M != MEnd; ++M) {
2211 unsigned Priority = CCP_Macro;
2212
2213 // Treat the "nil" and "NULL" macros as null pointer constants.
2214 if (M->first->isStr("nil") || M->first->isStr("NULL")) {
2215 Priority = CCP_Constant;
2216 if (TargetTypeIsPointer)
2217 Priority = Priority / CCF_SimilarTypeMatch;
2218 }
2219
2220 Results.AddResult(Result(M->first, Priority));
2221 }
Douglas Gregorf329c7c2009-10-30 16:50:04 +00002222 Results.ExitScope();
2223}
2224
Daniel Dunbar242ea9a2009-11-13 08:58:20 +00002225static void HandleCodeCompleteResults(Sema *S,
2226 CodeCompleteConsumer *CodeCompleter,
2227 CodeCompleteConsumer::Result *Results,
2228 unsigned NumResults) {
Douglas Gregor3545ff42009-09-21 16:56:56 +00002229 std::stable_sort(Results, Results + NumResults, SortCodeCompleteResult());
2230
2231 if (CodeCompleter)
Daniel Dunbar242ea9a2009-11-13 08:58:20 +00002232 CodeCompleter->ProcessCodeCompleteResults(*S, Results, NumResults);
Douglas Gregor45f83ee2009-11-19 00:01:57 +00002233
2234 for (unsigned I = 0; I != NumResults; ++I)
2235 Results[I].Destroy();
Douglas Gregor3545ff42009-09-21 16:56:56 +00002236}
2237
Douglas Gregor504a6ae2010-01-10 23:08:15 +00002238void Sema::CodeCompleteOrdinaryName(Scope *S,
2239 CodeCompletionContext CompletionContext) {
Douglas Gregor92253692009-12-07 09:54:55 +00002240 typedef CodeCompleteConsumer::Result Result;
Douglas Gregor504a6ae2010-01-10 23:08:15 +00002241 ResultBuilder Results(*this);
2242
2243 // Determine how to filter results, e.g., so that the names of
2244 // values (functions, enumerators, function templates, etc.) are
2245 // only allowed where we can have an expression.
2246 switch (CompletionContext) {
2247 case CCC_Namespace:
2248 case CCC_Class:
Douglas Gregorf1934162010-01-13 21:24:21 +00002249 case CCC_ObjCInterface:
2250 case CCC_ObjCImplementation:
Douglas Gregor48d46252010-01-13 21:54:15 +00002251 case CCC_ObjCInstanceVariableList:
Douglas Gregor504a6ae2010-01-10 23:08:15 +00002252 case CCC_Template:
2253 case CCC_MemberTemplate:
2254 Results.setFilter(&ResultBuilder::IsOrdinaryNonValueName);
2255 break;
2256
2257 case CCC_Expression:
2258 case CCC_Statement:
2259 case CCC_ForInit:
2260 case CCC_Condition:
Douglas Gregor70febae2010-05-28 00:49:12 +00002261 if (WantTypesInContext(CompletionContext, getLangOptions()))
2262 Results.setFilter(&ResultBuilder::IsOrdinaryName);
2263 else
2264 Results.setFilter(&ResultBuilder::IsOrdinaryNonTypeName);
Douglas Gregor504a6ae2010-01-10 23:08:15 +00002265 break;
Douglas Gregor6da3db42010-05-25 05:58:43 +00002266
2267 case CCC_RecoveryInFunction:
2268 // Unfiltered
2269 break;
Douglas Gregor504a6ae2010-01-10 23:08:15 +00002270 }
2271
Douglas Gregorc580c522010-01-14 01:09:38 +00002272 CodeCompletionDeclConsumer Consumer(Results, CurContext);
2273 LookupVisibleDecls(S, LookupOrdinaryName, Consumer);
Douglas Gregor92253692009-12-07 09:54:55 +00002274
2275 Results.EnterNewScope();
Douglas Gregorf98e6a22010-01-13 23:51:12 +00002276 AddOrdinaryNameResults(CompletionContext, S, *this, Results);
Douglas Gregor92253692009-12-07 09:54:55 +00002277 Results.ExitScope();
2278
Douglas Gregor9eb77012009-11-07 00:00:49 +00002279 if (CodeCompleter->includeMacros())
Douglas Gregorf98e6a22010-01-13 23:51:12 +00002280 AddMacroResults(PP, Results);
Daniel Dunbar242ea9a2009-11-13 08:58:20 +00002281 HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
Douglas Gregor9d64c5e2009-09-21 20:51:25 +00002282}
2283
Douglas Gregor7aa6b222010-05-30 01:49:25 +00002284/// \brief Perform code-completion in an expression context when we know what
2285/// type we're looking for.
Douglas Gregor85b50632010-07-28 21:50:18 +00002286///
2287/// \param IntegralConstantExpression Only permit integral constant
2288/// expressions.
2289void Sema::CodeCompleteExpression(Scope *S, QualType T,
2290 bool IntegralConstantExpression) {
Douglas Gregor7aa6b222010-05-30 01:49:25 +00002291 typedef CodeCompleteConsumer::Result Result;
2292 ResultBuilder Results(*this);
2293
Douglas Gregor85b50632010-07-28 21:50:18 +00002294 if (IntegralConstantExpression)
2295 Results.setFilter(&ResultBuilder::IsIntegralConstantValue);
2296 else if (WantTypesInContext(CCC_Expression, getLangOptions()))
Douglas Gregor7aa6b222010-05-30 01:49:25 +00002297 Results.setFilter(&ResultBuilder::IsOrdinaryName);
2298 else
2299 Results.setFilter(&ResultBuilder::IsOrdinaryNonTypeName);
2300 Results.setPreferredType(T.getNonReferenceType());
2301
2302 CodeCompletionDeclConsumer Consumer(Results, CurContext);
2303 LookupVisibleDecls(S, LookupOrdinaryName, Consumer);
2304
2305 Results.EnterNewScope();
2306 AddOrdinaryNameResults(CCC_Expression, S, *this, Results);
2307 Results.ExitScope();
2308
Douglas Gregor55b037b2010-07-08 20:55:51 +00002309 bool PreferredTypeIsPointer = false;
2310 if (!T.isNull())
2311 PreferredTypeIsPointer = T->isAnyPointerType() ||
2312 T->isMemberPointerType() || T->isBlockPointerType();
2313
Douglas Gregor7aa6b222010-05-30 01:49:25 +00002314 if (CodeCompleter->includeMacros())
Douglas Gregor55b037b2010-07-08 20:55:51 +00002315 AddMacroResults(PP, Results, PreferredTypeIsPointer);
Douglas Gregor7aa6b222010-05-30 01:49:25 +00002316 HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
2317}
2318
2319
Douglas Gregor9291bad2009-11-18 01:29:26 +00002320static void AddObjCProperties(ObjCContainerDecl *Container,
Douglas Gregor5d649882009-11-18 22:32:06 +00002321 bool AllowCategories,
Douglas Gregor9291bad2009-11-18 01:29:26 +00002322 DeclContext *CurContext,
2323 ResultBuilder &Results) {
2324 typedef CodeCompleteConsumer::Result Result;
2325
2326 // Add properties in this container.
2327 for (ObjCContainerDecl::prop_iterator P = Container->prop_begin(),
2328 PEnd = Container->prop_end();
2329 P != PEnd;
2330 ++P)
2331 Results.MaybeAddResult(Result(*P, 0), CurContext);
2332
2333 // Add properties in referenced protocols.
2334 if (ObjCProtocolDecl *Protocol = dyn_cast<ObjCProtocolDecl>(Container)) {
2335 for (ObjCProtocolDecl::protocol_iterator P = Protocol->protocol_begin(),
2336 PEnd = Protocol->protocol_end();
2337 P != PEnd; ++P)
Douglas Gregor5d649882009-11-18 22:32:06 +00002338 AddObjCProperties(*P, AllowCategories, CurContext, Results);
Douglas Gregor9291bad2009-11-18 01:29:26 +00002339 } else if (ObjCInterfaceDecl *IFace = dyn_cast<ObjCInterfaceDecl>(Container)){
Douglas Gregor5d649882009-11-18 22:32:06 +00002340 if (AllowCategories) {
2341 // Look through categories.
2342 for (ObjCCategoryDecl *Category = IFace->getCategoryList();
2343 Category; Category = Category->getNextClassCategory())
2344 AddObjCProperties(Category, AllowCategories, CurContext, Results);
2345 }
Douglas Gregor9291bad2009-11-18 01:29:26 +00002346
2347 // Look through protocols.
2348 for (ObjCInterfaceDecl::protocol_iterator I = IFace->protocol_begin(),
2349 E = IFace->protocol_end();
2350 I != E; ++I)
Douglas Gregor5d649882009-11-18 22:32:06 +00002351 AddObjCProperties(*I, AllowCategories, CurContext, Results);
Douglas Gregor9291bad2009-11-18 01:29:26 +00002352
2353 // Look in the superclass.
2354 if (IFace->getSuperClass())
Douglas Gregor5d649882009-11-18 22:32:06 +00002355 AddObjCProperties(IFace->getSuperClass(), AllowCategories, CurContext,
2356 Results);
Douglas Gregor9291bad2009-11-18 01:29:26 +00002357 } else if (const ObjCCategoryDecl *Category
2358 = dyn_cast<ObjCCategoryDecl>(Container)) {
2359 // Look through protocols.
2360 for (ObjCInterfaceDecl::protocol_iterator P = Category->protocol_begin(),
2361 PEnd = Category->protocol_end();
2362 P != PEnd; ++P)
Douglas Gregor5d649882009-11-18 22:32:06 +00002363 AddObjCProperties(*P, AllowCategories, CurContext, Results);
Douglas Gregor9291bad2009-11-18 01:29:26 +00002364 }
2365}
2366
Douglas Gregor2436e712009-09-17 21:32:03 +00002367void Sema::CodeCompleteMemberReferenceExpr(Scope *S, ExprTy *BaseE,
2368 SourceLocation OpLoc,
2369 bool IsArrow) {
2370 if (!BaseE || !CodeCompleter)
2371 return;
2372
Douglas Gregor3545ff42009-09-21 16:56:56 +00002373 typedef CodeCompleteConsumer::Result Result;
2374
Douglas Gregor2436e712009-09-17 21:32:03 +00002375 Expr *Base = static_cast<Expr *>(BaseE);
2376 QualType BaseType = Base->getType();
Douglas Gregor3545ff42009-09-21 16:56:56 +00002377
2378 if (IsArrow) {
2379 if (const PointerType *Ptr = BaseType->getAs<PointerType>())
2380 BaseType = Ptr->getPointeeType();
2381 else if (BaseType->isObjCObjectPointerType())
2382 /*Do nothing*/ ;
2383 else
2384 return;
2385 }
2386
Douglas Gregore412a5a2009-09-23 22:26:46 +00002387 ResultBuilder Results(*this, &ResultBuilder::IsMember);
Douglas Gregor9291bad2009-11-18 01:29:26 +00002388 Results.EnterNewScope();
2389 if (const RecordType *Record = BaseType->getAs<RecordType>()) {
2390 // Access to a C/C++ class, struct, or union.
Douglas Gregor6ae4c522010-01-14 03:21:49 +00002391 Results.allowNestedNameSpecifiers();
Douglas Gregor09bbc652010-01-14 15:47:35 +00002392 CodeCompletionDeclConsumer Consumer(Results, CurContext);
2393 LookupVisibleDecls(Record->getDecl(), LookupMemberName, Consumer);
Daniel Dunbar242ea9a2009-11-13 08:58:20 +00002394
Douglas Gregor9291bad2009-11-18 01:29:26 +00002395 if (getLangOptions().CPlusPlus) {
2396 if (!Results.empty()) {
2397 // The "template" keyword can follow "->" or "." in the grammar.
2398 // However, we only want to suggest the template keyword if something
2399 // is dependent.
2400 bool IsDependent = BaseType->isDependentType();
2401 if (!IsDependent) {
2402 for (Scope *DepScope = S; DepScope; DepScope = DepScope->getParent())
2403 if (DeclContext *Ctx = (DeclContext *)DepScope->getEntity()) {
2404 IsDependent = Ctx->isDependentContext();
2405 break;
2406 }
2407 }
Daniel Dunbar242ea9a2009-11-13 08:58:20 +00002408
Douglas Gregor9291bad2009-11-18 01:29:26 +00002409 if (IsDependent)
Douglas Gregor78a21012010-01-14 16:01:26 +00002410 Results.AddResult(Result("template"));
Daniel Dunbar242ea9a2009-11-13 08:58:20 +00002411 }
Daniel Dunbar242ea9a2009-11-13 08:58:20 +00002412 }
Douglas Gregor9291bad2009-11-18 01:29:26 +00002413 } else if (!IsArrow && BaseType->getAsObjCInterfacePointerType()) {
2414 // Objective-C property reference.
2415
2416 // Add property results based on our interface.
2417 const ObjCObjectPointerType *ObjCPtr
2418 = BaseType->getAsObjCInterfacePointerType();
2419 assert(ObjCPtr && "Non-NULL pointer guaranteed above!");
Douglas Gregor5d649882009-11-18 22:32:06 +00002420 AddObjCProperties(ObjCPtr->getInterfaceDecl(), true, CurContext, Results);
Douglas Gregor9291bad2009-11-18 01:29:26 +00002421
2422 // Add properties from the protocols in a qualified interface.
2423 for (ObjCObjectPointerType::qual_iterator I = ObjCPtr->qual_begin(),
2424 E = ObjCPtr->qual_end();
2425 I != E; ++I)
Douglas Gregor5d649882009-11-18 22:32:06 +00002426 AddObjCProperties(*I, true, CurContext, Results);
Douglas Gregor9291bad2009-11-18 01:29:26 +00002427 } else if ((IsArrow && BaseType->isObjCObjectPointerType()) ||
John McCall8b07ec22010-05-15 11:32:37 +00002428 (!IsArrow && BaseType->isObjCObjectType())) {
Douglas Gregor9291bad2009-11-18 01:29:26 +00002429 // Objective-C instance variable access.
2430 ObjCInterfaceDecl *Class = 0;
2431 if (const ObjCObjectPointerType *ObjCPtr
2432 = BaseType->getAs<ObjCObjectPointerType>())
2433 Class = ObjCPtr->getInterfaceDecl();
2434 else
John McCall8b07ec22010-05-15 11:32:37 +00002435 Class = BaseType->getAs<ObjCObjectType>()->getInterface();
Douglas Gregor9291bad2009-11-18 01:29:26 +00002436
2437 // Add all ivars from this class and its superclasses.
Douglas Gregor2b8162b2010-01-14 16:08:12 +00002438 if (Class) {
2439 CodeCompletionDeclConsumer Consumer(Results, CurContext);
2440 Results.setFilter(&ResultBuilder::IsObjCIvar);
2441 LookupVisibleDecls(Class, LookupMemberName, Consumer);
Douglas Gregor9291bad2009-11-18 01:29:26 +00002442 }
Douglas Gregor3545ff42009-09-21 16:56:56 +00002443 }
Douglas Gregor9291bad2009-11-18 01:29:26 +00002444
2445 // FIXME: How do we cope with isa?
2446
2447 Results.ExitScope();
Daniel Dunbar242ea9a2009-11-13 08:58:20 +00002448
Daniel Dunbar242ea9a2009-11-13 08:58:20 +00002449 // Hand off the results found for code completion.
2450 HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
Douglas Gregor2436e712009-09-17 21:32:03 +00002451}
2452
Douglas Gregorf45b0cf2009-09-18 15:37:17 +00002453void Sema::CodeCompleteTag(Scope *S, unsigned TagSpec) {
2454 if (!CodeCompleter)
2455 return;
2456
Douglas Gregor3545ff42009-09-21 16:56:56 +00002457 typedef CodeCompleteConsumer::Result Result;
2458 ResultBuilder::LookupFilter Filter = 0;
Douglas Gregorf45b0cf2009-09-18 15:37:17 +00002459 switch ((DeclSpec::TST)TagSpec) {
2460 case DeclSpec::TST_enum:
Douglas Gregor3545ff42009-09-21 16:56:56 +00002461 Filter = &ResultBuilder::IsEnum;
Douglas Gregorf45b0cf2009-09-18 15:37:17 +00002462 break;
2463
2464 case DeclSpec::TST_union:
Douglas Gregor3545ff42009-09-21 16:56:56 +00002465 Filter = &ResultBuilder::IsUnion;
Douglas Gregorf45b0cf2009-09-18 15:37:17 +00002466 break;
2467
2468 case DeclSpec::TST_struct:
Douglas Gregorf45b0cf2009-09-18 15:37:17 +00002469 case DeclSpec::TST_class:
Douglas Gregor3545ff42009-09-21 16:56:56 +00002470 Filter = &ResultBuilder::IsClassOrStruct;
Douglas Gregorf45b0cf2009-09-18 15:37:17 +00002471 break;
2472
2473 default:
2474 assert(false && "Unknown type specifier kind in CodeCompleteTag");
2475 return;
2476 }
Douglas Gregor3545ff42009-09-21 16:56:56 +00002477
John McCalle87beb22010-04-23 18:46:30 +00002478 ResultBuilder Results(*this);
Douglas Gregora6e2edc2010-01-14 03:27:13 +00002479 CodeCompletionDeclConsumer Consumer(Results, CurContext);
John McCalle87beb22010-04-23 18:46:30 +00002480
2481 // First pass: look for tags.
2482 Results.setFilter(Filter);
Douglas Gregora6e2edc2010-01-14 03:27:13 +00002483 LookupVisibleDecls(S, LookupTagName, Consumer);
John McCalle87beb22010-04-23 18:46:30 +00002484
2485 // Second pass: look for nested name specifiers.
2486 Results.setFilter(&ResultBuilder::IsNestedNameSpecifier);
2487 LookupVisibleDecls(S, LookupNestedNameSpecifierName, Consumer);
Douglas Gregor3545ff42009-09-21 16:56:56 +00002488
Daniel Dunbar242ea9a2009-11-13 08:58:20 +00002489 HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
Douglas Gregorf45b0cf2009-09-18 15:37:17 +00002490}
2491
Douglas Gregord328d572009-09-21 18:10:23 +00002492void Sema::CodeCompleteCase(Scope *S) {
2493 if (getSwitchStack().empty() || !CodeCompleter)
2494 return;
2495
2496 SwitchStmt *Switch = getSwitchStack().back();
Douglas Gregor85b50632010-07-28 21:50:18 +00002497 if (!Switch->getCond()->getType()->isEnumeralType()) {
2498 CodeCompleteExpression(S, Switch->getCond()->getType(), true);
Douglas Gregord328d572009-09-21 18:10:23 +00002499 return;
Douglas Gregor85b50632010-07-28 21:50:18 +00002500 }
Douglas Gregord328d572009-09-21 18:10:23 +00002501
2502 // Code-complete the cases of a switch statement over an enumeration type
2503 // by providing the list of
2504 EnumDecl *Enum = Switch->getCond()->getType()->getAs<EnumType>()->getDecl();
2505
2506 // Determine which enumerators we have already seen in the switch statement.
2507 // FIXME: Ideally, we would also be able to look *past* the code-completion
2508 // token, in case we are code-completing in the middle of the switch and not
2509 // at the end. However, we aren't able to do so at the moment.
2510 llvm::SmallPtrSet<EnumConstantDecl *, 8> EnumeratorsSeen;
Douglas Gregorf2510672009-09-21 19:57:38 +00002511 NestedNameSpecifier *Qualifier = 0;
Douglas Gregord328d572009-09-21 18:10:23 +00002512 for (SwitchCase *SC = Switch->getSwitchCaseList(); SC;
2513 SC = SC->getNextSwitchCase()) {
2514 CaseStmt *Case = dyn_cast<CaseStmt>(SC);
2515 if (!Case)
2516 continue;
2517
2518 Expr *CaseVal = Case->getLHS()->IgnoreParenCasts();
2519 if (DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(CaseVal))
2520 if (EnumConstantDecl *Enumerator
2521 = dyn_cast<EnumConstantDecl>(DRE->getDecl())) {
2522 // We look into the AST of the case statement to determine which
2523 // enumerator was named. Alternatively, we could compute the value of
2524 // the integral constant expression, then compare it against the
2525 // values of each enumerator. However, value-based approach would not
2526 // work as well with C++ templates where enumerators declared within a
2527 // template are type- and value-dependent.
2528 EnumeratorsSeen.insert(Enumerator);
2529
Douglas Gregorf2510672009-09-21 19:57:38 +00002530 // If this is a qualified-id, keep track of the nested-name-specifier
2531 // so that we can reproduce it as part of code completion, e.g.,
Douglas Gregord328d572009-09-21 18:10:23 +00002532 //
2533 // switch (TagD.getKind()) {
2534 // case TagDecl::TK_enum:
2535 // break;
2536 // case XXX
2537 //
Douglas Gregorf2510672009-09-21 19:57:38 +00002538 // At the XXX, our completions are TagDecl::TK_union,
Douglas Gregord328d572009-09-21 18:10:23 +00002539 // TagDecl::TK_struct, and TagDecl::TK_class, rather than TK_union,
2540 // TK_struct, and TK_class.
Douglas Gregor4bd90e52009-10-23 18:54:35 +00002541 Qualifier = DRE->getQualifier();
Douglas Gregord328d572009-09-21 18:10:23 +00002542 }
2543 }
2544
Douglas Gregorf2510672009-09-21 19:57:38 +00002545 if (getLangOptions().CPlusPlus && !Qualifier && EnumeratorsSeen.empty()) {
2546 // If there are no prior enumerators in C++, check whether we have to
2547 // qualify the names of the enumerators that we suggest, because they
2548 // may not be visible in this scope.
2549 Qualifier = getRequiredQualification(Context, CurContext,
2550 Enum->getDeclContext());
2551
2552 // FIXME: Scoped enums need to start with "EnumDecl" as the context!
2553 }
2554
Douglas Gregord328d572009-09-21 18:10:23 +00002555 // Add any enumerators that have not yet been mentioned.
2556 ResultBuilder Results(*this);
2557 Results.EnterNewScope();
2558 for (EnumDecl::enumerator_iterator E = Enum->enumerator_begin(),
2559 EEnd = Enum->enumerator_end();
2560 E != EEnd; ++E) {
2561 if (EnumeratorsSeen.count(*E))
2562 continue;
2563
Douglas Gregorfc59ce12010-01-14 16:14:35 +00002564 Results.AddResult(CodeCompleteConsumer::Result(*E, Qualifier),
2565 CurContext, 0, false);
Douglas Gregord328d572009-09-21 18:10:23 +00002566 }
2567 Results.ExitScope();
Douglas Gregor285560922010-04-06 20:02:15 +00002568
Douglas Gregor9eb77012009-11-07 00:00:49 +00002569 if (CodeCompleter->includeMacros())
Douglas Gregorf98e6a22010-01-13 23:51:12 +00002570 AddMacroResults(PP, Results);
Daniel Dunbar242ea9a2009-11-13 08:58:20 +00002571 HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
Douglas Gregord328d572009-09-21 18:10:23 +00002572}
2573
Douglas Gregorcabea402009-09-22 15:41:20 +00002574namespace {
2575 struct IsBetterOverloadCandidate {
2576 Sema &S;
John McCallbc077cf2010-02-08 23:07:23 +00002577 SourceLocation Loc;
Douglas Gregorcabea402009-09-22 15:41:20 +00002578
2579 public:
John McCallbc077cf2010-02-08 23:07:23 +00002580 explicit IsBetterOverloadCandidate(Sema &S, SourceLocation Loc)
2581 : S(S), Loc(Loc) { }
Douglas Gregorcabea402009-09-22 15:41:20 +00002582
2583 bool
2584 operator()(const OverloadCandidate &X, const OverloadCandidate &Y) const {
John McCallbc077cf2010-02-08 23:07:23 +00002585 return S.isBetterOverloadCandidate(X, Y, Loc);
Douglas Gregorcabea402009-09-22 15:41:20 +00002586 }
2587 };
2588}
2589
Douglas Gregor6ed3eb82010-05-30 06:10:08 +00002590static bool anyNullArguments(Expr **Args, unsigned NumArgs) {
2591 if (NumArgs && !Args)
2592 return true;
2593
2594 for (unsigned I = 0; I != NumArgs; ++I)
2595 if (!Args[I])
2596 return true;
2597
2598 return false;
2599}
2600
Douglas Gregorcabea402009-09-22 15:41:20 +00002601void Sema::CodeCompleteCall(Scope *S, ExprTy *FnIn,
2602 ExprTy **ArgsIn, unsigned NumArgs) {
2603 if (!CodeCompleter)
2604 return;
Douglas Gregor3ef59522009-12-11 19:06:04 +00002605
2606 // When we're code-completing for a call, we fall back to ordinary
2607 // name code-completion whenever we can't produce specific
2608 // results. We may want to revisit this strategy in the future,
2609 // e.g., by merging the two kinds of results.
2610
Douglas Gregorcabea402009-09-22 15:41:20 +00002611 Expr *Fn = (Expr *)FnIn;
2612 Expr **Args = (Expr **)ArgsIn;
Douglas Gregor3ef59522009-12-11 19:06:04 +00002613
Douglas Gregorcabea402009-09-22 15:41:20 +00002614 // Ignore type-dependent call expressions entirely.
Douglas Gregor6ed3eb82010-05-30 06:10:08 +00002615 if (!Fn || Fn->isTypeDependent() || anyNullArguments(Args, NumArgs) ||
Douglas Gregor3ef59522009-12-11 19:06:04 +00002616 Expr::hasAnyTypeDependentArguments(Args, NumArgs)) {
Douglas Gregor504a6ae2010-01-10 23:08:15 +00002617 CodeCompleteOrdinaryName(S, CCC_Expression);
Douglas Gregorcabea402009-09-22 15:41:20 +00002618 return;
Douglas Gregor3ef59522009-12-11 19:06:04 +00002619 }
Douglas Gregorcabea402009-09-22 15:41:20 +00002620
John McCall57500772009-12-16 12:17:52 +00002621 // Build an overload candidate set based on the functions we find.
John McCallbc077cf2010-02-08 23:07:23 +00002622 SourceLocation Loc = Fn->getExprLoc();
2623 OverloadCandidateSet CandidateSet(Loc);
John McCall57500772009-12-16 12:17:52 +00002624
Douglas Gregorcabea402009-09-22 15:41:20 +00002625 // FIXME: What if we're calling something that isn't a function declaration?
2626 // FIXME: What if we're calling a pseudo-destructor?
2627 // FIXME: What if we're calling a member function?
2628
Douglas Gregorff59f672010-01-21 15:46:19 +00002629 typedef CodeCompleteConsumer::OverloadCandidate ResultCandidate;
2630 llvm::SmallVector<ResultCandidate, 8> Results;
2631
John McCall57500772009-12-16 12:17:52 +00002632 Expr *NakedFn = Fn->IgnoreParenCasts();
2633 if (UnresolvedLookupExpr *ULE = dyn_cast<UnresolvedLookupExpr>(NakedFn))
2634 AddOverloadedCallCandidates(ULE, Args, NumArgs, CandidateSet,
2635 /*PartialOverloading=*/ true);
2636 else if (DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(NakedFn)) {
2637 FunctionDecl *FDecl = dyn_cast<FunctionDecl>(DRE->getDecl());
Douglas Gregorff59f672010-01-21 15:46:19 +00002638 if (FDecl) {
Douglas Gregor6ed3eb82010-05-30 06:10:08 +00002639 if (!getLangOptions().CPlusPlus ||
2640 !FDecl->getType()->getAs<FunctionProtoType>())
Douglas Gregorff59f672010-01-21 15:46:19 +00002641 Results.push_back(ResultCandidate(FDecl));
2642 else
John McCallb89836b2010-01-26 01:37:31 +00002643 // FIXME: access?
John McCalla0296f72010-03-19 07:35:19 +00002644 AddOverloadCandidate(FDecl, DeclAccessPair::make(FDecl, AS_none),
2645 Args, NumArgs, CandidateSet,
Douglas Gregorb05275a2010-04-16 17:41:49 +00002646 false, /*PartialOverloading*/true);
Douglas Gregorff59f672010-01-21 15:46:19 +00002647 }
John McCall57500772009-12-16 12:17:52 +00002648 }
Douglas Gregorcabea402009-09-22 15:41:20 +00002649
Douglas Gregor7aa6b222010-05-30 01:49:25 +00002650 QualType ParamType;
2651
Douglas Gregorff59f672010-01-21 15:46:19 +00002652 if (!CandidateSet.empty()) {
2653 // Sort the overload candidate set by placing the best overloads first.
2654 std::stable_sort(CandidateSet.begin(), CandidateSet.end(),
John McCallbc077cf2010-02-08 23:07:23 +00002655 IsBetterOverloadCandidate(*this, Loc));
Douglas Gregorcabea402009-09-22 15:41:20 +00002656
Douglas Gregorff59f672010-01-21 15:46:19 +00002657 // Add the remaining viable overload candidates as code-completion reslults.
2658 for (OverloadCandidateSet::iterator Cand = CandidateSet.begin(),
2659 CandEnd = CandidateSet.end();
2660 Cand != CandEnd; ++Cand) {
2661 if (Cand->Viable)
2662 Results.push_back(ResultCandidate(Cand->Function));
2663 }
Douglas Gregor7aa6b222010-05-30 01:49:25 +00002664
2665 // From the viable candidates, try to determine the type of this parameter.
2666 for (unsigned I = 0, N = Results.size(); I != N; ++I) {
2667 if (const FunctionType *FType = Results[I].getFunctionType())
2668 if (const FunctionProtoType *Proto = dyn_cast<FunctionProtoType>(FType))
2669 if (NumArgs < Proto->getNumArgs()) {
2670 if (ParamType.isNull())
2671 ParamType = Proto->getArgType(NumArgs);
2672 else if (!Context.hasSameUnqualifiedType(
2673 ParamType.getNonReferenceType(),
2674 Proto->getArgType(NumArgs).getNonReferenceType())) {
2675 ParamType = QualType();
2676 break;
2677 }
2678 }
2679 }
2680 } else {
2681 // Try to determine the parameter type from the type of the expression
2682 // being called.
2683 QualType FunctionType = Fn->getType();
2684 if (const PointerType *Ptr = FunctionType->getAs<PointerType>())
2685 FunctionType = Ptr->getPointeeType();
2686 else if (const BlockPointerType *BlockPtr
2687 = FunctionType->getAs<BlockPointerType>())
2688 FunctionType = BlockPtr->getPointeeType();
2689 else if (const MemberPointerType *MemPtr
2690 = FunctionType->getAs<MemberPointerType>())
2691 FunctionType = MemPtr->getPointeeType();
2692
2693 if (const FunctionProtoType *Proto
2694 = FunctionType->getAs<FunctionProtoType>()) {
2695 if (NumArgs < Proto->getNumArgs())
2696 ParamType = Proto->getArgType(NumArgs);
2697 }
Douglas Gregorcabea402009-09-22 15:41:20 +00002698 }
Douglas Gregor3ef59522009-12-11 19:06:04 +00002699
Douglas Gregor7aa6b222010-05-30 01:49:25 +00002700 if (ParamType.isNull())
2701 CodeCompleteOrdinaryName(S, CCC_Expression);
2702 else
2703 CodeCompleteExpression(S, ParamType);
2704
Douglas Gregorc01890e2010-04-06 20:19:47 +00002705 if (!Results.empty())
Douglas Gregor3ef59522009-12-11 19:06:04 +00002706 CodeCompleter->ProcessOverloadCandidates(*this, NumArgs, Results.data(),
2707 Results.size());
Douglas Gregorcabea402009-09-22 15:41:20 +00002708}
2709
Douglas Gregor7aa6b222010-05-30 01:49:25 +00002710void Sema::CodeCompleteInitializer(Scope *S, DeclPtrTy D) {
2711 ValueDecl *VD = dyn_cast_or_null<ValueDecl>(D.getAs<Decl>());
2712 if (!VD) {
2713 CodeCompleteOrdinaryName(S, CCC_Expression);
2714 return;
2715 }
2716
2717 CodeCompleteExpression(S, VD->getType());
2718}
2719
2720void Sema::CodeCompleteReturn(Scope *S) {
2721 QualType ResultType;
2722 if (isa<BlockDecl>(CurContext)) {
2723 if (BlockScopeInfo *BSI = getCurBlock())
2724 ResultType = BSI->ReturnType;
2725 } else if (FunctionDecl *Function = dyn_cast<FunctionDecl>(CurContext))
2726 ResultType = Function->getResultType();
2727 else if (ObjCMethodDecl *Method = dyn_cast<ObjCMethodDecl>(CurContext))
2728 ResultType = Method->getResultType();
2729
2730 if (ResultType.isNull())
2731 CodeCompleteOrdinaryName(S, CCC_Expression);
2732 else
2733 CodeCompleteExpression(S, ResultType);
2734}
2735
2736void Sema::CodeCompleteAssignmentRHS(Scope *S, ExprTy *LHS) {
2737 if (LHS)
2738 CodeCompleteExpression(S, static_cast<Expr *>(LHS)->getType());
2739 else
2740 CodeCompleteOrdinaryName(S, CCC_Expression);
2741}
2742
Jeffrey Yasskinc76498d2010-04-08 16:38:48 +00002743void Sema::CodeCompleteQualifiedId(Scope *S, CXXScopeSpec &SS,
Douglas Gregor2436e712009-09-17 21:32:03 +00002744 bool EnteringContext) {
2745 if (!SS.getScopeRep() || !CodeCompleter)
2746 return;
2747
Douglas Gregor3545ff42009-09-21 16:56:56 +00002748 DeclContext *Ctx = computeDeclContext(SS, EnteringContext);
2749 if (!Ctx)
2750 return;
Douglas Gregor800f2f02009-12-11 18:28:39 +00002751
2752 // Try to instantiate any non-dependent declaration contexts before
2753 // we look in them.
John McCall0b66eb32010-05-01 00:40:08 +00002754 if (!isDependentScopeSpecifier(SS) && RequireCompleteDeclContext(SS, Ctx))
Douglas Gregor800f2f02009-12-11 18:28:39 +00002755 return;
2756
Douglas Gregor3545ff42009-09-21 16:56:56 +00002757 ResultBuilder Results(*this);
Douglas Gregor200c99d2010-01-14 03:35:48 +00002758 CodeCompletionDeclConsumer Consumer(Results, CurContext);
2759 LookupVisibleDecls(Ctx, LookupOrdinaryName, Consumer);
Douglas Gregor3545ff42009-09-21 16:56:56 +00002760
2761 // The "template" keyword can follow "::" in the grammar, but only
2762 // put it into the grammar if the nested-name-specifier is dependent.
2763 NestedNameSpecifier *NNS = (NestedNameSpecifier *)SS.getScopeRep();
2764 if (!Results.empty() && NNS->isDependent())
Douglas Gregor78a21012010-01-14 16:01:26 +00002765 Results.AddResult("template");
Douglas Gregor3545ff42009-09-21 16:56:56 +00002766
Daniel Dunbar242ea9a2009-11-13 08:58:20 +00002767 HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
Douglas Gregor2436e712009-09-17 21:32:03 +00002768}
Douglas Gregor7e90c6d2009-09-18 19:03:04 +00002769
2770void Sema::CodeCompleteUsing(Scope *S) {
2771 if (!CodeCompleter)
2772 return;
2773
Douglas Gregor3545ff42009-09-21 16:56:56 +00002774 ResultBuilder Results(*this, &ResultBuilder::IsNestedNameSpecifier);
Douglas Gregor64b12b52009-09-22 23:31:26 +00002775 Results.EnterNewScope();
Douglas Gregor3545ff42009-09-21 16:56:56 +00002776
2777 // If we aren't in class scope, we could see the "namespace" keyword.
2778 if (!S->isClassScope())
Douglas Gregor78a21012010-01-14 16:01:26 +00002779 Results.AddResult(CodeCompleteConsumer::Result("namespace"));
Douglas Gregor3545ff42009-09-21 16:56:56 +00002780
2781 // After "using", we can see anything that would start a
2782 // nested-name-specifier.
Douglas Gregora6e2edc2010-01-14 03:27:13 +00002783 CodeCompletionDeclConsumer Consumer(Results, CurContext);
2784 LookupVisibleDecls(S, LookupOrdinaryName, Consumer);
Douglas Gregor64b12b52009-09-22 23:31:26 +00002785 Results.ExitScope();
Douglas Gregor3545ff42009-09-21 16:56:56 +00002786
Daniel Dunbar242ea9a2009-11-13 08:58:20 +00002787 HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
Douglas Gregor7e90c6d2009-09-18 19:03:04 +00002788}
2789
2790void Sema::CodeCompleteUsingDirective(Scope *S) {
2791 if (!CodeCompleter)
2792 return;
2793
Douglas Gregor3545ff42009-09-21 16:56:56 +00002794 // After "using namespace", we expect to see a namespace name or namespace
2795 // alias.
2796 ResultBuilder Results(*this, &ResultBuilder::IsNamespaceOrAlias);
Douglas Gregor64b12b52009-09-22 23:31:26 +00002797 Results.EnterNewScope();
Douglas Gregora6e2edc2010-01-14 03:27:13 +00002798 CodeCompletionDeclConsumer Consumer(Results, CurContext);
2799 LookupVisibleDecls(S, LookupOrdinaryName, Consumer);
Douglas Gregor64b12b52009-09-22 23:31:26 +00002800 Results.ExitScope();
Daniel Dunbar242ea9a2009-11-13 08:58:20 +00002801 HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
Douglas Gregor7e90c6d2009-09-18 19:03:04 +00002802}
2803
2804void Sema::CodeCompleteNamespaceDecl(Scope *S) {
2805 if (!CodeCompleter)
2806 return;
2807
Douglas Gregor3545ff42009-09-21 16:56:56 +00002808 ResultBuilder Results(*this, &ResultBuilder::IsNamespace);
2809 DeclContext *Ctx = (DeclContext *)S->getEntity();
2810 if (!S->getParent())
2811 Ctx = Context.getTranslationUnitDecl();
2812
2813 if (Ctx && Ctx->isFileContext()) {
2814 // We only want to see those namespaces that have already been defined
2815 // within this scope, because its likely that the user is creating an
2816 // extended namespace declaration. Keep track of the most recent
2817 // definition of each namespace.
2818 std::map<NamespaceDecl *, NamespaceDecl *> OrigToLatest;
2819 for (DeclContext::specific_decl_iterator<NamespaceDecl>
2820 NS(Ctx->decls_begin()), NSEnd(Ctx->decls_end());
2821 NS != NSEnd; ++NS)
2822 OrigToLatest[NS->getOriginalNamespace()] = *NS;
2823
2824 // Add the most recent definition (or extended definition) of each
2825 // namespace to the list of results.
Douglas Gregor64b12b52009-09-22 23:31:26 +00002826 Results.EnterNewScope();
Douglas Gregor3545ff42009-09-21 16:56:56 +00002827 for (std::map<NamespaceDecl *, NamespaceDecl *>::iterator
2828 NS = OrigToLatest.begin(), NSEnd = OrigToLatest.end();
2829 NS != NSEnd; ++NS)
Douglas Gregorfc59ce12010-01-14 16:14:35 +00002830 Results.AddResult(CodeCompleteConsumer::Result(NS->second, 0),
2831 CurContext, 0, false);
Douglas Gregor64b12b52009-09-22 23:31:26 +00002832 Results.ExitScope();
Douglas Gregor3545ff42009-09-21 16:56:56 +00002833 }
2834
Daniel Dunbar242ea9a2009-11-13 08:58:20 +00002835 HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
Douglas Gregor7e90c6d2009-09-18 19:03:04 +00002836}
2837
2838void Sema::CodeCompleteNamespaceAliasDecl(Scope *S) {
2839 if (!CodeCompleter)
2840 return;
2841
Douglas Gregor3545ff42009-09-21 16:56:56 +00002842 // After "namespace", we expect to see a namespace or alias.
2843 ResultBuilder Results(*this, &ResultBuilder::IsNamespaceOrAlias);
Douglas Gregora6e2edc2010-01-14 03:27:13 +00002844 CodeCompletionDeclConsumer Consumer(Results, CurContext);
2845 LookupVisibleDecls(S, LookupOrdinaryName, Consumer);
Daniel Dunbar242ea9a2009-11-13 08:58:20 +00002846 HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
Douglas Gregor7e90c6d2009-09-18 19:03:04 +00002847}
2848
Douglas Gregorc811ede2009-09-18 20:05:18 +00002849void Sema::CodeCompleteOperatorName(Scope *S) {
2850 if (!CodeCompleter)
2851 return;
Douglas Gregor3545ff42009-09-21 16:56:56 +00002852
2853 typedef CodeCompleteConsumer::Result Result;
2854 ResultBuilder Results(*this, &ResultBuilder::IsType);
Douglas Gregor64b12b52009-09-22 23:31:26 +00002855 Results.EnterNewScope();
Douglas Gregorc811ede2009-09-18 20:05:18 +00002856
Douglas Gregor3545ff42009-09-21 16:56:56 +00002857 // Add the names of overloadable operators.
2858#define OVERLOADED_OPERATOR(Name,Spelling,Token,Unary,Binary,MemberOnly) \
2859 if (std::strcmp(Spelling, "?")) \
Douglas Gregor78a21012010-01-14 16:01:26 +00002860 Results.AddResult(Result(Spelling));
Douglas Gregor3545ff42009-09-21 16:56:56 +00002861#include "clang/Basic/OperatorKinds.def"
2862
2863 // Add any type names visible from the current scope
Douglas Gregor6ae4c522010-01-14 03:21:49 +00002864 Results.allowNestedNameSpecifiers();
Douglas Gregora6e2edc2010-01-14 03:27:13 +00002865 CodeCompletionDeclConsumer Consumer(Results, CurContext);
2866 LookupVisibleDecls(S, LookupOrdinaryName, Consumer);
Douglas Gregor3545ff42009-09-21 16:56:56 +00002867
2868 // Add any type specifiers
Douglas Gregorf98e6a22010-01-13 23:51:12 +00002869 AddTypeSpecifierResults(getLangOptions(), Results);
Douglas Gregor64b12b52009-09-22 23:31:26 +00002870 Results.ExitScope();
Douglas Gregor3545ff42009-09-21 16:56:56 +00002871
Daniel Dunbar242ea9a2009-11-13 08:58:20 +00002872 HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
Douglas Gregorc811ede2009-09-18 20:05:18 +00002873}
Douglas Gregor7e90c6d2009-09-18 19:03:04 +00002874
Douglas Gregorf1934162010-01-13 21:24:21 +00002875// Macro that expands to @Keyword or Keyword, depending on whether NeedAt is
2876// true or false.
2877#define OBJC_AT_KEYWORD_NAME(NeedAt,Keyword) NeedAt? "@" #Keyword : #Keyword
Douglas Gregorf98e6a22010-01-13 23:51:12 +00002878static void AddObjCImplementationResults(const LangOptions &LangOpts,
Douglas Gregorf1934162010-01-13 21:24:21 +00002879 ResultBuilder &Results,
2880 bool NeedAt) {
2881 typedef CodeCompleteConsumer::Result Result;
2882 // Since we have an implementation, we can end it.
Douglas Gregor78a21012010-01-14 16:01:26 +00002883 Results.AddResult(Result(OBJC_AT_KEYWORD_NAME(NeedAt,end)));
Douglas Gregorf1934162010-01-13 21:24:21 +00002884
2885 CodeCompletionString *Pattern = 0;
2886 if (LangOpts.ObjC2) {
2887 // @dynamic
2888 Pattern = new CodeCompletionString;
2889 Pattern->AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt,dynamic));
2890 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
2891 Pattern->AddPlaceholderChunk("property");
Douglas Gregor78a21012010-01-14 16:01:26 +00002892 Results.AddResult(Result(Pattern));
Douglas Gregorf1934162010-01-13 21:24:21 +00002893
2894 // @synthesize
2895 Pattern = new CodeCompletionString;
2896 Pattern->AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt,synthesize));
2897 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
2898 Pattern->AddPlaceholderChunk("property");
Douglas Gregor78a21012010-01-14 16:01:26 +00002899 Results.AddResult(Result(Pattern));
Douglas Gregorf1934162010-01-13 21:24:21 +00002900 }
2901}
2902
Douglas Gregorf98e6a22010-01-13 23:51:12 +00002903static void AddObjCInterfaceResults(const LangOptions &LangOpts,
Douglas Gregorf1934162010-01-13 21:24:21 +00002904 ResultBuilder &Results,
2905 bool NeedAt) {
2906 typedef CodeCompleteConsumer::Result Result;
2907
2908 // Since we have an interface or protocol, we can end it.
Douglas Gregor78a21012010-01-14 16:01:26 +00002909 Results.AddResult(Result(OBJC_AT_KEYWORD_NAME(NeedAt,end)));
Douglas Gregorf1934162010-01-13 21:24:21 +00002910
2911 if (LangOpts.ObjC2) {
2912 // @property
Douglas Gregor78a21012010-01-14 16:01:26 +00002913 Results.AddResult(Result(OBJC_AT_KEYWORD_NAME(NeedAt,property)));
Douglas Gregorf1934162010-01-13 21:24:21 +00002914
2915 // @required
Douglas Gregor78a21012010-01-14 16:01:26 +00002916 Results.AddResult(Result(OBJC_AT_KEYWORD_NAME(NeedAt,required)));
Douglas Gregorf1934162010-01-13 21:24:21 +00002917
2918 // @optional
Douglas Gregor78a21012010-01-14 16:01:26 +00002919 Results.AddResult(Result(OBJC_AT_KEYWORD_NAME(NeedAt,optional)));
Douglas Gregorf1934162010-01-13 21:24:21 +00002920 }
2921}
2922
Douglas Gregorf98e6a22010-01-13 23:51:12 +00002923static void AddObjCTopLevelResults(ResultBuilder &Results, bool NeedAt) {
Douglas Gregorf1934162010-01-13 21:24:21 +00002924 typedef CodeCompleteConsumer::Result Result;
2925 CodeCompletionString *Pattern = 0;
2926
2927 // @class name ;
2928 Pattern = new CodeCompletionString;
2929 Pattern->AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt,class));
2930 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
Douglas Gregorf4c33342010-05-28 00:22:41 +00002931 Pattern->AddPlaceholderChunk("name");
Douglas Gregor78a21012010-01-14 16:01:26 +00002932 Results.AddResult(Result(Pattern));
Douglas Gregorf1934162010-01-13 21:24:21 +00002933
Douglas Gregorf4c33342010-05-28 00:22:41 +00002934 if (Results.includeCodePatterns()) {
2935 // @interface name
2936 // FIXME: Could introduce the whole pattern, including superclasses and
2937 // such.
2938 Pattern = new CodeCompletionString;
2939 Pattern->AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt,interface));
2940 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
2941 Pattern->AddPlaceholderChunk("class");
2942 Results.AddResult(Result(Pattern));
Douglas Gregorf1934162010-01-13 21:24:21 +00002943
Douglas Gregorf4c33342010-05-28 00:22:41 +00002944 // @protocol name
2945 Pattern = new CodeCompletionString;
2946 Pattern->AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt,protocol));
2947 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
2948 Pattern->AddPlaceholderChunk("protocol");
2949 Results.AddResult(Result(Pattern));
2950
2951 // @implementation name
2952 Pattern = new CodeCompletionString;
2953 Pattern->AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt,implementation));
2954 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
2955 Pattern->AddPlaceholderChunk("class");
2956 Results.AddResult(Result(Pattern));
2957 }
Douglas Gregorf1934162010-01-13 21:24:21 +00002958
2959 // @compatibility_alias name
2960 Pattern = new CodeCompletionString;
2961 Pattern->AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt,compatibility_alias));
2962 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
2963 Pattern->AddPlaceholderChunk("alias");
2964 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
2965 Pattern->AddPlaceholderChunk("class");
Douglas Gregor78a21012010-01-14 16:01:26 +00002966 Results.AddResult(Result(Pattern));
Douglas Gregorf1934162010-01-13 21:24:21 +00002967}
2968
Douglas Gregorf48706c2009-12-07 09:27:33 +00002969void Sema::CodeCompleteObjCAtDirective(Scope *S, DeclPtrTy ObjCImpDecl,
2970 bool InInterface) {
2971 typedef CodeCompleteConsumer::Result Result;
2972 ResultBuilder Results(*this);
2973 Results.EnterNewScope();
Douglas Gregorf1934162010-01-13 21:24:21 +00002974 if (ObjCImpDecl)
Douglas Gregorf98e6a22010-01-13 23:51:12 +00002975 AddObjCImplementationResults(getLangOptions(), Results, false);
Douglas Gregorf1934162010-01-13 21:24:21 +00002976 else if (InInterface)
Douglas Gregorf98e6a22010-01-13 23:51:12 +00002977 AddObjCInterfaceResults(getLangOptions(), Results, false);
Douglas Gregorf1934162010-01-13 21:24:21 +00002978 else
Douglas Gregorf98e6a22010-01-13 23:51:12 +00002979 AddObjCTopLevelResults(Results, false);
Douglas Gregorf48706c2009-12-07 09:27:33 +00002980 Results.ExitScope();
2981 HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
2982}
2983
Douglas Gregorf98e6a22010-01-13 23:51:12 +00002984static void AddObjCExpressionResults(ResultBuilder &Results, bool NeedAt) {
Douglas Gregorbc7c5e42009-12-07 09:51:25 +00002985 typedef CodeCompleteConsumer::Result Result;
2986 CodeCompletionString *Pattern = 0;
2987
2988 // @encode ( type-name )
2989 Pattern = new CodeCompletionString;
Douglas Gregorf1934162010-01-13 21:24:21 +00002990 Pattern->AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt,encode));
Douglas Gregorbc7c5e42009-12-07 09:51:25 +00002991 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
2992 Pattern->AddPlaceholderChunk("type-name");
2993 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
Douglas Gregor78a21012010-01-14 16:01:26 +00002994 Results.AddResult(Result(Pattern));
Douglas Gregorbc7c5e42009-12-07 09:51:25 +00002995
2996 // @protocol ( protocol-name )
2997 Pattern = new CodeCompletionString;
Douglas Gregorf1934162010-01-13 21:24:21 +00002998 Pattern->AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt,protocol));
Douglas Gregorbc7c5e42009-12-07 09:51:25 +00002999 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
3000 Pattern->AddPlaceholderChunk("protocol-name");
3001 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
Douglas Gregor78a21012010-01-14 16:01:26 +00003002 Results.AddResult(Result(Pattern));
Douglas Gregorbc7c5e42009-12-07 09:51:25 +00003003
3004 // @selector ( selector )
3005 Pattern = new CodeCompletionString;
Douglas Gregorf1934162010-01-13 21:24:21 +00003006 Pattern->AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt,selector));
Douglas Gregorbc7c5e42009-12-07 09:51:25 +00003007 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
3008 Pattern->AddPlaceholderChunk("selector");
3009 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
Douglas Gregor78a21012010-01-14 16:01:26 +00003010 Results.AddResult(Result(Pattern));
Douglas Gregorbc7c5e42009-12-07 09:51:25 +00003011}
3012
Douglas Gregorf98e6a22010-01-13 23:51:12 +00003013static void AddObjCStatementResults(ResultBuilder &Results, bool NeedAt) {
Douglas Gregorbc7c5e42009-12-07 09:51:25 +00003014 typedef CodeCompleteConsumer::Result Result;
Douglas Gregorbc7c5e42009-12-07 09:51:25 +00003015 CodeCompletionString *Pattern = 0;
Douglas Gregorf1934162010-01-13 21:24:21 +00003016
Douglas Gregorf4c33342010-05-28 00:22:41 +00003017 if (Results.includeCodePatterns()) {
3018 // @try { statements } @catch ( declaration ) { statements } @finally
3019 // { statements }
3020 Pattern = new CodeCompletionString;
3021 Pattern->AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt,try));
3022 Pattern->AddChunk(CodeCompletionString::CK_LeftBrace);
3023 Pattern->AddPlaceholderChunk("statements");
3024 Pattern->AddChunk(CodeCompletionString::CK_RightBrace);
3025 Pattern->AddTextChunk("@catch");
3026 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
3027 Pattern->AddPlaceholderChunk("parameter");
3028 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
3029 Pattern->AddChunk(CodeCompletionString::CK_LeftBrace);
3030 Pattern->AddPlaceholderChunk("statements");
3031 Pattern->AddChunk(CodeCompletionString::CK_RightBrace);
3032 Pattern->AddTextChunk("@finally");
3033 Pattern->AddChunk(CodeCompletionString::CK_LeftBrace);
3034 Pattern->AddPlaceholderChunk("statements");
3035 Pattern->AddChunk(CodeCompletionString::CK_RightBrace);
3036 Results.AddResult(Result(Pattern));
3037 }
Douglas Gregorf1934162010-01-13 21:24:21 +00003038
Douglas Gregorbc7c5e42009-12-07 09:51:25 +00003039 // @throw
3040 Pattern = new CodeCompletionString;
Douglas Gregorf1934162010-01-13 21:24:21 +00003041 Pattern->AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt,throw));
Douglas Gregor6a803932010-01-12 06:38:28 +00003042 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
Douglas Gregorbc7c5e42009-12-07 09:51:25 +00003043 Pattern->AddPlaceholderChunk("expression");
Douglas Gregor78a21012010-01-14 16:01:26 +00003044 Results.AddResult(Result(Pattern));
Douglas Gregorf1934162010-01-13 21:24:21 +00003045
Douglas Gregorf4c33342010-05-28 00:22:41 +00003046 if (Results.includeCodePatterns()) {
3047 // @synchronized ( expression ) { statements }
3048 Pattern = new CodeCompletionString;
3049 Pattern->AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt,synchronized));
3050 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
3051 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
3052 Pattern->AddPlaceholderChunk("expression");
3053 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
3054 Pattern->AddChunk(CodeCompletionString::CK_LeftBrace);
3055 Pattern->AddPlaceholderChunk("statements");
3056 Pattern->AddChunk(CodeCompletionString::CK_RightBrace);
3057 Results.AddResult(Result(Pattern));
3058 }
Douglas Gregorf1934162010-01-13 21:24:21 +00003059}
Douglas Gregorbc7c5e42009-12-07 09:51:25 +00003060
Douglas Gregorf98e6a22010-01-13 23:51:12 +00003061static void AddObjCVisibilityResults(const LangOptions &LangOpts,
Douglas Gregor48d46252010-01-13 21:54:15 +00003062 ResultBuilder &Results,
3063 bool NeedAt) {
Douglas Gregorf1934162010-01-13 21:24:21 +00003064 typedef CodeCompleteConsumer::Result Result;
Douglas Gregor78a21012010-01-14 16:01:26 +00003065 Results.AddResult(Result(OBJC_AT_KEYWORD_NAME(NeedAt,private)));
3066 Results.AddResult(Result(OBJC_AT_KEYWORD_NAME(NeedAt,protected)));
3067 Results.AddResult(Result(OBJC_AT_KEYWORD_NAME(NeedAt,public)));
Douglas Gregor48d46252010-01-13 21:54:15 +00003068 if (LangOpts.ObjC2)
Douglas Gregor78a21012010-01-14 16:01:26 +00003069 Results.AddResult(Result(OBJC_AT_KEYWORD_NAME(NeedAt,package)));
Douglas Gregor48d46252010-01-13 21:54:15 +00003070}
3071
3072void Sema::CodeCompleteObjCAtVisibility(Scope *S) {
3073 ResultBuilder Results(*this);
3074 Results.EnterNewScope();
Douglas Gregorf98e6a22010-01-13 23:51:12 +00003075 AddObjCVisibilityResults(getLangOptions(), Results, false);
Douglas Gregor48d46252010-01-13 21:54:15 +00003076 Results.ExitScope();
3077 HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
3078}
3079
3080void Sema::CodeCompleteObjCAtStatement(Scope *S) {
Douglas Gregorf1934162010-01-13 21:24:21 +00003081 ResultBuilder Results(*this);
3082 Results.EnterNewScope();
Douglas Gregorf98e6a22010-01-13 23:51:12 +00003083 AddObjCStatementResults(Results, false);
3084 AddObjCExpressionResults(Results, false);
Douglas Gregorbc7c5e42009-12-07 09:51:25 +00003085 Results.ExitScope();
3086 HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
3087}
3088
3089void Sema::CodeCompleteObjCAtExpression(Scope *S) {
3090 ResultBuilder Results(*this);
3091 Results.EnterNewScope();
Douglas Gregorf98e6a22010-01-13 23:51:12 +00003092 AddObjCExpressionResults(Results, false);
Douglas Gregorbc7c5e42009-12-07 09:51:25 +00003093 Results.ExitScope();
3094 HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
3095}
3096
Douglas Gregore6078da2009-11-19 00:14:45 +00003097/// \brief Determine whether the addition of the given flag to an Objective-C
3098/// property's attributes will cause a conflict.
3099static bool ObjCPropertyFlagConflicts(unsigned Attributes, unsigned NewFlag) {
3100 // Check if we've already added this flag.
3101 if (Attributes & NewFlag)
3102 return true;
3103
3104 Attributes |= NewFlag;
3105
3106 // Check for collisions with "readonly".
3107 if ((Attributes & ObjCDeclSpec::DQ_PR_readonly) &&
3108 (Attributes & (ObjCDeclSpec::DQ_PR_readwrite |
3109 ObjCDeclSpec::DQ_PR_assign |
3110 ObjCDeclSpec::DQ_PR_copy |
3111 ObjCDeclSpec::DQ_PR_retain)))
3112 return true;
3113
3114 // Check for more than one of { assign, copy, retain }.
3115 unsigned AssignCopyRetMask = Attributes & (ObjCDeclSpec::DQ_PR_assign |
3116 ObjCDeclSpec::DQ_PR_copy |
3117 ObjCDeclSpec::DQ_PR_retain);
3118 if (AssignCopyRetMask &&
3119 AssignCopyRetMask != ObjCDeclSpec::DQ_PR_assign &&
3120 AssignCopyRetMask != ObjCDeclSpec::DQ_PR_copy &&
3121 AssignCopyRetMask != ObjCDeclSpec::DQ_PR_retain)
3122 return true;
3123
3124 return false;
3125}
3126
Douglas Gregor36029f42009-11-18 23:08:07 +00003127void Sema::CodeCompleteObjCPropertyFlags(Scope *S, ObjCDeclSpec &ODS) {
Steve Naroff936354c2009-10-08 21:55:05 +00003128 if (!CodeCompleter)
3129 return;
Douglas Gregor1b605f72009-11-19 01:08:35 +00003130
Steve Naroff936354c2009-10-08 21:55:05 +00003131 unsigned Attributes = ODS.getPropertyAttributes();
3132
3133 typedef CodeCompleteConsumer::Result Result;
3134 ResultBuilder Results(*this);
3135 Results.EnterNewScope();
Douglas Gregore6078da2009-11-19 00:14:45 +00003136 if (!ObjCPropertyFlagConflicts(Attributes, ObjCDeclSpec::DQ_PR_readonly))
Douglas Gregor78a21012010-01-14 16:01:26 +00003137 Results.AddResult(CodeCompleteConsumer::Result("readonly"));
Douglas Gregore6078da2009-11-19 00:14:45 +00003138 if (!ObjCPropertyFlagConflicts(Attributes, ObjCDeclSpec::DQ_PR_assign))
Douglas Gregor78a21012010-01-14 16:01:26 +00003139 Results.AddResult(CodeCompleteConsumer::Result("assign"));
Douglas Gregore6078da2009-11-19 00:14:45 +00003140 if (!ObjCPropertyFlagConflicts(Attributes, ObjCDeclSpec::DQ_PR_readwrite))
Douglas Gregor78a21012010-01-14 16:01:26 +00003141 Results.AddResult(CodeCompleteConsumer::Result("readwrite"));
Douglas Gregore6078da2009-11-19 00:14:45 +00003142 if (!ObjCPropertyFlagConflicts(Attributes, ObjCDeclSpec::DQ_PR_retain))
Douglas Gregor78a21012010-01-14 16:01:26 +00003143 Results.AddResult(CodeCompleteConsumer::Result("retain"));
Douglas Gregore6078da2009-11-19 00:14:45 +00003144 if (!ObjCPropertyFlagConflicts(Attributes, ObjCDeclSpec::DQ_PR_copy))
Douglas Gregor78a21012010-01-14 16:01:26 +00003145 Results.AddResult(CodeCompleteConsumer::Result("copy"));
Douglas Gregore6078da2009-11-19 00:14:45 +00003146 if (!ObjCPropertyFlagConflicts(Attributes, ObjCDeclSpec::DQ_PR_nonatomic))
Douglas Gregor78a21012010-01-14 16:01:26 +00003147 Results.AddResult(CodeCompleteConsumer::Result("nonatomic"));
Douglas Gregore6078da2009-11-19 00:14:45 +00003148 if (!ObjCPropertyFlagConflicts(Attributes, ObjCDeclSpec::DQ_PR_setter)) {
Douglas Gregor45f83ee2009-11-19 00:01:57 +00003149 CodeCompletionString *Setter = new CodeCompletionString;
3150 Setter->AddTypedTextChunk("setter");
3151 Setter->AddTextChunk(" = ");
3152 Setter->AddPlaceholderChunk("method");
Douglas Gregor78a21012010-01-14 16:01:26 +00003153 Results.AddResult(CodeCompleteConsumer::Result(Setter));
Douglas Gregor45f83ee2009-11-19 00:01:57 +00003154 }
Douglas Gregore6078da2009-11-19 00:14:45 +00003155 if (!ObjCPropertyFlagConflicts(Attributes, ObjCDeclSpec::DQ_PR_getter)) {
Douglas Gregor45f83ee2009-11-19 00:01:57 +00003156 CodeCompletionString *Getter = new CodeCompletionString;
3157 Getter->AddTypedTextChunk("getter");
3158 Getter->AddTextChunk(" = ");
3159 Getter->AddPlaceholderChunk("method");
Douglas Gregor78a21012010-01-14 16:01:26 +00003160 Results.AddResult(CodeCompleteConsumer::Result(Getter));
Douglas Gregor45f83ee2009-11-19 00:01:57 +00003161 }
Steve Naroff936354c2009-10-08 21:55:05 +00003162 Results.ExitScope();
Daniel Dunbar242ea9a2009-11-13 08:58:20 +00003163 HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
Steve Naroff936354c2009-10-08 21:55:05 +00003164}
Steve Naroffeae65032009-11-07 02:08:14 +00003165
Douglas Gregorc8537c52009-11-19 07:41:15 +00003166/// \brief Descripts the kind of Objective-C method that we want to find
3167/// via code completion.
3168enum ObjCMethodKind {
3169 MK_Any, //< Any kind of method, provided it means other specified criteria.
3170 MK_ZeroArgSelector, //< Zero-argument (unary) selector.
3171 MK_OneArgSelector //< One-argument selector.
3172};
3173
3174static bool isAcceptableObjCMethod(ObjCMethodDecl *Method,
3175 ObjCMethodKind WantKind,
3176 IdentifierInfo **SelIdents,
3177 unsigned NumSelIdents) {
3178 Selector Sel = Method->getSelector();
3179 if (NumSelIdents > Sel.getNumArgs())
3180 return false;
3181
3182 switch (WantKind) {
3183 case MK_Any: break;
3184 case MK_ZeroArgSelector: return Sel.isUnarySelector();
3185 case MK_OneArgSelector: return Sel.getNumArgs() == 1;
3186 }
3187
3188 for (unsigned I = 0; I != NumSelIdents; ++I)
3189 if (SelIdents[I] != Sel.getIdentifierInfoForSlot(I))
3190 return false;
3191
3192 return true;
3193}
3194
Douglas Gregorbab2b3c2009-11-17 23:22:23 +00003195/// \brief Add all of the Objective-C methods in the given Objective-C
3196/// container to the set of results.
3197///
3198/// The container will be a class, protocol, category, or implementation of
3199/// any of the above. This mether will recurse to include methods from
3200/// the superclasses of classes along with their categories, protocols, and
3201/// implementations.
3202///
3203/// \param Container the container in which we'll look to find methods.
3204///
3205/// \param WantInstance whether to add instance methods (only); if false, this
3206/// routine will add factory methods (only).
3207///
3208/// \param CurContext the context in which we're performing the lookup that
3209/// finds methods.
3210///
3211/// \param Results the structure into which we'll add results.
3212static void AddObjCMethods(ObjCContainerDecl *Container,
3213 bool WantInstanceMethods,
Douglas Gregorc8537c52009-11-19 07:41:15 +00003214 ObjCMethodKind WantKind,
Douglas Gregor1b605f72009-11-19 01:08:35 +00003215 IdentifierInfo **SelIdents,
3216 unsigned NumSelIdents,
Douglas Gregorbab2b3c2009-11-17 23:22:23 +00003217 DeclContext *CurContext,
3218 ResultBuilder &Results) {
3219 typedef CodeCompleteConsumer::Result Result;
3220 for (ObjCContainerDecl::method_iterator M = Container->meth_begin(),
3221 MEnd = Container->meth_end();
3222 M != MEnd; ++M) {
Douglas Gregor1b605f72009-11-19 01:08:35 +00003223 if ((*M)->isInstanceMethod() == WantInstanceMethods) {
3224 // Check whether the selector identifiers we've been given are a
3225 // subset of the identifiers for this particular method.
Douglas Gregorc8537c52009-11-19 07:41:15 +00003226 if (!isAcceptableObjCMethod(*M, WantKind, SelIdents, NumSelIdents))
Douglas Gregor1b605f72009-11-19 01:08:35 +00003227 continue;
Douglas Gregorc8537c52009-11-19 07:41:15 +00003228
Douglas Gregor1b605f72009-11-19 01:08:35 +00003229 Result R = Result(*M, 0);
3230 R.StartParameter = NumSelIdents;
Douglas Gregorc8537c52009-11-19 07:41:15 +00003231 R.AllParametersAreInformative = (WantKind != MK_Any);
Douglas Gregor1b605f72009-11-19 01:08:35 +00003232 Results.MaybeAddResult(R, CurContext);
3233 }
Douglas Gregorbab2b3c2009-11-17 23:22:23 +00003234 }
3235
3236 ObjCInterfaceDecl *IFace = dyn_cast<ObjCInterfaceDecl>(Container);
3237 if (!IFace)
3238 return;
3239
3240 // Add methods in protocols.
3241 const ObjCList<ObjCProtocolDecl> &Protocols= IFace->getReferencedProtocols();
3242 for (ObjCList<ObjCProtocolDecl>::iterator I = Protocols.begin(),
3243 E = Protocols.end();
3244 I != E; ++I)
Douglas Gregorc8537c52009-11-19 07:41:15 +00003245 AddObjCMethods(*I, WantInstanceMethods, WantKind, SelIdents, NumSelIdents,
Douglas Gregor1b605f72009-11-19 01:08:35 +00003246 CurContext, Results);
Douglas Gregorbab2b3c2009-11-17 23:22:23 +00003247
3248 // Add methods in categories.
3249 for (ObjCCategoryDecl *CatDecl = IFace->getCategoryList(); CatDecl;
3250 CatDecl = CatDecl->getNextClassCategory()) {
Douglas Gregorc8537c52009-11-19 07:41:15 +00003251 AddObjCMethods(CatDecl, WantInstanceMethods, WantKind, SelIdents,
3252 NumSelIdents, CurContext, Results);
Douglas Gregorbab2b3c2009-11-17 23:22:23 +00003253
3254 // Add a categories protocol methods.
3255 const ObjCList<ObjCProtocolDecl> &Protocols
3256 = CatDecl->getReferencedProtocols();
3257 for (ObjCList<ObjCProtocolDecl>::iterator I = Protocols.begin(),
3258 E = Protocols.end();
3259 I != E; ++I)
Douglas Gregorc8537c52009-11-19 07:41:15 +00003260 AddObjCMethods(*I, WantInstanceMethods, WantKind, SelIdents,
3261 NumSelIdents, CurContext, Results);
Douglas Gregorbab2b3c2009-11-17 23:22:23 +00003262
3263 // Add methods in category implementations.
3264 if (ObjCCategoryImplDecl *Impl = CatDecl->getImplementation())
Douglas Gregorc8537c52009-11-19 07:41:15 +00003265 AddObjCMethods(Impl, WantInstanceMethods, WantKind, SelIdents,
3266 NumSelIdents, CurContext, Results);
Douglas Gregorbab2b3c2009-11-17 23:22:23 +00003267 }
3268
3269 // Add methods in superclass.
3270 if (IFace->getSuperClass())
Douglas Gregorc8537c52009-11-19 07:41:15 +00003271 AddObjCMethods(IFace->getSuperClass(), WantInstanceMethods, WantKind,
3272 SelIdents, NumSelIdents, CurContext, Results);
Douglas Gregorbab2b3c2009-11-17 23:22:23 +00003273
3274 // Add methods in our implementation, if any.
3275 if (ObjCImplementationDecl *Impl = IFace->getImplementation())
Douglas Gregorc8537c52009-11-19 07:41:15 +00003276 AddObjCMethods(Impl, WantInstanceMethods, WantKind, SelIdents,
3277 NumSelIdents, CurContext, Results);
3278}
3279
3280
3281void Sema::CodeCompleteObjCPropertyGetter(Scope *S, DeclPtrTy ClassDecl,
3282 DeclPtrTy *Methods,
3283 unsigned NumMethods) {
3284 typedef CodeCompleteConsumer::Result Result;
3285
3286 // Try to find the interface where getters might live.
3287 ObjCInterfaceDecl *Class
3288 = dyn_cast_or_null<ObjCInterfaceDecl>(ClassDecl.getAs<Decl>());
3289 if (!Class) {
3290 if (ObjCCategoryDecl *Category
3291 = dyn_cast_or_null<ObjCCategoryDecl>(ClassDecl.getAs<Decl>()))
3292 Class = Category->getClassInterface();
3293
3294 if (!Class)
3295 return;
3296 }
3297
3298 // Find all of the potential getters.
3299 ResultBuilder Results(*this);
3300 Results.EnterNewScope();
3301
3302 // FIXME: We need to do this because Objective-C methods don't get
3303 // pushed into DeclContexts early enough. Argh!
3304 for (unsigned I = 0; I != NumMethods; ++I) {
3305 if (ObjCMethodDecl *Method
3306 = dyn_cast_or_null<ObjCMethodDecl>(Methods[I].getAs<Decl>()))
3307 if (Method->isInstanceMethod() &&
3308 isAcceptableObjCMethod(Method, MK_ZeroArgSelector, 0, 0)) {
3309 Result R = Result(Method, 0);
3310 R.AllParametersAreInformative = true;
3311 Results.MaybeAddResult(R, CurContext);
3312 }
3313 }
3314
3315 AddObjCMethods(Class, true, MK_ZeroArgSelector, 0, 0, CurContext, Results);
3316 Results.ExitScope();
3317 HandleCodeCompleteResults(this, CodeCompleter,Results.data(),Results.size());
3318}
3319
3320void Sema::CodeCompleteObjCPropertySetter(Scope *S, DeclPtrTy ObjCImplDecl,
3321 DeclPtrTy *Methods,
3322 unsigned NumMethods) {
3323 typedef CodeCompleteConsumer::Result Result;
3324
3325 // Try to find the interface where setters might live.
3326 ObjCInterfaceDecl *Class
3327 = dyn_cast_or_null<ObjCInterfaceDecl>(ObjCImplDecl.getAs<Decl>());
3328 if (!Class) {
3329 if (ObjCCategoryDecl *Category
3330 = dyn_cast_or_null<ObjCCategoryDecl>(ObjCImplDecl.getAs<Decl>()))
3331 Class = Category->getClassInterface();
3332
3333 if (!Class)
3334 return;
3335 }
3336
3337 // Find all of the potential getters.
3338 ResultBuilder Results(*this);
3339 Results.EnterNewScope();
3340
3341 // FIXME: We need to do this because Objective-C methods don't get
3342 // pushed into DeclContexts early enough. Argh!
3343 for (unsigned I = 0; I != NumMethods; ++I) {
3344 if (ObjCMethodDecl *Method
3345 = dyn_cast_or_null<ObjCMethodDecl>(Methods[I].getAs<Decl>()))
3346 if (Method->isInstanceMethod() &&
3347 isAcceptableObjCMethod(Method, MK_OneArgSelector, 0, 0)) {
3348 Result R = Result(Method, 0);
3349 R.AllParametersAreInformative = true;
3350 Results.MaybeAddResult(R, CurContext);
3351 }
3352 }
3353
3354 AddObjCMethods(Class, true, MK_OneArgSelector, 0, 0, CurContext, Results);
3355
3356 Results.ExitScope();
3357 HandleCodeCompleteResults(this, CodeCompleter,Results.data(),Results.size());
Douglas Gregorbab2b3c2009-11-17 23:22:23 +00003358}
3359
Douglas Gregor9d2ddb22010-04-06 19:22:33 +00003360/// \brief When we have an expression with type "id", we may assume
3361/// that it has some more-specific class type based on knowledge of
3362/// common uses of Objective-C. This routine returns that class type,
3363/// or NULL if no better result could be determined.
3364static ObjCInterfaceDecl *GetAssumedMessageSendExprType(Expr *E) {
3365 ObjCMessageExpr *Msg = dyn_cast<ObjCMessageExpr>(E);
3366 if (!Msg)
3367 return 0;
3368
3369 Selector Sel = Msg->getSelector();
3370 if (Sel.isNull())
3371 return 0;
3372
3373 IdentifierInfo *Id = Sel.getIdentifierInfoForSlot(0);
3374 if (!Id)
3375 return 0;
3376
3377 ObjCMethodDecl *Method = Msg->getMethodDecl();
3378 if (!Method)
3379 return 0;
3380
3381 // Determine the class that we're sending the message to.
Douglas Gregor9a129192010-04-21 00:45:42 +00003382 ObjCInterfaceDecl *IFace = 0;
3383 switch (Msg->getReceiverKind()) {
3384 case ObjCMessageExpr::Class:
John McCall8b07ec22010-05-15 11:32:37 +00003385 if (const ObjCObjectType *ObjType
3386 = Msg->getClassReceiver()->getAs<ObjCObjectType>())
3387 IFace = ObjType->getInterface();
Douglas Gregor9a129192010-04-21 00:45:42 +00003388 break;
3389
3390 case ObjCMessageExpr::Instance: {
3391 QualType T = Msg->getInstanceReceiver()->getType();
3392 if (const ObjCObjectPointerType *Ptr = T->getAs<ObjCObjectPointerType>())
3393 IFace = Ptr->getInterfaceDecl();
3394 break;
3395 }
3396
3397 case ObjCMessageExpr::SuperInstance:
3398 case ObjCMessageExpr::SuperClass:
3399 break;
Douglas Gregor9d2ddb22010-04-06 19:22:33 +00003400 }
3401
3402 if (!IFace)
3403 return 0;
3404
3405 ObjCInterfaceDecl *Super = IFace->getSuperClass();
3406 if (Method->isInstanceMethod())
3407 return llvm::StringSwitch<ObjCInterfaceDecl *>(Id->getName())
3408 .Case("retain", IFace)
3409 .Case("autorelease", IFace)
3410 .Case("copy", IFace)
3411 .Case("copyWithZone", IFace)
3412 .Case("mutableCopy", IFace)
3413 .Case("mutableCopyWithZone", IFace)
3414 .Case("awakeFromCoder", IFace)
3415 .Case("replacementObjectFromCoder", IFace)
3416 .Case("class", IFace)
3417 .Case("classForCoder", IFace)
3418 .Case("superclass", Super)
3419 .Default(0);
3420
3421 return llvm::StringSwitch<ObjCInterfaceDecl *>(Id->getName())
3422 .Case("new", IFace)
3423 .Case("alloc", IFace)
3424 .Case("allocWithZone", IFace)
3425 .Case("class", IFace)
3426 .Case("superclass", Super)
3427 .Default(0);
3428}
3429
Douglas Gregora817a192010-05-27 23:06:34 +00003430void Sema::CodeCompleteObjCMessageReceiver(Scope *S) {
3431 typedef CodeCompleteConsumer::Result Result;
3432 ResultBuilder Results(*this);
3433
3434 // Find anything that looks like it could be a message receiver.
3435 Results.setFilter(&ResultBuilder::IsObjCMessageReceiver);
3436 CodeCompletionDeclConsumer Consumer(Results, CurContext);
3437 Results.EnterNewScope();
3438 LookupVisibleDecls(S, LookupOrdinaryName, Consumer);
3439
3440 // If we are in an Objective-C method inside a class that has a superclass,
3441 // add "super" as an option.
3442 if (ObjCMethodDecl *Method = getCurMethodDecl())
3443 if (ObjCInterfaceDecl *Iface = Method->getClassInterface())
3444 if (Iface->getSuperClass())
3445 Results.AddResult(Result("super"));
3446
3447 Results.ExitScope();
3448
3449 if (CodeCompleter->includeMacros())
3450 AddMacroResults(PP, Results);
3451 HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
3452
3453}
3454
Douglas Gregor0c78ad92010-04-21 19:57:20 +00003455void Sema::CodeCompleteObjCSuperMessage(Scope *S, SourceLocation SuperLoc,
3456 IdentifierInfo **SelIdents,
3457 unsigned NumSelIdents) {
3458 ObjCInterfaceDecl *CDecl = 0;
3459 if (ObjCMethodDecl *CurMethod = getCurMethodDecl()) {
3460 // Figure out which interface we're in.
3461 CDecl = CurMethod->getClassInterface();
3462 if (!CDecl)
3463 return;
3464
3465 // Find the superclass of this class.
3466 CDecl = CDecl->getSuperClass();
3467 if (!CDecl)
3468 return;
3469
3470 if (CurMethod->isInstanceMethod()) {
3471 // We are inside an instance method, which means that the message
3472 // send [super ...] is actually calling an instance method on the
3473 // current object. Build the super expression and handle this like
3474 // an instance method.
3475 QualType SuperTy = Context.getObjCInterfaceType(CDecl);
3476 SuperTy = Context.getObjCObjectPointerType(SuperTy);
3477 OwningExprResult Super
3478 = Owned(new (Context) ObjCSuperExpr(SuperLoc, SuperTy));
3479 return CodeCompleteObjCInstanceMessage(S, (Expr *)Super.get(),
3480 SelIdents, NumSelIdents);
3481 }
3482
3483 // Fall through to send to the superclass in CDecl.
3484 } else {
3485 // "super" may be the name of a type or variable. Figure out which
3486 // it is.
3487 IdentifierInfo *Super = &Context.Idents.get("super");
3488 NamedDecl *ND = LookupSingleName(S, Super, SuperLoc,
3489 LookupOrdinaryName);
3490 if ((CDecl = dyn_cast_or_null<ObjCInterfaceDecl>(ND))) {
3491 // "super" names an interface. Use it.
3492 } else if (TypeDecl *TD = dyn_cast_or_null<TypeDecl>(ND)) {
John McCall8b07ec22010-05-15 11:32:37 +00003493 if (const ObjCObjectType *Iface
3494 = Context.getTypeDeclType(TD)->getAs<ObjCObjectType>())
3495 CDecl = Iface->getInterface();
Douglas Gregor0c78ad92010-04-21 19:57:20 +00003496 } else if (ND && isa<UnresolvedUsingTypenameDecl>(ND)) {
3497 // "super" names an unresolved type; we can't be more specific.
3498 } else {
3499 // Assume that "super" names some kind of value and parse that way.
3500 CXXScopeSpec SS;
3501 UnqualifiedId id;
3502 id.setIdentifier(Super, SuperLoc);
3503 OwningExprResult SuperExpr = ActOnIdExpression(S, SS, id, false, false);
3504 return CodeCompleteObjCInstanceMessage(S, (Expr *)SuperExpr.get(),
3505 SelIdents, NumSelIdents);
3506 }
3507
3508 // Fall through
3509 }
3510
3511 TypeTy *Receiver = 0;
3512 if (CDecl)
3513 Receiver = Context.getObjCInterfaceType(CDecl).getAsOpaquePtr();
3514 return CodeCompleteObjCClassMessage(S, Receiver, SelIdents,
3515 NumSelIdents);
3516}
3517
3518void Sema::CodeCompleteObjCClassMessage(Scope *S, TypeTy *Receiver,
Douglas Gregor1b605f72009-11-19 01:08:35 +00003519 IdentifierInfo **SelIdents,
3520 unsigned NumSelIdents) {
Steve Naroffeae65032009-11-07 02:08:14 +00003521 typedef CodeCompleteConsumer::Result Result;
Douglas Gregor8ce33212009-11-17 17:59:40 +00003522 ObjCInterfaceDecl *CDecl = 0;
3523
Douglas Gregor8ce33212009-11-17 17:59:40 +00003524 // If the given name refers to an interface type, retrieve the
3525 // corresponding declaration.
Douglas Gregor0c78ad92010-04-21 19:57:20 +00003526 if (Receiver) {
3527 QualType T = GetTypeFromParser(Receiver, 0);
3528 if (!T.isNull())
John McCall8b07ec22010-05-15 11:32:37 +00003529 if (const ObjCObjectType *Interface = T->getAs<ObjCObjectType>())
3530 CDecl = Interface->getInterface();
Douglas Gregor8ce33212009-11-17 17:59:40 +00003531 }
3532
Douglas Gregorbab2b3c2009-11-17 23:22:23 +00003533 // Add all of the factory methods in this Objective-C class, its protocols,
3534 // superclasses, categories, implementation, etc.
Steve Naroffeae65032009-11-07 02:08:14 +00003535 ResultBuilder Results(*this);
3536 Results.EnterNewScope();
Douglas Gregor6285f752010-04-06 16:40:00 +00003537
3538 if (CDecl)
3539 AddObjCMethods(CDecl, false, MK_Any, SelIdents, NumSelIdents, CurContext,
3540 Results);
Douglas Gregor0c78ad92010-04-21 19:57:20 +00003541 else {
Douglas Gregor6285f752010-04-06 16:40:00 +00003542 // We're messaging "id" as a type; provide all class/factory methods.
3543
Douglas Gregord720daf2010-04-06 17:30:22 +00003544 // If we have an external source, load the entire class method
3545 // pool from the PCH file.
3546 if (ExternalSource) {
John McCall75b960e2010-06-01 09:23:16 +00003547 for (uint32_t I = 0, N = ExternalSource->GetNumExternalSelectors();
3548 I != N; ++I) {
3549 Selector Sel = ExternalSource->GetExternalSelector(I);
Douglas Gregord720daf2010-04-06 17:30:22 +00003550 if (Sel.isNull() || FactoryMethodPool.count(Sel) ||
3551 InstanceMethodPool.count(Sel))
3552 continue;
3553
3554 ReadMethodPool(Sel, /*isInstance=*/false);
3555 }
3556 }
3557
Douglas Gregor6285f752010-04-06 16:40:00 +00003558 for (llvm::DenseMap<Selector, ObjCMethodList>::iterator
3559 M = FactoryMethodPool.begin(),
3560 MEnd = FactoryMethodPool.end();
3561 M != MEnd;
3562 ++M) {
Douglas Gregord720daf2010-04-06 17:30:22 +00003563 for (ObjCMethodList *MethList = &M->second; MethList && MethList->Method;
Douglas Gregor6285f752010-04-06 16:40:00 +00003564 MethList = MethList->Next) {
3565 if (!isAcceptableObjCMethod(MethList->Method, MK_Any, SelIdents,
3566 NumSelIdents))
3567 continue;
3568
3569 Result R(MethList->Method, 0);
3570 R.StartParameter = NumSelIdents;
3571 R.AllParametersAreInformative = false;
3572 Results.MaybeAddResult(R, CurContext);
3573 }
3574 }
3575 }
3576
Steve Naroffeae65032009-11-07 02:08:14 +00003577 Results.ExitScope();
Daniel Dunbar242ea9a2009-11-13 08:58:20 +00003578 HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
Steve Naroffeae65032009-11-07 02:08:14 +00003579}
3580
Douglas Gregor1b605f72009-11-19 01:08:35 +00003581void Sema::CodeCompleteObjCInstanceMessage(Scope *S, ExprTy *Receiver,
3582 IdentifierInfo **SelIdents,
3583 unsigned NumSelIdents) {
Steve Naroffeae65032009-11-07 02:08:14 +00003584 typedef CodeCompleteConsumer::Result Result;
Steve Naroffeae65032009-11-07 02:08:14 +00003585
3586 Expr *RecExpr = static_cast<Expr *>(Receiver);
Steve Naroffeae65032009-11-07 02:08:14 +00003587
Douglas Gregorbab2b3c2009-11-17 23:22:23 +00003588 // If necessary, apply function/array conversion to the receiver.
3589 // C99 6.7.5.3p[7,8].
Douglas Gregorb92a1562010-02-03 00:27:59 +00003590 DefaultFunctionArrayLvalueConversion(RecExpr);
Douglas Gregorbab2b3c2009-11-17 23:22:23 +00003591 QualType ReceiverType = RecExpr->getType();
Steve Naroffeae65032009-11-07 02:08:14 +00003592
Douglas Gregorbab2b3c2009-11-17 23:22:23 +00003593 // Build the set of methods we can see.
3594 ResultBuilder Results(*this);
3595 Results.EnterNewScope();
Douglas Gregor9d2ddb22010-04-06 19:22:33 +00003596
3597 // If we're messaging an expression with type "id" or "Class", check
3598 // whether we know something special about the receiver that allows
3599 // us to assume a more-specific receiver type.
3600 if (ReceiverType->isObjCIdType() || ReceiverType->isObjCClassType())
3601 if (ObjCInterfaceDecl *IFace = GetAssumedMessageSendExprType(RecExpr))
3602 ReceiverType = Context.getObjCObjectPointerType(
3603 Context.getObjCInterfaceType(IFace));
Douglas Gregorbab2b3c2009-11-17 23:22:23 +00003604
Douglas Gregora3329fa2009-11-18 00:06:18 +00003605 // Handle messages to Class. This really isn't a message to an instance
3606 // method, so we treat it the same way we would treat a message send to a
3607 // class method.
3608 if (ReceiverType->isObjCClassType() ||
3609 ReceiverType->isObjCQualifiedClassType()) {
3610 if (ObjCMethodDecl *CurMethod = getCurMethodDecl()) {
3611 if (ObjCInterfaceDecl *ClassDecl = CurMethod->getClassInterface())
Douglas Gregorc8537c52009-11-19 07:41:15 +00003612 AddObjCMethods(ClassDecl, false, MK_Any, SelIdents, NumSelIdents,
3613 CurContext, Results);
Douglas Gregora3329fa2009-11-18 00:06:18 +00003614 }
3615 }
3616 // Handle messages to a qualified ID ("id<foo>").
3617 else if (const ObjCObjectPointerType *QualID
3618 = ReceiverType->getAsObjCQualifiedIdType()) {
3619 // Search protocols for instance methods.
3620 for (ObjCObjectPointerType::qual_iterator I = QualID->qual_begin(),
3621 E = QualID->qual_end();
3622 I != E; ++I)
Douglas Gregorc8537c52009-11-19 07:41:15 +00003623 AddObjCMethods(*I, true, MK_Any, SelIdents, NumSelIdents, CurContext,
3624 Results);
Douglas Gregora3329fa2009-11-18 00:06:18 +00003625 }
3626 // Handle messages to a pointer to interface type.
3627 else if (const ObjCObjectPointerType *IFacePtr
3628 = ReceiverType->getAsObjCInterfacePointerType()) {
3629 // Search the class, its superclasses, etc., for instance methods.
Douglas Gregorc8537c52009-11-19 07:41:15 +00003630 AddObjCMethods(IFacePtr->getInterfaceDecl(), true, MK_Any, SelIdents,
3631 NumSelIdents, CurContext, Results);
Douglas Gregora3329fa2009-11-18 00:06:18 +00003632
3633 // Search protocols for instance methods.
3634 for (ObjCObjectPointerType::qual_iterator I = IFacePtr->qual_begin(),
3635 E = IFacePtr->qual_end();
3636 I != E; ++I)
Douglas Gregorc8537c52009-11-19 07:41:15 +00003637 AddObjCMethods(*I, true, MK_Any, SelIdents, NumSelIdents, CurContext,
3638 Results);
Douglas Gregora3329fa2009-11-18 00:06:18 +00003639 }
Douglas Gregor6285f752010-04-06 16:40:00 +00003640 // Handle messages to "id".
3641 else if (ReceiverType->isObjCIdType()) {
Douglas Gregord720daf2010-04-06 17:30:22 +00003642 // We're messaging "id", so provide all instance methods we know
3643 // about as code-completion results.
3644
3645 // If we have an external source, load the entire class method
3646 // pool from the PCH file.
3647 if (ExternalSource) {
John McCall75b960e2010-06-01 09:23:16 +00003648 for (uint32_t I = 0, N = ExternalSource->GetNumExternalSelectors();
3649 I != N; ++I) {
3650 Selector Sel = ExternalSource->GetExternalSelector(I);
Douglas Gregord720daf2010-04-06 17:30:22 +00003651 if (Sel.isNull() || InstanceMethodPool.count(Sel) ||
3652 FactoryMethodPool.count(Sel))
3653 continue;
3654
3655 ReadMethodPool(Sel, /*isInstance=*/true);
3656 }
3657 }
3658
Douglas Gregor6285f752010-04-06 16:40:00 +00003659 for (llvm::DenseMap<Selector, ObjCMethodList>::iterator
3660 M = InstanceMethodPool.begin(),
3661 MEnd = InstanceMethodPool.end();
3662 M != MEnd;
3663 ++M) {
Douglas Gregord720daf2010-04-06 17:30:22 +00003664 for (ObjCMethodList *MethList = &M->second; MethList && MethList->Method;
Douglas Gregor6285f752010-04-06 16:40:00 +00003665 MethList = MethList->Next) {
3666 if (!isAcceptableObjCMethod(MethList->Method, MK_Any, SelIdents,
3667 NumSelIdents))
3668 continue;
3669
3670 Result R(MethList->Method, 0);
3671 R.StartParameter = NumSelIdents;
3672 R.AllParametersAreInformative = false;
3673 Results.MaybeAddResult(R, CurContext);
3674 }
3675 }
3676 }
3677
Steve Naroffeae65032009-11-07 02:08:14 +00003678 Results.ExitScope();
Daniel Dunbar242ea9a2009-11-13 08:58:20 +00003679 HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
Steve Naroffeae65032009-11-07 02:08:14 +00003680}
Douglas Gregorbaf69612009-11-18 04:19:12 +00003681
3682/// \brief Add all of the protocol declarations that we find in the given
3683/// (translation unit) context.
3684static void AddProtocolResults(DeclContext *Ctx, DeclContext *CurContext,
Douglas Gregor5b4671c2009-11-18 04:49:41 +00003685 bool OnlyForwardDeclarations,
Douglas Gregorbaf69612009-11-18 04:19:12 +00003686 ResultBuilder &Results) {
3687 typedef CodeCompleteConsumer::Result Result;
3688
3689 for (DeclContext::decl_iterator D = Ctx->decls_begin(),
3690 DEnd = Ctx->decls_end();
3691 D != DEnd; ++D) {
3692 // Record any protocols we find.
3693 if (ObjCProtocolDecl *Proto = dyn_cast<ObjCProtocolDecl>(*D))
Douglas Gregor5b4671c2009-11-18 04:49:41 +00003694 if (!OnlyForwardDeclarations || Proto->isForwardDecl())
Douglas Gregorfc59ce12010-01-14 16:14:35 +00003695 Results.AddResult(Result(Proto, 0), CurContext, 0, false);
Douglas Gregorbaf69612009-11-18 04:19:12 +00003696
3697 // Record any forward-declared protocols we find.
3698 if (ObjCForwardProtocolDecl *Forward
3699 = dyn_cast<ObjCForwardProtocolDecl>(*D)) {
3700 for (ObjCForwardProtocolDecl::protocol_iterator
3701 P = Forward->protocol_begin(),
3702 PEnd = Forward->protocol_end();
3703 P != PEnd; ++P)
Douglas Gregor5b4671c2009-11-18 04:49:41 +00003704 if (!OnlyForwardDeclarations || (*P)->isForwardDecl())
Douglas Gregorfc59ce12010-01-14 16:14:35 +00003705 Results.AddResult(Result(*P, 0), CurContext, 0, false);
Douglas Gregorbaf69612009-11-18 04:19:12 +00003706 }
3707 }
3708}
3709
3710void Sema::CodeCompleteObjCProtocolReferences(IdentifierLocPair *Protocols,
3711 unsigned NumProtocols) {
3712 ResultBuilder Results(*this);
3713 Results.EnterNewScope();
3714
3715 // Tell the result set to ignore all of the protocols we have
3716 // already seen.
3717 for (unsigned I = 0; I != NumProtocols; ++I)
Douglas Gregorb2ccf012010-04-15 22:33:43 +00003718 if (ObjCProtocolDecl *Protocol = LookupProtocol(Protocols[I].first,
3719 Protocols[I].second))
Douglas Gregorbaf69612009-11-18 04:19:12 +00003720 Results.Ignore(Protocol);
3721
3722 // Add all protocols.
Douglas Gregor5b4671c2009-11-18 04:49:41 +00003723 AddProtocolResults(Context.getTranslationUnitDecl(), CurContext, false,
3724 Results);
3725
3726 Results.ExitScope();
3727 HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
3728}
3729
3730void Sema::CodeCompleteObjCProtocolDecl(Scope *) {
3731 ResultBuilder Results(*this);
3732 Results.EnterNewScope();
3733
3734 // Add all protocols.
3735 AddProtocolResults(Context.getTranslationUnitDecl(), CurContext, true,
3736 Results);
Douglas Gregorbaf69612009-11-18 04:19:12 +00003737
3738 Results.ExitScope();
3739 HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
3740}
Douglas Gregor49c22a72009-11-18 16:26:39 +00003741
3742/// \brief Add all of the Objective-C interface declarations that we find in
3743/// the given (translation unit) context.
3744static void AddInterfaceResults(DeclContext *Ctx, DeclContext *CurContext,
3745 bool OnlyForwardDeclarations,
3746 bool OnlyUnimplemented,
3747 ResultBuilder &Results) {
3748 typedef CodeCompleteConsumer::Result Result;
3749
3750 for (DeclContext::decl_iterator D = Ctx->decls_begin(),
3751 DEnd = Ctx->decls_end();
3752 D != DEnd; ++D) {
3753 // Record any interfaces we find.
3754 if (ObjCInterfaceDecl *Class = dyn_cast<ObjCInterfaceDecl>(*D))
3755 if ((!OnlyForwardDeclarations || Class->isForwardDecl()) &&
3756 (!OnlyUnimplemented || !Class->getImplementation()))
Douglas Gregorfc59ce12010-01-14 16:14:35 +00003757 Results.AddResult(Result(Class, 0), CurContext, 0, false);
Douglas Gregor49c22a72009-11-18 16:26:39 +00003758
3759 // Record any forward-declared interfaces we find.
3760 if (ObjCClassDecl *Forward = dyn_cast<ObjCClassDecl>(*D)) {
3761 for (ObjCClassDecl::iterator C = Forward->begin(), CEnd = Forward->end();
3762 C != CEnd; ++C)
3763 if ((!OnlyForwardDeclarations || C->getInterface()->isForwardDecl()) &&
3764 (!OnlyUnimplemented || !C->getInterface()->getImplementation()))
Douglas Gregorfc59ce12010-01-14 16:14:35 +00003765 Results.AddResult(Result(C->getInterface(), 0), CurContext,
3766 0, false);
Douglas Gregor49c22a72009-11-18 16:26:39 +00003767 }
3768 }
3769}
3770
3771void Sema::CodeCompleteObjCInterfaceDecl(Scope *S) {
3772 ResultBuilder Results(*this);
3773 Results.EnterNewScope();
3774
3775 // Add all classes.
3776 AddInterfaceResults(Context.getTranslationUnitDecl(), CurContext, true,
3777 false, Results);
3778
3779 Results.ExitScope();
3780 HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
3781}
3782
Douglas Gregorb2ccf012010-04-15 22:33:43 +00003783void Sema::CodeCompleteObjCSuperclass(Scope *S, IdentifierInfo *ClassName,
3784 SourceLocation ClassNameLoc) {
Douglas Gregor49c22a72009-11-18 16:26:39 +00003785 ResultBuilder Results(*this);
3786 Results.EnterNewScope();
3787
3788 // Make sure that we ignore the class we're currently defining.
3789 NamedDecl *CurClass
Douglas Gregorb2ccf012010-04-15 22:33:43 +00003790 = LookupSingleName(TUScope, ClassName, ClassNameLoc, LookupOrdinaryName);
Douglas Gregor5d34fd32009-11-18 19:08:43 +00003791 if (CurClass && isa<ObjCInterfaceDecl>(CurClass))
Douglas Gregor49c22a72009-11-18 16:26:39 +00003792 Results.Ignore(CurClass);
3793
3794 // Add all classes.
3795 AddInterfaceResults(Context.getTranslationUnitDecl(), CurContext, false,
3796 false, Results);
3797
3798 Results.ExitScope();
3799 HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
3800}
3801
3802void Sema::CodeCompleteObjCImplementationDecl(Scope *S) {
3803 ResultBuilder Results(*this);
3804 Results.EnterNewScope();
3805
3806 // Add all unimplemented classes.
3807 AddInterfaceResults(Context.getTranslationUnitDecl(), CurContext, false,
3808 true, Results);
3809
3810 Results.ExitScope();
3811 HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
3812}
Douglas Gregor5d34fd32009-11-18 19:08:43 +00003813
3814void Sema::CodeCompleteObjCInterfaceCategory(Scope *S,
Douglas Gregorb2ccf012010-04-15 22:33:43 +00003815 IdentifierInfo *ClassName,
3816 SourceLocation ClassNameLoc) {
Douglas Gregor5d34fd32009-11-18 19:08:43 +00003817 typedef CodeCompleteConsumer::Result Result;
3818
3819 ResultBuilder Results(*this);
3820
3821 // Ignore any categories we find that have already been implemented by this
3822 // interface.
3823 llvm::SmallPtrSet<IdentifierInfo *, 16> CategoryNames;
3824 NamedDecl *CurClass
Douglas Gregorb2ccf012010-04-15 22:33:43 +00003825 = LookupSingleName(TUScope, ClassName, ClassNameLoc, LookupOrdinaryName);
Douglas Gregor5d34fd32009-11-18 19:08:43 +00003826 if (ObjCInterfaceDecl *Class = dyn_cast_or_null<ObjCInterfaceDecl>(CurClass))
3827 for (ObjCCategoryDecl *Category = Class->getCategoryList(); Category;
3828 Category = Category->getNextClassCategory())
3829 CategoryNames.insert(Category->getIdentifier());
3830
3831 // Add all of the categories we know about.
3832 Results.EnterNewScope();
3833 TranslationUnitDecl *TU = Context.getTranslationUnitDecl();
3834 for (DeclContext::decl_iterator D = TU->decls_begin(),
3835 DEnd = TU->decls_end();
3836 D != DEnd; ++D)
3837 if (ObjCCategoryDecl *Category = dyn_cast<ObjCCategoryDecl>(*D))
3838 if (CategoryNames.insert(Category->getIdentifier()))
Douglas Gregorfc59ce12010-01-14 16:14:35 +00003839 Results.AddResult(Result(Category, 0), CurContext, 0, false);
Douglas Gregor5d34fd32009-11-18 19:08:43 +00003840 Results.ExitScope();
3841
3842 HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
3843}
3844
3845void Sema::CodeCompleteObjCImplementationCategory(Scope *S,
Douglas Gregorb2ccf012010-04-15 22:33:43 +00003846 IdentifierInfo *ClassName,
3847 SourceLocation ClassNameLoc) {
Douglas Gregor5d34fd32009-11-18 19:08:43 +00003848 typedef CodeCompleteConsumer::Result Result;
3849
3850 // Find the corresponding interface. If we couldn't find the interface, the
3851 // program itself is ill-formed. However, we'll try to be helpful still by
3852 // providing the list of all of the categories we know about.
3853 NamedDecl *CurClass
Douglas Gregorb2ccf012010-04-15 22:33:43 +00003854 = LookupSingleName(TUScope, ClassName, ClassNameLoc, LookupOrdinaryName);
Douglas Gregor5d34fd32009-11-18 19:08:43 +00003855 ObjCInterfaceDecl *Class = dyn_cast_or_null<ObjCInterfaceDecl>(CurClass);
3856 if (!Class)
Douglas Gregorb2ccf012010-04-15 22:33:43 +00003857 return CodeCompleteObjCInterfaceCategory(S, ClassName, ClassNameLoc);
Douglas Gregor5d34fd32009-11-18 19:08:43 +00003858
3859 ResultBuilder Results(*this);
3860
3861 // Add all of the categories that have have corresponding interface
3862 // declarations in this class and any of its superclasses, except for
3863 // already-implemented categories in the class itself.
3864 llvm::SmallPtrSet<IdentifierInfo *, 16> CategoryNames;
3865 Results.EnterNewScope();
3866 bool IgnoreImplemented = true;
3867 while (Class) {
3868 for (ObjCCategoryDecl *Category = Class->getCategoryList(); Category;
3869 Category = Category->getNextClassCategory())
3870 if ((!IgnoreImplemented || !Category->getImplementation()) &&
3871 CategoryNames.insert(Category->getIdentifier()))
Douglas Gregorfc59ce12010-01-14 16:14:35 +00003872 Results.AddResult(Result(Category, 0), CurContext, 0, false);
Douglas Gregor5d34fd32009-11-18 19:08:43 +00003873
3874 Class = Class->getSuperClass();
3875 IgnoreImplemented = false;
3876 }
3877 Results.ExitScope();
3878
3879 HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
3880}
Douglas Gregor5d649882009-11-18 22:32:06 +00003881
Douglas Gregor52e78bd2009-11-18 22:56:13 +00003882void Sema::CodeCompleteObjCPropertyDefinition(Scope *S, DeclPtrTy ObjCImpDecl) {
Douglas Gregor5d649882009-11-18 22:32:06 +00003883 typedef CodeCompleteConsumer::Result Result;
3884 ResultBuilder Results(*this);
3885
3886 // Figure out where this @synthesize lives.
3887 ObjCContainerDecl *Container
3888 = dyn_cast_or_null<ObjCContainerDecl>(ObjCImpDecl.getAs<Decl>());
3889 if (!Container ||
3890 (!isa<ObjCImplementationDecl>(Container) &&
3891 !isa<ObjCCategoryImplDecl>(Container)))
3892 return;
3893
3894 // Ignore any properties that have already been implemented.
3895 for (DeclContext::decl_iterator D = Container->decls_begin(),
3896 DEnd = Container->decls_end();
3897 D != DEnd; ++D)
3898 if (ObjCPropertyImplDecl *PropertyImpl = dyn_cast<ObjCPropertyImplDecl>(*D))
3899 Results.Ignore(PropertyImpl->getPropertyDecl());
3900
3901 // Add any properties that we find.
3902 Results.EnterNewScope();
3903 if (ObjCImplementationDecl *ClassImpl
3904 = dyn_cast<ObjCImplementationDecl>(Container))
3905 AddObjCProperties(ClassImpl->getClassInterface(), false, CurContext,
3906 Results);
3907 else
3908 AddObjCProperties(cast<ObjCCategoryImplDecl>(Container)->getCategoryDecl(),
3909 false, CurContext, Results);
3910 Results.ExitScope();
3911
3912 HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
3913}
3914
3915void Sema::CodeCompleteObjCPropertySynthesizeIvar(Scope *S,
3916 IdentifierInfo *PropertyName,
3917 DeclPtrTy ObjCImpDecl) {
3918 typedef CodeCompleteConsumer::Result Result;
3919 ResultBuilder Results(*this);
3920
3921 // Figure out where this @synthesize lives.
3922 ObjCContainerDecl *Container
3923 = dyn_cast_or_null<ObjCContainerDecl>(ObjCImpDecl.getAs<Decl>());
3924 if (!Container ||
3925 (!isa<ObjCImplementationDecl>(Container) &&
3926 !isa<ObjCCategoryImplDecl>(Container)))
3927 return;
3928
3929 // Figure out which interface we're looking into.
3930 ObjCInterfaceDecl *Class = 0;
3931 if (ObjCImplementationDecl *ClassImpl
3932 = dyn_cast<ObjCImplementationDecl>(Container))
3933 Class = ClassImpl->getClassInterface();
3934 else
3935 Class = cast<ObjCCategoryImplDecl>(Container)->getCategoryDecl()
3936 ->getClassInterface();
3937
3938 // Add all of the instance variables in this class and its superclasses.
3939 Results.EnterNewScope();
3940 for(; Class; Class = Class->getSuperClass()) {
3941 // FIXME: We could screen the type of each ivar for compatibility with
3942 // the property, but is that being too paternal?
3943 for (ObjCInterfaceDecl::ivar_iterator IVar = Class->ivar_begin(),
3944 IVarEnd = Class->ivar_end();
3945 IVar != IVarEnd; ++IVar)
Douglas Gregorfc59ce12010-01-14 16:14:35 +00003946 Results.AddResult(Result(*IVar, 0), CurContext, 0, false);
Douglas Gregor5d649882009-11-18 22:32:06 +00003947 }
3948 Results.ExitScope();
3949
3950 HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
3951}
Douglas Gregor636a61e2010-04-07 00:21:17 +00003952
3953typedef llvm::DenseMap<Selector, ObjCMethodDecl *> KnownMethodsMap;
3954
3955/// \brief Find all of the methods that reside in the given container
3956/// (and its superclasses, protocols, etc.) that meet the given
3957/// criteria. Insert those methods into the map of known methods,
3958/// indexed by selector so they can be easily found.
3959static void FindImplementableMethods(ASTContext &Context,
3960 ObjCContainerDecl *Container,
3961 bool WantInstanceMethods,
3962 QualType ReturnType,
3963 bool IsInImplementation,
3964 KnownMethodsMap &KnownMethods) {
3965 if (ObjCInterfaceDecl *IFace = dyn_cast<ObjCInterfaceDecl>(Container)) {
3966 // Recurse into protocols.
3967 const ObjCList<ObjCProtocolDecl> &Protocols
3968 = IFace->getReferencedProtocols();
3969 for (ObjCList<ObjCProtocolDecl>::iterator I = Protocols.begin(),
3970 E = Protocols.end();
3971 I != E; ++I)
3972 FindImplementableMethods(Context, *I, WantInstanceMethods, ReturnType,
3973 IsInImplementation, KnownMethods);
3974
3975 // If we're not in the implementation of a class, also visit the
3976 // superclass.
3977 if (!IsInImplementation && IFace->getSuperClass())
3978 FindImplementableMethods(Context, IFace->getSuperClass(),
3979 WantInstanceMethods, ReturnType,
3980 IsInImplementation, KnownMethods);
3981
3982 // Add methods from any class extensions (but not from categories;
3983 // those should go into category implementations).
Fariborz Jahanian3bf0ded2010-06-22 23:20:40 +00003984 for (const ObjCCategoryDecl *Cat = IFace->getFirstClassExtension(); Cat;
3985 Cat = Cat->getNextClassExtension())
3986 FindImplementableMethods(Context, const_cast<ObjCCategoryDecl*>(Cat),
3987 WantInstanceMethods, ReturnType,
Douglas Gregor636a61e2010-04-07 00:21:17 +00003988 IsInImplementation, KnownMethods);
Douglas Gregor636a61e2010-04-07 00:21:17 +00003989 }
3990
3991 if (ObjCCategoryDecl *Category = dyn_cast<ObjCCategoryDecl>(Container)) {
3992 // Recurse into protocols.
3993 const ObjCList<ObjCProtocolDecl> &Protocols
3994 = Category->getReferencedProtocols();
3995 for (ObjCList<ObjCProtocolDecl>::iterator I = Protocols.begin(),
3996 E = Protocols.end();
3997 I != E; ++I)
3998 FindImplementableMethods(Context, *I, WantInstanceMethods, ReturnType,
3999 IsInImplementation, KnownMethods);
4000 }
4001
4002 if (ObjCProtocolDecl *Protocol = dyn_cast<ObjCProtocolDecl>(Container)) {
4003 // Recurse into protocols.
4004 const ObjCList<ObjCProtocolDecl> &Protocols
4005 = Protocol->getReferencedProtocols();
4006 for (ObjCList<ObjCProtocolDecl>::iterator I = Protocols.begin(),
4007 E = Protocols.end();
4008 I != E; ++I)
4009 FindImplementableMethods(Context, *I, WantInstanceMethods, ReturnType,
4010 IsInImplementation, KnownMethods);
4011 }
4012
4013 // Add methods in this container. This operation occurs last because
4014 // we want the methods from this container to override any methods
4015 // we've previously seen with the same selector.
4016 for (ObjCContainerDecl::method_iterator M = Container->meth_begin(),
4017 MEnd = Container->meth_end();
4018 M != MEnd; ++M) {
4019 if ((*M)->isInstanceMethod() == WantInstanceMethods) {
4020 if (!ReturnType.isNull() &&
4021 !Context.hasSameUnqualifiedType(ReturnType, (*M)->getResultType()))
4022 continue;
4023
4024 KnownMethods[(*M)->getSelector()] = *M;
4025 }
4026 }
4027}
4028
4029void Sema::CodeCompleteObjCMethodDecl(Scope *S,
4030 bool IsInstanceMethod,
4031 TypeTy *ReturnTy,
4032 DeclPtrTy IDecl) {
4033 // Determine the return type of the method we're declaring, if
4034 // provided.
4035 QualType ReturnType = GetTypeFromParser(ReturnTy);
4036
4037 // Determine where we should start searching for methods, and where we
4038 ObjCContainerDecl *SearchDecl = 0, *CurrentDecl = 0;
4039 bool IsInImplementation = false;
4040 if (Decl *D = IDecl.getAs<Decl>()) {
4041 if (ObjCImplementationDecl *Impl = dyn_cast<ObjCImplementationDecl>(D)) {
4042 SearchDecl = Impl->getClassInterface();
4043 CurrentDecl = Impl;
4044 IsInImplementation = true;
4045 } else if (ObjCCategoryImplDecl *CatImpl
4046 = dyn_cast<ObjCCategoryImplDecl>(D)) {
4047 SearchDecl = CatImpl->getCategoryDecl();
4048 CurrentDecl = CatImpl;
4049 IsInImplementation = true;
4050 } else {
4051 SearchDecl = dyn_cast<ObjCContainerDecl>(D);
4052 CurrentDecl = SearchDecl;
4053 }
4054 }
4055
4056 if (!SearchDecl && S) {
4057 if (DeclContext *DC = static_cast<DeclContext *>(S->getEntity())) {
4058 SearchDecl = dyn_cast<ObjCContainerDecl>(DC);
4059 CurrentDecl = SearchDecl;
4060 }
4061 }
4062
4063 if (!SearchDecl || !CurrentDecl) {
4064 HandleCodeCompleteResults(this, CodeCompleter, 0, 0);
4065 return;
4066 }
4067
4068 // Find all of the methods that we could declare/implement here.
4069 KnownMethodsMap KnownMethods;
4070 FindImplementableMethods(Context, SearchDecl, IsInstanceMethod,
4071 ReturnType, IsInImplementation, KnownMethods);
4072
4073 // Erase any methods that have already been declared or
4074 // implemented here.
4075 for (ObjCContainerDecl::method_iterator M = CurrentDecl->meth_begin(),
4076 MEnd = CurrentDecl->meth_end();
4077 M != MEnd; ++M) {
4078 if ((*M)->isInstanceMethod() != IsInstanceMethod)
4079 continue;
4080
4081 KnownMethodsMap::iterator Pos = KnownMethods.find((*M)->getSelector());
4082 if (Pos != KnownMethods.end())
4083 KnownMethods.erase(Pos);
4084 }
4085
4086 // Add declarations or definitions for each of the known methods.
4087 typedef CodeCompleteConsumer::Result Result;
4088 ResultBuilder Results(*this);
4089 Results.EnterNewScope();
4090 PrintingPolicy Policy(Context.PrintingPolicy);
4091 Policy.AnonymousTagLocations = false;
4092 for (KnownMethodsMap::iterator M = KnownMethods.begin(),
4093 MEnd = KnownMethods.end();
4094 M != MEnd; ++M) {
4095 ObjCMethodDecl *Method = M->second;
4096 CodeCompletionString *Pattern = new CodeCompletionString;
4097
4098 // If the result type was not already provided, add it to the
4099 // pattern as (type).
4100 if (ReturnType.isNull()) {
4101 std::string TypeStr;
4102 Method->getResultType().getAsStringInternal(TypeStr, Policy);
4103 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
4104 Pattern->AddTextChunk(TypeStr);
4105 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
4106 }
4107
4108 Selector Sel = Method->getSelector();
4109
4110 // Add the first part of the selector to the pattern.
4111 Pattern->AddTypedTextChunk(Sel.getIdentifierInfoForSlot(0)->getName());
4112
4113 // Add parameters to the pattern.
4114 unsigned I = 0;
4115 for (ObjCMethodDecl::param_iterator P = Method->param_begin(),
4116 PEnd = Method->param_end();
4117 P != PEnd; (void)++P, ++I) {
4118 // Add the part of the selector name.
4119 if (I == 0)
4120 Pattern->AddChunk(CodeCompletionString::CK_Colon);
4121 else if (I < Sel.getNumArgs()) {
4122 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
4123 Pattern->AddTextChunk(Sel.getIdentifierInfoForSlot(1)->getName());
4124 Pattern->AddChunk(CodeCompletionString::CK_Colon);
4125 } else
4126 break;
4127
4128 // Add the parameter type.
4129 std::string TypeStr;
4130 (*P)->getOriginalType().getAsStringInternal(TypeStr, Policy);
4131 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
4132 Pattern->AddTextChunk(TypeStr);
4133 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
4134
4135 if (IdentifierInfo *Id = (*P)->getIdentifier())
4136 Pattern->AddTextChunk(Id->getName());
4137 }
4138
4139 if (Method->isVariadic()) {
4140 if (Method->param_size() > 0)
4141 Pattern->AddChunk(CodeCompletionString::CK_Comma);
4142 Pattern->AddTextChunk("...");
4143 }
4144
Douglas Gregord37c59d2010-05-28 00:57:46 +00004145 if (IsInImplementation && Results.includeCodePatterns()) {
Douglas Gregor636a61e2010-04-07 00:21:17 +00004146 // We will be defining the method here, so add a compound statement.
4147 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
4148 Pattern->AddChunk(CodeCompletionString::CK_LeftBrace);
4149 Pattern->AddChunk(CodeCompletionString::CK_VerticalSpace);
4150 if (!Method->getResultType()->isVoidType()) {
4151 // If the result type is not void, add a return clause.
4152 Pattern->AddTextChunk("return");
4153 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
4154 Pattern->AddPlaceholderChunk("expression");
4155 Pattern->AddChunk(CodeCompletionString::CK_SemiColon);
4156 } else
4157 Pattern->AddPlaceholderChunk("statements");
4158
4159 Pattern->AddChunk(CodeCompletionString::CK_VerticalSpace);
4160 Pattern->AddChunk(CodeCompletionString::CK_RightBrace);
4161 }
4162
4163 Results.AddResult(Result(Pattern));
4164 }
4165
4166 Results.ExitScope();
4167
4168 HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
4169}
Douglas Gregor95887f92010-07-08 23:20:03 +00004170
4171void Sema::CodeCompleteObjCMethodDeclSelector(Scope *S,
4172 bool IsInstanceMethod,
Douglas Gregor45879692010-07-08 23:37:41 +00004173 bool AtParameterName,
Douglas Gregor95887f92010-07-08 23:20:03 +00004174 TypeTy *ReturnTy,
4175 IdentifierInfo **SelIdents,
4176 unsigned NumSelIdents) {
4177 llvm::DenseMap<Selector, ObjCMethodList> &Pool
4178 = IsInstanceMethod? InstanceMethodPool : FactoryMethodPool;
4179
4180 // If we have an external source, load the entire class method
4181 // pool from the PCH file.
4182 if (ExternalSource) {
4183 for (uint32_t I = 0, N = ExternalSource->GetNumExternalSelectors();
4184 I != N; ++I) {
4185 Selector Sel = ExternalSource->GetExternalSelector(I);
4186 if (Sel.isNull() || InstanceMethodPool.count(Sel) ||
4187 FactoryMethodPool.count(Sel))
4188 continue;
4189
4190 ReadMethodPool(Sel, IsInstanceMethod);
4191 }
4192 }
4193
4194 // Build the set of methods we can see.
4195 typedef CodeCompleteConsumer::Result Result;
4196 ResultBuilder Results(*this);
4197
4198 if (ReturnTy)
4199 Results.setPreferredType(GetTypeFromParser(ReturnTy).getNonReferenceType());
4200
4201 Results.EnterNewScope();
4202 for (llvm::DenseMap<Selector, ObjCMethodList>::iterator M = Pool.begin(),
4203 MEnd = Pool.end();
4204 M != MEnd;
4205 ++M) {
4206 for (ObjCMethodList *MethList = &M->second; MethList && MethList->Method;
4207 MethList = MethList->Next) {
4208 if (!isAcceptableObjCMethod(MethList->Method, MK_Any, SelIdents,
4209 NumSelIdents))
4210 continue;
4211
Douglas Gregor45879692010-07-08 23:37:41 +00004212 if (AtParameterName) {
4213 // Suggest parameter names we've seen before.
4214 if (NumSelIdents && NumSelIdents <= MethList->Method->param_size()) {
4215 ParmVarDecl *Param = MethList->Method->param_begin()[NumSelIdents-1];
4216 if (Param->getIdentifier()) {
4217 CodeCompletionString *Pattern = new CodeCompletionString;
4218 Pattern->AddTypedTextChunk(Param->getIdentifier()->getName());
4219 Results.AddResult(Pattern);
4220 }
4221 }
4222
4223 continue;
4224 }
4225
Douglas Gregor95887f92010-07-08 23:20:03 +00004226 Result R(MethList->Method, 0);
4227 R.StartParameter = NumSelIdents;
4228 R.AllParametersAreInformative = false;
4229 R.DeclaringEntity = true;
4230 Results.MaybeAddResult(R, CurContext);
4231 }
4232 }
4233
4234 Results.ExitScope();
4235 HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
4236}