blob: 635236ec4c8d7121400b44db4fc45a3348832029 [file] [log] [blame]
Douglas Gregor2436e712009-09-17 21:32:03 +00001//===---------------- SemaCodeComplete.cpp - Code Completion ----*- C++ -*-===//
2//
3// The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9//
10// This file defines the code-completion semantic actions.
11//
12//===----------------------------------------------------------------------===//
Douglas Gregorc3a6ade2010-08-12 20:07:10 +000013#include "clang/Sema/Sema.h"
14#include "clang/Sema/Lookup.h"
Douglas Gregor2436e712009-09-17 21:32:03 +000015#include "clang/Sema/CodeCompleteConsumer.h"
Douglas Gregord720daf2010-04-06 17:30:22 +000016#include "clang/Sema/ExternalSemaSource.h"
Douglas Gregorf2510672009-09-21 19:57:38 +000017#include "clang/AST/ExprCXX.h"
Douglas Gregor8ce33212009-11-17 17:59:40 +000018#include "clang/AST/ExprObjC.h"
Douglas Gregorf329c7c2009-10-30 16:50:04 +000019#include "clang/Lex/MacroInfo.h"
20#include "clang/Lex/Preprocessor.h"
Douglas Gregor3545ff42009-09-21 16:56:56 +000021#include "llvm/ADT/SmallPtrSet.h"
Douglas Gregore6688e62009-09-28 03:51:44 +000022#include "llvm/ADT/StringExtras.h"
Douglas Gregor9d2ddb22010-04-06 19:22:33 +000023#include "llvm/ADT/StringSwitch.h"
Douglas Gregor3545ff42009-09-21 16:56:56 +000024#include <list>
25#include <map>
26#include <vector>
Douglas Gregor2436e712009-09-17 21:32:03 +000027
28using namespace clang;
29
Douglas Gregor3545ff42009-09-21 16:56:56 +000030namespace {
31 /// \brief A container of code-completion results.
32 class ResultBuilder {
33 public:
34 /// \brief The type of a name-lookup filter, which can be provided to the
35 /// name-lookup routines to specify which declarations should be included in
36 /// the result set (when it returns true) and which declarations should be
37 /// filtered out (returns false).
38 typedef bool (ResultBuilder::*LookupFilter)(NamedDecl *) const;
39
40 typedef CodeCompleteConsumer::Result Result;
41
42 private:
43 /// \brief The actual results we have found.
44 std::vector<Result> Results;
45
46 /// \brief A record of all of the declarations we have found and placed
47 /// into the result set, used to ensure that no declaration ever gets into
48 /// the result set twice.
49 llvm::SmallPtrSet<Decl*, 16> AllDeclsFound;
50
Douglas Gregor05e7ca32009-12-06 20:23:50 +000051 typedef std::pair<NamedDecl *, unsigned> DeclIndexPair;
52
53 /// \brief An entry in the shadow map, which is optimized to store
54 /// a single (declaration, index) mapping (the common case) but
55 /// can also store a list of (declaration, index) mappings.
56 class ShadowMapEntry {
57 typedef llvm::SmallVector<DeclIndexPair, 4> DeclIndexPairVector;
58
59 /// \brief Contains either the solitary NamedDecl * or a vector
60 /// of (declaration, index) pairs.
61 llvm::PointerUnion<NamedDecl *, DeclIndexPairVector*> DeclOrVector;
62
63 /// \brief When the entry contains a single declaration, this is
64 /// the index associated with that entry.
65 unsigned SingleDeclIndex;
66
67 public:
68 ShadowMapEntry() : DeclOrVector(), SingleDeclIndex(0) { }
69
70 void Add(NamedDecl *ND, unsigned Index) {
71 if (DeclOrVector.isNull()) {
72 // 0 - > 1 elements: just set the single element information.
73 DeclOrVector = ND;
74 SingleDeclIndex = Index;
75 return;
76 }
77
78 if (NamedDecl *PrevND = DeclOrVector.dyn_cast<NamedDecl *>()) {
79 // 1 -> 2 elements: create the vector of results and push in the
80 // existing declaration.
81 DeclIndexPairVector *Vec = new DeclIndexPairVector;
82 Vec->push_back(DeclIndexPair(PrevND, SingleDeclIndex));
83 DeclOrVector = Vec;
84 }
85
86 // Add the new element to the end of the vector.
87 DeclOrVector.get<DeclIndexPairVector*>()->push_back(
88 DeclIndexPair(ND, Index));
89 }
90
91 void Destroy() {
92 if (DeclIndexPairVector *Vec
93 = DeclOrVector.dyn_cast<DeclIndexPairVector *>()) {
94 delete Vec;
95 DeclOrVector = ((NamedDecl *)0);
96 }
97 }
98
99 // Iteration.
100 class iterator;
101 iterator begin() const;
102 iterator end() const;
103 };
104
Douglas Gregor3545ff42009-09-21 16:56:56 +0000105 /// \brief A mapping from declaration names to the declarations that have
106 /// this name within a particular scope and their index within the list of
107 /// results.
Douglas Gregor05e7ca32009-12-06 20:23:50 +0000108 typedef llvm::DenseMap<DeclarationName, ShadowMapEntry> ShadowMap;
Douglas Gregor3545ff42009-09-21 16:56:56 +0000109
110 /// \brief The semantic analysis object for which results are being
111 /// produced.
112 Sema &SemaRef;
113
114 /// \brief If non-NULL, a filter function used to remove any code-completion
115 /// results that are not desirable.
116 LookupFilter Filter;
Douglas Gregor6ae4c522010-01-14 03:21:49 +0000117
118 /// \brief Whether we should allow declarations as
119 /// nested-name-specifiers that would otherwise be filtered out.
120 bool AllowNestedNameSpecifiers;
121
Douglas Gregor7aa6b222010-05-30 01:49:25 +0000122 /// \brief If set, the type that we would prefer our resulting value
123 /// declarations to have.
124 ///
125 /// Closely matching the preferred type gives a boost to a result's
126 /// priority.
127 CanQualType PreferredType;
128
Douglas Gregor3545ff42009-09-21 16:56:56 +0000129 /// \brief A list of shadow maps, which is used to model name hiding at
130 /// different levels of, e.g., the inheritance hierarchy.
131 std::list<ShadowMap> ShadowMaps;
132
Douglas Gregor95887f92010-07-08 23:20:03 +0000133 void AdjustResultPriorityForPreferredType(Result &R);
134
Douglas Gregor3545ff42009-09-21 16:56:56 +0000135 public:
136 explicit ResultBuilder(Sema &SemaRef, LookupFilter Filter = 0)
Douglas Gregor6ae4c522010-01-14 03:21:49 +0000137 : SemaRef(SemaRef), Filter(Filter), AllowNestedNameSpecifiers(false) { }
Douglas Gregor3545ff42009-09-21 16:56:56 +0000138
Douglas Gregorf64acca2010-05-25 21:41:55 +0000139 /// \brief Whether we should include code patterns in the completion
140 /// results.
141 bool includeCodePatterns() const {
142 return SemaRef.CodeCompleter &&
143 SemaRef.CodeCompleter->includeCodePatterns();
144 }
145
Douglas Gregor3545ff42009-09-21 16:56:56 +0000146 /// \brief Set the filter used for code-completion results.
147 void setFilter(LookupFilter Filter) {
148 this->Filter = Filter;
149 }
150
151 typedef std::vector<Result>::iterator iterator;
152 iterator begin() { return Results.begin(); }
153 iterator end() { return Results.end(); }
154
155 Result *data() { return Results.empty()? 0 : &Results.front(); }
156 unsigned size() const { return Results.size(); }
157 bool empty() const { return Results.empty(); }
158
Douglas Gregor7aa6b222010-05-30 01:49:25 +0000159 /// \brief Specify the preferred type.
160 void setPreferredType(QualType T) {
161 PreferredType = SemaRef.Context.getCanonicalType(T);
162 }
163
Douglas Gregor6ae4c522010-01-14 03:21:49 +0000164 /// \brief Specify whether nested-name-specifiers are allowed.
165 void allowNestedNameSpecifiers(bool Allow = true) {
166 AllowNestedNameSpecifiers = Allow;
167 }
168
Douglas Gregor7c208612010-01-14 00:20:49 +0000169 /// \brief Determine whether the given declaration is at all interesting
170 /// as a code-completion result.
Douglas Gregor6ae4c522010-01-14 03:21:49 +0000171 ///
172 /// \param ND the declaration that we are inspecting.
173 ///
174 /// \param AsNestedNameSpecifier will be set true if this declaration is
175 /// only interesting when it is a nested-name-specifier.
176 bool isInterestingDecl(NamedDecl *ND, bool &AsNestedNameSpecifier) const;
Douglas Gregore0717ab2010-01-14 00:41:07 +0000177
178 /// \brief Check whether the result is hidden by the Hiding declaration.
179 ///
180 /// \returns true if the result is hidden and cannot be found, false if
181 /// the hidden result could still be found. When false, \p R may be
182 /// modified to describe how the result can be found (e.g., via extra
183 /// qualification).
184 bool CheckHiddenResult(Result &R, DeclContext *CurContext,
185 NamedDecl *Hiding);
186
Douglas Gregor3545ff42009-09-21 16:56:56 +0000187 /// \brief Add a new result to this result set (if it isn't already in one
188 /// of the shadow maps), or replace an existing result (for, e.g., a
189 /// redeclaration).
Douglas Gregor2af2f672009-09-21 20:12:40 +0000190 ///
Douglas Gregorc580c522010-01-14 01:09:38 +0000191 /// \param CurContext the result to add (if it is unique).
Douglas Gregor2af2f672009-09-21 20:12:40 +0000192 ///
193 /// \param R the context in which this result will be named.
194 void MaybeAddResult(Result R, DeclContext *CurContext = 0);
Douglas Gregor3545ff42009-09-21 16:56:56 +0000195
Douglas Gregorc580c522010-01-14 01:09:38 +0000196 /// \brief Add a new result to this result set, where we already know
197 /// the hiding declation (if any).
198 ///
199 /// \param R the result to add (if it is unique).
200 ///
201 /// \param CurContext the context in which this result will be named.
202 ///
203 /// \param Hiding the declaration that hides the result.
Douglas Gregor09bbc652010-01-14 15:47:35 +0000204 ///
205 /// \param InBaseClass whether the result was found in a base
206 /// class of the searched context.
207 void AddResult(Result R, DeclContext *CurContext, NamedDecl *Hiding,
208 bool InBaseClass);
Douglas Gregorc580c522010-01-14 01:09:38 +0000209
Douglas Gregor78a21012010-01-14 16:01:26 +0000210 /// \brief Add a new non-declaration result to this result set.
211 void AddResult(Result R);
212
Douglas Gregor3545ff42009-09-21 16:56:56 +0000213 /// \brief Enter into a new scope.
214 void EnterNewScope();
215
216 /// \brief Exit from the current scope.
217 void ExitScope();
218
Douglas Gregorbaf69612009-11-18 04:19:12 +0000219 /// \brief Ignore this declaration, if it is seen again.
220 void Ignore(Decl *D) { AllDeclsFound.insert(D->getCanonicalDecl()); }
221
Douglas Gregor3545ff42009-09-21 16:56:56 +0000222 /// \name Name lookup predicates
223 ///
224 /// These predicates can be passed to the name lookup functions to filter the
225 /// results of name lookup. All of the predicates have the same type, so that
226 ///
227 //@{
Douglas Gregor9d64c5e2009-09-21 20:51:25 +0000228 bool IsOrdinaryName(NamedDecl *ND) const;
Douglas Gregor70febae2010-05-28 00:49:12 +0000229 bool IsOrdinaryNonTypeName(NamedDecl *ND) const;
Douglas Gregor85b50632010-07-28 21:50:18 +0000230 bool IsIntegralConstantValue(NamedDecl *ND) const;
Douglas Gregor504a6ae2010-01-10 23:08:15 +0000231 bool IsOrdinaryNonValueName(NamedDecl *ND) const;
Douglas Gregor3545ff42009-09-21 16:56:56 +0000232 bool IsNestedNameSpecifier(NamedDecl *ND) const;
233 bool IsEnum(NamedDecl *ND) const;
234 bool IsClassOrStruct(NamedDecl *ND) const;
235 bool IsUnion(NamedDecl *ND) const;
236 bool IsNamespace(NamedDecl *ND) const;
237 bool IsNamespaceOrAlias(NamedDecl *ND) const;
238 bool IsType(NamedDecl *ND) const;
Douglas Gregore412a5a2009-09-23 22:26:46 +0000239 bool IsMember(NamedDecl *ND) const;
Douglas Gregor2b8162b2010-01-14 16:08:12 +0000240 bool IsObjCIvar(NamedDecl *ND) const;
Douglas Gregora817a192010-05-27 23:06:34 +0000241 bool IsObjCMessageReceiver(NamedDecl *ND) const;
Douglas Gregor3545ff42009-09-21 16:56:56 +0000242 //@}
243 };
244}
245
Douglas Gregor05e7ca32009-12-06 20:23:50 +0000246class ResultBuilder::ShadowMapEntry::iterator {
247 llvm::PointerUnion<NamedDecl*, const DeclIndexPair*> DeclOrIterator;
248 unsigned SingleDeclIndex;
249
250public:
251 typedef DeclIndexPair value_type;
252 typedef value_type reference;
253 typedef std::ptrdiff_t difference_type;
254 typedef std::input_iterator_tag iterator_category;
255
256 class pointer {
257 DeclIndexPair Value;
258
259 public:
260 pointer(const DeclIndexPair &Value) : Value(Value) { }
261
262 const DeclIndexPair *operator->() const {
263 return &Value;
264 }
265 };
266
267 iterator() : DeclOrIterator((NamedDecl *)0), SingleDeclIndex(0) { }
268
269 iterator(NamedDecl *SingleDecl, unsigned Index)
270 : DeclOrIterator(SingleDecl), SingleDeclIndex(Index) { }
271
272 iterator(const DeclIndexPair *Iterator)
273 : DeclOrIterator(Iterator), SingleDeclIndex(0) { }
274
275 iterator &operator++() {
276 if (DeclOrIterator.is<NamedDecl *>()) {
277 DeclOrIterator = (NamedDecl *)0;
278 SingleDeclIndex = 0;
279 return *this;
280 }
281
282 const DeclIndexPair *I = DeclOrIterator.get<const DeclIndexPair*>();
283 ++I;
284 DeclOrIterator = I;
285 return *this;
286 }
287
288 iterator operator++(int) {
289 iterator tmp(*this);
290 ++(*this);
291 return tmp;
292 }
293
294 reference operator*() const {
295 if (NamedDecl *ND = DeclOrIterator.dyn_cast<NamedDecl *>())
296 return reference(ND, SingleDeclIndex);
297
Douglas Gregor94bb5e82009-12-06 21:27:58 +0000298 return *DeclOrIterator.get<const DeclIndexPair*>();
Douglas Gregor05e7ca32009-12-06 20:23:50 +0000299 }
300
301 pointer operator->() const {
302 return pointer(**this);
303 }
304
305 friend bool operator==(const iterator &X, const iterator &Y) {
Douglas Gregor94bb5e82009-12-06 21:27:58 +0000306 return X.DeclOrIterator.getOpaqueValue()
307 == Y.DeclOrIterator.getOpaqueValue() &&
Douglas Gregor05e7ca32009-12-06 20:23:50 +0000308 X.SingleDeclIndex == Y.SingleDeclIndex;
309 }
310
311 friend bool operator!=(const iterator &X, const iterator &Y) {
Douglas Gregor94bb5e82009-12-06 21:27:58 +0000312 return !(X == Y);
Douglas Gregor05e7ca32009-12-06 20:23:50 +0000313 }
314};
315
Douglas Gregor05e7ca32009-12-06 20:23:50 +0000316ResultBuilder::ShadowMapEntry::iterator
317ResultBuilder::ShadowMapEntry::begin() const {
318 if (DeclOrVector.isNull())
319 return iterator();
320
321 if (NamedDecl *ND = DeclOrVector.dyn_cast<NamedDecl *>())
322 return iterator(ND, SingleDeclIndex);
323
324 return iterator(DeclOrVector.get<DeclIndexPairVector *>()->begin());
325}
326
327ResultBuilder::ShadowMapEntry::iterator
328ResultBuilder::ShadowMapEntry::end() const {
329 if (DeclOrVector.is<NamedDecl *>() || DeclOrVector.isNull())
330 return iterator();
331
332 return iterator(DeclOrVector.get<DeclIndexPairVector *>()->end());
333}
334
Douglas Gregor2af2f672009-09-21 20:12:40 +0000335/// \brief Compute the qualification required to get from the current context
336/// (\p CurContext) to the target context (\p TargetContext).
337///
338/// \param Context the AST context in which the qualification will be used.
339///
340/// \param CurContext the context where an entity is being named, which is
341/// typically based on the current scope.
342///
343/// \param TargetContext the context in which the named entity actually
344/// resides.
345///
346/// \returns a nested name specifier that refers into the target context, or
347/// NULL if no qualification is needed.
348static NestedNameSpecifier *
349getRequiredQualification(ASTContext &Context,
350 DeclContext *CurContext,
351 DeclContext *TargetContext) {
352 llvm::SmallVector<DeclContext *, 4> TargetParents;
353
354 for (DeclContext *CommonAncestor = TargetContext;
355 CommonAncestor && !CommonAncestor->Encloses(CurContext);
356 CommonAncestor = CommonAncestor->getLookupParent()) {
357 if (CommonAncestor->isTransparentContext() ||
358 CommonAncestor->isFunctionOrMethod())
359 continue;
360
361 TargetParents.push_back(CommonAncestor);
362 }
363
364 NestedNameSpecifier *Result = 0;
365 while (!TargetParents.empty()) {
366 DeclContext *Parent = TargetParents.back();
367 TargetParents.pop_back();
368
369 if (NamespaceDecl *Namespace = dyn_cast<NamespaceDecl>(Parent))
370 Result = NestedNameSpecifier::Create(Context, Result, Namespace);
371 else if (TagDecl *TD = dyn_cast<TagDecl>(Parent))
372 Result = NestedNameSpecifier::Create(Context, Result,
373 false,
374 Context.getTypeDeclType(TD).getTypePtr());
Douglas Gregor9eb77012009-11-07 00:00:49 +0000375 }
Douglas Gregor2af2f672009-09-21 20:12:40 +0000376 return Result;
377}
378
Douglas Gregor6ae4c522010-01-14 03:21:49 +0000379bool ResultBuilder::isInterestingDecl(NamedDecl *ND,
380 bool &AsNestedNameSpecifier) const {
381 AsNestedNameSpecifier = false;
382
Douglas Gregor7c208612010-01-14 00:20:49 +0000383 ND = ND->getUnderlyingDecl();
384 unsigned IDNS = ND->getIdentifierNamespace();
Douglas Gregor58acf322009-10-09 22:16:47 +0000385
386 // Skip unnamed entities.
Douglas Gregor7c208612010-01-14 00:20:49 +0000387 if (!ND->getDeclName())
388 return false;
Douglas Gregor3545ff42009-09-21 16:56:56 +0000389
390 // Friend declarations and declarations introduced due to friends are never
391 // added as results.
John McCallbbbbe4e2010-03-11 07:50:04 +0000392 if (IDNS & (Decl::IDNS_OrdinaryFriend | Decl::IDNS_TagFriend))
Douglas Gregor7c208612010-01-14 00:20:49 +0000393 return false;
394
Douglas Gregor99fe2ad2009-12-11 17:31:05 +0000395 // Class template (partial) specializations are never added as results.
Douglas Gregor7c208612010-01-14 00:20:49 +0000396 if (isa<ClassTemplateSpecializationDecl>(ND) ||
397 isa<ClassTemplatePartialSpecializationDecl>(ND))
398 return false;
Douglas Gregor3545ff42009-09-21 16:56:56 +0000399
Douglas Gregor99fe2ad2009-12-11 17:31:05 +0000400 // Using declarations themselves are never added as results.
Douglas Gregor7c208612010-01-14 00:20:49 +0000401 if (isa<UsingDecl>(ND))
402 return false;
403
404 // Some declarations have reserved names that we don't want to ever show.
405 if (const IdentifierInfo *Id = ND->getIdentifier()) {
Douglas Gregor3545ff42009-09-21 16:56:56 +0000406 // __va_list_tag is a freak of nature. Find it and skip it.
407 if (Id->isStr("__va_list_tag") || Id->isStr("__builtin_va_list"))
Douglas Gregor7c208612010-01-14 00:20:49 +0000408 return false;
Douglas Gregor3545ff42009-09-21 16:56:56 +0000409
Douglas Gregor58acf322009-10-09 22:16:47 +0000410 // Filter out names reserved for the implementation (C99 7.1.3,
Douglas Gregor9f1570d2010-07-14 17:44:04 +0000411 // C++ [lib.global.names]) if they come from a system header.
Daniel Dunbar2c422dc92009-10-18 20:26:12 +0000412 //
413 // FIXME: Add predicate for this.
Douglas Gregor58acf322009-10-09 22:16:47 +0000414 if (Id->getLength() >= 2) {
Daniel Dunbar2c422dc92009-10-18 20:26:12 +0000415 const char *Name = Id->getNameStart();
Douglas Gregor58acf322009-10-09 22:16:47 +0000416 if (Name[0] == '_' &&
Douglas Gregor9f1570d2010-07-14 17:44:04 +0000417 (Name[1] == '_' || (Name[1] >= 'A' && Name[1] <= 'Z')) &&
418 (ND->getLocation().isInvalid() ||
419 SemaRef.SourceMgr.isInSystemHeader(
420 SemaRef.SourceMgr.getSpellingLoc(ND->getLocation()))))
Douglas Gregor7c208612010-01-14 00:20:49 +0000421 return false;
Douglas Gregor58acf322009-10-09 22:16:47 +0000422 }
Douglas Gregor3545ff42009-09-21 16:56:56 +0000423 }
Douglas Gregor7c208612010-01-14 00:20:49 +0000424
Douglas Gregor3545ff42009-09-21 16:56:56 +0000425 // C++ constructors are never found by name lookup.
Douglas Gregor7c208612010-01-14 00:20:49 +0000426 if (isa<CXXConstructorDecl>(ND))
427 return false;
Douglas Gregor3545ff42009-09-21 16:56:56 +0000428
Douglas Gregor59cab552010-08-16 23:05:20 +0000429 if (Filter == &ResultBuilder::IsNestedNameSpecifier ||
430 ((isa<NamespaceDecl>(ND) || isa<NamespaceAliasDecl>(ND)) &&
431 Filter != &ResultBuilder::IsNamespace &&
432 Filter != &ResultBuilder::IsNamespaceOrAlias))
433 AsNestedNameSpecifier = true;
434
Douglas Gregor3545ff42009-09-21 16:56:56 +0000435 // Filter out any unwanted results.
Douglas Gregor6ae4c522010-01-14 03:21:49 +0000436 if (Filter && !(this->*Filter)(ND)) {
437 // Check whether it is interesting as a nested-name-specifier.
438 if (AllowNestedNameSpecifiers && SemaRef.getLangOptions().CPlusPlus &&
439 IsNestedNameSpecifier(ND) &&
440 (Filter != &ResultBuilder::IsMember ||
441 (isa<CXXRecordDecl>(ND) &&
442 cast<CXXRecordDecl>(ND)->isInjectedClassName()))) {
443 AsNestedNameSpecifier = true;
444 return true;
445 }
446
Douglas Gregor7c208612010-01-14 00:20:49 +0000447 return false;
Douglas Gregor59cab552010-08-16 23:05:20 +0000448 }
Douglas Gregor7c208612010-01-14 00:20:49 +0000449 // ... then it must be interesting!
450 return true;
451}
452
Douglas Gregore0717ab2010-01-14 00:41:07 +0000453bool ResultBuilder::CheckHiddenResult(Result &R, DeclContext *CurContext,
454 NamedDecl *Hiding) {
455 // In C, there is no way to refer to a hidden name.
456 // FIXME: This isn't true; we can find a tag name hidden by an ordinary
457 // name if we introduce the tag type.
458 if (!SemaRef.getLangOptions().CPlusPlus)
459 return true;
460
461 DeclContext *HiddenCtx = R.Declaration->getDeclContext()->getLookupContext();
462
463 // There is no way to qualify a name declared in a function or method.
464 if (HiddenCtx->isFunctionOrMethod())
465 return true;
466
467 if (HiddenCtx == Hiding->getDeclContext()->getLookupContext())
468 return true;
469
470 // We can refer to the result with the appropriate qualification. Do it.
471 R.Hidden = true;
472 R.QualifierIsInformative = false;
473
474 if (!R.Qualifier)
475 R.Qualifier = getRequiredQualification(SemaRef.Context,
476 CurContext,
477 R.Declaration->getDeclContext());
478 return false;
479}
480
Douglas Gregor95887f92010-07-08 23:20:03 +0000481/// \brief A simplified classification of types used to determine whether two
482/// types are "similar enough" when adjusting priorities.
Douglas Gregor6e240332010-08-16 16:18:59 +0000483SimplifiedTypeClass clang::getSimplifiedTypeClass(CanQualType T) {
Douglas Gregor95887f92010-07-08 23:20:03 +0000484 switch (T->getTypeClass()) {
485 case Type::Builtin:
486 switch (cast<BuiltinType>(T)->getKind()) {
487 case BuiltinType::Void:
488 return STC_Void;
489
490 case BuiltinType::NullPtr:
491 return STC_Pointer;
492
493 case BuiltinType::Overload:
494 case BuiltinType::Dependent:
495 case BuiltinType::UndeducedAuto:
496 return STC_Other;
497
498 case BuiltinType::ObjCId:
499 case BuiltinType::ObjCClass:
500 case BuiltinType::ObjCSel:
501 return STC_ObjectiveC;
502
503 default:
504 return STC_Arithmetic;
505 }
506 return STC_Other;
507
508 case Type::Complex:
509 return STC_Arithmetic;
510
511 case Type::Pointer:
512 return STC_Pointer;
513
514 case Type::BlockPointer:
515 return STC_Block;
516
517 case Type::LValueReference:
518 case Type::RValueReference:
519 return getSimplifiedTypeClass(T->getAs<ReferenceType>()->getPointeeType());
520
521 case Type::ConstantArray:
522 case Type::IncompleteArray:
523 case Type::VariableArray:
524 case Type::DependentSizedArray:
525 return STC_Array;
526
527 case Type::DependentSizedExtVector:
528 case Type::Vector:
529 case Type::ExtVector:
530 return STC_Arithmetic;
531
532 case Type::FunctionProto:
533 case Type::FunctionNoProto:
534 return STC_Function;
535
536 case Type::Record:
537 return STC_Record;
538
539 case Type::Enum:
540 return STC_Arithmetic;
541
542 case Type::ObjCObject:
543 case Type::ObjCInterface:
544 case Type::ObjCObjectPointer:
545 return STC_ObjectiveC;
546
547 default:
548 return STC_Other;
549 }
550}
551
552/// \brief Get the type that a given expression will have if this declaration
553/// is used as an expression in its "typical" code-completion form.
Douglas Gregor6e240332010-08-16 16:18:59 +0000554QualType clang::getDeclUsageType(ASTContext &C, NamedDecl *ND) {
Douglas Gregor95887f92010-07-08 23:20:03 +0000555 ND = cast<NamedDecl>(ND->getUnderlyingDecl());
556
557 if (TypeDecl *Type = dyn_cast<TypeDecl>(ND))
558 return C.getTypeDeclType(Type);
559 if (ObjCInterfaceDecl *Iface = dyn_cast<ObjCInterfaceDecl>(ND))
560 return C.getObjCInterfaceType(Iface);
561
562 QualType T;
563 if (FunctionDecl *Function = dyn_cast<FunctionDecl>(ND))
Douglas Gregor603d81b2010-07-13 08:18:22 +0000564 T = Function->getCallResultType();
Douglas Gregor95887f92010-07-08 23:20:03 +0000565 else if (ObjCMethodDecl *Method = dyn_cast<ObjCMethodDecl>(ND))
Douglas Gregor603d81b2010-07-13 08:18:22 +0000566 T = Method->getSendResultType();
Douglas Gregor95887f92010-07-08 23:20:03 +0000567 else if (FunctionTemplateDecl *FunTmpl = dyn_cast<FunctionTemplateDecl>(ND))
Douglas Gregor603d81b2010-07-13 08:18:22 +0000568 T = FunTmpl->getTemplatedDecl()->getCallResultType();
Douglas Gregor95887f92010-07-08 23:20:03 +0000569 else if (EnumConstantDecl *Enumerator = dyn_cast<EnumConstantDecl>(ND))
570 T = C.getTypeDeclType(cast<EnumDecl>(Enumerator->getDeclContext()));
571 else if (ObjCPropertyDecl *Property = dyn_cast<ObjCPropertyDecl>(ND))
572 T = Property->getType();
573 else if (ValueDecl *Value = dyn_cast<ValueDecl>(ND))
574 T = Value->getType();
575 else
576 return QualType();
577
578 return T.getNonReferenceType();
579}
580
581void ResultBuilder::AdjustResultPriorityForPreferredType(Result &R) {
582 QualType T = getDeclUsageType(SemaRef.Context, R.Declaration);
583 if (T.isNull())
584 return;
585
586 CanQualType TC = SemaRef.Context.getCanonicalType(T);
587 // Check for exactly-matching types (modulo qualifiers).
588 if (SemaRef.Context.hasSameUnqualifiedType(PreferredType, TC))
589 R.Priority /= CCF_ExactTypeMatch;
590 // Check for nearly-matching types, based on classification of each.
591 else if ((getSimplifiedTypeClass(PreferredType)
592 == getSimplifiedTypeClass(TC)) &&
593 !(PreferredType->isEnumeralType() && TC->isEnumeralType()))
594 R.Priority /= CCF_SimilarTypeMatch;
595}
596
Douglas Gregor7c208612010-01-14 00:20:49 +0000597void ResultBuilder::MaybeAddResult(Result R, DeclContext *CurContext) {
598 assert(!ShadowMaps.empty() && "Must enter into a results scope");
599
600 if (R.Kind != Result::RK_Declaration) {
601 // For non-declaration results, just add the result.
602 Results.push_back(R);
603 return;
604 }
605
606 // Look through using declarations.
607 if (UsingShadowDecl *Using = dyn_cast<UsingShadowDecl>(R.Declaration)) {
608 MaybeAddResult(Result(Using->getTargetDecl(), R.Qualifier), CurContext);
609 return;
610 }
611
612 Decl *CanonDecl = R.Declaration->getCanonicalDecl();
613 unsigned IDNS = CanonDecl->getIdentifierNamespace();
614
Douglas Gregor6ae4c522010-01-14 03:21:49 +0000615 bool AsNestedNameSpecifier = false;
616 if (!isInterestingDecl(R.Declaration, AsNestedNameSpecifier))
Douglas Gregor7c208612010-01-14 00:20:49 +0000617 return;
618
Douglas Gregor3545ff42009-09-21 16:56:56 +0000619 ShadowMap &SMap = ShadowMaps.back();
Douglas Gregor05e7ca32009-12-06 20:23:50 +0000620 ShadowMapEntry::iterator I, IEnd;
621 ShadowMap::iterator NamePos = SMap.find(R.Declaration->getDeclName());
622 if (NamePos != SMap.end()) {
623 I = NamePos->second.begin();
624 IEnd = NamePos->second.end();
625 }
626
627 for (; I != IEnd; ++I) {
628 NamedDecl *ND = I->first;
629 unsigned Index = I->second;
Douglas Gregor3545ff42009-09-21 16:56:56 +0000630 if (ND->getCanonicalDecl() == CanonDecl) {
631 // This is a redeclaration. Always pick the newer declaration.
Douglas Gregor3545ff42009-09-21 16:56:56 +0000632 Results[Index].Declaration = R.Declaration;
633
Douglas Gregor3545ff42009-09-21 16:56:56 +0000634 // We're done.
635 return;
636 }
637 }
638
639 // This is a new declaration in this scope. However, check whether this
640 // declaration name is hidden by a similarly-named declaration in an outer
641 // scope.
642 std::list<ShadowMap>::iterator SM, SMEnd = ShadowMaps.end();
643 --SMEnd;
644 for (SM = ShadowMaps.begin(); SM != SMEnd; ++SM) {
Douglas Gregor05e7ca32009-12-06 20:23:50 +0000645 ShadowMapEntry::iterator I, IEnd;
646 ShadowMap::iterator NamePos = SM->find(R.Declaration->getDeclName());
647 if (NamePos != SM->end()) {
648 I = NamePos->second.begin();
649 IEnd = NamePos->second.end();
650 }
651 for (; I != IEnd; ++I) {
Douglas Gregor3545ff42009-09-21 16:56:56 +0000652 // A tag declaration does not hide a non-tag declaration.
John McCalle87beb22010-04-23 18:46:30 +0000653 if (I->first->hasTagIdentifierNamespace() &&
Douglas Gregor3545ff42009-09-21 16:56:56 +0000654 (IDNS & (Decl::IDNS_Member | Decl::IDNS_Ordinary |
655 Decl::IDNS_ObjCProtocol)))
656 continue;
657
658 // Protocols are in distinct namespaces from everything else.
Douglas Gregor05e7ca32009-12-06 20:23:50 +0000659 if (((I->first->getIdentifierNamespace() & Decl::IDNS_ObjCProtocol)
Douglas Gregor3545ff42009-09-21 16:56:56 +0000660 || (IDNS & Decl::IDNS_ObjCProtocol)) &&
Douglas Gregor05e7ca32009-12-06 20:23:50 +0000661 I->first->getIdentifierNamespace() != IDNS)
Douglas Gregor3545ff42009-09-21 16:56:56 +0000662 continue;
663
664 // The newly-added result is hidden by an entry in the shadow map.
Douglas Gregore0717ab2010-01-14 00:41:07 +0000665 if (CheckHiddenResult(R, CurContext, I->first))
Douglas Gregor3545ff42009-09-21 16:56:56 +0000666 return;
Douglas Gregor3545ff42009-09-21 16:56:56 +0000667
668 break;
669 }
670 }
671
672 // Make sure that any given declaration only shows up in the result set once.
673 if (!AllDeclsFound.insert(CanonDecl))
674 return;
675
Douglas Gregore412a5a2009-09-23 22:26:46 +0000676 // If the filter is for nested-name-specifiers, then this result starts a
677 // nested-name-specifier.
Douglas Gregora2db7932010-05-26 22:00:08 +0000678 if (AsNestedNameSpecifier) {
Douglas Gregore412a5a2009-09-23 22:26:46 +0000679 R.StartsNestedNameSpecifier = true;
Douglas Gregora2db7932010-05-26 22:00:08 +0000680 R.Priority = CCP_NestedNameSpecifier;
Douglas Gregor95887f92010-07-08 23:20:03 +0000681 } else if (!PreferredType.isNull())
682 AdjustResultPriorityForPreferredType(R);
683
Douglas Gregor5bf52692009-09-22 23:15:58 +0000684 // If this result is supposed to have an informative qualifier, add one.
Douglas Gregore412a5a2009-09-23 22:26:46 +0000685 if (R.QualifierIsInformative && !R.Qualifier &&
686 !R.StartsNestedNameSpecifier) {
Douglas Gregor5bf52692009-09-22 23:15:58 +0000687 DeclContext *Ctx = R.Declaration->getDeclContext();
688 if (NamespaceDecl *Namespace = dyn_cast<NamespaceDecl>(Ctx))
689 R.Qualifier = NestedNameSpecifier::Create(SemaRef.Context, 0, Namespace);
690 else if (TagDecl *Tag = dyn_cast<TagDecl>(Ctx))
691 R.Qualifier = NestedNameSpecifier::Create(SemaRef.Context, 0, false,
692 SemaRef.Context.getTypeDeclType(Tag).getTypePtr());
693 else
694 R.QualifierIsInformative = false;
695 }
Douglas Gregore412a5a2009-09-23 22:26:46 +0000696
Douglas Gregor3545ff42009-09-21 16:56:56 +0000697 // Insert this result into the set of results and into the current shadow
698 // map.
Douglas Gregor05e7ca32009-12-06 20:23:50 +0000699 SMap[R.Declaration->getDeclName()].Add(R.Declaration, Results.size());
Douglas Gregor3545ff42009-09-21 16:56:56 +0000700 Results.push_back(R);
701}
702
Douglas Gregorc580c522010-01-14 01:09:38 +0000703void ResultBuilder::AddResult(Result R, DeclContext *CurContext,
Douglas Gregor09bbc652010-01-14 15:47:35 +0000704 NamedDecl *Hiding, bool InBaseClass = false) {
Douglas Gregor78a21012010-01-14 16:01:26 +0000705 if (R.Kind != Result::RK_Declaration) {
706 // For non-declaration results, just add the result.
707 Results.push_back(R);
708 return;
709 }
710
Douglas Gregorc580c522010-01-14 01:09:38 +0000711 // Look through using declarations.
712 if (UsingShadowDecl *Using = dyn_cast<UsingShadowDecl>(R.Declaration)) {
713 AddResult(Result(Using->getTargetDecl(), R.Qualifier), CurContext, Hiding);
714 return;
715 }
716
Douglas Gregor6ae4c522010-01-14 03:21:49 +0000717 bool AsNestedNameSpecifier = false;
718 if (!isInterestingDecl(R.Declaration, AsNestedNameSpecifier))
Douglas Gregorc580c522010-01-14 01:09:38 +0000719 return;
720
721 if (Hiding && CheckHiddenResult(R, CurContext, Hiding))
722 return;
723
724 // Make sure that any given declaration only shows up in the result set once.
725 if (!AllDeclsFound.insert(R.Declaration->getCanonicalDecl()))
726 return;
727
728 // If the filter is for nested-name-specifiers, then this result starts a
729 // nested-name-specifier.
Douglas Gregora2db7932010-05-26 22:00:08 +0000730 if (AsNestedNameSpecifier) {
Douglas Gregorc580c522010-01-14 01:09:38 +0000731 R.StartsNestedNameSpecifier = true;
Douglas Gregora2db7932010-05-26 22:00:08 +0000732 R.Priority = CCP_NestedNameSpecifier;
733 }
Douglas Gregor09bbc652010-01-14 15:47:35 +0000734 else if (Filter == &ResultBuilder::IsMember && !R.Qualifier && InBaseClass &&
735 isa<CXXRecordDecl>(R.Declaration->getDeclContext()
736 ->getLookupContext()))
737 R.QualifierIsInformative = true;
738
Douglas Gregorc580c522010-01-14 01:09:38 +0000739 // If this result is supposed to have an informative qualifier, add one.
740 if (R.QualifierIsInformative && !R.Qualifier &&
741 !R.StartsNestedNameSpecifier) {
742 DeclContext *Ctx = R.Declaration->getDeclContext();
743 if (NamespaceDecl *Namespace = dyn_cast<NamespaceDecl>(Ctx))
744 R.Qualifier = NestedNameSpecifier::Create(SemaRef.Context, 0, Namespace);
745 else if (TagDecl *Tag = dyn_cast<TagDecl>(Ctx))
746 R.Qualifier = NestedNameSpecifier::Create(SemaRef.Context, 0, false,
Douglas Gregor6ae4c522010-01-14 03:21:49 +0000747 SemaRef.Context.getTypeDeclType(Tag).getTypePtr());
Douglas Gregorc580c522010-01-14 01:09:38 +0000748 else
749 R.QualifierIsInformative = false;
750 }
751
Douglas Gregora2db7932010-05-26 22:00:08 +0000752 // Adjust the priority if this result comes from a base class.
753 if (InBaseClass)
754 R.Priority += CCD_InBaseClass;
755
Douglas Gregor95887f92010-07-08 23:20:03 +0000756 if (!PreferredType.isNull())
757 AdjustResultPriorityForPreferredType(R);
Douglas Gregor7aa6b222010-05-30 01:49:25 +0000758
Douglas Gregorc580c522010-01-14 01:09:38 +0000759 // Insert this result into the set of results.
760 Results.push_back(R);
761}
762
Douglas Gregor78a21012010-01-14 16:01:26 +0000763void ResultBuilder::AddResult(Result R) {
764 assert(R.Kind != Result::RK_Declaration &&
765 "Declaration results need more context");
766 Results.push_back(R);
767}
768
Douglas Gregor3545ff42009-09-21 16:56:56 +0000769/// \brief Enter into a new scope.
770void ResultBuilder::EnterNewScope() {
771 ShadowMaps.push_back(ShadowMap());
772}
773
774/// \brief Exit from the current scope.
775void ResultBuilder::ExitScope() {
Douglas Gregor05e7ca32009-12-06 20:23:50 +0000776 for (ShadowMap::iterator E = ShadowMaps.back().begin(),
777 EEnd = ShadowMaps.back().end();
778 E != EEnd;
779 ++E)
780 E->second.Destroy();
781
Douglas Gregor3545ff42009-09-21 16:56:56 +0000782 ShadowMaps.pop_back();
783}
784
Douglas Gregor9d64c5e2009-09-21 20:51:25 +0000785/// \brief Determines whether this given declaration will be found by
786/// ordinary name lookup.
787bool ResultBuilder::IsOrdinaryName(NamedDecl *ND) const {
Douglas Gregor70febae2010-05-28 00:49:12 +0000788 ND = cast<NamedDecl>(ND->getUnderlyingDecl());
789
Douglas Gregor9d64c5e2009-09-21 20:51:25 +0000790 unsigned IDNS = Decl::IDNS_Ordinary;
791 if (SemaRef.getLangOptions().CPlusPlus)
Douglas Gregor9858ed52010-06-15 20:26:51 +0000792 IDNS |= Decl::IDNS_Tag | Decl::IDNS_Namespace | Decl::IDNS_Member;
Douglas Gregorc580c522010-01-14 01:09:38 +0000793 else if (SemaRef.getLangOptions().ObjC1 && isa<ObjCIvarDecl>(ND))
794 return true;
795
Douglas Gregor9d64c5e2009-09-21 20:51:25 +0000796 return ND->getIdentifierNamespace() & IDNS;
797}
798
Douglas Gregor504a6ae2010-01-10 23:08:15 +0000799/// \brief Determines whether this given declaration will be found by
Douglas Gregor70febae2010-05-28 00:49:12 +0000800/// ordinary name lookup but is not a type name.
801bool ResultBuilder::IsOrdinaryNonTypeName(NamedDecl *ND) const {
802 ND = cast<NamedDecl>(ND->getUnderlyingDecl());
803 if (isa<TypeDecl>(ND) || isa<ObjCInterfaceDecl>(ND))
804 return false;
805
806 unsigned IDNS = Decl::IDNS_Ordinary;
807 if (SemaRef.getLangOptions().CPlusPlus)
Douglas Gregor9858ed52010-06-15 20:26:51 +0000808 IDNS |= Decl::IDNS_Tag | Decl::IDNS_Namespace | Decl::IDNS_Member;
Douglas Gregor70febae2010-05-28 00:49:12 +0000809 else if (SemaRef.getLangOptions().ObjC1 && isa<ObjCIvarDecl>(ND))
810 return true;
811
812 return ND->getIdentifierNamespace() & IDNS;
813}
814
Douglas Gregor85b50632010-07-28 21:50:18 +0000815bool ResultBuilder::IsIntegralConstantValue(NamedDecl *ND) const {
816 if (!IsOrdinaryNonTypeName(ND))
817 return 0;
818
819 if (ValueDecl *VD = dyn_cast<ValueDecl>(ND->getUnderlyingDecl()))
820 if (VD->getType()->isIntegralOrEnumerationType())
821 return true;
822
823 return false;
824}
825
Douglas Gregor70febae2010-05-28 00:49:12 +0000826/// \brief Determines whether this given declaration will be found by
Douglas Gregor504a6ae2010-01-10 23:08:15 +0000827/// ordinary name lookup.
828bool ResultBuilder::IsOrdinaryNonValueName(NamedDecl *ND) const {
Douglas Gregor70febae2010-05-28 00:49:12 +0000829 ND = cast<NamedDecl>(ND->getUnderlyingDecl());
830
Douglas Gregor504a6ae2010-01-10 23:08:15 +0000831 unsigned IDNS = Decl::IDNS_Ordinary;
832 if (SemaRef.getLangOptions().CPlusPlus)
John McCalle87beb22010-04-23 18:46:30 +0000833 IDNS |= Decl::IDNS_Tag | Decl::IDNS_Namespace;
Douglas Gregor504a6ae2010-01-10 23:08:15 +0000834
835 return (ND->getIdentifierNamespace() & IDNS) &&
Douglas Gregor70febae2010-05-28 00:49:12 +0000836 !isa<ValueDecl>(ND) && !isa<FunctionTemplateDecl>(ND) &&
837 !isa<ObjCPropertyDecl>(ND);
Douglas Gregor504a6ae2010-01-10 23:08:15 +0000838}
839
Douglas Gregor3545ff42009-09-21 16:56:56 +0000840/// \brief Determines whether the given declaration is suitable as the
841/// start of a C++ nested-name-specifier, e.g., a class or namespace.
842bool ResultBuilder::IsNestedNameSpecifier(NamedDecl *ND) const {
843 // Allow us to find class templates, too.
844 if (ClassTemplateDecl *ClassTemplate = dyn_cast<ClassTemplateDecl>(ND))
845 ND = ClassTemplate->getTemplatedDecl();
846
847 return SemaRef.isAcceptableNestedNameSpecifier(ND);
848}
849
850/// \brief Determines whether the given declaration is an enumeration.
851bool ResultBuilder::IsEnum(NamedDecl *ND) const {
852 return isa<EnumDecl>(ND);
853}
854
855/// \brief Determines whether the given declaration is a class or struct.
856bool ResultBuilder::IsClassOrStruct(NamedDecl *ND) const {
857 // Allow us to find class templates, too.
858 if (ClassTemplateDecl *ClassTemplate = dyn_cast<ClassTemplateDecl>(ND))
859 ND = ClassTemplate->getTemplatedDecl();
860
861 if (RecordDecl *RD = dyn_cast<RecordDecl>(ND))
Abramo Bagnara6150c882010-05-11 21:36:43 +0000862 return RD->getTagKind() == TTK_Class ||
863 RD->getTagKind() == TTK_Struct;
Douglas Gregor3545ff42009-09-21 16:56:56 +0000864
865 return false;
866}
867
868/// \brief Determines whether the given declaration is a union.
869bool ResultBuilder::IsUnion(NamedDecl *ND) const {
870 // Allow us to find class templates, too.
871 if (ClassTemplateDecl *ClassTemplate = dyn_cast<ClassTemplateDecl>(ND))
872 ND = ClassTemplate->getTemplatedDecl();
873
874 if (RecordDecl *RD = dyn_cast<RecordDecl>(ND))
Abramo Bagnara6150c882010-05-11 21:36:43 +0000875 return RD->getTagKind() == TTK_Union;
Douglas Gregor3545ff42009-09-21 16:56:56 +0000876
877 return false;
878}
879
880/// \brief Determines whether the given declaration is a namespace.
881bool ResultBuilder::IsNamespace(NamedDecl *ND) const {
882 return isa<NamespaceDecl>(ND);
883}
884
885/// \brief Determines whether the given declaration is a namespace or
886/// namespace alias.
887bool ResultBuilder::IsNamespaceOrAlias(NamedDecl *ND) const {
888 return isa<NamespaceDecl>(ND) || isa<NamespaceAliasDecl>(ND);
889}
890
Douglas Gregor99fe2ad2009-12-11 17:31:05 +0000891/// \brief Determines whether the given declaration is a type.
Douglas Gregor3545ff42009-09-21 16:56:56 +0000892bool ResultBuilder::IsType(NamedDecl *ND) const {
893 return isa<TypeDecl>(ND);
894}
895
Douglas Gregor99fe2ad2009-12-11 17:31:05 +0000896/// \brief Determines which members of a class should be visible via
897/// "." or "->". Only value declarations, nested name specifiers, and
898/// using declarations thereof should show up.
Douglas Gregore412a5a2009-09-23 22:26:46 +0000899bool ResultBuilder::IsMember(NamedDecl *ND) const {
Douglas Gregor99fe2ad2009-12-11 17:31:05 +0000900 if (UsingShadowDecl *Using = dyn_cast<UsingShadowDecl>(ND))
901 ND = Using->getTargetDecl();
902
Douglas Gregor70788392009-12-11 18:14:22 +0000903 return isa<ValueDecl>(ND) || isa<FunctionTemplateDecl>(ND) ||
904 isa<ObjCPropertyDecl>(ND);
Douglas Gregore412a5a2009-09-23 22:26:46 +0000905}
906
Douglas Gregora817a192010-05-27 23:06:34 +0000907static bool isObjCReceiverType(ASTContext &C, QualType T) {
908 T = C.getCanonicalType(T);
909 switch (T->getTypeClass()) {
910 case Type::ObjCObject:
911 case Type::ObjCInterface:
912 case Type::ObjCObjectPointer:
913 return true;
914
915 case Type::Builtin:
916 switch (cast<BuiltinType>(T)->getKind()) {
917 case BuiltinType::ObjCId:
918 case BuiltinType::ObjCClass:
919 case BuiltinType::ObjCSel:
920 return true;
921
922 default:
923 break;
924 }
925 return false;
926
927 default:
928 break;
929 }
930
931 if (!C.getLangOptions().CPlusPlus)
932 return false;
933
934 // FIXME: We could perform more analysis here to determine whether a
935 // particular class type has any conversions to Objective-C types. For now,
936 // just accept all class types.
937 return T->isDependentType() || T->isRecordType();
938}
939
940bool ResultBuilder::IsObjCMessageReceiver(NamedDecl *ND) const {
941 QualType T = getDeclUsageType(SemaRef.Context, ND);
942 if (T.isNull())
943 return false;
944
945 T = SemaRef.Context.getBaseElementType(T);
946 return isObjCReceiverType(SemaRef.Context, T);
947}
948
949
Douglas Gregor2b8162b2010-01-14 16:08:12 +0000950/// \rief Determines whether the given declaration is an Objective-C
951/// instance variable.
952bool ResultBuilder::IsObjCIvar(NamedDecl *ND) const {
953 return isa<ObjCIvarDecl>(ND);
954}
955
Douglas Gregorc580c522010-01-14 01:09:38 +0000956namespace {
957 /// \brief Visible declaration consumer that adds a code-completion result
958 /// for each visible declaration.
959 class CodeCompletionDeclConsumer : public VisibleDeclConsumer {
960 ResultBuilder &Results;
961 DeclContext *CurContext;
962
963 public:
964 CodeCompletionDeclConsumer(ResultBuilder &Results, DeclContext *CurContext)
965 : Results(Results), CurContext(CurContext) { }
966
Douglas Gregor09bbc652010-01-14 15:47:35 +0000967 virtual void FoundDecl(NamedDecl *ND, NamedDecl *Hiding, bool InBaseClass) {
968 Results.AddResult(ND, CurContext, Hiding, InBaseClass);
Douglas Gregorc580c522010-01-14 01:09:38 +0000969 }
970 };
971}
972
Douglas Gregor3545ff42009-09-21 16:56:56 +0000973/// \brief Add type specifiers for the current language as keyword results.
Douglas Gregorf98e6a22010-01-13 23:51:12 +0000974static void AddTypeSpecifierResults(const LangOptions &LangOpts,
Douglas Gregor3545ff42009-09-21 16:56:56 +0000975 ResultBuilder &Results) {
976 typedef CodeCompleteConsumer::Result Result;
Douglas Gregora2db7932010-05-26 22:00:08 +0000977 Results.AddResult(Result("short", CCP_Type));
978 Results.AddResult(Result("long", CCP_Type));
979 Results.AddResult(Result("signed", CCP_Type));
980 Results.AddResult(Result("unsigned", CCP_Type));
981 Results.AddResult(Result("void", CCP_Type));
982 Results.AddResult(Result("char", CCP_Type));
983 Results.AddResult(Result("int", CCP_Type));
984 Results.AddResult(Result("float", CCP_Type));
985 Results.AddResult(Result("double", CCP_Type));
986 Results.AddResult(Result("enum", CCP_Type));
987 Results.AddResult(Result("struct", CCP_Type));
988 Results.AddResult(Result("union", CCP_Type));
989 Results.AddResult(Result("const", CCP_Type));
990 Results.AddResult(Result("volatile", CCP_Type));
Douglas Gregor504a6ae2010-01-10 23:08:15 +0000991
Douglas Gregor3545ff42009-09-21 16:56:56 +0000992 if (LangOpts.C99) {
993 // C99-specific
Douglas Gregora2db7932010-05-26 22:00:08 +0000994 Results.AddResult(Result("_Complex", CCP_Type));
995 Results.AddResult(Result("_Imaginary", CCP_Type));
996 Results.AddResult(Result("_Bool", CCP_Type));
997 Results.AddResult(Result("restrict", CCP_Type));
Douglas Gregor3545ff42009-09-21 16:56:56 +0000998 }
999
1000 if (LangOpts.CPlusPlus) {
1001 // C++-specific
Douglas Gregora2db7932010-05-26 22:00:08 +00001002 Results.AddResult(Result("bool", CCP_Type));
1003 Results.AddResult(Result("class", CCP_Type));
1004 Results.AddResult(Result("wchar_t", CCP_Type));
Douglas Gregor3545ff42009-09-21 16:56:56 +00001005
Douglas Gregorf4c33342010-05-28 00:22:41 +00001006 // typename qualified-id
1007 CodeCompletionString *Pattern = new CodeCompletionString;
1008 Pattern->AddTypedTextChunk("typename");
1009 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
1010 Pattern->AddPlaceholderChunk("qualifier");
1011 Pattern->AddTextChunk("::");
1012 Pattern->AddPlaceholderChunk("name");
1013 Results.AddResult(Result(Pattern));
Douglas Gregorf64acca2010-05-25 21:41:55 +00001014
Douglas Gregor3545ff42009-09-21 16:56:56 +00001015 if (LangOpts.CPlusPlus0x) {
Douglas Gregora2db7932010-05-26 22:00:08 +00001016 Results.AddResult(Result("auto", CCP_Type));
1017 Results.AddResult(Result("char16_t", CCP_Type));
1018 Results.AddResult(Result("char32_t", CCP_Type));
Douglas Gregorf4c33342010-05-28 00:22:41 +00001019
1020 CodeCompletionString *Pattern = new CodeCompletionString;
1021 Pattern->AddTypedTextChunk("decltype");
1022 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
1023 Pattern->AddPlaceholderChunk("expression");
1024 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
1025 Results.AddResult(Result(Pattern));
Douglas Gregor3545ff42009-09-21 16:56:56 +00001026 }
1027 }
1028
1029 // GNU extensions
1030 if (LangOpts.GNUMode) {
1031 // FIXME: Enable when we actually support decimal floating point.
Douglas Gregor78a21012010-01-14 16:01:26 +00001032 // Results.AddResult(Result("_Decimal32"));
1033 // Results.AddResult(Result("_Decimal64"));
1034 // Results.AddResult(Result("_Decimal128"));
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001035
Douglas Gregorf4c33342010-05-28 00:22:41 +00001036 CodeCompletionString *Pattern = new CodeCompletionString;
1037 Pattern->AddTypedTextChunk("typeof");
1038 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
1039 Pattern->AddPlaceholderChunk("expression");
1040 Results.AddResult(Result(Pattern));
1041
1042 Pattern = new CodeCompletionString;
1043 Pattern->AddTypedTextChunk("typeof");
1044 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
1045 Pattern->AddPlaceholderChunk("type");
1046 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
1047 Results.AddResult(Result(Pattern));
Douglas Gregor3545ff42009-09-21 16:56:56 +00001048 }
1049}
1050
Douglas Gregor00c37ef2010-08-11 21:23:17 +00001051static void AddStorageSpecifiers(Action::ParserCompletionContext CCC,
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001052 const LangOptions &LangOpts,
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001053 ResultBuilder &Results) {
1054 typedef CodeCompleteConsumer::Result Result;
1055 // Note: we don't suggest either "auto" or "register", because both
1056 // are pointless as storage specifiers. Elsewhere, we suggest "auto"
1057 // in C++0x as a type specifier.
Douglas Gregor78a21012010-01-14 16:01:26 +00001058 Results.AddResult(Result("extern"));
1059 Results.AddResult(Result("static"));
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001060}
1061
Douglas Gregor00c37ef2010-08-11 21:23:17 +00001062static void AddFunctionSpecifiers(Action::ParserCompletionContext CCC,
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001063 const LangOptions &LangOpts,
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001064 ResultBuilder &Results) {
1065 typedef CodeCompleteConsumer::Result Result;
1066 switch (CCC) {
Douglas Gregor00c37ef2010-08-11 21:23:17 +00001067 case Action::PCC_Class:
1068 case Action::PCC_MemberTemplate:
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001069 if (LangOpts.CPlusPlus) {
Douglas Gregor78a21012010-01-14 16:01:26 +00001070 Results.AddResult(Result("explicit"));
1071 Results.AddResult(Result("friend"));
1072 Results.AddResult(Result("mutable"));
1073 Results.AddResult(Result("virtual"));
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001074 }
1075 // Fall through
1076
Douglas Gregor00c37ef2010-08-11 21:23:17 +00001077 case Action::PCC_ObjCInterface:
1078 case Action::PCC_ObjCImplementation:
1079 case Action::PCC_Namespace:
1080 case Action::PCC_Template:
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001081 if (LangOpts.CPlusPlus || LangOpts.C99)
Douglas Gregor78a21012010-01-14 16:01:26 +00001082 Results.AddResult(Result("inline"));
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001083 break;
1084
Douglas Gregor00c37ef2010-08-11 21:23:17 +00001085 case Action::PCC_ObjCInstanceVariableList:
1086 case Action::PCC_Expression:
1087 case Action::PCC_Statement:
1088 case Action::PCC_ForInit:
1089 case Action::PCC_Condition:
1090 case Action::PCC_RecoveryInFunction:
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001091 break;
1092 }
1093}
1094
Douglas Gregorf98e6a22010-01-13 23:51:12 +00001095static void AddObjCExpressionResults(ResultBuilder &Results, bool NeedAt);
1096static void AddObjCStatementResults(ResultBuilder &Results, bool NeedAt);
1097static void AddObjCVisibilityResults(const LangOptions &LangOpts,
Douglas Gregor48d46252010-01-13 21:54:15 +00001098 ResultBuilder &Results,
1099 bool NeedAt);
Douglas Gregorf98e6a22010-01-13 23:51:12 +00001100static void AddObjCImplementationResults(const LangOptions &LangOpts,
Douglas Gregorf1934162010-01-13 21:24:21 +00001101 ResultBuilder &Results,
1102 bool NeedAt);
Douglas Gregorf98e6a22010-01-13 23:51:12 +00001103static void AddObjCInterfaceResults(const LangOptions &LangOpts,
Douglas Gregorf1934162010-01-13 21:24:21 +00001104 ResultBuilder &Results,
1105 bool NeedAt);
Douglas Gregorf98e6a22010-01-13 23:51:12 +00001106static void AddObjCTopLevelResults(ResultBuilder &Results, bool NeedAt);
Douglas Gregorf1934162010-01-13 21:24:21 +00001107
Douglas Gregorf4c33342010-05-28 00:22:41 +00001108static void AddTypedefResult(ResultBuilder &Results) {
1109 CodeCompletionString *Pattern = new CodeCompletionString;
1110 Pattern->AddTypedTextChunk("typedef");
1111 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
1112 Pattern->AddPlaceholderChunk("type");
1113 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
1114 Pattern->AddPlaceholderChunk("name");
1115 Results.AddResult(CodeCompleteConsumer::Result(Pattern));
1116}
1117
Douglas Gregor00c37ef2010-08-11 21:23:17 +00001118static bool WantTypesInContext(Action::ParserCompletionContext CCC,
Douglas Gregor70febae2010-05-28 00:49:12 +00001119 const LangOptions &LangOpts) {
1120 if (LangOpts.CPlusPlus)
1121 return true;
1122
1123 switch (CCC) {
Douglas Gregor00c37ef2010-08-11 21:23:17 +00001124 case Action::PCC_Namespace:
1125 case Action::PCC_Class:
1126 case Action::PCC_ObjCInstanceVariableList:
1127 case Action::PCC_Template:
1128 case Action::PCC_MemberTemplate:
1129 case Action::PCC_Statement:
1130 case Action::PCC_RecoveryInFunction:
Douglas Gregor70febae2010-05-28 00:49:12 +00001131 return true;
1132
Douglas Gregor00c37ef2010-08-11 21:23:17 +00001133 case Action::PCC_ObjCInterface:
1134 case Action::PCC_ObjCImplementation:
1135 case Action::PCC_Expression:
1136 case Action::PCC_Condition:
Douglas Gregor70febae2010-05-28 00:49:12 +00001137 return false;
1138
Douglas Gregor00c37ef2010-08-11 21:23:17 +00001139 case Action::PCC_ForInit:
Douglas Gregor70febae2010-05-28 00:49:12 +00001140 return LangOpts.ObjC1 || LangOpts.C99;
1141 }
1142
1143 return false;
1144}
1145
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001146/// \brief Add language constructs that show up for "ordinary" names.
Douglas Gregor00c37ef2010-08-11 21:23:17 +00001147static void AddOrdinaryNameResults(Action::ParserCompletionContext CCC,
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001148 Scope *S,
1149 Sema &SemaRef,
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001150 ResultBuilder &Results) {
1151 typedef CodeCompleteConsumer::Result Result;
1152 switch (CCC) {
Douglas Gregor00c37ef2010-08-11 21:23:17 +00001153 case Action::PCC_Namespace:
Douglas Gregorf4c33342010-05-28 00:22:41 +00001154 if (SemaRef.getLangOptions().CPlusPlus) {
1155 CodeCompletionString *Pattern = 0;
1156
1157 if (Results.includeCodePatterns()) {
1158 // namespace <identifier> { declarations }
1159 CodeCompletionString *Pattern = new CodeCompletionString;
1160 Pattern->AddTypedTextChunk("namespace");
1161 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
1162 Pattern->AddPlaceholderChunk("identifier");
1163 Pattern->AddChunk(CodeCompletionString::CK_LeftBrace);
1164 Pattern->AddPlaceholderChunk("declarations");
1165 Pattern->AddChunk(CodeCompletionString::CK_VerticalSpace);
1166 Pattern->AddChunk(CodeCompletionString::CK_RightBrace);
1167 Results.AddResult(Result(Pattern));
1168 }
1169
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001170 // namespace identifier = identifier ;
1171 Pattern = new CodeCompletionString;
1172 Pattern->AddTypedTextChunk("namespace");
1173 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
Douglas Gregorf4c33342010-05-28 00:22:41 +00001174 Pattern->AddPlaceholderChunk("name");
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001175 Pattern->AddChunk(CodeCompletionString::CK_Equal);
Douglas Gregorf4c33342010-05-28 00:22:41 +00001176 Pattern->AddPlaceholderChunk("namespace");
Douglas Gregor78a21012010-01-14 16:01:26 +00001177 Results.AddResult(Result(Pattern));
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001178
1179 // Using directives
1180 Pattern = new CodeCompletionString;
1181 Pattern->AddTypedTextChunk("using");
1182 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
1183 Pattern->AddTextChunk("namespace");
1184 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
1185 Pattern->AddPlaceholderChunk("identifier");
Douglas Gregor78a21012010-01-14 16:01:26 +00001186 Results.AddResult(Result(Pattern));
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001187
1188 // asm(string-literal)
1189 Pattern = new CodeCompletionString;
1190 Pattern->AddTypedTextChunk("asm");
1191 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
1192 Pattern->AddPlaceholderChunk("string-literal");
1193 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
Douglas Gregor78a21012010-01-14 16:01:26 +00001194 Results.AddResult(Result(Pattern));
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001195
Douglas Gregorf4c33342010-05-28 00:22:41 +00001196 if (Results.includeCodePatterns()) {
1197 // Explicit template instantiation
1198 Pattern = new CodeCompletionString;
1199 Pattern->AddTypedTextChunk("template");
1200 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
1201 Pattern->AddPlaceholderChunk("declaration");
1202 Results.AddResult(Result(Pattern));
1203 }
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001204 }
Douglas Gregorf1934162010-01-13 21:24:21 +00001205
1206 if (SemaRef.getLangOptions().ObjC1)
Douglas Gregorf98e6a22010-01-13 23:51:12 +00001207 AddObjCTopLevelResults(Results, true);
Douglas Gregorf1934162010-01-13 21:24:21 +00001208
Douglas Gregorf4c33342010-05-28 00:22:41 +00001209 AddTypedefResult(Results);
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001210 // Fall through
1211
Douglas Gregor00c37ef2010-08-11 21:23:17 +00001212 case Action::PCC_Class:
Douglas Gregorf4c33342010-05-28 00:22:41 +00001213 if (SemaRef.getLangOptions().CPlusPlus) {
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001214 // Using declaration
1215 CodeCompletionString *Pattern = new CodeCompletionString;
1216 Pattern->AddTypedTextChunk("using");
1217 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
Douglas Gregorf4c33342010-05-28 00:22:41 +00001218 Pattern->AddPlaceholderChunk("qualifier");
1219 Pattern->AddTextChunk("::");
1220 Pattern->AddPlaceholderChunk("name");
Douglas Gregor78a21012010-01-14 16:01:26 +00001221 Results.AddResult(Result(Pattern));
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001222
Douglas Gregorf4c33342010-05-28 00:22:41 +00001223 // using typename qualifier::name (only in a dependent context)
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001224 if (SemaRef.CurContext->isDependentContext()) {
1225 Pattern = new CodeCompletionString;
1226 Pattern->AddTypedTextChunk("using");
1227 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
1228 Pattern->AddTextChunk("typename");
1229 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
Douglas Gregorf4c33342010-05-28 00:22:41 +00001230 Pattern->AddPlaceholderChunk("qualifier");
1231 Pattern->AddTextChunk("::");
1232 Pattern->AddPlaceholderChunk("name");
Douglas Gregor78a21012010-01-14 16:01:26 +00001233 Results.AddResult(Result(Pattern));
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001234 }
1235
Douglas Gregor00c37ef2010-08-11 21:23:17 +00001236 if (CCC == Action::PCC_Class) {
Douglas Gregorf4c33342010-05-28 00:22:41 +00001237 AddTypedefResult(Results);
1238
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001239 // public:
1240 Pattern = new CodeCompletionString;
1241 Pattern->AddTypedTextChunk("public");
1242 Pattern->AddChunk(CodeCompletionString::CK_Colon);
Douglas Gregor78a21012010-01-14 16:01:26 +00001243 Results.AddResult(Result(Pattern));
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001244
1245 // protected:
1246 Pattern = new CodeCompletionString;
1247 Pattern->AddTypedTextChunk("protected");
1248 Pattern->AddChunk(CodeCompletionString::CK_Colon);
Douglas Gregor78a21012010-01-14 16:01:26 +00001249 Results.AddResult(Result(Pattern));
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001250
1251 // private:
1252 Pattern = new CodeCompletionString;
1253 Pattern->AddTypedTextChunk("private");
1254 Pattern->AddChunk(CodeCompletionString::CK_Colon);
Douglas Gregor78a21012010-01-14 16:01:26 +00001255 Results.AddResult(Result(Pattern));
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001256 }
1257 }
1258 // Fall through
1259
Douglas Gregor00c37ef2010-08-11 21:23:17 +00001260 case Action::PCC_Template:
1261 case Action::PCC_MemberTemplate:
Douglas Gregorf64acca2010-05-25 21:41:55 +00001262 if (SemaRef.getLangOptions().CPlusPlus && Results.includeCodePatterns()) {
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001263 // template < parameters >
1264 CodeCompletionString *Pattern = new CodeCompletionString;
1265 Pattern->AddTypedTextChunk("template");
1266 Pattern->AddChunk(CodeCompletionString::CK_LeftAngle);
1267 Pattern->AddPlaceholderChunk("parameters");
1268 Pattern->AddChunk(CodeCompletionString::CK_RightAngle);
Douglas Gregor78a21012010-01-14 16:01:26 +00001269 Results.AddResult(Result(Pattern));
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001270 }
1271
Douglas Gregorf98e6a22010-01-13 23:51:12 +00001272 AddStorageSpecifiers(CCC, SemaRef.getLangOptions(), Results);
1273 AddFunctionSpecifiers(CCC, SemaRef.getLangOptions(), Results);
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001274 break;
1275
Douglas Gregor00c37ef2010-08-11 21:23:17 +00001276 case Action::PCC_ObjCInterface:
Douglas Gregorf98e6a22010-01-13 23:51:12 +00001277 AddObjCInterfaceResults(SemaRef.getLangOptions(), Results, true);
1278 AddStorageSpecifiers(CCC, SemaRef.getLangOptions(), Results);
1279 AddFunctionSpecifiers(CCC, SemaRef.getLangOptions(), Results);
Douglas Gregorf1934162010-01-13 21:24:21 +00001280 break;
1281
Douglas Gregor00c37ef2010-08-11 21:23:17 +00001282 case Action::PCC_ObjCImplementation:
Douglas Gregorf98e6a22010-01-13 23:51:12 +00001283 AddObjCImplementationResults(SemaRef.getLangOptions(), Results, true);
1284 AddStorageSpecifiers(CCC, SemaRef.getLangOptions(), Results);
1285 AddFunctionSpecifiers(CCC, SemaRef.getLangOptions(), Results);
Douglas Gregorf1934162010-01-13 21:24:21 +00001286 break;
1287
Douglas Gregor00c37ef2010-08-11 21:23:17 +00001288 case Action::PCC_ObjCInstanceVariableList:
Douglas Gregorf98e6a22010-01-13 23:51:12 +00001289 AddObjCVisibilityResults(SemaRef.getLangOptions(), Results, true);
Douglas Gregor48d46252010-01-13 21:54:15 +00001290 break;
1291
Douglas Gregor00c37ef2010-08-11 21:23:17 +00001292 case Action::PCC_RecoveryInFunction:
1293 case Action::PCC_Statement: {
Douglas Gregorf4c33342010-05-28 00:22:41 +00001294 AddTypedefResult(Results);
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001295
1296 CodeCompletionString *Pattern = 0;
Douglas Gregorf64acca2010-05-25 21:41:55 +00001297 if (SemaRef.getLangOptions().CPlusPlus && Results.includeCodePatterns()) {
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001298 Pattern = new CodeCompletionString;
1299 Pattern->AddTypedTextChunk("try");
1300 Pattern->AddChunk(CodeCompletionString::CK_LeftBrace);
1301 Pattern->AddPlaceholderChunk("statements");
1302 Pattern->AddChunk(CodeCompletionString::CK_VerticalSpace);
1303 Pattern->AddChunk(CodeCompletionString::CK_RightBrace);
1304 Pattern->AddTextChunk("catch");
1305 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
1306 Pattern->AddPlaceholderChunk("declaration");
1307 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
1308 Pattern->AddChunk(CodeCompletionString::CK_LeftBrace);
1309 Pattern->AddPlaceholderChunk("statements");
1310 Pattern->AddChunk(CodeCompletionString::CK_VerticalSpace);
1311 Pattern->AddChunk(CodeCompletionString::CK_RightBrace);
Douglas Gregor78a21012010-01-14 16:01:26 +00001312 Results.AddResult(Result(Pattern));
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001313 }
Douglas Gregorf1934162010-01-13 21:24:21 +00001314 if (SemaRef.getLangOptions().ObjC1)
Douglas Gregorf98e6a22010-01-13 23:51:12 +00001315 AddObjCStatementResults(Results, true);
Douglas Gregorf1934162010-01-13 21:24:21 +00001316
Douglas Gregorf64acca2010-05-25 21:41:55 +00001317 if (Results.includeCodePatterns()) {
1318 // if (condition) { statements }
1319 Pattern = new CodeCompletionString;
1320 Pattern->AddTypedTextChunk("if");
1321 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
1322 if (SemaRef.getLangOptions().CPlusPlus)
1323 Pattern->AddPlaceholderChunk("condition");
1324 else
1325 Pattern->AddPlaceholderChunk("expression");
1326 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
1327 Pattern->AddChunk(CodeCompletionString::CK_LeftBrace);
1328 Pattern->AddPlaceholderChunk("statements");
1329 Pattern->AddChunk(CodeCompletionString::CK_VerticalSpace);
1330 Pattern->AddChunk(CodeCompletionString::CK_RightBrace);
1331 Results.AddResult(Result(Pattern));
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001332
Douglas Gregorf64acca2010-05-25 21:41:55 +00001333 // switch (condition) { }
1334 Pattern = new CodeCompletionString;
1335 Pattern->AddTypedTextChunk("switch");
1336 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
1337 if (SemaRef.getLangOptions().CPlusPlus)
1338 Pattern->AddPlaceholderChunk("condition");
1339 else
1340 Pattern->AddPlaceholderChunk("expression");
1341 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
1342 Pattern->AddChunk(CodeCompletionString::CK_LeftBrace);
1343 Pattern->AddChunk(CodeCompletionString::CK_VerticalSpace);
1344 Pattern->AddChunk(CodeCompletionString::CK_RightBrace);
1345 Results.AddResult(Result(Pattern));
1346 }
1347
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001348 // Switch-specific statements.
Douglas Gregorf4c33342010-05-28 00:22:41 +00001349 if (!SemaRef.getSwitchStack().empty()) {
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001350 // case expression:
1351 Pattern = new CodeCompletionString;
1352 Pattern->AddTypedTextChunk("case");
Douglas Gregorf4c33342010-05-28 00:22:41 +00001353 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001354 Pattern->AddPlaceholderChunk("expression");
1355 Pattern->AddChunk(CodeCompletionString::CK_Colon);
Douglas Gregor78a21012010-01-14 16:01:26 +00001356 Results.AddResult(Result(Pattern));
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001357
1358 // default:
1359 Pattern = new CodeCompletionString;
1360 Pattern->AddTypedTextChunk("default");
1361 Pattern->AddChunk(CodeCompletionString::CK_Colon);
Douglas Gregor78a21012010-01-14 16:01:26 +00001362 Results.AddResult(Result(Pattern));
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001363 }
1364
Douglas Gregorf64acca2010-05-25 21:41:55 +00001365 if (Results.includeCodePatterns()) {
1366 /// while (condition) { statements }
1367 Pattern = new CodeCompletionString;
1368 Pattern->AddTypedTextChunk("while");
1369 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
1370 if (SemaRef.getLangOptions().CPlusPlus)
1371 Pattern->AddPlaceholderChunk("condition");
1372 else
1373 Pattern->AddPlaceholderChunk("expression");
1374 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
1375 Pattern->AddChunk(CodeCompletionString::CK_LeftBrace);
1376 Pattern->AddPlaceholderChunk("statements");
1377 Pattern->AddChunk(CodeCompletionString::CK_VerticalSpace);
1378 Pattern->AddChunk(CodeCompletionString::CK_RightBrace);
1379 Results.AddResult(Result(Pattern));
1380
1381 // do { statements } while ( expression );
1382 Pattern = new CodeCompletionString;
1383 Pattern->AddTypedTextChunk("do");
1384 Pattern->AddChunk(CodeCompletionString::CK_LeftBrace);
1385 Pattern->AddPlaceholderChunk("statements");
1386 Pattern->AddChunk(CodeCompletionString::CK_VerticalSpace);
1387 Pattern->AddChunk(CodeCompletionString::CK_RightBrace);
1388 Pattern->AddTextChunk("while");
1389 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001390 Pattern->AddPlaceholderChunk("expression");
Douglas Gregorf64acca2010-05-25 21:41:55 +00001391 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
1392 Results.AddResult(Result(Pattern));
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001393
Douglas Gregorf64acca2010-05-25 21:41:55 +00001394 // for ( for-init-statement ; condition ; expression ) { statements }
1395 Pattern = new CodeCompletionString;
1396 Pattern->AddTypedTextChunk("for");
1397 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
1398 if (SemaRef.getLangOptions().CPlusPlus || SemaRef.getLangOptions().C99)
1399 Pattern->AddPlaceholderChunk("init-statement");
1400 else
1401 Pattern->AddPlaceholderChunk("init-expression");
1402 Pattern->AddChunk(CodeCompletionString::CK_SemiColon);
1403 Pattern->AddPlaceholderChunk("condition");
1404 Pattern->AddChunk(CodeCompletionString::CK_SemiColon);
1405 Pattern->AddPlaceholderChunk("inc-expression");
1406 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
1407 Pattern->AddChunk(CodeCompletionString::CK_LeftBrace);
1408 Pattern->AddPlaceholderChunk("statements");
1409 Pattern->AddChunk(CodeCompletionString::CK_VerticalSpace);
1410 Pattern->AddChunk(CodeCompletionString::CK_RightBrace);
1411 Results.AddResult(Result(Pattern));
1412 }
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001413
1414 if (S->getContinueParent()) {
1415 // continue ;
1416 Pattern = new CodeCompletionString;
1417 Pattern->AddTypedTextChunk("continue");
Douglas Gregor78a21012010-01-14 16:01:26 +00001418 Results.AddResult(Result(Pattern));
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001419 }
1420
1421 if (S->getBreakParent()) {
1422 // break ;
1423 Pattern = new CodeCompletionString;
1424 Pattern->AddTypedTextChunk("break");
Douglas Gregor78a21012010-01-14 16:01:26 +00001425 Results.AddResult(Result(Pattern));
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001426 }
1427
1428 // "return expression ;" or "return ;", depending on whether we
1429 // know the function is void or not.
1430 bool isVoid = false;
1431 if (FunctionDecl *Function = dyn_cast<FunctionDecl>(SemaRef.CurContext))
1432 isVoid = Function->getResultType()->isVoidType();
1433 else if (ObjCMethodDecl *Method
1434 = dyn_cast<ObjCMethodDecl>(SemaRef.CurContext))
1435 isVoid = Method->getResultType()->isVoidType();
Douglas Gregor9a28e842010-03-01 23:15:13 +00001436 else if (SemaRef.getCurBlock() &&
1437 !SemaRef.getCurBlock()->ReturnType.isNull())
1438 isVoid = SemaRef.getCurBlock()->ReturnType->isVoidType();
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001439 Pattern = new CodeCompletionString;
1440 Pattern->AddTypedTextChunk("return");
Douglas Gregor44272ca2010-02-18 04:06:48 +00001441 if (!isVoid) {
1442 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001443 Pattern->AddPlaceholderChunk("expression");
Douglas Gregor44272ca2010-02-18 04:06:48 +00001444 }
Douglas Gregor78a21012010-01-14 16:01:26 +00001445 Results.AddResult(Result(Pattern));
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001446
Douglas Gregorf4c33342010-05-28 00:22:41 +00001447 // goto identifier ;
1448 Pattern = new CodeCompletionString;
1449 Pattern->AddTypedTextChunk("goto");
1450 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
1451 Pattern->AddPlaceholderChunk("label");
1452 Results.AddResult(Result(Pattern));
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001453
Douglas Gregorf4c33342010-05-28 00:22:41 +00001454 // Using directives
1455 Pattern = new CodeCompletionString;
1456 Pattern->AddTypedTextChunk("using");
1457 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
1458 Pattern->AddTextChunk("namespace");
1459 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
1460 Pattern->AddPlaceholderChunk("identifier");
1461 Results.AddResult(Result(Pattern));
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001462 }
1463
1464 // Fall through (for statement expressions).
Douglas Gregor00c37ef2010-08-11 21:23:17 +00001465 case Action::PCC_ForInit:
1466 case Action::PCC_Condition:
Douglas Gregorf98e6a22010-01-13 23:51:12 +00001467 AddStorageSpecifiers(CCC, SemaRef.getLangOptions(), Results);
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001468 // Fall through: conditions and statements can have expressions.
1469
Douglas Gregor00c37ef2010-08-11 21:23:17 +00001470 case Action::PCC_Expression: {
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001471 CodeCompletionString *Pattern = 0;
1472 if (SemaRef.getLangOptions().CPlusPlus) {
1473 // 'this', if we're in a non-static member function.
1474 if (CXXMethodDecl *Method = dyn_cast<CXXMethodDecl>(SemaRef.CurContext))
1475 if (!Method->isStatic())
Douglas Gregor78a21012010-01-14 16:01:26 +00001476 Results.AddResult(Result("this"));
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001477
1478 // true, false
Douglas Gregor78a21012010-01-14 16:01:26 +00001479 Results.AddResult(Result("true"));
1480 Results.AddResult(Result("false"));
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001481
Douglas Gregorf4c33342010-05-28 00:22:41 +00001482 // dynamic_cast < type-id > ( expression )
1483 Pattern = new CodeCompletionString;
1484 Pattern->AddTypedTextChunk("dynamic_cast");
1485 Pattern->AddChunk(CodeCompletionString::CK_LeftAngle);
1486 Pattern->AddPlaceholderChunk("type");
1487 Pattern->AddChunk(CodeCompletionString::CK_RightAngle);
1488 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
1489 Pattern->AddPlaceholderChunk("expression");
1490 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
1491 Results.AddResult(Result(Pattern));
1492
1493 // static_cast < type-id > ( expression )
1494 Pattern = new CodeCompletionString;
1495 Pattern->AddTypedTextChunk("static_cast");
1496 Pattern->AddChunk(CodeCompletionString::CK_LeftAngle);
1497 Pattern->AddPlaceholderChunk("type");
1498 Pattern->AddChunk(CodeCompletionString::CK_RightAngle);
1499 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
1500 Pattern->AddPlaceholderChunk("expression");
1501 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
1502 Results.AddResult(Result(Pattern));
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001503
Douglas Gregorf4c33342010-05-28 00:22:41 +00001504 // reinterpret_cast < type-id > ( expression )
1505 Pattern = new CodeCompletionString;
1506 Pattern->AddTypedTextChunk("reinterpret_cast");
1507 Pattern->AddChunk(CodeCompletionString::CK_LeftAngle);
1508 Pattern->AddPlaceholderChunk("type");
1509 Pattern->AddChunk(CodeCompletionString::CK_RightAngle);
1510 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
1511 Pattern->AddPlaceholderChunk("expression");
1512 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
1513 Results.AddResult(Result(Pattern));
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001514
Douglas Gregorf4c33342010-05-28 00:22:41 +00001515 // const_cast < type-id > ( expression )
1516 Pattern = new CodeCompletionString;
1517 Pattern->AddTypedTextChunk("const_cast");
1518 Pattern->AddChunk(CodeCompletionString::CK_LeftAngle);
1519 Pattern->AddPlaceholderChunk("type");
1520 Pattern->AddChunk(CodeCompletionString::CK_RightAngle);
1521 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
1522 Pattern->AddPlaceholderChunk("expression");
1523 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
1524 Results.AddResult(Result(Pattern));
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001525
Douglas Gregorf4c33342010-05-28 00:22:41 +00001526 // typeid ( expression-or-type )
1527 Pattern = new CodeCompletionString;
1528 Pattern->AddTypedTextChunk("typeid");
1529 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
1530 Pattern->AddPlaceholderChunk("expression-or-type");
1531 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
1532 Results.AddResult(Result(Pattern));
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001533
Douglas Gregorf4c33342010-05-28 00:22:41 +00001534 // new T ( ... )
1535 Pattern = new CodeCompletionString;
1536 Pattern->AddTypedTextChunk("new");
1537 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
1538 Pattern->AddPlaceholderChunk("type");
1539 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
1540 Pattern->AddPlaceholderChunk("expressions");
1541 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
1542 Results.AddResult(Result(Pattern));
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001543
Douglas Gregorf4c33342010-05-28 00:22:41 +00001544 // new T [ ] ( ... )
1545 Pattern = new CodeCompletionString;
1546 Pattern->AddTypedTextChunk("new");
1547 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
1548 Pattern->AddPlaceholderChunk("type");
1549 Pattern->AddChunk(CodeCompletionString::CK_LeftBracket);
1550 Pattern->AddPlaceholderChunk("size");
1551 Pattern->AddChunk(CodeCompletionString::CK_RightBracket);
1552 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
1553 Pattern->AddPlaceholderChunk("expressions");
1554 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
1555 Results.AddResult(Result(Pattern));
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001556
Douglas Gregorf4c33342010-05-28 00:22:41 +00001557 // delete expression
1558 Pattern = new CodeCompletionString;
1559 Pattern->AddTypedTextChunk("delete");
1560 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
1561 Pattern->AddPlaceholderChunk("expression");
1562 Results.AddResult(Result(Pattern));
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001563
Douglas Gregorf4c33342010-05-28 00:22:41 +00001564 // delete [] expression
1565 Pattern = new CodeCompletionString;
1566 Pattern->AddTypedTextChunk("delete");
1567 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
1568 Pattern->AddChunk(CodeCompletionString::CK_LeftBracket);
1569 Pattern->AddChunk(CodeCompletionString::CK_RightBracket);
1570 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
1571 Pattern->AddPlaceholderChunk("expression");
1572 Results.AddResult(Result(Pattern));
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001573
Douglas Gregorf4c33342010-05-28 00:22:41 +00001574 // throw expression
1575 Pattern = new CodeCompletionString;
1576 Pattern->AddTypedTextChunk("throw");
1577 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
1578 Pattern->AddPlaceholderChunk("expression");
1579 Results.AddResult(Result(Pattern));
Douglas Gregora2db7932010-05-26 22:00:08 +00001580
1581 // FIXME: Rethrow?
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001582 }
1583
1584 if (SemaRef.getLangOptions().ObjC1) {
1585 // Add "super", if we're in an Objective-C class with a superclass.
Ted Kremenek305a0a72010-05-31 21:43:10 +00001586 if (ObjCMethodDecl *Method = SemaRef.getCurMethodDecl()) {
1587 // The interface can be NULL.
1588 if (ObjCInterfaceDecl *ID = Method->getClassInterface())
1589 if (ID->getSuperClass())
1590 Results.AddResult(Result("super"));
1591 }
1592
Douglas Gregorf98e6a22010-01-13 23:51:12 +00001593 AddObjCExpressionResults(Results, true);
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001594 }
1595
Douglas Gregorf4c33342010-05-28 00:22:41 +00001596 // sizeof expression
1597 Pattern = new CodeCompletionString;
1598 Pattern->AddTypedTextChunk("sizeof");
1599 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
1600 Pattern->AddPlaceholderChunk("expression-or-type");
1601 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
1602 Results.AddResult(Result(Pattern));
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001603 break;
1604 }
1605 }
1606
Douglas Gregor70febae2010-05-28 00:49:12 +00001607 if (WantTypesInContext(CCC, SemaRef.getLangOptions()))
1608 AddTypeSpecifierResults(SemaRef.getLangOptions(), Results);
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001609
1610 if (SemaRef.getLangOptions().CPlusPlus)
Douglas Gregor78a21012010-01-14 16:01:26 +00001611 Results.AddResult(Result("operator"));
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001612}
1613
Douglas Gregorb3fa9192009-12-18 18:53:37 +00001614/// \brief If the given declaration has an associated type, add it as a result
1615/// type chunk.
1616static void AddResultTypeChunk(ASTContext &Context,
1617 NamedDecl *ND,
1618 CodeCompletionString *Result) {
1619 if (!ND)
1620 return;
1621
1622 // Determine the type of the declaration (if it has a type).
1623 QualType T;
1624 if (FunctionDecl *Function = dyn_cast<FunctionDecl>(ND))
1625 T = Function->getResultType();
1626 else if (ObjCMethodDecl *Method = dyn_cast<ObjCMethodDecl>(ND))
1627 T = Method->getResultType();
1628 else if (FunctionTemplateDecl *FunTmpl = dyn_cast<FunctionTemplateDecl>(ND))
1629 T = FunTmpl->getTemplatedDecl()->getResultType();
1630 else if (EnumConstantDecl *Enumerator = dyn_cast<EnumConstantDecl>(ND))
1631 T = Context.getTypeDeclType(cast<TypeDecl>(Enumerator->getDeclContext()));
1632 else if (isa<UnresolvedUsingValueDecl>(ND)) {
1633 /* Do nothing: ignore unresolved using declarations*/
1634 } else if (ValueDecl *Value = dyn_cast<ValueDecl>(ND))
1635 T = Value->getType();
1636 else if (ObjCPropertyDecl *Property = dyn_cast<ObjCPropertyDecl>(ND))
1637 T = Property->getType();
1638
1639 if (T.isNull() || Context.hasSameType(T, Context.DependentTy))
1640 return;
1641
Douglas Gregorcf04b022010-04-05 21:25:31 +00001642 PrintingPolicy Policy(Context.PrintingPolicy);
1643 Policy.AnonymousTagLocations = false;
1644
Douglas Gregorb3fa9192009-12-18 18:53:37 +00001645 std::string TypeStr;
Douglas Gregorcf04b022010-04-05 21:25:31 +00001646 T.getAsStringInternal(TypeStr, Policy);
Douglas Gregorb3fa9192009-12-18 18:53:37 +00001647 Result->AddResultTypeChunk(TypeStr);
1648}
1649
Douglas Gregor3545ff42009-09-21 16:56:56 +00001650/// \brief Add function parameter chunks to the given code completion string.
1651static void AddFunctionParameterChunks(ASTContext &Context,
1652 FunctionDecl *Function,
1653 CodeCompletionString *Result) {
Douglas Gregor9eb77012009-11-07 00:00:49 +00001654 typedef CodeCompletionString::Chunk Chunk;
1655
Douglas Gregor3545ff42009-09-21 16:56:56 +00001656 CodeCompletionString *CCStr = Result;
1657
1658 for (unsigned P = 0, N = Function->getNumParams(); P != N; ++P) {
1659 ParmVarDecl *Param = Function->getParamDecl(P);
1660
1661 if (Param->hasDefaultArg()) {
1662 // When we see an optional default argument, put that argument and
1663 // the remaining default arguments into a new, optional string.
1664 CodeCompletionString *Opt = new CodeCompletionString;
1665 CCStr->AddOptionalChunk(std::auto_ptr<CodeCompletionString>(Opt));
1666 CCStr = Opt;
1667 }
1668
1669 if (P != 0)
Douglas Gregor9eb77012009-11-07 00:00:49 +00001670 CCStr->AddChunk(Chunk(CodeCompletionString::CK_Comma));
Douglas Gregor3545ff42009-09-21 16:56:56 +00001671
1672 // Format the placeholder string.
1673 std::string PlaceholderStr;
1674 if (Param->getIdentifier())
1675 PlaceholderStr = Param->getIdentifier()->getName();
1676
1677 Param->getType().getAsStringInternal(PlaceholderStr,
1678 Context.PrintingPolicy);
1679
1680 // Add the placeholder string.
Benjamin Kramerb33a97c2009-11-29 20:18:50 +00001681 CCStr->AddPlaceholderChunk(PlaceholderStr);
Douglas Gregor3545ff42009-09-21 16:56:56 +00001682 }
Douglas Gregorba449032009-09-22 21:42:17 +00001683
1684 if (const FunctionProtoType *Proto
1685 = Function->getType()->getAs<FunctionProtoType>())
1686 if (Proto->isVariadic())
1687 CCStr->AddPlaceholderChunk(", ...");
Douglas Gregor3545ff42009-09-21 16:56:56 +00001688}
1689
1690/// \brief Add template parameter chunks to the given code completion string.
1691static void AddTemplateParameterChunks(ASTContext &Context,
1692 TemplateDecl *Template,
1693 CodeCompletionString *Result,
1694 unsigned MaxParameters = 0) {
Douglas Gregor9eb77012009-11-07 00:00:49 +00001695 typedef CodeCompletionString::Chunk Chunk;
1696
Douglas Gregor3545ff42009-09-21 16:56:56 +00001697 CodeCompletionString *CCStr = Result;
1698 bool FirstParameter = true;
1699
1700 TemplateParameterList *Params = Template->getTemplateParameters();
1701 TemplateParameterList::iterator PEnd = Params->end();
1702 if (MaxParameters)
1703 PEnd = Params->begin() + MaxParameters;
1704 for (TemplateParameterList::iterator P = Params->begin(); P != PEnd; ++P) {
1705 bool HasDefaultArg = false;
1706 std::string PlaceholderStr;
1707 if (TemplateTypeParmDecl *TTP = dyn_cast<TemplateTypeParmDecl>(*P)) {
1708 if (TTP->wasDeclaredWithTypename())
1709 PlaceholderStr = "typename";
1710 else
1711 PlaceholderStr = "class";
1712
1713 if (TTP->getIdentifier()) {
1714 PlaceholderStr += ' ';
1715 PlaceholderStr += TTP->getIdentifier()->getName();
1716 }
1717
1718 HasDefaultArg = TTP->hasDefaultArgument();
1719 } else if (NonTypeTemplateParmDecl *NTTP
1720 = dyn_cast<NonTypeTemplateParmDecl>(*P)) {
1721 if (NTTP->getIdentifier())
1722 PlaceholderStr = NTTP->getIdentifier()->getName();
1723 NTTP->getType().getAsStringInternal(PlaceholderStr,
1724 Context.PrintingPolicy);
1725 HasDefaultArg = NTTP->hasDefaultArgument();
1726 } else {
1727 assert(isa<TemplateTemplateParmDecl>(*P));
1728 TemplateTemplateParmDecl *TTP = cast<TemplateTemplateParmDecl>(*P);
1729
1730 // Since putting the template argument list into the placeholder would
1731 // be very, very long, we just use an abbreviation.
1732 PlaceholderStr = "template<...> class";
1733 if (TTP->getIdentifier()) {
1734 PlaceholderStr += ' ';
1735 PlaceholderStr += TTP->getIdentifier()->getName();
1736 }
1737
1738 HasDefaultArg = TTP->hasDefaultArgument();
1739 }
1740
1741 if (HasDefaultArg) {
1742 // When we see an optional default argument, put that argument and
1743 // the remaining default arguments into a new, optional string.
1744 CodeCompletionString *Opt = new CodeCompletionString;
1745 CCStr->AddOptionalChunk(std::auto_ptr<CodeCompletionString>(Opt));
1746 CCStr = Opt;
1747 }
1748
1749 if (FirstParameter)
1750 FirstParameter = false;
1751 else
Douglas Gregor9eb77012009-11-07 00:00:49 +00001752 CCStr->AddChunk(Chunk(CodeCompletionString::CK_Comma));
Douglas Gregor3545ff42009-09-21 16:56:56 +00001753
1754 // Add the placeholder string.
Benjamin Kramerb33a97c2009-11-29 20:18:50 +00001755 CCStr->AddPlaceholderChunk(PlaceholderStr);
Douglas Gregor3545ff42009-09-21 16:56:56 +00001756 }
1757}
1758
Douglas Gregorf2510672009-09-21 19:57:38 +00001759/// \brief Add a qualifier to the given code-completion string, if the
1760/// provided nested-name-specifier is non-NULL.
Douglas Gregor0f622362009-12-11 18:44:16 +00001761static void
1762AddQualifierToCompletionString(CodeCompletionString *Result,
1763 NestedNameSpecifier *Qualifier,
1764 bool QualifierIsInformative,
1765 ASTContext &Context) {
Douglas Gregorf2510672009-09-21 19:57:38 +00001766 if (!Qualifier)
1767 return;
1768
1769 std::string PrintedNNS;
1770 {
1771 llvm::raw_string_ostream OS(PrintedNNS);
1772 Qualifier->print(OS, Context.PrintingPolicy);
1773 }
Douglas Gregor5bf52692009-09-22 23:15:58 +00001774 if (QualifierIsInformative)
Benjamin Kramerb33a97c2009-11-29 20:18:50 +00001775 Result->AddInformativeChunk(PrintedNNS);
Douglas Gregor5bf52692009-09-22 23:15:58 +00001776 else
Benjamin Kramerb33a97c2009-11-29 20:18:50 +00001777 Result->AddTextChunk(PrintedNNS);
Douglas Gregorf2510672009-09-21 19:57:38 +00001778}
1779
Douglas Gregor0f622362009-12-11 18:44:16 +00001780static void AddFunctionTypeQualsToCompletionString(CodeCompletionString *Result,
1781 FunctionDecl *Function) {
1782 const FunctionProtoType *Proto
1783 = Function->getType()->getAs<FunctionProtoType>();
1784 if (!Proto || !Proto->getTypeQuals())
1785 return;
1786
1787 std::string QualsStr;
1788 if (Proto->getTypeQuals() & Qualifiers::Const)
1789 QualsStr += " const";
1790 if (Proto->getTypeQuals() & Qualifiers::Volatile)
1791 QualsStr += " volatile";
1792 if (Proto->getTypeQuals() & Qualifiers::Restrict)
1793 QualsStr += " restrict";
1794 Result->AddInformativeChunk(QualsStr);
1795}
1796
Douglas Gregor3545ff42009-09-21 16:56:56 +00001797/// \brief If possible, create a new code completion string for the given
1798/// result.
1799///
1800/// \returns Either a new, heap-allocated code completion string describing
1801/// how to use this result, or NULL to indicate that the string or name of the
1802/// result is all that is needed.
1803CodeCompletionString *
Douglas Gregor8e984da2010-08-04 16:47:14 +00001804CodeCompleteConsumer::Result::CreateCodeCompletionString(Sema &S,
1805 CodeCompletionString *Result) {
Douglas Gregor9eb77012009-11-07 00:00:49 +00001806 typedef CodeCompletionString::Chunk Chunk;
1807
Douglas Gregorf09935f2009-12-01 05:55:20 +00001808 if (Kind == RK_Pattern)
Douglas Gregor8e984da2010-08-04 16:47:14 +00001809 return Pattern->Clone(Result);
Douglas Gregorf09935f2009-12-01 05:55:20 +00001810
Douglas Gregor8e984da2010-08-04 16:47:14 +00001811 if (!Result)
1812 Result = new CodeCompletionString;
Douglas Gregorf09935f2009-12-01 05:55:20 +00001813
1814 if (Kind == RK_Keyword) {
1815 Result->AddTypedTextChunk(Keyword);
1816 return Result;
1817 }
Douglas Gregor3545ff42009-09-21 16:56:56 +00001818
Douglas Gregorf329c7c2009-10-30 16:50:04 +00001819 if (Kind == RK_Macro) {
1820 MacroInfo *MI = S.PP.getMacroInfo(Macro);
Douglas Gregorf09935f2009-12-01 05:55:20 +00001821 assert(MI && "Not a macro?");
1822
1823 Result->AddTypedTextChunk(Macro->getName());
1824
1825 if (!MI->isFunctionLike())
1826 return Result;
Douglas Gregorf329c7c2009-10-30 16:50:04 +00001827
1828 // Format a function-like macro with placeholders for the arguments.
Douglas Gregor9eb77012009-11-07 00:00:49 +00001829 Result->AddChunk(Chunk(CodeCompletionString::CK_LeftParen));
Douglas Gregorf329c7c2009-10-30 16:50:04 +00001830 for (MacroInfo::arg_iterator A = MI->arg_begin(), AEnd = MI->arg_end();
1831 A != AEnd; ++A) {
1832 if (A != MI->arg_begin())
Douglas Gregor9eb77012009-11-07 00:00:49 +00001833 Result->AddChunk(Chunk(CodeCompletionString::CK_Comma));
Douglas Gregorf329c7c2009-10-30 16:50:04 +00001834
1835 if (!MI->isVariadic() || A != AEnd - 1) {
1836 // Non-variadic argument.
Benjamin Kramerb33a97c2009-11-29 20:18:50 +00001837 Result->AddPlaceholderChunk((*A)->getName());
Douglas Gregorf329c7c2009-10-30 16:50:04 +00001838 continue;
1839 }
1840
1841 // Variadic argument; cope with the different between GNU and C99
1842 // variadic macros, providing a single placeholder for the rest of the
1843 // arguments.
1844 if ((*A)->isStr("__VA_ARGS__"))
1845 Result->AddPlaceholderChunk("...");
1846 else {
1847 std::string Arg = (*A)->getName();
1848 Arg += "...";
Benjamin Kramerb33a97c2009-11-29 20:18:50 +00001849 Result->AddPlaceholderChunk(Arg);
Douglas Gregorf329c7c2009-10-30 16:50:04 +00001850 }
1851 }
Douglas Gregor9eb77012009-11-07 00:00:49 +00001852 Result->AddChunk(Chunk(CodeCompletionString::CK_RightParen));
Douglas Gregorf329c7c2009-10-30 16:50:04 +00001853 return Result;
1854 }
1855
Douglas Gregorf64acca2010-05-25 21:41:55 +00001856 assert(Kind == RK_Declaration && "Missed a result kind?");
Douglas Gregor3545ff42009-09-21 16:56:56 +00001857 NamedDecl *ND = Declaration;
1858
Douglas Gregor9eb77012009-11-07 00:00:49 +00001859 if (StartsNestedNameSpecifier) {
Benjamin Kramerb33a97c2009-11-29 20:18:50 +00001860 Result->AddTypedTextChunk(ND->getNameAsString());
Douglas Gregor9eb77012009-11-07 00:00:49 +00001861 Result->AddTextChunk("::");
1862 return Result;
1863 }
1864
Douglas Gregorb3fa9192009-12-18 18:53:37 +00001865 AddResultTypeChunk(S.Context, ND, Result);
1866
Douglas Gregor3545ff42009-09-21 16:56:56 +00001867 if (FunctionDecl *Function = dyn_cast<FunctionDecl>(ND)) {
Douglas Gregor5bf52692009-09-22 23:15:58 +00001868 AddQualifierToCompletionString(Result, Qualifier, QualifierIsInformative,
1869 S.Context);
Benjamin Kramerb33a97c2009-11-29 20:18:50 +00001870 Result->AddTypedTextChunk(Function->getNameAsString());
Douglas Gregor9eb77012009-11-07 00:00:49 +00001871 Result->AddChunk(Chunk(CodeCompletionString::CK_LeftParen));
Douglas Gregor3545ff42009-09-21 16:56:56 +00001872 AddFunctionParameterChunks(S.Context, Function, Result);
Douglas Gregor9eb77012009-11-07 00:00:49 +00001873 Result->AddChunk(Chunk(CodeCompletionString::CK_RightParen));
Douglas Gregor0f622362009-12-11 18:44:16 +00001874 AddFunctionTypeQualsToCompletionString(Result, Function);
Douglas Gregor3545ff42009-09-21 16:56:56 +00001875 return Result;
1876 }
1877
1878 if (FunctionTemplateDecl *FunTmpl = dyn_cast<FunctionTemplateDecl>(ND)) {
Douglas Gregor5bf52692009-09-22 23:15:58 +00001879 AddQualifierToCompletionString(Result, Qualifier, QualifierIsInformative,
1880 S.Context);
Douglas Gregor3545ff42009-09-21 16:56:56 +00001881 FunctionDecl *Function = FunTmpl->getTemplatedDecl();
Benjamin Kramerb33a97c2009-11-29 20:18:50 +00001882 Result->AddTypedTextChunk(Function->getNameAsString());
Douglas Gregor3545ff42009-09-21 16:56:56 +00001883
1884 // Figure out which template parameters are deduced (or have default
1885 // arguments).
1886 llvm::SmallVector<bool, 16> Deduced;
1887 S.MarkDeducedTemplateParameters(FunTmpl, Deduced);
1888 unsigned LastDeducibleArgument;
1889 for (LastDeducibleArgument = Deduced.size(); LastDeducibleArgument > 0;
1890 --LastDeducibleArgument) {
1891 if (!Deduced[LastDeducibleArgument - 1]) {
1892 // C++0x: Figure out if the template argument has a default. If so,
1893 // the user doesn't need to type this argument.
1894 // FIXME: We need to abstract template parameters better!
1895 bool HasDefaultArg = false;
1896 NamedDecl *Param = FunTmpl->getTemplateParameters()->getParam(
1897 LastDeducibleArgument - 1);
1898 if (TemplateTypeParmDecl *TTP = dyn_cast<TemplateTypeParmDecl>(Param))
1899 HasDefaultArg = TTP->hasDefaultArgument();
1900 else if (NonTypeTemplateParmDecl *NTTP
1901 = dyn_cast<NonTypeTemplateParmDecl>(Param))
1902 HasDefaultArg = NTTP->hasDefaultArgument();
1903 else {
1904 assert(isa<TemplateTemplateParmDecl>(Param));
1905 HasDefaultArg
Douglas Gregor9eb77012009-11-07 00:00:49 +00001906 = cast<TemplateTemplateParmDecl>(Param)->hasDefaultArgument();
Douglas Gregor3545ff42009-09-21 16:56:56 +00001907 }
1908
1909 if (!HasDefaultArg)
1910 break;
1911 }
1912 }
1913
1914 if (LastDeducibleArgument) {
1915 // Some of the function template arguments cannot be deduced from a
1916 // function call, so we introduce an explicit template argument list
1917 // containing all of the arguments up to the first deducible argument.
Douglas Gregor9eb77012009-11-07 00:00:49 +00001918 Result->AddChunk(Chunk(CodeCompletionString::CK_LeftAngle));
Douglas Gregor3545ff42009-09-21 16:56:56 +00001919 AddTemplateParameterChunks(S.Context, FunTmpl, Result,
1920 LastDeducibleArgument);
Douglas Gregor9eb77012009-11-07 00:00:49 +00001921 Result->AddChunk(Chunk(CodeCompletionString::CK_RightAngle));
Douglas Gregor3545ff42009-09-21 16:56:56 +00001922 }
1923
1924 // Add the function parameters
Douglas Gregor9eb77012009-11-07 00:00:49 +00001925 Result->AddChunk(Chunk(CodeCompletionString::CK_LeftParen));
Douglas Gregor3545ff42009-09-21 16:56:56 +00001926 AddFunctionParameterChunks(S.Context, Function, Result);
Douglas Gregor9eb77012009-11-07 00:00:49 +00001927 Result->AddChunk(Chunk(CodeCompletionString::CK_RightParen));
Douglas Gregor0f622362009-12-11 18:44:16 +00001928 AddFunctionTypeQualsToCompletionString(Result, Function);
Douglas Gregor3545ff42009-09-21 16:56:56 +00001929 return Result;
1930 }
1931
1932 if (TemplateDecl *Template = dyn_cast<TemplateDecl>(ND)) {
Douglas Gregor5bf52692009-09-22 23:15:58 +00001933 AddQualifierToCompletionString(Result, Qualifier, QualifierIsInformative,
1934 S.Context);
Benjamin Kramerb33a97c2009-11-29 20:18:50 +00001935 Result->AddTypedTextChunk(Template->getNameAsString());
Douglas Gregor9eb77012009-11-07 00:00:49 +00001936 Result->AddChunk(Chunk(CodeCompletionString::CK_LeftAngle));
Douglas Gregor3545ff42009-09-21 16:56:56 +00001937 AddTemplateParameterChunks(S.Context, Template, Result);
Douglas Gregor9eb77012009-11-07 00:00:49 +00001938 Result->AddChunk(Chunk(CodeCompletionString::CK_RightAngle));
Douglas Gregor3545ff42009-09-21 16:56:56 +00001939 return Result;
1940 }
1941
Douglas Gregord3c5d792009-11-17 16:44:22 +00001942 if (ObjCMethodDecl *Method = dyn_cast<ObjCMethodDecl>(ND)) {
Douglas Gregord3c5d792009-11-17 16:44:22 +00001943 Selector Sel = Method->getSelector();
1944 if (Sel.isUnarySelector()) {
1945 Result->AddTypedTextChunk(Sel.getIdentifierInfoForSlot(0)->getName());
1946 return Result;
1947 }
1948
Douglas Gregor1b605f72009-11-19 01:08:35 +00001949 std::string SelName = Sel.getIdentifierInfoForSlot(0)->getName().str();
1950 SelName += ':';
1951 if (StartParameter == 0)
1952 Result->AddTypedTextChunk(SelName);
1953 else {
1954 Result->AddInformativeChunk(SelName);
1955
1956 // If there is only one parameter, and we're past it, add an empty
1957 // typed-text chunk since there is nothing to type.
1958 if (Method->param_size() == 1)
1959 Result->AddTypedTextChunk("");
1960 }
Douglas Gregord3c5d792009-11-17 16:44:22 +00001961 unsigned Idx = 0;
1962 for (ObjCMethodDecl::param_iterator P = Method->param_begin(),
1963 PEnd = Method->param_end();
1964 P != PEnd; (void)++P, ++Idx) {
1965 if (Idx > 0) {
Douglas Gregor1b605f72009-11-19 01:08:35 +00001966 std::string Keyword;
1967 if (Idx > StartParameter)
Douglas Gregor6a803932010-01-12 06:38:28 +00001968 Result->AddChunk(CodeCompletionString::CK_HorizontalSpace);
Douglas Gregord3c5d792009-11-17 16:44:22 +00001969 if (IdentifierInfo *II = Sel.getIdentifierInfoForSlot(Idx))
1970 Keyword += II->getName().str();
1971 Keyword += ":";
Douglas Gregor95887f92010-07-08 23:20:03 +00001972 if (Idx < StartParameter || AllParametersAreInformative)
Douglas Gregor1b605f72009-11-19 01:08:35 +00001973 Result->AddInformativeChunk(Keyword);
Douglas Gregor95887f92010-07-08 23:20:03 +00001974 else if (Idx == StartParameter)
Douglas Gregor1b605f72009-11-19 01:08:35 +00001975 Result->AddTypedTextChunk(Keyword);
1976 else
1977 Result->AddTextChunk(Keyword);
Douglas Gregord3c5d792009-11-17 16:44:22 +00001978 }
Douglas Gregor1b605f72009-11-19 01:08:35 +00001979
1980 // If we're before the starting parameter, skip the placeholder.
1981 if (Idx < StartParameter)
1982 continue;
Douglas Gregord3c5d792009-11-17 16:44:22 +00001983
1984 std::string Arg;
1985 (*P)->getType().getAsStringInternal(Arg, S.Context.PrintingPolicy);
1986 Arg = "(" + Arg + ")";
1987 if (IdentifierInfo *II = (*P)->getIdentifier())
1988 Arg += II->getName().str();
Douglas Gregor95887f92010-07-08 23:20:03 +00001989 if (DeclaringEntity)
1990 Result->AddTextChunk(Arg);
1991 else if (AllParametersAreInformative)
Douglas Gregorc8537c52009-11-19 07:41:15 +00001992 Result->AddInformativeChunk(Arg);
1993 else
1994 Result->AddPlaceholderChunk(Arg);
Douglas Gregord3c5d792009-11-17 16:44:22 +00001995 }
1996
Douglas Gregor04c5f972009-12-23 00:21:46 +00001997 if (Method->isVariadic()) {
Douglas Gregor95887f92010-07-08 23:20:03 +00001998 if (DeclaringEntity)
1999 Result->AddTextChunk(", ...");
2000 else if (AllParametersAreInformative)
Douglas Gregor04c5f972009-12-23 00:21:46 +00002001 Result->AddInformativeChunk(", ...");
2002 else
2003 Result->AddPlaceholderChunk(", ...");
2004 }
2005
Douglas Gregord3c5d792009-11-17 16:44:22 +00002006 return Result;
2007 }
2008
Douglas Gregorf09935f2009-12-01 05:55:20 +00002009 if (Qualifier)
Douglas Gregor5bf52692009-09-22 23:15:58 +00002010 AddQualifierToCompletionString(Result, Qualifier, QualifierIsInformative,
2011 S.Context);
Douglas Gregorf09935f2009-12-01 05:55:20 +00002012
2013 Result->AddTypedTextChunk(ND->getNameAsString());
2014 return Result;
Douglas Gregor3545ff42009-09-21 16:56:56 +00002015}
2016
Douglas Gregorf0f51982009-09-23 00:34:09 +00002017CodeCompletionString *
2018CodeCompleteConsumer::OverloadCandidate::CreateSignatureString(
2019 unsigned CurrentArg,
2020 Sema &S) const {
Douglas Gregor9eb77012009-11-07 00:00:49 +00002021 typedef CodeCompletionString::Chunk Chunk;
2022
Douglas Gregorf0f51982009-09-23 00:34:09 +00002023 CodeCompletionString *Result = new CodeCompletionString;
2024 FunctionDecl *FDecl = getFunction();
Douglas Gregorb3fa9192009-12-18 18:53:37 +00002025 AddResultTypeChunk(S.Context, FDecl, Result);
Douglas Gregorf0f51982009-09-23 00:34:09 +00002026 const FunctionProtoType *Proto
2027 = dyn_cast<FunctionProtoType>(getFunctionType());
2028 if (!FDecl && !Proto) {
2029 // Function without a prototype. Just give the return type and a
2030 // highlighted ellipsis.
2031 const FunctionType *FT = getFunctionType();
2032 Result->AddTextChunk(
Benjamin Kramerb33a97c2009-11-29 20:18:50 +00002033 FT->getResultType().getAsString(S.Context.PrintingPolicy));
Douglas Gregor9eb77012009-11-07 00:00:49 +00002034 Result->AddChunk(Chunk(CodeCompletionString::CK_LeftParen));
2035 Result->AddChunk(Chunk(CodeCompletionString::CK_CurrentParameter, "..."));
2036 Result->AddChunk(Chunk(CodeCompletionString::CK_RightParen));
Douglas Gregorf0f51982009-09-23 00:34:09 +00002037 return Result;
2038 }
2039
2040 if (FDecl)
Benjamin Kramerb33a97c2009-11-29 20:18:50 +00002041 Result->AddTextChunk(FDecl->getNameAsString());
Douglas Gregorf0f51982009-09-23 00:34:09 +00002042 else
2043 Result->AddTextChunk(
Benjamin Kramerb33a97c2009-11-29 20:18:50 +00002044 Proto->getResultType().getAsString(S.Context.PrintingPolicy));
Douglas Gregorf0f51982009-09-23 00:34:09 +00002045
Douglas Gregor9eb77012009-11-07 00:00:49 +00002046 Result->AddChunk(Chunk(CodeCompletionString::CK_LeftParen));
Douglas Gregorf0f51982009-09-23 00:34:09 +00002047 unsigned NumParams = FDecl? FDecl->getNumParams() : Proto->getNumArgs();
2048 for (unsigned I = 0; I != NumParams; ++I) {
2049 if (I)
Douglas Gregor9eb77012009-11-07 00:00:49 +00002050 Result->AddChunk(Chunk(CodeCompletionString::CK_Comma));
Douglas Gregorf0f51982009-09-23 00:34:09 +00002051
2052 std::string ArgString;
2053 QualType ArgType;
2054
2055 if (FDecl) {
2056 ArgString = FDecl->getParamDecl(I)->getNameAsString();
2057 ArgType = FDecl->getParamDecl(I)->getOriginalType();
2058 } else {
2059 ArgType = Proto->getArgType(I);
2060 }
2061
2062 ArgType.getAsStringInternal(ArgString, S.Context.PrintingPolicy);
2063
2064 if (I == CurrentArg)
Douglas Gregor9eb77012009-11-07 00:00:49 +00002065 Result->AddChunk(Chunk(CodeCompletionString::CK_CurrentParameter,
Benjamin Kramerb33a97c2009-11-29 20:18:50 +00002066 ArgString));
Douglas Gregorf0f51982009-09-23 00:34:09 +00002067 else
Benjamin Kramerb33a97c2009-11-29 20:18:50 +00002068 Result->AddTextChunk(ArgString);
Douglas Gregorf0f51982009-09-23 00:34:09 +00002069 }
2070
2071 if (Proto && Proto->isVariadic()) {
Douglas Gregor9eb77012009-11-07 00:00:49 +00002072 Result->AddChunk(Chunk(CodeCompletionString::CK_Comma));
Douglas Gregorf0f51982009-09-23 00:34:09 +00002073 if (CurrentArg < NumParams)
2074 Result->AddTextChunk("...");
2075 else
Douglas Gregor9eb77012009-11-07 00:00:49 +00002076 Result->AddChunk(Chunk(CodeCompletionString::CK_CurrentParameter, "..."));
Douglas Gregorf0f51982009-09-23 00:34:09 +00002077 }
Douglas Gregor9eb77012009-11-07 00:00:49 +00002078 Result->AddChunk(Chunk(CodeCompletionString::CK_RightParen));
Douglas Gregorf0f51982009-09-23 00:34:09 +00002079
2080 return Result;
2081}
2082
Douglas Gregor3545ff42009-09-21 16:56:56 +00002083namespace {
2084 struct SortCodeCompleteResult {
2085 typedef CodeCompleteConsumer::Result Result;
2086
Douglas Gregor52ce62f2010-01-13 23:24:38 +00002087 /// \brief Retrieve the name that should be used to order a result.
2088 ///
2089 /// If the name needs to be constructed as a string, that string will be
2090 /// saved into Saved and the returned StringRef will refer to it.
2091 static llvm::StringRef getOrderedName(const Result &R,
2092 std::string &Saved) {
2093 switch (R.Kind) {
2094 case Result::RK_Keyword:
2095 return R.Keyword;
2096
2097 case Result::RK_Pattern:
2098 return R.Pattern->getTypedText();
2099
2100 case Result::RK_Macro:
2101 return R.Macro->getName();
2102
2103 case Result::RK_Declaration:
2104 // Handle declarations below.
2105 break;
Douglas Gregor45f83ee2009-11-19 00:01:57 +00002106 }
Douglas Gregor52ce62f2010-01-13 23:24:38 +00002107
2108 DeclarationName Name = R.Declaration->getDeclName();
Douglas Gregor45f83ee2009-11-19 00:01:57 +00002109
Douglas Gregor52ce62f2010-01-13 23:24:38 +00002110 // If the name is a simple identifier (by far the common case), or a
2111 // zero-argument selector, just return a reference to that identifier.
2112 if (IdentifierInfo *Id = Name.getAsIdentifierInfo())
2113 return Id->getName();
2114 if (Name.isObjCZeroArgSelector())
2115 if (IdentifierInfo *Id
2116 = Name.getObjCSelector().getIdentifierInfoForSlot(0))
2117 return Id->getName();
2118
2119 Saved = Name.getAsString();
2120 return Saved;
2121 }
2122
2123 bool operator()(const Result &X, const Result &Y) const {
2124 std::string XSaved, YSaved;
2125 llvm::StringRef XStr = getOrderedName(X, XSaved);
2126 llvm::StringRef YStr = getOrderedName(Y, YSaved);
2127 int cmp = XStr.compare_lower(YStr);
2128 if (cmp)
2129 return cmp < 0;
Douglas Gregor3545ff42009-09-21 16:56:56 +00002130
2131 // Non-hidden names precede hidden names.
2132 if (X.Hidden != Y.Hidden)
2133 return !X.Hidden;
2134
Douglas Gregore412a5a2009-09-23 22:26:46 +00002135 // Non-nested-name-specifiers precede nested-name-specifiers.
2136 if (X.StartsNestedNameSpecifier != Y.StartsNestedNameSpecifier)
2137 return !X.StartsNestedNameSpecifier;
2138
Douglas Gregor3545ff42009-09-21 16:56:56 +00002139 return false;
2140 }
2141 };
2142}
2143
Douglas Gregor6e240332010-08-16 16:18:59 +00002144unsigned clang::getMacroUsagePriority(llvm::StringRef MacroName,
2145 bool PreferredTypeIsPointer) {
2146 unsigned Priority = CCP_Macro;
2147
2148 // Treat the "nil" and "NULL" macros as null pointer constants.
2149 if (MacroName.equals("nil") || MacroName.equals("NULL")) {
2150 Priority = CCP_Constant;
2151 if (PreferredTypeIsPointer)
2152 Priority = Priority / CCF_SimilarTypeMatch;
2153 }
2154
2155 return Priority;
2156}
2157
Douglas Gregor55b037b2010-07-08 20:55:51 +00002158static void AddMacroResults(Preprocessor &PP, ResultBuilder &Results,
2159 bool TargetTypeIsPointer = false) {
2160 typedef CodeCompleteConsumer::Result Result;
2161
Douglas Gregorf329c7c2009-10-30 16:50:04 +00002162 Results.EnterNewScope();
Douglas Gregor9eb77012009-11-07 00:00:49 +00002163 for (Preprocessor::macro_iterator M = PP.macro_begin(),
2164 MEnd = PP.macro_end();
Douglas Gregor55b037b2010-07-08 20:55:51 +00002165 M != MEnd; ++M) {
Douglas Gregor6e240332010-08-16 16:18:59 +00002166 Results.AddResult(Result(M->first,
2167 getMacroUsagePriority(M->first->getName(),
2168 TargetTypeIsPointer)));
Douglas Gregor55b037b2010-07-08 20:55:51 +00002169 }
Douglas Gregorf329c7c2009-10-30 16:50:04 +00002170 Results.ExitScope();
2171}
2172
Daniel Dunbar242ea9a2009-11-13 08:58:20 +00002173static void HandleCodeCompleteResults(Sema *S,
2174 CodeCompleteConsumer *CodeCompleter,
Douglas Gregor00c37ef2010-08-11 21:23:17 +00002175 CodeCompletionContext Context,
2176 CodeCompleteConsumer::Result *Results,
2177 unsigned NumResults) {
Douglas Gregor3545ff42009-09-21 16:56:56 +00002178 std::stable_sort(Results, Results + NumResults, SortCodeCompleteResult());
2179
2180 if (CodeCompleter)
Douglas Gregor00c37ef2010-08-11 21:23:17 +00002181 CodeCompleter->ProcessCodeCompleteResults(*S, Context, Results, NumResults);
Douglas Gregor45f83ee2009-11-19 00:01:57 +00002182
2183 for (unsigned I = 0; I != NumResults; ++I)
2184 Results[I].Destroy();
Douglas Gregor3545ff42009-09-21 16:56:56 +00002185}
2186
Douglas Gregor00c37ef2010-08-11 21:23:17 +00002187static enum CodeCompletionContext::Kind mapCodeCompletionContext(Sema &S,
2188 Sema::ParserCompletionContext PCC) {
2189 switch (PCC) {
2190 case Action::PCC_Namespace:
2191 return CodeCompletionContext::CCC_TopLevel;
2192
2193 case Action::PCC_Class:
2194 return CodeCompletionContext::CCC_ClassStructUnion;
2195
2196 case Action::PCC_ObjCInterface:
2197 return CodeCompletionContext::CCC_ObjCInterface;
2198
2199 case Action::PCC_ObjCImplementation:
2200 return CodeCompletionContext::CCC_ObjCImplementation;
2201
2202 case Action::PCC_ObjCInstanceVariableList:
2203 return CodeCompletionContext::CCC_ObjCIvarList;
2204
2205 case Action::PCC_Template:
2206 case Action::PCC_MemberTemplate:
2207 case Action::PCC_RecoveryInFunction:
2208 return CodeCompletionContext::CCC_Other;
2209
2210 case Action::PCC_Expression:
2211 case Action::PCC_ForInit:
2212 case Action::PCC_Condition:
2213 return CodeCompletionContext::CCC_Expression;
2214
2215 case Action::PCC_Statement:
2216 return CodeCompletionContext::CCC_Statement;
2217 }
2218
2219 return CodeCompletionContext::CCC_Other;
2220}
2221
Douglas Gregor504a6ae2010-01-10 23:08:15 +00002222void Sema::CodeCompleteOrdinaryName(Scope *S,
Douglas Gregor00c37ef2010-08-11 21:23:17 +00002223 ParserCompletionContext CompletionContext) {
Douglas Gregor92253692009-12-07 09:54:55 +00002224 typedef CodeCompleteConsumer::Result Result;
Douglas Gregor504a6ae2010-01-10 23:08:15 +00002225 ResultBuilder Results(*this);
2226
2227 // Determine how to filter results, e.g., so that the names of
2228 // values (functions, enumerators, function templates, etc.) are
2229 // only allowed where we can have an expression.
2230 switch (CompletionContext) {
Douglas Gregor00c37ef2010-08-11 21:23:17 +00002231 case PCC_Namespace:
2232 case PCC_Class:
2233 case PCC_ObjCInterface:
2234 case PCC_ObjCImplementation:
2235 case PCC_ObjCInstanceVariableList:
2236 case PCC_Template:
2237 case PCC_MemberTemplate:
Douglas Gregor504a6ae2010-01-10 23:08:15 +00002238 Results.setFilter(&ResultBuilder::IsOrdinaryNonValueName);
2239 break;
2240
Douglas Gregor00c37ef2010-08-11 21:23:17 +00002241 case PCC_Expression:
2242 case PCC_Statement:
2243 case PCC_ForInit:
2244 case PCC_Condition:
Douglas Gregor70febae2010-05-28 00:49:12 +00002245 if (WantTypesInContext(CompletionContext, getLangOptions()))
2246 Results.setFilter(&ResultBuilder::IsOrdinaryName);
2247 else
2248 Results.setFilter(&ResultBuilder::IsOrdinaryNonTypeName);
Douglas Gregor504a6ae2010-01-10 23:08:15 +00002249 break;
Douglas Gregor6da3db42010-05-25 05:58:43 +00002250
Douglas Gregor00c37ef2010-08-11 21:23:17 +00002251 case PCC_RecoveryInFunction:
Douglas Gregor6da3db42010-05-25 05:58:43 +00002252 // Unfiltered
2253 break;
Douglas Gregor504a6ae2010-01-10 23:08:15 +00002254 }
2255
Douglas Gregorc580c522010-01-14 01:09:38 +00002256 CodeCompletionDeclConsumer Consumer(Results, CurContext);
Douglas Gregor39982192010-08-15 06:18:01 +00002257 LookupVisibleDecls(S, LookupOrdinaryName, Consumer,
2258 CodeCompleter->includeGlobals());
Douglas Gregor92253692009-12-07 09:54:55 +00002259
2260 Results.EnterNewScope();
Douglas Gregorf98e6a22010-01-13 23:51:12 +00002261 AddOrdinaryNameResults(CompletionContext, S, *this, Results);
Douglas Gregor92253692009-12-07 09:54:55 +00002262 Results.ExitScope();
2263
Douglas Gregor9eb77012009-11-07 00:00:49 +00002264 if (CodeCompleter->includeMacros())
Douglas Gregorf98e6a22010-01-13 23:51:12 +00002265 AddMacroResults(PP, Results);
Douglas Gregor00c37ef2010-08-11 21:23:17 +00002266 HandleCodeCompleteResults(this, CodeCompleter,
2267 mapCodeCompletionContext(*this, CompletionContext),
2268 Results.data(),Results.size());
Douglas Gregor9d64c5e2009-09-21 20:51:25 +00002269}
2270
Douglas Gregor7aa6b222010-05-30 01:49:25 +00002271/// \brief Perform code-completion in an expression context when we know what
2272/// type we're looking for.
Douglas Gregor85b50632010-07-28 21:50:18 +00002273///
2274/// \param IntegralConstantExpression Only permit integral constant
2275/// expressions.
2276void Sema::CodeCompleteExpression(Scope *S, QualType T,
2277 bool IntegralConstantExpression) {
Douglas Gregor7aa6b222010-05-30 01:49:25 +00002278 typedef CodeCompleteConsumer::Result Result;
2279 ResultBuilder Results(*this);
2280
Douglas Gregor85b50632010-07-28 21:50:18 +00002281 if (IntegralConstantExpression)
2282 Results.setFilter(&ResultBuilder::IsIntegralConstantValue);
Douglas Gregor00c37ef2010-08-11 21:23:17 +00002283 else if (WantTypesInContext(PCC_Expression, getLangOptions()))
Douglas Gregor7aa6b222010-05-30 01:49:25 +00002284 Results.setFilter(&ResultBuilder::IsOrdinaryName);
2285 else
2286 Results.setFilter(&ResultBuilder::IsOrdinaryNonTypeName);
2287 Results.setPreferredType(T.getNonReferenceType());
2288
2289 CodeCompletionDeclConsumer Consumer(Results, CurContext);
Douglas Gregor39982192010-08-15 06:18:01 +00002290 LookupVisibleDecls(S, LookupOrdinaryName, Consumer,
2291 CodeCompleter->includeGlobals());
Douglas Gregor7aa6b222010-05-30 01:49:25 +00002292
2293 Results.EnterNewScope();
Douglas Gregor00c37ef2010-08-11 21:23:17 +00002294 AddOrdinaryNameResults(PCC_Expression, S, *this, Results);
Douglas Gregor7aa6b222010-05-30 01:49:25 +00002295 Results.ExitScope();
2296
Douglas Gregor55b037b2010-07-08 20:55:51 +00002297 bool PreferredTypeIsPointer = false;
2298 if (!T.isNull())
2299 PreferredTypeIsPointer = T->isAnyPointerType() ||
2300 T->isMemberPointerType() || T->isBlockPointerType();
2301
Douglas Gregor7aa6b222010-05-30 01:49:25 +00002302 if (CodeCompleter->includeMacros())
Douglas Gregor55b037b2010-07-08 20:55:51 +00002303 AddMacroResults(PP, Results, PreferredTypeIsPointer);
Douglas Gregor00c37ef2010-08-11 21:23:17 +00002304 HandleCodeCompleteResults(this, CodeCompleter,
Douglas Gregor6e240332010-08-16 16:18:59 +00002305 CodeCompletionContext(CodeCompletionContext::CCC_Expression, T),
Douglas Gregor00c37ef2010-08-11 21:23:17 +00002306 Results.data(),Results.size());
Douglas Gregor7aa6b222010-05-30 01:49:25 +00002307}
2308
2309
Douglas Gregor9291bad2009-11-18 01:29:26 +00002310static void AddObjCProperties(ObjCContainerDecl *Container,
Douglas Gregor5d649882009-11-18 22:32:06 +00002311 bool AllowCategories,
Douglas Gregor9291bad2009-11-18 01:29:26 +00002312 DeclContext *CurContext,
2313 ResultBuilder &Results) {
2314 typedef CodeCompleteConsumer::Result Result;
2315
2316 // Add properties in this container.
2317 for (ObjCContainerDecl::prop_iterator P = Container->prop_begin(),
2318 PEnd = Container->prop_end();
2319 P != PEnd;
2320 ++P)
2321 Results.MaybeAddResult(Result(*P, 0), CurContext);
2322
2323 // Add properties in referenced protocols.
2324 if (ObjCProtocolDecl *Protocol = dyn_cast<ObjCProtocolDecl>(Container)) {
2325 for (ObjCProtocolDecl::protocol_iterator P = Protocol->protocol_begin(),
2326 PEnd = Protocol->protocol_end();
2327 P != PEnd; ++P)
Douglas Gregor5d649882009-11-18 22:32:06 +00002328 AddObjCProperties(*P, AllowCategories, CurContext, Results);
Douglas Gregor9291bad2009-11-18 01:29:26 +00002329 } else if (ObjCInterfaceDecl *IFace = dyn_cast<ObjCInterfaceDecl>(Container)){
Douglas Gregor5d649882009-11-18 22:32:06 +00002330 if (AllowCategories) {
2331 // Look through categories.
2332 for (ObjCCategoryDecl *Category = IFace->getCategoryList();
2333 Category; Category = Category->getNextClassCategory())
2334 AddObjCProperties(Category, AllowCategories, CurContext, Results);
2335 }
Douglas Gregor9291bad2009-11-18 01:29:26 +00002336
2337 // Look through protocols.
2338 for (ObjCInterfaceDecl::protocol_iterator I = IFace->protocol_begin(),
2339 E = IFace->protocol_end();
2340 I != E; ++I)
Douglas Gregor5d649882009-11-18 22:32:06 +00002341 AddObjCProperties(*I, AllowCategories, CurContext, Results);
Douglas Gregor9291bad2009-11-18 01:29:26 +00002342
2343 // Look in the superclass.
2344 if (IFace->getSuperClass())
Douglas Gregor5d649882009-11-18 22:32:06 +00002345 AddObjCProperties(IFace->getSuperClass(), AllowCategories, CurContext,
2346 Results);
Douglas Gregor9291bad2009-11-18 01:29:26 +00002347 } else if (const ObjCCategoryDecl *Category
2348 = dyn_cast<ObjCCategoryDecl>(Container)) {
2349 // Look through protocols.
2350 for (ObjCInterfaceDecl::protocol_iterator P = Category->protocol_begin(),
2351 PEnd = Category->protocol_end();
2352 P != PEnd; ++P)
Douglas Gregor5d649882009-11-18 22:32:06 +00002353 AddObjCProperties(*P, AllowCategories, CurContext, Results);
Douglas Gregor9291bad2009-11-18 01:29:26 +00002354 }
2355}
2356
Douglas Gregor2436e712009-09-17 21:32:03 +00002357void Sema::CodeCompleteMemberReferenceExpr(Scope *S, ExprTy *BaseE,
2358 SourceLocation OpLoc,
2359 bool IsArrow) {
2360 if (!BaseE || !CodeCompleter)
2361 return;
2362
Douglas Gregor3545ff42009-09-21 16:56:56 +00002363 typedef CodeCompleteConsumer::Result Result;
2364
Douglas Gregor2436e712009-09-17 21:32:03 +00002365 Expr *Base = static_cast<Expr *>(BaseE);
2366 QualType BaseType = Base->getType();
Douglas Gregor3545ff42009-09-21 16:56:56 +00002367
2368 if (IsArrow) {
2369 if (const PointerType *Ptr = BaseType->getAs<PointerType>())
2370 BaseType = Ptr->getPointeeType();
2371 else if (BaseType->isObjCObjectPointerType())
2372 /*Do nothing*/ ;
2373 else
2374 return;
2375 }
2376
Douglas Gregore412a5a2009-09-23 22:26:46 +00002377 ResultBuilder Results(*this, &ResultBuilder::IsMember);
Douglas Gregor9291bad2009-11-18 01:29:26 +00002378 Results.EnterNewScope();
2379 if (const RecordType *Record = BaseType->getAs<RecordType>()) {
2380 // Access to a C/C++ class, struct, or union.
Douglas Gregor6ae4c522010-01-14 03:21:49 +00002381 Results.allowNestedNameSpecifiers();
Douglas Gregor09bbc652010-01-14 15:47:35 +00002382 CodeCompletionDeclConsumer Consumer(Results, CurContext);
Douglas Gregor39982192010-08-15 06:18:01 +00002383 LookupVisibleDecls(Record->getDecl(), LookupMemberName, Consumer,
2384 CodeCompleter->includeGlobals());
Daniel Dunbar242ea9a2009-11-13 08:58:20 +00002385
Douglas Gregor9291bad2009-11-18 01:29:26 +00002386 if (getLangOptions().CPlusPlus) {
2387 if (!Results.empty()) {
2388 // The "template" keyword can follow "->" or "." in the grammar.
2389 // However, we only want to suggest the template keyword if something
2390 // is dependent.
2391 bool IsDependent = BaseType->isDependentType();
2392 if (!IsDependent) {
2393 for (Scope *DepScope = S; DepScope; DepScope = DepScope->getParent())
2394 if (DeclContext *Ctx = (DeclContext *)DepScope->getEntity()) {
2395 IsDependent = Ctx->isDependentContext();
2396 break;
2397 }
2398 }
Daniel Dunbar242ea9a2009-11-13 08:58:20 +00002399
Douglas Gregor9291bad2009-11-18 01:29:26 +00002400 if (IsDependent)
Douglas Gregor78a21012010-01-14 16:01:26 +00002401 Results.AddResult(Result("template"));
Daniel Dunbar242ea9a2009-11-13 08:58:20 +00002402 }
Daniel Dunbar242ea9a2009-11-13 08:58:20 +00002403 }
Douglas Gregor9291bad2009-11-18 01:29:26 +00002404 } else if (!IsArrow && BaseType->getAsObjCInterfacePointerType()) {
2405 // Objective-C property reference.
2406
2407 // Add property results based on our interface.
2408 const ObjCObjectPointerType *ObjCPtr
2409 = BaseType->getAsObjCInterfacePointerType();
2410 assert(ObjCPtr && "Non-NULL pointer guaranteed above!");
Douglas Gregor5d649882009-11-18 22:32:06 +00002411 AddObjCProperties(ObjCPtr->getInterfaceDecl(), true, CurContext, Results);
Douglas Gregor9291bad2009-11-18 01:29:26 +00002412
2413 // Add properties from the protocols in a qualified interface.
2414 for (ObjCObjectPointerType::qual_iterator I = ObjCPtr->qual_begin(),
2415 E = ObjCPtr->qual_end();
2416 I != E; ++I)
Douglas Gregor5d649882009-11-18 22:32:06 +00002417 AddObjCProperties(*I, true, CurContext, Results);
Douglas Gregor9291bad2009-11-18 01:29:26 +00002418 } else if ((IsArrow && BaseType->isObjCObjectPointerType()) ||
John McCall8b07ec22010-05-15 11:32:37 +00002419 (!IsArrow && BaseType->isObjCObjectType())) {
Douglas Gregor9291bad2009-11-18 01:29:26 +00002420 // Objective-C instance variable access.
2421 ObjCInterfaceDecl *Class = 0;
2422 if (const ObjCObjectPointerType *ObjCPtr
2423 = BaseType->getAs<ObjCObjectPointerType>())
2424 Class = ObjCPtr->getInterfaceDecl();
2425 else
John McCall8b07ec22010-05-15 11:32:37 +00002426 Class = BaseType->getAs<ObjCObjectType>()->getInterface();
Douglas Gregor9291bad2009-11-18 01:29:26 +00002427
2428 // Add all ivars from this class and its superclasses.
Douglas Gregor2b8162b2010-01-14 16:08:12 +00002429 if (Class) {
2430 CodeCompletionDeclConsumer Consumer(Results, CurContext);
2431 Results.setFilter(&ResultBuilder::IsObjCIvar);
Douglas Gregor39982192010-08-15 06:18:01 +00002432 LookupVisibleDecls(Class, LookupMemberName, Consumer,
2433 CodeCompleter->includeGlobals());
Douglas Gregor9291bad2009-11-18 01:29:26 +00002434 }
Douglas Gregor3545ff42009-09-21 16:56:56 +00002435 }
Douglas Gregor9291bad2009-11-18 01:29:26 +00002436
2437 // FIXME: How do we cope with isa?
2438
2439 Results.ExitScope();
Daniel Dunbar242ea9a2009-11-13 08:58:20 +00002440
Daniel Dunbar242ea9a2009-11-13 08:58:20 +00002441 // Hand off the results found for code completion.
Douglas Gregor00c37ef2010-08-11 21:23:17 +00002442 HandleCodeCompleteResults(this, CodeCompleter,
2443 CodeCompletionContext(CodeCompletionContext::CCC_MemberAccess,
2444 BaseType),
2445 Results.data(),Results.size());
Douglas Gregor2436e712009-09-17 21:32:03 +00002446}
2447
Douglas Gregorf45b0cf2009-09-18 15:37:17 +00002448void Sema::CodeCompleteTag(Scope *S, unsigned TagSpec) {
2449 if (!CodeCompleter)
2450 return;
2451
Douglas Gregor3545ff42009-09-21 16:56:56 +00002452 typedef CodeCompleteConsumer::Result Result;
2453 ResultBuilder::LookupFilter Filter = 0;
Douglas Gregor00c37ef2010-08-11 21:23:17 +00002454 enum CodeCompletionContext::Kind ContextKind
2455 = CodeCompletionContext::CCC_Other;
Douglas Gregorf45b0cf2009-09-18 15:37:17 +00002456 switch ((DeclSpec::TST)TagSpec) {
2457 case DeclSpec::TST_enum:
Douglas Gregor3545ff42009-09-21 16:56:56 +00002458 Filter = &ResultBuilder::IsEnum;
Douglas Gregor00c37ef2010-08-11 21:23:17 +00002459 ContextKind = CodeCompletionContext::CCC_EnumTag;
Douglas Gregorf45b0cf2009-09-18 15:37:17 +00002460 break;
2461
2462 case DeclSpec::TST_union:
Douglas Gregor3545ff42009-09-21 16:56:56 +00002463 Filter = &ResultBuilder::IsUnion;
Douglas Gregor00c37ef2010-08-11 21:23:17 +00002464 ContextKind = CodeCompletionContext::CCC_UnionTag;
Douglas Gregorf45b0cf2009-09-18 15:37:17 +00002465 break;
2466
2467 case DeclSpec::TST_struct:
Douglas Gregorf45b0cf2009-09-18 15:37:17 +00002468 case DeclSpec::TST_class:
Douglas Gregor3545ff42009-09-21 16:56:56 +00002469 Filter = &ResultBuilder::IsClassOrStruct;
Douglas Gregor00c37ef2010-08-11 21:23:17 +00002470 ContextKind = CodeCompletionContext::CCC_ClassOrStructTag;
Douglas Gregorf45b0cf2009-09-18 15:37:17 +00002471 break;
2472
2473 default:
2474 assert(false && "Unknown type specifier kind in CodeCompleteTag");
2475 return;
2476 }
Douglas Gregor3545ff42009-09-21 16:56:56 +00002477
John McCalle87beb22010-04-23 18:46:30 +00002478 ResultBuilder Results(*this);
Douglas Gregora6e2edc2010-01-14 03:27:13 +00002479 CodeCompletionDeclConsumer Consumer(Results, CurContext);
John McCalle87beb22010-04-23 18:46:30 +00002480
2481 // First pass: look for tags.
2482 Results.setFilter(Filter);
Douglas Gregor39982192010-08-15 06:18:01 +00002483 LookupVisibleDecls(S, LookupTagName, Consumer,
2484 CodeCompleter->includeGlobals());
John McCalle87beb22010-04-23 18:46:30 +00002485
Douglas Gregor39982192010-08-15 06:18:01 +00002486 if (CodeCompleter->includeGlobals()) {
2487 // Second pass: look for nested name specifiers.
2488 Results.setFilter(&ResultBuilder::IsNestedNameSpecifier);
2489 LookupVisibleDecls(S, LookupNestedNameSpecifierName, Consumer);
2490 }
Douglas Gregor3545ff42009-09-21 16:56:56 +00002491
Douglas Gregor00c37ef2010-08-11 21:23:17 +00002492 HandleCodeCompleteResults(this, CodeCompleter, ContextKind,
2493 Results.data(),Results.size());
Douglas Gregorf45b0cf2009-09-18 15:37:17 +00002494}
2495
Douglas Gregord328d572009-09-21 18:10:23 +00002496void Sema::CodeCompleteCase(Scope *S) {
2497 if (getSwitchStack().empty() || !CodeCompleter)
2498 return;
2499
2500 SwitchStmt *Switch = getSwitchStack().back();
Douglas Gregor85b50632010-07-28 21:50:18 +00002501 if (!Switch->getCond()->getType()->isEnumeralType()) {
2502 CodeCompleteExpression(S, Switch->getCond()->getType(), true);
Douglas Gregord328d572009-09-21 18:10:23 +00002503 return;
Douglas Gregor85b50632010-07-28 21:50:18 +00002504 }
Douglas Gregord328d572009-09-21 18:10:23 +00002505
2506 // Code-complete the cases of a switch statement over an enumeration type
2507 // by providing the list of
2508 EnumDecl *Enum = Switch->getCond()->getType()->getAs<EnumType>()->getDecl();
2509
2510 // Determine which enumerators we have already seen in the switch statement.
2511 // FIXME: Ideally, we would also be able to look *past* the code-completion
2512 // token, in case we are code-completing in the middle of the switch and not
2513 // at the end. However, we aren't able to do so at the moment.
2514 llvm::SmallPtrSet<EnumConstantDecl *, 8> EnumeratorsSeen;
Douglas Gregorf2510672009-09-21 19:57:38 +00002515 NestedNameSpecifier *Qualifier = 0;
Douglas Gregord328d572009-09-21 18:10:23 +00002516 for (SwitchCase *SC = Switch->getSwitchCaseList(); SC;
2517 SC = SC->getNextSwitchCase()) {
2518 CaseStmt *Case = dyn_cast<CaseStmt>(SC);
2519 if (!Case)
2520 continue;
2521
2522 Expr *CaseVal = Case->getLHS()->IgnoreParenCasts();
2523 if (DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(CaseVal))
2524 if (EnumConstantDecl *Enumerator
2525 = dyn_cast<EnumConstantDecl>(DRE->getDecl())) {
2526 // We look into the AST of the case statement to determine which
2527 // enumerator was named. Alternatively, we could compute the value of
2528 // the integral constant expression, then compare it against the
2529 // values of each enumerator. However, value-based approach would not
2530 // work as well with C++ templates where enumerators declared within a
2531 // template are type- and value-dependent.
2532 EnumeratorsSeen.insert(Enumerator);
2533
Douglas Gregorf2510672009-09-21 19:57:38 +00002534 // If this is a qualified-id, keep track of the nested-name-specifier
2535 // so that we can reproduce it as part of code completion, e.g.,
Douglas Gregord328d572009-09-21 18:10:23 +00002536 //
2537 // switch (TagD.getKind()) {
2538 // case TagDecl::TK_enum:
2539 // break;
2540 // case XXX
2541 //
Douglas Gregorf2510672009-09-21 19:57:38 +00002542 // At the XXX, our completions are TagDecl::TK_union,
Douglas Gregord328d572009-09-21 18:10:23 +00002543 // TagDecl::TK_struct, and TagDecl::TK_class, rather than TK_union,
2544 // TK_struct, and TK_class.
Douglas Gregor4bd90e52009-10-23 18:54:35 +00002545 Qualifier = DRE->getQualifier();
Douglas Gregord328d572009-09-21 18:10:23 +00002546 }
2547 }
2548
Douglas Gregorf2510672009-09-21 19:57:38 +00002549 if (getLangOptions().CPlusPlus && !Qualifier && EnumeratorsSeen.empty()) {
2550 // If there are no prior enumerators in C++, check whether we have to
2551 // qualify the names of the enumerators that we suggest, because they
2552 // may not be visible in this scope.
2553 Qualifier = getRequiredQualification(Context, CurContext,
2554 Enum->getDeclContext());
2555
2556 // FIXME: Scoped enums need to start with "EnumDecl" as the context!
2557 }
2558
Douglas Gregord328d572009-09-21 18:10:23 +00002559 // Add any enumerators that have not yet been mentioned.
2560 ResultBuilder Results(*this);
2561 Results.EnterNewScope();
2562 for (EnumDecl::enumerator_iterator E = Enum->enumerator_begin(),
2563 EEnd = Enum->enumerator_end();
2564 E != EEnd; ++E) {
2565 if (EnumeratorsSeen.count(*E))
2566 continue;
2567
Douglas Gregorfc59ce12010-01-14 16:14:35 +00002568 Results.AddResult(CodeCompleteConsumer::Result(*E, Qualifier),
2569 CurContext, 0, false);
Douglas Gregord328d572009-09-21 18:10:23 +00002570 }
2571 Results.ExitScope();
Douglas Gregor285560922010-04-06 20:02:15 +00002572
Douglas Gregor9eb77012009-11-07 00:00:49 +00002573 if (CodeCompleter->includeMacros())
Douglas Gregorf98e6a22010-01-13 23:51:12 +00002574 AddMacroResults(PP, Results);
Douglas Gregor00c37ef2010-08-11 21:23:17 +00002575 HandleCodeCompleteResults(this, CodeCompleter,
2576 CodeCompletionContext::CCC_Expression,
2577 Results.data(),Results.size());
Douglas Gregord328d572009-09-21 18:10:23 +00002578}
2579
Douglas Gregorcabea402009-09-22 15:41:20 +00002580namespace {
2581 struct IsBetterOverloadCandidate {
2582 Sema &S;
John McCallbc077cf2010-02-08 23:07:23 +00002583 SourceLocation Loc;
Douglas Gregorcabea402009-09-22 15:41:20 +00002584
2585 public:
John McCallbc077cf2010-02-08 23:07:23 +00002586 explicit IsBetterOverloadCandidate(Sema &S, SourceLocation Loc)
2587 : S(S), Loc(Loc) { }
Douglas Gregorcabea402009-09-22 15:41:20 +00002588
2589 bool
2590 operator()(const OverloadCandidate &X, const OverloadCandidate &Y) const {
John McCallbc077cf2010-02-08 23:07:23 +00002591 return S.isBetterOverloadCandidate(X, Y, Loc);
Douglas Gregorcabea402009-09-22 15:41:20 +00002592 }
2593 };
2594}
2595
Douglas Gregor6ed3eb82010-05-30 06:10:08 +00002596static bool anyNullArguments(Expr **Args, unsigned NumArgs) {
2597 if (NumArgs && !Args)
2598 return true;
2599
2600 for (unsigned I = 0; I != NumArgs; ++I)
2601 if (!Args[I])
2602 return true;
2603
2604 return false;
2605}
2606
Douglas Gregorcabea402009-09-22 15:41:20 +00002607void Sema::CodeCompleteCall(Scope *S, ExprTy *FnIn,
2608 ExprTy **ArgsIn, unsigned NumArgs) {
2609 if (!CodeCompleter)
2610 return;
Douglas Gregor3ef59522009-12-11 19:06:04 +00002611
2612 // When we're code-completing for a call, we fall back to ordinary
2613 // name code-completion whenever we can't produce specific
2614 // results. We may want to revisit this strategy in the future,
2615 // e.g., by merging the two kinds of results.
2616
Douglas Gregorcabea402009-09-22 15:41:20 +00002617 Expr *Fn = (Expr *)FnIn;
2618 Expr **Args = (Expr **)ArgsIn;
Douglas Gregor3ef59522009-12-11 19:06:04 +00002619
Douglas Gregorcabea402009-09-22 15:41:20 +00002620 // Ignore type-dependent call expressions entirely.
Douglas Gregor6ed3eb82010-05-30 06:10:08 +00002621 if (!Fn || Fn->isTypeDependent() || anyNullArguments(Args, NumArgs) ||
Douglas Gregor3ef59522009-12-11 19:06:04 +00002622 Expr::hasAnyTypeDependentArguments(Args, NumArgs)) {
Douglas Gregor00c37ef2010-08-11 21:23:17 +00002623 CodeCompleteOrdinaryName(S, PCC_Expression);
Douglas Gregorcabea402009-09-22 15:41:20 +00002624 return;
Douglas Gregor3ef59522009-12-11 19:06:04 +00002625 }
Douglas Gregorcabea402009-09-22 15:41:20 +00002626
John McCall57500772009-12-16 12:17:52 +00002627 // Build an overload candidate set based on the functions we find.
John McCallbc077cf2010-02-08 23:07:23 +00002628 SourceLocation Loc = Fn->getExprLoc();
2629 OverloadCandidateSet CandidateSet(Loc);
John McCall57500772009-12-16 12:17:52 +00002630
Douglas Gregorcabea402009-09-22 15:41:20 +00002631 // FIXME: What if we're calling something that isn't a function declaration?
2632 // FIXME: What if we're calling a pseudo-destructor?
2633 // FIXME: What if we're calling a member function?
2634
Douglas Gregorff59f672010-01-21 15:46:19 +00002635 typedef CodeCompleteConsumer::OverloadCandidate ResultCandidate;
2636 llvm::SmallVector<ResultCandidate, 8> Results;
2637
John McCall57500772009-12-16 12:17:52 +00002638 Expr *NakedFn = Fn->IgnoreParenCasts();
2639 if (UnresolvedLookupExpr *ULE = dyn_cast<UnresolvedLookupExpr>(NakedFn))
2640 AddOverloadedCallCandidates(ULE, Args, NumArgs, CandidateSet,
2641 /*PartialOverloading=*/ true);
2642 else if (DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(NakedFn)) {
2643 FunctionDecl *FDecl = dyn_cast<FunctionDecl>(DRE->getDecl());
Douglas Gregorff59f672010-01-21 15:46:19 +00002644 if (FDecl) {
Douglas Gregor6ed3eb82010-05-30 06:10:08 +00002645 if (!getLangOptions().CPlusPlus ||
2646 !FDecl->getType()->getAs<FunctionProtoType>())
Douglas Gregorff59f672010-01-21 15:46:19 +00002647 Results.push_back(ResultCandidate(FDecl));
2648 else
John McCallb89836b2010-01-26 01:37:31 +00002649 // FIXME: access?
John McCalla0296f72010-03-19 07:35:19 +00002650 AddOverloadCandidate(FDecl, DeclAccessPair::make(FDecl, AS_none),
2651 Args, NumArgs, CandidateSet,
Douglas Gregorb05275a2010-04-16 17:41:49 +00002652 false, /*PartialOverloading*/true);
Douglas Gregorff59f672010-01-21 15:46:19 +00002653 }
John McCall57500772009-12-16 12:17:52 +00002654 }
Douglas Gregorcabea402009-09-22 15:41:20 +00002655
Douglas Gregor7aa6b222010-05-30 01:49:25 +00002656 QualType ParamType;
2657
Douglas Gregorff59f672010-01-21 15:46:19 +00002658 if (!CandidateSet.empty()) {
2659 // Sort the overload candidate set by placing the best overloads first.
2660 std::stable_sort(CandidateSet.begin(), CandidateSet.end(),
John McCallbc077cf2010-02-08 23:07:23 +00002661 IsBetterOverloadCandidate(*this, Loc));
Douglas Gregorcabea402009-09-22 15:41:20 +00002662
Douglas Gregorff59f672010-01-21 15:46:19 +00002663 // Add the remaining viable overload candidates as code-completion reslults.
2664 for (OverloadCandidateSet::iterator Cand = CandidateSet.begin(),
2665 CandEnd = CandidateSet.end();
2666 Cand != CandEnd; ++Cand) {
2667 if (Cand->Viable)
2668 Results.push_back(ResultCandidate(Cand->Function));
2669 }
Douglas Gregor7aa6b222010-05-30 01:49:25 +00002670
2671 // From the viable candidates, try to determine the type of this parameter.
2672 for (unsigned I = 0, N = Results.size(); I != N; ++I) {
2673 if (const FunctionType *FType = Results[I].getFunctionType())
2674 if (const FunctionProtoType *Proto = dyn_cast<FunctionProtoType>(FType))
2675 if (NumArgs < Proto->getNumArgs()) {
2676 if (ParamType.isNull())
2677 ParamType = Proto->getArgType(NumArgs);
2678 else if (!Context.hasSameUnqualifiedType(
2679 ParamType.getNonReferenceType(),
2680 Proto->getArgType(NumArgs).getNonReferenceType())) {
2681 ParamType = QualType();
2682 break;
2683 }
2684 }
2685 }
2686 } else {
2687 // Try to determine the parameter type from the type of the expression
2688 // being called.
2689 QualType FunctionType = Fn->getType();
2690 if (const PointerType *Ptr = FunctionType->getAs<PointerType>())
2691 FunctionType = Ptr->getPointeeType();
2692 else if (const BlockPointerType *BlockPtr
2693 = FunctionType->getAs<BlockPointerType>())
2694 FunctionType = BlockPtr->getPointeeType();
2695 else if (const MemberPointerType *MemPtr
2696 = FunctionType->getAs<MemberPointerType>())
2697 FunctionType = MemPtr->getPointeeType();
2698
2699 if (const FunctionProtoType *Proto
2700 = FunctionType->getAs<FunctionProtoType>()) {
2701 if (NumArgs < Proto->getNumArgs())
2702 ParamType = Proto->getArgType(NumArgs);
2703 }
Douglas Gregorcabea402009-09-22 15:41:20 +00002704 }
Douglas Gregor3ef59522009-12-11 19:06:04 +00002705
Douglas Gregor7aa6b222010-05-30 01:49:25 +00002706 if (ParamType.isNull())
Douglas Gregor00c37ef2010-08-11 21:23:17 +00002707 CodeCompleteOrdinaryName(S, PCC_Expression);
Douglas Gregor7aa6b222010-05-30 01:49:25 +00002708 else
2709 CodeCompleteExpression(S, ParamType);
2710
Douglas Gregorc01890e2010-04-06 20:19:47 +00002711 if (!Results.empty())
Douglas Gregor3ef59522009-12-11 19:06:04 +00002712 CodeCompleter->ProcessOverloadCandidates(*this, NumArgs, Results.data(),
2713 Results.size());
Douglas Gregorcabea402009-09-22 15:41:20 +00002714}
2715
Douglas Gregor7aa6b222010-05-30 01:49:25 +00002716void Sema::CodeCompleteInitializer(Scope *S, DeclPtrTy D) {
2717 ValueDecl *VD = dyn_cast_or_null<ValueDecl>(D.getAs<Decl>());
2718 if (!VD) {
Douglas Gregor00c37ef2010-08-11 21:23:17 +00002719 CodeCompleteOrdinaryName(S, PCC_Expression);
Douglas Gregor7aa6b222010-05-30 01:49:25 +00002720 return;
2721 }
2722
2723 CodeCompleteExpression(S, VD->getType());
2724}
2725
2726void Sema::CodeCompleteReturn(Scope *S) {
2727 QualType ResultType;
2728 if (isa<BlockDecl>(CurContext)) {
2729 if (BlockScopeInfo *BSI = getCurBlock())
2730 ResultType = BSI->ReturnType;
2731 } else if (FunctionDecl *Function = dyn_cast<FunctionDecl>(CurContext))
2732 ResultType = Function->getResultType();
2733 else if (ObjCMethodDecl *Method = dyn_cast<ObjCMethodDecl>(CurContext))
2734 ResultType = Method->getResultType();
2735
2736 if (ResultType.isNull())
Douglas Gregor00c37ef2010-08-11 21:23:17 +00002737 CodeCompleteOrdinaryName(S, PCC_Expression);
Douglas Gregor7aa6b222010-05-30 01:49:25 +00002738 else
2739 CodeCompleteExpression(S, ResultType);
2740}
2741
2742void Sema::CodeCompleteAssignmentRHS(Scope *S, ExprTy *LHS) {
2743 if (LHS)
2744 CodeCompleteExpression(S, static_cast<Expr *>(LHS)->getType());
2745 else
Douglas Gregor00c37ef2010-08-11 21:23:17 +00002746 CodeCompleteOrdinaryName(S, PCC_Expression);
Douglas Gregor7aa6b222010-05-30 01:49:25 +00002747}
2748
Jeffrey Yasskinc76498d2010-04-08 16:38:48 +00002749void Sema::CodeCompleteQualifiedId(Scope *S, CXXScopeSpec &SS,
Douglas Gregor2436e712009-09-17 21:32:03 +00002750 bool EnteringContext) {
2751 if (!SS.getScopeRep() || !CodeCompleter)
2752 return;
2753
Douglas Gregor3545ff42009-09-21 16:56:56 +00002754 DeclContext *Ctx = computeDeclContext(SS, EnteringContext);
2755 if (!Ctx)
2756 return;
Douglas Gregor800f2f02009-12-11 18:28:39 +00002757
2758 // Try to instantiate any non-dependent declaration contexts before
2759 // we look in them.
John McCall0b66eb32010-05-01 00:40:08 +00002760 if (!isDependentScopeSpecifier(SS) && RequireCompleteDeclContext(SS, Ctx))
Douglas Gregor800f2f02009-12-11 18:28:39 +00002761 return;
2762
Douglas Gregor3545ff42009-09-21 16:56:56 +00002763 ResultBuilder Results(*this);
Douglas Gregor200c99d2010-01-14 03:35:48 +00002764 CodeCompletionDeclConsumer Consumer(Results, CurContext);
2765 LookupVisibleDecls(Ctx, LookupOrdinaryName, Consumer);
Douglas Gregor3545ff42009-09-21 16:56:56 +00002766
2767 // The "template" keyword can follow "::" in the grammar, but only
2768 // put it into the grammar if the nested-name-specifier is dependent.
2769 NestedNameSpecifier *NNS = (NestedNameSpecifier *)SS.getScopeRep();
2770 if (!Results.empty() && NNS->isDependent())
Douglas Gregor78a21012010-01-14 16:01:26 +00002771 Results.AddResult("template");
Douglas Gregor3545ff42009-09-21 16:56:56 +00002772
Douglas Gregor00c37ef2010-08-11 21:23:17 +00002773 HandleCodeCompleteResults(this, CodeCompleter,
2774 CodeCompletionContext::CCC_Other,
2775 Results.data(),Results.size());
Douglas Gregor2436e712009-09-17 21:32:03 +00002776}
Douglas Gregor7e90c6d2009-09-18 19:03:04 +00002777
2778void Sema::CodeCompleteUsing(Scope *S) {
2779 if (!CodeCompleter)
2780 return;
2781
Douglas Gregor3545ff42009-09-21 16:56:56 +00002782 ResultBuilder Results(*this, &ResultBuilder::IsNestedNameSpecifier);
Douglas Gregor64b12b52009-09-22 23:31:26 +00002783 Results.EnterNewScope();
Douglas Gregor3545ff42009-09-21 16:56:56 +00002784
2785 // If we aren't in class scope, we could see the "namespace" keyword.
2786 if (!S->isClassScope())
Douglas Gregor78a21012010-01-14 16:01:26 +00002787 Results.AddResult(CodeCompleteConsumer::Result("namespace"));
Douglas Gregor3545ff42009-09-21 16:56:56 +00002788
2789 // After "using", we can see anything that would start a
2790 // nested-name-specifier.
Douglas Gregora6e2edc2010-01-14 03:27:13 +00002791 CodeCompletionDeclConsumer Consumer(Results, CurContext);
Douglas Gregor39982192010-08-15 06:18:01 +00002792 LookupVisibleDecls(S, LookupOrdinaryName, Consumer,
2793 CodeCompleter->includeGlobals());
Douglas Gregor64b12b52009-09-22 23:31:26 +00002794 Results.ExitScope();
Douglas Gregor3545ff42009-09-21 16:56:56 +00002795
Douglas Gregor00c37ef2010-08-11 21:23:17 +00002796 HandleCodeCompleteResults(this, CodeCompleter,
2797 CodeCompletionContext::CCC_Other,
2798 Results.data(),Results.size());
Douglas Gregor7e90c6d2009-09-18 19:03:04 +00002799}
2800
2801void Sema::CodeCompleteUsingDirective(Scope *S) {
2802 if (!CodeCompleter)
2803 return;
2804
Douglas Gregor3545ff42009-09-21 16:56:56 +00002805 // After "using namespace", we expect to see a namespace name or namespace
2806 // alias.
2807 ResultBuilder Results(*this, &ResultBuilder::IsNamespaceOrAlias);
Douglas Gregor64b12b52009-09-22 23:31:26 +00002808 Results.EnterNewScope();
Douglas Gregora6e2edc2010-01-14 03:27:13 +00002809 CodeCompletionDeclConsumer Consumer(Results, CurContext);
Douglas Gregor39982192010-08-15 06:18:01 +00002810 LookupVisibleDecls(S, LookupOrdinaryName, Consumer,
2811 CodeCompleter->includeGlobals());
Douglas Gregor64b12b52009-09-22 23:31:26 +00002812 Results.ExitScope();
Douglas Gregor00c37ef2010-08-11 21:23:17 +00002813 HandleCodeCompleteResults(this, CodeCompleter,
Douglas Gregor39982192010-08-15 06:18:01 +00002814 CodeCompletionContext::CCC_Namespace,
Douglas Gregor00c37ef2010-08-11 21:23:17 +00002815 Results.data(),Results.size());
Douglas Gregor7e90c6d2009-09-18 19:03:04 +00002816}
2817
2818void Sema::CodeCompleteNamespaceDecl(Scope *S) {
2819 if (!CodeCompleter)
2820 return;
2821
Douglas Gregor3545ff42009-09-21 16:56:56 +00002822 ResultBuilder Results(*this, &ResultBuilder::IsNamespace);
2823 DeclContext *Ctx = (DeclContext *)S->getEntity();
2824 if (!S->getParent())
2825 Ctx = Context.getTranslationUnitDecl();
2826
2827 if (Ctx && Ctx->isFileContext()) {
2828 // We only want to see those namespaces that have already been defined
2829 // within this scope, because its likely that the user is creating an
2830 // extended namespace declaration. Keep track of the most recent
2831 // definition of each namespace.
2832 std::map<NamespaceDecl *, NamespaceDecl *> OrigToLatest;
2833 for (DeclContext::specific_decl_iterator<NamespaceDecl>
2834 NS(Ctx->decls_begin()), NSEnd(Ctx->decls_end());
2835 NS != NSEnd; ++NS)
2836 OrigToLatest[NS->getOriginalNamespace()] = *NS;
2837
2838 // Add the most recent definition (or extended definition) of each
2839 // namespace to the list of results.
Douglas Gregor64b12b52009-09-22 23:31:26 +00002840 Results.EnterNewScope();
Douglas Gregor3545ff42009-09-21 16:56:56 +00002841 for (std::map<NamespaceDecl *, NamespaceDecl *>::iterator
2842 NS = OrigToLatest.begin(), NSEnd = OrigToLatest.end();
2843 NS != NSEnd; ++NS)
Douglas Gregorfc59ce12010-01-14 16:14:35 +00002844 Results.AddResult(CodeCompleteConsumer::Result(NS->second, 0),
2845 CurContext, 0, false);
Douglas Gregor64b12b52009-09-22 23:31:26 +00002846 Results.ExitScope();
Douglas Gregor3545ff42009-09-21 16:56:56 +00002847 }
2848
Douglas Gregor00c37ef2010-08-11 21:23:17 +00002849 HandleCodeCompleteResults(this, CodeCompleter,
2850 CodeCompletionContext::CCC_Other,
2851 Results.data(),Results.size());
Douglas Gregor7e90c6d2009-09-18 19:03:04 +00002852}
2853
2854void Sema::CodeCompleteNamespaceAliasDecl(Scope *S) {
2855 if (!CodeCompleter)
2856 return;
2857
Douglas Gregor3545ff42009-09-21 16:56:56 +00002858 // After "namespace", we expect to see a namespace or alias.
2859 ResultBuilder Results(*this, &ResultBuilder::IsNamespaceOrAlias);
Douglas Gregora6e2edc2010-01-14 03:27:13 +00002860 CodeCompletionDeclConsumer Consumer(Results, CurContext);
Douglas Gregor39982192010-08-15 06:18:01 +00002861 LookupVisibleDecls(S, LookupOrdinaryName, Consumer,
2862 CodeCompleter->includeGlobals());
Douglas Gregor00c37ef2010-08-11 21:23:17 +00002863 HandleCodeCompleteResults(this, CodeCompleter,
Douglas Gregor39982192010-08-15 06:18:01 +00002864 CodeCompletionContext::CCC_Namespace,
Douglas Gregor00c37ef2010-08-11 21:23:17 +00002865 Results.data(),Results.size());
Douglas Gregor7e90c6d2009-09-18 19:03:04 +00002866}
2867
Douglas Gregorc811ede2009-09-18 20:05:18 +00002868void Sema::CodeCompleteOperatorName(Scope *S) {
2869 if (!CodeCompleter)
2870 return;
Douglas Gregor3545ff42009-09-21 16:56:56 +00002871
2872 typedef CodeCompleteConsumer::Result Result;
2873 ResultBuilder Results(*this, &ResultBuilder::IsType);
Douglas Gregor64b12b52009-09-22 23:31:26 +00002874 Results.EnterNewScope();
Douglas Gregorc811ede2009-09-18 20:05:18 +00002875
Douglas Gregor3545ff42009-09-21 16:56:56 +00002876 // Add the names of overloadable operators.
2877#define OVERLOADED_OPERATOR(Name,Spelling,Token,Unary,Binary,MemberOnly) \
2878 if (std::strcmp(Spelling, "?")) \
Douglas Gregor78a21012010-01-14 16:01:26 +00002879 Results.AddResult(Result(Spelling));
Douglas Gregor3545ff42009-09-21 16:56:56 +00002880#include "clang/Basic/OperatorKinds.def"
2881
2882 // Add any type names visible from the current scope
Douglas Gregor6ae4c522010-01-14 03:21:49 +00002883 Results.allowNestedNameSpecifiers();
Douglas Gregora6e2edc2010-01-14 03:27:13 +00002884 CodeCompletionDeclConsumer Consumer(Results, CurContext);
Douglas Gregor39982192010-08-15 06:18:01 +00002885 LookupVisibleDecls(S, LookupOrdinaryName, Consumer,
2886 CodeCompleter->includeGlobals());
Douglas Gregor3545ff42009-09-21 16:56:56 +00002887
2888 // Add any type specifiers
Douglas Gregorf98e6a22010-01-13 23:51:12 +00002889 AddTypeSpecifierResults(getLangOptions(), Results);
Douglas Gregor64b12b52009-09-22 23:31:26 +00002890 Results.ExitScope();
Douglas Gregor3545ff42009-09-21 16:56:56 +00002891
Douglas Gregor00c37ef2010-08-11 21:23:17 +00002892 HandleCodeCompleteResults(this, CodeCompleter,
Douglas Gregor39982192010-08-15 06:18:01 +00002893 CodeCompletionContext::CCC_Type,
Douglas Gregor00c37ef2010-08-11 21:23:17 +00002894 Results.data(),Results.size());
Douglas Gregorc811ede2009-09-18 20:05:18 +00002895}
Douglas Gregor7e90c6d2009-09-18 19:03:04 +00002896
Douglas Gregorf1934162010-01-13 21:24:21 +00002897// Macro that expands to @Keyword or Keyword, depending on whether NeedAt is
2898// true or false.
2899#define OBJC_AT_KEYWORD_NAME(NeedAt,Keyword) NeedAt? "@" #Keyword : #Keyword
Douglas Gregorf98e6a22010-01-13 23:51:12 +00002900static void AddObjCImplementationResults(const LangOptions &LangOpts,
Douglas Gregorf1934162010-01-13 21:24:21 +00002901 ResultBuilder &Results,
2902 bool NeedAt) {
2903 typedef CodeCompleteConsumer::Result Result;
2904 // Since we have an implementation, we can end it.
Douglas Gregor78a21012010-01-14 16:01:26 +00002905 Results.AddResult(Result(OBJC_AT_KEYWORD_NAME(NeedAt,end)));
Douglas Gregorf1934162010-01-13 21:24:21 +00002906
2907 CodeCompletionString *Pattern = 0;
2908 if (LangOpts.ObjC2) {
2909 // @dynamic
2910 Pattern = new CodeCompletionString;
2911 Pattern->AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt,dynamic));
2912 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
2913 Pattern->AddPlaceholderChunk("property");
Douglas Gregor78a21012010-01-14 16:01:26 +00002914 Results.AddResult(Result(Pattern));
Douglas Gregorf1934162010-01-13 21:24:21 +00002915
2916 // @synthesize
2917 Pattern = new CodeCompletionString;
2918 Pattern->AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt,synthesize));
2919 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
2920 Pattern->AddPlaceholderChunk("property");
Douglas Gregor78a21012010-01-14 16:01:26 +00002921 Results.AddResult(Result(Pattern));
Douglas Gregorf1934162010-01-13 21:24:21 +00002922 }
2923}
2924
Douglas Gregorf98e6a22010-01-13 23:51:12 +00002925static void AddObjCInterfaceResults(const LangOptions &LangOpts,
Douglas Gregorf1934162010-01-13 21:24:21 +00002926 ResultBuilder &Results,
2927 bool NeedAt) {
2928 typedef CodeCompleteConsumer::Result Result;
2929
2930 // Since we have an interface or protocol, we can end it.
Douglas Gregor78a21012010-01-14 16:01:26 +00002931 Results.AddResult(Result(OBJC_AT_KEYWORD_NAME(NeedAt,end)));
Douglas Gregorf1934162010-01-13 21:24:21 +00002932
2933 if (LangOpts.ObjC2) {
2934 // @property
Douglas Gregor78a21012010-01-14 16:01:26 +00002935 Results.AddResult(Result(OBJC_AT_KEYWORD_NAME(NeedAt,property)));
Douglas Gregorf1934162010-01-13 21:24:21 +00002936
2937 // @required
Douglas Gregor78a21012010-01-14 16:01:26 +00002938 Results.AddResult(Result(OBJC_AT_KEYWORD_NAME(NeedAt,required)));
Douglas Gregorf1934162010-01-13 21:24:21 +00002939
2940 // @optional
Douglas Gregor78a21012010-01-14 16:01:26 +00002941 Results.AddResult(Result(OBJC_AT_KEYWORD_NAME(NeedAt,optional)));
Douglas Gregorf1934162010-01-13 21:24:21 +00002942 }
2943}
2944
Douglas Gregorf98e6a22010-01-13 23:51:12 +00002945static void AddObjCTopLevelResults(ResultBuilder &Results, bool NeedAt) {
Douglas Gregorf1934162010-01-13 21:24:21 +00002946 typedef CodeCompleteConsumer::Result Result;
2947 CodeCompletionString *Pattern = 0;
2948
2949 // @class name ;
2950 Pattern = new CodeCompletionString;
2951 Pattern->AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt,class));
2952 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
Douglas Gregorf4c33342010-05-28 00:22:41 +00002953 Pattern->AddPlaceholderChunk("name");
Douglas Gregor78a21012010-01-14 16:01:26 +00002954 Results.AddResult(Result(Pattern));
Douglas Gregorf1934162010-01-13 21:24:21 +00002955
Douglas Gregorf4c33342010-05-28 00:22:41 +00002956 if (Results.includeCodePatterns()) {
2957 // @interface name
2958 // FIXME: Could introduce the whole pattern, including superclasses and
2959 // such.
2960 Pattern = new CodeCompletionString;
2961 Pattern->AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt,interface));
2962 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
2963 Pattern->AddPlaceholderChunk("class");
2964 Results.AddResult(Result(Pattern));
Douglas Gregorf1934162010-01-13 21:24:21 +00002965
Douglas Gregorf4c33342010-05-28 00:22:41 +00002966 // @protocol name
2967 Pattern = new CodeCompletionString;
2968 Pattern->AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt,protocol));
2969 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
2970 Pattern->AddPlaceholderChunk("protocol");
2971 Results.AddResult(Result(Pattern));
2972
2973 // @implementation name
2974 Pattern = new CodeCompletionString;
2975 Pattern->AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt,implementation));
2976 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
2977 Pattern->AddPlaceholderChunk("class");
2978 Results.AddResult(Result(Pattern));
2979 }
Douglas Gregorf1934162010-01-13 21:24:21 +00002980
2981 // @compatibility_alias name
2982 Pattern = new CodeCompletionString;
2983 Pattern->AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt,compatibility_alias));
2984 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
2985 Pattern->AddPlaceholderChunk("alias");
2986 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
2987 Pattern->AddPlaceholderChunk("class");
Douglas Gregor78a21012010-01-14 16:01:26 +00002988 Results.AddResult(Result(Pattern));
Douglas Gregorf1934162010-01-13 21:24:21 +00002989}
2990
Douglas Gregorf48706c2009-12-07 09:27:33 +00002991void Sema::CodeCompleteObjCAtDirective(Scope *S, DeclPtrTy ObjCImpDecl,
2992 bool InInterface) {
2993 typedef CodeCompleteConsumer::Result Result;
2994 ResultBuilder Results(*this);
2995 Results.EnterNewScope();
Douglas Gregorf1934162010-01-13 21:24:21 +00002996 if (ObjCImpDecl)
Douglas Gregorf98e6a22010-01-13 23:51:12 +00002997 AddObjCImplementationResults(getLangOptions(), Results, false);
Douglas Gregorf1934162010-01-13 21:24:21 +00002998 else if (InInterface)
Douglas Gregorf98e6a22010-01-13 23:51:12 +00002999 AddObjCInterfaceResults(getLangOptions(), Results, false);
Douglas Gregorf1934162010-01-13 21:24:21 +00003000 else
Douglas Gregorf98e6a22010-01-13 23:51:12 +00003001 AddObjCTopLevelResults(Results, false);
Douglas Gregorf48706c2009-12-07 09:27:33 +00003002 Results.ExitScope();
Douglas Gregor00c37ef2010-08-11 21:23:17 +00003003 HandleCodeCompleteResults(this, CodeCompleter,
3004 CodeCompletionContext::CCC_Other,
3005 Results.data(),Results.size());
Douglas Gregorf48706c2009-12-07 09:27:33 +00003006}
3007
Douglas Gregorf98e6a22010-01-13 23:51:12 +00003008static void AddObjCExpressionResults(ResultBuilder &Results, bool NeedAt) {
Douglas Gregorbc7c5e42009-12-07 09:51:25 +00003009 typedef CodeCompleteConsumer::Result Result;
3010 CodeCompletionString *Pattern = 0;
3011
3012 // @encode ( type-name )
3013 Pattern = new CodeCompletionString;
Douglas Gregorf1934162010-01-13 21:24:21 +00003014 Pattern->AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt,encode));
Douglas Gregorbc7c5e42009-12-07 09:51:25 +00003015 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
3016 Pattern->AddPlaceholderChunk("type-name");
3017 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
Douglas Gregor78a21012010-01-14 16:01:26 +00003018 Results.AddResult(Result(Pattern));
Douglas Gregorbc7c5e42009-12-07 09:51:25 +00003019
3020 // @protocol ( protocol-name )
3021 Pattern = new CodeCompletionString;
Douglas Gregorf1934162010-01-13 21:24:21 +00003022 Pattern->AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt,protocol));
Douglas Gregorbc7c5e42009-12-07 09:51:25 +00003023 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
3024 Pattern->AddPlaceholderChunk("protocol-name");
3025 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
Douglas Gregor78a21012010-01-14 16:01:26 +00003026 Results.AddResult(Result(Pattern));
Douglas Gregorbc7c5e42009-12-07 09:51:25 +00003027
3028 // @selector ( selector )
3029 Pattern = new CodeCompletionString;
Douglas Gregorf1934162010-01-13 21:24:21 +00003030 Pattern->AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt,selector));
Douglas Gregorbc7c5e42009-12-07 09:51:25 +00003031 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
3032 Pattern->AddPlaceholderChunk("selector");
3033 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
Douglas Gregor78a21012010-01-14 16:01:26 +00003034 Results.AddResult(Result(Pattern));
Douglas Gregorbc7c5e42009-12-07 09:51:25 +00003035}
3036
Douglas Gregorf98e6a22010-01-13 23:51:12 +00003037static void AddObjCStatementResults(ResultBuilder &Results, bool NeedAt) {
Douglas Gregorbc7c5e42009-12-07 09:51:25 +00003038 typedef CodeCompleteConsumer::Result Result;
Douglas Gregorbc7c5e42009-12-07 09:51:25 +00003039 CodeCompletionString *Pattern = 0;
Douglas Gregorf1934162010-01-13 21:24:21 +00003040
Douglas Gregorf4c33342010-05-28 00:22:41 +00003041 if (Results.includeCodePatterns()) {
3042 // @try { statements } @catch ( declaration ) { statements } @finally
3043 // { statements }
3044 Pattern = new CodeCompletionString;
3045 Pattern->AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt,try));
3046 Pattern->AddChunk(CodeCompletionString::CK_LeftBrace);
3047 Pattern->AddPlaceholderChunk("statements");
3048 Pattern->AddChunk(CodeCompletionString::CK_RightBrace);
3049 Pattern->AddTextChunk("@catch");
3050 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
3051 Pattern->AddPlaceholderChunk("parameter");
3052 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
3053 Pattern->AddChunk(CodeCompletionString::CK_LeftBrace);
3054 Pattern->AddPlaceholderChunk("statements");
3055 Pattern->AddChunk(CodeCompletionString::CK_RightBrace);
3056 Pattern->AddTextChunk("@finally");
3057 Pattern->AddChunk(CodeCompletionString::CK_LeftBrace);
3058 Pattern->AddPlaceholderChunk("statements");
3059 Pattern->AddChunk(CodeCompletionString::CK_RightBrace);
3060 Results.AddResult(Result(Pattern));
3061 }
Douglas Gregorf1934162010-01-13 21:24:21 +00003062
Douglas Gregorbc7c5e42009-12-07 09:51:25 +00003063 // @throw
3064 Pattern = new CodeCompletionString;
Douglas Gregorf1934162010-01-13 21:24:21 +00003065 Pattern->AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt,throw));
Douglas Gregor6a803932010-01-12 06:38:28 +00003066 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
Douglas Gregorbc7c5e42009-12-07 09:51:25 +00003067 Pattern->AddPlaceholderChunk("expression");
Douglas Gregor78a21012010-01-14 16:01:26 +00003068 Results.AddResult(Result(Pattern));
Douglas Gregorf1934162010-01-13 21:24:21 +00003069
Douglas Gregorf4c33342010-05-28 00:22:41 +00003070 if (Results.includeCodePatterns()) {
3071 // @synchronized ( expression ) { statements }
3072 Pattern = new CodeCompletionString;
3073 Pattern->AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt,synchronized));
3074 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
3075 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
3076 Pattern->AddPlaceholderChunk("expression");
3077 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
3078 Pattern->AddChunk(CodeCompletionString::CK_LeftBrace);
3079 Pattern->AddPlaceholderChunk("statements");
3080 Pattern->AddChunk(CodeCompletionString::CK_RightBrace);
3081 Results.AddResult(Result(Pattern));
3082 }
Douglas Gregorf1934162010-01-13 21:24:21 +00003083}
Douglas Gregorbc7c5e42009-12-07 09:51:25 +00003084
Douglas Gregorf98e6a22010-01-13 23:51:12 +00003085static void AddObjCVisibilityResults(const LangOptions &LangOpts,
Douglas Gregor48d46252010-01-13 21:54:15 +00003086 ResultBuilder &Results,
3087 bool NeedAt) {
Douglas Gregorf1934162010-01-13 21:24:21 +00003088 typedef CodeCompleteConsumer::Result Result;
Douglas Gregor78a21012010-01-14 16:01:26 +00003089 Results.AddResult(Result(OBJC_AT_KEYWORD_NAME(NeedAt,private)));
3090 Results.AddResult(Result(OBJC_AT_KEYWORD_NAME(NeedAt,protected)));
3091 Results.AddResult(Result(OBJC_AT_KEYWORD_NAME(NeedAt,public)));
Douglas Gregor48d46252010-01-13 21:54:15 +00003092 if (LangOpts.ObjC2)
Douglas Gregor78a21012010-01-14 16:01:26 +00003093 Results.AddResult(Result(OBJC_AT_KEYWORD_NAME(NeedAt,package)));
Douglas Gregor48d46252010-01-13 21:54:15 +00003094}
3095
3096void Sema::CodeCompleteObjCAtVisibility(Scope *S) {
3097 ResultBuilder Results(*this);
3098 Results.EnterNewScope();
Douglas Gregorf98e6a22010-01-13 23:51:12 +00003099 AddObjCVisibilityResults(getLangOptions(), Results, false);
Douglas Gregor48d46252010-01-13 21:54:15 +00003100 Results.ExitScope();
Douglas Gregor00c37ef2010-08-11 21:23:17 +00003101 HandleCodeCompleteResults(this, CodeCompleter,
3102 CodeCompletionContext::CCC_Other,
3103 Results.data(),Results.size());
Douglas Gregor48d46252010-01-13 21:54:15 +00003104}
3105
3106void Sema::CodeCompleteObjCAtStatement(Scope *S) {
Douglas Gregorf1934162010-01-13 21:24:21 +00003107 ResultBuilder Results(*this);
3108 Results.EnterNewScope();
Douglas Gregorf98e6a22010-01-13 23:51:12 +00003109 AddObjCStatementResults(Results, false);
3110 AddObjCExpressionResults(Results, false);
Douglas Gregorbc7c5e42009-12-07 09:51:25 +00003111 Results.ExitScope();
Douglas Gregor00c37ef2010-08-11 21:23:17 +00003112 HandleCodeCompleteResults(this, CodeCompleter,
3113 CodeCompletionContext::CCC_Other,
3114 Results.data(),Results.size());
Douglas Gregorbc7c5e42009-12-07 09:51:25 +00003115}
3116
3117void Sema::CodeCompleteObjCAtExpression(Scope *S) {
3118 ResultBuilder Results(*this);
3119 Results.EnterNewScope();
Douglas Gregorf98e6a22010-01-13 23:51:12 +00003120 AddObjCExpressionResults(Results, false);
Douglas Gregorbc7c5e42009-12-07 09:51:25 +00003121 Results.ExitScope();
Douglas Gregor00c37ef2010-08-11 21:23:17 +00003122 HandleCodeCompleteResults(this, CodeCompleter,
3123 CodeCompletionContext::CCC_Other,
3124 Results.data(),Results.size());
Douglas Gregorbc7c5e42009-12-07 09:51:25 +00003125}
3126
Douglas Gregore6078da2009-11-19 00:14:45 +00003127/// \brief Determine whether the addition of the given flag to an Objective-C
3128/// property's attributes will cause a conflict.
3129static bool ObjCPropertyFlagConflicts(unsigned Attributes, unsigned NewFlag) {
3130 // Check if we've already added this flag.
3131 if (Attributes & NewFlag)
3132 return true;
3133
3134 Attributes |= NewFlag;
3135
3136 // Check for collisions with "readonly".
3137 if ((Attributes & ObjCDeclSpec::DQ_PR_readonly) &&
3138 (Attributes & (ObjCDeclSpec::DQ_PR_readwrite |
3139 ObjCDeclSpec::DQ_PR_assign |
3140 ObjCDeclSpec::DQ_PR_copy |
3141 ObjCDeclSpec::DQ_PR_retain)))
3142 return true;
3143
3144 // Check for more than one of { assign, copy, retain }.
3145 unsigned AssignCopyRetMask = Attributes & (ObjCDeclSpec::DQ_PR_assign |
3146 ObjCDeclSpec::DQ_PR_copy |
3147 ObjCDeclSpec::DQ_PR_retain);
3148 if (AssignCopyRetMask &&
3149 AssignCopyRetMask != ObjCDeclSpec::DQ_PR_assign &&
3150 AssignCopyRetMask != ObjCDeclSpec::DQ_PR_copy &&
3151 AssignCopyRetMask != ObjCDeclSpec::DQ_PR_retain)
3152 return true;
3153
3154 return false;
3155}
3156
Douglas Gregor36029f42009-11-18 23:08:07 +00003157void Sema::CodeCompleteObjCPropertyFlags(Scope *S, ObjCDeclSpec &ODS) {
Steve Naroff936354c2009-10-08 21:55:05 +00003158 if (!CodeCompleter)
3159 return;
Douglas Gregor1b605f72009-11-19 01:08:35 +00003160
Steve Naroff936354c2009-10-08 21:55:05 +00003161 unsigned Attributes = ODS.getPropertyAttributes();
3162
3163 typedef CodeCompleteConsumer::Result Result;
3164 ResultBuilder Results(*this);
3165 Results.EnterNewScope();
Douglas Gregore6078da2009-11-19 00:14:45 +00003166 if (!ObjCPropertyFlagConflicts(Attributes, ObjCDeclSpec::DQ_PR_readonly))
Douglas Gregor78a21012010-01-14 16:01:26 +00003167 Results.AddResult(CodeCompleteConsumer::Result("readonly"));
Douglas Gregore6078da2009-11-19 00:14:45 +00003168 if (!ObjCPropertyFlagConflicts(Attributes, ObjCDeclSpec::DQ_PR_assign))
Douglas Gregor78a21012010-01-14 16:01:26 +00003169 Results.AddResult(CodeCompleteConsumer::Result("assign"));
Douglas Gregore6078da2009-11-19 00:14:45 +00003170 if (!ObjCPropertyFlagConflicts(Attributes, ObjCDeclSpec::DQ_PR_readwrite))
Douglas Gregor78a21012010-01-14 16:01:26 +00003171 Results.AddResult(CodeCompleteConsumer::Result("readwrite"));
Douglas Gregore6078da2009-11-19 00:14:45 +00003172 if (!ObjCPropertyFlagConflicts(Attributes, ObjCDeclSpec::DQ_PR_retain))
Douglas Gregor78a21012010-01-14 16:01:26 +00003173 Results.AddResult(CodeCompleteConsumer::Result("retain"));
Douglas Gregore6078da2009-11-19 00:14:45 +00003174 if (!ObjCPropertyFlagConflicts(Attributes, ObjCDeclSpec::DQ_PR_copy))
Douglas Gregor78a21012010-01-14 16:01:26 +00003175 Results.AddResult(CodeCompleteConsumer::Result("copy"));
Douglas Gregore6078da2009-11-19 00:14:45 +00003176 if (!ObjCPropertyFlagConflicts(Attributes, ObjCDeclSpec::DQ_PR_nonatomic))
Douglas Gregor78a21012010-01-14 16:01:26 +00003177 Results.AddResult(CodeCompleteConsumer::Result("nonatomic"));
Douglas Gregore6078da2009-11-19 00:14:45 +00003178 if (!ObjCPropertyFlagConflicts(Attributes, ObjCDeclSpec::DQ_PR_setter)) {
Douglas Gregor45f83ee2009-11-19 00:01:57 +00003179 CodeCompletionString *Setter = new CodeCompletionString;
3180 Setter->AddTypedTextChunk("setter");
3181 Setter->AddTextChunk(" = ");
3182 Setter->AddPlaceholderChunk("method");
Douglas Gregor78a21012010-01-14 16:01:26 +00003183 Results.AddResult(CodeCompleteConsumer::Result(Setter));
Douglas Gregor45f83ee2009-11-19 00:01:57 +00003184 }
Douglas Gregore6078da2009-11-19 00:14:45 +00003185 if (!ObjCPropertyFlagConflicts(Attributes, ObjCDeclSpec::DQ_PR_getter)) {
Douglas Gregor45f83ee2009-11-19 00:01:57 +00003186 CodeCompletionString *Getter = new CodeCompletionString;
3187 Getter->AddTypedTextChunk("getter");
3188 Getter->AddTextChunk(" = ");
3189 Getter->AddPlaceholderChunk("method");
Douglas Gregor78a21012010-01-14 16:01:26 +00003190 Results.AddResult(CodeCompleteConsumer::Result(Getter));
Douglas Gregor45f83ee2009-11-19 00:01:57 +00003191 }
Steve Naroff936354c2009-10-08 21:55:05 +00003192 Results.ExitScope();
Douglas Gregor00c37ef2010-08-11 21:23:17 +00003193 HandleCodeCompleteResults(this, CodeCompleter,
3194 CodeCompletionContext::CCC_Other,
3195 Results.data(),Results.size());
Steve Naroff936354c2009-10-08 21:55:05 +00003196}
Steve Naroffeae65032009-11-07 02:08:14 +00003197
Douglas Gregorc8537c52009-11-19 07:41:15 +00003198/// \brief Descripts the kind of Objective-C method that we want to find
3199/// via code completion.
3200enum ObjCMethodKind {
3201 MK_Any, //< Any kind of method, provided it means other specified criteria.
3202 MK_ZeroArgSelector, //< Zero-argument (unary) selector.
3203 MK_OneArgSelector //< One-argument selector.
3204};
3205
3206static bool isAcceptableObjCMethod(ObjCMethodDecl *Method,
3207 ObjCMethodKind WantKind,
3208 IdentifierInfo **SelIdents,
3209 unsigned NumSelIdents) {
3210 Selector Sel = Method->getSelector();
3211 if (NumSelIdents > Sel.getNumArgs())
3212 return false;
3213
3214 switch (WantKind) {
3215 case MK_Any: break;
3216 case MK_ZeroArgSelector: return Sel.isUnarySelector();
3217 case MK_OneArgSelector: return Sel.getNumArgs() == 1;
3218 }
3219
3220 for (unsigned I = 0; I != NumSelIdents; ++I)
3221 if (SelIdents[I] != Sel.getIdentifierInfoForSlot(I))
3222 return false;
3223
3224 return true;
3225}
3226
Douglas Gregorbab2b3c2009-11-17 23:22:23 +00003227/// \brief Add all of the Objective-C methods in the given Objective-C
3228/// container to the set of results.
3229///
3230/// The container will be a class, protocol, category, or implementation of
3231/// any of the above. This mether will recurse to include methods from
3232/// the superclasses of classes along with their categories, protocols, and
3233/// implementations.
3234///
3235/// \param Container the container in which we'll look to find methods.
3236///
3237/// \param WantInstance whether to add instance methods (only); if false, this
3238/// routine will add factory methods (only).
3239///
3240/// \param CurContext the context in which we're performing the lookup that
3241/// finds methods.
3242///
3243/// \param Results the structure into which we'll add results.
3244static void AddObjCMethods(ObjCContainerDecl *Container,
3245 bool WantInstanceMethods,
Douglas Gregorc8537c52009-11-19 07:41:15 +00003246 ObjCMethodKind WantKind,
Douglas Gregor1b605f72009-11-19 01:08:35 +00003247 IdentifierInfo **SelIdents,
3248 unsigned NumSelIdents,
Douglas Gregorbab2b3c2009-11-17 23:22:23 +00003249 DeclContext *CurContext,
3250 ResultBuilder &Results) {
3251 typedef CodeCompleteConsumer::Result Result;
3252 for (ObjCContainerDecl::method_iterator M = Container->meth_begin(),
3253 MEnd = Container->meth_end();
3254 M != MEnd; ++M) {
Douglas Gregor1b605f72009-11-19 01:08:35 +00003255 if ((*M)->isInstanceMethod() == WantInstanceMethods) {
3256 // Check whether the selector identifiers we've been given are a
3257 // subset of the identifiers for this particular method.
Douglas Gregorc8537c52009-11-19 07:41:15 +00003258 if (!isAcceptableObjCMethod(*M, WantKind, SelIdents, NumSelIdents))
Douglas Gregor1b605f72009-11-19 01:08:35 +00003259 continue;
Douglas Gregorc8537c52009-11-19 07:41:15 +00003260
Douglas Gregor1b605f72009-11-19 01:08:35 +00003261 Result R = Result(*M, 0);
3262 R.StartParameter = NumSelIdents;
Douglas Gregorc8537c52009-11-19 07:41:15 +00003263 R.AllParametersAreInformative = (WantKind != MK_Any);
Douglas Gregor1b605f72009-11-19 01:08:35 +00003264 Results.MaybeAddResult(R, CurContext);
3265 }
Douglas Gregorbab2b3c2009-11-17 23:22:23 +00003266 }
3267
3268 ObjCInterfaceDecl *IFace = dyn_cast<ObjCInterfaceDecl>(Container);
3269 if (!IFace)
3270 return;
3271
3272 // Add methods in protocols.
3273 const ObjCList<ObjCProtocolDecl> &Protocols= IFace->getReferencedProtocols();
3274 for (ObjCList<ObjCProtocolDecl>::iterator I = Protocols.begin(),
3275 E = Protocols.end();
3276 I != E; ++I)
Douglas Gregorc8537c52009-11-19 07:41:15 +00003277 AddObjCMethods(*I, WantInstanceMethods, WantKind, SelIdents, NumSelIdents,
Douglas Gregor1b605f72009-11-19 01:08:35 +00003278 CurContext, Results);
Douglas Gregorbab2b3c2009-11-17 23:22:23 +00003279
3280 // Add methods in categories.
3281 for (ObjCCategoryDecl *CatDecl = IFace->getCategoryList(); CatDecl;
3282 CatDecl = CatDecl->getNextClassCategory()) {
Douglas Gregorc8537c52009-11-19 07:41:15 +00003283 AddObjCMethods(CatDecl, WantInstanceMethods, WantKind, SelIdents,
3284 NumSelIdents, CurContext, Results);
Douglas Gregorbab2b3c2009-11-17 23:22:23 +00003285
3286 // Add a categories protocol methods.
3287 const ObjCList<ObjCProtocolDecl> &Protocols
3288 = CatDecl->getReferencedProtocols();
3289 for (ObjCList<ObjCProtocolDecl>::iterator I = Protocols.begin(),
3290 E = Protocols.end();
3291 I != E; ++I)
Douglas Gregorc8537c52009-11-19 07:41:15 +00003292 AddObjCMethods(*I, WantInstanceMethods, WantKind, SelIdents,
3293 NumSelIdents, CurContext, Results);
Douglas Gregorbab2b3c2009-11-17 23:22:23 +00003294
3295 // Add methods in category implementations.
3296 if (ObjCCategoryImplDecl *Impl = CatDecl->getImplementation())
Douglas Gregorc8537c52009-11-19 07:41:15 +00003297 AddObjCMethods(Impl, WantInstanceMethods, WantKind, SelIdents,
3298 NumSelIdents, CurContext, Results);
Douglas Gregorbab2b3c2009-11-17 23:22:23 +00003299 }
3300
3301 // Add methods in superclass.
3302 if (IFace->getSuperClass())
Douglas Gregorc8537c52009-11-19 07:41:15 +00003303 AddObjCMethods(IFace->getSuperClass(), WantInstanceMethods, WantKind,
3304 SelIdents, NumSelIdents, CurContext, Results);
Douglas Gregorbab2b3c2009-11-17 23:22:23 +00003305
3306 // Add methods in our implementation, if any.
3307 if (ObjCImplementationDecl *Impl = IFace->getImplementation())
Douglas Gregorc8537c52009-11-19 07:41:15 +00003308 AddObjCMethods(Impl, WantInstanceMethods, WantKind, SelIdents,
3309 NumSelIdents, CurContext, Results);
3310}
3311
3312
3313void Sema::CodeCompleteObjCPropertyGetter(Scope *S, DeclPtrTy ClassDecl,
3314 DeclPtrTy *Methods,
3315 unsigned NumMethods) {
3316 typedef CodeCompleteConsumer::Result Result;
3317
3318 // Try to find the interface where getters might live.
3319 ObjCInterfaceDecl *Class
3320 = dyn_cast_or_null<ObjCInterfaceDecl>(ClassDecl.getAs<Decl>());
3321 if (!Class) {
3322 if (ObjCCategoryDecl *Category
3323 = dyn_cast_or_null<ObjCCategoryDecl>(ClassDecl.getAs<Decl>()))
3324 Class = Category->getClassInterface();
3325
3326 if (!Class)
3327 return;
3328 }
3329
3330 // Find all of the potential getters.
3331 ResultBuilder Results(*this);
3332 Results.EnterNewScope();
3333
3334 // FIXME: We need to do this because Objective-C methods don't get
3335 // pushed into DeclContexts early enough. Argh!
3336 for (unsigned I = 0; I != NumMethods; ++I) {
3337 if (ObjCMethodDecl *Method
3338 = dyn_cast_or_null<ObjCMethodDecl>(Methods[I].getAs<Decl>()))
3339 if (Method->isInstanceMethod() &&
3340 isAcceptableObjCMethod(Method, MK_ZeroArgSelector, 0, 0)) {
3341 Result R = Result(Method, 0);
3342 R.AllParametersAreInformative = true;
3343 Results.MaybeAddResult(R, CurContext);
3344 }
3345 }
3346
3347 AddObjCMethods(Class, true, MK_ZeroArgSelector, 0, 0, CurContext, Results);
3348 Results.ExitScope();
Douglas Gregor00c37ef2010-08-11 21:23:17 +00003349 HandleCodeCompleteResults(this, CodeCompleter,
3350 CodeCompletionContext::CCC_Other,
3351 Results.data(),Results.size());
Douglas Gregorc8537c52009-11-19 07:41:15 +00003352}
3353
3354void Sema::CodeCompleteObjCPropertySetter(Scope *S, DeclPtrTy ObjCImplDecl,
3355 DeclPtrTy *Methods,
3356 unsigned NumMethods) {
3357 typedef CodeCompleteConsumer::Result Result;
3358
3359 // Try to find the interface where setters might live.
3360 ObjCInterfaceDecl *Class
3361 = dyn_cast_or_null<ObjCInterfaceDecl>(ObjCImplDecl.getAs<Decl>());
3362 if (!Class) {
3363 if (ObjCCategoryDecl *Category
3364 = dyn_cast_or_null<ObjCCategoryDecl>(ObjCImplDecl.getAs<Decl>()))
3365 Class = Category->getClassInterface();
3366
3367 if (!Class)
3368 return;
3369 }
3370
3371 // Find all of the potential getters.
3372 ResultBuilder Results(*this);
3373 Results.EnterNewScope();
3374
3375 // FIXME: We need to do this because Objective-C methods don't get
3376 // pushed into DeclContexts early enough. Argh!
3377 for (unsigned I = 0; I != NumMethods; ++I) {
3378 if (ObjCMethodDecl *Method
3379 = dyn_cast_or_null<ObjCMethodDecl>(Methods[I].getAs<Decl>()))
3380 if (Method->isInstanceMethod() &&
3381 isAcceptableObjCMethod(Method, MK_OneArgSelector, 0, 0)) {
3382 Result R = Result(Method, 0);
3383 R.AllParametersAreInformative = true;
3384 Results.MaybeAddResult(R, CurContext);
3385 }
3386 }
3387
3388 AddObjCMethods(Class, true, MK_OneArgSelector, 0, 0, CurContext, Results);
3389
3390 Results.ExitScope();
Douglas Gregor00c37ef2010-08-11 21:23:17 +00003391 HandleCodeCompleteResults(this, CodeCompleter,
3392 CodeCompletionContext::CCC_Other,
3393 Results.data(),Results.size());
Douglas Gregorbab2b3c2009-11-17 23:22:23 +00003394}
3395
Douglas Gregor9d2ddb22010-04-06 19:22:33 +00003396/// \brief When we have an expression with type "id", we may assume
3397/// that it has some more-specific class type based on knowledge of
3398/// common uses of Objective-C. This routine returns that class type,
3399/// or NULL if no better result could be determined.
3400static ObjCInterfaceDecl *GetAssumedMessageSendExprType(Expr *E) {
3401 ObjCMessageExpr *Msg = dyn_cast<ObjCMessageExpr>(E);
3402 if (!Msg)
3403 return 0;
3404
3405 Selector Sel = Msg->getSelector();
3406 if (Sel.isNull())
3407 return 0;
3408
3409 IdentifierInfo *Id = Sel.getIdentifierInfoForSlot(0);
3410 if (!Id)
3411 return 0;
3412
3413 ObjCMethodDecl *Method = Msg->getMethodDecl();
3414 if (!Method)
3415 return 0;
3416
3417 // Determine the class that we're sending the message to.
Douglas Gregor9a129192010-04-21 00:45:42 +00003418 ObjCInterfaceDecl *IFace = 0;
3419 switch (Msg->getReceiverKind()) {
3420 case ObjCMessageExpr::Class:
John McCall8b07ec22010-05-15 11:32:37 +00003421 if (const ObjCObjectType *ObjType
3422 = Msg->getClassReceiver()->getAs<ObjCObjectType>())
3423 IFace = ObjType->getInterface();
Douglas Gregor9a129192010-04-21 00:45:42 +00003424 break;
3425
3426 case ObjCMessageExpr::Instance: {
3427 QualType T = Msg->getInstanceReceiver()->getType();
3428 if (const ObjCObjectPointerType *Ptr = T->getAs<ObjCObjectPointerType>())
3429 IFace = Ptr->getInterfaceDecl();
3430 break;
3431 }
3432
3433 case ObjCMessageExpr::SuperInstance:
3434 case ObjCMessageExpr::SuperClass:
3435 break;
Douglas Gregor9d2ddb22010-04-06 19:22:33 +00003436 }
3437
3438 if (!IFace)
3439 return 0;
3440
3441 ObjCInterfaceDecl *Super = IFace->getSuperClass();
3442 if (Method->isInstanceMethod())
3443 return llvm::StringSwitch<ObjCInterfaceDecl *>(Id->getName())
3444 .Case("retain", IFace)
3445 .Case("autorelease", IFace)
3446 .Case("copy", IFace)
3447 .Case("copyWithZone", IFace)
3448 .Case("mutableCopy", IFace)
3449 .Case("mutableCopyWithZone", IFace)
3450 .Case("awakeFromCoder", IFace)
3451 .Case("replacementObjectFromCoder", IFace)
3452 .Case("class", IFace)
3453 .Case("classForCoder", IFace)
3454 .Case("superclass", Super)
3455 .Default(0);
3456
3457 return llvm::StringSwitch<ObjCInterfaceDecl *>(Id->getName())
3458 .Case("new", IFace)
3459 .Case("alloc", IFace)
3460 .Case("allocWithZone", IFace)
3461 .Case("class", IFace)
3462 .Case("superclass", Super)
3463 .Default(0);
3464}
3465
Douglas Gregora817a192010-05-27 23:06:34 +00003466void Sema::CodeCompleteObjCMessageReceiver(Scope *S) {
3467 typedef CodeCompleteConsumer::Result Result;
3468 ResultBuilder Results(*this);
3469
3470 // Find anything that looks like it could be a message receiver.
3471 Results.setFilter(&ResultBuilder::IsObjCMessageReceiver);
3472 CodeCompletionDeclConsumer Consumer(Results, CurContext);
3473 Results.EnterNewScope();
Douglas Gregor39982192010-08-15 06:18:01 +00003474 LookupVisibleDecls(S, LookupOrdinaryName, Consumer,
3475 CodeCompleter->includeGlobals());
Douglas Gregora817a192010-05-27 23:06:34 +00003476
3477 // If we are in an Objective-C method inside a class that has a superclass,
3478 // add "super" as an option.
3479 if (ObjCMethodDecl *Method = getCurMethodDecl())
3480 if (ObjCInterfaceDecl *Iface = Method->getClassInterface())
3481 if (Iface->getSuperClass())
3482 Results.AddResult(Result("super"));
3483
3484 Results.ExitScope();
3485
3486 if (CodeCompleter->includeMacros())
3487 AddMacroResults(PP, Results);
Douglas Gregor00c37ef2010-08-11 21:23:17 +00003488 HandleCodeCompleteResults(this, CodeCompleter,
3489 CodeCompletionContext::CCC_ObjCMessageReceiver,
3490 Results.data(), Results.size());
Douglas Gregora817a192010-05-27 23:06:34 +00003491
3492}
3493
Douglas Gregor0c78ad92010-04-21 19:57:20 +00003494void Sema::CodeCompleteObjCSuperMessage(Scope *S, SourceLocation SuperLoc,
3495 IdentifierInfo **SelIdents,
3496 unsigned NumSelIdents) {
3497 ObjCInterfaceDecl *CDecl = 0;
3498 if (ObjCMethodDecl *CurMethod = getCurMethodDecl()) {
3499 // Figure out which interface we're in.
3500 CDecl = CurMethod->getClassInterface();
3501 if (!CDecl)
3502 return;
3503
3504 // Find the superclass of this class.
3505 CDecl = CDecl->getSuperClass();
3506 if (!CDecl)
3507 return;
3508
3509 if (CurMethod->isInstanceMethod()) {
3510 // We are inside an instance method, which means that the message
3511 // send [super ...] is actually calling an instance method on the
3512 // current object. Build the super expression and handle this like
3513 // an instance method.
3514 QualType SuperTy = Context.getObjCInterfaceType(CDecl);
3515 SuperTy = Context.getObjCObjectPointerType(SuperTy);
3516 OwningExprResult Super
3517 = Owned(new (Context) ObjCSuperExpr(SuperLoc, SuperTy));
3518 return CodeCompleteObjCInstanceMessage(S, (Expr *)Super.get(),
3519 SelIdents, NumSelIdents);
3520 }
3521
3522 // Fall through to send to the superclass in CDecl.
3523 } else {
3524 // "super" may be the name of a type or variable. Figure out which
3525 // it is.
3526 IdentifierInfo *Super = &Context.Idents.get("super");
3527 NamedDecl *ND = LookupSingleName(S, Super, SuperLoc,
3528 LookupOrdinaryName);
3529 if ((CDecl = dyn_cast_or_null<ObjCInterfaceDecl>(ND))) {
3530 // "super" names an interface. Use it.
3531 } else if (TypeDecl *TD = dyn_cast_or_null<TypeDecl>(ND)) {
John McCall8b07ec22010-05-15 11:32:37 +00003532 if (const ObjCObjectType *Iface
3533 = Context.getTypeDeclType(TD)->getAs<ObjCObjectType>())
3534 CDecl = Iface->getInterface();
Douglas Gregor0c78ad92010-04-21 19:57:20 +00003535 } else if (ND && isa<UnresolvedUsingTypenameDecl>(ND)) {
3536 // "super" names an unresolved type; we can't be more specific.
3537 } else {
3538 // Assume that "super" names some kind of value and parse that way.
3539 CXXScopeSpec SS;
3540 UnqualifiedId id;
3541 id.setIdentifier(Super, SuperLoc);
3542 OwningExprResult SuperExpr = ActOnIdExpression(S, SS, id, false, false);
3543 return CodeCompleteObjCInstanceMessage(S, (Expr *)SuperExpr.get(),
3544 SelIdents, NumSelIdents);
3545 }
3546
3547 // Fall through
3548 }
3549
3550 TypeTy *Receiver = 0;
3551 if (CDecl)
3552 Receiver = Context.getObjCInterfaceType(CDecl).getAsOpaquePtr();
3553 return CodeCompleteObjCClassMessage(S, Receiver, SelIdents,
3554 NumSelIdents);
3555}
3556
3557void Sema::CodeCompleteObjCClassMessage(Scope *S, TypeTy *Receiver,
Douglas Gregor1b605f72009-11-19 01:08:35 +00003558 IdentifierInfo **SelIdents,
3559 unsigned NumSelIdents) {
Steve Naroffeae65032009-11-07 02:08:14 +00003560 typedef CodeCompleteConsumer::Result Result;
Douglas Gregor8ce33212009-11-17 17:59:40 +00003561 ObjCInterfaceDecl *CDecl = 0;
3562
Douglas Gregor8ce33212009-11-17 17:59:40 +00003563 // If the given name refers to an interface type, retrieve the
3564 // corresponding declaration.
Douglas Gregor0c78ad92010-04-21 19:57:20 +00003565 if (Receiver) {
3566 QualType T = GetTypeFromParser(Receiver, 0);
3567 if (!T.isNull())
John McCall8b07ec22010-05-15 11:32:37 +00003568 if (const ObjCObjectType *Interface = T->getAs<ObjCObjectType>())
3569 CDecl = Interface->getInterface();
Douglas Gregor8ce33212009-11-17 17:59:40 +00003570 }
3571
Douglas Gregorbab2b3c2009-11-17 23:22:23 +00003572 // Add all of the factory methods in this Objective-C class, its protocols,
3573 // superclasses, categories, implementation, etc.
Steve Naroffeae65032009-11-07 02:08:14 +00003574 ResultBuilder Results(*this);
3575 Results.EnterNewScope();
Douglas Gregor6285f752010-04-06 16:40:00 +00003576
3577 if (CDecl)
3578 AddObjCMethods(CDecl, false, MK_Any, SelIdents, NumSelIdents, CurContext,
3579 Results);
Douglas Gregor0c78ad92010-04-21 19:57:20 +00003580 else {
Douglas Gregor6285f752010-04-06 16:40:00 +00003581 // We're messaging "id" as a type; provide all class/factory methods.
3582
Douglas Gregord720daf2010-04-06 17:30:22 +00003583 // If we have an external source, load the entire class method
Sebastian Redld44cd6a2010-08-18 23:57:06 +00003584 // pool from the AST file.
Douglas Gregord720daf2010-04-06 17:30:22 +00003585 if (ExternalSource) {
John McCall75b960e2010-06-01 09:23:16 +00003586 for (uint32_t I = 0, N = ExternalSource->GetNumExternalSelectors();
3587 I != N; ++I) {
3588 Selector Sel = ExternalSource->GetExternalSelector(I);
Sebastian Redl75d8a322010-08-02 23:18:59 +00003589 if (Sel.isNull() || MethodPool.count(Sel))
Douglas Gregord720daf2010-04-06 17:30:22 +00003590 continue;
3591
Sebastian Redl75d8a322010-08-02 23:18:59 +00003592 ReadMethodPool(Sel);
Douglas Gregord720daf2010-04-06 17:30:22 +00003593 }
3594 }
3595
Sebastian Redl75d8a322010-08-02 23:18:59 +00003596 for (GlobalMethodPool::iterator M = MethodPool.begin(),
3597 MEnd = MethodPool.end();
3598 M != MEnd; ++M) {
3599 for (ObjCMethodList *MethList = &M->second.second;
3600 MethList && MethList->Method;
Douglas Gregor6285f752010-04-06 16:40:00 +00003601 MethList = MethList->Next) {
3602 if (!isAcceptableObjCMethod(MethList->Method, MK_Any, SelIdents,
3603 NumSelIdents))
3604 continue;
3605
3606 Result R(MethList->Method, 0);
3607 R.StartParameter = NumSelIdents;
3608 R.AllParametersAreInformative = false;
3609 Results.MaybeAddResult(R, CurContext);
3610 }
3611 }
3612 }
3613
Steve Naroffeae65032009-11-07 02:08:14 +00003614 Results.ExitScope();
Douglas Gregor00c37ef2010-08-11 21:23:17 +00003615 HandleCodeCompleteResults(this, CodeCompleter,
3616 CodeCompletionContext::CCC_Other,
3617 Results.data(),Results.size());
Steve Naroffeae65032009-11-07 02:08:14 +00003618}
3619
Douglas Gregor1b605f72009-11-19 01:08:35 +00003620void Sema::CodeCompleteObjCInstanceMessage(Scope *S, ExprTy *Receiver,
3621 IdentifierInfo **SelIdents,
3622 unsigned NumSelIdents) {
Steve Naroffeae65032009-11-07 02:08:14 +00003623 typedef CodeCompleteConsumer::Result Result;
Steve Naroffeae65032009-11-07 02:08:14 +00003624
3625 Expr *RecExpr = static_cast<Expr *>(Receiver);
Steve Naroffeae65032009-11-07 02:08:14 +00003626
Douglas Gregorbab2b3c2009-11-17 23:22:23 +00003627 // If necessary, apply function/array conversion to the receiver.
3628 // C99 6.7.5.3p[7,8].
Douglas Gregorb92a1562010-02-03 00:27:59 +00003629 DefaultFunctionArrayLvalueConversion(RecExpr);
Douglas Gregorbab2b3c2009-11-17 23:22:23 +00003630 QualType ReceiverType = RecExpr->getType();
Steve Naroffeae65032009-11-07 02:08:14 +00003631
Douglas Gregorbab2b3c2009-11-17 23:22:23 +00003632 // Build the set of methods we can see.
3633 ResultBuilder Results(*this);
3634 Results.EnterNewScope();
Douglas Gregor9d2ddb22010-04-06 19:22:33 +00003635
3636 // If we're messaging an expression with type "id" or "Class", check
3637 // whether we know something special about the receiver that allows
3638 // us to assume a more-specific receiver type.
3639 if (ReceiverType->isObjCIdType() || ReceiverType->isObjCClassType())
3640 if (ObjCInterfaceDecl *IFace = GetAssumedMessageSendExprType(RecExpr))
3641 ReceiverType = Context.getObjCObjectPointerType(
3642 Context.getObjCInterfaceType(IFace));
Douglas Gregorbab2b3c2009-11-17 23:22:23 +00003643
Douglas Gregora3329fa2009-11-18 00:06:18 +00003644 // Handle messages to Class. This really isn't a message to an instance
3645 // method, so we treat it the same way we would treat a message send to a
3646 // class method.
3647 if (ReceiverType->isObjCClassType() ||
3648 ReceiverType->isObjCQualifiedClassType()) {
3649 if (ObjCMethodDecl *CurMethod = getCurMethodDecl()) {
3650 if (ObjCInterfaceDecl *ClassDecl = CurMethod->getClassInterface())
Douglas Gregorc8537c52009-11-19 07:41:15 +00003651 AddObjCMethods(ClassDecl, false, MK_Any, SelIdents, NumSelIdents,
3652 CurContext, Results);
Douglas Gregora3329fa2009-11-18 00:06:18 +00003653 }
3654 }
3655 // Handle messages to a qualified ID ("id<foo>").
3656 else if (const ObjCObjectPointerType *QualID
3657 = ReceiverType->getAsObjCQualifiedIdType()) {
3658 // Search protocols for instance methods.
3659 for (ObjCObjectPointerType::qual_iterator I = QualID->qual_begin(),
3660 E = QualID->qual_end();
3661 I != E; ++I)
Douglas Gregorc8537c52009-11-19 07:41:15 +00003662 AddObjCMethods(*I, true, MK_Any, SelIdents, NumSelIdents, CurContext,
3663 Results);
Douglas Gregora3329fa2009-11-18 00:06:18 +00003664 }
3665 // Handle messages to a pointer to interface type.
3666 else if (const ObjCObjectPointerType *IFacePtr
3667 = ReceiverType->getAsObjCInterfacePointerType()) {
3668 // Search the class, its superclasses, etc., for instance methods.
Douglas Gregorc8537c52009-11-19 07:41:15 +00003669 AddObjCMethods(IFacePtr->getInterfaceDecl(), true, MK_Any, SelIdents,
3670 NumSelIdents, CurContext, Results);
Douglas Gregora3329fa2009-11-18 00:06:18 +00003671
3672 // Search protocols for instance methods.
3673 for (ObjCObjectPointerType::qual_iterator I = IFacePtr->qual_begin(),
3674 E = IFacePtr->qual_end();
3675 I != E; ++I)
Douglas Gregorc8537c52009-11-19 07:41:15 +00003676 AddObjCMethods(*I, true, MK_Any, SelIdents, NumSelIdents, CurContext,
3677 Results);
Douglas Gregora3329fa2009-11-18 00:06:18 +00003678 }
Douglas Gregor6285f752010-04-06 16:40:00 +00003679 // Handle messages to "id".
3680 else if (ReceiverType->isObjCIdType()) {
Douglas Gregord720daf2010-04-06 17:30:22 +00003681 // We're messaging "id", so provide all instance methods we know
3682 // about as code-completion results.
3683
3684 // If we have an external source, load the entire class method
Sebastian Redld44cd6a2010-08-18 23:57:06 +00003685 // pool from the AST file.
Douglas Gregord720daf2010-04-06 17:30:22 +00003686 if (ExternalSource) {
John McCall75b960e2010-06-01 09:23:16 +00003687 for (uint32_t I = 0, N = ExternalSource->GetNumExternalSelectors();
3688 I != N; ++I) {
3689 Selector Sel = ExternalSource->GetExternalSelector(I);
Sebastian Redl75d8a322010-08-02 23:18:59 +00003690 if (Sel.isNull() || MethodPool.count(Sel))
Douglas Gregord720daf2010-04-06 17:30:22 +00003691 continue;
3692
Sebastian Redl75d8a322010-08-02 23:18:59 +00003693 ReadMethodPool(Sel);
Douglas Gregord720daf2010-04-06 17:30:22 +00003694 }
3695 }
3696
Sebastian Redl75d8a322010-08-02 23:18:59 +00003697 for (GlobalMethodPool::iterator M = MethodPool.begin(),
3698 MEnd = MethodPool.end();
3699 M != MEnd; ++M) {
3700 for (ObjCMethodList *MethList = &M->second.first;
3701 MethList && MethList->Method;
Douglas Gregor6285f752010-04-06 16:40:00 +00003702 MethList = MethList->Next) {
3703 if (!isAcceptableObjCMethod(MethList->Method, MK_Any, SelIdents,
3704 NumSelIdents))
3705 continue;
3706
3707 Result R(MethList->Method, 0);
3708 R.StartParameter = NumSelIdents;
3709 R.AllParametersAreInformative = false;
3710 Results.MaybeAddResult(R, CurContext);
3711 }
3712 }
3713 }
3714
Steve Naroffeae65032009-11-07 02:08:14 +00003715 Results.ExitScope();
Douglas Gregor00c37ef2010-08-11 21:23:17 +00003716 HandleCodeCompleteResults(this, CodeCompleter,
3717 CodeCompletionContext::CCC_Other,
3718 Results.data(),Results.size());
Steve Naroffeae65032009-11-07 02:08:14 +00003719}
Douglas Gregorbaf69612009-11-18 04:19:12 +00003720
3721/// \brief Add all of the protocol declarations that we find in the given
3722/// (translation unit) context.
3723static void AddProtocolResults(DeclContext *Ctx, DeclContext *CurContext,
Douglas Gregor5b4671c2009-11-18 04:49:41 +00003724 bool OnlyForwardDeclarations,
Douglas Gregorbaf69612009-11-18 04:19:12 +00003725 ResultBuilder &Results) {
3726 typedef CodeCompleteConsumer::Result Result;
3727
3728 for (DeclContext::decl_iterator D = Ctx->decls_begin(),
3729 DEnd = Ctx->decls_end();
3730 D != DEnd; ++D) {
3731 // Record any protocols we find.
3732 if (ObjCProtocolDecl *Proto = dyn_cast<ObjCProtocolDecl>(*D))
Douglas Gregor5b4671c2009-11-18 04:49:41 +00003733 if (!OnlyForwardDeclarations || Proto->isForwardDecl())
Douglas Gregorfc59ce12010-01-14 16:14:35 +00003734 Results.AddResult(Result(Proto, 0), CurContext, 0, false);
Douglas Gregorbaf69612009-11-18 04:19:12 +00003735
3736 // Record any forward-declared protocols we find.
3737 if (ObjCForwardProtocolDecl *Forward
3738 = dyn_cast<ObjCForwardProtocolDecl>(*D)) {
3739 for (ObjCForwardProtocolDecl::protocol_iterator
3740 P = Forward->protocol_begin(),
3741 PEnd = Forward->protocol_end();
3742 P != PEnd; ++P)
Douglas Gregor5b4671c2009-11-18 04:49:41 +00003743 if (!OnlyForwardDeclarations || (*P)->isForwardDecl())
Douglas Gregorfc59ce12010-01-14 16:14:35 +00003744 Results.AddResult(Result(*P, 0), CurContext, 0, false);
Douglas Gregorbaf69612009-11-18 04:19:12 +00003745 }
3746 }
3747}
3748
3749void Sema::CodeCompleteObjCProtocolReferences(IdentifierLocPair *Protocols,
3750 unsigned NumProtocols) {
3751 ResultBuilder Results(*this);
3752 Results.EnterNewScope();
3753
3754 // Tell the result set to ignore all of the protocols we have
3755 // already seen.
3756 for (unsigned I = 0; I != NumProtocols; ++I)
Douglas Gregorb2ccf012010-04-15 22:33:43 +00003757 if (ObjCProtocolDecl *Protocol = LookupProtocol(Protocols[I].first,
3758 Protocols[I].second))
Douglas Gregorbaf69612009-11-18 04:19:12 +00003759 Results.Ignore(Protocol);
3760
3761 // Add all protocols.
Douglas Gregor5b4671c2009-11-18 04:49:41 +00003762 AddProtocolResults(Context.getTranslationUnitDecl(), CurContext, false,
3763 Results);
3764
3765 Results.ExitScope();
Douglas Gregor00c37ef2010-08-11 21:23:17 +00003766 HandleCodeCompleteResults(this, CodeCompleter,
3767 CodeCompletionContext::CCC_ObjCProtocolName,
3768 Results.data(),Results.size());
Douglas Gregor5b4671c2009-11-18 04:49:41 +00003769}
3770
3771void Sema::CodeCompleteObjCProtocolDecl(Scope *) {
3772 ResultBuilder Results(*this);
3773 Results.EnterNewScope();
3774
3775 // Add all protocols.
3776 AddProtocolResults(Context.getTranslationUnitDecl(), CurContext, true,
3777 Results);
Douglas Gregorbaf69612009-11-18 04:19:12 +00003778
3779 Results.ExitScope();
Douglas Gregor00c37ef2010-08-11 21:23:17 +00003780 HandleCodeCompleteResults(this, CodeCompleter,
3781 CodeCompletionContext::CCC_ObjCProtocolName,
3782 Results.data(),Results.size());
Douglas Gregorbaf69612009-11-18 04:19:12 +00003783}
Douglas Gregor49c22a72009-11-18 16:26:39 +00003784
3785/// \brief Add all of the Objective-C interface declarations that we find in
3786/// the given (translation unit) context.
3787static void AddInterfaceResults(DeclContext *Ctx, DeclContext *CurContext,
3788 bool OnlyForwardDeclarations,
3789 bool OnlyUnimplemented,
3790 ResultBuilder &Results) {
3791 typedef CodeCompleteConsumer::Result Result;
3792
3793 for (DeclContext::decl_iterator D = Ctx->decls_begin(),
3794 DEnd = Ctx->decls_end();
3795 D != DEnd; ++D) {
Douglas Gregor1c283312010-08-11 12:19:30 +00003796 // Record any interfaces we find.
3797 if (ObjCInterfaceDecl *Class = dyn_cast<ObjCInterfaceDecl>(*D))
3798 if ((!OnlyForwardDeclarations || Class->isForwardDecl()) &&
3799 (!OnlyUnimplemented || !Class->getImplementation()))
3800 Results.AddResult(Result(Class, 0), CurContext, 0, false);
Douglas Gregor49c22a72009-11-18 16:26:39 +00003801
3802 // Record any forward-declared interfaces we find.
3803 if (ObjCClassDecl *Forward = dyn_cast<ObjCClassDecl>(*D)) {
3804 for (ObjCClassDecl::iterator C = Forward->begin(), CEnd = Forward->end();
Douglas Gregor1c283312010-08-11 12:19:30 +00003805 C != CEnd; ++C)
3806 if ((!OnlyForwardDeclarations || C->getInterface()->isForwardDecl()) &&
3807 (!OnlyUnimplemented || !C->getInterface()->getImplementation()))
3808 Results.AddResult(Result(C->getInterface(), 0), CurContext,
Douglas Gregorfc59ce12010-01-14 16:14:35 +00003809 0, false);
Douglas Gregor49c22a72009-11-18 16:26:39 +00003810 }
3811 }
3812}
3813
3814void Sema::CodeCompleteObjCInterfaceDecl(Scope *S) {
3815 ResultBuilder Results(*this);
3816 Results.EnterNewScope();
3817
3818 // Add all classes.
3819 AddInterfaceResults(Context.getTranslationUnitDecl(), CurContext, true,
3820 false, Results);
3821
3822 Results.ExitScope();
Douglas Gregor00c37ef2010-08-11 21:23:17 +00003823 HandleCodeCompleteResults(this, CodeCompleter,
3824 CodeCompletionContext::CCC_Other,
3825 Results.data(),Results.size());
Douglas Gregor49c22a72009-11-18 16:26:39 +00003826}
3827
Douglas Gregorb2ccf012010-04-15 22:33:43 +00003828void Sema::CodeCompleteObjCSuperclass(Scope *S, IdentifierInfo *ClassName,
3829 SourceLocation ClassNameLoc) {
Douglas Gregor49c22a72009-11-18 16:26:39 +00003830 ResultBuilder Results(*this);
3831 Results.EnterNewScope();
3832
3833 // Make sure that we ignore the class we're currently defining.
3834 NamedDecl *CurClass
Douglas Gregorb2ccf012010-04-15 22:33:43 +00003835 = LookupSingleName(TUScope, ClassName, ClassNameLoc, LookupOrdinaryName);
Douglas Gregor5d34fd32009-11-18 19:08:43 +00003836 if (CurClass && isa<ObjCInterfaceDecl>(CurClass))
Douglas Gregor49c22a72009-11-18 16:26:39 +00003837 Results.Ignore(CurClass);
3838
3839 // Add all classes.
3840 AddInterfaceResults(Context.getTranslationUnitDecl(), CurContext, false,
3841 false, Results);
3842
3843 Results.ExitScope();
Douglas Gregor00c37ef2010-08-11 21:23:17 +00003844 HandleCodeCompleteResults(this, CodeCompleter,
3845 CodeCompletionContext::CCC_Other,
3846 Results.data(),Results.size());
Douglas Gregor49c22a72009-11-18 16:26:39 +00003847}
3848
3849void Sema::CodeCompleteObjCImplementationDecl(Scope *S) {
3850 ResultBuilder Results(*this);
3851 Results.EnterNewScope();
3852
3853 // Add all unimplemented classes.
3854 AddInterfaceResults(Context.getTranslationUnitDecl(), CurContext, false,
3855 true, Results);
3856
3857 Results.ExitScope();
Douglas Gregor00c37ef2010-08-11 21:23:17 +00003858 HandleCodeCompleteResults(this, CodeCompleter,
3859 CodeCompletionContext::CCC_Other,
3860 Results.data(),Results.size());
Douglas Gregor49c22a72009-11-18 16:26:39 +00003861}
Douglas Gregor5d34fd32009-11-18 19:08:43 +00003862
3863void Sema::CodeCompleteObjCInterfaceCategory(Scope *S,
Douglas Gregorb2ccf012010-04-15 22:33:43 +00003864 IdentifierInfo *ClassName,
3865 SourceLocation ClassNameLoc) {
Douglas Gregor5d34fd32009-11-18 19:08:43 +00003866 typedef CodeCompleteConsumer::Result Result;
3867
3868 ResultBuilder Results(*this);
3869
3870 // Ignore any categories we find that have already been implemented by this
3871 // interface.
3872 llvm::SmallPtrSet<IdentifierInfo *, 16> CategoryNames;
3873 NamedDecl *CurClass
Douglas Gregorb2ccf012010-04-15 22:33:43 +00003874 = LookupSingleName(TUScope, ClassName, ClassNameLoc, LookupOrdinaryName);
Douglas Gregor5d34fd32009-11-18 19:08:43 +00003875 if (ObjCInterfaceDecl *Class = dyn_cast_or_null<ObjCInterfaceDecl>(CurClass))
3876 for (ObjCCategoryDecl *Category = Class->getCategoryList(); Category;
3877 Category = Category->getNextClassCategory())
3878 CategoryNames.insert(Category->getIdentifier());
3879
3880 // Add all of the categories we know about.
3881 Results.EnterNewScope();
3882 TranslationUnitDecl *TU = Context.getTranslationUnitDecl();
3883 for (DeclContext::decl_iterator D = TU->decls_begin(),
3884 DEnd = TU->decls_end();
3885 D != DEnd; ++D)
3886 if (ObjCCategoryDecl *Category = dyn_cast<ObjCCategoryDecl>(*D))
3887 if (CategoryNames.insert(Category->getIdentifier()))
Douglas Gregorfc59ce12010-01-14 16:14:35 +00003888 Results.AddResult(Result(Category, 0), CurContext, 0, false);
Douglas Gregor5d34fd32009-11-18 19:08:43 +00003889 Results.ExitScope();
3890
Douglas Gregor00c37ef2010-08-11 21:23:17 +00003891 HandleCodeCompleteResults(this, CodeCompleter,
3892 CodeCompletionContext::CCC_Other,
3893 Results.data(),Results.size());
Douglas Gregor5d34fd32009-11-18 19:08:43 +00003894}
3895
3896void Sema::CodeCompleteObjCImplementationCategory(Scope *S,
Douglas Gregorb2ccf012010-04-15 22:33:43 +00003897 IdentifierInfo *ClassName,
3898 SourceLocation ClassNameLoc) {
Douglas Gregor5d34fd32009-11-18 19:08:43 +00003899 typedef CodeCompleteConsumer::Result Result;
3900
3901 // Find the corresponding interface. If we couldn't find the interface, the
3902 // program itself is ill-formed. However, we'll try to be helpful still by
3903 // providing the list of all of the categories we know about.
3904 NamedDecl *CurClass
Douglas Gregorb2ccf012010-04-15 22:33:43 +00003905 = LookupSingleName(TUScope, ClassName, ClassNameLoc, LookupOrdinaryName);
Douglas Gregor5d34fd32009-11-18 19:08:43 +00003906 ObjCInterfaceDecl *Class = dyn_cast_or_null<ObjCInterfaceDecl>(CurClass);
3907 if (!Class)
Douglas Gregorb2ccf012010-04-15 22:33:43 +00003908 return CodeCompleteObjCInterfaceCategory(S, ClassName, ClassNameLoc);
Douglas Gregor5d34fd32009-11-18 19:08:43 +00003909
3910 ResultBuilder Results(*this);
3911
3912 // Add all of the categories that have have corresponding interface
3913 // declarations in this class and any of its superclasses, except for
3914 // already-implemented categories in the class itself.
3915 llvm::SmallPtrSet<IdentifierInfo *, 16> CategoryNames;
3916 Results.EnterNewScope();
3917 bool IgnoreImplemented = true;
3918 while (Class) {
3919 for (ObjCCategoryDecl *Category = Class->getCategoryList(); Category;
3920 Category = Category->getNextClassCategory())
3921 if ((!IgnoreImplemented || !Category->getImplementation()) &&
3922 CategoryNames.insert(Category->getIdentifier()))
Douglas Gregorfc59ce12010-01-14 16:14:35 +00003923 Results.AddResult(Result(Category, 0), CurContext, 0, false);
Douglas Gregor5d34fd32009-11-18 19:08:43 +00003924
3925 Class = Class->getSuperClass();
3926 IgnoreImplemented = false;
3927 }
3928 Results.ExitScope();
3929
Douglas Gregor00c37ef2010-08-11 21:23:17 +00003930 HandleCodeCompleteResults(this, CodeCompleter,
3931 CodeCompletionContext::CCC_Other,
3932 Results.data(),Results.size());
Douglas Gregor5d34fd32009-11-18 19:08:43 +00003933}
Douglas Gregor5d649882009-11-18 22:32:06 +00003934
Douglas Gregor52e78bd2009-11-18 22:56:13 +00003935void Sema::CodeCompleteObjCPropertyDefinition(Scope *S, DeclPtrTy ObjCImpDecl) {
Douglas Gregor5d649882009-11-18 22:32:06 +00003936 typedef CodeCompleteConsumer::Result Result;
3937 ResultBuilder Results(*this);
3938
3939 // Figure out where this @synthesize lives.
3940 ObjCContainerDecl *Container
3941 = dyn_cast_or_null<ObjCContainerDecl>(ObjCImpDecl.getAs<Decl>());
3942 if (!Container ||
3943 (!isa<ObjCImplementationDecl>(Container) &&
3944 !isa<ObjCCategoryImplDecl>(Container)))
3945 return;
3946
3947 // Ignore any properties that have already been implemented.
3948 for (DeclContext::decl_iterator D = Container->decls_begin(),
3949 DEnd = Container->decls_end();
3950 D != DEnd; ++D)
3951 if (ObjCPropertyImplDecl *PropertyImpl = dyn_cast<ObjCPropertyImplDecl>(*D))
3952 Results.Ignore(PropertyImpl->getPropertyDecl());
3953
3954 // Add any properties that we find.
3955 Results.EnterNewScope();
3956 if (ObjCImplementationDecl *ClassImpl
3957 = dyn_cast<ObjCImplementationDecl>(Container))
3958 AddObjCProperties(ClassImpl->getClassInterface(), false, CurContext,
3959 Results);
3960 else
3961 AddObjCProperties(cast<ObjCCategoryImplDecl>(Container)->getCategoryDecl(),
3962 false, CurContext, Results);
3963 Results.ExitScope();
3964
Douglas Gregor00c37ef2010-08-11 21:23:17 +00003965 HandleCodeCompleteResults(this, CodeCompleter,
3966 CodeCompletionContext::CCC_Other,
3967 Results.data(),Results.size());
Douglas Gregor5d649882009-11-18 22:32:06 +00003968}
3969
3970void Sema::CodeCompleteObjCPropertySynthesizeIvar(Scope *S,
3971 IdentifierInfo *PropertyName,
3972 DeclPtrTy ObjCImpDecl) {
3973 typedef CodeCompleteConsumer::Result Result;
3974 ResultBuilder Results(*this);
3975
3976 // Figure out where this @synthesize lives.
3977 ObjCContainerDecl *Container
3978 = dyn_cast_or_null<ObjCContainerDecl>(ObjCImpDecl.getAs<Decl>());
3979 if (!Container ||
3980 (!isa<ObjCImplementationDecl>(Container) &&
3981 !isa<ObjCCategoryImplDecl>(Container)))
3982 return;
3983
3984 // Figure out which interface we're looking into.
3985 ObjCInterfaceDecl *Class = 0;
3986 if (ObjCImplementationDecl *ClassImpl
3987 = dyn_cast<ObjCImplementationDecl>(Container))
3988 Class = ClassImpl->getClassInterface();
3989 else
3990 Class = cast<ObjCCategoryImplDecl>(Container)->getCategoryDecl()
3991 ->getClassInterface();
3992
3993 // Add all of the instance variables in this class and its superclasses.
3994 Results.EnterNewScope();
3995 for(; Class; Class = Class->getSuperClass()) {
3996 // FIXME: We could screen the type of each ivar for compatibility with
3997 // the property, but is that being too paternal?
3998 for (ObjCInterfaceDecl::ivar_iterator IVar = Class->ivar_begin(),
3999 IVarEnd = Class->ivar_end();
4000 IVar != IVarEnd; ++IVar)
Douglas Gregorfc59ce12010-01-14 16:14:35 +00004001 Results.AddResult(Result(*IVar, 0), CurContext, 0, false);
Douglas Gregor5d649882009-11-18 22:32:06 +00004002 }
4003 Results.ExitScope();
4004
Douglas Gregor00c37ef2010-08-11 21:23:17 +00004005 HandleCodeCompleteResults(this, CodeCompleter,
4006 CodeCompletionContext::CCC_Other,
4007 Results.data(),Results.size());
Douglas Gregor5d649882009-11-18 22:32:06 +00004008}
Douglas Gregor636a61e2010-04-07 00:21:17 +00004009
4010typedef llvm::DenseMap<Selector, ObjCMethodDecl *> KnownMethodsMap;
4011
4012/// \brief Find all of the methods that reside in the given container
4013/// (and its superclasses, protocols, etc.) that meet the given
4014/// criteria. Insert those methods into the map of known methods,
4015/// indexed by selector so they can be easily found.
4016static void FindImplementableMethods(ASTContext &Context,
4017 ObjCContainerDecl *Container,
4018 bool WantInstanceMethods,
4019 QualType ReturnType,
4020 bool IsInImplementation,
4021 KnownMethodsMap &KnownMethods) {
4022 if (ObjCInterfaceDecl *IFace = dyn_cast<ObjCInterfaceDecl>(Container)) {
4023 // Recurse into protocols.
4024 const ObjCList<ObjCProtocolDecl> &Protocols
4025 = IFace->getReferencedProtocols();
4026 for (ObjCList<ObjCProtocolDecl>::iterator I = Protocols.begin(),
4027 E = Protocols.end();
4028 I != E; ++I)
4029 FindImplementableMethods(Context, *I, WantInstanceMethods, ReturnType,
4030 IsInImplementation, KnownMethods);
4031
4032 // If we're not in the implementation of a class, also visit the
4033 // superclass.
4034 if (!IsInImplementation && IFace->getSuperClass())
4035 FindImplementableMethods(Context, IFace->getSuperClass(),
4036 WantInstanceMethods, ReturnType,
4037 IsInImplementation, KnownMethods);
4038
4039 // Add methods from any class extensions (but not from categories;
4040 // those should go into category implementations).
Fariborz Jahanian3bf0ded2010-06-22 23:20:40 +00004041 for (const ObjCCategoryDecl *Cat = IFace->getFirstClassExtension(); Cat;
4042 Cat = Cat->getNextClassExtension())
4043 FindImplementableMethods(Context, const_cast<ObjCCategoryDecl*>(Cat),
4044 WantInstanceMethods, ReturnType,
Douglas Gregor636a61e2010-04-07 00:21:17 +00004045 IsInImplementation, KnownMethods);
Douglas Gregor636a61e2010-04-07 00:21:17 +00004046 }
4047
4048 if (ObjCCategoryDecl *Category = dyn_cast<ObjCCategoryDecl>(Container)) {
4049 // Recurse into protocols.
4050 const ObjCList<ObjCProtocolDecl> &Protocols
4051 = Category->getReferencedProtocols();
4052 for (ObjCList<ObjCProtocolDecl>::iterator I = Protocols.begin(),
4053 E = Protocols.end();
4054 I != E; ++I)
4055 FindImplementableMethods(Context, *I, WantInstanceMethods, ReturnType,
4056 IsInImplementation, KnownMethods);
4057 }
4058
4059 if (ObjCProtocolDecl *Protocol = dyn_cast<ObjCProtocolDecl>(Container)) {
4060 // Recurse into protocols.
4061 const ObjCList<ObjCProtocolDecl> &Protocols
4062 = Protocol->getReferencedProtocols();
4063 for (ObjCList<ObjCProtocolDecl>::iterator I = Protocols.begin(),
4064 E = Protocols.end();
4065 I != E; ++I)
4066 FindImplementableMethods(Context, *I, WantInstanceMethods, ReturnType,
4067 IsInImplementation, KnownMethods);
4068 }
4069
4070 // Add methods in this container. This operation occurs last because
4071 // we want the methods from this container to override any methods
4072 // we've previously seen with the same selector.
4073 for (ObjCContainerDecl::method_iterator M = Container->meth_begin(),
4074 MEnd = Container->meth_end();
4075 M != MEnd; ++M) {
4076 if ((*M)->isInstanceMethod() == WantInstanceMethods) {
4077 if (!ReturnType.isNull() &&
4078 !Context.hasSameUnqualifiedType(ReturnType, (*M)->getResultType()))
4079 continue;
4080
4081 KnownMethods[(*M)->getSelector()] = *M;
4082 }
4083 }
4084}
4085
4086void Sema::CodeCompleteObjCMethodDecl(Scope *S,
4087 bool IsInstanceMethod,
4088 TypeTy *ReturnTy,
4089 DeclPtrTy IDecl) {
4090 // Determine the return type of the method we're declaring, if
4091 // provided.
4092 QualType ReturnType = GetTypeFromParser(ReturnTy);
4093
4094 // Determine where we should start searching for methods, and where we
4095 ObjCContainerDecl *SearchDecl = 0, *CurrentDecl = 0;
4096 bool IsInImplementation = false;
4097 if (Decl *D = IDecl.getAs<Decl>()) {
4098 if (ObjCImplementationDecl *Impl = dyn_cast<ObjCImplementationDecl>(D)) {
4099 SearchDecl = Impl->getClassInterface();
4100 CurrentDecl = Impl;
4101 IsInImplementation = true;
4102 } else if (ObjCCategoryImplDecl *CatImpl
4103 = dyn_cast<ObjCCategoryImplDecl>(D)) {
4104 SearchDecl = CatImpl->getCategoryDecl();
4105 CurrentDecl = CatImpl;
4106 IsInImplementation = true;
4107 } else {
4108 SearchDecl = dyn_cast<ObjCContainerDecl>(D);
4109 CurrentDecl = SearchDecl;
4110 }
4111 }
4112
4113 if (!SearchDecl && S) {
4114 if (DeclContext *DC = static_cast<DeclContext *>(S->getEntity())) {
4115 SearchDecl = dyn_cast<ObjCContainerDecl>(DC);
4116 CurrentDecl = SearchDecl;
4117 }
4118 }
4119
4120 if (!SearchDecl || !CurrentDecl) {
Douglas Gregor00c37ef2010-08-11 21:23:17 +00004121 HandleCodeCompleteResults(this, CodeCompleter,
4122 CodeCompletionContext::CCC_Other,
4123 0, 0);
Douglas Gregor636a61e2010-04-07 00:21:17 +00004124 return;
4125 }
4126
4127 // Find all of the methods that we could declare/implement here.
4128 KnownMethodsMap KnownMethods;
4129 FindImplementableMethods(Context, SearchDecl, IsInstanceMethod,
4130 ReturnType, IsInImplementation, KnownMethods);
4131
4132 // Erase any methods that have already been declared or
4133 // implemented here.
4134 for (ObjCContainerDecl::method_iterator M = CurrentDecl->meth_begin(),
4135 MEnd = CurrentDecl->meth_end();
4136 M != MEnd; ++M) {
4137 if ((*M)->isInstanceMethod() != IsInstanceMethod)
4138 continue;
4139
4140 KnownMethodsMap::iterator Pos = KnownMethods.find((*M)->getSelector());
4141 if (Pos != KnownMethods.end())
4142 KnownMethods.erase(Pos);
4143 }
4144
4145 // Add declarations or definitions for each of the known methods.
4146 typedef CodeCompleteConsumer::Result Result;
4147 ResultBuilder Results(*this);
4148 Results.EnterNewScope();
4149 PrintingPolicy Policy(Context.PrintingPolicy);
4150 Policy.AnonymousTagLocations = false;
4151 for (KnownMethodsMap::iterator M = KnownMethods.begin(),
4152 MEnd = KnownMethods.end();
4153 M != MEnd; ++M) {
4154 ObjCMethodDecl *Method = M->second;
4155 CodeCompletionString *Pattern = new CodeCompletionString;
4156
4157 // If the result type was not already provided, add it to the
4158 // pattern as (type).
4159 if (ReturnType.isNull()) {
4160 std::string TypeStr;
4161 Method->getResultType().getAsStringInternal(TypeStr, Policy);
4162 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
4163 Pattern->AddTextChunk(TypeStr);
4164 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
4165 }
4166
4167 Selector Sel = Method->getSelector();
4168
4169 // Add the first part of the selector to the pattern.
4170 Pattern->AddTypedTextChunk(Sel.getIdentifierInfoForSlot(0)->getName());
4171
4172 // Add parameters to the pattern.
4173 unsigned I = 0;
4174 for (ObjCMethodDecl::param_iterator P = Method->param_begin(),
4175 PEnd = Method->param_end();
4176 P != PEnd; (void)++P, ++I) {
4177 // Add the part of the selector name.
4178 if (I == 0)
4179 Pattern->AddChunk(CodeCompletionString::CK_Colon);
4180 else if (I < Sel.getNumArgs()) {
4181 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
Douglas Gregorb0ce9b72010-08-17 15:53:35 +00004182 Pattern->AddTextChunk(Sel.getIdentifierInfoForSlot(I)->getName());
Douglas Gregor636a61e2010-04-07 00:21:17 +00004183 Pattern->AddChunk(CodeCompletionString::CK_Colon);
4184 } else
4185 break;
4186
4187 // Add the parameter type.
4188 std::string TypeStr;
4189 (*P)->getOriginalType().getAsStringInternal(TypeStr, Policy);
4190 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
4191 Pattern->AddTextChunk(TypeStr);
4192 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
4193
4194 if (IdentifierInfo *Id = (*P)->getIdentifier())
4195 Pattern->AddTextChunk(Id->getName());
4196 }
4197
4198 if (Method->isVariadic()) {
4199 if (Method->param_size() > 0)
4200 Pattern->AddChunk(CodeCompletionString::CK_Comma);
4201 Pattern->AddTextChunk("...");
4202 }
4203
Douglas Gregord37c59d2010-05-28 00:57:46 +00004204 if (IsInImplementation && Results.includeCodePatterns()) {
Douglas Gregor636a61e2010-04-07 00:21:17 +00004205 // We will be defining the method here, so add a compound statement.
4206 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
4207 Pattern->AddChunk(CodeCompletionString::CK_LeftBrace);
4208 Pattern->AddChunk(CodeCompletionString::CK_VerticalSpace);
4209 if (!Method->getResultType()->isVoidType()) {
4210 // If the result type is not void, add a return clause.
4211 Pattern->AddTextChunk("return");
4212 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
4213 Pattern->AddPlaceholderChunk("expression");
4214 Pattern->AddChunk(CodeCompletionString::CK_SemiColon);
4215 } else
4216 Pattern->AddPlaceholderChunk("statements");
4217
4218 Pattern->AddChunk(CodeCompletionString::CK_VerticalSpace);
4219 Pattern->AddChunk(CodeCompletionString::CK_RightBrace);
4220 }
4221
Douglas Gregor7116a8c2010-08-17 16:06:07 +00004222 Results.AddResult(Result(Pattern, CCP_CodePattern,
4223 Method->isInstanceMethod()
4224 ? CXCursor_ObjCInstanceMethodDecl
4225 : CXCursor_ObjCClassMethodDecl));
Douglas Gregor636a61e2010-04-07 00:21:17 +00004226 }
4227
4228 Results.ExitScope();
4229
Douglas Gregor00c37ef2010-08-11 21:23:17 +00004230 HandleCodeCompleteResults(this, CodeCompleter,
4231 CodeCompletionContext::CCC_Other,
4232 Results.data(),Results.size());
Douglas Gregor636a61e2010-04-07 00:21:17 +00004233}
Douglas Gregor95887f92010-07-08 23:20:03 +00004234
4235void Sema::CodeCompleteObjCMethodDeclSelector(Scope *S,
4236 bool IsInstanceMethod,
Douglas Gregor45879692010-07-08 23:37:41 +00004237 bool AtParameterName,
Douglas Gregor95887f92010-07-08 23:20:03 +00004238 TypeTy *ReturnTy,
4239 IdentifierInfo **SelIdents,
4240 unsigned NumSelIdents) {
Douglas Gregor95887f92010-07-08 23:20:03 +00004241 // If we have an external source, load the entire class method
Sebastian Redld44cd6a2010-08-18 23:57:06 +00004242 // pool from the AST file.
Douglas Gregor95887f92010-07-08 23:20:03 +00004243 if (ExternalSource) {
4244 for (uint32_t I = 0, N = ExternalSource->GetNumExternalSelectors();
4245 I != N; ++I) {
4246 Selector Sel = ExternalSource->GetExternalSelector(I);
Sebastian Redl75d8a322010-08-02 23:18:59 +00004247 if (Sel.isNull() || MethodPool.count(Sel))
Douglas Gregor95887f92010-07-08 23:20:03 +00004248 continue;
Sebastian Redl75d8a322010-08-02 23:18:59 +00004249
4250 ReadMethodPool(Sel);
Douglas Gregor95887f92010-07-08 23:20:03 +00004251 }
4252 }
4253
4254 // Build the set of methods we can see.
4255 typedef CodeCompleteConsumer::Result Result;
4256 ResultBuilder Results(*this);
4257
4258 if (ReturnTy)
4259 Results.setPreferredType(GetTypeFromParser(ReturnTy).getNonReferenceType());
Sebastian Redl75d8a322010-08-02 23:18:59 +00004260
Douglas Gregor95887f92010-07-08 23:20:03 +00004261 Results.EnterNewScope();
Sebastian Redl75d8a322010-08-02 23:18:59 +00004262 for (GlobalMethodPool::iterator M = MethodPool.begin(),
4263 MEnd = MethodPool.end();
4264 M != MEnd; ++M) {
4265 for (ObjCMethodList *MethList = IsInstanceMethod ? &M->second.first :
4266 &M->second.second;
4267 MethList && MethList->Method;
Douglas Gregor95887f92010-07-08 23:20:03 +00004268 MethList = MethList->Next) {
4269 if (!isAcceptableObjCMethod(MethList->Method, MK_Any, SelIdents,
4270 NumSelIdents))
4271 continue;
4272
Douglas Gregor45879692010-07-08 23:37:41 +00004273 if (AtParameterName) {
4274 // Suggest parameter names we've seen before.
4275 if (NumSelIdents && NumSelIdents <= MethList->Method->param_size()) {
4276 ParmVarDecl *Param = MethList->Method->param_begin()[NumSelIdents-1];
4277 if (Param->getIdentifier()) {
4278 CodeCompletionString *Pattern = new CodeCompletionString;
4279 Pattern->AddTypedTextChunk(Param->getIdentifier()->getName());
4280 Results.AddResult(Pattern);
4281 }
4282 }
4283
4284 continue;
4285 }
4286
Douglas Gregor95887f92010-07-08 23:20:03 +00004287 Result R(MethList->Method, 0);
4288 R.StartParameter = NumSelIdents;
4289 R.AllParametersAreInformative = false;
4290 R.DeclaringEntity = true;
4291 Results.MaybeAddResult(R, CurContext);
4292 }
4293 }
4294
4295 Results.ExitScope();
Douglas Gregor00c37ef2010-08-11 21:23:17 +00004296 HandleCodeCompleteResults(this, CodeCompleter,
4297 CodeCompletionContext::CCC_Other,
4298 Results.data(),Results.size());
Douglas Gregor95887f92010-07-08 23:20:03 +00004299}
Douglas Gregorb14904c2010-08-13 22:48:40 +00004300
4301void Sema::GatherGlobalCodeCompletions(
4302 llvm::SmallVectorImpl<CodeCompleteConsumer::Result> &Results) {
4303 ResultBuilder Builder(*this);
4304
Douglas Gregor39982192010-08-15 06:18:01 +00004305 if (!CodeCompleter || CodeCompleter->includeGlobals()) {
4306 CodeCompletionDeclConsumer Consumer(Builder,
4307 Context.getTranslationUnitDecl());
4308 LookupVisibleDecls(Context.getTranslationUnitDecl(), LookupAnyName,
4309 Consumer);
4310 }
Douglas Gregorb14904c2010-08-13 22:48:40 +00004311
4312 if (!CodeCompleter || CodeCompleter->includeMacros())
4313 AddMacroResults(PP, Builder);
4314
4315 Results.clear();
4316 Results.insert(Results.end(),
4317 Builder.data(), Builder.data() + Builder.size());
4318}