blob: 6a706dfefe59a9dd76a5c8b805d54f4259547fae [file] [log] [blame]
Douglas Gregor81b747b2009-09-17 21:32:03 +00001//===---------------- SemaCodeComplete.cpp - Code Completion ----*- C++ -*-===//
2//
3// The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9//
10// This file defines the code-completion semantic actions.
11//
12//===----------------------------------------------------------------------===//
13#include "Sema.h"
Douglas Gregor1ca6ae82010-01-14 01:09:38 +000014#include "Lookup.h"
Douglas Gregor81b747b2009-09-17 21:32:03 +000015#include "clang/Sema/CodeCompleteConsumer.h"
Douglas Gregor719770d2010-04-06 17:30:22 +000016#include "clang/Sema/ExternalSemaSource.h"
Douglas Gregorb9d0ef72009-09-21 19:57:38 +000017#include "clang/AST/ExprCXX.h"
Douglas Gregor24a069f2009-11-17 17:59:40 +000018#include "clang/AST/ExprObjC.h"
Douglas Gregor3f7c7f42009-10-30 16:50:04 +000019#include "clang/Lex/MacroInfo.h"
20#include "clang/Lex/Preprocessor.h"
Douglas Gregor86d9a522009-09-21 16:56:56 +000021#include "llvm/ADT/SmallPtrSet.h"
Douglas Gregor6a684032009-09-28 03:51:44 +000022#include "llvm/ADT/StringExtras.h"
Douglas Gregor22f56992010-04-06 19:22:33 +000023#include "llvm/ADT/StringSwitch.h"
Douglas Gregor86d9a522009-09-21 16:56:56 +000024#include <list>
25#include <map>
26#include <vector>
Douglas Gregor81b747b2009-09-17 21:32:03 +000027
28using namespace clang;
29
Douglas Gregor86d9a522009-09-21 16:56:56 +000030namespace {
31 /// \brief A container of code-completion results.
32 class ResultBuilder {
33 public:
34 /// \brief The type of a name-lookup filter, which can be provided to the
35 /// name-lookup routines to specify which declarations should be included in
36 /// the result set (when it returns true) and which declarations should be
37 /// filtered out (returns false).
38 typedef bool (ResultBuilder::*LookupFilter)(NamedDecl *) const;
39
40 typedef CodeCompleteConsumer::Result Result;
41
42 private:
43 /// \brief The actual results we have found.
44 std::vector<Result> Results;
45
46 /// \brief A record of all of the declarations we have found and placed
47 /// into the result set, used to ensure that no declaration ever gets into
48 /// the result set twice.
49 llvm::SmallPtrSet<Decl*, 16> AllDeclsFound;
50
Douglas Gregorfbcb5d62009-12-06 20:23:50 +000051 typedef std::pair<NamedDecl *, unsigned> DeclIndexPair;
52
53 /// \brief An entry in the shadow map, which is optimized to store
54 /// a single (declaration, index) mapping (the common case) but
55 /// can also store a list of (declaration, index) mappings.
56 class ShadowMapEntry {
57 typedef llvm::SmallVector<DeclIndexPair, 4> DeclIndexPairVector;
58
59 /// \brief Contains either the solitary NamedDecl * or a vector
60 /// of (declaration, index) pairs.
61 llvm::PointerUnion<NamedDecl *, DeclIndexPairVector*> DeclOrVector;
62
63 /// \brief When the entry contains a single declaration, this is
64 /// the index associated with that entry.
65 unsigned SingleDeclIndex;
66
67 public:
68 ShadowMapEntry() : DeclOrVector(), SingleDeclIndex(0) { }
69
70 void Add(NamedDecl *ND, unsigned Index) {
71 if (DeclOrVector.isNull()) {
72 // 0 - > 1 elements: just set the single element information.
73 DeclOrVector = ND;
74 SingleDeclIndex = Index;
75 return;
76 }
77
78 if (NamedDecl *PrevND = DeclOrVector.dyn_cast<NamedDecl *>()) {
79 // 1 -> 2 elements: create the vector of results and push in the
80 // existing declaration.
81 DeclIndexPairVector *Vec = new DeclIndexPairVector;
82 Vec->push_back(DeclIndexPair(PrevND, SingleDeclIndex));
83 DeclOrVector = Vec;
84 }
85
86 // Add the new element to the end of the vector.
87 DeclOrVector.get<DeclIndexPairVector*>()->push_back(
88 DeclIndexPair(ND, Index));
89 }
90
91 void Destroy() {
92 if (DeclIndexPairVector *Vec
93 = DeclOrVector.dyn_cast<DeclIndexPairVector *>()) {
94 delete Vec;
95 DeclOrVector = ((NamedDecl *)0);
96 }
97 }
98
99 // Iteration.
100 class iterator;
101 iterator begin() const;
102 iterator end() const;
103 };
104
Douglas Gregor86d9a522009-09-21 16:56:56 +0000105 /// \brief A mapping from declaration names to the declarations that have
106 /// this name within a particular scope and their index within the list of
107 /// results.
Douglas Gregorfbcb5d62009-12-06 20:23:50 +0000108 typedef llvm::DenseMap<DeclarationName, ShadowMapEntry> ShadowMap;
Douglas Gregor86d9a522009-09-21 16:56:56 +0000109
110 /// \brief The semantic analysis object for which results are being
111 /// produced.
112 Sema &SemaRef;
113
114 /// \brief If non-NULL, a filter function used to remove any code-completion
115 /// results that are not desirable.
116 LookupFilter Filter;
Douglas Gregor45bcd432010-01-14 03:21:49 +0000117
118 /// \brief Whether we should allow declarations as
119 /// nested-name-specifiers that would otherwise be filtered out.
120 bool AllowNestedNameSpecifiers;
121
Douglas Gregor5ac3bdb2010-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 Gregor86d9a522009-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 Gregor1f5537a2010-07-08 23:20:03 +0000133 void AdjustResultPriorityForPreferredType(Result &R);
134
Douglas Gregor86d9a522009-09-21 16:56:56 +0000135 public:
136 explicit ResultBuilder(Sema &SemaRef, LookupFilter Filter = 0)
Douglas Gregor45bcd432010-01-14 03:21:49 +0000137 : SemaRef(SemaRef), Filter(Filter), AllowNestedNameSpecifiers(false) { }
Douglas Gregor86d9a522009-09-21 16:56:56 +0000138
Douglas Gregord8e8a582010-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 Gregor86d9a522009-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 Gregor5ac3bdb2010-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 Gregor45bcd432010-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 Gregore495b7f2010-01-14 00:20:49 +0000169 /// \brief Determine whether the given declaration is at all interesting
170 /// as a code-completion result.
Douglas Gregor45bcd432010-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 Gregor6660d842010-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 Gregor86d9a522009-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 Gregor456c4a12009-09-21 20:12:40 +0000190 ///
Douglas Gregor1ca6ae82010-01-14 01:09:38 +0000191 /// \param CurContext the result to add (if it is unique).
Douglas Gregor456c4a12009-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 Gregor86d9a522009-09-21 16:56:56 +0000195
Douglas Gregor1ca6ae82010-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 Gregor0cc84042010-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 Gregor1ca6ae82010-01-14 01:09:38 +0000209
Douglas Gregora4477812010-01-14 16:01:26 +0000210 /// \brief Add a new non-declaration result to this result set.
211 void AddResult(Result R);
212
Douglas Gregor86d9a522009-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 Gregor55385fe2009-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 Gregor86d9a522009-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 Gregor791215b2009-09-21 20:51:25 +0000228 bool IsOrdinaryName(NamedDecl *ND) const;
Douglas Gregor4710e5b2010-05-28 00:49:12 +0000229 bool IsOrdinaryNonTypeName(NamedDecl *ND) const;
Douglas Gregor01dfea02010-01-10 23:08:15 +0000230 bool IsOrdinaryNonValueName(NamedDecl *ND) const;
Douglas Gregor86d9a522009-09-21 16:56:56 +0000231 bool IsNestedNameSpecifier(NamedDecl *ND) const;
232 bool IsEnum(NamedDecl *ND) const;
233 bool IsClassOrStruct(NamedDecl *ND) const;
234 bool IsUnion(NamedDecl *ND) const;
235 bool IsNamespace(NamedDecl *ND) const;
236 bool IsNamespaceOrAlias(NamedDecl *ND) const;
237 bool IsType(NamedDecl *ND) const;
Douglas Gregoreb5758b2009-09-23 22:26:46 +0000238 bool IsMember(NamedDecl *ND) const;
Douglas Gregor80f4f4c2010-01-14 16:08:12 +0000239 bool IsObjCIvar(NamedDecl *ND) const;
Douglas Gregor8e254cf2010-05-27 23:06:34 +0000240 bool IsObjCMessageReceiver(NamedDecl *ND) const;
Douglas Gregor86d9a522009-09-21 16:56:56 +0000241 //@}
242 };
243}
244
Douglas Gregorfbcb5d62009-12-06 20:23:50 +0000245class ResultBuilder::ShadowMapEntry::iterator {
246 llvm::PointerUnion<NamedDecl*, const DeclIndexPair*> DeclOrIterator;
247 unsigned SingleDeclIndex;
248
249public:
250 typedef DeclIndexPair value_type;
251 typedef value_type reference;
252 typedef std::ptrdiff_t difference_type;
253 typedef std::input_iterator_tag iterator_category;
254
255 class pointer {
256 DeclIndexPair Value;
257
258 public:
259 pointer(const DeclIndexPair &Value) : Value(Value) { }
260
261 const DeclIndexPair *operator->() const {
262 return &Value;
263 }
264 };
265
266 iterator() : DeclOrIterator((NamedDecl *)0), SingleDeclIndex(0) { }
267
268 iterator(NamedDecl *SingleDecl, unsigned Index)
269 : DeclOrIterator(SingleDecl), SingleDeclIndex(Index) { }
270
271 iterator(const DeclIndexPair *Iterator)
272 : DeclOrIterator(Iterator), SingleDeclIndex(0) { }
273
274 iterator &operator++() {
275 if (DeclOrIterator.is<NamedDecl *>()) {
276 DeclOrIterator = (NamedDecl *)0;
277 SingleDeclIndex = 0;
278 return *this;
279 }
280
281 const DeclIndexPair *I = DeclOrIterator.get<const DeclIndexPair*>();
282 ++I;
283 DeclOrIterator = I;
284 return *this;
285 }
286
287 iterator operator++(int) {
288 iterator tmp(*this);
289 ++(*this);
290 return tmp;
291 }
292
293 reference operator*() const {
294 if (NamedDecl *ND = DeclOrIterator.dyn_cast<NamedDecl *>())
295 return reference(ND, SingleDeclIndex);
296
Douglas Gregord490f952009-12-06 21:27:58 +0000297 return *DeclOrIterator.get<const DeclIndexPair*>();
Douglas Gregorfbcb5d62009-12-06 20:23:50 +0000298 }
299
300 pointer operator->() const {
301 return pointer(**this);
302 }
303
304 friend bool operator==(const iterator &X, const iterator &Y) {
Douglas Gregord490f952009-12-06 21:27:58 +0000305 return X.DeclOrIterator.getOpaqueValue()
306 == Y.DeclOrIterator.getOpaqueValue() &&
Douglas Gregorfbcb5d62009-12-06 20:23:50 +0000307 X.SingleDeclIndex == Y.SingleDeclIndex;
308 }
309
310 friend bool operator!=(const iterator &X, const iterator &Y) {
Douglas Gregord490f952009-12-06 21:27:58 +0000311 return !(X == Y);
Douglas Gregorfbcb5d62009-12-06 20:23:50 +0000312 }
313};
314
Douglas Gregorfbcb5d62009-12-06 20:23:50 +0000315ResultBuilder::ShadowMapEntry::iterator
316ResultBuilder::ShadowMapEntry::begin() const {
317 if (DeclOrVector.isNull())
318 return iterator();
319
320 if (NamedDecl *ND = DeclOrVector.dyn_cast<NamedDecl *>())
321 return iterator(ND, SingleDeclIndex);
322
323 return iterator(DeclOrVector.get<DeclIndexPairVector *>()->begin());
324}
325
326ResultBuilder::ShadowMapEntry::iterator
327ResultBuilder::ShadowMapEntry::end() const {
328 if (DeclOrVector.is<NamedDecl *>() || DeclOrVector.isNull())
329 return iterator();
330
331 return iterator(DeclOrVector.get<DeclIndexPairVector *>()->end());
332}
333
Douglas Gregor456c4a12009-09-21 20:12:40 +0000334/// \brief Compute the qualification required to get from the current context
335/// (\p CurContext) to the target context (\p TargetContext).
336///
337/// \param Context the AST context in which the qualification will be used.
338///
339/// \param CurContext the context where an entity is being named, which is
340/// typically based on the current scope.
341///
342/// \param TargetContext the context in which the named entity actually
343/// resides.
344///
345/// \returns a nested name specifier that refers into the target context, or
346/// NULL if no qualification is needed.
347static NestedNameSpecifier *
348getRequiredQualification(ASTContext &Context,
349 DeclContext *CurContext,
350 DeclContext *TargetContext) {
351 llvm::SmallVector<DeclContext *, 4> TargetParents;
352
353 for (DeclContext *CommonAncestor = TargetContext;
354 CommonAncestor && !CommonAncestor->Encloses(CurContext);
355 CommonAncestor = CommonAncestor->getLookupParent()) {
356 if (CommonAncestor->isTransparentContext() ||
357 CommonAncestor->isFunctionOrMethod())
358 continue;
359
360 TargetParents.push_back(CommonAncestor);
361 }
362
363 NestedNameSpecifier *Result = 0;
364 while (!TargetParents.empty()) {
365 DeclContext *Parent = TargetParents.back();
366 TargetParents.pop_back();
367
368 if (NamespaceDecl *Namespace = dyn_cast<NamespaceDecl>(Parent))
369 Result = NestedNameSpecifier::Create(Context, Result, Namespace);
370 else if (TagDecl *TD = dyn_cast<TagDecl>(Parent))
371 Result = NestedNameSpecifier::Create(Context, Result,
372 false,
373 Context.getTypeDeclType(TD).getTypePtr());
Douglas Gregor0c8296d2009-11-07 00:00:49 +0000374 }
Douglas Gregor456c4a12009-09-21 20:12:40 +0000375 return Result;
376}
377
Douglas Gregor45bcd432010-01-14 03:21:49 +0000378bool ResultBuilder::isInterestingDecl(NamedDecl *ND,
379 bool &AsNestedNameSpecifier) const {
380 AsNestedNameSpecifier = false;
381
Douglas Gregore495b7f2010-01-14 00:20:49 +0000382 ND = ND->getUnderlyingDecl();
383 unsigned IDNS = ND->getIdentifierNamespace();
Douglas Gregorf52cede2009-10-09 22:16:47 +0000384
385 // Skip unnamed entities.
Douglas Gregore495b7f2010-01-14 00:20:49 +0000386 if (!ND->getDeclName())
387 return false;
Douglas Gregor86d9a522009-09-21 16:56:56 +0000388
389 // Friend declarations and declarations introduced due to friends are never
390 // added as results.
John McCall92b7f702010-03-11 07:50:04 +0000391 if (IDNS & (Decl::IDNS_OrdinaryFriend | Decl::IDNS_TagFriend))
Douglas Gregore495b7f2010-01-14 00:20:49 +0000392 return false;
393
Douglas Gregor76282942009-12-11 17:31:05 +0000394 // Class template (partial) specializations are never added as results.
Douglas Gregore495b7f2010-01-14 00:20:49 +0000395 if (isa<ClassTemplateSpecializationDecl>(ND) ||
396 isa<ClassTemplatePartialSpecializationDecl>(ND))
397 return false;
Douglas Gregor86d9a522009-09-21 16:56:56 +0000398
Douglas Gregor76282942009-12-11 17:31:05 +0000399 // Using declarations themselves are never added as results.
Douglas Gregore495b7f2010-01-14 00:20:49 +0000400 if (isa<UsingDecl>(ND))
401 return false;
402
403 // Some declarations have reserved names that we don't want to ever show.
404 if (const IdentifierInfo *Id = ND->getIdentifier()) {
Douglas Gregor86d9a522009-09-21 16:56:56 +0000405 // __va_list_tag is a freak of nature. Find it and skip it.
406 if (Id->isStr("__va_list_tag") || Id->isStr("__builtin_va_list"))
Douglas Gregore495b7f2010-01-14 00:20:49 +0000407 return false;
Douglas Gregor86d9a522009-09-21 16:56:56 +0000408
Douglas Gregorf52cede2009-10-09 22:16:47 +0000409 // Filter out names reserved for the implementation (C99 7.1.3,
410 // C++ [lib.global.names]). Users don't need to see those.
Daniel Dunbare013d682009-10-18 20:26:12 +0000411 //
412 // FIXME: Add predicate for this.
Douglas Gregorf52cede2009-10-09 22:16:47 +0000413 if (Id->getLength() >= 2) {
Daniel Dunbare013d682009-10-18 20:26:12 +0000414 const char *Name = Id->getNameStart();
Douglas Gregorf52cede2009-10-09 22:16:47 +0000415 if (Name[0] == '_' &&
416 (Name[1] == '_' || (Name[1] >= 'A' && Name[1] <= 'Z')))
Douglas Gregore495b7f2010-01-14 00:20:49 +0000417 return false;
Douglas Gregorf52cede2009-10-09 22:16:47 +0000418 }
Douglas Gregor86d9a522009-09-21 16:56:56 +0000419 }
Douglas Gregore495b7f2010-01-14 00:20:49 +0000420
Douglas Gregor86d9a522009-09-21 16:56:56 +0000421 // C++ constructors are never found by name lookup.
Douglas Gregore495b7f2010-01-14 00:20:49 +0000422 if (isa<CXXConstructorDecl>(ND))
423 return false;
Douglas Gregor86d9a522009-09-21 16:56:56 +0000424
425 // Filter out any unwanted results.
Douglas Gregor45bcd432010-01-14 03:21:49 +0000426 if (Filter && !(this->*Filter)(ND)) {
427 // Check whether it is interesting as a nested-name-specifier.
428 if (AllowNestedNameSpecifiers && SemaRef.getLangOptions().CPlusPlus &&
429 IsNestedNameSpecifier(ND) &&
430 (Filter != &ResultBuilder::IsMember ||
431 (isa<CXXRecordDecl>(ND) &&
432 cast<CXXRecordDecl>(ND)->isInjectedClassName()))) {
433 AsNestedNameSpecifier = true;
434 return true;
435 }
436
Douglas Gregore495b7f2010-01-14 00:20:49 +0000437 return false;
Douglas Gregor45bcd432010-01-14 03:21:49 +0000438 }
John McCall0d6b1642010-04-23 18:46:30 +0000439
440 if (Filter == &ResultBuilder::IsNestedNameSpecifier)
441 AsNestedNameSpecifier = true;
Douglas Gregor86d9a522009-09-21 16:56:56 +0000442
Douglas Gregore495b7f2010-01-14 00:20:49 +0000443 // ... then it must be interesting!
444 return true;
445}
446
Douglas Gregor6660d842010-01-14 00:41:07 +0000447bool ResultBuilder::CheckHiddenResult(Result &R, DeclContext *CurContext,
448 NamedDecl *Hiding) {
449 // In C, there is no way to refer to a hidden name.
450 // FIXME: This isn't true; we can find a tag name hidden by an ordinary
451 // name if we introduce the tag type.
452 if (!SemaRef.getLangOptions().CPlusPlus)
453 return true;
454
455 DeclContext *HiddenCtx = R.Declaration->getDeclContext()->getLookupContext();
456
457 // There is no way to qualify a name declared in a function or method.
458 if (HiddenCtx->isFunctionOrMethod())
459 return true;
460
461 if (HiddenCtx == Hiding->getDeclContext()->getLookupContext())
462 return true;
463
464 // We can refer to the result with the appropriate qualification. Do it.
465 R.Hidden = true;
466 R.QualifierIsInformative = false;
467
468 if (!R.Qualifier)
469 R.Qualifier = getRequiredQualification(SemaRef.Context,
470 CurContext,
471 R.Declaration->getDeclContext());
472 return false;
473}
474
Douglas Gregor1f5537a2010-07-08 23:20:03 +0000475enum SimplifiedTypeClass {
476 STC_Arithmetic,
477 STC_Array,
478 STC_Block,
479 STC_Function,
480 STC_ObjectiveC,
481 STC_Other,
482 STC_Pointer,
483 STC_Record,
484 STC_Void
485};
486
487/// \brief A simplified classification of types used to determine whether two
488/// types are "similar enough" when adjusting priorities.
489static SimplifiedTypeClass getSimplifiedTypeClass(CanQualType T) {
490 switch (T->getTypeClass()) {
491 case Type::Builtin:
492 switch (cast<BuiltinType>(T)->getKind()) {
493 case BuiltinType::Void:
494 return STC_Void;
495
496 case BuiltinType::NullPtr:
497 return STC_Pointer;
498
499 case BuiltinType::Overload:
500 case BuiltinType::Dependent:
501 case BuiltinType::UndeducedAuto:
502 return STC_Other;
503
504 case BuiltinType::ObjCId:
505 case BuiltinType::ObjCClass:
506 case BuiltinType::ObjCSel:
507 return STC_ObjectiveC;
508
509 default:
510 return STC_Arithmetic;
511 }
512 return STC_Other;
513
514 case Type::Complex:
515 return STC_Arithmetic;
516
517 case Type::Pointer:
518 return STC_Pointer;
519
520 case Type::BlockPointer:
521 return STC_Block;
522
523 case Type::LValueReference:
524 case Type::RValueReference:
525 return getSimplifiedTypeClass(T->getAs<ReferenceType>()->getPointeeType());
526
527 case Type::ConstantArray:
528 case Type::IncompleteArray:
529 case Type::VariableArray:
530 case Type::DependentSizedArray:
531 return STC_Array;
532
533 case Type::DependentSizedExtVector:
534 case Type::Vector:
535 case Type::ExtVector:
536 return STC_Arithmetic;
537
538 case Type::FunctionProto:
539 case Type::FunctionNoProto:
540 return STC_Function;
541
542 case Type::Record:
543 return STC_Record;
544
545 case Type::Enum:
546 return STC_Arithmetic;
547
548 case Type::ObjCObject:
549 case Type::ObjCInterface:
550 case Type::ObjCObjectPointer:
551 return STC_ObjectiveC;
552
553 default:
554 return STC_Other;
555 }
556}
557
558/// \brief Get the type that a given expression will have if this declaration
559/// is used as an expression in its "typical" code-completion form.
560static QualType getDeclUsageType(ASTContext &C, NamedDecl *ND) {
561 ND = cast<NamedDecl>(ND->getUnderlyingDecl());
562
563 if (TypeDecl *Type = dyn_cast<TypeDecl>(ND))
564 return C.getTypeDeclType(Type);
565 if (ObjCInterfaceDecl *Iface = dyn_cast<ObjCInterfaceDecl>(ND))
566 return C.getObjCInterfaceType(Iface);
567
568 QualType T;
569 if (FunctionDecl *Function = dyn_cast<FunctionDecl>(ND))
570 T = Function->getResultType();
571 else if (ObjCMethodDecl *Method = dyn_cast<ObjCMethodDecl>(ND))
572 T = Method->getResultType();
573 else if (FunctionTemplateDecl *FunTmpl = dyn_cast<FunctionTemplateDecl>(ND))
574 T = FunTmpl->getTemplatedDecl()->getResultType();
575 else if (EnumConstantDecl *Enumerator = dyn_cast<EnumConstantDecl>(ND))
576 T = C.getTypeDeclType(cast<EnumDecl>(Enumerator->getDeclContext()));
577 else if (ObjCPropertyDecl *Property = dyn_cast<ObjCPropertyDecl>(ND))
578 T = Property->getType();
579 else if (ValueDecl *Value = dyn_cast<ValueDecl>(ND))
580 T = Value->getType();
581 else
582 return QualType();
583
584 return T.getNonReferenceType();
585}
586
587void ResultBuilder::AdjustResultPriorityForPreferredType(Result &R) {
588 QualType T = getDeclUsageType(SemaRef.Context, R.Declaration);
589 if (T.isNull())
590 return;
591
592 CanQualType TC = SemaRef.Context.getCanonicalType(T);
593 // Check for exactly-matching types (modulo qualifiers).
594 if (SemaRef.Context.hasSameUnqualifiedType(PreferredType, TC))
595 R.Priority /= CCF_ExactTypeMatch;
596 // Check for nearly-matching types, based on classification of each.
597 else if ((getSimplifiedTypeClass(PreferredType)
598 == getSimplifiedTypeClass(TC)) &&
599 !(PreferredType->isEnumeralType() && TC->isEnumeralType()))
600 R.Priority /= CCF_SimilarTypeMatch;
601}
602
Douglas Gregore495b7f2010-01-14 00:20:49 +0000603void ResultBuilder::MaybeAddResult(Result R, DeclContext *CurContext) {
604 assert(!ShadowMaps.empty() && "Must enter into a results scope");
605
606 if (R.Kind != Result::RK_Declaration) {
607 // For non-declaration results, just add the result.
608 Results.push_back(R);
609 return;
610 }
611
612 // Look through using declarations.
613 if (UsingShadowDecl *Using = dyn_cast<UsingShadowDecl>(R.Declaration)) {
614 MaybeAddResult(Result(Using->getTargetDecl(), R.Qualifier), CurContext);
615 return;
616 }
617
618 Decl *CanonDecl = R.Declaration->getCanonicalDecl();
619 unsigned IDNS = CanonDecl->getIdentifierNamespace();
620
Douglas Gregor45bcd432010-01-14 03:21:49 +0000621 bool AsNestedNameSpecifier = false;
622 if (!isInterestingDecl(R.Declaration, AsNestedNameSpecifier))
Douglas Gregore495b7f2010-01-14 00:20:49 +0000623 return;
624
Douglas Gregor86d9a522009-09-21 16:56:56 +0000625 ShadowMap &SMap = ShadowMaps.back();
Douglas Gregorfbcb5d62009-12-06 20:23:50 +0000626 ShadowMapEntry::iterator I, IEnd;
627 ShadowMap::iterator NamePos = SMap.find(R.Declaration->getDeclName());
628 if (NamePos != SMap.end()) {
629 I = NamePos->second.begin();
630 IEnd = NamePos->second.end();
631 }
632
633 for (; I != IEnd; ++I) {
634 NamedDecl *ND = I->first;
635 unsigned Index = I->second;
Douglas Gregor86d9a522009-09-21 16:56:56 +0000636 if (ND->getCanonicalDecl() == CanonDecl) {
637 // This is a redeclaration. Always pick the newer declaration.
Douglas Gregor86d9a522009-09-21 16:56:56 +0000638 Results[Index].Declaration = R.Declaration;
639
Douglas Gregor86d9a522009-09-21 16:56:56 +0000640 // We're done.
641 return;
642 }
643 }
644
645 // This is a new declaration in this scope. However, check whether this
646 // declaration name is hidden by a similarly-named declaration in an outer
647 // scope.
648 std::list<ShadowMap>::iterator SM, SMEnd = ShadowMaps.end();
649 --SMEnd;
650 for (SM = ShadowMaps.begin(); SM != SMEnd; ++SM) {
Douglas Gregorfbcb5d62009-12-06 20:23:50 +0000651 ShadowMapEntry::iterator I, IEnd;
652 ShadowMap::iterator NamePos = SM->find(R.Declaration->getDeclName());
653 if (NamePos != SM->end()) {
654 I = NamePos->second.begin();
655 IEnd = NamePos->second.end();
656 }
657 for (; I != IEnd; ++I) {
Douglas Gregor86d9a522009-09-21 16:56:56 +0000658 // A tag declaration does not hide a non-tag declaration.
John McCall0d6b1642010-04-23 18:46:30 +0000659 if (I->first->hasTagIdentifierNamespace() &&
Douglas Gregor86d9a522009-09-21 16:56:56 +0000660 (IDNS & (Decl::IDNS_Member | Decl::IDNS_Ordinary |
661 Decl::IDNS_ObjCProtocol)))
662 continue;
663
664 // Protocols are in distinct namespaces from everything else.
Douglas Gregorfbcb5d62009-12-06 20:23:50 +0000665 if (((I->first->getIdentifierNamespace() & Decl::IDNS_ObjCProtocol)
Douglas Gregor86d9a522009-09-21 16:56:56 +0000666 || (IDNS & Decl::IDNS_ObjCProtocol)) &&
Douglas Gregorfbcb5d62009-12-06 20:23:50 +0000667 I->first->getIdentifierNamespace() != IDNS)
Douglas Gregor86d9a522009-09-21 16:56:56 +0000668 continue;
669
670 // The newly-added result is hidden by an entry in the shadow map.
Douglas Gregor6660d842010-01-14 00:41:07 +0000671 if (CheckHiddenResult(R, CurContext, I->first))
Douglas Gregor86d9a522009-09-21 16:56:56 +0000672 return;
Douglas Gregor86d9a522009-09-21 16:56:56 +0000673
674 break;
675 }
676 }
677
678 // Make sure that any given declaration only shows up in the result set once.
679 if (!AllDeclsFound.insert(CanonDecl))
680 return;
681
Douglas Gregoreb5758b2009-09-23 22:26:46 +0000682 // If the filter is for nested-name-specifiers, then this result starts a
683 // nested-name-specifier.
Douglas Gregor12e13132010-05-26 22:00:08 +0000684 if (AsNestedNameSpecifier) {
Douglas Gregoreb5758b2009-09-23 22:26:46 +0000685 R.StartsNestedNameSpecifier = true;
Douglas Gregor12e13132010-05-26 22:00:08 +0000686 R.Priority = CCP_NestedNameSpecifier;
Douglas Gregor1f5537a2010-07-08 23:20:03 +0000687 } else if (!PreferredType.isNull())
688 AdjustResultPriorityForPreferredType(R);
689
Douglas Gregor0563c262009-09-22 23:15:58 +0000690 // If this result is supposed to have an informative qualifier, add one.
Douglas Gregoreb5758b2009-09-23 22:26:46 +0000691 if (R.QualifierIsInformative && !R.Qualifier &&
692 !R.StartsNestedNameSpecifier) {
Douglas Gregor0563c262009-09-22 23:15:58 +0000693 DeclContext *Ctx = R.Declaration->getDeclContext();
694 if (NamespaceDecl *Namespace = dyn_cast<NamespaceDecl>(Ctx))
695 R.Qualifier = NestedNameSpecifier::Create(SemaRef.Context, 0, Namespace);
696 else if (TagDecl *Tag = dyn_cast<TagDecl>(Ctx))
697 R.Qualifier = NestedNameSpecifier::Create(SemaRef.Context, 0, false,
698 SemaRef.Context.getTypeDeclType(Tag).getTypePtr());
699 else
700 R.QualifierIsInformative = false;
701 }
Douglas Gregoreb5758b2009-09-23 22:26:46 +0000702
Douglas Gregor86d9a522009-09-21 16:56:56 +0000703 // Insert this result into the set of results and into the current shadow
704 // map.
Douglas Gregorfbcb5d62009-12-06 20:23:50 +0000705 SMap[R.Declaration->getDeclName()].Add(R.Declaration, Results.size());
Douglas Gregor86d9a522009-09-21 16:56:56 +0000706 Results.push_back(R);
707}
708
Douglas Gregor1ca6ae82010-01-14 01:09:38 +0000709void ResultBuilder::AddResult(Result R, DeclContext *CurContext,
Douglas Gregor0cc84042010-01-14 15:47:35 +0000710 NamedDecl *Hiding, bool InBaseClass = false) {
Douglas Gregora4477812010-01-14 16:01:26 +0000711 if (R.Kind != Result::RK_Declaration) {
712 // For non-declaration results, just add the result.
713 Results.push_back(R);
714 return;
715 }
716
Douglas Gregor1ca6ae82010-01-14 01:09:38 +0000717 // Look through using declarations.
718 if (UsingShadowDecl *Using = dyn_cast<UsingShadowDecl>(R.Declaration)) {
719 AddResult(Result(Using->getTargetDecl(), R.Qualifier), CurContext, Hiding);
720 return;
721 }
722
Douglas Gregor45bcd432010-01-14 03:21:49 +0000723 bool AsNestedNameSpecifier = false;
724 if (!isInterestingDecl(R.Declaration, AsNestedNameSpecifier))
Douglas Gregor1ca6ae82010-01-14 01:09:38 +0000725 return;
726
727 if (Hiding && CheckHiddenResult(R, CurContext, Hiding))
728 return;
729
730 // Make sure that any given declaration only shows up in the result set once.
731 if (!AllDeclsFound.insert(R.Declaration->getCanonicalDecl()))
732 return;
733
734 // If the filter is for nested-name-specifiers, then this result starts a
735 // nested-name-specifier.
Douglas Gregor12e13132010-05-26 22:00:08 +0000736 if (AsNestedNameSpecifier) {
Douglas Gregor1ca6ae82010-01-14 01:09:38 +0000737 R.StartsNestedNameSpecifier = true;
Douglas Gregor12e13132010-05-26 22:00:08 +0000738 R.Priority = CCP_NestedNameSpecifier;
739 }
Douglas Gregor0cc84042010-01-14 15:47:35 +0000740 else if (Filter == &ResultBuilder::IsMember && !R.Qualifier && InBaseClass &&
741 isa<CXXRecordDecl>(R.Declaration->getDeclContext()
742 ->getLookupContext()))
743 R.QualifierIsInformative = true;
744
Douglas Gregor1ca6ae82010-01-14 01:09:38 +0000745 // If this result is supposed to have an informative qualifier, add one.
746 if (R.QualifierIsInformative && !R.Qualifier &&
747 !R.StartsNestedNameSpecifier) {
748 DeclContext *Ctx = R.Declaration->getDeclContext();
749 if (NamespaceDecl *Namespace = dyn_cast<NamespaceDecl>(Ctx))
750 R.Qualifier = NestedNameSpecifier::Create(SemaRef.Context, 0, Namespace);
751 else if (TagDecl *Tag = dyn_cast<TagDecl>(Ctx))
752 R.Qualifier = NestedNameSpecifier::Create(SemaRef.Context, 0, false,
Douglas Gregor45bcd432010-01-14 03:21:49 +0000753 SemaRef.Context.getTypeDeclType(Tag).getTypePtr());
Douglas Gregor1ca6ae82010-01-14 01:09:38 +0000754 else
755 R.QualifierIsInformative = false;
756 }
757
Douglas Gregor12e13132010-05-26 22:00:08 +0000758 // Adjust the priority if this result comes from a base class.
759 if (InBaseClass)
760 R.Priority += CCD_InBaseClass;
761
Douglas Gregor1f5537a2010-07-08 23:20:03 +0000762 if (!PreferredType.isNull())
763 AdjustResultPriorityForPreferredType(R);
Douglas Gregor5ac3bdb2010-05-30 01:49:25 +0000764
Douglas Gregor1ca6ae82010-01-14 01:09:38 +0000765 // Insert this result into the set of results.
766 Results.push_back(R);
767}
768
Douglas Gregora4477812010-01-14 16:01:26 +0000769void ResultBuilder::AddResult(Result R) {
770 assert(R.Kind != Result::RK_Declaration &&
771 "Declaration results need more context");
772 Results.push_back(R);
773}
774
Douglas Gregor86d9a522009-09-21 16:56:56 +0000775/// \brief Enter into a new scope.
776void ResultBuilder::EnterNewScope() {
777 ShadowMaps.push_back(ShadowMap());
778}
779
780/// \brief Exit from the current scope.
781void ResultBuilder::ExitScope() {
Douglas Gregorfbcb5d62009-12-06 20:23:50 +0000782 for (ShadowMap::iterator E = ShadowMaps.back().begin(),
783 EEnd = ShadowMaps.back().end();
784 E != EEnd;
785 ++E)
786 E->second.Destroy();
787
Douglas Gregor86d9a522009-09-21 16:56:56 +0000788 ShadowMaps.pop_back();
789}
790
Douglas Gregor791215b2009-09-21 20:51:25 +0000791/// \brief Determines whether this given declaration will be found by
792/// ordinary name lookup.
793bool ResultBuilder::IsOrdinaryName(NamedDecl *ND) const {
Douglas Gregor4710e5b2010-05-28 00:49:12 +0000794 ND = cast<NamedDecl>(ND->getUnderlyingDecl());
795
Douglas Gregor791215b2009-09-21 20:51:25 +0000796 unsigned IDNS = Decl::IDNS_Ordinary;
797 if (SemaRef.getLangOptions().CPlusPlus)
Douglas Gregor9b30b262010-06-15 20:26:51 +0000798 IDNS |= Decl::IDNS_Tag | Decl::IDNS_Namespace | Decl::IDNS_Member;
Douglas Gregor1ca6ae82010-01-14 01:09:38 +0000799 else if (SemaRef.getLangOptions().ObjC1 && isa<ObjCIvarDecl>(ND))
800 return true;
801
Douglas Gregor791215b2009-09-21 20:51:25 +0000802 return ND->getIdentifierNamespace() & IDNS;
803}
804
Douglas Gregor01dfea02010-01-10 23:08:15 +0000805/// \brief Determines whether this given declaration will be found by
Douglas Gregor4710e5b2010-05-28 00:49:12 +0000806/// ordinary name lookup but is not a type name.
807bool ResultBuilder::IsOrdinaryNonTypeName(NamedDecl *ND) const {
808 ND = cast<NamedDecl>(ND->getUnderlyingDecl());
809 if (isa<TypeDecl>(ND) || isa<ObjCInterfaceDecl>(ND))
810 return false;
811
812 unsigned IDNS = Decl::IDNS_Ordinary;
813 if (SemaRef.getLangOptions().CPlusPlus)
Douglas Gregor9b30b262010-06-15 20:26:51 +0000814 IDNS |= Decl::IDNS_Tag | Decl::IDNS_Namespace | Decl::IDNS_Member;
Douglas Gregor4710e5b2010-05-28 00:49:12 +0000815 else if (SemaRef.getLangOptions().ObjC1 && isa<ObjCIvarDecl>(ND))
816 return true;
817
818 return ND->getIdentifierNamespace() & IDNS;
819}
820
821/// \brief Determines whether this given declaration will be found by
Douglas Gregor01dfea02010-01-10 23:08:15 +0000822/// ordinary name lookup.
823bool ResultBuilder::IsOrdinaryNonValueName(NamedDecl *ND) const {
Douglas Gregor4710e5b2010-05-28 00:49:12 +0000824 ND = cast<NamedDecl>(ND->getUnderlyingDecl());
825
Douglas Gregor01dfea02010-01-10 23:08:15 +0000826 unsigned IDNS = Decl::IDNS_Ordinary;
827 if (SemaRef.getLangOptions().CPlusPlus)
John McCall0d6b1642010-04-23 18:46:30 +0000828 IDNS |= Decl::IDNS_Tag | Decl::IDNS_Namespace;
Douglas Gregor01dfea02010-01-10 23:08:15 +0000829
830 return (ND->getIdentifierNamespace() & IDNS) &&
Douglas Gregor4710e5b2010-05-28 00:49:12 +0000831 !isa<ValueDecl>(ND) && !isa<FunctionTemplateDecl>(ND) &&
832 !isa<ObjCPropertyDecl>(ND);
Douglas Gregor01dfea02010-01-10 23:08:15 +0000833}
834
Douglas Gregor86d9a522009-09-21 16:56:56 +0000835/// \brief Determines whether the given declaration is suitable as the
836/// start of a C++ nested-name-specifier, e.g., a class or namespace.
837bool ResultBuilder::IsNestedNameSpecifier(NamedDecl *ND) const {
838 // Allow us to find class templates, too.
839 if (ClassTemplateDecl *ClassTemplate = dyn_cast<ClassTemplateDecl>(ND))
840 ND = ClassTemplate->getTemplatedDecl();
841
842 return SemaRef.isAcceptableNestedNameSpecifier(ND);
843}
844
845/// \brief Determines whether the given declaration is an enumeration.
846bool ResultBuilder::IsEnum(NamedDecl *ND) const {
847 return isa<EnumDecl>(ND);
848}
849
850/// \brief Determines whether the given declaration is a class or struct.
851bool ResultBuilder::IsClassOrStruct(NamedDecl *ND) const {
852 // Allow us to find class templates, too.
853 if (ClassTemplateDecl *ClassTemplate = dyn_cast<ClassTemplateDecl>(ND))
854 ND = ClassTemplate->getTemplatedDecl();
855
856 if (RecordDecl *RD = dyn_cast<RecordDecl>(ND))
Abramo Bagnara465d41b2010-05-11 21:36:43 +0000857 return RD->getTagKind() == TTK_Class ||
858 RD->getTagKind() == TTK_Struct;
Douglas Gregor86d9a522009-09-21 16:56:56 +0000859
860 return false;
861}
862
863/// \brief Determines whether the given declaration is a union.
864bool ResultBuilder::IsUnion(NamedDecl *ND) const {
865 // Allow us to find class templates, too.
866 if (ClassTemplateDecl *ClassTemplate = dyn_cast<ClassTemplateDecl>(ND))
867 ND = ClassTemplate->getTemplatedDecl();
868
869 if (RecordDecl *RD = dyn_cast<RecordDecl>(ND))
Abramo Bagnara465d41b2010-05-11 21:36:43 +0000870 return RD->getTagKind() == TTK_Union;
Douglas Gregor86d9a522009-09-21 16:56:56 +0000871
872 return false;
873}
874
875/// \brief Determines whether the given declaration is a namespace.
876bool ResultBuilder::IsNamespace(NamedDecl *ND) const {
877 return isa<NamespaceDecl>(ND);
878}
879
880/// \brief Determines whether the given declaration is a namespace or
881/// namespace alias.
882bool ResultBuilder::IsNamespaceOrAlias(NamedDecl *ND) const {
883 return isa<NamespaceDecl>(ND) || isa<NamespaceAliasDecl>(ND);
884}
885
Douglas Gregor76282942009-12-11 17:31:05 +0000886/// \brief Determines whether the given declaration is a type.
Douglas Gregor86d9a522009-09-21 16:56:56 +0000887bool ResultBuilder::IsType(NamedDecl *ND) const {
888 return isa<TypeDecl>(ND);
889}
890
Douglas Gregor76282942009-12-11 17:31:05 +0000891/// \brief Determines which members of a class should be visible via
892/// "." or "->". Only value declarations, nested name specifiers, and
893/// using declarations thereof should show up.
Douglas Gregoreb5758b2009-09-23 22:26:46 +0000894bool ResultBuilder::IsMember(NamedDecl *ND) const {
Douglas Gregor76282942009-12-11 17:31:05 +0000895 if (UsingShadowDecl *Using = dyn_cast<UsingShadowDecl>(ND))
896 ND = Using->getTargetDecl();
897
Douglas Gregorce821962009-12-11 18:14:22 +0000898 return isa<ValueDecl>(ND) || isa<FunctionTemplateDecl>(ND) ||
899 isa<ObjCPropertyDecl>(ND);
Douglas Gregoreb5758b2009-09-23 22:26:46 +0000900}
901
Douglas Gregor8e254cf2010-05-27 23:06:34 +0000902static bool isObjCReceiverType(ASTContext &C, QualType T) {
903 T = C.getCanonicalType(T);
904 switch (T->getTypeClass()) {
905 case Type::ObjCObject:
906 case Type::ObjCInterface:
907 case Type::ObjCObjectPointer:
908 return true;
909
910 case Type::Builtin:
911 switch (cast<BuiltinType>(T)->getKind()) {
912 case BuiltinType::ObjCId:
913 case BuiltinType::ObjCClass:
914 case BuiltinType::ObjCSel:
915 return true;
916
917 default:
918 break;
919 }
920 return false;
921
922 default:
923 break;
924 }
925
926 if (!C.getLangOptions().CPlusPlus)
927 return false;
928
929 // FIXME: We could perform more analysis here to determine whether a
930 // particular class type has any conversions to Objective-C types. For now,
931 // just accept all class types.
932 return T->isDependentType() || T->isRecordType();
933}
934
935bool ResultBuilder::IsObjCMessageReceiver(NamedDecl *ND) const {
936 QualType T = getDeclUsageType(SemaRef.Context, ND);
937 if (T.isNull())
938 return false;
939
940 T = SemaRef.Context.getBaseElementType(T);
941 return isObjCReceiverType(SemaRef.Context, T);
942}
943
944
Douglas Gregor80f4f4c2010-01-14 16:08:12 +0000945/// \rief Determines whether the given declaration is an Objective-C
946/// instance variable.
947bool ResultBuilder::IsObjCIvar(NamedDecl *ND) const {
948 return isa<ObjCIvarDecl>(ND);
949}
950
Douglas Gregor1ca6ae82010-01-14 01:09:38 +0000951namespace {
952 /// \brief Visible declaration consumer that adds a code-completion result
953 /// for each visible declaration.
954 class CodeCompletionDeclConsumer : public VisibleDeclConsumer {
955 ResultBuilder &Results;
956 DeclContext *CurContext;
957
958 public:
959 CodeCompletionDeclConsumer(ResultBuilder &Results, DeclContext *CurContext)
960 : Results(Results), CurContext(CurContext) { }
961
Douglas Gregor0cc84042010-01-14 15:47:35 +0000962 virtual void FoundDecl(NamedDecl *ND, NamedDecl *Hiding, bool InBaseClass) {
963 Results.AddResult(ND, CurContext, Hiding, InBaseClass);
Douglas Gregor1ca6ae82010-01-14 01:09:38 +0000964 }
965 };
966}
967
Douglas Gregor86d9a522009-09-21 16:56:56 +0000968/// \brief Add type specifiers for the current language as keyword results.
Douglas Gregorbca403c2010-01-13 23:51:12 +0000969static void AddTypeSpecifierResults(const LangOptions &LangOpts,
Douglas Gregor86d9a522009-09-21 16:56:56 +0000970 ResultBuilder &Results) {
971 typedef CodeCompleteConsumer::Result Result;
Douglas Gregor12e13132010-05-26 22:00:08 +0000972 Results.AddResult(Result("short", CCP_Type));
973 Results.AddResult(Result("long", CCP_Type));
974 Results.AddResult(Result("signed", CCP_Type));
975 Results.AddResult(Result("unsigned", CCP_Type));
976 Results.AddResult(Result("void", CCP_Type));
977 Results.AddResult(Result("char", CCP_Type));
978 Results.AddResult(Result("int", CCP_Type));
979 Results.AddResult(Result("float", CCP_Type));
980 Results.AddResult(Result("double", CCP_Type));
981 Results.AddResult(Result("enum", CCP_Type));
982 Results.AddResult(Result("struct", CCP_Type));
983 Results.AddResult(Result("union", CCP_Type));
984 Results.AddResult(Result("const", CCP_Type));
985 Results.AddResult(Result("volatile", CCP_Type));
Douglas Gregor01dfea02010-01-10 23:08:15 +0000986
Douglas Gregor86d9a522009-09-21 16:56:56 +0000987 if (LangOpts.C99) {
988 // C99-specific
Douglas Gregor12e13132010-05-26 22:00:08 +0000989 Results.AddResult(Result("_Complex", CCP_Type));
990 Results.AddResult(Result("_Imaginary", CCP_Type));
991 Results.AddResult(Result("_Bool", CCP_Type));
992 Results.AddResult(Result("restrict", CCP_Type));
Douglas Gregor86d9a522009-09-21 16:56:56 +0000993 }
994
995 if (LangOpts.CPlusPlus) {
996 // C++-specific
Douglas Gregor12e13132010-05-26 22:00:08 +0000997 Results.AddResult(Result("bool", CCP_Type));
998 Results.AddResult(Result("class", CCP_Type));
999 Results.AddResult(Result("wchar_t", CCP_Type));
Douglas Gregor86d9a522009-09-21 16:56:56 +00001000
Douglas Gregorc8bddde2010-05-28 00:22:41 +00001001 // typename qualified-id
1002 CodeCompletionString *Pattern = new CodeCompletionString;
1003 Pattern->AddTypedTextChunk("typename");
1004 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
1005 Pattern->AddPlaceholderChunk("qualifier");
1006 Pattern->AddTextChunk("::");
1007 Pattern->AddPlaceholderChunk("name");
1008 Results.AddResult(Result(Pattern));
Douglas Gregord8e8a582010-05-25 21:41:55 +00001009
Douglas Gregor86d9a522009-09-21 16:56:56 +00001010 if (LangOpts.CPlusPlus0x) {
Douglas Gregor12e13132010-05-26 22:00:08 +00001011 Results.AddResult(Result("auto", CCP_Type));
1012 Results.AddResult(Result("char16_t", CCP_Type));
1013 Results.AddResult(Result("char32_t", CCP_Type));
Douglas Gregorc8bddde2010-05-28 00:22:41 +00001014
1015 CodeCompletionString *Pattern = new CodeCompletionString;
1016 Pattern->AddTypedTextChunk("decltype");
1017 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
1018 Pattern->AddPlaceholderChunk("expression");
1019 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
1020 Results.AddResult(Result(Pattern));
Douglas Gregor86d9a522009-09-21 16:56:56 +00001021 }
1022 }
1023
1024 // GNU extensions
1025 if (LangOpts.GNUMode) {
1026 // FIXME: Enable when we actually support decimal floating point.
Douglas Gregora4477812010-01-14 16:01:26 +00001027 // Results.AddResult(Result("_Decimal32"));
1028 // Results.AddResult(Result("_Decimal64"));
1029 // Results.AddResult(Result("_Decimal128"));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001030
Douglas Gregorc8bddde2010-05-28 00:22:41 +00001031 CodeCompletionString *Pattern = new CodeCompletionString;
1032 Pattern->AddTypedTextChunk("typeof");
1033 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
1034 Pattern->AddPlaceholderChunk("expression");
1035 Results.AddResult(Result(Pattern));
1036
1037 Pattern = new CodeCompletionString;
1038 Pattern->AddTypedTextChunk("typeof");
1039 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
1040 Pattern->AddPlaceholderChunk("type");
1041 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
1042 Results.AddResult(Result(Pattern));
Douglas Gregor86d9a522009-09-21 16:56:56 +00001043 }
1044}
1045
Douglas Gregor01dfea02010-01-10 23:08:15 +00001046static void AddStorageSpecifiers(Action::CodeCompletionContext CCC,
1047 const LangOptions &LangOpts,
Douglas Gregor01dfea02010-01-10 23:08:15 +00001048 ResultBuilder &Results) {
1049 typedef CodeCompleteConsumer::Result Result;
1050 // Note: we don't suggest either "auto" or "register", because both
1051 // are pointless as storage specifiers. Elsewhere, we suggest "auto"
1052 // in C++0x as a type specifier.
Douglas Gregora4477812010-01-14 16:01:26 +00001053 Results.AddResult(Result("extern"));
1054 Results.AddResult(Result("static"));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001055}
1056
1057static void AddFunctionSpecifiers(Action::CodeCompletionContext CCC,
1058 const LangOptions &LangOpts,
Douglas Gregor01dfea02010-01-10 23:08:15 +00001059 ResultBuilder &Results) {
1060 typedef CodeCompleteConsumer::Result Result;
1061 switch (CCC) {
1062 case Action::CCC_Class:
1063 case Action::CCC_MemberTemplate:
1064 if (LangOpts.CPlusPlus) {
Douglas Gregora4477812010-01-14 16:01:26 +00001065 Results.AddResult(Result("explicit"));
1066 Results.AddResult(Result("friend"));
1067 Results.AddResult(Result("mutable"));
1068 Results.AddResult(Result("virtual"));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001069 }
1070 // Fall through
1071
Douglas Gregorb6ac2452010-01-13 21:24:21 +00001072 case Action::CCC_ObjCInterface:
1073 case Action::CCC_ObjCImplementation:
Douglas Gregor01dfea02010-01-10 23:08:15 +00001074 case Action::CCC_Namespace:
1075 case Action::CCC_Template:
1076 if (LangOpts.CPlusPlus || LangOpts.C99)
Douglas Gregora4477812010-01-14 16:01:26 +00001077 Results.AddResult(Result("inline"));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001078 break;
1079
Douglas Gregorc38c3e12010-01-13 21:54:15 +00001080 case Action::CCC_ObjCInstanceVariableList:
Douglas Gregor01dfea02010-01-10 23:08:15 +00001081 case Action::CCC_Expression:
1082 case Action::CCC_Statement:
1083 case Action::CCC_ForInit:
1084 case Action::CCC_Condition:
Douglas Gregordc845342010-05-25 05:58:43 +00001085 case Action::CCC_RecoveryInFunction:
Douglas Gregor01dfea02010-01-10 23:08:15 +00001086 break;
1087 }
1088}
1089
Douglas Gregorbca403c2010-01-13 23:51:12 +00001090static void AddObjCExpressionResults(ResultBuilder &Results, bool NeedAt);
1091static void AddObjCStatementResults(ResultBuilder &Results, bool NeedAt);
1092static void AddObjCVisibilityResults(const LangOptions &LangOpts,
Douglas Gregorc38c3e12010-01-13 21:54:15 +00001093 ResultBuilder &Results,
1094 bool NeedAt);
Douglas Gregorbca403c2010-01-13 23:51:12 +00001095static void AddObjCImplementationResults(const LangOptions &LangOpts,
Douglas Gregorb6ac2452010-01-13 21:24:21 +00001096 ResultBuilder &Results,
1097 bool NeedAt);
Douglas Gregorbca403c2010-01-13 23:51:12 +00001098static void AddObjCInterfaceResults(const LangOptions &LangOpts,
Douglas Gregorb6ac2452010-01-13 21:24:21 +00001099 ResultBuilder &Results,
1100 bool NeedAt);
Douglas Gregorbca403c2010-01-13 23:51:12 +00001101static void AddObjCTopLevelResults(ResultBuilder &Results, bool NeedAt);
Douglas Gregorb6ac2452010-01-13 21:24:21 +00001102
Douglas Gregorc8bddde2010-05-28 00:22:41 +00001103static void AddTypedefResult(ResultBuilder &Results) {
1104 CodeCompletionString *Pattern = new CodeCompletionString;
1105 Pattern->AddTypedTextChunk("typedef");
1106 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
1107 Pattern->AddPlaceholderChunk("type");
1108 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
1109 Pattern->AddPlaceholderChunk("name");
1110 Results.AddResult(CodeCompleteConsumer::Result(Pattern));
1111}
1112
Douglas Gregor4710e5b2010-05-28 00:49:12 +00001113static bool WantTypesInContext(Action::CodeCompletionContext CCC,
1114 const LangOptions &LangOpts) {
1115 if (LangOpts.CPlusPlus)
1116 return true;
1117
1118 switch (CCC) {
1119 case Action::CCC_Namespace:
1120 case Action::CCC_Class:
1121 case Action::CCC_ObjCInstanceVariableList:
1122 case Action::CCC_Template:
1123 case Action::CCC_MemberTemplate:
1124 case Action::CCC_Statement:
1125 case Action::CCC_RecoveryInFunction:
1126 return true;
1127
1128 case Action::CCC_ObjCInterface:
1129 case Action::CCC_ObjCImplementation:
1130 case Action::CCC_Expression:
1131 case Action::CCC_Condition:
1132 return false;
1133
1134 case Action::CCC_ForInit:
1135 return LangOpts.ObjC1 || LangOpts.C99;
1136 }
1137
1138 return false;
1139}
1140
Douglas Gregor01dfea02010-01-10 23:08:15 +00001141/// \brief Add language constructs that show up for "ordinary" names.
1142static void AddOrdinaryNameResults(Action::CodeCompletionContext CCC,
1143 Scope *S,
1144 Sema &SemaRef,
Douglas Gregor01dfea02010-01-10 23:08:15 +00001145 ResultBuilder &Results) {
1146 typedef CodeCompleteConsumer::Result Result;
1147 switch (CCC) {
1148 case Action::CCC_Namespace:
Douglas Gregorc8bddde2010-05-28 00:22:41 +00001149 if (SemaRef.getLangOptions().CPlusPlus) {
1150 CodeCompletionString *Pattern = 0;
1151
1152 if (Results.includeCodePatterns()) {
1153 // namespace <identifier> { declarations }
1154 CodeCompletionString *Pattern = new CodeCompletionString;
1155 Pattern->AddTypedTextChunk("namespace");
1156 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
1157 Pattern->AddPlaceholderChunk("identifier");
1158 Pattern->AddChunk(CodeCompletionString::CK_LeftBrace);
1159 Pattern->AddPlaceholderChunk("declarations");
1160 Pattern->AddChunk(CodeCompletionString::CK_VerticalSpace);
1161 Pattern->AddChunk(CodeCompletionString::CK_RightBrace);
1162 Results.AddResult(Result(Pattern));
1163 }
1164
Douglas Gregor01dfea02010-01-10 23:08:15 +00001165 // namespace identifier = identifier ;
1166 Pattern = new CodeCompletionString;
1167 Pattern->AddTypedTextChunk("namespace");
1168 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
Douglas Gregorc8bddde2010-05-28 00:22:41 +00001169 Pattern->AddPlaceholderChunk("name");
Douglas Gregor01dfea02010-01-10 23:08:15 +00001170 Pattern->AddChunk(CodeCompletionString::CK_Equal);
Douglas Gregorc8bddde2010-05-28 00:22:41 +00001171 Pattern->AddPlaceholderChunk("namespace");
Douglas Gregora4477812010-01-14 16:01:26 +00001172 Results.AddResult(Result(Pattern));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001173
1174 // Using directives
1175 Pattern = new CodeCompletionString;
1176 Pattern->AddTypedTextChunk("using");
1177 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
1178 Pattern->AddTextChunk("namespace");
1179 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
1180 Pattern->AddPlaceholderChunk("identifier");
Douglas Gregora4477812010-01-14 16:01:26 +00001181 Results.AddResult(Result(Pattern));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001182
1183 // asm(string-literal)
1184 Pattern = new CodeCompletionString;
1185 Pattern->AddTypedTextChunk("asm");
1186 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
1187 Pattern->AddPlaceholderChunk("string-literal");
1188 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
Douglas Gregora4477812010-01-14 16:01:26 +00001189 Results.AddResult(Result(Pattern));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001190
Douglas Gregorc8bddde2010-05-28 00:22:41 +00001191 if (Results.includeCodePatterns()) {
1192 // Explicit template instantiation
1193 Pattern = new CodeCompletionString;
1194 Pattern->AddTypedTextChunk("template");
1195 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
1196 Pattern->AddPlaceholderChunk("declaration");
1197 Results.AddResult(Result(Pattern));
1198 }
Douglas Gregor01dfea02010-01-10 23:08:15 +00001199 }
Douglas Gregorb6ac2452010-01-13 21:24:21 +00001200
1201 if (SemaRef.getLangOptions().ObjC1)
Douglas Gregorbca403c2010-01-13 23:51:12 +00001202 AddObjCTopLevelResults(Results, true);
Douglas Gregorb6ac2452010-01-13 21:24:21 +00001203
Douglas Gregorc8bddde2010-05-28 00:22:41 +00001204 AddTypedefResult(Results);
Douglas Gregor01dfea02010-01-10 23:08:15 +00001205 // Fall through
1206
1207 case Action::CCC_Class:
Douglas Gregorc8bddde2010-05-28 00:22:41 +00001208 if (SemaRef.getLangOptions().CPlusPlus) {
Douglas Gregor01dfea02010-01-10 23:08:15 +00001209 // Using declaration
1210 CodeCompletionString *Pattern = new CodeCompletionString;
1211 Pattern->AddTypedTextChunk("using");
1212 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
Douglas Gregorc8bddde2010-05-28 00:22:41 +00001213 Pattern->AddPlaceholderChunk("qualifier");
1214 Pattern->AddTextChunk("::");
1215 Pattern->AddPlaceholderChunk("name");
Douglas Gregora4477812010-01-14 16:01:26 +00001216 Results.AddResult(Result(Pattern));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001217
Douglas Gregorc8bddde2010-05-28 00:22:41 +00001218 // using typename qualifier::name (only in a dependent context)
Douglas Gregor01dfea02010-01-10 23:08:15 +00001219 if (SemaRef.CurContext->isDependentContext()) {
1220 Pattern = new CodeCompletionString;
1221 Pattern->AddTypedTextChunk("using");
1222 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
1223 Pattern->AddTextChunk("typename");
1224 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
Douglas Gregorc8bddde2010-05-28 00:22:41 +00001225 Pattern->AddPlaceholderChunk("qualifier");
1226 Pattern->AddTextChunk("::");
1227 Pattern->AddPlaceholderChunk("name");
Douglas Gregora4477812010-01-14 16:01:26 +00001228 Results.AddResult(Result(Pattern));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001229 }
1230
1231 if (CCC == Action::CCC_Class) {
Douglas Gregorc8bddde2010-05-28 00:22:41 +00001232 AddTypedefResult(Results);
1233
Douglas Gregor01dfea02010-01-10 23:08:15 +00001234 // public:
1235 Pattern = new CodeCompletionString;
1236 Pattern->AddTypedTextChunk("public");
1237 Pattern->AddChunk(CodeCompletionString::CK_Colon);
Douglas Gregora4477812010-01-14 16:01:26 +00001238 Results.AddResult(Result(Pattern));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001239
1240 // protected:
1241 Pattern = new CodeCompletionString;
1242 Pattern->AddTypedTextChunk("protected");
1243 Pattern->AddChunk(CodeCompletionString::CK_Colon);
Douglas Gregora4477812010-01-14 16:01:26 +00001244 Results.AddResult(Result(Pattern));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001245
1246 // private:
1247 Pattern = new CodeCompletionString;
1248 Pattern->AddTypedTextChunk("private");
1249 Pattern->AddChunk(CodeCompletionString::CK_Colon);
Douglas Gregora4477812010-01-14 16:01:26 +00001250 Results.AddResult(Result(Pattern));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001251 }
1252 }
1253 // Fall through
1254
1255 case Action::CCC_Template:
1256 case Action::CCC_MemberTemplate:
Douglas Gregord8e8a582010-05-25 21:41:55 +00001257 if (SemaRef.getLangOptions().CPlusPlus && Results.includeCodePatterns()) {
Douglas Gregor01dfea02010-01-10 23:08:15 +00001258 // template < parameters >
1259 CodeCompletionString *Pattern = new CodeCompletionString;
1260 Pattern->AddTypedTextChunk("template");
1261 Pattern->AddChunk(CodeCompletionString::CK_LeftAngle);
1262 Pattern->AddPlaceholderChunk("parameters");
1263 Pattern->AddChunk(CodeCompletionString::CK_RightAngle);
Douglas Gregora4477812010-01-14 16:01:26 +00001264 Results.AddResult(Result(Pattern));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001265 }
1266
Douglas Gregorbca403c2010-01-13 23:51:12 +00001267 AddStorageSpecifiers(CCC, SemaRef.getLangOptions(), Results);
1268 AddFunctionSpecifiers(CCC, SemaRef.getLangOptions(), Results);
Douglas Gregor01dfea02010-01-10 23:08:15 +00001269 break;
1270
Douglas Gregorb6ac2452010-01-13 21:24:21 +00001271 case Action::CCC_ObjCInterface:
Douglas Gregorbca403c2010-01-13 23:51:12 +00001272 AddObjCInterfaceResults(SemaRef.getLangOptions(), Results, true);
1273 AddStorageSpecifiers(CCC, SemaRef.getLangOptions(), Results);
1274 AddFunctionSpecifiers(CCC, SemaRef.getLangOptions(), Results);
Douglas Gregorb6ac2452010-01-13 21:24:21 +00001275 break;
1276
1277 case Action::CCC_ObjCImplementation:
Douglas Gregorbca403c2010-01-13 23:51:12 +00001278 AddObjCImplementationResults(SemaRef.getLangOptions(), Results, true);
1279 AddStorageSpecifiers(CCC, SemaRef.getLangOptions(), Results);
1280 AddFunctionSpecifiers(CCC, SemaRef.getLangOptions(), Results);
Douglas Gregorb6ac2452010-01-13 21:24:21 +00001281 break;
1282
Douglas Gregorc38c3e12010-01-13 21:54:15 +00001283 case Action::CCC_ObjCInstanceVariableList:
Douglas Gregorbca403c2010-01-13 23:51:12 +00001284 AddObjCVisibilityResults(SemaRef.getLangOptions(), Results, true);
Douglas Gregorc38c3e12010-01-13 21:54:15 +00001285 break;
1286
Douglas Gregordc845342010-05-25 05:58:43 +00001287 case Action::CCC_RecoveryInFunction:
Douglas Gregor01dfea02010-01-10 23:08:15 +00001288 case Action::CCC_Statement: {
Douglas Gregorc8bddde2010-05-28 00:22:41 +00001289 AddTypedefResult(Results);
Douglas Gregor01dfea02010-01-10 23:08:15 +00001290
1291 CodeCompletionString *Pattern = 0;
Douglas Gregord8e8a582010-05-25 21:41:55 +00001292 if (SemaRef.getLangOptions().CPlusPlus && Results.includeCodePatterns()) {
Douglas Gregor01dfea02010-01-10 23:08:15 +00001293 Pattern = new CodeCompletionString;
1294 Pattern->AddTypedTextChunk("try");
1295 Pattern->AddChunk(CodeCompletionString::CK_LeftBrace);
1296 Pattern->AddPlaceholderChunk("statements");
1297 Pattern->AddChunk(CodeCompletionString::CK_VerticalSpace);
1298 Pattern->AddChunk(CodeCompletionString::CK_RightBrace);
1299 Pattern->AddTextChunk("catch");
1300 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
1301 Pattern->AddPlaceholderChunk("declaration");
1302 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
1303 Pattern->AddChunk(CodeCompletionString::CK_LeftBrace);
1304 Pattern->AddPlaceholderChunk("statements");
1305 Pattern->AddChunk(CodeCompletionString::CK_VerticalSpace);
1306 Pattern->AddChunk(CodeCompletionString::CK_RightBrace);
Douglas Gregora4477812010-01-14 16:01:26 +00001307 Results.AddResult(Result(Pattern));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001308 }
Douglas Gregorb6ac2452010-01-13 21:24:21 +00001309 if (SemaRef.getLangOptions().ObjC1)
Douglas Gregorbca403c2010-01-13 23:51:12 +00001310 AddObjCStatementResults(Results, true);
Douglas Gregorb6ac2452010-01-13 21:24:21 +00001311
Douglas Gregord8e8a582010-05-25 21:41:55 +00001312 if (Results.includeCodePatterns()) {
1313 // if (condition) { statements }
1314 Pattern = new CodeCompletionString;
1315 Pattern->AddTypedTextChunk("if");
1316 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
1317 if (SemaRef.getLangOptions().CPlusPlus)
1318 Pattern->AddPlaceholderChunk("condition");
1319 else
1320 Pattern->AddPlaceholderChunk("expression");
1321 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
1322 Pattern->AddChunk(CodeCompletionString::CK_LeftBrace);
1323 Pattern->AddPlaceholderChunk("statements");
1324 Pattern->AddChunk(CodeCompletionString::CK_VerticalSpace);
1325 Pattern->AddChunk(CodeCompletionString::CK_RightBrace);
1326 Results.AddResult(Result(Pattern));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001327
Douglas Gregord8e8a582010-05-25 21:41:55 +00001328 // switch (condition) { }
1329 Pattern = new CodeCompletionString;
1330 Pattern->AddTypedTextChunk("switch");
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->AddChunk(CodeCompletionString::CK_VerticalSpace);
1339 Pattern->AddChunk(CodeCompletionString::CK_RightBrace);
1340 Results.AddResult(Result(Pattern));
1341 }
1342
Douglas Gregor01dfea02010-01-10 23:08:15 +00001343 // Switch-specific statements.
Douglas Gregorc8bddde2010-05-28 00:22:41 +00001344 if (!SemaRef.getSwitchStack().empty()) {
Douglas Gregor01dfea02010-01-10 23:08:15 +00001345 // case expression:
1346 Pattern = new CodeCompletionString;
1347 Pattern->AddTypedTextChunk("case");
Douglas Gregorc8bddde2010-05-28 00:22:41 +00001348 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
Douglas Gregor01dfea02010-01-10 23:08:15 +00001349 Pattern->AddPlaceholderChunk("expression");
1350 Pattern->AddChunk(CodeCompletionString::CK_Colon);
Douglas Gregora4477812010-01-14 16:01:26 +00001351 Results.AddResult(Result(Pattern));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001352
1353 // default:
1354 Pattern = new CodeCompletionString;
1355 Pattern->AddTypedTextChunk("default");
1356 Pattern->AddChunk(CodeCompletionString::CK_Colon);
Douglas Gregora4477812010-01-14 16:01:26 +00001357 Results.AddResult(Result(Pattern));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001358 }
1359
Douglas Gregord8e8a582010-05-25 21:41:55 +00001360 if (Results.includeCodePatterns()) {
1361 /// while (condition) { statements }
1362 Pattern = new CodeCompletionString;
1363 Pattern->AddTypedTextChunk("while");
1364 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
1365 if (SemaRef.getLangOptions().CPlusPlus)
1366 Pattern->AddPlaceholderChunk("condition");
1367 else
1368 Pattern->AddPlaceholderChunk("expression");
1369 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
1370 Pattern->AddChunk(CodeCompletionString::CK_LeftBrace);
1371 Pattern->AddPlaceholderChunk("statements");
1372 Pattern->AddChunk(CodeCompletionString::CK_VerticalSpace);
1373 Pattern->AddChunk(CodeCompletionString::CK_RightBrace);
1374 Results.AddResult(Result(Pattern));
1375
1376 // do { statements } while ( expression );
1377 Pattern = new CodeCompletionString;
1378 Pattern->AddTypedTextChunk("do");
1379 Pattern->AddChunk(CodeCompletionString::CK_LeftBrace);
1380 Pattern->AddPlaceholderChunk("statements");
1381 Pattern->AddChunk(CodeCompletionString::CK_VerticalSpace);
1382 Pattern->AddChunk(CodeCompletionString::CK_RightBrace);
1383 Pattern->AddTextChunk("while");
1384 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
Douglas Gregor01dfea02010-01-10 23:08:15 +00001385 Pattern->AddPlaceholderChunk("expression");
Douglas Gregord8e8a582010-05-25 21:41:55 +00001386 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
1387 Results.AddResult(Result(Pattern));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001388
Douglas Gregord8e8a582010-05-25 21:41:55 +00001389 // for ( for-init-statement ; condition ; expression ) { statements }
1390 Pattern = new CodeCompletionString;
1391 Pattern->AddTypedTextChunk("for");
1392 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
1393 if (SemaRef.getLangOptions().CPlusPlus || SemaRef.getLangOptions().C99)
1394 Pattern->AddPlaceholderChunk("init-statement");
1395 else
1396 Pattern->AddPlaceholderChunk("init-expression");
1397 Pattern->AddChunk(CodeCompletionString::CK_SemiColon);
1398 Pattern->AddPlaceholderChunk("condition");
1399 Pattern->AddChunk(CodeCompletionString::CK_SemiColon);
1400 Pattern->AddPlaceholderChunk("inc-expression");
1401 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
1402 Pattern->AddChunk(CodeCompletionString::CK_LeftBrace);
1403 Pattern->AddPlaceholderChunk("statements");
1404 Pattern->AddChunk(CodeCompletionString::CK_VerticalSpace);
1405 Pattern->AddChunk(CodeCompletionString::CK_RightBrace);
1406 Results.AddResult(Result(Pattern));
1407 }
Douglas Gregor01dfea02010-01-10 23:08:15 +00001408
1409 if (S->getContinueParent()) {
1410 // continue ;
1411 Pattern = new CodeCompletionString;
1412 Pattern->AddTypedTextChunk("continue");
Douglas Gregora4477812010-01-14 16:01:26 +00001413 Results.AddResult(Result(Pattern));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001414 }
1415
1416 if (S->getBreakParent()) {
1417 // break ;
1418 Pattern = new CodeCompletionString;
1419 Pattern->AddTypedTextChunk("break");
Douglas Gregora4477812010-01-14 16:01:26 +00001420 Results.AddResult(Result(Pattern));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001421 }
1422
1423 // "return expression ;" or "return ;", depending on whether we
1424 // know the function is void or not.
1425 bool isVoid = false;
1426 if (FunctionDecl *Function = dyn_cast<FunctionDecl>(SemaRef.CurContext))
1427 isVoid = Function->getResultType()->isVoidType();
1428 else if (ObjCMethodDecl *Method
1429 = dyn_cast<ObjCMethodDecl>(SemaRef.CurContext))
1430 isVoid = Method->getResultType()->isVoidType();
Douglas Gregor9ea9bdb2010-03-01 23:15:13 +00001431 else if (SemaRef.getCurBlock() &&
1432 !SemaRef.getCurBlock()->ReturnType.isNull())
1433 isVoid = SemaRef.getCurBlock()->ReturnType->isVoidType();
Douglas Gregor01dfea02010-01-10 23:08:15 +00001434 Pattern = new CodeCompletionString;
1435 Pattern->AddTypedTextChunk("return");
Douglas Gregor93298002010-02-18 04:06:48 +00001436 if (!isVoid) {
1437 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
Douglas Gregor01dfea02010-01-10 23:08:15 +00001438 Pattern->AddPlaceholderChunk("expression");
Douglas Gregor93298002010-02-18 04:06:48 +00001439 }
Douglas Gregora4477812010-01-14 16:01:26 +00001440 Results.AddResult(Result(Pattern));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001441
Douglas Gregorc8bddde2010-05-28 00:22:41 +00001442 // goto identifier ;
1443 Pattern = new CodeCompletionString;
1444 Pattern->AddTypedTextChunk("goto");
1445 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
1446 Pattern->AddPlaceholderChunk("label");
1447 Results.AddResult(Result(Pattern));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001448
Douglas Gregorc8bddde2010-05-28 00:22:41 +00001449 // Using directives
1450 Pattern = new CodeCompletionString;
1451 Pattern->AddTypedTextChunk("using");
1452 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
1453 Pattern->AddTextChunk("namespace");
1454 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
1455 Pattern->AddPlaceholderChunk("identifier");
1456 Results.AddResult(Result(Pattern));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001457 }
1458
1459 // Fall through (for statement expressions).
1460 case Action::CCC_ForInit:
1461 case Action::CCC_Condition:
Douglas Gregorbca403c2010-01-13 23:51:12 +00001462 AddStorageSpecifiers(CCC, SemaRef.getLangOptions(), Results);
Douglas Gregor01dfea02010-01-10 23:08:15 +00001463 // Fall through: conditions and statements can have expressions.
1464
1465 case Action::CCC_Expression: {
1466 CodeCompletionString *Pattern = 0;
1467 if (SemaRef.getLangOptions().CPlusPlus) {
1468 // 'this', if we're in a non-static member function.
1469 if (CXXMethodDecl *Method = dyn_cast<CXXMethodDecl>(SemaRef.CurContext))
1470 if (!Method->isStatic())
Douglas Gregora4477812010-01-14 16:01:26 +00001471 Results.AddResult(Result("this"));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001472
1473 // true, false
Douglas Gregora4477812010-01-14 16:01:26 +00001474 Results.AddResult(Result("true"));
1475 Results.AddResult(Result("false"));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001476
Douglas Gregorc8bddde2010-05-28 00:22:41 +00001477 // dynamic_cast < type-id > ( expression )
1478 Pattern = new CodeCompletionString;
1479 Pattern->AddTypedTextChunk("dynamic_cast");
1480 Pattern->AddChunk(CodeCompletionString::CK_LeftAngle);
1481 Pattern->AddPlaceholderChunk("type");
1482 Pattern->AddChunk(CodeCompletionString::CK_RightAngle);
1483 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
1484 Pattern->AddPlaceholderChunk("expression");
1485 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
1486 Results.AddResult(Result(Pattern));
1487
1488 // static_cast < type-id > ( expression )
1489 Pattern = new CodeCompletionString;
1490 Pattern->AddTypedTextChunk("static_cast");
1491 Pattern->AddChunk(CodeCompletionString::CK_LeftAngle);
1492 Pattern->AddPlaceholderChunk("type");
1493 Pattern->AddChunk(CodeCompletionString::CK_RightAngle);
1494 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
1495 Pattern->AddPlaceholderChunk("expression");
1496 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
1497 Results.AddResult(Result(Pattern));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001498
Douglas Gregorc8bddde2010-05-28 00:22:41 +00001499 // reinterpret_cast < type-id > ( expression )
1500 Pattern = new CodeCompletionString;
1501 Pattern->AddTypedTextChunk("reinterpret_cast");
1502 Pattern->AddChunk(CodeCompletionString::CK_LeftAngle);
1503 Pattern->AddPlaceholderChunk("type");
1504 Pattern->AddChunk(CodeCompletionString::CK_RightAngle);
1505 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
1506 Pattern->AddPlaceholderChunk("expression");
1507 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
1508 Results.AddResult(Result(Pattern));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001509
Douglas Gregorc8bddde2010-05-28 00:22:41 +00001510 // const_cast < type-id > ( expression )
1511 Pattern = new CodeCompletionString;
1512 Pattern->AddTypedTextChunk("const_cast");
1513 Pattern->AddChunk(CodeCompletionString::CK_LeftAngle);
1514 Pattern->AddPlaceholderChunk("type");
1515 Pattern->AddChunk(CodeCompletionString::CK_RightAngle);
1516 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
1517 Pattern->AddPlaceholderChunk("expression");
1518 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
1519 Results.AddResult(Result(Pattern));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001520
Douglas Gregorc8bddde2010-05-28 00:22:41 +00001521 // typeid ( expression-or-type )
1522 Pattern = new CodeCompletionString;
1523 Pattern->AddTypedTextChunk("typeid");
1524 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
1525 Pattern->AddPlaceholderChunk("expression-or-type");
1526 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
1527 Results.AddResult(Result(Pattern));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001528
Douglas Gregorc8bddde2010-05-28 00:22:41 +00001529 // new T ( ... )
1530 Pattern = new CodeCompletionString;
1531 Pattern->AddTypedTextChunk("new");
1532 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
1533 Pattern->AddPlaceholderChunk("type");
1534 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
1535 Pattern->AddPlaceholderChunk("expressions");
1536 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
1537 Results.AddResult(Result(Pattern));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001538
Douglas Gregorc8bddde2010-05-28 00:22:41 +00001539 // new T [ ] ( ... )
1540 Pattern = new CodeCompletionString;
1541 Pattern->AddTypedTextChunk("new");
1542 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
1543 Pattern->AddPlaceholderChunk("type");
1544 Pattern->AddChunk(CodeCompletionString::CK_LeftBracket);
1545 Pattern->AddPlaceholderChunk("size");
1546 Pattern->AddChunk(CodeCompletionString::CK_RightBracket);
1547 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
1548 Pattern->AddPlaceholderChunk("expressions");
1549 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
1550 Results.AddResult(Result(Pattern));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001551
Douglas Gregorc8bddde2010-05-28 00:22:41 +00001552 // delete expression
1553 Pattern = new CodeCompletionString;
1554 Pattern->AddTypedTextChunk("delete");
1555 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
1556 Pattern->AddPlaceholderChunk("expression");
1557 Results.AddResult(Result(Pattern));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001558
Douglas Gregorc8bddde2010-05-28 00:22:41 +00001559 // delete [] expression
1560 Pattern = new CodeCompletionString;
1561 Pattern->AddTypedTextChunk("delete");
1562 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
1563 Pattern->AddChunk(CodeCompletionString::CK_LeftBracket);
1564 Pattern->AddChunk(CodeCompletionString::CK_RightBracket);
1565 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
1566 Pattern->AddPlaceholderChunk("expression");
1567 Results.AddResult(Result(Pattern));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001568
Douglas Gregorc8bddde2010-05-28 00:22:41 +00001569 // throw expression
1570 Pattern = new CodeCompletionString;
1571 Pattern->AddTypedTextChunk("throw");
1572 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
1573 Pattern->AddPlaceholderChunk("expression");
1574 Results.AddResult(Result(Pattern));
Douglas Gregor12e13132010-05-26 22:00:08 +00001575
1576 // FIXME: Rethrow?
Douglas Gregor01dfea02010-01-10 23:08:15 +00001577 }
1578
1579 if (SemaRef.getLangOptions().ObjC1) {
1580 // Add "super", if we're in an Objective-C class with a superclass.
Ted Kremenek681e2562010-05-31 21:43:10 +00001581 if (ObjCMethodDecl *Method = SemaRef.getCurMethodDecl()) {
1582 // The interface can be NULL.
1583 if (ObjCInterfaceDecl *ID = Method->getClassInterface())
1584 if (ID->getSuperClass())
1585 Results.AddResult(Result("super"));
1586 }
1587
Douglas Gregorbca403c2010-01-13 23:51:12 +00001588 AddObjCExpressionResults(Results, true);
Douglas Gregor01dfea02010-01-10 23:08:15 +00001589 }
1590
Douglas Gregorc8bddde2010-05-28 00:22:41 +00001591 // sizeof expression
1592 Pattern = new CodeCompletionString;
1593 Pattern->AddTypedTextChunk("sizeof");
1594 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
1595 Pattern->AddPlaceholderChunk("expression-or-type");
1596 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
1597 Results.AddResult(Result(Pattern));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001598 break;
1599 }
1600 }
1601
Douglas Gregor4710e5b2010-05-28 00:49:12 +00001602 if (WantTypesInContext(CCC, SemaRef.getLangOptions()))
1603 AddTypeSpecifierResults(SemaRef.getLangOptions(), Results);
Douglas Gregor01dfea02010-01-10 23:08:15 +00001604
1605 if (SemaRef.getLangOptions().CPlusPlus)
Douglas Gregora4477812010-01-14 16:01:26 +00001606 Results.AddResult(Result("operator"));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001607}
1608
Douglas Gregorff5ce6e2009-12-18 18:53:37 +00001609/// \brief If the given declaration has an associated type, add it as a result
1610/// type chunk.
1611static void AddResultTypeChunk(ASTContext &Context,
1612 NamedDecl *ND,
1613 CodeCompletionString *Result) {
1614 if (!ND)
1615 return;
1616
1617 // Determine the type of the declaration (if it has a type).
1618 QualType T;
1619 if (FunctionDecl *Function = dyn_cast<FunctionDecl>(ND))
1620 T = Function->getResultType();
1621 else if (ObjCMethodDecl *Method = dyn_cast<ObjCMethodDecl>(ND))
1622 T = Method->getResultType();
1623 else if (FunctionTemplateDecl *FunTmpl = dyn_cast<FunctionTemplateDecl>(ND))
1624 T = FunTmpl->getTemplatedDecl()->getResultType();
1625 else if (EnumConstantDecl *Enumerator = dyn_cast<EnumConstantDecl>(ND))
1626 T = Context.getTypeDeclType(cast<TypeDecl>(Enumerator->getDeclContext()));
1627 else if (isa<UnresolvedUsingValueDecl>(ND)) {
1628 /* Do nothing: ignore unresolved using declarations*/
1629 } else if (ValueDecl *Value = dyn_cast<ValueDecl>(ND))
1630 T = Value->getType();
1631 else if (ObjCPropertyDecl *Property = dyn_cast<ObjCPropertyDecl>(ND))
1632 T = Property->getType();
1633
1634 if (T.isNull() || Context.hasSameType(T, Context.DependentTy))
1635 return;
1636
Douglas Gregor84139d62010-04-05 21:25:31 +00001637 PrintingPolicy Policy(Context.PrintingPolicy);
1638 Policy.AnonymousTagLocations = false;
1639
Douglas Gregorff5ce6e2009-12-18 18:53:37 +00001640 std::string TypeStr;
Douglas Gregor84139d62010-04-05 21:25:31 +00001641 T.getAsStringInternal(TypeStr, Policy);
Douglas Gregorff5ce6e2009-12-18 18:53:37 +00001642 Result->AddResultTypeChunk(TypeStr);
1643}
1644
Douglas Gregor86d9a522009-09-21 16:56:56 +00001645/// \brief Add function parameter chunks to the given code completion string.
1646static void AddFunctionParameterChunks(ASTContext &Context,
1647 FunctionDecl *Function,
1648 CodeCompletionString *Result) {
Douglas Gregor0c8296d2009-11-07 00:00:49 +00001649 typedef CodeCompletionString::Chunk Chunk;
1650
Douglas Gregor86d9a522009-09-21 16:56:56 +00001651 CodeCompletionString *CCStr = Result;
1652
1653 for (unsigned P = 0, N = Function->getNumParams(); P != N; ++P) {
1654 ParmVarDecl *Param = Function->getParamDecl(P);
1655
1656 if (Param->hasDefaultArg()) {
1657 // When we see an optional default argument, put that argument and
1658 // the remaining default arguments into a new, optional string.
1659 CodeCompletionString *Opt = new CodeCompletionString;
1660 CCStr->AddOptionalChunk(std::auto_ptr<CodeCompletionString>(Opt));
1661 CCStr = Opt;
1662 }
1663
1664 if (P != 0)
Douglas Gregor0c8296d2009-11-07 00:00:49 +00001665 CCStr->AddChunk(Chunk(CodeCompletionString::CK_Comma));
Douglas Gregor86d9a522009-09-21 16:56:56 +00001666
1667 // Format the placeholder string.
1668 std::string PlaceholderStr;
1669 if (Param->getIdentifier())
1670 PlaceholderStr = Param->getIdentifier()->getName();
1671
1672 Param->getType().getAsStringInternal(PlaceholderStr,
1673 Context.PrintingPolicy);
1674
1675 // Add the placeholder string.
Benjamin Kramer660cc182009-11-29 20:18:50 +00001676 CCStr->AddPlaceholderChunk(PlaceholderStr);
Douglas Gregor86d9a522009-09-21 16:56:56 +00001677 }
Douglas Gregorb3d45252009-09-22 21:42:17 +00001678
1679 if (const FunctionProtoType *Proto
1680 = Function->getType()->getAs<FunctionProtoType>())
1681 if (Proto->isVariadic())
1682 CCStr->AddPlaceholderChunk(", ...");
Douglas Gregor86d9a522009-09-21 16:56:56 +00001683}
1684
1685/// \brief Add template parameter chunks to the given code completion string.
1686static void AddTemplateParameterChunks(ASTContext &Context,
1687 TemplateDecl *Template,
1688 CodeCompletionString *Result,
1689 unsigned MaxParameters = 0) {
Douglas Gregor0c8296d2009-11-07 00:00:49 +00001690 typedef CodeCompletionString::Chunk Chunk;
1691
Douglas Gregor86d9a522009-09-21 16:56:56 +00001692 CodeCompletionString *CCStr = Result;
1693 bool FirstParameter = true;
1694
1695 TemplateParameterList *Params = Template->getTemplateParameters();
1696 TemplateParameterList::iterator PEnd = Params->end();
1697 if (MaxParameters)
1698 PEnd = Params->begin() + MaxParameters;
1699 for (TemplateParameterList::iterator P = Params->begin(); P != PEnd; ++P) {
1700 bool HasDefaultArg = false;
1701 std::string PlaceholderStr;
1702 if (TemplateTypeParmDecl *TTP = dyn_cast<TemplateTypeParmDecl>(*P)) {
1703 if (TTP->wasDeclaredWithTypename())
1704 PlaceholderStr = "typename";
1705 else
1706 PlaceholderStr = "class";
1707
1708 if (TTP->getIdentifier()) {
1709 PlaceholderStr += ' ';
1710 PlaceholderStr += TTP->getIdentifier()->getName();
1711 }
1712
1713 HasDefaultArg = TTP->hasDefaultArgument();
1714 } else if (NonTypeTemplateParmDecl *NTTP
1715 = dyn_cast<NonTypeTemplateParmDecl>(*P)) {
1716 if (NTTP->getIdentifier())
1717 PlaceholderStr = NTTP->getIdentifier()->getName();
1718 NTTP->getType().getAsStringInternal(PlaceholderStr,
1719 Context.PrintingPolicy);
1720 HasDefaultArg = NTTP->hasDefaultArgument();
1721 } else {
1722 assert(isa<TemplateTemplateParmDecl>(*P));
1723 TemplateTemplateParmDecl *TTP = cast<TemplateTemplateParmDecl>(*P);
1724
1725 // Since putting the template argument list into the placeholder would
1726 // be very, very long, we just use an abbreviation.
1727 PlaceholderStr = "template<...> class";
1728 if (TTP->getIdentifier()) {
1729 PlaceholderStr += ' ';
1730 PlaceholderStr += TTP->getIdentifier()->getName();
1731 }
1732
1733 HasDefaultArg = TTP->hasDefaultArgument();
1734 }
1735
1736 if (HasDefaultArg) {
1737 // When we see an optional default argument, put that argument and
1738 // the remaining default arguments into a new, optional string.
1739 CodeCompletionString *Opt = new CodeCompletionString;
1740 CCStr->AddOptionalChunk(std::auto_ptr<CodeCompletionString>(Opt));
1741 CCStr = Opt;
1742 }
1743
1744 if (FirstParameter)
1745 FirstParameter = false;
1746 else
Douglas Gregor0c8296d2009-11-07 00:00:49 +00001747 CCStr->AddChunk(Chunk(CodeCompletionString::CK_Comma));
Douglas Gregor86d9a522009-09-21 16:56:56 +00001748
1749 // Add the placeholder string.
Benjamin Kramer660cc182009-11-29 20:18:50 +00001750 CCStr->AddPlaceholderChunk(PlaceholderStr);
Douglas Gregor86d9a522009-09-21 16:56:56 +00001751 }
1752}
1753
Douglas Gregorb9d0ef72009-09-21 19:57:38 +00001754/// \brief Add a qualifier to the given code-completion string, if the
1755/// provided nested-name-specifier is non-NULL.
Douglas Gregora61a8792009-12-11 18:44:16 +00001756static void
1757AddQualifierToCompletionString(CodeCompletionString *Result,
1758 NestedNameSpecifier *Qualifier,
1759 bool QualifierIsInformative,
1760 ASTContext &Context) {
Douglas Gregorb9d0ef72009-09-21 19:57:38 +00001761 if (!Qualifier)
1762 return;
1763
1764 std::string PrintedNNS;
1765 {
1766 llvm::raw_string_ostream OS(PrintedNNS);
1767 Qualifier->print(OS, Context.PrintingPolicy);
1768 }
Douglas Gregor0563c262009-09-22 23:15:58 +00001769 if (QualifierIsInformative)
Benjamin Kramer660cc182009-11-29 20:18:50 +00001770 Result->AddInformativeChunk(PrintedNNS);
Douglas Gregor0563c262009-09-22 23:15:58 +00001771 else
Benjamin Kramer660cc182009-11-29 20:18:50 +00001772 Result->AddTextChunk(PrintedNNS);
Douglas Gregorb9d0ef72009-09-21 19:57:38 +00001773}
1774
Douglas Gregora61a8792009-12-11 18:44:16 +00001775static void AddFunctionTypeQualsToCompletionString(CodeCompletionString *Result,
1776 FunctionDecl *Function) {
1777 const FunctionProtoType *Proto
1778 = Function->getType()->getAs<FunctionProtoType>();
1779 if (!Proto || !Proto->getTypeQuals())
1780 return;
1781
1782 std::string QualsStr;
1783 if (Proto->getTypeQuals() & Qualifiers::Const)
1784 QualsStr += " const";
1785 if (Proto->getTypeQuals() & Qualifiers::Volatile)
1786 QualsStr += " volatile";
1787 if (Proto->getTypeQuals() & Qualifiers::Restrict)
1788 QualsStr += " restrict";
1789 Result->AddInformativeChunk(QualsStr);
1790}
1791
Douglas Gregor86d9a522009-09-21 16:56:56 +00001792/// \brief If possible, create a new code completion string for the given
1793/// result.
1794///
1795/// \returns Either a new, heap-allocated code completion string describing
1796/// how to use this result, or NULL to indicate that the string or name of the
1797/// result is all that is needed.
1798CodeCompletionString *
1799CodeCompleteConsumer::Result::CreateCodeCompletionString(Sema &S) {
Douglas Gregor0c8296d2009-11-07 00:00:49 +00001800 typedef CodeCompletionString::Chunk Chunk;
1801
Douglas Gregor2b4074f2009-12-01 05:55:20 +00001802 if (Kind == RK_Pattern)
1803 return Pattern->Clone();
1804
1805 CodeCompletionString *Result = new CodeCompletionString;
1806
1807 if (Kind == RK_Keyword) {
1808 Result->AddTypedTextChunk(Keyword);
1809 return Result;
1810 }
Douglas Gregor86d9a522009-09-21 16:56:56 +00001811
Douglas Gregor3f7c7f42009-10-30 16:50:04 +00001812 if (Kind == RK_Macro) {
1813 MacroInfo *MI = S.PP.getMacroInfo(Macro);
Douglas Gregor2b4074f2009-12-01 05:55:20 +00001814 assert(MI && "Not a macro?");
1815
1816 Result->AddTypedTextChunk(Macro->getName());
1817
1818 if (!MI->isFunctionLike())
1819 return Result;
Douglas Gregor3f7c7f42009-10-30 16:50:04 +00001820
1821 // Format a function-like macro with placeholders for the arguments.
Douglas Gregor0c8296d2009-11-07 00:00:49 +00001822 Result->AddChunk(Chunk(CodeCompletionString::CK_LeftParen));
Douglas Gregor3f7c7f42009-10-30 16:50:04 +00001823 for (MacroInfo::arg_iterator A = MI->arg_begin(), AEnd = MI->arg_end();
1824 A != AEnd; ++A) {
1825 if (A != MI->arg_begin())
Douglas Gregor0c8296d2009-11-07 00:00:49 +00001826 Result->AddChunk(Chunk(CodeCompletionString::CK_Comma));
Douglas Gregor3f7c7f42009-10-30 16:50:04 +00001827
1828 if (!MI->isVariadic() || A != AEnd - 1) {
1829 // Non-variadic argument.
Benjamin Kramer660cc182009-11-29 20:18:50 +00001830 Result->AddPlaceholderChunk((*A)->getName());
Douglas Gregor3f7c7f42009-10-30 16:50:04 +00001831 continue;
1832 }
1833
1834 // Variadic argument; cope with the different between GNU and C99
1835 // variadic macros, providing a single placeholder for the rest of the
1836 // arguments.
1837 if ((*A)->isStr("__VA_ARGS__"))
1838 Result->AddPlaceholderChunk("...");
1839 else {
1840 std::string Arg = (*A)->getName();
1841 Arg += "...";
Benjamin Kramer660cc182009-11-29 20:18:50 +00001842 Result->AddPlaceholderChunk(Arg);
Douglas Gregor3f7c7f42009-10-30 16:50:04 +00001843 }
1844 }
Douglas Gregor0c8296d2009-11-07 00:00:49 +00001845 Result->AddChunk(Chunk(CodeCompletionString::CK_RightParen));
Douglas Gregor3f7c7f42009-10-30 16:50:04 +00001846 return Result;
1847 }
1848
Douglas Gregord8e8a582010-05-25 21:41:55 +00001849 assert(Kind == RK_Declaration && "Missed a result kind?");
Douglas Gregor86d9a522009-09-21 16:56:56 +00001850 NamedDecl *ND = Declaration;
1851
Douglas Gregor0c8296d2009-11-07 00:00:49 +00001852 if (StartsNestedNameSpecifier) {
Benjamin Kramer660cc182009-11-29 20:18:50 +00001853 Result->AddTypedTextChunk(ND->getNameAsString());
Douglas Gregor0c8296d2009-11-07 00:00:49 +00001854 Result->AddTextChunk("::");
1855 return Result;
1856 }
1857
Douglas Gregorff5ce6e2009-12-18 18:53:37 +00001858 AddResultTypeChunk(S.Context, ND, Result);
1859
Douglas Gregor86d9a522009-09-21 16:56:56 +00001860 if (FunctionDecl *Function = dyn_cast<FunctionDecl>(ND)) {
Douglas Gregor0563c262009-09-22 23:15:58 +00001861 AddQualifierToCompletionString(Result, Qualifier, QualifierIsInformative,
1862 S.Context);
Benjamin Kramer660cc182009-11-29 20:18:50 +00001863 Result->AddTypedTextChunk(Function->getNameAsString());
Douglas Gregor0c8296d2009-11-07 00:00:49 +00001864 Result->AddChunk(Chunk(CodeCompletionString::CK_LeftParen));
Douglas Gregor86d9a522009-09-21 16:56:56 +00001865 AddFunctionParameterChunks(S.Context, Function, Result);
Douglas Gregor0c8296d2009-11-07 00:00:49 +00001866 Result->AddChunk(Chunk(CodeCompletionString::CK_RightParen));
Douglas Gregora61a8792009-12-11 18:44:16 +00001867 AddFunctionTypeQualsToCompletionString(Result, Function);
Douglas Gregor86d9a522009-09-21 16:56:56 +00001868 return Result;
1869 }
1870
1871 if (FunctionTemplateDecl *FunTmpl = dyn_cast<FunctionTemplateDecl>(ND)) {
Douglas Gregor0563c262009-09-22 23:15:58 +00001872 AddQualifierToCompletionString(Result, Qualifier, QualifierIsInformative,
1873 S.Context);
Douglas Gregor86d9a522009-09-21 16:56:56 +00001874 FunctionDecl *Function = FunTmpl->getTemplatedDecl();
Benjamin Kramer660cc182009-11-29 20:18:50 +00001875 Result->AddTypedTextChunk(Function->getNameAsString());
Douglas Gregor86d9a522009-09-21 16:56:56 +00001876
1877 // Figure out which template parameters are deduced (or have default
1878 // arguments).
1879 llvm::SmallVector<bool, 16> Deduced;
1880 S.MarkDeducedTemplateParameters(FunTmpl, Deduced);
1881 unsigned LastDeducibleArgument;
1882 for (LastDeducibleArgument = Deduced.size(); LastDeducibleArgument > 0;
1883 --LastDeducibleArgument) {
1884 if (!Deduced[LastDeducibleArgument - 1]) {
1885 // C++0x: Figure out if the template argument has a default. If so,
1886 // the user doesn't need to type this argument.
1887 // FIXME: We need to abstract template parameters better!
1888 bool HasDefaultArg = false;
1889 NamedDecl *Param = FunTmpl->getTemplateParameters()->getParam(
1890 LastDeducibleArgument - 1);
1891 if (TemplateTypeParmDecl *TTP = dyn_cast<TemplateTypeParmDecl>(Param))
1892 HasDefaultArg = TTP->hasDefaultArgument();
1893 else if (NonTypeTemplateParmDecl *NTTP
1894 = dyn_cast<NonTypeTemplateParmDecl>(Param))
1895 HasDefaultArg = NTTP->hasDefaultArgument();
1896 else {
1897 assert(isa<TemplateTemplateParmDecl>(Param));
1898 HasDefaultArg
Douglas Gregor0c8296d2009-11-07 00:00:49 +00001899 = cast<TemplateTemplateParmDecl>(Param)->hasDefaultArgument();
Douglas Gregor86d9a522009-09-21 16:56:56 +00001900 }
1901
1902 if (!HasDefaultArg)
1903 break;
1904 }
1905 }
1906
1907 if (LastDeducibleArgument) {
1908 // Some of the function template arguments cannot be deduced from a
1909 // function call, so we introduce an explicit template argument list
1910 // containing all of the arguments up to the first deducible argument.
Douglas Gregor0c8296d2009-11-07 00:00:49 +00001911 Result->AddChunk(Chunk(CodeCompletionString::CK_LeftAngle));
Douglas Gregor86d9a522009-09-21 16:56:56 +00001912 AddTemplateParameterChunks(S.Context, FunTmpl, Result,
1913 LastDeducibleArgument);
Douglas Gregor0c8296d2009-11-07 00:00:49 +00001914 Result->AddChunk(Chunk(CodeCompletionString::CK_RightAngle));
Douglas Gregor86d9a522009-09-21 16:56:56 +00001915 }
1916
1917 // Add the function parameters
Douglas Gregor0c8296d2009-11-07 00:00:49 +00001918 Result->AddChunk(Chunk(CodeCompletionString::CK_LeftParen));
Douglas Gregor86d9a522009-09-21 16:56:56 +00001919 AddFunctionParameterChunks(S.Context, Function, Result);
Douglas Gregor0c8296d2009-11-07 00:00:49 +00001920 Result->AddChunk(Chunk(CodeCompletionString::CK_RightParen));
Douglas Gregora61a8792009-12-11 18:44:16 +00001921 AddFunctionTypeQualsToCompletionString(Result, Function);
Douglas Gregor86d9a522009-09-21 16:56:56 +00001922 return Result;
1923 }
1924
1925 if (TemplateDecl *Template = dyn_cast<TemplateDecl>(ND)) {
Douglas Gregor0563c262009-09-22 23:15:58 +00001926 AddQualifierToCompletionString(Result, Qualifier, QualifierIsInformative,
1927 S.Context);
Benjamin Kramer660cc182009-11-29 20:18:50 +00001928 Result->AddTypedTextChunk(Template->getNameAsString());
Douglas Gregor0c8296d2009-11-07 00:00:49 +00001929 Result->AddChunk(Chunk(CodeCompletionString::CK_LeftAngle));
Douglas Gregor86d9a522009-09-21 16:56:56 +00001930 AddTemplateParameterChunks(S.Context, Template, Result);
Douglas Gregor0c8296d2009-11-07 00:00:49 +00001931 Result->AddChunk(Chunk(CodeCompletionString::CK_RightAngle));
Douglas Gregor86d9a522009-09-21 16:56:56 +00001932 return Result;
1933 }
1934
Douglas Gregor9630eb62009-11-17 16:44:22 +00001935 if (ObjCMethodDecl *Method = dyn_cast<ObjCMethodDecl>(ND)) {
Douglas Gregor9630eb62009-11-17 16:44:22 +00001936 Selector Sel = Method->getSelector();
1937 if (Sel.isUnarySelector()) {
1938 Result->AddTypedTextChunk(Sel.getIdentifierInfoForSlot(0)->getName());
1939 return Result;
1940 }
1941
Douglas Gregord3c68542009-11-19 01:08:35 +00001942 std::string SelName = Sel.getIdentifierInfoForSlot(0)->getName().str();
1943 SelName += ':';
1944 if (StartParameter == 0)
1945 Result->AddTypedTextChunk(SelName);
1946 else {
1947 Result->AddInformativeChunk(SelName);
1948
1949 // If there is only one parameter, and we're past it, add an empty
1950 // typed-text chunk since there is nothing to type.
1951 if (Method->param_size() == 1)
1952 Result->AddTypedTextChunk("");
1953 }
Douglas Gregor9630eb62009-11-17 16:44:22 +00001954 unsigned Idx = 0;
1955 for (ObjCMethodDecl::param_iterator P = Method->param_begin(),
1956 PEnd = Method->param_end();
1957 P != PEnd; (void)++P, ++Idx) {
1958 if (Idx > 0) {
Douglas Gregord3c68542009-11-19 01:08:35 +00001959 std::string Keyword;
1960 if (Idx > StartParameter)
Douglas Gregor834389b2010-01-12 06:38:28 +00001961 Result->AddChunk(CodeCompletionString::CK_HorizontalSpace);
Douglas Gregor9630eb62009-11-17 16:44:22 +00001962 if (IdentifierInfo *II = Sel.getIdentifierInfoForSlot(Idx))
1963 Keyword += II->getName().str();
1964 Keyword += ":";
Douglas Gregor1f5537a2010-07-08 23:20:03 +00001965 if (Idx < StartParameter || AllParametersAreInformative)
Douglas Gregord3c68542009-11-19 01:08:35 +00001966 Result->AddInformativeChunk(Keyword);
Douglas Gregor1f5537a2010-07-08 23:20:03 +00001967 else if (Idx == StartParameter)
Douglas Gregord3c68542009-11-19 01:08:35 +00001968 Result->AddTypedTextChunk(Keyword);
1969 else
1970 Result->AddTextChunk(Keyword);
Douglas Gregor9630eb62009-11-17 16:44:22 +00001971 }
Douglas Gregord3c68542009-11-19 01:08:35 +00001972
1973 // If we're before the starting parameter, skip the placeholder.
1974 if (Idx < StartParameter)
1975 continue;
Douglas Gregor9630eb62009-11-17 16:44:22 +00001976
1977 std::string Arg;
1978 (*P)->getType().getAsStringInternal(Arg, S.Context.PrintingPolicy);
1979 Arg = "(" + Arg + ")";
1980 if (IdentifierInfo *II = (*P)->getIdentifier())
1981 Arg += II->getName().str();
Douglas Gregor1f5537a2010-07-08 23:20:03 +00001982 if (DeclaringEntity)
1983 Result->AddTextChunk(Arg);
1984 else if (AllParametersAreInformative)
Douglas Gregor4ad96852009-11-19 07:41:15 +00001985 Result->AddInformativeChunk(Arg);
1986 else
1987 Result->AddPlaceholderChunk(Arg);
Douglas Gregor9630eb62009-11-17 16:44:22 +00001988 }
1989
Douglas Gregor2a17af02009-12-23 00:21:46 +00001990 if (Method->isVariadic()) {
Douglas Gregor1f5537a2010-07-08 23:20:03 +00001991 if (DeclaringEntity)
1992 Result->AddTextChunk(", ...");
1993 else if (AllParametersAreInformative)
Douglas Gregor2a17af02009-12-23 00:21:46 +00001994 Result->AddInformativeChunk(", ...");
1995 else
1996 Result->AddPlaceholderChunk(", ...");
1997 }
1998
Douglas Gregor9630eb62009-11-17 16:44:22 +00001999 return Result;
2000 }
2001
Douglas Gregor2b4074f2009-12-01 05:55:20 +00002002 if (Qualifier)
Douglas Gregor0563c262009-09-22 23:15:58 +00002003 AddQualifierToCompletionString(Result, Qualifier, QualifierIsInformative,
2004 S.Context);
Douglas Gregor2b4074f2009-12-01 05:55:20 +00002005
2006 Result->AddTypedTextChunk(ND->getNameAsString());
2007 return Result;
Douglas Gregor86d9a522009-09-21 16:56:56 +00002008}
2009
Douglas Gregor86d802e2009-09-23 00:34:09 +00002010CodeCompletionString *
2011CodeCompleteConsumer::OverloadCandidate::CreateSignatureString(
2012 unsigned CurrentArg,
2013 Sema &S) const {
Douglas Gregor0c8296d2009-11-07 00:00:49 +00002014 typedef CodeCompletionString::Chunk Chunk;
2015
Douglas Gregor86d802e2009-09-23 00:34:09 +00002016 CodeCompletionString *Result = new CodeCompletionString;
2017 FunctionDecl *FDecl = getFunction();
Douglas Gregorff5ce6e2009-12-18 18:53:37 +00002018 AddResultTypeChunk(S.Context, FDecl, Result);
Douglas Gregor86d802e2009-09-23 00:34:09 +00002019 const FunctionProtoType *Proto
2020 = dyn_cast<FunctionProtoType>(getFunctionType());
2021 if (!FDecl && !Proto) {
2022 // Function without a prototype. Just give the return type and a
2023 // highlighted ellipsis.
2024 const FunctionType *FT = getFunctionType();
2025 Result->AddTextChunk(
Benjamin Kramer660cc182009-11-29 20:18:50 +00002026 FT->getResultType().getAsString(S.Context.PrintingPolicy));
Douglas Gregor0c8296d2009-11-07 00:00:49 +00002027 Result->AddChunk(Chunk(CodeCompletionString::CK_LeftParen));
2028 Result->AddChunk(Chunk(CodeCompletionString::CK_CurrentParameter, "..."));
2029 Result->AddChunk(Chunk(CodeCompletionString::CK_RightParen));
Douglas Gregor86d802e2009-09-23 00:34:09 +00002030 return Result;
2031 }
2032
2033 if (FDecl)
Benjamin Kramer660cc182009-11-29 20:18:50 +00002034 Result->AddTextChunk(FDecl->getNameAsString());
Douglas Gregor86d802e2009-09-23 00:34:09 +00002035 else
2036 Result->AddTextChunk(
Benjamin Kramer660cc182009-11-29 20:18:50 +00002037 Proto->getResultType().getAsString(S.Context.PrintingPolicy));
Douglas Gregor86d802e2009-09-23 00:34:09 +00002038
Douglas Gregor0c8296d2009-11-07 00:00:49 +00002039 Result->AddChunk(Chunk(CodeCompletionString::CK_LeftParen));
Douglas Gregor86d802e2009-09-23 00:34:09 +00002040 unsigned NumParams = FDecl? FDecl->getNumParams() : Proto->getNumArgs();
2041 for (unsigned I = 0; I != NumParams; ++I) {
2042 if (I)
Douglas Gregor0c8296d2009-11-07 00:00:49 +00002043 Result->AddChunk(Chunk(CodeCompletionString::CK_Comma));
Douglas Gregor86d802e2009-09-23 00:34:09 +00002044
2045 std::string ArgString;
2046 QualType ArgType;
2047
2048 if (FDecl) {
2049 ArgString = FDecl->getParamDecl(I)->getNameAsString();
2050 ArgType = FDecl->getParamDecl(I)->getOriginalType();
2051 } else {
2052 ArgType = Proto->getArgType(I);
2053 }
2054
2055 ArgType.getAsStringInternal(ArgString, S.Context.PrintingPolicy);
2056
2057 if (I == CurrentArg)
Douglas Gregor0c8296d2009-11-07 00:00:49 +00002058 Result->AddChunk(Chunk(CodeCompletionString::CK_CurrentParameter,
Benjamin Kramer660cc182009-11-29 20:18:50 +00002059 ArgString));
Douglas Gregor86d802e2009-09-23 00:34:09 +00002060 else
Benjamin Kramer660cc182009-11-29 20:18:50 +00002061 Result->AddTextChunk(ArgString);
Douglas Gregor86d802e2009-09-23 00:34:09 +00002062 }
2063
2064 if (Proto && Proto->isVariadic()) {
Douglas Gregor0c8296d2009-11-07 00:00:49 +00002065 Result->AddChunk(Chunk(CodeCompletionString::CK_Comma));
Douglas Gregor86d802e2009-09-23 00:34:09 +00002066 if (CurrentArg < NumParams)
2067 Result->AddTextChunk("...");
2068 else
Douglas Gregor0c8296d2009-11-07 00:00:49 +00002069 Result->AddChunk(Chunk(CodeCompletionString::CK_CurrentParameter, "..."));
Douglas Gregor86d802e2009-09-23 00:34:09 +00002070 }
Douglas Gregor0c8296d2009-11-07 00:00:49 +00002071 Result->AddChunk(Chunk(CodeCompletionString::CK_RightParen));
Douglas Gregor86d802e2009-09-23 00:34:09 +00002072
2073 return Result;
2074}
2075
Douglas Gregor86d9a522009-09-21 16:56:56 +00002076namespace {
2077 struct SortCodeCompleteResult {
2078 typedef CodeCompleteConsumer::Result Result;
2079
Douglas Gregor6a684032009-09-28 03:51:44 +00002080 bool isEarlierDeclarationName(DeclarationName X, DeclarationName Y) const {
Douglas Gregor2b0cc122009-12-05 09:08:56 +00002081 Selector XSel = X.getObjCSelector();
2082 Selector YSel = Y.getObjCSelector();
2083 if (!XSel.isNull() && !YSel.isNull()) {
2084 // We are comparing two selectors.
2085 unsigned N = std::min(XSel.getNumArgs(), YSel.getNumArgs());
2086 if (N == 0)
2087 ++N;
2088 for (unsigned I = 0; I != N; ++I) {
2089 IdentifierInfo *XId = XSel.getIdentifierInfoForSlot(I);
2090 IdentifierInfo *YId = YSel.getIdentifierInfoForSlot(I);
2091 if (!XId || !YId)
2092 return XId && !YId;
2093
2094 switch (XId->getName().compare_lower(YId->getName())) {
2095 case -1: return true;
2096 case 1: return false;
2097 default: break;
2098 }
2099 }
2100
2101 return XSel.getNumArgs() < YSel.getNumArgs();
2102 }
2103
2104 // For non-selectors, order by kind.
2105 if (X.getNameKind() != Y.getNameKind())
Douglas Gregor6a684032009-09-28 03:51:44 +00002106 return X.getNameKind() < Y.getNameKind();
2107
Douglas Gregor2b0cc122009-12-05 09:08:56 +00002108 // Order identifiers by comparison of their lowercased names.
2109 if (IdentifierInfo *XId = X.getAsIdentifierInfo())
2110 return XId->getName().compare_lower(
2111 Y.getAsIdentifierInfo()->getName()) < 0;
2112
2113 // Order overloaded operators by the order in which they appear
2114 // in our list of operators.
2115 if (OverloadedOperatorKind XOp = X.getCXXOverloadedOperator())
2116 return XOp < Y.getCXXOverloadedOperator();
2117
2118 // Order C++0x user-defined literal operators lexically by their
2119 // lowercased suffixes.
2120 if (IdentifierInfo *XLit = X.getCXXLiteralIdentifier())
2121 return XLit->getName().compare_lower(
2122 Y.getCXXLiteralIdentifier()->getName()) < 0;
2123
2124 // The only stable ordering we have is to turn the name into a
2125 // string and then compare the lower-case strings. This is
2126 // inefficient, but thankfully does not happen too often.
Benjamin Kramer0e7049f2009-12-05 10:22:15 +00002127 return llvm::StringRef(X.getAsString()).compare_lower(
2128 Y.getAsString()) < 0;
Douglas Gregor6a684032009-09-28 03:51:44 +00002129 }
2130
Douglas Gregorab0b4f12010-01-13 23:24:38 +00002131 /// \brief Retrieve the name that should be used to order a result.
2132 ///
2133 /// If the name needs to be constructed as a string, that string will be
2134 /// saved into Saved and the returned StringRef will refer to it.
2135 static llvm::StringRef getOrderedName(const Result &R,
2136 std::string &Saved) {
2137 switch (R.Kind) {
2138 case Result::RK_Keyword:
2139 return R.Keyword;
2140
2141 case Result::RK_Pattern:
2142 return R.Pattern->getTypedText();
2143
2144 case Result::RK_Macro:
2145 return R.Macro->getName();
2146
2147 case Result::RK_Declaration:
2148 // Handle declarations below.
2149 break;
Douglas Gregor54f01612009-11-19 00:01:57 +00002150 }
Douglas Gregorab0b4f12010-01-13 23:24:38 +00002151
2152 DeclarationName Name = R.Declaration->getDeclName();
Douglas Gregor54f01612009-11-19 00:01:57 +00002153
Douglas Gregorab0b4f12010-01-13 23:24:38 +00002154 // If the name is a simple identifier (by far the common case), or a
2155 // zero-argument selector, just return a reference to that identifier.
2156 if (IdentifierInfo *Id = Name.getAsIdentifierInfo())
2157 return Id->getName();
2158 if (Name.isObjCZeroArgSelector())
2159 if (IdentifierInfo *Id
2160 = Name.getObjCSelector().getIdentifierInfoForSlot(0))
2161 return Id->getName();
2162
2163 Saved = Name.getAsString();
2164 return Saved;
2165 }
2166
2167 bool operator()(const Result &X, const Result &Y) const {
2168 std::string XSaved, YSaved;
2169 llvm::StringRef XStr = getOrderedName(X, XSaved);
2170 llvm::StringRef YStr = getOrderedName(Y, YSaved);
2171 int cmp = XStr.compare_lower(YStr);
2172 if (cmp)
2173 return cmp < 0;
Douglas Gregor86d9a522009-09-21 16:56:56 +00002174
2175 // Non-hidden names precede hidden names.
2176 if (X.Hidden != Y.Hidden)
2177 return !X.Hidden;
2178
Douglas Gregoreb5758b2009-09-23 22:26:46 +00002179 // Non-nested-name-specifiers precede nested-name-specifiers.
2180 if (X.StartsNestedNameSpecifier != Y.StartsNestedNameSpecifier)
2181 return !X.StartsNestedNameSpecifier;
2182
Douglas Gregor86d9a522009-09-21 16:56:56 +00002183 return false;
2184 }
2185 };
2186}
2187
Douglas Gregor590c7d52010-07-08 20:55:51 +00002188static void AddMacroResults(Preprocessor &PP, ResultBuilder &Results,
2189 bool TargetTypeIsPointer = false) {
2190 typedef CodeCompleteConsumer::Result Result;
2191
Douglas Gregor3f7c7f42009-10-30 16:50:04 +00002192 Results.EnterNewScope();
Douglas Gregor0c8296d2009-11-07 00:00:49 +00002193 for (Preprocessor::macro_iterator M = PP.macro_begin(),
2194 MEnd = PP.macro_end();
Douglas Gregor590c7d52010-07-08 20:55:51 +00002195 M != MEnd; ++M) {
2196 unsigned Priority = CCP_Macro;
2197
2198 // Treat the "nil" and "NULL" macros as null pointer constants.
2199 if (M->first->isStr("nil") || M->first->isStr("NULL")) {
2200 Priority = CCP_Constant;
2201 if (TargetTypeIsPointer)
2202 Priority = Priority / CCF_SimilarTypeMatch;
2203 }
2204
2205 Results.AddResult(Result(M->first, Priority));
2206 }
Douglas Gregor3f7c7f42009-10-30 16:50:04 +00002207 Results.ExitScope();
2208}
2209
Daniel Dunbar3a2838d2009-11-13 08:58:20 +00002210static void HandleCodeCompleteResults(Sema *S,
2211 CodeCompleteConsumer *CodeCompleter,
2212 CodeCompleteConsumer::Result *Results,
2213 unsigned NumResults) {
Douglas Gregor86d9a522009-09-21 16:56:56 +00002214 std::stable_sort(Results, Results + NumResults, SortCodeCompleteResult());
2215
2216 if (CodeCompleter)
Daniel Dunbar3a2838d2009-11-13 08:58:20 +00002217 CodeCompleter->ProcessCodeCompleteResults(*S, Results, NumResults);
Douglas Gregor54f01612009-11-19 00:01:57 +00002218
2219 for (unsigned I = 0; I != NumResults; ++I)
2220 Results[I].Destroy();
Douglas Gregor86d9a522009-09-21 16:56:56 +00002221}
2222
Douglas Gregor01dfea02010-01-10 23:08:15 +00002223void Sema::CodeCompleteOrdinaryName(Scope *S,
2224 CodeCompletionContext CompletionContext) {
Douglas Gregor2a7925c2009-12-07 09:54:55 +00002225 typedef CodeCompleteConsumer::Result Result;
Douglas Gregor01dfea02010-01-10 23:08:15 +00002226 ResultBuilder Results(*this);
2227
2228 // Determine how to filter results, e.g., so that the names of
2229 // values (functions, enumerators, function templates, etc.) are
2230 // only allowed where we can have an expression.
2231 switch (CompletionContext) {
2232 case CCC_Namespace:
2233 case CCC_Class:
Douglas Gregorb6ac2452010-01-13 21:24:21 +00002234 case CCC_ObjCInterface:
2235 case CCC_ObjCImplementation:
Douglas Gregorc38c3e12010-01-13 21:54:15 +00002236 case CCC_ObjCInstanceVariableList:
Douglas Gregor01dfea02010-01-10 23:08:15 +00002237 case CCC_Template:
2238 case CCC_MemberTemplate:
2239 Results.setFilter(&ResultBuilder::IsOrdinaryNonValueName);
2240 break;
2241
2242 case CCC_Expression:
2243 case CCC_Statement:
2244 case CCC_ForInit:
2245 case CCC_Condition:
Douglas Gregor4710e5b2010-05-28 00:49:12 +00002246 if (WantTypesInContext(CompletionContext, getLangOptions()))
2247 Results.setFilter(&ResultBuilder::IsOrdinaryName);
2248 else
2249 Results.setFilter(&ResultBuilder::IsOrdinaryNonTypeName);
Douglas Gregor01dfea02010-01-10 23:08:15 +00002250 break;
Douglas Gregordc845342010-05-25 05:58:43 +00002251
2252 case CCC_RecoveryInFunction:
2253 // Unfiltered
2254 break;
Douglas Gregor01dfea02010-01-10 23:08:15 +00002255 }
2256
Douglas Gregor1ca6ae82010-01-14 01:09:38 +00002257 CodeCompletionDeclConsumer Consumer(Results, CurContext);
2258 LookupVisibleDecls(S, LookupOrdinaryName, Consumer);
Douglas Gregor2a7925c2009-12-07 09:54:55 +00002259
2260 Results.EnterNewScope();
Douglas Gregorbca403c2010-01-13 23:51:12 +00002261 AddOrdinaryNameResults(CompletionContext, S, *this, Results);
Douglas Gregor2a7925c2009-12-07 09:54:55 +00002262 Results.ExitScope();
2263
Douglas Gregor0c8296d2009-11-07 00:00:49 +00002264 if (CodeCompleter->includeMacros())
Douglas Gregorbca403c2010-01-13 23:51:12 +00002265 AddMacroResults(PP, Results);
Daniel Dunbar3a2838d2009-11-13 08:58:20 +00002266 HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
Douglas Gregor791215b2009-09-21 20:51:25 +00002267}
2268
Douglas Gregor5ac3bdb2010-05-30 01:49:25 +00002269/// \brief Perform code-completion in an expression context when we know what
2270/// type we're looking for.
2271void Sema::CodeCompleteExpression(Scope *S, QualType T) {
2272 typedef CodeCompleteConsumer::Result Result;
2273 ResultBuilder Results(*this);
2274
2275 if (WantTypesInContext(CCC_Expression, getLangOptions()))
2276 Results.setFilter(&ResultBuilder::IsOrdinaryName);
2277 else
2278 Results.setFilter(&ResultBuilder::IsOrdinaryNonTypeName);
2279 Results.setPreferredType(T.getNonReferenceType());
2280
2281 CodeCompletionDeclConsumer Consumer(Results, CurContext);
2282 LookupVisibleDecls(S, LookupOrdinaryName, Consumer);
2283
2284 Results.EnterNewScope();
2285 AddOrdinaryNameResults(CCC_Expression, S, *this, Results);
2286 Results.ExitScope();
2287
Douglas Gregor590c7d52010-07-08 20:55:51 +00002288 bool PreferredTypeIsPointer = false;
2289 if (!T.isNull())
2290 PreferredTypeIsPointer = T->isAnyPointerType() ||
2291 T->isMemberPointerType() || T->isBlockPointerType();
2292
Douglas Gregor5ac3bdb2010-05-30 01:49:25 +00002293 if (CodeCompleter->includeMacros())
Douglas Gregor590c7d52010-07-08 20:55:51 +00002294 AddMacroResults(PP, Results, PreferredTypeIsPointer);
Douglas Gregor5ac3bdb2010-05-30 01:49:25 +00002295 HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
2296}
2297
2298
Douglas Gregor95ac6552009-11-18 01:29:26 +00002299static void AddObjCProperties(ObjCContainerDecl *Container,
Douglas Gregor322328b2009-11-18 22:32:06 +00002300 bool AllowCategories,
Douglas Gregor95ac6552009-11-18 01:29:26 +00002301 DeclContext *CurContext,
2302 ResultBuilder &Results) {
2303 typedef CodeCompleteConsumer::Result Result;
2304
2305 // Add properties in this container.
2306 for (ObjCContainerDecl::prop_iterator P = Container->prop_begin(),
2307 PEnd = Container->prop_end();
2308 P != PEnd;
2309 ++P)
2310 Results.MaybeAddResult(Result(*P, 0), CurContext);
2311
2312 // Add properties in referenced protocols.
2313 if (ObjCProtocolDecl *Protocol = dyn_cast<ObjCProtocolDecl>(Container)) {
2314 for (ObjCProtocolDecl::protocol_iterator P = Protocol->protocol_begin(),
2315 PEnd = Protocol->protocol_end();
2316 P != PEnd; ++P)
Douglas Gregor322328b2009-11-18 22:32:06 +00002317 AddObjCProperties(*P, AllowCategories, CurContext, Results);
Douglas Gregor95ac6552009-11-18 01:29:26 +00002318 } else if (ObjCInterfaceDecl *IFace = dyn_cast<ObjCInterfaceDecl>(Container)){
Douglas Gregor322328b2009-11-18 22:32:06 +00002319 if (AllowCategories) {
2320 // Look through categories.
2321 for (ObjCCategoryDecl *Category = IFace->getCategoryList();
2322 Category; Category = Category->getNextClassCategory())
2323 AddObjCProperties(Category, AllowCategories, CurContext, Results);
2324 }
Douglas Gregor95ac6552009-11-18 01:29:26 +00002325
2326 // Look through protocols.
2327 for (ObjCInterfaceDecl::protocol_iterator I = IFace->protocol_begin(),
2328 E = IFace->protocol_end();
2329 I != E; ++I)
Douglas Gregor322328b2009-11-18 22:32:06 +00002330 AddObjCProperties(*I, AllowCategories, CurContext, Results);
Douglas Gregor95ac6552009-11-18 01:29:26 +00002331
2332 // Look in the superclass.
2333 if (IFace->getSuperClass())
Douglas Gregor322328b2009-11-18 22:32:06 +00002334 AddObjCProperties(IFace->getSuperClass(), AllowCategories, CurContext,
2335 Results);
Douglas Gregor95ac6552009-11-18 01:29:26 +00002336 } else if (const ObjCCategoryDecl *Category
2337 = dyn_cast<ObjCCategoryDecl>(Container)) {
2338 // Look through protocols.
2339 for (ObjCInterfaceDecl::protocol_iterator P = Category->protocol_begin(),
2340 PEnd = Category->protocol_end();
2341 P != PEnd; ++P)
Douglas Gregor322328b2009-11-18 22:32:06 +00002342 AddObjCProperties(*P, AllowCategories, CurContext, Results);
Douglas Gregor95ac6552009-11-18 01:29:26 +00002343 }
2344}
2345
Douglas Gregor81b747b2009-09-17 21:32:03 +00002346void Sema::CodeCompleteMemberReferenceExpr(Scope *S, ExprTy *BaseE,
2347 SourceLocation OpLoc,
2348 bool IsArrow) {
2349 if (!BaseE || !CodeCompleter)
2350 return;
2351
Douglas Gregor86d9a522009-09-21 16:56:56 +00002352 typedef CodeCompleteConsumer::Result Result;
2353
Douglas Gregor81b747b2009-09-17 21:32:03 +00002354 Expr *Base = static_cast<Expr *>(BaseE);
2355 QualType BaseType = Base->getType();
Douglas Gregor86d9a522009-09-21 16:56:56 +00002356
2357 if (IsArrow) {
2358 if (const PointerType *Ptr = BaseType->getAs<PointerType>())
2359 BaseType = Ptr->getPointeeType();
2360 else if (BaseType->isObjCObjectPointerType())
2361 /*Do nothing*/ ;
2362 else
2363 return;
2364 }
2365
Douglas Gregoreb5758b2009-09-23 22:26:46 +00002366 ResultBuilder Results(*this, &ResultBuilder::IsMember);
Douglas Gregor95ac6552009-11-18 01:29:26 +00002367 Results.EnterNewScope();
2368 if (const RecordType *Record = BaseType->getAs<RecordType>()) {
2369 // Access to a C/C++ class, struct, or union.
Douglas Gregor45bcd432010-01-14 03:21:49 +00002370 Results.allowNestedNameSpecifiers();
Douglas Gregor0cc84042010-01-14 15:47:35 +00002371 CodeCompletionDeclConsumer Consumer(Results, CurContext);
2372 LookupVisibleDecls(Record->getDecl(), LookupMemberName, Consumer);
Daniel Dunbar3a2838d2009-11-13 08:58:20 +00002373
Douglas Gregor95ac6552009-11-18 01:29:26 +00002374 if (getLangOptions().CPlusPlus) {
2375 if (!Results.empty()) {
2376 // The "template" keyword can follow "->" or "." in the grammar.
2377 // However, we only want to suggest the template keyword if something
2378 // is dependent.
2379 bool IsDependent = BaseType->isDependentType();
2380 if (!IsDependent) {
2381 for (Scope *DepScope = S; DepScope; DepScope = DepScope->getParent())
2382 if (DeclContext *Ctx = (DeclContext *)DepScope->getEntity()) {
2383 IsDependent = Ctx->isDependentContext();
2384 break;
2385 }
2386 }
Daniel Dunbar3a2838d2009-11-13 08:58:20 +00002387
Douglas Gregor95ac6552009-11-18 01:29:26 +00002388 if (IsDependent)
Douglas Gregora4477812010-01-14 16:01:26 +00002389 Results.AddResult(Result("template"));
Daniel Dunbar3a2838d2009-11-13 08:58:20 +00002390 }
Daniel Dunbar3a2838d2009-11-13 08:58:20 +00002391 }
Douglas Gregor95ac6552009-11-18 01:29:26 +00002392 } else if (!IsArrow && BaseType->getAsObjCInterfacePointerType()) {
2393 // Objective-C property reference.
2394
2395 // Add property results based on our interface.
2396 const ObjCObjectPointerType *ObjCPtr
2397 = BaseType->getAsObjCInterfacePointerType();
2398 assert(ObjCPtr && "Non-NULL pointer guaranteed above!");
Douglas Gregor322328b2009-11-18 22:32:06 +00002399 AddObjCProperties(ObjCPtr->getInterfaceDecl(), true, CurContext, Results);
Douglas Gregor95ac6552009-11-18 01:29:26 +00002400
2401 // Add properties from the protocols in a qualified interface.
2402 for (ObjCObjectPointerType::qual_iterator I = ObjCPtr->qual_begin(),
2403 E = ObjCPtr->qual_end();
2404 I != E; ++I)
Douglas Gregor322328b2009-11-18 22:32:06 +00002405 AddObjCProperties(*I, true, CurContext, Results);
Douglas Gregor95ac6552009-11-18 01:29:26 +00002406 } else if ((IsArrow && BaseType->isObjCObjectPointerType()) ||
John McCallc12c5bb2010-05-15 11:32:37 +00002407 (!IsArrow && BaseType->isObjCObjectType())) {
Douglas Gregor95ac6552009-11-18 01:29:26 +00002408 // Objective-C instance variable access.
2409 ObjCInterfaceDecl *Class = 0;
2410 if (const ObjCObjectPointerType *ObjCPtr
2411 = BaseType->getAs<ObjCObjectPointerType>())
2412 Class = ObjCPtr->getInterfaceDecl();
2413 else
John McCallc12c5bb2010-05-15 11:32:37 +00002414 Class = BaseType->getAs<ObjCObjectType>()->getInterface();
Douglas Gregor95ac6552009-11-18 01:29:26 +00002415
2416 // Add all ivars from this class and its superclasses.
Douglas Gregor80f4f4c2010-01-14 16:08:12 +00002417 if (Class) {
2418 CodeCompletionDeclConsumer Consumer(Results, CurContext);
2419 Results.setFilter(&ResultBuilder::IsObjCIvar);
2420 LookupVisibleDecls(Class, LookupMemberName, Consumer);
Douglas Gregor95ac6552009-11-18 01:29:26 +00002421 }
Douglas Gregor86d9a522009-09-21 16:56:56 +00002422 }
Douglas Gregor95ac6552009-11-18 01:29:26 +00002423
2424 // FIXME: How do we cope with isa?
2425
2426 Results.ExitScope();
Daniel Dunbar3a2838d2009-11-13 08:58:20 +00002427
Daniel Dunbar3a2838d2009-11-13 08:58:20 +00002428 // Hand off the results found for code completion.
2429 HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
Douglas Gregor81b747b2009-09-17 21:32:03 +00002430}
2431
Douglas Gregor374929f2009-09-18 15:37:17 +00002432void Sema::CodeCompleteTag(Scope *S, unsigned TagSpec) {
2433 if (!CodeCompleter)
2434 return;
2435
Douglas Gregor86d9a522009-09-21 16:56:56 +00002436 typedef CodeCompleteConsumer::Result Result;
2437 ResultBuilder::LookupFilter Filter = 0;
Douglas Gregor374929f2009-09-18 15:37:17 +00002438 switch ((DeclSpec::TST)TagSpec) {
2439 case DeclSpec::TST_enum:
Douglas Gregor86d9a522009-09-21 16:56:56 +00002440 Filter = &ResultBuilder::IsEnum;
Douglas Gregor374929f2009-09-18 15:37:17 +00002441 break;
2442
2443 case DeclSpec::TST_union:
Douglas Gregor86d9a522009-09-21 16:56:56 +00002444 Filter = &ResultBuilder::IsUnion;
Douglas Gregor374929f2009-09-18 15:37:17 +00002445 break;
2446
2447 case DeclSpec::TST_struct:
Douglas Gregor374929f2009-09-18 15:37:17 +00002448 case DeclSpec::TST_class:
Douglas Gregor86d9a522009-09-21 16:56:56 +00002449 Filter = &ResultBuilder::IsClassOrStruct;
Douglas Gregor374929f2009-09-18 15:37:17 +00002450 break;
2451
2452 default:
2453 assert(false && "Unknown type specifier kind in CodeCompleteTag");
2454 return;
2455 }
Douglas Gregor86d9a522009-09-21 16:56:56 +00002456
John McCall0d6b1642010-04-23 18:46:30 +00002457 ResultBuilder Results(*this);
Douglas Gregor5d2fc402010-01-14 03:27:13 +00002458 CodeCompletionDeclConsumer Consumer(Results, CurContext);
John McCall0d6b1642010-04-23 18:46:30 +00002459
2460 // First pass: look for tags.
2461 Results.setFilter(Filter);
Douglas Gregor5d2fc402010-01-14 03:27:13 +00002462 LookupVisibleDecls(S, LookupTagName, Consumer);
John McCall0d6b1642010-04-23 18:46:30 +00002463
2464 // Second pass: look for nested name specifiers.
2465 Results.setFilter(&ResultBuilder::IsNestedNameSpecifier);
2466 LookupVisibleDecls(S, LookupNestedNameSpecifierName, Consumer);
Douglas Gregor86d9a522009-09-21 16:56:56 +00002467
Daniel Dunbar3a2838d2009-11-13 08:58:20 +00002468 HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
Douglas Gregor374929f2009-09-18 15:37:17 +00002469}
2470
Douglas Gregor3e1005f2009-09-21 18:10:23 +00002471void Sema::CodeCompleteCase(Scope *S) {
2472 if (getSwitchStack().empty() || !CodeCompleter)
2473 return;
2474
2475 SwitchStmt *Switch = getSwitchStack().back();
2476 if (!Switch->getCond()->getType()->isEnumeralType())
2477 return;
2478
2479 // Code-complete the cases of a switch statement over an enumeration type
2480 // by providing the list of
2481 EnumDecl *Enum = Switch->getCond()->getType()->getAs<EnumType>()->getDecl();
2482
2483 // Determine which enumerators we have already seen in the switch statement.
2484 // FIXME: Ideally, we would also be able to look *past* the code-completion
2485 // token, in case we are code-completing in the middle of the switch and not
2486 // at the end. However, we aren't able to do so at the moment.
2487 llvm::SmallPtrSet<EnumConstantDecl *, 8> EnumeratorsSeen;
Douglas Gregorb9d0ef72009-09-21 19:57:38 +00002488 NestedNameSpecifier *Qualifier = 0;
Douglas Gregor3e1005f2009-09-21 18:10:23 +00002489 for (SwitchCase *SC = Switch->getSwitchCaseList(); SC;
2490 SC = SC->getNextSwitchCase()) {
2491 CaseStmt *Case = dyn_cast<CaseStmt>(SC);
2492 if (!Case)
2493 continue;
2494
2495 Expr *CaseVal = Case->getLHS()->IgnoreParenCasts();
2496 if (DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(CaseVal))
2497 if (EnumConstantDecl *Enumerator
2498 = dyn_cast<EnumConstantDecl>(DRE->getDecl())) {
2499 // We look into the AST of the case statement to determine which
2500 // enumerator was named. Alternatively, we could compute the value of
2501 // the integral constant expression, then compare it against the
2502 // values of each enumerator. However, value-based approach would not
2503 // work as well with C++ templates where enumerators declared within a
2504 // template are type- and value-dependent.
2505 EnumeratorsSeen.insert(Enumerator);
2506
Douglas Gregorb9d0ef72009-09-21 19:57:38 +00002507 // If this is a qualified-id, keep track of the nested-name-specifier
2508 // so that we can reproduce it as part of code completion, e.g.,
Douglas Gregor3e1005f2009-09-21 18:10:23 +00002509 //
2510 // switch (TagD.getKind()) {
2511 // case TagDecl::TK_enum:
2512 // break;
2513 // case XXX
2514 //
Douglas Gregorb9d0ef72009-09-21 19:57:38 +00002515 // At the XXX, our completions are TagDecl::TK_union,
Douglas Gregor3e1005f2009-09-21 18:10:23 +00002516 // TagDecl::TK_struct, and TagDecl::TK_class, rather than TK_union,
2517 // TK_struct, and TK_class.
Douglas Gregora2813ce2009-10-23 18:54:35 +00002518 Qualifier = DRE->getQualifier();
Douglas Gregor3e1005f2009-09-21 18:10:23 +00002519 }
2520 }
2521
Douglas Gregorb9d0ef72009-09-21 19:57:38 +00002522 if (getLangOptions().CPlusPlus && !Qualifier && EnumeratorsSeen.empty()) {
2523 // If there are no prior enumerators in C++, check whether we have to
2524 // qualify the names of the enumerators that we suggest, because they
2525 // may not be visible in this scope.
2526 Qualifier = getRequiredQualification(Context, CurContext,
2527 Enum->getDeclContext());
2528
2529 // FIXME: Scoped enums need to start with "EnumDecl" as the context!
2530 }
2531
Douglas Gregor3e1005f2009-09-21 18:10:23 +00002532 // Add any enumerators that have not yet been mentioned.
2533 ResultBuilder Results(*this);
2534 Results.EnterNewScope();
2535 for (EnumDecl::enumerator_iterator E = Enum->enumerator_begin(),
2536 EEnd = Enum->enumerator_end();
2537 E != EEnd; ++E) {
2538 if (EnumeratorsSeen.count(*E))
2539 continue;
2540
Douglas Gregor608300b2010-01-14 16:14:35 +00002541 Results.AddResult(CodeCompleteConsumer::Result(*E, Qualifier),
2542 CurContext, 0, false);
Douglas Gregor3e1005f2009-09-21 18:10:23 +00002543 }
2544 Results.ExitScope();
Douglas Gregor2f880e42010-04-06 20:02:15 +00002545
Douglas Gregor0c8296d2009-11-07 00:00:49 +00002546 if (CodeCompleter->includeMacros())
Douglas Gregorbca403c2010-01-13 23:51:12 +00002547 AddMacroResults(PP, Results);
Daniel Dunbar3a2838d2009-11-13 08:58:20 +00002548 HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
Douglas Gregor3e1005f2009-09-21 18:10:23 +00002549}
2550
Douglas Gregor9c6a0e92009-09-22 15:41:20 +00002551namespace {
2552 struct IsBetterOverloadCandidate {
2553 Sema &S;
John McCall5769d612010-02-08 23:07:23 +00002554 SourceLocation Loc;
Douglas Gregor9c6a0e92009-09-22 15:41:20 +00002555
2556 public:
John McCall5769d612010-02-08 23:07:23 +00002557 explicit IsBetterOverloadCandidate(Sema &S, SourceLocation Loc)
2558 : S(S), Loc(Loc) { }
Douglas Gregor9c6a0e92009-09-22 15:41:20 +00002559
2560 bool
2561 operator()(const OverloadCandidate &X, const OverloadCandidate &Y) const {
John McCall5769d612010-02-08 23:07:23 +00002562 return S.isBetterOverloadCandidate(X, Y, Loc);
Douglas Gregor9c6a0e92009-09-22 15:41:20 +00002563 }
2564 };
2565}
2566
Douglas Gregord28dcd72010-05-30 06:10:08 +00002567static bool anyNullArguments(Expr **Args, unsigned NumArgs) {
2568 if (NumArgs && !Args)
2569 return true;
2570
2571 for (unsigned I = 0; I != NumArgs; ++I)
2572 if (!Args[I])
2573 return true;
2574
2575 return false;
2576}
2577
Douglas Gregor9c6a0e92009-09-22 15:41:20 +00002578void Sema::CodeCompleteCall(Scope *S, ExprTy *FnIn,
2579 ExprTy **ArgsIn, unsigned NumArgs) {
2580 if (!CodeCompleter)
2581 return;
Douglas Gregoref96eac2009-12-11 19:06:04 +00002582
2583 // When we're code-completing for a call, we fall back to ordinary
2584 // name code-completion whenever we can't produce specific
2585 // results. We may want to revisit this strategy in the future,
2586 // e.g., by merging the two kinds of results.
2587
Douglas Gregor9c6a0e92009-09-22 15:41:20 +00002588 Expr *Fn = (Expr *)FnIn;
2589 Expr **Args = (Expr **)ArgsIn;
Douglas Gregoref96eac2009-12-11 19:06:04 +00002590
Douglas Gregor9c6a0e92009-09-22 15:41:20 +00002591 // Ignore type-dependent call expressions entirely.
Douglas Gregord28dcd72010-05-30 06:10:08 +00002592 if (!Fn || Fn->isTypeDependent() || anyNullArguments(Args, NumArgs) ||
Douglas Gregoref96eac2009-12-11 19:06:04 +00002593 Expr::hasAnyTypeDependentArguments(Args, NumArgs)) {
Douglas Gregor01dfea02010-01-10 23:08:15 +00002594 CodeCompleteOrdinaryName(S, CCC_Expression);
Douglas Gregor9c6a0e92009-09-22 15:41:20 +00002595 return;
Douglas Gregoref96eac2009-12-11 19:06:04 +00002596 }
Douglas Gregor9c6a0e92009-09-22 15:41:20 +00002597
John McCall3b4294e2009-12-16 12:17:52 +00002598 // Build an overload candidate set based on the functions we find.
John McCall5769d612010-02-08 23:07:23 +00002599 SourceLocation Loc = Fn->getExprLoc();
2600 OverloadCandidateSet CandidateSet(Loc);
John McCall3b4294e2009-12-16 12:17:52 +00002601
Douglas Gregor9c6a0e92009-09-22 15:41:20 +00002602 // FIXME: What if we're calling something that isn't a function declaration?
2603 // FIXME: What if we're calling a pseudo-destructor?
2604 // FIXME: What if we're calling a member function?
2605
Douglas Gregorc0265402010-01-21 15:46:19 +00002606 typedef CodeCompleteConsumer::OverloadCandidate ResultCandidate;
2607 llvm::SmallVector<ResultCandidate, 8> Results;
2608
John McCall3b4294e2009-12-16 12:17:52 +00002609 Expr *NakedFn = Fn->IgnoreParenCasts();
2610 if (UnresolvedLookupExpr *ULE = dyn_cast<UnresolvedLookupExpr>(NakedFn))
2611 AddOverloadedCallCandidates(ULE, Args, NumArgs, CandidateSet,
2612 /*PartialOverloading=*/ true);
2613 else if (DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(NakedFn)) {
2614 FunctionDecl *FDecl = dyn_cast<FunctionDecl>(DRE->getDecl());
Douglas Gregorc0265402010-01-21 15:46:19 +00002615 if (FDecl) {
Douglas Gregord28dcd72010-05-30 06:10:08 +00002616 if (!getLangOptions().CPlusPlus ||
2617 !FDecl->getType()->getAs<FunctionProtoType>())
Douglas Gregorc0265402010-01-21 15:46:19 +00002618 Results.push_back(ResultCandidate(FDecl));
2619 else
John McCall86820f52010-01-26 01:37:31 +00002620 // FIXME: access?
John McCall9aa472c2010-03-19 07:35:19 +00002621 AddOverloadCandidate(FDecl, DeclAccessPair::make(FDecl, AS_none),
2622 Args, NumArgs, CandidateSet,
Douglas Gregorc27d6c52010-04-16 17:41:49 +00002623 false, /*PartialOverloading*/true);
Douglas Gregorc0265402010-01-21 15:46:19 +00002624 }
John McCall3b4294e2009-12-16 12:17:52 +00002625 }
Douglas Gregor9c6a0e92009-09-22 15:41:20 +00002626
Douglas Gregor5ac3bdb2010-05-30 01:49:25 +00002627 QualType ParamType;
2628
Douglas Gregorc0265402010-01-21 15:46:19 +00002629 if (!CandidateSet.empty()) {
2630 // Sort the overload candidate set by placing the best overloads first.
2631 std::stable_sort(CandidateSet.begin(), CandidateSet.end(),
John McCall5769d612010-02-08 23:07:23 +00002632 IsBetterOverloadCandidate(*this, Loc));
Douglas Gregor9c6a0e92009-09-22 15:41:20 +00002633
Douglas Gregorc0265402010-01-21 15:46:19 +00002634 // Add the remaining viable overload candidates as code-completion reslults.
2635 for (OverloadCandidateSet::iterator Cand = CandidateSet.begin(),
2636 CandEnd = CandidateSet.end();
2637 Cand != CandEnd; ++Cand) {
2638 if (Cand->Viable)
2639 Results.push_back(ResultCandidate(Cand->Function));
2640 }
Douglas Gregor5ac3bdb2010-05-30 01:49:25 +00002641
2642 // From the viable candidates, try to determine the type of this parameter.
2643 for (unsigned I = 0, N = Results.size(); I != N; ++I) {
2644 if (const FunctionType *FType = Results[I].getFunctionType())
2645 if (const FunctionProtoType *Proto = dyn_cast<FunctionProtoType>(FType))
2646 if (NumArgs < Proto->getNumArgs()) {
2647 if (ParamType.isNull())
2648 ParamType = Proto->getArgType(NumArgs);
2649 else if (!Context.hasSameUnqualifiedType(
2650 ParamType.getNonReferenceType(),
2651 Proto->getArgType(NumArgs).getNonReferenceType())) {
2652 ParamType = QualType();
2653 break;
2654 }
2655 }
2656 }
2657 } else {
2658 // Try to determine the parameter type from the type of the expression
2659 // being called.
2660 QualType FunctionType = Fn->getType();
2661 if (const PointerType *Ptr = FunctionType->getAs<PointerType>())
2662 FunctionType = Ptr->getPointeeType();
2663 else if (const BlockPointerType *BlockPtr
2664 = FunctionType->getAs<BlockPointerType>())
2665 FunctionType = BlockPtr->getPointeeType();
2666 else if (const MemberPointerType *MemPtr
2667 = FunctionType->getAs<MemberPointerType>())
2668 FunctionType = MemPtr->getPointeeType();
2669
2670 if (const FunctionProtoType *Proto
2671 = FunctionType->getAs<FunctionProtoType>()) {
2672 if (NumArgs < Proto->getNumArgs())
2673 ParamType = Proto->getArgType(NumArgs);
2674 }
Douglas Gregor9c6a0e92009-09-22 15:41:20 +00002675 }
Douglas Gregoref96eac2009-12-11 19:06:04 +00002676
Douglas Gregor5ac3bdb2010-05-30 01:49:25 +00002677 if (ParamType.isNull())
2678 CodeCompleteOrdinaryName(S, CCC_Expression);
2679 else
2680 CodeCompleteExpression(S, ParamType);
2681
Douglas Gregor2e4c7a52010-04-06 20:19:47 +00002682 if (!Results.empty())
Douglas Gregoref96eac2009-12-11 19:06:04 +00002683 CodeCompleter->ProcessOverloadCandidates(*this, NumArgs, Results.data(),
2684 Results.size());
Douglas Gregor9c6a0e92009-09-22 15:41:20 +00002685}
2686
Douglas Gregor5ac3bdb2010-05-30 01:49:25 +00002687void Sema::CodeCompleteInitializer(Scope *S, DeclPtrTy D) {
2688 ValueDecl *VD = dyn_cast_or_null<ValueDecl>(D.getAs<Decl>());
2689 if (!VD) {
2690 CodeCompleteOrdinaryName(S, CCC_Expression);
2691 return;
2692 }
2693
2694 CodeCompleteExpression(S, VD->getType());
2695}
2696
2697void Sema::CodeCompleteReturn(Scope *S) {
2698 QualType ResultType;
2699 if (isa<BlockDecl>(CurContext)) {
2700 if (BlockScopeInfo *BSI = getCurBlock())
2701 ResultType = BSI->ReturnType;
2702 } else if (FunctionDecl *Function = dyn_cast<FunctionDecl>(CurContext))
2703 ResultType = Function->getResultType();
2704 else if (ObjCMethodDecl *Method = dyn_cast<ObjCMethodDecl>(CurContext))
2705 ResultType = Method->getResultType();
2706
2707 if (ResultType.isNull())
2708 CodeCompleteOrdinaryName(S, CCC_Expression);
2709 else
2710 CodeCompleteExpression(S, ResultType);
2711}
2712
2713void Sema::CodeCompleteAssignmentRHS(Scope *S, ExprTy *LHS) {
2714 if (LHS)
2715 CodeCompleteExpression(S, static_cast<Expr *>(LHS)->getType());
2716 else
2717 CodeCompleteOrdinaryName(S, CCC_Expression);
2718}
2719
Jeffrey Yasskin9ab14542010-04-08 16:38:48 +00002720void Sema::CodeCompleteQualifiedId(Scope *S, CXXScopeSpec &SS,
Douglas Gregor81b747b2009-09-17 21:32:03 +00002721 bool EnteringContext) {
2722 if (!SS.getScopeRep() || !CodeCompleter)
2723 return;
2724
Douglas Gregor86d9a522009-09-21 16:56:56 +00002725 DeclContext *Ctx = computeDeclContext(SS, EnteringContext);
2726 if (!Ctx)
2727 return;
Douglas Gregord1cd31a2009-12-11 18:28:39 +00002728
2729 // Try to instantiate any non-dependent declaration contexts before
2730 // we look in them.
John McCall77bb1aa2010-05-01 00:40:08 +00002731 if (!isDependentScopeSpecifier(SS) && RequireCompleteDeclContext(SS, Ctx))
Douglas Gregord1cd31a2009-12-11 18:28:39 +00002732 return;
2733
Douglas Gregor86d9a522009-09-21 16:56:56 +00002734 ResultBuilder Results(*this);
Douglas Gregordef91072010-01-14 03:35:48 +00002735 CodeCompletionDeclConsumer Consumer(Results, CurContext);
2736 LookupVisibleDecls(Ctx, LookupOrdinaryName, Consumer);
Douglas Gregor86d9a522009-09-21 16:56:56 +00002737
2738 // The "template" keyword can follow "::" in the grammar, but only
2739 // put it into the grammar if the nested-name-specifier is dependent.
2740 NestedNameSpecifier *NNS = (NestedNameSpecifier *)SS.getScopeRep();
2741 if (!Results.empty() && NNS->isDependent())
Douglas Gregora4477812010-01-14 16:01:26 +00002742 Results.AddResult("template");
Douglas Gregor86d9a522009-09-21 16:56:56 +00002743
Daniel Dunbar3a2838d2009-11-13 08:58:20 +00002744 HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
Douglas Gregor81b747b2009-09-17 21:32:03 +00002745}
Douglas Gregor49f40bd2009-09-18 19:03:04 +00002746
2747void Sema::CodeCompleteUsing(Scope *S) {
2748 if (!CodeCompleter)
2749 return;
2750
Douglas Gregor86d9a522009-09-21 16:56:56 +00002751 ResultBuilder Results(*this, &ResultBuilder::IsNestedNameSpecifier);
Douglas Gregor8e0a0e42009-09-22 23:31:26 +00002752 Results.EnterNewScope();
Douglas Gregor86d9a522009-09-21 16:56:56 +00002753
2754 // If we aren't in class scope, we could see the "namespace" keyword.
2755 if (!S->isClassScope())
Douglas Gregora4477812010-01-14 16:01:26 +00002756 Results.AddResult(CodeCompleteConsumer::Result("namespace"));
Douglas Gregor86d9a522009-09-21 16:56:56 +00002757
2758 // After "using", we can see anything that would start a
2759 // nested-name-specifier.
Douglas Gregor5d2fc402010-01-14 03:27:13 +00002760 CodeCompletionDeclConsumer Consumer(Results, CurContext);
2761 LookupVisibleDecls(S, LookupOrdinaryName, Consumer);
Douglas Gregor8e0a0e42009-09-22 23:31:26 +00002762 Results.ExitScope();
Douglas Gregor86d9a522009-09-21 16:56:56 +00002763
Daniel Dunbar3a2838d2009-11-13 08:58:20 +00002764 HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
Douglas Gregor49f40bd2009-09-18 19:03:04 +00002765}
2766
2767void Sema::CodeCompleteUsingDirective(Scope *S) {
2768 if (!CodeCompleter)
2769 return;
2770
Douglas Gregor86d9a522009-09-21 16:56:56 +00002771 // After "using namespace", we expect to see a namespace name or namespace
2772 // alias.
2773 ResultBuilder Results(*this, &ResultBuilder::IsNamespaceOrAlias);
Douglas Gregor8e0a0e42009-09-22 23:31:26 +00002774 Results.EnterNewScope();
Douglas Gregor5d2fc402010-01-14 03:27:13 +00002775 CodeCompletionDeclConsumer Consumer(Results, CurContext);
2776 LookupVisibleDecls(S, LookupOrdinaryName, Consumer);
Douglas Gregor8e0a0e42009-09-22 23:31:26 +00002777 Results.ExitScope();
Daniel Dunbar3a2838d2009-11-13 08:58:20 +00002778 HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
Douglas Gregor49f40bd2009-09-18 19:03:04 +00002779}
2780
2781void Sema::CodeCompleteNamespaceDecl(Scope *S) {
2782 if (!CodeCompleter)
2783 return;
2784
Douglas Gregor86d9a522009-09-21 16:56:56 +00002785 ResultBuilder Results(*this, &ResultBuilder::IsNamespace);
2786 DeclContext *Ctx = (DeclContext *)S->getEntity();
2787 if (!S->getParent())
2788 Ctx = Context.getTranslationUnitDecl();
2789
2790 if (Ctx && Ctx->isFileContext()) {
2791 // We only want to see those namespaces that have already been defined
2792 // within this scope, because its likely that the user is creating an
2793 // extended namespace declaration. Keep track of the most recent
2794 // definition of each namespace.
2795 std::map<NamespaceDecl *, NamespaceDecl *> OrigToLatest;
2796 for (DeclContext::specific_decl_iterator<NamespaceDecl>
2797 NS(Ctx->decls_begin()), NSEnd(Ctx->decls_end());
2798 NS != NSEnd; ++NS)
2799 OrigToLatest[NS->getOriginalNamespace()] = *NS;
2800
2801 // Add the most recent definition (or extended definition) of each
2802 // namespace to the list of results.
Douglas Gregor8e0a0e42009-09-22 23:31:26 +00002803 Results.EnterNewScope();
Douglas Gregor86d9a522009-09-21 16:56:56 +00002804 for (std::map<NamespaceDecl *, NamespaceDecl *>::iterator
2805 NS = OrigToLatest.begin(), NSEnd = OrigToLatest.end();
2806 NS != NSEnd; ++NS)
Douglas Gregor608300b2010-01-14 16:14:35 +00002807 Results.AddResult(CodeCompleteConsumer::Result(NS->second, 0),
2808 CurContext, 0, false);
Douglas Gregor8e0a0e42009-09-22 23:31:26 +00002809 Results.ExitScope();
Douglas Gregor86d9a522009-09-21 16:56:56 +00002810 }
2811
Daniel Dunbar3a2838d2009-11-13 08:58:20 +00002812 HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
Douglas Gregor49f40bd2009-09-18 19:03:04 +00002813}
2814
2815void Sema::CodeCompleteNamespaceAliasDecl(Scope *S) {
2816 if (!CodeCompleter)
2817 return;
2818
Douglas Gregor86d9a522009-09-21 16:56:56 +00002819 // After "namespace", we expect to see a namespace or alias.
2820 ResultBuilder Results(*this, &ResultBuilder::IsNamespaceOrAlias);
Douglas Gregor5d2fc402010-01-14 03:27:13 +00002821 CodeCompletionDeclConsumer Consumer(Results, CurContext);
2822 LookupVisibleDecls(S, LookupOrdinaryName, Consumer);
Daniel Dunbar3a2838d2009-11-13 08:58:20 +00002823 HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
Douglas Gregor49f40bd2009-09-18 19:03:04 +00002824}
2825
Douglas Gregored8d3222009-09-18 20:05:18 +00002826void Sema::CodeCompleteOperatorName(Scope *S) {
2827 if (!CodeCompleter)
2828 return;
Douglas Gregor86d9a522009-09-21 16:56:56 +00002829
2830 typedef CodeCompleteConsumer::Result Result;
2831 ResultBuilder Results(*this, &ResultBuilder::IsType);
Douglas Gregor8e0a0e42009-09-22 23:31:26 +00002832 Results.EnterNewScope();
Douglas Gregored8d3222009-09-18 20:05:18 +00002833
Douglas Gregor86d9a522009-09-21 16:56:56 +00002834 // Add the names of overloadable operators.
2835#define OVERLOADED_OPERATOR(Name,Spelling,Token,Unary,Binary,MemberOnly) \
2836 if (std::strcmp(Spelling, "?")) \
Douglas Gregora4477812010-01-14 16:01:26 +00002837 Results.AddResult(Result(Spelling));
Douglas Gregor86d9a522009-09-21 16:56:56 +00002838#include "clang/Basic/OperatorKinds.def"
2839
2840 // Add any type names visible from the current scope
Douglas Gregor45bcd432010-01-14 03:21:49 +00002841 Results.allowNestedNameSpecifiers();
Douglas Gregor5d2fc402010-01-14 03:27:13 +00002842 CodeCompletionDeclConsumer Consumer(Results, CurContext);
2843 LookupVisibleDecls(S, LookupOrdinaryName, Consumer);
Douglas Gregor86d9a522009-09-21 16:56:56 +00002844
2845 // Add any type specifiers
Douglas Gregorbca403c2010-01-13 23:51:12 +00002846 AddTypeSpecifierResults(getLangOptions(), Results);
Douglas Gregor8e0a0e42009-09-22 23:31:26 +00002847 Results.ExitScope();
Douglas Gregor86d9a522009-09-21 16:56:56 +00002848
Daniel Dunbar3a2838d2009-11-13 08:58:20 +00002849 HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
Douglas Gregored8d3222009-09-18 20:05:18 +00002850}
Douglas Gregor49f40bd2009-09-18 19:03:04 +00002851
Douglas Gregorb6ac2452010-01-13 21:24:21 +00002852// Macro that expands to @Keyword or Keyword, depending on whether NeedAt is
2853// true or false.
2854#define OBJC_AT_KEYWORD_NAME(NeedAt,Keyword) NeedAt? "@" #Keyword : #Keyword
Douglas Gregorbca403c2010-01-13 23:51:12 +00002855static void AddObjCImplementationResults(const LangOptions &LangOpts,
Douglas Gregorb6ac2452010-01-13 21:24:21 +00002856 ResultBuilder &Results,
2857 bool NeedAt) {
2858 typedef CodeCompleteConsumer::Result Result;
2859 // Since we have an implementation, we can end it.
Douglas Gregora4477812010-01-14 16:01:26 +00002860 Results.AddResult(Result(OBJC_AT_KEYWORD_NAME(NeedAt,end)));
Douglas Gregorb6ac2452010-01-13 21:24:21 +00002861
2862 CodeCompletionString *Pattern = 0;
2863 if (LangOpts.ObjC2) {
2864 // @dynamic
2865 Pattern = new CodeCompletionString;
2866 Pattern->AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt,dynamic));
2867 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
2868 Pattern->AddPlaceholderChunk("property");
Douglas Gregora4477812010-01-14 16:01:26 +00002869 Results.AddResult(Result(Pattern));
Douglas Gregorb6ac2452010-01-13 21:24:21 +00002870
2871 // @synthesize
2872 Pattern = new CodeCompletionString;
2873 Pattern->AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt,synthesize));
2874 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
2875 Pattern->AddPlaceholderChunk("property");
Douglas Gregora4477812010-01-14 16:01:26 +00002876 Results.AddResult(Result(Pattern));
Douglas Gregorb6ac2452010-01-13 21:24:21 +00002877 }
2878}
2879
Douglas Gregorbca403c2010-01-13 23:51:12 +00002880static void AddObjCInterfaceResults(const LangOptions &LangOpts,
Douglas Gregorb6ac2452010-01-13 21:24:21 +00002881 ResultBuilder &Results,
2882 bool NeedAt) {
2883 typedef CodeCompleteConsumer::Result Result;
2884
2885 // Since we have an interface or protocol, we can end it.
Douglas Gregora4477812010-01-14 16:01:26 +00002886 Results.AddResult(Result(OBJC_AT_KEYWORD_NAME(NeedAt,end)));
Douglas Gregorb6ac2452010-01-13 21:24:21 +00002887
2888 if (LangOpts.ObjC2) {
2889 // @property
Douglas Gregora4477812010-01-14 16:01:26 +00002890 Results.AddResult(Result(OBJC_AT_KEYWORD_NAME(NeedAt,property)));
Douglas Gregorb6ac2452010-01-13 21:24:21 +00002891
2892 // @required
Douglas Gregora4477812010-01-14 16:01:26 +00002893 Results.AddResult(Result(OBJC_AT_KEYWORD_NAME(NeedAt,required)));
Douglas Gregorb6ac2452010-01-13 21:24:21 +00002894
2895 // @optional
Douglas Gregora4477812010-01-14 16:01:26 +00002896 Results.AddResult(Result(OBJC_AT_KEYWORD_NAME(NeedAt,optional)));
Douglas Gregorb6ac2452010-01-13 21:24:21 +00002897 }
2898}
2899
Douglas Gregorbca403c2010-01-13 23:51:12 +00002900static void AddObjCTopLevelResults(ResultBuilder &Results, bool NeedAt) {
Douglas Gregorb6ac2452010-01-13 21:24:21 +00002901 typedef CodeCompleteConsumer::Result Result;
2902 CodeCompletionString *Pattern = 0;
2903
2904 // @class name ;
2905 Pattern = new CodeCompletionString;
2906 Pattern->AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt,class));
2907 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
Douglas Gregorc8bddde2010-05-28 00:22:41 +00002908 Pattern->AddPlaceholderChunk("name");
Douglas Gregora4477812010-01-14 16:01:26 +00002909 Results.AddResult(Result(Pattern));
Douglas Gregorb6ac2452010-01-13 21:24:21 +00002910
Douglas Gregorc8bddde2010-05-28 00:22:41 +00002911 if (Results.includeCodePatterns()) {
2912 // @interface name
2913 // FIXME: Could introduce the whole pattern, including superclasses and
2914 // such.
2915 Pattern = new CodeCompletionString;
2916 Pattern->AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt,interface));
2917 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
2918 Pattern->AddPlaceholderChunk("class");
2919 Results.AddResult(Result(Pattern));
Douglas Gregorb6ac2452010-01-13 21:24:21 +00002920
Douglas Gregorc8bddde2010-05-28 00:22:41 +00002921 // @protocol name
2922 Pattern = new CodeCompletionString;
2923 Pattern->AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt,protocol));
2924 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
2925 Pattern->AddPlaceholderChunk("protocol");
2926 Results.AddResult(Result(Pattern));
2927
2928 // @implementation name
2929 Pattern = new CodeCompletionString;
2930 Pattern->AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt,implementation));
2931 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
2932 Pattern->AddPlaceholderChunk("class");
2933 Results.AddResult(Result(Pattern));
2934 }
Douglas Gregorb6ac2452010-01-13 21:24:21 +00002935
2936 // @compatibility_alias name
2937 Pattern = new CodeCompletionString;
2938 Pattern->AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt,compatibility_alias));
2939 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
2940 Pattern->AddPlaceholderChunk("alias");
2941 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
2942 Pattern->AddPlaceholderChunk("class");
Douglas Gregora4477812010-01-14 16:01:26 +00002943 Results.AddResult(Result(Pattern));
Douglas Gregorb6ac2452010-01-13 21:24:21 +00002944}
2945
Douglas Gregorc464ae82009-12-07 09:27:33 +00002946void Sema::CodeCompleteObjCAtDirective(Scope *S, DeclPtrTy ObjCImpDecl,
2947 bool InInterface) {
2948 typedef CodeCompleteConsumer::Result Result;
2949 ResultBuilder Results(*this);
2950 Results.EnterNewScope();
Douglas Gregorb6ac2452010-01-13 21:24:21 +00002951 if (ObjCImpDecl)
Douglas Gregorbca403c2010-01-13 23:51:12 +00002952 AddObjCImplementationResults(getLangOptions(), Results, false);
Douglas Gregorb6ac2452010-01-13 21:24:21 +00002953 else if (InInterface)
Douglas Gregorbca403c2010-01-13 23:51:12 +00002954 AddObjCInterfaceResults(getLangOptions(), Results, false);
Douglas Gregorb6ac2452010-01-13 21:24:21 +00002955 else
Douglas Gregorbca403c2010-01-13 23:51:12 +00002956 AddObjCTopLevelResults(Results, false);
Douglas Gregorc464ae82009-12-07 09:27:33 +00002957 Results.ExitScope();
2958 HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
2959}
2960
Douglas Gregorbca403c2010-01-13 23:51:12 +00002961static void AddObjCExpressionResults(ResultBuilder &Results, bool NeedAt) {
Douglas Gregor9a0c85e2009-12-07 09:51:25 +00002962 typedef CodeCompleteConsumer::Result Result;
2963 CodeCompletionString *Pattern = 0;
2964
2965 // @encode ( type-name )
2966 Pattern = new CodeCompletionString;
Douglas Gregorb6ac2452010-01-13 21:24:21 +00002967 Pattern->AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt,encode));
Douglas Gregor9a0c85e2009-12-07 09:51:25 +00002968 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
2969 Pattern->AddPlaceholderChunk("type-name");
2970 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
Douglas Gregora4477812010-01-14 16:01:26 +00002971 Results.AddResult(Result(Pattern));
Douglas Gregor9a0c85e2009-12-07 09:51:25 +00002972
2973 // @protocol ( protocol-name )
2974 Pattern = new CodeCompletionString;
Douglas Gregorb6ac2452010-01-13 21:24:21 +00002975 Pattern->AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt,protocol));
Douglas Gregor9a0c85e2009-12-07 09:51:25 +00002976 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
2977 Pattern->AddPlaceholderChunk("protocol-name");
2978 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
Douglas Gregora4477812010-01-14 16:01:26 +00002979 Results.AddResult(Result(Pattern));
Douglas Gregor9a0c85e2009-12-07 09:51:25 +00002980
2981 // @selector ( selector )
2982 Pattern = new CodeCompletionString;
Douglas Gregorb6ac2452010-01-13 21:24:21 +00002983 Pattern->AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt,selector));
Douglas Gregor9a0c85e2009-12-07 09:51:25 +00002984 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
2985 Pattern->AddPlaceholderChunk("selector");
2986 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
Douglas Gregora4477812010-01-14 16:01:26 +00002987 Results.AddResult(Result(Pattern));
Douglas Gregor9a0c85e2009-12-07 09:51:25 +00002988}
2989
Douglas Gregorbca403c2010-01-13 23:51:12 +00002990static void AddObjCStatementResults(ResultBuilder &Results, bool NeedAt) {
Douglas Gregor9a0c85e2009-12-07 09:51:25 +00002991 typedef CodeCompleteConsumer::Result Result;
Douglas Gregor9a0c85e2009-12-07 09:51:25 +00002992 CodeCompletionString *Pattern = 0;
Douglas Gregorb6ac2452010-01-13 21:24:21 +00002993
Douglas Gregorc8bddde2010-05-28 00:22:41 +00002994 if (Results.includeCodePatterns()) {
2995 // @try { statements } @catch ( declaration ) { statements } @finally
2996 // { statements }
2997 Pattern = new CodeCompletionString;
2998 Pattern->AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt,try));
2999 Pattern->AddChunk(CodeCompletionString::CK_LeftBrace);
3000 Pattern->AddPlaceholderChunk("statements");
3001 Pattern->AddChunk(CodeCompletionString::CK_RightBrace);
3002 Pattern->AddTextChunk("@catch");
3003 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
3004 Pattern->AddPlaceholderChunk("parameter");
3005 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
3006 Pattern->AddChunk(CodeCompletionString::CK_LeftBrace);
3007 Pattern->AddPlaceholderChunk("statements");
3008 Pattern->AddChunk(CodeCompletionString::CK_RightBrace);
3009 Pattern->AddTextChunk("@finally");
3010 Pattern->AddChunk(CodeCompletionString::CK_LeftBrace);
3011 Pattern->AddPlaceholderChunk("statements");
3012 Pattern->AddChunk(CodeCompletionString::CK_RightBrace);
3013 Results.AddResult(Result(Pattern));
3014 }
Douglas Gregorb6ac2452010-01-13 21:24:21 +00003015
Douglas Gregor9a0c85e2009-12-07 09:51:25 +00003016 // @throw
3017 Pattern = new CodeCompletionString;
Douglas Gregorb6ac2452010-01-13 21:24:21 +00003018 Pattern->AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt,throw));
Douglas Gregor834389b2010-01-12 06:38:28 +00003019 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
Douglas Gregor9a0c85e2009-12-07 09:51:25 +00003020 Pattern->AddPlaceholderChunk("expression");
Douglas Gregora4477812010-01-14 16:01:26 +00003021 Results.AddResult(Result(Pattern));
Douglas Gregorb6ac2452010-01-13 21:24:21 +00003022
Douglas Gregorc8bddde2010-05-28 00:22:41 +00003023 if (Results.includeCodePatterns()) {
3024 // @synchronized ( expression ) { statements }
3025 Pattern = new CodeCompletionString;
3026 Pattern->AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt,synchronized));
3027 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
3028 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
3029 Pattern->AddPlaceholderChunk("expression");
3030 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
3031 Pattern->AddChunk(CodeCompletionString::CK_LeftBrace);
3032 Pattern->AddPlaceholderChunk("statements");
3033 Pattern->AddChunk(CodeCompletionString::CK_RightBrace);
3034 Results.AddResult(Result(Pattern));
3035 }
Douglas Gregorb6ac2452010-01-13 21:24:21 +00003036}
Douglas Gregor9a0c85e2009-12-07 09:51:25 +00003037
Douglas Gregorbca403c2010-01-13 23:51:12 +00003038static void AddObjCVisibilityResults(const LangOptions &LangOpts,
Douglas Gregorc38c3e12010-01-13 21:54:15 +00003039 ResultBuilder &Results,
3040 bool NeedAt) {
Douglas Gregorb6ac2452010-01-13 21:24:21 +00003041 typedef CodeCompleteConsumer::Result Result;
Douglas Gregora4477812010-01-14 16:01:26 +00003042 Results.AddResult(Result(OBJC_AT_KEYWORD_NAME(NeedAt,private)));
3043 Results.AddResult(Result(OBJC_AT_KEYWORD_NAME(NeedAt,protected)));
3044 Results.AddResult(Result(OBJC_AT_KEYWORD_NAME(NeedAt,public)));
Douglas Gregorc38c3e12010-01-13 21:54:15 +00003045 if (LangOpts.ObjC2)
Douglas Gregora4477812010-01-14 16:01:26 +00003046 Results.AddResult(Result(OBJC_AT_KEYWORD_NAME(NeedAt,package)));
Douglas Gregorc38c3e12010-01-13 21:54:15 +00003047}
3048
3049void Sema::CodeCompleteObjCAtVisibility(Scope *S) {
3050 ResultBuilder Results(*this);
3051 Results.EnterNewScope();
Douglas Gregorbca403c2010-01-13 23:51:12 +00003052 AddObjCVisibilityResults(getLangOptions(), Results, false);
Douglas Gregorc38c3e12010-01-13 21:54:15 +00003053 Results.ExitScope();
3054 HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
3055}
3056
3057void Sema::CodeCompleteObjCAtStatement(Scope *S) {
Douglas Gregorb6ac2452010-01-13 21:24:21 +00003058 ResultBuilder Results(*this);
3059 Results.EnterNewScope();
Douglas Gregorbca403c2010-01-13 23:51:12 +00003060 AddObjCStatementResults(Results, false);
3061 AddObjCExpressionResults(Results, false);
Douglas Gregor9a0c85e2009-12-07 09:51:25 +00003062 Results.ExitScope();
3063 HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
3064}
3065
3066void Sema::CodeCompleteObjCAtExpression(Scope *S) {
3067 ResultBuilder Results(*this);
3068 Results.EnterNewScope();
Douglas Gregorbca403c2010-01-13 23:51:12 +00003069 AddObjCExpressionResults(Results, false);
Douglas Gregor9a0c85e2009-12-07 09:51:25 +00003070 Results.ExitScope();
3071 HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
3072}
3073
Douglas Gregor988358f2009-11-19 00:14:45 +00003074/// \brief Determine whether the addition of the given flag to an Objective-C
3075/// property's attributes will cause a conflict.
3076static bool ObjCPropertyFlagConflicts(unsigned Attributes, unsigned NewFlag) {
3077 // Check if we've already added this flag.
3078 if (Attributes & NewFlag)
3079 return true;
3080
3081 Attributes |= NewFlag;
3082
3083 // Check for collisions with "readonly".
3084 if ((Attributes & ObjCDeclSpec::DQ_PR_readonly) &&
3085 (Attributes & (ObjCDeclSpec::DQ_PR_readwrite |
3086 ObjCDeclSpec::DQ_PR_assign |
3087 ObjCDeclSpec::DQ_PR_copy |
3088 ObjCDeclSpec::DQ_PR_retain)))
3089 return true;
3090
3091 // Check for more than one of { assign, copy, retain }.
3092 unsigned AssignCopyRetMask = Attributes & (ObjCDeclSpec::DQ_PR_assign |
3093 ObjCDeclSpec::DQ_PR_copy |
3094 ObjCDeclSpec::DQ_PR_retain);
3095 if (AssignCopyRetMask &&
3096 AssignCopyRetMask != ObjCDeclSpec::DQ_PR_assign &&
3097 AssignCopyRetMask != ObjCDeclSpec::DQ_PR_copy &&
3098 AssignCopyRetMask != ObjCDeclSpec::DQ_PR_retain)
3099 return true;
3100
3101 return false;
3102}
3103
Douglas Gregora93b1082009-11-18 23:08:07 +00003104void Sema::CodeCompleteObjCPropertyFlags(Scope *S, ObjCDeclSpec &ODS) {
Steve Naroffece8e712009-10-08 21:55:05 +00003105 if (!CodeCompleter)
3106 return;
Douglas Gregord3c68542009-11-19 01:08:35 +00003107
Steve Naroffece8e712009-10-08 21:55:05 +00003108 unsigned Attributes = ODS.getPropertyAttributes();
3109
3110 typedef CodeCompleteConsumer::Result Result;
3111 ResultBuilder Results(*this);
3112 Results.EnterNewScope();
Douglas Gregor988358f2009-11-19 00:14:45 +00003113 if (!ObjCPropertyFlagConflicts(Attributes, ObjCDeclSpec::DQ_PR_readonly))
Douglas Gregora4477812010-01-14 16:01:26 +00003114 Results.AddResult(CodeCompleteConsumer::Result("readonly"));
Douglas Gregor988358f2009-11-19 00:14:45 +00003115 if (!ObjCPropertyFlagConflicts(Attributes, ObjCDeclSpec::DQ_PR_assign))
Douglas Gregora4477812010-01-14 16:01:26 +00003116 Results.AddResult(CodeCompleteConsumer::Result("assign"));
Douglas Gregor988358f2009-11-19 00:14:45 +00003117 if (!ObjCPropertyFlagConflicts(Attributes, ObjCDeclSpec::DQ_PR_readwrite))
Douglas Gregora4477812010-01-14 16:01:26 +00003118 Results.AddResult(CodeCompleteConsumer::Result("readwrite"));
Douglas Gregor988358f2009-11-19 00:14:45 +00003119 if (!ObjCPropertyFlagConflicts(Attributes, ObjCDeclSpec::DQ_PR_retain))
Douglas Gregora4477812010-01-14 16:01:26 +00003120 Results.AddResult(CodeCompleteConsumer::Result("retain"));
Douglas Gregor988358f2009-11-19 00:14:45 +00003121 if (!ObjCPropertyFlagConflicts(Attributes, ObjCDeclSpec::DQ_PR_copy))
Douglas Gregora4477812010-01-14 16:01:26 +00003122 Results.AddResult(CodeCompleteConsumer::Result("copy"));
Douglas Gregor988358f2009-11-19 00:14:45 +00003123 if (!ObjCPropertyFlagConflicts(Attributes, ObjCDeclSpec::DQ_PR_nonatomic))
Douglas Gregora4477812010-01-14 16:01:26 +00003124 Results.AddResult(CodeCompleteConsumer::Result("nonatomic"));
Douglas Gregor988358f2009-11-19 00:14:45 +00003125 if (!ObjCPropertyFlagConflicts(Attributes, ObjCDeclSpec::DQ_PR_setter)) {
Douglas Gregor54f01612009-11-19 00:01:57 +00003126 CodeCompletionString *Setter = new CodeCompletionString;
3127 Setter->AddTypedTextChunk("setter");
3128 Setter->AddTextChunk(" = ");
3129 Setter->AddPlaceholderChunk("method");
Douglas Gregora4477812010-01-14 16:01:26 +00003130 Results.AddResult(CodeCompleteConsumer::Result(Setter));
Douglas Gregor54f01612009-11-19 00:01:57 +00003131 }
Douglas Gregor988358f2009-11-19 00:14:45 +00003132 if (!ObjCPropertyFlagConflicts(Attributes, ObjCDeclSpec::DQ_PR_getter)) {
Douglas Gregor54f01612009-11-19 00:01:57 +00003133 CodeCompletionString *Getter = new CodeCompletionString;
3134 Getter->AddTypedTextChunk("getter");
3135 Getter->AddTextChunk(" = ");
3136 Getter->AddPlaceholderChunk("method");
Douglas Gregora4477812010-01-14 16:01:26 +00003137 Results.AddResult(CodeCompleteConsumer::Result(Getter));
Douglas Gregor54f01612009-11-19 00:01:57 +00003138 }
Steve Naroffece8e712009-10-08 21:55:05 +00003139 Results.ExitScope();
Daniel Dunbar3a2838d2009-11-13 08:58:20 +00003140 HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
Steve Naroffece8e712009-10-08 21:55:05 +00003141}
Steve Naroffc4df6d22009-11-07 02:08:14 +00003142
Douglas Gregor4ad96852009-11-19 07:41:15 +00003143/// \brief Descripts the kind of Objective-C method that we want to find
3144/// via code completion.
3145enum ObjCMethodKind {
3146 MK_Any, //< Any kind of method, provided it means other specified criteria.
3147 MK_ZeroArgSelector, //< Zero-argument (unary) selector.
3148 MK_OneArgSelector //< One-argument selector.
3149};
3150
3151static bool isAcceptableObjCMethod(ObjCMethodDecl *Method,
3152 ObjCMethodKind WantKind,
3153 IdentifierInfo **SelIdents,
3154 unsigned NumSelIdents) {
3155 Selector Sel = Method->getSelector();
3156 if (NumSelIdents > Sel.getNumArgs())
3157 return false;
3158
3159 switch (WantKind) {
3160 case MK_Any: break;
3161 case MK_ZeroArgSelector: return Sel.isUnarySelector();
3162 case MK_OneArgSelector: return Sel.getNumArgs() == 1;
3163 }
3164
3165 for (unsigned I = 0; I != NumSelIdents; ++I)
3166 if (SelIdents[I] != Sel.getIdentifierInfoForSlot(I))
3167 return false;
3168
3169 return true;
3170}
3171
Douglas Gregor36ecb042009-11-17 23:22:23 +00003172/// \brief Add all of the Objective-C methods in the given Objective-C
3173/// container to the set of results.
3174///
3175/// The container will be a class, protocol, category, or implementation of
3176/// any of the above. This mether will recurse to include methods from
3177/// the superclasses of classes along with their categories, protocols, and
3178/// implementations.
3179///
3180/// \param Container the container in which we'll look to find methods.
3181///
3182/// \param WantInstance whether to add instance methods (only); if false, this
3183/// routine will add factory methods (only).
3184///
3185/// \param CurContext the context in which we're performing the lookup that
3186/// finds methods.
3187///
3188/// \param Results the structure into which we'll add results.
3189static void AddObjCMethods(ObjCContainerDecl *Container,
3190 bool WantInstanceMethods,
Douglas Gregor4ad96852009-11-19 07:41:15 +00003191 ObjCMethodKind WantKind,
Douglas Gregord3c68542009-11-19 01:08:35 +00003192 IdentifierInfo **SelIdents,
3193 unsigned NumSelIdents,
Douglas Gregor36ecb042009-11-17 23:22:23 +00003194 DeclContext *CurContext,
3195 ResultBuilder &Results) {
3196 typedef CodeCompleteConsumer::Result Result;
3197 for (ObjCContainerDecl::method_iterator M = Container->meth_begin(),
3198 MEnd = Container->meth_end();
3199 M != MEnd; ++M) {
Douglas Gregord3c68542009-11-19 01:08:35 +00003200 if ((*M)->isInstanceMethod() == WantInstanceMethods) {
3201 // Check whether the selector identifiers we've been given are a
3202 // subset of the identifiers for this particular method.
Douglas Gregor4ad96852009-11-19 07:41:15 +00003203 if (!isAcceptableObjCMethod(*M, WantKind, SelIdents, NumSelIdents))
Douglas Gregord3c68542009-11-19 01:08:35 +00003204 continue;
Douglas Gregor4ad96852009-11-19 07:41:15 +00003205
Douglas Gregord3c68542009-11-19 01:08:35 +00003206 Result R = Result(*M, 0);
3207 R.StartParameter = NumSelIdents;
Douglas Gregor4ad96852009-11-19 07:41:15 +00003208 R.AllParametersAreInformative = (WantKind != MK_Any);
Douglas Gregord3c68542009-11-19 01:08:35 +00003209 Results.MaybeAddResult(R, CurContext);
3210 }
Douglas Gregor36ecb042009-11-17 23:22:23 +00003211 }
3212
3213 ObjCInterfaceDecl *IFace = dyn_cast<ObjCInterfaceDecl>(Container);
3214 if (!IFace)
3215 return;
3216
3217 // Add methods in protocols.
3218 const ObjCList<ObjCProtocolDecl> &Protocols= IFace->getReferencedProtocols();
3219 for (ObjCList<ObjCProtocolDecl>::iterator I = Protocols.begin(),
3220 E = Protocols.end();
3221 I != E; ++I)
Douglas Gregor4ad96852009-11-19 07:41:15 +00003222 AddObjCMethods(*I, WantInstanceMethods, WantKind, SelIdents, NumSelIdents,
Douglas Gregord3c68542009-11-19 01:08:35 +00003223 CurContext, Results);
Douglas Gregor36ecb042009-11-17 23:22:23 +00003224
3225 // Add methods in categories.
3226 for (ObjCCategoryDecl *CatDecl = IFace->getCategoryList(); CatDecl;
3227 CatDecl = CatDecl->getNextClassCategory()) {
Douglas Gregor4ad96852009-11-19 07:41:15 +00003228 AddObjCMethods(CatDecl, WantInstanceMethods, WantKind, SelIdents,
3229 NumSelIdents, CurContext, Results);
Douglas Gregor36ecb042009-11-17 23:22:23 +00003230
3231 // Add a categories protocol methods.
3232 const ObjCList<ObjCProtocolDecl> &Protocols
3233 = CatDecl->getReferencedProtocols();
3234 for (ObjCList<ObjCProtocolDecl>::iterator I = Protocols.begin(),
3235 E = Protocols.end();
3236 I != E; ++I)
Douglas Gregor4ad96852009-11-19 07:41:15 +00003237 AddObjCMethods(*I, WantInstanceMethods, WantKind, SelIdents,
3238 NumSelIdents, CurContext, Results);
Douglas Gregor36ecb042009-11-17 23:22:23 +00003239
3240 // Add methods in category implementations.
3241 if (ObjCCategoryImplDecl *Impl = CatDecl->getImplementation())
Douglas Gregor4ad96852009-11-19 07:41:15 +00003242 AddObjCMethods(Impl, WantInstanceMethods, WantKind, SelIdents,
3243 NumSelIdents, CurContext, Results);
Douglas Gregor36ecb042009-11-17 23:22:23 +00003244 }
3245
3246 // Add methods in superclass.
3247 if (IFace->getSuperClass())
Douglas Gregor4ad96852009-11-19 07:41:15 +00003248 AddObjCMethods(IFace->getSuperClass(), WantInstanceMethods, WantKind,
3249 SelIdents, NumSelIdents, CurContext, Results);
Douglas Gregor36ecb042009-11-17 23:22:23 +00003250
3251 // Add methods in our implementation, if any.
3252 if (ObjCImplementationDecl *Impl = IFace->getImplementation())
Douglas Gregor4ad96852009-11-19 07:41:15 +00003253 AddObjCMethods(Impl, WantInstanceMethods, WantKind, SelIdents,
3254 NumSelIdents, CurContext, Results);
3255}
3256
3257
3258void Sema::CodeCompleteObjCPropertyGetter(Scope *S, DeclPtrTy ClassDecl,
3259 DeclPtrTy *Methods,
3260 unsigned NumMethods) {
3261 typedef CodeCompleteConsumer::Result Result;
3262
3263 // Try to find the interface where getters might live.
3264 ObjCInterfaceDecl *Class
3265 = dyn_cast_or_null<ObjCInterfaceDecl>(ClassDecl.getAs<Decl>());
3266 if (!Class) {
3267 if (ObjCCategoryDecl *Category
3268 = dyn_cast_or_null<ObjCCategoryDecl>(ClassDecl.getAs<Decl>()))
3269 Class = Category->getClassInterface();
3270
3271 if (!Class)
3272 return;
3273 }
3274
3275 // Find all of the potential getters.
3276 ResultBuilder Results(*this);
3277 Results.EnterNewScope();
3278
3279 // FIXME: We need to do this because Objective-C methods don't get
3280 // pushed into DeclContexts early enough. Argh!
3281 for (unsigned I = 0; I != NumMethods; ++I) {
3282 if (ObjCMethodDecl *Method
3283 = dyn_cast_or_null<ObjCMethodDecl>(Methods[I].getAs<Decl>()))
3284 if (Method->isInstanceMethod() &&
3285 isAcceptableObjCMethod(Method, MK_ZeroArgSelector, 0, 0)) {
3286 Result R = Result(Method, 0);
3287 R.AllParametersAreInformative = true;
3288 Results.MaybeAddResult(R, CurContext);
3289 }
3290 }
3291
3292 AddObjCMethods(Class, true, MK_ZeroArgSelector, 0, 0, CurContext, Results);
3293 Results.ExitScope();
3294 HandleCodeCompleteResults(this, CodeCompleter,Results.data(),Results.size());
3295}
3296
3297void Sema::CodeCompleteObjCPropertySetter(Scope *S, DeclPtrTy ObjCImplDecl,
3298 DeclPtrTy *Methods,
3299 unsigned NumMethods) {
3300 typedef CodeCompleteConsumer::Result Result;
3301
3302 // Try to find the interface where setters might live.
3303 ObjCInterfaceDecl *Class
3304 = dyn_cast_or_null<ObjCInterfaceDecl>(ObjCImplDecl.getAs<Decl>());
3305 if (!Class) {
3306 if (ObjCCategoryDecl *Category
3307 = dyn_cast_or_null<ObjCCategoryDecl>(ObjCImplDecl.getAs<Decl>()))
3308 Class = Category->getClassInterface();
3309
3310 if (!Class)
3311 return;
3312 }
3313
3314 // Find all of the potential getters.
3315 ResultBuilder Results(*this);
3316 Results.EnterNewScope();
3317
3318 // FIXME: We need to do this because Objective-C methods don't get
3319 // pushed into DeclContexts early enough. Argh!
3320 for (unsigned I = 0; I != NumMethods; ++I) {
3321 if (ObjCMethodDecl *Method
3322 = dyn_cast_or_null<ObjCMethodDecl>(Methods[I].getAs<Decl>()))
3323 if (Method->isInstanceMethod() &&
3324 isAcceptableObjCMethod(Method, MK_OneArgSelector, 0, 0)) {
3325 Result R = Result(Method, 0);
3326 R.AllParametersAreInformative = true;
3327 Results.MaybeAddResult(R, CurContext);
3328 }
3329 }
3330
3331 AddObjCMethods(Class, true, MK_OneArgSelector, 0, 0, CurContext, Results);
3332
3333 Results.ExitScope();
3334 HandleCodeCompleteResults(this, CodeCompleter,Results.data(),Results.size());
Douglas Gregor36ecb042009-11-17 23:22:23 +00003335}
3336
Douglas Gregor22f56992010-04-06 19:22:33 +00003337/// \brief When we have an expression with type "id", we may assume
3338/// that it has some more-specific class type based on knowledge of
3339/// common uses of Objective-C. This routine returns that class type,
3340/// or NULL if no better result could be determined.
3341static ObjCInterfaceDecl *GetAssumedMessageSendExprType(Expr *E) {
3342 ObjCMessageExpr *Msg = dyn_cast<ObjCMessageExpr>(E);
3343 if (!Msg)
3344 return 0;
3345
3346 Selector Sel = Msg->getSelector();
3347 if (Sel.isNull())
3348 return 0;
3349
3350 IdentifierInfo *Id = Sel.getIdentifierInfoForSlot(0);
3351 if (!Id)
3352 return 0;
3353
3354 ObjCMethodDecl *Method = Msg->getMethodDecl();
3355 if (!Method)
3356 return 0;
3357
3358 // Determine the class that we're sending the message to.
Douglas Gregor04badcf2010-04-21 00:45:42 +00003359 ObjCInterfaceDecl *IFace = 0;
3360 switch (Msg->getReceiverKind()) {
3361 case ObjCMessageExpr::Class:
John McCallc12c5bb2010-05-15 11:32:37 +00003362 if (const ObjCObjectType *ObjType
3363 = Msg->getClassReceiver()->getAs<ObjCObjectType>())
3364 IFace = ObjType->getInterface();
Douglas Gregor04badcf2010-04-21 00:45:42 +00003365 break;
3366
3367 case ObjCMessageExpr::Instance: {
3368 QualType T = Msg->getInstanceReceiver()->getType();
3369 if (const ObjCObjectPointerType *Ptr = T->getAs<ObjCObjectPointerType>())
3370 IFace = Ptr->getInterfaceDecl();
3371 break;
3372 }
3373
3374 case ObjCMessageExpr::SuperInstance:
3375 case ObjCMessageExpr::SuperClass:
3376 break;
Douglas Gregor22f56992010-04-06 19:22:33 +00003377 }
3378
3379 if (!IFace)
3380 return 0;
3381
3382 ObjCInterfaceDecl *Super = IFace->getSuperClass();
3383 if (Method->isInstanceMethod())
3384 return llvm::StringSwitch<ObjCInterfaceDecl *>(Id->getName())
3385 .Case("retain", IFace)
3386 .Case("autorelease", IFace)
3387 .Case("copy", IFace)
3388 .Case("copyWithZone", IFace)
3389 .Case("mutableCopy", IFace)
3390 .Case("mutableCopyWithZone", IFace)
3391 .Case("awakeFromCoder", IFace)
3392 .Case("replacementObjectFromCoder", IFace)
3393 .Case("class", IFace)
3394 .Case("classForCoder", IFace)
3395 .Case("superclass", Super)
3396 .Default(0);
3397
3398 return llvm::StringSwitch<ObjCInterfaceDecl *>(Id->getName())
3399 .Case("new", IFace)
3400 .Case("alloc", IFace)
3401 .Case("allocWithZone", IFace)
3402 .Case("class", IFace)
3403 .Case("superclass", Super)
3404 .Default(0);
3405}
3406
Douglas Gregor8e254cf2010-05-27 23:06:34 +00003407void Sema::CodeCompleteObjCMessageReceiver(Scope *S) {
3408 typedef CodeCompleteConsumer::Result Result;
3409 ResultBuilder Results(*this);
3410
3411 // Find anything that looks like it could be a message receiver.
3412 Results.setFilter(&ResultBuilder::IsObjCMessageReceiver);
3413 CodeCompletionDeclConsumer Consumer(Results, CurContext);
3414 Results.EnterNewScope();
3415 LookupVisibleDecls(S, LookupOrdinaryName, Consumer);
3416
3417 // If we are in an Objective-C method inside a class that has a superclass,
3418 // add "super" as an option.
3419 if (ObjCMethodDecl *Method = getCurMethodDecl())
3420 if (ObjCInterfaceDecl *Iface = Method->getClassInterface())
3421 if (Iface->getSuperClass())
3422 Results.AddResult(Result("super"));
3423
3424 Results.ExitScope();
3425
3426 if (CodeCompleter->includeMacros())
3427 AddMacroResults(PP, Results);
3428 HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
3429
3430}
3431
Douglas Gregor2725ca82010-04-21 19:57:20 +00003432void Sema::CodeCompleteObjCSuperMessage(Scope *S, SourceLocation SuperLoc,
3433 IdentifierInfo **SelIdents,
3434 unsigned NumSelIdents) {
3435 ObjCInterfaceDecl *CDecl = 0;
3436 if (ObjCMethodDecl *CurMethod = getCurMethodDecl()) {
3437 // Figure out which interface we're in.
3438 CDecl = CurMethod->getClassInterface();
3439 if (!CDecl)
3440 return;
3441
3442 // Find the superclass of this class.
3443 CDecl = CDecl->getSuperClass();
3444 if (!CDecl)
3445 return;
3446
3447 if (CurMethod->isInstanceMethod()) {
3448 // We are inside an instance method, which means that the message
3449 // send [super ...] is actually calling an instance method on the
3450 // current object. Build the super expression and handle this like
3451 // an instance method.
3452 QualType SuperTy = Context.getObjCInterfaceType(CDecl);
3453 SuperTy = Context.getObjCObjectPointerType(SuperTy);
3454 OwningExprResult Super
3455 = Owned(new (Context) ObjCSuperExpr(SuperLoc, SuperTy));
3456 return CodeCompleteObjCInstanceMessage(S, (Expr *)Super.get(),
3457 SelIdents, NumSelIdents);
3458 }
3459
3460 // Fall through to send to the superclass in CDecl.
3461 } else {
3462 // "super" may be the name of a type or variable. Figure out which
3463 // it is.
3464 IdentifierInfo *Super = &Context.Idents.get("super");
3465 NamedDecl *ND = LookupSingleName(S, Super, SuperLoc,
3466 LookupOrdinaryName);
3467 if ((CDecl = dyn_cast_or_null<ObjCInterfaceDecl>(ND))) {
3468 // "super" names an interface. Use it.
3469 } else if (TypeDecl *TD = dyn_cast_or_null<TypeDecl>(ND)) {
John McCallc12c5bb2010-05-15 11:32:37 +00003470 if (const ObjCObjectType *Iface
3471 = Context.getTypeDeclType(TD)->getAs<ObjCObjectType>())
3472 CDecl = Iface->getInterface();
Douglas Gregor2725ca82010-04-21 19:57:20 +00003473 } else if (ND && isa<UnresolvedUsingTypenameDecl>(ND)) {
3474 // "super" names an unresolved type; we can't be more specific.
3475 } else {
3476 // Assume that "super" names some kind of value and parse that way.
3477 CXXScopeSpec SS;
3478 UnqualifiedId id;
3479 id.setIdentifier(Super, SuperLoc);
3480 OwningExprResult SuperExpr = ActOnIdExpression(S, SS, id, false, false);
3481 return CodeCompleteObjCInstanceMessage(S, (Expr *)SuperExpr.get(),
3482 SelIdents, NumSelIdents);
3483 }
3484
3485 // Fall through
3486 }
3487
3488 TypeTy *Receiver = 0;
3489 if (CDecl)
3490 Receiver = Context.getObjCInterfaceType(CDecl).getAsOpaquePtr();
3491 return CodeCompleteObjCClassMessage(S, Receiver, SelIdents,
3492 NumSelIdents);
3493}
3494
3495void Sema::CodeCompleteObjCClassMessage(Scope *S, TypeTy *Receiver,
Douglas Gregord3c68542009-11-19 01:08:35 +00003496 IdentifierInfo **SelIdents,
3497 unsigned NumSelIdents) {
Steve Naroffc4df6d22009-11-07 02:08:14 +00003498 typedef CodeCompleteConsumer::Result Result;
Douglas Gregor24a069f2009-11-17 17:59:40 +00003499 ObjCInterfaceDecl *CDecl = 0;
3500
Douglas Gregor24a069f2009-11-17 17:59:40 +00003501 // If the given name refers to an interface type, retrieve the
3502 // corresponding declaration.
Douglas Gregor2725ca82010-04-21 19:57:20 +00003503 if (Receiver) {
3504 QualType T = GetTypeFromParser(Receiver, 0);
3505 if (!T.isNull())
John McCallc12c5bb2010-05-15 11:32:37 +00003506 if (const ObjCObjectType *Interface = T->getAs<ObjCObjectType>())
3507 CDecl = Interface->getInterface();
Douglas Gregor24a069f2009-11-17 17:59:40 +00003508 }
3509
Douglas Gregor36ecb042009-11-17 23:22:23 +00003510 // Add all of the factory methods in this Objective-C class, its protocols,
3511 // superclasses, categories, implementation, etc.
Steve Naroffc4df6d22009-11-07 02:08:14 +00003512 ResultBuilder Results(*this);
3513 Results.EnterNewScope();
Douglas Gregor13438f92010-04-06 16:40:00 +00003514
3515 if (CDecl)
3516 AddObjCMethods(CDecl, false, MK_Any, SelIdents, NumSelIdents, CurContext,
3517 Results);
Douglas Gregor2725ca82010-04-21 19:57:20 +00003518 else {
Douglas Gregor13438f92010-04-06 16:40:00 +00003519 // We're messaging "id" as a type; provide all class/factory methods.
3520
Douglas Gregor719770d2010-04-06 17:30:22 +00003521 // If we have an external source, load the entire class method
3522 // pool from the PCH file.
3523 if (ExternalSource) {
John McCall76bd1f32010-06-01 09:23:16 +00003524 for (uint32_t I = 0, N = ExternalSource->GetNumExternalSelectors();
3525 I != N; ++I) {
3526 Selector Sel = ExternalSource->GetExternalSelector(I);
Douglas Gregor719770d2010-04-06 17:30:22 +00003527 if (Sel.isNull() || FactoryMethodPool.count(Sel) ||
3528 InstanceMethodPool.count(Sel))
3529 continue;
3530
3531 ReadMethodPool(Sel, /*isInstance=*/false);
3532 }
3533 }
3534
Douglas Gregor13438f92010-04-06 16:40:00 +00003535 for (llvm::DenseMap<Selector, ObjCMethodList>::iterator
3536 M = FactoryMethodPool.begin(),
3537 MEnd = FactoryMethodPool.end();
3538 M != MEnd;
3539 ++M) {
Douglas Gregor719770d2010-04-06 17:30:22 +00003540 for (ObjCMethodList *MethList = &M->second; MethList && MethList->Method;
Douglas Gregor13438f92010-04-06 16:40:00 +00003541 MethList = MethList->Next) {
3542 if (!isAcceptableObjCMethod(MethList->Method, MK_Any, SelIdents,
3543 NumSelIdents))
3544 continue;
3545
3546 Result R(MethList->Method, 0);
3547 R.StartParameter = NumSelIdents;
3548 R.AllParametersAreInformative = false;
3549 Results.MaybeAddResult(R, CurContext);
3550 }
3551 }
3552 }
3553
Steve Naroffc4df6d22009-11-07 02:08:14 +00003554 Results.ExitScope();
Daniel Dunbar3a2838d2009-11-13 08:58:20 +00003555 HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
Steve Naroffc4df6d22009-11-07 02:08:14 +00003556}
3557
Douglas Gregord3c68542009-11-19 01:08:35 +00003558void Sema::CodeCompleteObjCInstanceMessage(Scope *S, ExprTy *Receiver,
3559 IdentifierInfo **SelIdents,
3560 unsigned NumSelIdents) {
Steve Naroffc4df6d22009-11-07 02:08:14 +00003561 typedef CodeCompleteConsumer::Result Result;
Steve Naroffc4df6d22009-11-07 02:08:14 +00003562
3563 Expr *RecExpr = static_cast<Expr *>(Receiver);
Steve Naroffc4df6d22009-11-07 02:08:14 +00003564
Douglas Gregor36ecb042009-11-17 23:22:23 +00003565 // If necessary, apply function/array conversion to the receiver.
3566 // C99 6.7.5.3p[7,8].
Douglas Gregora873dfc2010-02-03 00:27:59 +00003567 DefaultFunctionArrayLvalueConversion(RecExpr);
Douglas Gregor36ecb042009-11-17 23:22:23 +00003568 QualType ReceiverType = RecExpr->getType();
Steve Naroffc4df6d22009-11-07 02:08:14 +00003569
Douglas Gregor36ecb042009-11-17 23:22:23 +00003570 // Build the set of methods we can see.
3571 ResultBuilder Results(*this);
3572 Results.EnterNewScope();
Douglas Gregor22f56992010-04-06 19:22:33 +00003573
3574 // If we're messaging an expression with type "id" or "Class", check
3575 // whether we know something special about the receiver that allows
3576 // us to assume a more-specific receiver type.
3577 if (ReceiverType->isObjCIdType() || ReceiverType->isObjCClassType())
3578 if (ObjCInterfaceDecl *IFace = GetAssumedMessageSendExprType(RecExpr))
3579 ReceiverType = Context.getObjCObjectPointerType(
3580 Context.getObjCInterfaceType(IFace));
Douglas Gregor36ecb042009-11-17 23:22:23 +00003581
Douglas Gregorf74a4192009-11-18 00:06:18 +00003582 // Handle messages to Class. This really isn't a message to an instance
3583 // method, so we treat it the same way we would treat a message send to a
3584 // class method.
3585 if (ReceiverType->isObjCClassType() ||
3586 ReceiverType->isObjCQualifiedClassType()) {
3587 if (ObjCMethodDecl *CurMethod = getCurMethodDecl()) {
3588 if (ObjCInterfaceDecl *ClassDecl = CurMethod->getClassInterface())
Douglas Gregor4ad96852009-11-19 07:41:15 +00003589 AddObjCMethods(ClassDecl, false, MK_Any, SelIdents, NumSelIdents,
3590 CurContext, Results);
Douglas Gregorf74a4192009-11-18 00:06:18 +00003591 }
3592 }
3593 // Handle messages to a qualified ID ("id<foo>").
3594 else if (const ObjCObjectPointerType *QualID
3595 = ReceiverType->getAsObjCQualifiedIdType()) {
3596 // Search protocols for instance methods.
3597 for (ObjCObjectPointerType::qual_iterator I = QualID->qual_begin(),
3598 E = QualID->qual_end();
3599 I != E; ++I)
Douglas Gregor4ad96852009-11-19 07:41:15 +00003600 AddObjCMethods(*I, true, MK_Any, SelIdents, NumSelIdents, CurContext,
3601 Results);
Douglas Gregorf74a4192009-11-18 00:06:18 +00003602 }
3603 // Handle messages to a pointer to interface type.
3604 else if (const ObjCObjectPointerType *IFacePtr
3605 = ReceiverType->getAsObjCInterfacePointerType()) {
3606 // Search the class, its superclasses, etc., for instance methods.
Douglas Gregor4ad96852009-11-19 07:41:15 +00003607 AddObjCMethods(IFacePtr->getInterfaceDecl(), true, MK_Any, SelIdents,
3608 NumSelIdents, CurContext, Results);
Douglas Gregorf74a4192009-11-18 00:06:18 +00003609
3610 // Search protocols for instance methods.
3611 for (ObjCObjectPointerType::qual_iterator I = IFacePtr->qual_begin(),
3612 E = IFacePtr->qual_end();
3613 I != E; ++I)
Douglas Gregor4ad96852009-11-19 07:41:15 +00003614 AddObjCMethods(*I, true, MK_Any, SelIdents, NumSelIdents, CurContext,
3615 Results);
Douglas Gregorf74a4192009-11-18 00:06:18 +00003616 }
Douglas Gregor13438f92010-04-06 16:40:00 +00003617 // Handle messages to "id".
3618 else if (ReceiverType->isObjCIdType()) {
Douglas Gregor719770d2010-04-06 17:30:22 +00003619 // We're messaging "id", so provide all instance methods we know
3620 // about as code-completion results.
3621
3622 // If we have an external source, load the entire class method
3623 // pool from the PCH file.
3624 if (ExternalSource) {
John McCall76bd1f32010-06-01 09:23:16 +00003625 for (uint32_t I = 0, N = ExternalSource->GetNumExternalSelectors();
3626 I != N; ++I) {
3627 Selector Sel = ExternalSource->GetExternalSelector(I);
Douglas Gregor719770d2010-04-06 17:30:22 +00003628 if (Sel.isNull() || InstanceMethodPool.count(Sel) ||
3629 FactoryMethodPool.count(Sel))
3630 continue;
3631
3632 ReadMethodPool(Sel, /*isInstance=*/true);
3633 }
3634 }
3635
Douglas Gregor13438f92010-04-06 16:40:00 +00003636 for (llvm::DenseMap<Selector, ObjCMethodList>::iterator
3637 M = InstanceMethodPool.begin(),
3638 MEnd = InstanceMethodPool.end();
3639 M != MEnd;
3640 ++M) {
Douglas Gregor719770d2010-04-06 17:30:22 +00003641 for (ObjCMethodList *MethList = &M->second; MethList && MethList->Method;
Douglas Gregor13438f92010-04-06 16:40:00 +00003642 MethList = MethList->Next) {
3643 if (!isAcceptableObjCMethod(MethList->Method, MK_Any, SelIdents,
3644 NumSelIdents))
3645 continue;
3646
3647 Result R(MethList->Method, 0);
3648 R.StartParameter = NumSelIdents;
3649 R.AllParametersAreInformative = false;
3650 Results.MaybeAddResult(R, CurContext);
3651 }
3652 }
3653 }
3654
Steve Naroffc4df6d22009-11-07 02:08:14 +00003655 Results.ExitScope();
Daniel Dunbar3a2838d2009-11-13 08:58:20 +00003656 HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
Steve Naroffc4df6d22009-11-07 02:08:14 +00003657}
Douglas Gregor55385fe2009-11-18 04:19:12 +00003658
3659/// \brief Add all of the protocol declarations that we find in the given
3660/// (translation unit) context.
3661static void AddProtocolResults(DeclContext *Ctx, DeclContext *CurContext,
Douglas Gregor083128f2009-11-18 04:49:41 +00003662 bool OnlyForwardDeclarations,
Douglas Gregor55385fe2009-11-18 04:19:12 +00003663 ResultBuilder &Results) {
3664 typedef CodeCompleteConsumer::Result Result;
3665
3666 for (DeclContext::decl_iterator D = Ctx->decls_begin(),
3667 DEnd = Ctx->decls_end();
3668 D != DEnd; ++D) {
3669 // Record any protocols we find.
3670 if (ObjCProtocolDecl *Proto = dyn_cast<ObjCProtocolDecl>(*D))
Douglas Gregor083128f2009-11-18 04:49:41 +00003671 if (!OnlyForwardDeclarations || Proto->isForwardDecl())
Douglas Gregor608300b2010-01-14 16:14:35 +00003672 Results.AddResult(Result(Proto, 0), CurContext, 0, false);
Douglas Gregor55385fe2009-11-18 04:19:12 +00003673
3674 // Record any forward-declared protocols we find.
3675 if (ObjCForwardProtocolDecl *Forward
3676 = dyn_cast<ObjCForwardProtocolDecl>(*D)) {
3677 for (ObjCForwardProtocolDecl::protocol_iterator
3678 P = Forward->protocol_begin(),
3679 PEnd = Forward->protocol_end();
3680 P != PEnd; ++P)
Douglas Gregor083128f2009-11-18 04:49:41 +00003681 if (!OnlyForwardDeclarations || (*P)->isForwardDecl())
Douglas Gregor608300b2010-01-14 16:14:35 +00003682 Results.AddResult(Result(*P, 0), CurContext, 0, false);
Douglas Gregor55385fe2009-11-18 04:19:12 +00003683 }
3684 }
3685}
3686
3687void Sema::CodeCompleteObjCProtocolReferences(IdentifierLocPair *Protocols,
3688 unsigned NumProtocols) {
3689 ResultBuilder Results(*this);
3690 Results.EnterNewScope();
3691
3692 // Tell the result set to ignore all of the protocols we have
3693 // already seen.
3694 for (unsigned I = 0; I != NumProtocols; ++I)
Douglas Gregorc83c6872010-04-15 22:33:43 +00003695 if (ObjCProtocolDecl *Protocol = LookupProtocol(Protocols[I].first,
3696 Protocols[I].second))
Douglas Gregor55385fe2009-11-18 04:19:12 +00003697 Results.Ignore(Protocol);
3698
3699 // Add all protocols.
Douglas Gregor083128f2009-11-18 04:49:41 +00003700 AddProtocolResults(Context.getTranslationUnitDecl(), CurContext, false,
3701 Results);
3702
3703 Results.ExitScope();
3704 HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
3705}
3706
3707void Sema::CodeCompleteObjCProtocolDecl(Scope *) {
3708 ResultBuilder Results(*this);
3709 Results.EnterNewScope();
3710
3711 // Add all protocols.
3712 AddProtocolResults(Context.getTranslationUnitDecl(), CurContext, true,
3713 Results);
Douglas Gregor55385fe2009-11-18 04:19:12 +00003714
3715 Results.ExitScope();
3716 HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
3717}
Douglas Gregor3b49aca2009-11-18 16:26:39 +00003718
3719/// \brief Add all of the Objective-C interface declarations that we find in
3720/// the given (translation unit) context.
3721static void AddInterfaceResults(DeclContext *Ctx, DeclContext *CurContext,
3722 bool OnlyForwardDeclarations,
3723 bool OnlyUnimplemented,
3724 ResultBuilder &Results) {
3725 typedef CodeCompleteConsumer::Result Result;
3726
3727 for (DeclContext::decl_iterator D = Ctx->decls_begin(),
3728 DEnd = Ctx->decls_end();
3729 D != DEnd; ++D) {
3730 // Record any interfaces we find.
3731 if (ObjCInterfaceDecl *Class = dyn_cast<ObjCInterfaceDecl>(*D))
3732 if ((!OnlyForwardDeclarations || Class->isForwardDecl()) &&
3733 (!OnlyUnimplemented || !Class->getImplementation()))
Douglas Gregor608300b2010-01-14 16:14:35 +00003734 Results.AddResult(Result(Class, 0), CurContext, 0, false);
Douglas Gregor3b49aca2009-11-18 16:26:39 +00003735
3736 // Record any forward-declared interfaces we find.
3737 if (ObjCClassDecl *Forward = dyn_cast<ObjCClassDecl>(*D)) {
3738 for (ObjCClassDecl::iterator C = Forward->begin(), CEnd = Forward->end();
3739 C != CEnd; ++C)
3740 if ((!OnlyForwardDeclarations || C->getInterface()->isForwardDecl()) &&
3741 (!OnlyUnimplemented || !C->getInterface()->getImplementation()))
Douglas Gregor608300b2010-01-14 16:14:35 +00003742 Results.AddResult(Result(C->getInterface(), 0), CurContext,
3743 0, false);
Douglas Gregor3b49aca2009-11-18 16:26:39 +00003744 }
3745 }
3746}
3747
3748void Sema::CodeCompleteObjCInterfaceDecl(Scope *S) {
3749 ResultBuilder Results(*this);
3750 Results.EnterNewScope();
3751
3752 // Add all classes.
3753 AddInterfaceResults(Context.getTranslationUnitDecl(), CurContext, true,
3754 false, Results);
3755
3756 Results.ExitScope();
3757 HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
3758}
3759
Douglas Gregorc83c6872010-04-15 22:33:43 +00003760void Sema::CodeCompleteObjCSuperclass(Scope *S, IdentifierInfo *ClassName,
3761 SourceLocation ClassNameLoc) {
Douglas Gregor3b49aca2009-11-18 16:26:39 +00003762 ResultBuilder Results(*this);
3763 Results.EnterNewScope();
3764
3765 // Make sure that we ignore the class we're currently defining.
3766 NamedDecl *CurClass
Douglas Gregorc83c6872010-04-15 22:33:43 +00003767 = LookupSingleName(TUScope, ClassName, ClassNameLoc, LookupOrdinaryName);
Douglas Gregor33ced0b2009-11-18 19:08:43 +00003768 if (CurClass && isa<ObjCInterfaceDecl>(CurClass))
Douglas Gregor3b49aca2009-11-18 16:26:39 +00003769 Results.Ignore(CurClass);
3770
3771 // Add all classes.
3772 AddInterfaceResults(Context.getTranslationUnitDecl(), CurContext, false,
3773 false, Results);
3774
3775 Results.ExitScope();
3776 HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
3777}
3778
3779void Sema::CodeCompleteObjCImplementationDecl(Scope *S) {
3780 ResultBuilder Results(*this);
3781 Results.EnterNewScope();
3782
3783 // Add all unimplemented classes.
3784 AddInterfaceResults(Context.getTranslationUnitDecl(), CurContext, false,
3785 true, Results);
3786
3787 Results.ExitScope();
3788 HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
3789}
Douglas Gregor33ced0b2009-11-18 19:08:43 +00003790
3791void Sema::CodeCompleteObjCInterfaceCategory(Scope *S,
Douglas Gregorc83c6872010-04-15 22:33:43 +00003792 IdentifierInfo *ClassName,
3793 SourceLocation ClassNameLoc) {
Douglas Gregor33ced0b2009-11-18 19:08:43 +00003794 typedef CodeCompleteConsumer::Result Result;
3795
3796 ResultBuilder Results(*this);
3797
3798 // Ignore any categories we find that have already been implemented by this
3799 // interface.
3800 llvm::SmallPtrSet<IdentifierInfo *, 16> CategoryNames;
3801 NamedDecl *CurClass
Douglas Gregorc83c6872010-04-15 22:33:43 +00003802 = LookupSingleName(TUScope, ClassName, ClassNameLoc, LookupOrdinaryName);
Douglas Gregor33ced0b2009-11-18 19:08:43 +00003803 if (ObjCInterfaceDecl *Class = dyn_cast_or_null<ObjCInterfaceDecl>(CurClass))
3804 for (ObjCCategoryDecl *Category = Class->getCategoryList(); Category;
3805 Category = Category->getNextClassCategory())
3806 CategoryNames.insert(Category->getIdentifier());
3807
3808 // Add all of the categories we know about.
3809 Results.EnterNewScope();
3810 TranslationUnitDecl *TU = Context.getTranslationUnitDecl();
3811 for (DeclContext::decl_iterator D = TU->decls_begin(),
3812 DEnd = TU->decls_end();
3813 D != DEnd; ++D)
3814 if (ObjCCategoryDecl *Category = dyn_cast<ObjCCategoryDecl>(*D))
3815 if (CategoryNames.insert(Category->getIdentifier()))
Douglas Gregor608300b2010-01-14 16:14:35 +00003816 Results.AddResult(Result(Category, 0), CurContext, 0, false);
Douglas Gregor33ced0b2009-11-18 19:08:43 +00003817 Results.ExitScope();
3818
3819 HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
3820}
3821
3822void Sema::CodeCompleteObjCImplementationCategory(Scope *S,
Douglas Gregorc83c6872010-04-15 22:33:43 +00003823 IdentifierInfo *ClassName,
3824 SourceLocation ClassNameLoc) {
Douglas Gregor33ced0b2009-11-18 19:08:43 +00003825 typedef CodeCompleteConsumer::Result Result;
3826
3827 // Find the corresponding interface. If we couldn't find the interface, the
3828 // program itself is ill-formed. However, we'll try to be helpful still by
3829 // providing the list of all of the categories we know about.
3830 NamedDecl *CurClass
Douglas Gregorc83c6872010-04-15 22:33:43 +00003831 = LookupSingleName(TUScope, ClassName, ClassNameLoc, LookupOrdinaryName);
Douglas Gregor33ced0b2009-11-18 19:08:43 +00003832 ObjCInterfaceDecl *Class = dyn_cast_or_null<ObjCInterfaceDecl>(CurClass);
3833 if (!Class)
Douglas Gregorc83c6872010-04-15 22:33:43 +00003834 return CodeCompleteObjCInterfaceCategory(S, ClassName, ClassNameLoc);
Douglas Gregor33ced0b2009-11-18 19:08:43 +00003835
3836 ResultBuilder Results(*this);
3837
3838 // Add all of the categories that have have corresponding interface
3839 // declarations in this class and any of its superclasses, except for
3840 // already-implemented categories in the class itself.
3841 llvm::SmallPtrSet<IdentifierInfo *, 16> CategoryNames;
3842 Results.EnterNewScope();
3843 bool IgnoreImplemented = true;
3844 while (Class) {
3845 for (ObjCCategoryDecl *Category = Class->getCategoryList(); Category;
3846 Category = Category->getNextClassCategory())
3847 if ((!IgnoreImplemented || !Category->getImplementation()) &&
3848 CategoryNames.insert(Category->getIdentifier()))
Douglas Gregor608300b2010-01-14 16:14:35 +00003849 Results.AddResult(Result(Category, 0), CurContext, 0, false);
Douglas Gregor33ced0b2009-11-18 19:08:43 +00003850
3851 Class = Class->getSuperClass();
3852 IgnoreImplemented = false;
3853 }
3854 Results.ExitScope();
3855
3856 HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
3857}
Douglas Gregor322328b2009-11-18 22:32:06 +00003858
Douglas Gregor424b2a52009-11-18 22:56:13 +00003859void Sema::CodeCompleteObjCPropertyDefinition(Scope *S, DeclPtrTy ObjCImpDecl) {
Douglas Gregor322328b2009-11-18 22:32:06 +00003860 typedef CodeCompleteConsumer::Result Result;
3861 ResultBuilder Results(*this);
3862
3863 // Figure out where this @synthesize lives.
3864 ObjCContainerDecl *Container
3865 = dyn_cast_or_null<ObjCContainerDecl>(ObjCImpDecl.getAs<Decl>());
3866 if (!Container ||
3867 (!isa<ObjCImplementationDecl>(Container) &&
3868 !isa<ObjCCategoryImplDecl>(Container)))
3869 return;
3870
3871 // Ignore any properties that have already been implemented.
3872 for (DeclContext::decl_iterator D = Container->decls_begin(),
3873 DEnd = Container->decls_end();
3874 D != DEnd; ++D)
3875 if (ObjCPropertyImplDecl *PropertyImpl = dyn_cast<ObjCPropertyImplDecl>(*D))
3876 Results.Ignore(PropertyImpl->getPropertyDecl());
3877
3878 // Add any properties that we find.
3879 Results.EnterNewScope();
3880 if (ObjCImplementationDecl *ClassImpl
3881 = dyn_cast<ObjCImplementationDecl>(Container))
3882 AddObjCProperties(ClassImpl->getClassInterface(), false, CurContext,
3883 Results);
3884 else
3885 AddObjCProperties(cast<ObjCCategoryImplDecl>(Container)->getCategoryDecl(),
3886 false, CurContext, Results);
3887 Results.ExitScope();
3888
3889 HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
3890}
3891
3892void Sema::CodeCompleteObjCPropertySynthesizeIvar(Scope *S,
3893 IdentifierInfo *PropertyName,
3894 DeclPtrTy ObjCImpDecl) {
3895 typedef CodeCompleteConsumer::Result Result;
3896 ResultBuilder Results(*this);
3897
3898 // Figure out where this @synthesize lives.
3899 ObjCContainerDecl *Container
3900 = dyn_cast_or_null<ObjCContainerDecl>(ObjCImpDecl.getAs<Decl>());
3901 if (!Container ||
3902 (!isa<ObjCImplementationDecl>(Container) &&
3903 !isa<ObjCCategoryImplDecl>(Container)))
3904 return;
3905
3906 // Figure out which interface we're looking into.
3907 ObjCInterfaceDecl *Class = 0;
3908 if (ObjCImplementationDecl *ClassImpl
3909 = dyn_cast<ObjCImplementationDecl>(Container))
3910 Class = ClassImpl->getClassInterface();
3911 else
3912 Class = cast<ObjCCategoryImplDecl>(Container)->getCategoryDecl()
3913 ->getClassInterface();
3914
3915 // Add all of the instance variables in this class and its superclasses.
3916 Results.EnterNewScope();
3917 for(; Class; Class = Class->getSuperClass()) {
3918 // FIXME: We could screen the type of each ivar for compatibility with
3919 // the property, but is that being too paternal?
3920 for (ObjCInterfaceDecl::ivar_iterator IVar = Class->ivar_begin(),
3921 IVarEnd = Class->ivar_end();
3922 IVar != IVarEnd; ++IVar)
Douglas Gregor608300b2010-01-14 16:14:35 +00003923 Results.AddResult(Result(*IVar, 0), CurContext, 0, false);
Douglas Gregor322328b2009-11-18 22:32:06 +00003924 }
3925 Results.ExitScope();
3926
3927 HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
3928}
Douglas Gregore8f5a172010-04-07 00:21:17 +00003929
3930typedef llvm::DenseMap<Selector, ObjCMethodDecl *> KnownMethodsMap;
3931
3932/// \brief Find all of the methods that reside in the given container
3933/// (and its superclasses, protocols, etc.) that meet the given
3934/// criteria. Insert those methods into the map of known methods,
3935/// indexed by selector so they can be easily found.
3936static void FindImplementableMethods(ASTContext &Context,
3937 ObjCContainerDecl *Container,
3938 bool WantInstanceMethods,
3939 QualType ReturnType,
3940 bool IsInImplementation,
3941 KnownMethodsMap &KnownMethods) {
3942 if (ObjCInterfaceDecl *IFace = dyn_cast<ObjCInterfaceDecl>(Container)) {
3943 // Recurse into protocols.
3944 const ObjCList<ObjCProtocolDecl> &Protocols
3945 = IFace->getReferencedProtocols();
3946 for (ObjCList<ObjCProtocolDecl>::iterator I = Protocols.begin(),
3947 E = Protocols.end();
3948 I != E; ++I)
3949 FindImplementableMethods(Context, *I, WantInstanceMethods, ReturnType,
3950 IsInImplementation, KnownMethods);
3951
3952 // If we're not in the implementation of a class, also visit the
3953 // superclass.
3954 if (!IsInImplementation && IFace->getSuperClass())
3955 FindImplementableMethods(Context, IFace->getSuperClass(),
3956 WantInstanceMethods, ReturnType,
3957 IsInImplementation, KnownMethods);
3958
3959 // Add methods from any class extensions (but not from categories;
3960 // those should go into category implementations).
Fariborz Jahanian80aa1cd2010-06-22 23:20:40 +00003961 for (const ObjCCategoryDecl *Cat = IFace->getFirstClassExtension(); Cat;
3962 Cat = Cat->getNextClassExtension())
3963 FindImplementableMethods(Context, const_cast<ObjCCategoryDecl*>(Cat),
3964 WantInstanceMethods, ReturnType,
Douglas Gregore8f5a172010-04-07 00:21:17 +00003965 IsInImplementation, KnownMethods);
Douglas Gregore8f5a172010-04-07 00:21:17 +00003966 }
3967
3968 if (ObjCCategoryDecl *Category = dyn_cast<ObjCCategoryDecl>(Container)) {
3969 // Recurse into protocols.
3970 const ObjCList<ObjCProtocolDecl> &Protocols
3971 = Category->getReferencedProtocols();
3972 for (ObjCList<ObjCProtocolDecl>::iterator I = Protocols.begin(),
3973 E = Protocols.end();
3974 I != E; ++I)
3975 FindImplementableMethods(Context, *I, WantInstanceMethods, ReturnType,
3976 IsInImplementation, KnownMethods);
3977 }
3978
3979 if (ObjCProtocolDecl *Protocol = dyn_cast<ObjCProtocolDecl>(Container)) {
3980 // Recurse into protocols.
3981 const ObjCList<ObjCProtocolDecl> &Protocols
3982 = Protocol->getReferencedProtocols();
3983 for (ObjCList<ObjCProtocolDecl>::iterator I = Protocols.begin(),
3984 E = Protocols.end();
3985 I != E; ++I)
3986 FindImplementableMethods(Context, *I, WantInstanceMethods, ReturnType,
3987 IsInImplementation, KnownMethods);
3988 }
3989
3990 // Add methods in this container. This operation occurs last because
3991 // we want the methods from this container to override any methods
3992 // we've previously seen with the same selector.
3993 for (ObjCContainerDecl::method_iterator M = Container->meth_begin(),
3994 MEnd = Container->meth_end();
3995 M != MEnd; ++M) {
3996 if ((*M)->isInstanceMethod() == WantInstanceMethods) {
3997 if (!ReturnType.isNull() &&
3998 !Context.hasSameUnqualifiedType(ReturnType, (*M)->getResultType()))
3999 continue;
4000
4001 KnownMethods[(*M)->getSelector()] = *M;
4002 }
4003 }
4004}
4005
4006void Sema::CodeCompleteObjCMethodDecl(Scope *S,
4007 bool IsInstanceMethod,
4008 TypeTy *ReturnTy,
4009 DeclPtrTy IDecl) {
4010 // Determine the return type of the method we're declaring, if
4011 // provided.
4012 QualType ReturnType = GetTypeFromParser(ReturnTy);
4013
4014 // Determine where we should start searching for methods, and where we
4015 ObjCContainerDecl *SearchDecl = 0, *CurrentDecl = 0;
4016 bool IsInImplementation = false;
4017 if (Decl *D = IDecl.getAs<Decl>()) {
4018 if (ObjCImplementationDecl *Impl = dyn_cast<ObjCImplementationDecl>(D)) {
4019 SearchDecl = Impl->getClassInterface();
4020 CurrentDecl = Impl;
4021 IsInImplementation = true;
4022 } else if (ObjCCategoryImplDecl *CatImpl
4023 = dyn_cast<ObjCCategoryImplDecl>(D)) {
4024 SearchDecl = CatImpl->getCategoryDecl();
4025 CurrentDecl = CatImpl;
4026 IsInImplementation = true;
4027 } else {
4028 SearchDecl = dyn_cast<ObjCContainerDecl>(D);
4029 CurrentDecl = SearchDecl;
4030 }
4031 }
4032
4033 if (!SearchDecl && S) {
4034 if (DeclContext *DC = static_cast<DeclContext *>(S->getEntity())) {
4035 SearchDecl = dyn_cast<ObjCContainerDecl>(DC);
4036 CurrentDecl = SearchDecl;
4037 }
4038 }
4039
4040 if (!SearchDecl || !CurrentDecl) {
4041 HandleCodeCompleteResults(this, CodeCompleter, 0, 0);
4042 return;
4043 }
4044
4045 // Find all of the methods that we could declare/implement here.
4046 KnownMethodsMap KnownMethods;
4047 FindImplementableMethods(Context, SearchDecl, IsInstanceMethod,
4048 ReturnType, IsInImplementation, KnownMethods);
4049
4050 // Erase any methods that have already been declared or
4051 // implemented here.
4052 for (ObjCContainerDecl::method_iterator M = CurrentDecl->meth_begin(),
4053 MEnd = CurrentDecl->meth_end();
4054 M != MEnd; ++M) {
4055 if ((*M)->isInstanceMethod() != IsInstanceMethod)
4056 continue;
4057
4058 KnownMethodsMap::iterator Pos = KnownMethods.find((*M)->getSelector());
4059 if (Pos != KnownMethods.end())
4060 KnownMethods.erase(Pos);
4061 }
4062
4063 // Add declarations or definitions for each of the known methods.
4064 typedef CodeCompleteConsumer::Result Result;
4065 ResultBuilder Results(*this);
4066 Results.EnterNewScope();
4067 PrintingPolicy Policy(Context.PrintingPolicy);
4068 Policy.AnonymousTagLocations = false;
4069 for (KnownMethodsMap::iterator M = KnownMethods.begin(),
4070 MEnd = KnownMethods.end();
4071 M != MEnd; ++M) {
4072 ObjCMethodDecl *Method = M->second;
4073 CodeCompletionString *Pattern = new CodeCompletionString;
4074
4075 // If the result type was not already provided, add it to the
4076 // pattern as (type).
4077 if (ReturnType.isNull()) {
4078 std::string TypeStr;
4079 Method->getResultType().getAsStringInternal(TypeStr, Policy);
4080 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
4081 Pattern->AddTextChunk(TypeStr);
4082 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
4083 }
4084
4085 Selector Sel = Method->getSelector();
4086
4087 // Add the first part of the selector to the pattern.
4088 Pattern->AddTypedTextChunk(Sel.getIdentifierInfoForSlot(0)->getName());
4089
4090 // Add parameters to the pattern.
4091 unsigned I = 0;
4092 for (ObjCMethodDecl::param_iterator P = Method->param_begin(),
4093 PEnd = Method->param_end();
4094 P != PEnd; (void)++P, ++I) {
4095 // Add the part of the selector name.
4096 if (I == 0)
4097 Pattern->AddChunk(CodeCompletionString::CK_Colon);
4098 else if (I < Sel.getNumArgs()) {
4099 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
4100 Pattern->AddTextChunk(Sel.getIdentifierInfoForSlot(1)->getName());
4101 Pattern->AddChunk(CodeCompletionString::CK_Colon);
4102 } else
4103 break;
4104
4105 // Add the parameter type.
4106 std::string TypeStr;
4107 (*P)->getOriginalType().getAsStringInternal(TypeStr, Policy);
4108 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
4109 Pattern->AddTextChunk(TypeStr);
4110 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
4111
4112 if (IdentifierInfo *Id = (*P)->getIdentifier())
4113 Pattern->AddTextChunk(Id->getName());
4114 }
4115
4116 if (Method->isVariadic()) {
4117 if (Method->param_size() > 0)
4118 Pattern->AddChunk(CodeCompletionString::CK_Comma);
4119 Pattern->AddTextChunk("...");
4120 }
4121
Douglas Gregor447107d2010-05-28 00:57:46 +00004122 if (IsInImplementation && Results.includeCodePatterns()) {
Douglas Gregore8f5a172010-04-07 00:21:17 +00004123 // We will be defining the method here, so add a compound statement.
4124 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
4125 Pattern->AddChunk(CodeCompletionString::CK_LeftBrace);
4126 Pattern->AddChunk(CodeCompletionString::CK_VerticalSpace);
4127 if (!Method->getResultType()->isVoidType()) {
4128 // If the result type is not void, add a return clause.
4129 Pattern->AddTextChunk("return");
4130 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
4131 Pattern->AddPlaceholderChunk("expression");
4132 Pattern->AddChunk(CodeCompletionString::CK_SemiColon);
4133 } else
4134 Pattern->AddPlaceholderChunk("statements");
4135
4136 Pattern->AddChunk(CodeCompletionString::CK_VerticalSpace);
4137 Pattern->AddChunk(CodeCompletionString::CK_RightBrace);
4138 }
4139
4140 Results.AddResult(Result(Pattern));
4141 }
4142
4143 Results.ExitScope();
4144
4145 HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
4146}
Douglas Gregor1f5537a2010-07-08 23:20:03 +00004147
4148void Sema::CodeCompleteObjCMethodDeclSelector(Scope *S,
4149 bool IsInstanceMethod,
Douglas Gregor40ed9a12010-07-08 23:37:41 +00004150 bool AtParameterName,
Douglas Gregor1f5537a2010-07-08 23:20:03 +00004151 TypeTy *ReturnTy,
4152 IdentifierInfo **SelIdents,
4153 unsigned NumSelIdents) {
4154 llvm::DenseMap<Selector, ObjCMethodList> &Pool
4155 = IsInstanceMethod? InstanceMethodPool : FactoryMethodPool;
4156
4157 // If we have an external source, load the entire class method
4158 // pool from the PCH file.
4159 if (ExternalSource) {
4160 for (uint32_t I = 0, N = ExternalSource->GetNumExternalSelectors();
4161 I != N; ++I) {
4162 Selector Sel = ExternalSource->GetExternalSelector(I);
4163 if (Sel.isNull() || InstanceMethodPool.count(Sel) ||
4164 FactoryMethodPool.count(Sel))
4165 continue;
4166
4167 ReadMethodPool(Sel, IsInstanceMethod);
4168 }
4169 }
4170
4171 // Build the set of methods we can see.
4172 typedef CodeCompleteConsumer::Result Result;
4173 ResultBuilder Results(*this);
4174
4175 if (ReturnTy)
4176 Results.setPreferredType(GetTypeFromParser(ReturnTy).getNonReferenceType());
4177
4178 Results.EnterNewScope();
4179 for (llvm::DenseMap<Selector, ObjCMethodList>::iterator M = Pool.begin(),
4180 MEnd = Pool.end();
4181 M != MEnd;
4182 ++M) {
4183 for (ObjCMethodList *MethList = &M->second; MethList && MethList->Method;
4184 MethList = MethList->Next) {
4185 if (!isAcceptableObjCMethod(MethList->Method, MK_Any, SelIdents,
4186 NumSelIdents))
4187 continue;
4188
Douglas Gregor40ed9a12010-07-08 23:37:41 +00004189 if (AtParameterName) {
4190 // Suggest parameter names we've seen before.
4191 if (NumSelIdents && NumSelIdents <= MethList->Method->param_size()) {
4192 ParmVarDecl *Param = MethList->Method->param_begin()[NumSelIdents-1];
4193 if (Param->getIdentifier()) {
4194 CodeCompletionString *Pattern = new CodeCompletionString;
4195 Pattern->AddTypedTextChunk(Param->getIdentifier()->getName());
4196 Results.AddResult(Pattern);
4197 }
4198 }
4199
4200 continue;
4201 }
4202
Douglas Gregor1f5537a2010-07-08 23:20:03 +00004203 Result R(MethList->Method, 0);
4204 R.StartParameter = NumSelIdents;
4205 R.AllParametersAreInformative = false;
4206 R.DeclaringEntity = true;
4207 Results.MaybeAddResult(R, CurContext);
4208 }
4209 }
4210
4211 Results.ExitScope();
4212 HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
4213}