blob: 06e65784e85dfda1af6fbd9a07275bdf2d098b4b [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"
John McCall5c32be02010-08-24 20:38:10 +000015#include "clang/Sema/Overload.h"
Douglas Gregor2436e712009-09-17 21:32:03 +000016#include "clang/Sema/CodeCompleteConsumer.h"
Douglas Gregord720daf2010-04-06 17:30:22 +000017#include "clang/Sema/ExternalSemaSource.h"
John McCallcc14d1f2010-08-24 08:50:51 +000018#include "clang/Sema/Scope.h"
John McCallde6836a2010-08-24 07:21:54 +000019#include "clang/AST/DeclObjC.h"
Douglas Gregorf2510672009-09-21 19:57:38 +000020#include "clang/AST/ExprCXX.h"
Douglas Gregor8ce33212009-11-17 17:59:40 +000021#include "clang/AST/ExprObjC.h"
Douglas Gregorf329c7c2009-10-30 16:50:04 +000022#include "clang/Lex/MacroInfo.h"
23#include "clang/Lex/Preprocessor.h"
Douglas Gregor3545ff42009-09-21 16:56:56 +000024#include "llvm/ADT/SmallPtrSet.h"
Douglas Gregore6688e62009-09-28 03:51:44 +000025#include "llvm/ADT/StringExtras.h"
Douglas Gregor9d2ddb22010-04-06 19:22:33 +000026#include "llvm/ADT/StringSwitch.h"
Douglas Gregor3545ff42009-09-21 16:56:56 +000027#include <list>
28#include <map>
29#include <vector>
Douglas Gregor2436e712009-09-17 21:32:03 +000030
31using namespace clang;
32
Douglas Gregor3545ff42009-09-21 16:56:56 +000033namespace {
34 /// \brief A container of code-completion results.
35 class ResultBuilder {
36 public:
37 /// \brief The type of a name-lookup filter, which can be provided to the
38 /// name-lookup routines to specify which declarations should be included in
39 /// the result set (when it returns true) and which declarations should be
40 /// filtered out (returns false).
41 typedef bool (ResultBuilder::*LookupFilter)(NamedDecl *) const;
42
43 typedef CodeCompleteConsumer::Result Result;
44
45 private:
46 /// \brief The actual results we have found.
47 std::vector<Result> Results;
48
49 /// \brief A record of all of the declarations we have found and placed
50 /// into the result set, used to ensure that no declaration ever gets into
51 /// the result set twice.
52 llvm::SmallPtrSet<Decl*, 16> AllDeclsFound;
53
Douglas Gregor05e7ca32009-12-06 20:23:50 +000054 typedef std::pair<NamedDecl *, unsigned> DeclIndexPair;
55
56 /// \brief An entry in the shadow map, which is optimized to store
57 /// a single (declaration, index) mapping (the common case) but
58 /// can also store a list of (declaration, index) mappings.
59 class ShadowMapEntry {
60 typedef llvm::SmallVector<DeclIndexPair, 4> DeclIndexPairVector;
61
62 /// \brief Contains either the solitary NamedDecl * or a vector
63 /// of (declaration, index) pairs.
64 llvm::PointerUnion<NamedDecl *, DeclIndexPairVector*> DeclOrVector;
65
66 /// \brief When the entry contains a single declaration, this is
67 /// the index associated with that entry.
68 unsigned SingleDeclIndex;
69
70 public:
71 ShadowMapEntry() : DeclOrVector(), SingleDeclIndex(0) { }
72
73 void Add(NamedDecl *ND, unsigned Index) {
74 if (DeclOrVector.isNull()) {
75 // 0 - > 1 elements: just set the single element information.
76 DeclOrVector = ND;
77 SingleDeclIndex = Index;
78 return;
79 }
80
81 if (NamedDecl *PrevND = DeclOrVector.dyn_cast<NamedDecl *>()) {
82 // 1 -> 2 elements: create the vector of results and push in the
83 // existing declaration.
84 DeclIndexPairVector *Vec = new DeclIndexPairVector;
85 Vec->push_back(DeclIndexPair(PrevND, SingleDeclIndex));
86 DeclOrVector = Vec;
87 }
88
89 // Add the new element to the end of the vector.
90 DeclOrVector.get<DeclIndexPairVector*>()->push_back(
91 DeclIndexPair(ND, Index));
92 }
93
94 void Destroy() {
95 if (DeclIndexPairVector *Vec
96 = DeclOrVector.dyn_cast<DeclIndexPairVector *>()) {
97 delete Vec;
98 DeclOrVector = ((NamedDecl *)0);
99 }
100 }
101
102 // Iteration.
103 class iterator;
104 iterator begin() const;
105 iterator end() const;
106 };
107
Douglas Gregor3545ff42009-09-21 16:56:56 +0000108 /// \brief A mapping from declaration names to the declarations that have
109 /// this name within a particular scope and their index within the list of
110 /// results.
Douglas Gregor05e7ca32009-12-06 20:23:50 +0000111 typedef llvm::DenseMap<DeclarationName, ShadowMapEntry> ShadowMap;
Douglas Gregor3545ff42009-09-21 16:56:56 +0000112
113 /// \brief The semantic analysis object for which results are being
114 /// produced.
115 Sema &SemaRef;
116
117 /// \brief If non-NULL, a filter function used to remove any code-completion
118 /// results that are not desirable.
119 LookupFilter Filter;
Douglas Gregor6ae4c522010-01-14 03:21:49 +0000120
121 /// \brief Whether we should allow declarations as
122 /// nested-name-specifiers that would otherwise be filtered out.
123 bool AllowNestedNameSpecifiers;
124
Douglas Gregor7aa6b222010-05-30 01:49:25 +0000125 /// \brief If set, the type that we would prefer our resulting value
126 /// declarations to have.
127 ///
128 /// Closely matching the preferred type gives a boost to a result's
129 /// priority.
130 CanQualType PreferredType;
131
Douglas Gregor3545ff42009-09-21 16:56:56 +0000132 /// \brief A list of shadow maps, which is used to model name hiding at
133 /// different levels of, e.g., the inheritance hierarchy.
134 std::list<ShadowMap> ShadowMaps;
135
Douglas Gregor95887f92010-07-08 23:20:03 +0000136 void AdjustResultPriorityForPreferredType(Result &R);
137
Douglas Gregor3545ff42009-09-21 16:56:56 +0000138 public:
139 explicit ResultBuilder(Sema &SemaRef, LookupFilter Filter = 0)
Douglas Gregor6ae4c522010-01-14 03:21:49 +0000140 : SemaRef(SemaRef), Filter(Filter), AllowNestedNameSpecifiers(false) { }
Douglas Gregor3545ff42009-09-21 16:56:56 +0000141
Douglas Gregorf64acca2010-05-25 21:41:55 +0000142 /// \brief Whether we should include code patterns in the completion
143 /// results.
144 bool includeCodePatterns() const {
145 return SemaRef.CodeCompleter &&
146 SemaRef.CodeCompleter->includeCodePatterns();
147 }
148
Douglas Gregor3545ff42009-09-21 16:56:56 +0000149 /// \brief Set the filter used for code-completion results.
150 void setFilter(LookupFilter Filter) {
151 this->Filter = Filter;
152 }
153
154 typedef std::vector<Result>::iterator iterator;
155 iterator begin() { return Results.begin(); }
156 iterator end() { return Results.end(); }
157
158 Result *data() { return Results.empty()? 0 : &Results.front(); }
159 unsigned size() const { return Results.size(); }
160 bool empty() const { return Results.empty(); }
161
Douglas Gregor7aa6b222010-05-30 01:49:25 +0000162 /// \brief Specify the preferred type.
163 void setPreferredType(QualType T) {
164 PreferredType = SemaRef.Context.getCanonicalType(T);
165 }
166
Douglas Gregor6ae4c522010-01-14 03:21:49 +0000167 /// \brief Specify whether nested-name-specifiers are allowed.
168 void allowNestedNameSpecifiers(bool Allow = true) {
169 AllowNestedNameSpecifiers = Allow;
170 }
171
Douglas Gregor7c208612010-01-14 00:20:49 +0000172 /// \brief Determine whether the given declaration is at all interesting
173 /// as a code-completion result.
Douglas Gregor6ae4c522010-01-14 03:21:49 +0000174 ///
175 /// \param ND the declaration that we are inspecting.
176 ///
177 /// \param AsNestedNameSpecifier will be set true if this declaration is
178 /// only interesting when it is a nested-name-specifier.
179 bool isInterestingDecl(NamedDecl *ND, bool &AsNestedNameSpecifier) const;
Douglas Gregore0717ab2010-01-14 00:41:07 +0000180
181 /// \brief Check whether the result is hidden by the Hiding declaration.
182 ///
183 /// \returns true if the result is hidden and cannot be found, false if
184 /// the hidden result could still be found. When false, \p R may be
185 /// modified to describe how the result can be found (e.g., via extra
186 /// qualification).
187 bool CheckHiddenResult(Result &R, DeclContext *CurContext,
188 NamedDecl *Hiding);
189
Douglas Gregor3545ff42009-09-21 16:56:56 +0000190 /// \brief Add a new result to this result set (if it isn't already in one
191 /// of the shadow maps), or replace an existing result (for, e.g., a
192 /// redeclaration).
Douglas Gregor2af2f672009-09-21 20:12:40 +0000193 ///
Douglas Gregorc580c522010-01-14 01:09:38 +0000194 /// \param CurContext the result to add (if it is unique).
Douglas Gregor2af2f672009-09-21 20:12:40 +0000195 ///
196 /// \param R the context in which this result will be named.
197 void MaybeAddResult(Result R, DeclContext *CurContext = 0);
Douglas Gregor3545ff42009-09-21 16:56:56 +0000198
Douglas Gregorc580c522010-01-14 01:09:38 +0000199 /// \brief Add a new result to this result set, where we already know
200 /// the hiding declation (if any).
201 ///
202 /// \param R the result to add (if it is unique).
203 ///
204 /// \param CurContext the context in which this result will be named.
205 ///
206 /// \param Hiding the declaration that hides the result.
Douglas Gregor09bbc652010-01-14 15:47:35 +0000207 ///
208 /// \param InBaseClass whether the result was found in a base
209 /// class of the searched context.
210 void AddResult(Result R, DeclContext *CurContext, NamedDecl *Hiding,
211 bool InBaseClass);
Douglas Gregorc580c522010-01-14 01:09:38 +0000212
Douglas Gregor78a21012010-01-14 16:01:26 +0000213 /// \brief Add a new non-declaration result to this result set.
214 void AddResult(Result R);
215
Douglas Gregor3545ff42009-09-21 16:56:56 +0000216 /// \brief Enter into a new scope.
217 void EnterNewScope();
218
219 /// \brief Exit from the current scope.
220 void ExitScope();
221
Douglas Gregorbaf69612009-11-18 04:19:12 +0000222 /// \brief Ignore this declaration, if it is seen again.
223 void Ignore(Decl *D) { AllDeclsFound.insert(D->getCanonicalDecl()); }
224
Douglas Gregor3545ff42009-09-21 16:56:56 +0000225 /// \name Name lookup predicates
226 ///
227 /// These predicates can be passed to the name lookup functions to filter the
228 /// results of name lookup. All of the predicates have the same type, so that
229 ///
230 //@{
Douglas Gregor9d64c5e2009-09-21 20:51:25 +0000231 bool IsOrdinaryName(NamedDecl *ND) const;
Douglas Gregor70febae2010-05-28 00:49:12 +0000232 bool IsOrdinaryNonTypeName(NamedDecl *ND) const;
Douglas Gregor85b50632010-07-28 21:50:18 +0000233 bool IsIntegralConstantValue(NamedDecl *ND) const;
Douglas Gregor504a6ae2010-01-10 23:08:15 +0000234 bool IsOrdinaryNonValueName(NamedDecl *ND) const;
Douglas Gregor3545ff42009-09-21 16:56:56 +0000235 bool IsNestedNameSpecifier(NamedDecl *ND) const;
236 bool IsEnum(NamedDecl *ND) const;
237 bool IsClassOrStruct(NamedDecl *ND) const;
238 bool IsUnion(NamedDecl *ND) const;
239 bool IsNamespace(NamedDecl *ND) const;
240 bool IsNamespaceOrAlias(NamedDecl *ND) const;
241 bool IsType(NamedDecl *ND) const;
Douglas Gregore412a5a2009-09-23 22:26:46 +0000242 bool IsMember(NamedDecl *ND) const;
Douglas Gregor2b8162b2010-01-14 16:08:12 +0000243 bool IsObjCIvar(NamedDecl *ND) const;
Douglas Gregora817a192010-05-27 23:06:34 +0000244 bool IsObjCMessageReceiver(NamedDecl *ND) const;
Douglas Gregor68762e72010-08-23 21:17:50 +0000245 bool IsObjCCollection(NamedDecl *ND) const;
Douglas Gregor3545ff42009-09-21 16:56:56 +0000246 //@}
247 };
248}
249
Douglas Gregor05e7ca32009-12-06 20:23:50 +0000250class ResultBuilder::ShadowMapEntry::iterator {
251 llvm::PointerUnion<NamedDecl*, const DeclIndexPair*> DeclOrIterator;
252 unsigned SingleDeclIndex;
253
254public:
255 typedef DeclIndexPair value_type;
256 typedef value_type reference;
257 typedef std::ptrdiff_t difference_type;
258 typedef std::input_iterator_tag iterator_category;
259
260 class pointer {
261 DeclIndexPair Value;
262
263 public:
264 pointer(const DeclIndexPair &Value) : Value(Value) { }
265
266 const DeclIndexPair *operator->() const {
267 return &Value;
268 }
269 };
270
271 iterator() : DeclOrIterator((NamedDecl *)0), SingleDeclIndex(0) { }
272
273 iterator(NamedDecl *SingleDecl, unsigned Index)
274 : DeclOrIterator(SingleDecl), SingleDeclIndex(Index) { }
275
276 iterator(const DeclIndexPair *Iterator)
277 : DeclOrIterator(Iterator), SingleDeclIndex(0) { }
278
279 iterator &operator++() {
280 if (DeclOrIterator.is<NamedDecl *>()) {
281 DeclOrIterator = (NamedDecl *)0;
282 SingleDeclIndex = 0;
283 return *this;
284 }
285
286 const DeclIndexPair *I = DeclOrIterator.get<const DeclIndexPair*>();
287 ++I;
288 DeclOrIterator = I;
289 return *this;
290 }
291
292 iterator operator++(int) {
293 iterator tmp(*this);
294 ++(*this);
295 return tmp;
296 }
297
298 reference operator*() const {
299 if (NamedDecl *ND = DeclOrIterator.dyn_cast<NamedDecl *>())
300 return reference(ND, SingleDeclIndex);
301
Douglas Gregor94bb5e82009-12-06 21:27:58 +0000302 return *DeclOrIterator.get<const DeclIndexPair*>();
Douglas Gregor05e7ca32009-12-06 20:23:50 +0000303 }
304
305 pointer operator->() const {
306 return pointer(**this);
307 }
308
309 friend bool operator==(const iterator &X, const iterator &Y) {
Douglas Gregor94bb5e82009-12-06 21:27:58 +0000310 return X.DeclOrIterator.getOpaqueValue()
311 == Y.DeclOrIterator.getOpaqueValue() &&
Douglas Gregor05e7ca32009-12-06 20:23:50 +0000312 X.SingleDeclIndex == Y.SingleDeclIndex;
313 }
314
315 friend bool operator!=(const iterator &X, const iterator &Y) {
Douglas Gregor94bb5e82009-12-06 21:27:58 +0000316 return !(X == Y);
Douglas Gregor05e7ca32009-12-06 20:23:50 +0000317 }
318};
319
Douglas Gregor05e7ca32009-12-06 20:23:50 +0000320ResultBuilder::ShadowMapEntry::iterator
321ResultBuilder::ShadowMapEntry::begin() const {
322 if (DeclOrVector.isNull())
323 return iterator();
324
325 if (NamedDecl *ND = DeclOrVector.dyn_cast<NamedDecl *>())
326 return iterator(ND, SingleDeclIndex);
327
328 return iterator(DeclOrVector.get<DeclIndexPairVector *>()->begin());
329}
330
331ResultBuilder::ShadowMapEntry::iterator
332ResultBuilder::ShadowMapEntry::end() const {
333 if (DeclOrVector.is<NamedDecl *>() || DeclOrVector.isNull())
334 return iterator();
335
336 return iterator(DeclOrVector.get<DeclIndexPairVector *>()->end());
337}
338
Douglas Gregor2af2f672009-09-21 20:12:40 +0000339/// \brief Compute the qualification required to get from the current context
340/// (\p CurContext) to the target context (\p TargetContext).
341///
342/// \param Context the AST context in which the qualification will be used.
343///
344/// \param CurContext the context where an entity is being named, which is
345/// typically based on the current scope.
346///
347/// \param TargetContext the context in which the named entity actually
348/// resides.
349///
350/// \returns a nested name specifier that refers into the target context, or
351/// NULL if no qualification is needed.
352static NestedNameSpecifier *
353getRequiredQualification(ASTContext &Context,
354 DeclContext *CurContext,
355 DeclContext *TargetContext) {
356 llvm::SmallVector<DeclContext *, 4> TargetParents;
357
358 for (DeclContext *CommonAncestor = TargetContext;
359 CommonAncestor && !CommonAncestor->Encloses(CurContext);
360 CommonAncestor = CommonAncestor->getLookupParent()) {
361 if (CommonAncestor->isTransparentContext() ||
362 CommonAncestor->isFunctionOrMethod())
363 continue;
364
365 TargetParents.push_back(CommonAncestor);
366 }
367
368 NestedNameSpecifier *Result = 0;
369 while (!TargetParents.empty()) {
370 DeclContext *Parent = TargetParents.back();
371 TargetParents.pop_back();
372
Douglas Gregor68762e72010-08-23 21:17:50 +0000373 if (NamespaceDecl *Namespace = dyn_cast<NamespaceDecl>(Parent)) {
374 if (!Namespace->getIdentifier())
375 continue;
376
Douglas Gregor2af2f672009-09-21 20:12:40 +0000377 Result = NestedNameSpecifier::Create(Context, Result, Namespace);
Douglas Gregor68762e72010-08-23 21:17:50 +0000378 }
Douglas Gregor2af2f672009-09-21 20:12:40 +0000379 else if (TagDecl *TD = dyn_cast<TagDecl>(Parent))
380 Result = NestedNameSpecifier::Create(Context, Result,
381 false,
382 Context.getTypeDeclType(TD).getTypePtr());
Douglas Gregor9eb77012009-11-07 00:00:49 +0000383 }
Douglas Gregor2af2f672009-09-21 20:12:40 +0000384 return Result;
385}
386
Douglas Gregor6ae4c522010-01-14 03:21:49 +0000387bool ResultBuilder::isInterestingDecl(NamedDecl *ND,
388 bool &AsNestedNameSpecifier) const {
389 AsNestedNameSpecifier = false;
390
Douglas Gregor7c208612010-01-14 00:20:49 +0000391 ND = ND->getUnderlyingDecl();
392 unsigned IDNS = ND->getIdentifierNamespace();
Douglas Gregor58acf322009-10-09 22:16:47 +0000393
394 // Skip unnamed entities.
Douglas Gregor7c208612010-01-14 00:20:49 +0000395 if (!ND->getDeclName())
396 return false;
Douglas Gregor3545ff42009-09-21 16:56:56 +0000397
398 // Friend declarations and declarations introduced due to friends are never
399 // added as results.
John McCallbbbbe4e2010-03-11 07:50:04 +0000400 if (IDNS & (Decl::IDNS_OrdinaryFriend | Decl::IDNS_TagFriend))
Douglas Gregor7c208612010-01-14 00:20:49 +0000401 return false;
402
Douglas Gregor99fe2ad2009-12-11 17:31:05 +0000403 // Class template (partial) specializations are never added as results.
Douglas Gregor7c208612010-01-14 00:20:49 +0000404 if (isa<ClassTemplateSpecializationDecl>(ND) ||
405 isa<ClassTemplatePartialSpecializationDecl>(ND))
406 return false;
Douglas Gregor3545ff42009-09-21 16:56:56 +0000407
Douglas Gregor99fe2ad2009-12-11 17:31:05 +0000408 // Using declarations themselves are never added as results.
Douglas Gregor7c208612010-01-14 00:20:49 +0000409 if (isa<UsingDecl>(ND))
410 return false;
411
412 // Some declarations have reserved names that we don't want to ever show.
413 if (const IdentifierInfo *Id = ND->getIdentifier()) {
Douglas Gregor3545ff42009-09-21 16:56:56 +0000414 // __va_list_tag is a freak of nature. Find it and skip it.
415 if (Id->isStr("__va_list_tag") || Id->isStr("__builtin_va_list"))
Douglas Gregor7c208612010-01-14 00:20:49 +0000416 return false;
Douglas Gregor3545ff42009-09-21 16:56:56 +0000417
Douglas Gregor58acf322009-10-09 22:16:47 +0000418 // Filter out names reserved for the implementation (C99 7.1.3,
Douglas Gregor9f1570d2010-07-14 17:44:04 +0000419 // C++ [lib.global.names]) if they come from a system header.
Daniel Dunbar2c422dc92009-10-18 20:26:12 +0000420 //
421 // FIXME: Add predicate for this.
Douglas Gregor58acf322009-10-09 22:16:47 +0000422 if (Id->getLength() >= 2) {
Daniel Dunbar2c422dc92009-10-18 20:26:12 +0000423 const char *Name = Id->getNameStart();
Douglas Gregor58acf322009-10-09 22:16:47 +0000424 if (Name[0] == '_' &&
Douglas Gregor9f1570d2010-07-14 17:44:04 +0000425 (Name[1] == '_' || (Name[1] >= 'A' && Name[1] <= 'Z')) &&
426 (ND->getLocation().isInvalid() ||
427 SemaRef.SourceMgr.isInSystemHeader(
428 SemaRef.SourceMgr.getSpellingLoc(ND->getLocation()))))
Douglas Gregor7c208612010-01-14 00:20:49 +0000429 return false;
Douglas Gregor58acf322009-10-09 22:16:47 +0000430 }
Douglas Gregor3545ff42009-09-21 16:56:56 +0000431 }
Douglas Gregor7c208612010-01-14 00:20:49 +0000432
Douglas Gregor3545ff42009-09-21 16:56:56 +0000433 // C++ constructors are never found by name lookup.
Douglas Gregor7c208612010-01-14 00:20:49 +0000434 if (isa<CXXConstructorDecl>(ND))
435 return false;
Douglas Gregor3545ff42009-09-21 16:56:56 +0000436
Douglas Gregor59cab552010-08-16 23:05:20 +0000437 if (Filter == &ResultBuilder::IsNestedNameSpecifier ||
438 ((isa<NamespaceDecl>(ND) || isa<NamespaceAliasDecl>(ND)) &&
439 Filter != &ResultBuilder::IsNamespace &&
440 Filter != &ResultBuilder::IsNamespaceOrAlias))
441 AsNestedNameSpecifier = true;
442
Douglas Gregor3545ff42009-09-21 16:56:56 +0000443 // Filter out any unwanted results.
Douglas Gregor6ae4c522010-01-14 03:21:49 +0000444 if (Filter && !(this->*Filter)(ND)) {
445 // Check whether it is interesting as a nested-name-specifier.
446 if (AllowNestedNameSpecifiers && SemaRef.getLangOptions().CPlusPlus &&
447 IsNestedNameSpecifier(ND) &&
448 (Filter != &ResultBuilder::IsMember ||
449 (isa<CXXRecordDecl>(ND) &&
450 cast<CXXRecordDecl>(ND)->isInjectedClassName()))) {
451 AsNestedNameSpecifier = true;
452 return true;
453 }
454
Douglas Gregor7c208612010-01-14 00:20:49 +0000455 return false;
Douglas Gregor59cab552010-08-16 23:05:20 +0000456 }
Douglas Gregor7c208612010-01-14 00:20:49 +0000457 // ... then it must be interesting!
458 return true;
459}
460
Douglas Gregore0717ab2010-01-14 00:41:07 +0000461bool ResultBuilder::CheckHiddenResult(Result &R, DeclContext *CurContext,
462 NamedDecl *Hiding) {
463 // In C, there is no way to refer to a hidden name.
464 // FIXME: This isn't true; we can find a tag name hidden by an ordinary
465 // name if we introduce the tag type.
466 if (!SemaRef.getLangOptions().CPlusPlus)
467 return true;
468
469 DeclContext *HiddenCtx = R.Declaration->getDeclContext()->getLookupContext();
470
471 // There is no way to qualify a name declared in a function or method.
472 if (HiddenCtx->isFunctionOrMethod())
473 return true;
474
475 if (HiddenCtx == Hiding->getDeclContext()->getLookupContext())
476 return true;
477
478 // We can refer to the result with the appropriate qualification. Do it.
479 R.Hidden = true;
480 R.QualifierIsInformative = false;
481
482 if (!R.Qualifier)
483 R.Qualifier = getRequiredQualification(SemaRef.Context,
484 CurContext,
485 R.Declaration->getDeclContext());
486 return false;
487}
488
Douglas Gregor95887f92010-07-08 23:20:03 +0000489/// \brief A simplified classification of types used to determine whether two
490/// types are "similar enough" when adjusting priorities.
Douglas Gregor6e240332010-08-16 16:18:59 +0000491SimplifiedTypeClass clang::getSimplifiedTypeClass(CanQualType T) {
Douglas Gregor95887f92010-07-08 23:20:03 +0000492 switch (T->getTypeClass()) {
493 case Type::Builtin:
494 switch (cast<BuiltinType>(T)->getKind()) {
495 case BuiltinType::Void:
496 return STC_Void;
497
498 case BuiltinType::NullPtr:
499 return STC_Pointer;
500
501 case BuiltinType::Overload:
502 case BuiltinType::Dependent:
503 case BuiltinType::UndeducedAuto:
504 return STC_Other;
505
506 case BuiltinType::ObjCId:
507 case BuiltinType::ObjCClass:
508 case BuiltinType::ObjCSel:
509 return STC_ObjectiveC;
510
511 default:
512 return STC_Arithmetic;
513 }
514 return STC_Other;
515
516 case Type::Complex:
517 return STC_Arithmetic;
518
519 case Type::Pointer:
520 return STC_Pointer;
521
522 case Type::BlockPointer:
523 return STC_Block;
524
525 case Type::LValueReference:
526 case Type::RValueReference:
527 return getSimplifiedTypeClass(T->getAs<ReferenceType>()->getPointeeType());
528
529 case Type::ConstantArray:
530 case Type::IncompleteArray:
531 case Type::VariableArray:
532 case Type::DependentSizedArray:
533 return STC_Array;
534
535 case Type::DependentSizedExtVector:
536 case Type::Vector:
537 case Type::ExtVector:
538 return STC_Arithmetic;
539
540 case Type::FunctionProto:
541 case Type::FunctionNoProto:
542 return STC_Function;
543
544 case Type::Record:
545 return STC_Record;
546
547 case Type::Enum:
548 return STC_Arithmetic;
549
550 case Type::ObjCObject:
551 case Type::ObjCInterface:
552 case Type::ObjCObjectPointer:
553 return STC_ObjectiveC;
554
555 default:
556 return STC_Other;
557 }
558}
559
560/// \brief Get the type that a given expression will have if this declaration
561/// is used as an expression in its "typical" code-completion form.
Douglas Gregor6e240332010-08-16 16:18:59 +0000562QualType clang::getDeclUsageType(ASTContext &C, NamedDecl *ND) {
Douglas Gregor95887f92010-07-08 23:20:03 +0000563 ND = cast<NamedDecl>(ND->getUnderlyingDecl());
564
565 if (TypeDecl *Type = dyn_cast<TypeDecl>(ND))
566 return C.getTypeDeclType(Type);
567 if (ObjCInterfaceDecl *Iface = dyn_cast<ObjCInterfaceDecl>(ND))
568 return C.getObjCInterfaceType(Iface);
569
570 QualType T;
571 if (FunctionDecl *Function = dyn_cast<FunctionDecl>(ND))
Douglas Gregor603d81b2010-07-13 08:18:22 +0000572 T = Function->getCallResultType();
Douglas Gregor95887f92010-07-08 23:20:03 +0000573 else if (ObjCMethodDecl *Method = dyn_cast<ObjCMethodDecl>(ND))
Douglas Gregor603d81b2010-07-13 08:18:22 +0000574 T = Method->getSendResultType();
Douglas Gregor95887f92010-07-08 23:20:03 +0000575 else if (FunctionTemplateDecl *FunTmpl = dyn_cast<FunctionTemplateDecl>(ND))
Douglas Gregor603d81b2010-07-13 08:18:22 +0000576 T = FunTmpl->getTemplatedDecl()->getCallResultType();
Douglas Gregor95887f92010-07-08 23:20:03 +0000577 else if (EnumConstantDecl *Enumerator = dyn_cast<EnumConstantDecl>(ND))
578 T = C.getTypeDeclType(cast<EnumDecl>(Enumerator->getDeclContext()));
579 else if (ObjCPropertyDecl *Property = dyn_cast<ObjCPropertyDecl>(ND))
580 T = Property->getType();
581 else if (ValueDecl *Value = dyn_cast<ValueDecl>(ND))
582 T = Value->getType();
583 else
584 return QualType();
585
586 return T.getNonReferenceType();
587}
588
589void ResultBuilder::AdjustResultPriorityForPreferredType(Result &R) {
590 QualType T = getDeclUsageType(SemaRef.Context, R.Declaration);
591 if (T.isNull())
592 return;
593
594 CanQualType TC = SemaRef.Context.getCanonicalType(T);
595 // Check for exactly-matching types (modulo qualifiers).
596 if (SemaRef.Context.hasSameUnqualifiedType(PreferredType, TC))
597 R.Priority /= CCF_ExactTypeMatch;
598 // Check for nearly-matching types, based on classification of each.
599 else if ((getSimplifiedTypeClass(PreferredType)
600 == getSimplifiedTypeClass(TC)) &&
601 !(PreferredType->isEnumeralType() && TC->isEnumeralType()))
602 R.Priority /= CCF_SimilarTypeMatch;
603}
604
Douglas Gregor7c208612010-01-14 00:20:49 +0000605void ResultBuilder::MaybeAddResult(Result R, DeclContext *CurContext) {
606 assert(!ShadowMaps.empty() && "Must enter into a results scope");
607
608 if (R.Kind != Result::RK_Declaration) {
609 // For non-declaration results, just add the result.
610 Results.push_back(R);
611 return;
612 }
613
614 // Look through using declarations.
615 if (UsingShadowDecl *Using = dyn_cast<UsingShadowDecl>(R.Declaration)) {
616 MaybeAddResult(Result(Using->getTargetDecl(), R.Qualifier), CurContext);
617 return;
618 }
619
620 Decl *CanonDecl = R.Declaration->getCanonicalDecl();
621 unsigned IDNS = CanonDecl->getIdentifierNamespace();
622
Douglas Gregor6ae4c522010-01-14 03:21:49 +0000623 bool AsNestedNameSpecifier = false;
624 if (!isInterestingDecl(R.Declaration, AsNestedNameSpecifier))
Douglas Gregor7c208612010-01-14 00:20:49 +0000625 return;
626
Douglas Gregor3545ff42009-09-21 16:56:56 +0000627 ShadowMap &SMap = ShadowMaps.back();
Douglas Gregor05e7ca32009-12-06 20:23:50 +0000628 ShadowMapEntry::iterator I, IEnd;
629 ShadowMap::iterator NamePos = SMap.find(R.Declaration->getDeclName());
630 if (NamePos != SMap.end()) {
631 I = NamePos->second.begin();
632 IEnd = NamePos->second.end();
633 }
634
635 for (; I != IEnd; ++I) {
636 NamedDecl *ND = I->first;
637 unsigned Index = I->second;
Douglas Gregor3545ff42009-09-21 16:56:56 +0000638 if (ND->getCanonicalDecl() == CanonDecl) {
639 // This is a redeclaration. Always pick the newer declaration.
Douglas Gregor3545ff42009-09-21 16:56:56 +0000640 Results[Index].Declaration = R.Declaration;
641
Douglas Gregor3545ff42009-09-21 16:56:56 +0000642 // We're done.
643 return;
644 }
645 }
646
647 // This is a new declaration in this scope. However, check whether this
648 // declaration name is hidden by a similarly-named declaration in an outer
649 // scope.
650 std::list<ShadowMap>::iterator SM, SMEnd = ShadowMaps.end();
651 --SMEnd;
652 for (SM = ShadowMaps.begin(); SM != SMEnd; ++SM) {
Douglas Gregor05e7ca32009-12-06 20:23:50 +0000653 ShadowMapEntry::iterator I, IEnd;
654 ShadowMap::iterator NamePos = SM->find(R.Declaration->getDeclName());
655 if (NamePos != SM->end()) {
656 I = NamePos->second.begin();
657 IEnd = NamePos->second.end();
658 }
659 for (; I != IEnd; ++I) {
Douglas Gregor3545ff42009-09-21 16:56:56 +0000660 // A tag declaration does not hide a non-tag declaration.
John McCalle87beb22010-04-23 18:46:30 +0000661 if (I->first->hasTagIdentifierNamespace() &&
Douglas Gregor3545ff42009-09-21 16:56:56 +0000662 (IDNS & (Decl::IDNS_Member | Decl::IDNS_Ordinary |
663 Decl::IDNS_ObjCProtocol)))
664 continue;
665
666 // Protocols are in distinct namespaces from everything else.
Douglas Gregor05e7ca32009-12-06 20:23:50 +0000667 if (((I->first->getIdentifierNamespace() & Decl::IDNS_ObjCProtocol)
Douglas Gregor3545ff42009-09-21 16:56:56 +0000668 || (IDNS & Decl::IDNS_ObjCProtocol)) &&
Douglas Gregor05e7ca32009-12-06 20:23:50 +0000669 I->first->getIdentifierNamespace() != IDNS)
Douglas Gregor3545ff42009-09-21 16:56:56 +0000670 continue;
671
672 // The newly-added result is hidden by an entry in the shadow map.
Douglas Gregore0717ab2010-01-14 00:41:07 +0000673 if (CheckHiddenResult(R, CurContext, I->first))
Douglas Gregor3545ff42009-09-21 16:56:56 +0000674 return;
Douglas Gregor3545ff42009-09-21 16:56:56 +0000675
676 break;
677 }
678 }
679
680 // Make sure that any given declaration only shows up in the result set once.
681 if (!AllDeclsFound.insert(CanonDecl))
682 return;
683
Douglas Gregore412a5a2009-09-23 22:26:46 +0000684 // If the filter is for nested-name-specifiers, then this result starts a
685 // nested-name-specifier.
Douglas Gregora2db7932010-05-26 22:00:08 +0000686 if (AsNestedNameSpecifier) {
Douglas Gregore412a5a2009-09-23 22:26:46 +0000687 R.StartsNestedNameSpecifier = true;
Douglas Gregora2db7932010-05-26 22:00:08 +0000688 R.Priority = CCP_NestedNameSpecifier;
Douglas Gregor95887f92010-07-08 23:20:03 +0000689 } else if (!PreferredType.isNull())
690 AdjustResultPriorityForPreferredType(R);
691
Douglas Gregor5bf52692009-09-22 23:15:58 +0000692 // If this result is supposed to have an informative qualifier, add one.
Douglas Gregore412a5a2009-09-23 22:26:46 +0000693 if (R.QualifierIsInformative && !R.Qualifier &&
694 !R.StartsNestedNameSpecifier) {
Douglas Gregor5bf52692009-09-22 23:15:58 +0000695 DeclContext *Ctx = R.Declaration->getDeclContext();
696 if (NamespaceDecl *Namespace = dyn_cast<NamespaceDecl>(Ctx))
697 R.Qualifier = NestedNameSpecifier::Create(SemaRef.Context, 0, Namespace);
698 else if (TagDecl *Tag = dyn_cast<TagDecl>(Ctx))
699 R.Qualifier = NestedNameSpecifier::Create(SemaRef.Context, 0, false,
700 SemaRef.Context.getTypeDeclType(Tag).getTypePtr());
701 else
702 R.QualifierIsInformative = false;
703 }
Douglas Gregore412a5a2009-09-23 22:26:46 +0000704
Douglas Gregor3545ff42009-09-21 16:56:56 +0000705 // Insert this result into the set of results and into the current shadow
706 // map.
Douglas Gregor05e7ca32009-12-06 20:23:50 +0000707 SMap[R.Declaration->getDeclName()].Add(R.Declaration, Results.size());
Douglas Gregor3545ff42009-09-21 16:56:56 +0000708 Results.push_back(R);
709}
710
Douglas Gregorc580c522010-01-14 01:09:38 +0000711void ResultBuilder::AddResult(Result R, DeclContext *CurContext,
Douglas Gregor09bbc652010-01-14 15:47:35 +0000712 NamedDecl *Hiding, bool InBaseClass = false) {
Douglas Gregor78a21012010-01-14 16:01:26 +0000713 if (R.Kind != Result::RK_Declaration) {
714 // For non-declaration results, just add the result.
715 Results.push_back(R);
716 return;
717 }
718
Douglas Gregorc580c522010-01-14 01:09:38 +0000719 // Look through using declarations.
720 if (UsingShadowDecl *Using = dyn_cast<UsingShadowDecl>(R.Declaration)) {
721 AddResult(Result(Using->getTargetDecl(), R.Qualifier), CurContext, Hiding);
722 return;
723 }
724
Douglas Gregor6ae4c522010-01-14 03:21:49 +0000725 bool AsNestedNameSpecifier = false;
726 if (!isInterestingDecl(R.Declaration, AsNestedNameSpecifier))
Douglas Gregorc580c522010-01-14 01:09:38 +0000727 return;
728
729 if (Hiding && CheckHiddenResult(R, CurContext, Hiding))
730 return;
731
732 // Make sure that any given declaration only shows up in the result set once.
733 if (!AllDeclsFound.insert(R.Declaration->getCanonicalDecl()))
734 return;
735
736 // If the filter is for nested-name-specifiers, then this result starts a
737 // nested-name-specifier.
Douglas Gregora2db7932010-05-26 22:00:08 +0000738 if (AsNestedNameSpecifier) {
Douglas Gregorc580c522010-01-14 01:09:38 +0000739 R.StartsNestedNameSpecifier = true;
Douglas Gregora2db7932010-05-26 22:00:08 +0000740 R.Priority = CCP_NestedNameSpecifier;
741 }
Douglas Gregor09bbc652010-01-14 15:47:35 +0000742 else if (Filter == &ResultBuilder::IsMember && !R.Qualifier && InBaseClass &&
743 isa<CXXRecordDecl>(R.Declaration->getDeclContext()
744 ->getLookupContext()))
745 R.QualifierIsInformative = true;
746
Douglas Gregorc580c522010-01-14 01:09:38 +0000747 // If this result is supposed to have an informative qualifier, add one.
748 if (R.QualifierIsInformative && !R.Qualifier &&
749 !R.StartsNestedNameSpecifier) {
750 DeclContext *Ctx = R.Declaration->getDeclContext();
751 if (NamespaceDecl *Namespace = dyn_cast<NamespaceDecl>(Ctx))
752 R.Qualifier = NestedNameSpecifier::Create(SemaRef.Context, 0, Namespace);
753 else if (TagDecl *Tag = dyn_cast<TagDecl>(Ctx))
754 R.Qualifier = NestedNameSpecifier::Create(SemaRef.Context, 0, false,
Douglas Gregor6ae4c522010-01-14 03:21:49 +0000755 SemaRef.Context.getTypeDeclType(Tag).getTypePtr());
Douglas Gregorc580c522010-01-14 01:09:38 +0000756 else
757 R.QualifierIsInformative = false;
758 }
759
Douglas Gregora2db7932010-05-26 22:00:08 +0000760 // Adjust the priority if this result comes from a base class.
761 if (InBaseClass)
762 R.Priority += CCD_InBaseClass;
763
Douglas Gregor95887f92010-07-08 23:20:03 +0000764 if (!PreferredType.isNull())
765 AdjustResultPriorityForPreferredType(R);
Douglas Gregor7aa6b222010-05-30 01:49:25 +0000766
Douglas Gregorc580c522010-01-14 01:09:38 +0000767 // Insert this result into the set of results.
768 Results.push_back(R);
769}
770
Douglas Gregor78a21012010-01-14 16:01:26 +0000771void ResultBuilder::AddResult(Result R) {
772 assert(R.Kind != Result::RK_Declaration &&
773 "Declaration results need more context");
774 Results.push_back(R);
775}
776
Douglas Gregor3545ff42009-09-21 16:56:56 +0000777/// \brief Enter into a new scope.
778void ResultBuilder::EnterNewScope() {
779 ShadowMaps.push_back(ShadowMap());
780}
781
782/// \brief Exit from the current scope.
783void ResultBuilder::ExitScope() {
Douglas Gregor05e7ca32009-12-06 20:23:50 +0000784 for (ShadowMap::iterator E = ShadowMaps.back().begin(),
785 EEnd = ShadowMaps.back().end();
786 E != EEnd;
787 ++E)
788 E->second.Destroy();
789
Douglas Gregor3545ff42009-09-21 16:56:56 +0000790 ShadowMaps.pop_back();
791}
792
Douglas Gregor9d64c5e2009-09-21 20:51:25 +0000793/// \brief Determines whether this given declaration will be found by
794/// ordinary name lookup.
795bool ResultBuilder::IsOrdinaryName(NamedDecl *ND) const {
Douglas Gregor70febae2010-05-28 00:49:12 +0000796 ND = cast<NamedDecl>(ND->getUnderlyingDecl());
797
Douglas Gregor9d64c5e2009-09-21 20:51:25 +0000798 unsigned IDNS = Decl::IDNS_Ordinary;
799 if (SemaRef.getLangOptions().CPlusPlus)
Douglas Gregor9858ed52010-06-15 20:26:51 +0000800 IDNS |= Decl::IDNS_Tag | Decl::IDNS_Namespace | Decl::IDNS_Member;
Douglas Gregorc580c522010-01-14 01:09:38 +0000801 else if (SemaRef.getLangOptions().ObjC1 && isa<ObjCIvarDecl>(ND))
802 return true;
803
Douglas Gregor9d64c5e2009-09-21 20:51:25 +0000804 return ND->getIdentifierNamespace() & IDNS;
805}
806
Douglas Gregor504a6ae2010-01-10 23:08:15 +0000807/// \brief Determines whether this given declaration will be found by
Douglas Gregor70febae2010-05-28 00:49:12 +0000808/// ordinary name lookup but is not a type name.
809bool ResultBuilder::IsOrdinaryNonTypeName(NamedDecl *ND) const {
810 ND = cast<NamedDecl>(ND->getUnderlyingDecl());
811 if (isa<TypeDecl>(ND) || isa<ObjCInterfaceDecl>(ND))
812 return false;
813
814 unsigned IDNS = Decl::IDNS_Ordinary;
815 if (SemaRef.getLangOptions().CPlusPlus)
Douglas Gregor9858ed52010-06-15 20:26:51 +0000816 IDNS |= Decl::IDNS_Tag | Decl::IDNS_Namespace | Decl::IDNS_Member;
Douglas Gregor70febae2010-05-28 00:49:12 +0000817 else if (SemaRef.getLangOptions().ObjC1 && isa<ObjCIvarDecl>(ND))
818 return true;
819
820 return ND->getIdentifierNamespace() & IDNS;
821}
822
Douglas Gregor85b50632010-07-28 21:50:18 +0000823bool ResultBuilder::IsIntegralConstantValue(NamedDecl *ND) const {
824 if (!IsOrdinaryNonTypeName(ND))
825 return 0;
826
827 if (ValueDecl *VD = dyn_cast<ValueDecl>(ND->getUnderlyingDecl()))
828 if (VD->getType()->isIntegralOrEnumerationType())
829 return true;
830
831 return false;
832}
833
Douglas Gregor70febae2010-05-28 00:49:12 +0000834/// \brief Determines whether this given declaration will be found by
Douglas Gregor504a6ae2010-01-10 23:08:15 +0000835/// ordinary name lookup.
836bool ResultBuilder::IsOrdinaryNonValueName(NamedDecl *ND) const {
Douglas Gregor70febae2010-05-28 00:49:12 +0000837 ND = cast<NamedDecl>(ND->getUnderlyingDecl());
838
Douglas Gregor504a6ae2010-01-10 23:08:15 +0000839 unsigned IDNS = Decl::IDNS_Ordinary;
840 if (SemaRef.getLangOptions().CPlusPlus)
John McCalle87beb22010-04-23 18:46:30 +0000841 IDNS |= Decl::IDNS_Tag | Decl::IDNS_Namespace;
Douglas Gregor504a6ae2010-01-10 23:08:15 +0000842
843 return (ND->getIdentifierNamespace() & IDNS) &&
Douglas Gregor70febae2010-05-28 00:49:12 +0000844 !isa<ValueDecl>(ND) && !isa<FunctionTemplateDecl>(ND) &&
845 !isa<ObjCPropertyDecl>(ND);
Douglas Gregor504a6ae2010-01-10 23:08:15 +0000846}
847
Douglas Gregor3545ff42009-09-21 16:56:56 +0000848/// \brief Determines whether the given declaration is suitable as the
849/// start of a C++ nested-name-specifier, e.g., a class or namespace.
850bool ResultBuilder::IsNestedNameSpecifier(NamedDecl *ND) const {
851 // Allow us to find class templates, too.
852 if (ClassTemplateDecl *ClassTemplate = dyn_cast<ClassTemplateDecl>(ND))
853 ND = ClassTemplate->getTemplatedDecl();
854
855 return SemaRef.isAcceptableNestedNameSpecifier(ND);
856}
857
858/// \brief Determines whether the given declaration is an enumeration.
859bool ResultBuilder::IsEnum(NamedDecl *ND) const {
860 return isa<EnumDecl>(ND);
861}
862
863/// \brief Determines whether the given declaration is a class or struct.
864bool ResultBuilder::IsClassOrStruct(NamedDecl *ND) const {
865 // Allow us to find class templates, too.
866 if (ClassTemplateDecl *ClassTemplate = dyn_cast<ClassTemplateDecl>(ND))
867 ND = ClassTemplate->getTemplatedDecl();
868
869 if (RecordDecl *RD = dyn_cast<RecordDecl>(ND))
Abramo Bagnara6150c882010-05-11 21:36:43 +0000870 return RD->getTagKind() == TTK_Class ||
871 RD->getTagKind() == TTK_Struct;
Douglas Gregor3545ff42009-09-21 16:56:56 +0000872
873 return false;
874}
875
876/// \brief Determines whether the given declaration is a union.
877bool ResultBuilder::IsUnion(NamedDecl *ND) const {
878 // Allow us to find class templates, too.
879 if (ClassTemplateDecl *ClassTemplate = dyn_cast<ClassTemplateDecl>(ND))
880 ND = ClassTemplate->getTemplatedDecl();
881
882 if (RecordDecl *RD = dyn_cast<RecordDecl>(ND))
Abramo Bagnara6150c882010-05-11 21:36:43 +0000883 return RD->getTagKind() == TTK_Union;
Douglas Gregor3545ff42009-09-21 16:56:56 +0000884
885 return false;
886}
887
888/// \brief Determines whether the given declaration is a namespace.
889bool ResultBuilder::IsNamespace(NamedDecl *ND) const {
890 return isa<NamespaceDecl>(ND);
891}
892
893/// \brief Determines whether the given declaration is a namespace or
894/// namespace alias.
895bool ResultBuilder::IsNamespaceOrAlias(NamedDecl *ND) const {
896 return isa<NamespaceDecl>(ND) || isa<NamespaceAliasDecl>(ND);
897}
898
Douglas Gregor99fe2ad2009-12-11 17:31:05 +0000899/// \brief Determines whether the given declaration is a type.
Douglas Gregor3545ff42009-09-21 16:56:56 +0000900bool ResultBuilder::IsType(NamedDecl *ND) const {
Douglas Gregor99fa2642010-08-24 01:06:58 +0000901 if (UsingShadowDecl *Using = dyn_cast<UsingShadowDecl>(ND))
902 ND = Using->getTargetDecl();
903
904 return isa<TypeDecl>(ND) || isa<ObjCInterfaceDecl>(ND);
Douglas Gregor3545ff42009-09-21 16:56:56 +0000905}
906
Douglas Gregor99fe2ad2009-12-11 17:31:05 +0000907/// \brief Determines which members of a class should be visible via
908/// "." or "->". Only value declarations, nested name specifiers, and
909/// using declarations thereof should show up.
Douglas Gregore412a5a2009-09-23 22:26:46 +0000910bool ResultBuilder::IsMember(NamedDecl *ND) const {
Douglas Gregor99fe2ad2009-12-11 17:31:05 +0000911 if (UsingShadowDecl *Using = dyn_cast<UsingShadowDecl>(ND))
912 ND = Using->getTargetDecl();
913
Douglas Gregor70788392009-12-11 18:14:22 +0000914 return isa<ValueDecl>(ND) || isa<FunctionTemplateDecl>(ND) ||
915 isa<ObjCPropertyDecl>(ND);
Douglas Gregore412a5a2009-09-23 22:26:46 +0000916}
917
Douglas Gregora817a192010-05-27 23:06:34 +0000918static bool isObjCReceiverType(ASTContext &C, QualType T) {
919 T = C.getCanonicalType(T);
920 switch (T->getTypeClass()) {
921 case Type::ObjCObject:
922 case Type::ObjCInterface:
923 case Type::ObjCObjectPointer:
924 return true;
925
926 case Type::Builtin:
927 switch (cast<BuiltinType>(T)->getKind()) {
928 case BuiltinType::ObjCId:
929 case BuiltinType::ObjCClass:
930 case BuiltinType::ObjCSel:
931 return true;
932
933 default:
934 break;
935 }
936 return false;
937
938 default:
939 break;
940 }
941
942 if (!C.getLangOptions().CPlusPlus)
943 return false;
944
945 // FIXME: We could perform more analysis here to determine whether a
946 // particular class type has any conversions to Objective-C types. For now,
947 // just accept all class types.
948 return T->isDependentType() || T->isRecordType();
949}
950
951bool ResultBuilder::IsObjCMessageReceiver(NamedDecl *ND) const {
952 QualType T = getDeclUsageType(SemaRef.Context, ND);
953 if (T.isNull())
954 return false;
955
956 T = SemaRef.Context.getBaseElementType(T);
957 return isObjCReceiverType(SemaRef.Context, T);
958}
959
Douglas Gregor68762e72010-08-23 21:17:50 +0000960bool ResultBuilder::IsObjCCollection(NamedDecl *ND) const {
961 if ((SemaRef.getLangOptions().CPlusPlus && !IsOrdinaryName(ND)) ||
962 (!SemaRef.getLangOptions().CPlusPlus && !IsOrdinaryNonTypeName(ND)))
963 return false;
964
965 QualType T = getDeclUsageType(SemaRef.Context, ND);
966 if (T.isNull())
967 return false;
968
969 T = SemaRef.Context.getBaseElementType(T);
970 return T->isObjCObjectType() || T->isObjCObjectPointerType() ||
971 T->isObjCIdType() ||
972 (SemaRef.getLangOptions().CPlusPlus && T->isRecordType());
973}
Douglas Gregora817a192010-05-27 23:06:34 +0000974
Douglas Gregor2b8162b2010-01-14 16:08:12 +0000975/// \rief Determines whether the given declaration is an Objective-C
976/// instance variable.
977bool ResultBuilder::IsObjCIvar(NamedDecl *ND) const {
978 return isa<ObjCIvarDecl>(ND);
979}
980
Douglas Gregorc580c522010-01-14 01:09:38 +0000981namespace {
982 /// \brief Visible declaration consumer that adds a code-completion result
983 /// for each visible declaration.
984 class CodeCompletionDeclConsumer : public VisibleDeclConsumer {
985 ResultBuilder &Results;
986 DeclContext *CurContext;
987
988 public:
989 CodeCompletionDeclConsumer(ResultBuilder &Results, DeclContext *CurContext)
990 : Results(Results), CurContext(CurContext) { }
991
Douglas Gregor09bbc652010-01-14 15:47:35 +0000992 virtual void FoundDecl(NamedDecl *ND, NamedDecl *Hiding, bool InBaseClass) {
993 Results.AddResult(ND, CurContext, Hiding, InBaseClass);
Douglas Gregorc580c522010-01-14 01:09:38 +0000994 }
995 };
996}
997
Douglas Gregor3545ff42009-09-21 16:56:56 +0000998/// \brief Add type specifiers for the current language as keyword results.
Douglas Gregorf98e6a22010-01-13 23:51:12 +0000999static void AddTypeSpecifierResults(const LangOptions &LangOpts,
Douglas Gregor3545ff42009-09-21 16:56:56 +00001000 ResultBuilder &Results) {
1001 typedef CodeCompleteConsumer::Result Result;
Douglas Gregora2db7932010-05-26 22:00:08 +00001002 Results.AddResult(Result("short", CCP_Type));
1003 Results.AddResult(Result("long", CCP_Type));
1004 Results.AddResult(Result("signed", CCP_Type));
1005 Results.AddResult(Result("unsigned", CCP_Type));
1006 Results.AddResult(Result("void", CCP_Type));
1007 Results.AddResult(Result("char", CCP_Type));
1008 Results.AddResult(Result("int", CCP_Type));
1009 Results.AddResult(Result("float", CCP_Type));
1010 Results.AddResult(Result("double", CCP_Type));
1011 Results.AddResult(Result("enum", CCP_Type));
1012 Results.AddResult(Result("struct", CCP_Type));
1013 Results.AddResult(Result("union", CCP_Type));
1014 Results.AddResult(Result("const", CCP_Type));
1015 Results.AddResult(Result("volatile", CCP_Type));
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001016
Douglas Gregor3545ff42009-09-21 16:56:56 +00001017 if (LangOpts.C99) {
1018 // C99-specific
Douglas Gregora2db7932010-05-26 22:00:08 +00001019 Results.AddResult(Result("_Complex", CCP_Type));
1020 Results.AddResult(Result("_Imaginary", CCP_Type));
1021 Results.AddResult(Result("_Bool", CCP_Type));
1022 Results.AddResult(Result("restrict", CCP_Type));
Douglas Gregor3545ff42009-09-21 16:56:56 +00001023 }
1024
1025 if (LangOpts.CPlusPlus) {
1026 // C++-specific
Douglas Gregora2db7932010-05-26 22:00:08 +00001027 Results.AddResult(Result("bool", CCP_Type));
1028 Results.AddResult(Result("class", CCP_Type));
1029 Results.AddResult(Result("wchar_t", CCP_Type));
Douglas Gregor3545ff42009-09-21 16:56:56 +00001030
Douglas Gregorf4c33342010-05-28 00:22:41 +00001031 // typename qualified-id
1032 CodeCompletionString *Pattern = new CodeCompletionString;
1033 Pattern->AddTypedTextChunk("typename");
1034 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
1035 Pattern->AddPlaceholderChunk("qualifier");
1036 Pattern->AddTextChunk("::");
1037 Pattern->AddPlaceholderChunk("name");
1038 Results.AddResult(Result(Pattern));
Douglas Gregorf64acca2010-05-25 21:41:55 +00001039
Douglas Gregor3545ff42009-09-21 16:56:56 +00001040 if (LangOpts.CPlusPlus0x) {
Douglas Gregora2db7932010-05-26 22:00:08 +00001041 Results.AddResult(Result("auto", CCP_Type));
1042 Results.AddResult(Result("char16_t", CCP_Type));
1043 Results.AddResult(Result("char32_t", CCP_Type));
Douglas Gregorf4c33342010-05-28 00:22:41 +00001044
1045 CodeCompletionString *Pattern = new CodeCompletionString;
1046 Pattern->AddTypedTextChunk("decltype");
1047 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
1048 Pattern->AddPlaceholderChunk("expression");
1049 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
1050 Results.AddResult(Result(Pattern));
Douglas Gregor3545ff42009-09-21 16:56:56 +00001051 }
1052 }
1053
1054 // GNU extensions
1055 if (LangOpts.GNUMode) {
1056 // FIXME: Enable when we actually support decimal floating point.
Douglas Gregor78a21012010-01-14 16:01:26 +00001057 // Results.AddResult(Result("_Decimal32"));
1058 // Results.AddResult(Result("_Decimal64"));
1059 // Results.AddResult(Result("_Decimal128"));
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001060
Douglas Gregorf4c33342010-05-28 00:22:41 +00001061 CodeCompletionString *Pattern = new CodeCompletionString;
1062 Pattern->AddTypedTextChunk("typeof");
1063 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
1064 Pattern->AddPlaceholderChunk("expression");
1065 Results.AddResult(Result(Pattern));
1066
1067 Pattern = new CodeCompletionString;
1068 Pattern->AddTypedTextChunk("typeof");
1069 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
1070 Pattern->AddPlaceholderChunk("type");
1071 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
1072 Results.AddResult(Result(Pattern));
Douglas Gregor3545ff42009-09-21 16:56:56 +00001073 }
1074}
1075
Douglas Gregor00c37ef2010-08-11 21:23:17 +00001076static void AddStorageSpecifiers(Action::ParserCompletionContext CCC,
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001077 const LangOptions &LangOpts,
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001078 ResultBuilder &Results) {
1079 typedef CodeCompleteConsumer::Result Result;
1080 // Note: we don't suggest either "auto" or "register", because both
1081 // are pointless as storage specifiers. Elsewhere, we suggest "auto"
1082 // in C++0x as a type specifier.
Douglas Gregor78a21012010-01-14 16:01:26 +00001083 Results.AddResult(Result("extern"));
1084 Results.AddResult(Result("static"));
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001085}
1086
Douglas Gregor00c37ef2010-08-11 21:23:17 +00001087static void AddFunctionSpecifiers(Action::ParserCompletionContext CCC,
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001088 const LangOptions &LangOpts,
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001089 ResultBuilder &Results) {
1090 typedef CodeCompleteConsumer::Result Result;
1091 switch (CCC) {
Douglas Gregor00c37ef2010-08-11 21:23:17 +00001092 case Action::PCC_Class:
1093 case Action::PCC_MemberTemplate:
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001094 if (LangOpts.CPlusPlus) {
Douglas Gregor78a21012010-01-14 16:01:26 +00001095 Results.AddResult(Result("explicit"));
1096 Results.AddResult(Result("friend"));
1097 Results.AddResult(Result("mutable"));
1098 Results.AddResult(Result("virtual"));
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001099 }
1100 // Fall through
1101
Douglas Gregor00c37ef2010-08-11 21:23:17 +00001102 case Action::PCC_ObjCInterface:
1103 case Action::PCC_ObjCImplementation:
1104 case Action::PCC_Namespace:
1105 case Action::PCC_Template:
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001106 if (LangOpts.CPlusPlus || LangOpts.C99)
Douglas Gregor78a21012010-01-14 16:01:26 +00001107 Results.AddResult(Result("inline"));
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001108 break;
1109
Douglas Gregor00c37ef2010-08-11 21:23:17 +00001110 case Action::PCC_ObjCInstanceVariableList:
1111 case Action::PCC_Expression:
1112 case Action::PCC_Statement:
1113 case Action::PCC_ForInit:
1114 case Action::PCC_Condition:
1115 case Action::PCC_RecoveryInFunction:
Douglas Gregor99fa2642010-08-24 01:06:58 +00001116 case Action::PCC_Type:
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001117 break;
1118 }
1119}
1120
Douglas Gregorf98e6a22010-01-13 23:51:12 +00001121static void AddObjCExpressionResults(ResultBuilder &Results, bool NeedAt);
1122static void AddObjCStatementResults(ResultBuilder &Results, bool NeedAt);
1123static void AddObjCVisibilityResults(const LangOptions &LangOpts,
Douglas Gregor48d46252010-01-13 21:54:15 +00001124 ResultBuilder &Results,
1125 bool NeedAt);
Douglas Gregorf98e6a22010-01-13 23:51:12 +00001126static void AddObjCImplementationResults(const LangOptions &LangOpts,
Douglas Gregorf1934162010-01-13 21:24:21 +00001127 ResultBuilder &Results,
1128 bool NeedAt);
Douglas Gregorf98e6a22010-01-13 23:51:12 +00001129static void AddObjCInterfaceResults(const LangOptions &LangOpts,
Douglas Gregorf1934162010-01-13 21:24:21 +00001130 ResultBuilder &Results,
1131 bool NeedAt);
Douglas Gregorf98e6a22010-01-13 23:51:12 +00001132static void AddObjCTopLevelResults(ResultBuilder &Results, bool NeedAt);
Douglas Gregorf1934162010-01-13 21:24:21 +00001133
Douglas Gregorf4c33342010-05-28 00:22:41 +00001134static void AddTypedefResult(ResultBuilder &Results) {
1135 CodeCompletionString *Pattern = new CodeCompletionString;
1136 Pattern->AddTypedTextChunk("typedef");
1137 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
1138 Pattern->AddPlaceholderChunk("type");
1139 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
1140 Pattern->AddPlaceholderChunk("name");
1141 Results.AddResult(CodeCompleteConsumer::Result(Pattern));
1142}
1143
Douglas Gregor00c37ef2010-08-11 21:23:17 +00001144static bool WantTypesInContext(Action::ParserCompletionContext CCC,
Douglas Gregor70febae2010-05-28 00:49:12 +00001145 const LangOptions &LangOpts) {
1146 if (LangOpts.CPlusPlus)
1147 return true;
1148
1149 switch (CCC) {
Douglas Gregor00c37ef2010-08-11 21:23:17 +00001150 case Action::PCC_Namespace:
1151 case Action::PCC_Class:
1152 case Action::PCC_ObjCInstanceVariableList:
1153 case Action::PCC_Template:
1154 case Action::PCC_MemberTemplate:
1155 case Action::PCC_Statement:
1156 case Action::PCC_RecoveryInFunction:
Douglas Gregor99fa2642010-08-24 01:06:58 +00001157 case Action::PCC_Type:
Douglas Gregor70febae2010-05-28 00:49:12 +00001158 return true;
1159
Douglas Gregor00c37ef2010-08-11 21:23:17 +00001160 case Action::PCC_ObjCInterface:
1161 case Action::PCC_ObjCImplementation:
1162 case Action::PCC_Expression:
1163 case Action::PCC_Condition:
Douglas Gregor70febae2010-05-28 00:49:12 +00001164 return false;
1165
Douglas Gregor00c37ef2010-08-11 21:23:17 +00001166 case Action::PCC_ForInit:
Douglas Gregor70febae2010-05-28 00:49:12 +00001167 return LangOpts.ObjC1 || LangOpts.C99;
1168 }
1169
1170 return false;
1171}
1172
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001173/// \brief Add language constructs that show up for "ordinary" names.
Douglas Gregor00c37ef2010-08-11 21:23:17 +00001174static void AddOrdinaryNameResults(Action::ParserCompletionContext CCC,
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001175 Scope *S,
1176 Sema &SemaRef,
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001177 ResultBuilder &Results) {
1178 typedef CodeCompleteConsumer::Result Result;
1179 switch (CCC) {
Douglas Gregor00c37ef2010-08-11 21:23:17 +00001180 case Action::PCC_Namespace:
Douglas Gregorf4c33342010-05-28 00:22:41 +00001181 if (SemaRef.getLangOptions().CPlusPlus) {
1182 CodeCompletionString *Pattern = 0;
1183
1184 if (Results.includeCodePatterns()) {
1185 // namespace <identifier> { declarations }
1186 CodeCompletionString *Pattern = new CodeCompletionString;
1187 Pattern->AddTypedTextChunk("namespace");
1188 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
1189 Pattern->AddPlaceholderChunk("identifier");
1190 Pattern->AddChunk(CodeCompletionString::CK_LeftBrace);
1191 Pattern->AddPlaceholderChunk("declarations");
1192 Pattern->AddChunk(CodeCompletionString::CK_VerticalSpace);
1193 Pattern->AddChunk(CodeCompletionString::CK_RightBrace);
1194 Results.AddResult(Result(Pattern));
1195 }
1196
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001197 // namespace identifier = identifier ;
1198 Pattern = new CodeCompletionString;
1199 Pattern->AddTypedTextChunk("namespace");
1200 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
Douglas Gregorf4c33342010-05-28 00:22:41 +00001201 Pattern->AddPlaceholderChunk("name");
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001202 Pattern->AddChunk(CodeCompletionString::CK_Equal);
Douglas Gregorf4c33342010-05-28 00:22:41 +00001203 Pattern->AddPlaceholderChunk("namespace");
Douglas Gregor78a21012010-01-14 16:01:26 +00001204 Results.AddResult(Result(Pattern));
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001205
1206 // Using directives
1207 Pattern = new CodeCompletionString;
1208 Pattern->AddTypedTextChunk("using");
1209 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
1210 Pattern->AddTextChunk("namespace");
1211 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
1212 Pattern->AddPlaceholderChunk("identifier");
Douglas Gregor78a21012010-01-14 16:01:26 +00001213 Results.AddResult(Result(Pattern));
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001214
1215 // asm(string-literal)
1216 Pattern = new CodeCompletionString;
1217 Pattern->AddTypedTextChunk("asm");
1218 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
1219 Pattern->AddPlaceholderChunk("string-literal");
1220 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
Douglas Gregor78a21012010-01-14 16:01:26 +00001221 Results.AddResult(Result(Pattern));
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001222
Douglas Gregorf4c33342010-05-28 00:22:41 +00001223 if (Results.includeCodePatterns()) {
1224 // Explicit template instantiation
1225 Pattern = new CodeCompletionString;
1226 Pattern->AddTypedTextChunk("template");
1227 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
1228 Pattern->AddPlaceholderChunk("declaration");
1229 Results.AddResult(Result(Pattern));
1230 }
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001231 }
Douglas Gregorf1934162010-01-13 21:24:21 +00001232
1233 if (SemaRef.getLangOptions().ObjC1)
Douglas Gregorf98e6a22010-01-13 23:51:12 +00001234 AddObjCTopLevelResults(Results, true);
Douglas Gregorf1934162010-01-13 21:24:21 +00001235
Douglas Gregorf4c33342010-05-28 00:22:41 +00001236 AddTypedefResult(Results);
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001237 // Fall through
1238
Douglas Gregor00c37ef2010-08-11 21:23:17 +00001239 case Action::PCC_Class:
Douglas Gregorf4c33342010-05-28 00:22:41 +00001240 if (SemaRef.getLangOptions().CPlusPlus) {
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001241 // Using declaration
1242 CodeCompletionString *Pattern = new CodeCompletionString;
1243 Pattern->AddTypedTextChunk("using");
1244 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
Douglas Gregorf4c33342010-05-28 00:22:41 +00001245 Pattern->AddPlaceholderChunk("qualifier");
1246 Pattern->AddTextChunk("::");
1247 Pattern->AddPlaceholderChunk("name");
Douglas Gregor78a21012010-01-14 16:01:26 +00001248 Results.AddResult(Result(Pattern));
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001249
Douglas Gregorf4c33342010-05-28 00:22:41 +00001250 // using typename qualifier::name (only in a dependent context)
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001251 if (SemaRef.CurContext->isDependentContext()) {
1252 Pattern = new CodeCompletionString;
1253 Pattern->AddTypedTextChunk("using");
1254 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
1255 Pattern->AddTextChunk("typename");
1256 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
Douglas Gregorf4c33342010-05-28 00:22:41 +00001257 Pattern->AddPlaceholderChunk("qualifier");
1258 Pattern->AddTextChunk("::");
1259 Pattern->AddPlaceholderChunk("name");
Douglas Gregor78a21012010-01-14 16:01:26 +00001260 Results.AddResult(Result(Pattern));
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001261 }
1262
Douglas Gregor00c37ef2010-08-11 21:23:17 +00001263 if (CCC == Action::PCC_Class) {
Douglas Gregorf4c33342010-05-28 00:22:41 +00001264 AddTypedefResult(Results);
1265
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001266 // public:
1267 Pattern = new CodeCompletionString;
1268 Pattern->AddTypedTextChunk("public");
1269 Pattern->AddChunk(CodeCompletionString::CK_Colon);
Douglas Gregor78a21012010-01-14 16:01:26 +00001270 Results.AddResult(Result(Pattern));
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001271
1272 // protected:
1273 Pattern = new CodeCompletionString;
1274 Pattern->AddTypedTextChunk("protected");
1275 Pattern->AddChunk(CodeCompletionString::CK_Colon);
Douglas Gregor78a21012010-01-14 16:01:26 +00001276 Results.AddResult(Result(Pattern));
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001277
1278 // private:
1279 Pattern = new CodeCompletionString;
1280 Pattern->AddTypedTextChunk("private");
1281 Pattern->AddChunk(CodeCompletionString::CK_Colon);
Douglas Gregor78a21012010-01-14 16:01:26 +00001282 Results.AddResult(Result(Pattern));
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001283 }
1284 }
1285 // Fall through
1286
Douglas Gregor00c37ef2010-08-11 21:23:17 +00001287 case Action::PCC_Template:
1288 case Action::PCC_MemberTemplate:
Douglas Gregorf64acca2010-05-25 21:41:55 +00001289 if (SemaRef.getLangOptions().CPlusPlus && Results.includeCodePatterns()) {
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001290 // template < parameters >
1291 CodeCompletionString *Pattern = new CodeCompletionString;
1292 Pattern->AddTypedTextChunk("template");
1293 Pattern->AddChunk(CodeCompletionString::CK_LeftAngle);
1294 Pattern->AddPlaceholderChunk("parameters");
1295 Pattern->AddChunk(CodeCompletionString::CK_RightAngle);
Douglas Gregor78a21012010-01-14 16:01:26 +00001296 Results.AddResult(Result(Pattern));
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001297 }
1298
Douglas Gregorf98e6a22010-01-13 23:51:12 +00001299 AddStorageSpecifiers(CCC, SemaRef.getLangOptions(), Results);
1300 AddFunctionSpecifiers(CCC, SemaRef.getLangOptions(), Results);
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001301 break;
1302
Douglas Gregor00c37ef2010-08-11 21:23:17 +00001303 case Action::PCC_ObjCInterface:
Douglas Gregorf98e6a22010-01-13 23:51:12 +00001304 AddObjCInterfaceResults(SemaRef.getLangOptions(), Results, true);
1305 AddStorageSpecifiers(CCC, SemaRef.getLangOptions(), Results);
1306 AddFunctionSpecifiers(CCC, SemaRef.getLangOptions(), Results);
Douglas Gregorf1934162010-01-13 21:24:21 +00001307 break;
1308
Douglas Gregor00c37ef2010-08-11 21:23:17 +00001309 case Action::PCC_ObjCImplementation:
Douglas Gregorf98e6a22010-01-13 23:51:12 +00001310 AddObjCImplementationResults(SemaRef.getLangOptions(), Results, true);
1311 AddStorageSpecifiers(CCC, SemaRef.getLangOptions(), Results);
1312 AddFunctionSpecifiers(CCC, SemaRef.getLangOptions(), Results);
Douglas Gregorf1934162010-01-13 21:24:21 +00001313 break;
1314
Douglas Gregor00c37ef2010-08-11 21:23:17 +00001315 case Action::PCC_ObjCInstanceVariableList:
Douglas Gregorf98e6a22010-01-13 23:51:12 +00001316 AddObjCVisibilityResults(SemaRef.getLangOptions(), Results, true);
Douglas Gregor48d46252010-01-13 21:54:15 +00001317 break;
1318
Douglas Gregor00c37ef2010-08-11 21:23:17 +00001319 case Action::PCC_RecoveryInFunction:
1320 case Action::PCC_Statement: {
Douglas Gregorf4c33342010-05-28 00:22:41 +00001321 AddTypedefResult(Results);
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001322
1323 CodeCompletionString *Pattern = 0;
Douglas Gregorf64acca2010-05-25 21:41:55 +00001324 if (SemaRef.getLangOptions().CPlusPlus && Results.includeCodePatterns()) {
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001325 Pattern = new CodeCompletionString;
1326 Pattern->AddTypedTextChunk("try");
1327 Pattern->AddChunk(CodeCompletionString::CK_LeftBrace);
1328 Pattern->AddPlaceholderChunk("statements");
1329 Pattern->AddChunk(CodeCompletionString::CK_VerticalSpace);
1330 Pattern->AddChunk(CodeCompletionString::CK_RightBrace);
1331 Pattern->AddTextChunk("catch");
1332 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
1333 Pattern->AddPlaceholderChunk("declaration");
1334 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
1335 Pattern->AddChunk(CodeCompletionString::CK_LeftBrace);
1336 Pattern->AddPlaceholderChunk("statements");
1337 Pattern->AddChunk(CodeCompletionString::CK_VerticalSpace);
1338 Pattern->AddChunk(CodeCompletionString::CK_RightBrace);
Douglas Gregor78a21012010-01-14 16:01:26 +00001339 Results.AddResult(Result(Pattern));
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001340 }
Douglas Gregorf1934162010-01-13 21:24:21 +00001341 if (SemaRef.getLangOptions().ObjC1)
Douglas Gregorf98e6a22010-01-13 23:51:12 +00001342 AddObjCStatementResults(Results, true);
Douglas Gregorf1934162010-01-13 21:24:21 +00001343
Douglas Gregorf64acca2010-05-25 21:41:55 +00001344 if (Results.includeCodePatterns()) {
1345 // if (condition) { statements }
1346 Pattern = new CodeCompletionString;
1347 Pattern->AddTypedTextChunk("if");
1348 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
1349 if (SemaRef.getLangOptions().CPlusPlus)
1350 Pattern->AddPlaceholderChunk("condition");
1351 else
1352 Pattern->AddPlaceholderChunk("expression");
1353 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
1354 Pattern->AddChunk(CodeCompletionString::CK_LeftBrace);
1355 Pattern->AddPlaceholderChunk("statements");
1356 Pattern->AddChunk(CodeCompletionString::CK_VerticalSpace);
1357 Pattern->AddChunk(CodeCompletionString::CK_RightBrace);
1358 Results.AddResult(Result(Pattern));
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001359
Douglas Gregorf64acca2010-05-25 21:41:55 +00001360 // switch (condition) { }
1361 Pattern = new CodeCompletionString;
1362 Pattern->AddTypedTextChunk("switch");
1363 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
1364 if (SemaRef.getLangOptions().CPlusPlus)
1365 Pattern->AddPlaceholderChunk("condition");
1366 else
1367 Pattern->AddPlaceholderChunk("expression");
1368 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
1369 Pattern->AddChunk(CodeCompletionString::CK_LeftBrace);
1370 Pattern->AddChunk(CodeCompletionString::CK_VerticalSpace);
1371 Pattern->AddChunk(CodeCompletionString::CK_RightBrace);
1372 Results.AddResult(Result(Pattern));
1373 }
1374
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001375 // Switch-specific statements.
Douglas Gregorf4c33342010-05-28 00:22:41 +00001376 if (!SemaRef.getSwitchStack().empty()) {
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001377 // case expression:
1378 Pattern = new CodeCompletionString;
1379 Pattern->AddTypedTextChunk("case");
Douglas Gregorf4c33342010-05-28 00:22:41 +00001380 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001381 Pattern->AddPlaceholderChunk("expression");
1382 Pattern->AddChunk(CodeCompletionString::CK_Colon);
Douglas Gregor78a21012010-01-14 16:01:26 +00001383 Results.AddResult(Result(Pattern));
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001384
1385 // default:
1386 Pattern = new CodeCompletionString;
1387 Pattern->AddTypedTextChunk("default");
1388 Pattern->AddChunk(CodeCompletionString::CK_Colon);
Douglas Gregor78a21012010-01-14 16:01:26 +00001389 Results.AddResult(Result(Pattern));
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001390 }
1391
Douglas Gregorf64acca2010-05-25 21:41:55 +00001392 if (Results.includeCodePatterns()) {
1393 /// while (condition) { statements }
1394 Pattern = new CodeCompletionString;
1395 Pattern->AddTypedTextChunk("while");
1396 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
1397 if (SemaRef.getLangOptions().CPlusPlus)
1398 Pattern->AddPlaceholderChunk("condition");
1399 else
1400 Pattern->AddPlaceholderChunk("expression");
1401 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
1402 Pattern->AddChunk(CodeCompletionString::CK_LeftBrace);
1403 Pattern->AddPlaceholderChunk("statements");
1404 Pattern->AddChunk(CodeCompletionString::CK_VerticalSpace);
1405 Pattern->AddChunk(CodeCompletionString::CK_RightBrace);
1406 Results.AddResult(Result(Pattern));
1407
1408 // do { statements } while ( expression );
1409 Pattern = new CodeCompletionString;
1410 Pattern->AddTypedTextChunk("do");
1411 Pattern->AddChunk(CodeCompletionString::CK_LeftBrace);
1412 Pattern->AddPlaceholderChunk("statements");
1413 Pattern->AddChunk(CodeCompletionString::CK_VerticalSpace);
1414 Pattern->AddChunk(CodeCompletionString::CK_RightBrace);
1415 Pattern->AddTextChunk("while");
1416 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001417 Pattern->AddPlaceholderChunk("expression");
Douglas Gregorf64acca2010-05-25 21:41:55 +00001418 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
1419 Results.AddResult(Result(Pattern));
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001420
Douglas Gregorf64acca2010-05-25 21:41:55 +00001421 // for ( for-init-statement ; condition ; expression ) { statements }
1422 Pattern = new CodeCompletionString;
1423 Pattern->AddTypedTextChunk("for");
1424 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
1425 if (SemaRef.getLangOptions().CPlusPlus || SemaRef.getLangOptions().C99)
1426 Pattern->AddPlaceholderChunk("init-statement");
1427 else
1428 Pattern->AddPlaceholderChunk("init-expression");
1429 Pattern->AddChunk(CodeCompletionString::CK_SemiColon);
1430 Pattern->AddPlaceholderChunk("condition");
1431 Pattern->AddChunk(CodeCompletionString::CK_SemiColon);
1432 Pattern->AddPlaceholderChunk("inc-expression");
1433 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
1434 Pattern->AddChunk(CodeCompletionString::CK_LeftBrace);
1435 Pattern->AddPlaceholderChunk("statements");
1436 Pattern->AddChunk(CodeCompletionString::CK_VerticalSpace);
1437 Pattern->AddChunk(CodeCompletionString::CK_RightBrace);
1438 Results.AddResult(Result(Pattern));
1439 }
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001440
1441 if (S->getContinueParent()) {
1442 // continue ;
1443 Pattern = new CodeCompletionString;
1444 Pattern->AddTypedTextChunk("continue");
Douglas Gregor78a21012010-01-14 16:01:26 +00001445 Results.AddResult(Result(Pattern));
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001446 }
1447
1448 if (S->getBreakParent()) {
1449 // break ;
1450 Pattern = new CodeCompletionString;
1451 Pattern->AddTypedTextChunk("break");
Douglas Gregor78a21012010-01-14 16:01:26 +00001452 Results.AddResult(Result(Pattern));
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001453 }
1454
1455 // "return expression ;" or "return ;", depending on whether we
1456 // know the function is void or not.
1457 bool isVoid = false;
1458 if (FunctionDecl *Function = dyn_cast<FunctionDecl>(SemaRef.CurContext))
1459 isVoid = Function->getResultType()->isVoidType();
1460 else if (ObjCMethodDecl *Method
1461 = dyn_cast<ObjCMethodDecl>(SemaRef.CurContext))
1462 isVoid = Method->getResultType()->isVoidType();
Douglas Gregor9a28e842010-03-01 23:15:13 +00001463 else if (SemaRef.getCurBlock() &&
1464 !SemaRef.getCurBlock()->ReturnType.isNull())
1465 isVoid = SemaRef.getCurBlock()->ReturnType->isVoidType();
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001466 Pattern = new CodeCompletionString;
1467 Pattern->AddTypedTextChunk("return");
Douglas Gregor44272ca2010-02-18 04:06:48 +00001468 if (!isVoid) {
1469 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001470 Pattern->AddPlaceholderChunk("expression");
Douglas Gregor44272ca2010-02-18 04:06:48 +00001471 }
Douglas Gregor78a21012010-01-14 16:01:26 +00001472 Results.AddResult(Result(Pattern));
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001473
Douglas Gregorf4c33342010-05-28 00:22:41 +00001474 // goto identifier ;
1475 Pattern = new CodeCompletionString;
1476 Pattern->AddTypedTextChunk("goto");
1477 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
1478 Pattern->AddPlaceholderChunk("label");
1479 Results.AddResult(Result(Pattern));
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001480
Douglas Gregorf4c33342010-05-28 00:22:41 +00001481 // Using directives
1482 Pattern = new CodeCompletionString;
1483 Pattern->AddTypedTextChunk("using");
1484 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
1485 Pattern->AddTextChunk("namespace");
1486 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
1487 Pattern->AddPlaceholderChunk("identifier");
1488 Results.AddResult(Result(Pattern));
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001489 }
1490
1491 // Fall through (for statement expressions).
Douglas Gregor00c37ef2010-08-11 21:23:17 +00001492 case Action::PCC_ForInit:
1493 case Action::PCC_Condition:
Douglas Gregorf98e6a22010-01-13 23:51:12 +00001494 AddStorageSpecifiers(CCC, SemaRef.getLangOptions(), Results);
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001495 // Fall through: conditions and statements can have expressions.
1496
Douglas Gregor00c37ef2010-08-11 21:23:17 +00001497 case Action::PCC_Expression: {
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001498 CodeCompletionString *Pattern = 0;
1499 if (SemaRef.getLangOptions().CPlusPlus) {
1500 // 'this', if we're in a non-static member function.
1501 if (CXXMethodDecl *Method = dyn_cast<CXXMethodDecl>(SemaRef.CurContext))
1502 if (!Method->isStatic())
Douglas Gregor78a21012010-01-14 16:01:26 +00001503 Results.AddResult(Result("this"));
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001504
1505 // true, false
Douglas Gregor78a21012010-01-14 16:01:26 +00001506 Results.AddResult(Result("true"));
1507 Results.AddResult(Result("false"));
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001508
Douglas Gregorf4c33342010-05-28 00:22:41 +00001509 // dynamic_cast < type-id > ( expression )
1510 Pattern = new CodeCompletionString;
1511 Pattern->AddTypedTextChunk("dynamic_cast");
1512 Pattern->AddChunk(CodeCompletionString::CK_LeftAngle);
1513 Pattern->AddPlaceholderChunk("type");
1514 Pattern->AddChunk(CodeCompletionString::CK_RightAngle);
1515 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
1516 Pattern->AddPlaceholderChunk("expression");
1517 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
1518 Results.AddResult(Result(Pattern));
1519
1520 // static_cast < type-id > ( expression )
1521 Pattern = new CodeCompletionString;
1522 Pattern->AddTypedTextChunk("static_cast");
1523 Pattern->AddChunk(CodeCompletionString::CK_LeftAngle);
1524 Pattern->AddPlaceholderChunk("type");
1525 Pattern->AddChunk(CodeCompletionString::CK_RightAngle);
1526 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
1527 Pattern->AddPlaceholderChunk("expression");
1528 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
1529 Results.AddResult(Result(Pattern));
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001530
Douglas Gregorf4c33342010-05-28 00:22:41 +00001531 // reinterpret_cast < type-id > ( expression )
1532 Pattern = new CodeCompletionString;
1533 Pattern->AddTypedTextChunk("reinterpret_cast");
1534 Pattern->AddChunk(CodeCompletionString::CK_LeftAngle);
1535 Pattern->AddPlaceholderChunk("type");
1536 Pattern->AddChunk(CodeCompletionString::CK_RightAngle);
1537 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
1538 Pattern->AddPlaceholderChunk("expression");
1539 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
1540 Results.AddResult(Result(Pattern));
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001541
Douglas Gregorf4c33342010-05-28 00:22:41 +00001542 // const_cast < type-id > ( expression )
1543 Pattern = new CodeCompletionString;
1544 Pattern->AddTypedTextChunk("const_cast");
1545 Pattern->AddChunk(CodeCompletionString::CK_LeftAngle);
1546 Pattern->AddPlaceholderChunk("type");
1547 Pattern->AddChunk(CodeCompletionString::CK_RightAngle);
1548 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
1549 Pattern->AddPlaceholderChunk("expression");
1550 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
1551 Results.AddResult(Result(Pattern));
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001552
Douglas Gregorf4c33342010-05-28 00:22:41 +00001553 // typeid ( expression-or-type )
1554 Pattern = new CodeCompletionString;
1555 Pattern->AddTypedTextChunk("typeid");
1556 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
1557 Pattern->AddPlaceholderChunk("expression-or-type");
1558 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
1559 Results.AddResult(Result(Pattern));
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001560
Douglas Gregorf4c33342010-05-28 00:22:41 +00001561 // new T ( ... )
1562 Pattern = new CodeCompletionString;
1563 Pattern->AddTypedTextChunk("new");
1564 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
1565 Pattern->AddPlaceholderChunk("type");
1566 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
1567 Pattern->AddPlaceholderChunk("expressions");
1568 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
1569 Results.AddResult(Result(Pattern));
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001570
Douglas Gregorf4c33342010-05-28 00:22:41 +00001571 // new T [ ] ( ... )
1572 Pattern = new CodeCompletionString;
1573 Pattern->AddTypedTextChunk("new");
1574 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
1575 Pattern->AddPlaceholderChunk("type");
1576 Pattern->AddChunk(CodeCompletionString::CK_LeftBracket);
1577 Pattern->AddPlaceholderChunk("size");
1578 Pattern->AddChunk(CodeCompletionString::CK_RightBracket);
1579 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
1580 Pattern->AddPlaceholderChunk("expressions");
1581 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
1582 Results.AddResult(Result(Pattern));
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001583
Douglas Gregorf4c33342010-05-28 00:22:41 +00001584 // delete expression
1585 Pattern = new CodeCompletionString;
1586 Pattern->AddTypedTextChunk("delete");
1587 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
1588 Pattern->AddPlaceholderChunk("expression");
1589 Results.AddResult(Result(Pattern));
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001590
Douglas Gregorf4c33342010-05-28 00:22:41 +00001591 // delete [] expression
1592 Pattern = new CodeCompletionString;
1593 Pattern->AddTypedTextChunk("delete");
1594 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
1595 Pattern->AddChunk(CodeCompletionString::CK_LeftBracket);
1596 Pattern->AddChunk(CodeCompletionString::CK_RightBracket);
1597 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
1598 Pattern->AddPlaceholderChunk("expression");
1599 Results.AddResult(Result(Pattern));
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001600
Douglas Gregorf4c33342010-05-28 00:22:41 +00001601 // throw expression
1602 Pattern = new CodeCompletionString;
1603 Pattern->AddTypedTextChunk("throw");
1604 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
1605 Pattern->AddPlaceholderChunk("expression");
1606 Results.AddResult(Result(Pattern));
Douglas Gregora2db7932010-05-26 22:00:08 +00001607
1608 // FIXME: Rethrow?
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001609 }
1610
1611 if (SemaRef.getLangOptions().ObjC1) {
1612 // Add "super", if we're in an Objective-C class with a superclass.
Ted Kremenek305a0a72010-05-31 21:43:10 +00001613 if (ObjCMethodDecl *Method = SemaRef.getCurMethodDecl()) {
1614 // The interface can be NULL.
1615 if (ObjCInterfaceDecl *ID = Method->getClassInterface())
1616 if (ID->getSuperClass())
1617 Results.AddResult(Result("super"));
1618 }
1619
Douglas Gregorf98e6a22010-01-13 23:51:12 +00001620 AddObjCExpressionResults(Results, true);
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001621 }
1622
Douglas Gregorf4c33342010-05-28 00:22:41 +00001623 // sizeof expression
1624 Pattern = new CodeCompletionString;
1625 Pattern->AddTypedTextChunk("sizeof");
1626 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
1627 Pattern->AddPlaceholderChunk("expression-or-type");
1628 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
1629 Results.AddResult(Result(Pattern));
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001630 break;
1631 }
Douglas Gregor99fa2642010-08-24 01:06:58 +00001632
1633 case Action::PCC_Type:
1634 break;
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001635 }
1636
Douglas Gregor70febae2010-05-28 00:49:12 +00001637 if (WantTypesInContext(CCC, SemaRef.getLangOptions()))
1638 AddTypeSpecifierResults(SemaRef.getLangOptions(), Results);
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001639
Douglas Gregor99fa2642010-08-24 01:06:58 +00001640 if (SemaRef.getLangOptions().CPlusPlus && CCC != Action::PCC_Type)
Douglas Gregor78a21012010-01-14 16:01:26 +00001641 Results.AddResult(Result("operator"));
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001642}
1643
Douglas Gregorb3fa9192009-12-18 18:53:37 +00001644/// \brief If the given declaration has an associated type, add it as a result
1645/// type chunk.
1646static void AddResultTypeChunk(ASTContext &Context,
1647 NamedDecl *ND,
1648 CodeCompletionString *Result) {
1649 if (!ND)
1650 return;
1651
1652 // Determine the type of the declaration (if it has a type).
1653 QualType T;
1654 if (FunctionDecl *Function = dyn_cast<FunctionDecl>(ND))
1655 T = Function->getResultType();
1656 else if (ObjCMethodDecl *Method = dyn_cast<ObjCMethodDecl>(ND))
1657 T = Method->getResultType();
1658 else if (FunctionTemplateDecl *FunTmpl = dyn_cast<FunctionTemplateDecl>(ND))
1659 T = FunTmpl->getTemplatedDecl()->getResultType();
1660 else if (EnumConstantDecl *Enumerator = dyn_cast<EnumConstantDecl>(ND))
1661 T = Context.getTypeDeclType(cast<TypeDecl>(Enumerator->getDeclContext()));
1662 else if (isa<UnresolvedUsingValueDecl>(ND)) {
1663 /* Do nothing: ignore unresolved using declarations*/
1664 } else if (ValueDecl *Value = dyn_cast<ValueDecl>(ND))
1665 T = Value->getType();
1666 else if (ObjCPropertyDecl *Property = dyn_cast<ObjCPropertyDecl>(ND))
1667 T = Property->getType();
1668
1669 if (T.isNull() || Context.hasSameType(T, Context.DependentTy))
1670 return;
1671
Douglas Gregorcf04b022010-04-05 21:25:31 +00001672 PrintingPolicy Policy(Context.PrintingPolicy);
1673 Policy.AnonymousTagLocations = false;
1674
Douglas Gregorb3fa9192009-12-18 18:53:37 +00001675 std::string TypeStr;
Douglas Gregorcf04b022010-04-05 21:25:31 +00001676 T.getAsStringInternal(TypeStr, Policy);
Douglas Gregorb3fa9192009-12-18 18:53:37 +00001677 Result->AddResultTypeChunk(TypeStr);
1678}
1679
Douglas Gregordbb71db2010-08-23 23:51:41 +00001680static void MaybeAddSentinel(ASTContext &Context, NamedDecl *FunctionOrMethod,
1681 CodeCompletionString *Result) {
1682 if (SentinelAttr *Sentinel = FunctionOrMethod->getAttr<SentinelAttr>())
1683 if (Sentinel->getSentinel() == 0) {
1684 if (Context.getLangOptions().ObjC1 &&
1685 Context.Idents.get("nil").hasMacroDefinition())
1686 Result->AddTextChunk(", nil");
1687 else if (Context.Idents.get("NULL").hasMacroDefinition())
1688 Result->AddTextChunk(", NULL");
1689 else
1690 Result->AddTextChunk(", (void*)0");
1691 }
1692}
1693
Douglas Gregore90dd002010-08-24 16:15:59 +00001694static std::string FormatFunctionParameter(ASTContext &Context,
1695 ParmVarDecl *Param) {
1696 bool ObjCMethodParam = isa<ObjCMethodDecl>(Param->getDeclContext());
1697 if (Param->getType()->isDependentType() ||
1698 !Param->getType()->isBlockPointerType()) {
1699 // The argument for a dependent or non-block parameter is a placeholder
1700 // containing that parameter's type.
1701 std::string Result;
1702
1703 if (Param->getIdentifier() && !ObjCMethodParam)
1704 Result = Param->getIdentifier()->getName();
1705
1706 Param->getType().getAsStringInternal(Result,
1707 Context.PrintingPolicy);
1708
1709 if (ObjCMethodParam) {
1710 Result = "(" + Result;
1711 Result += ")";
1712 if (Param->getIdentifier())
1713 Result += Param->getIdentifier()->getName();
1714 }
1715 return Result;
1716 }
1717
1718 // The argument for a block pointer parameter is a block literal with
1719 // the appropriate type.
1720 FunctionProtoTypeLoc *Block = 0;
1721 TypeLoc TL;
1722 if (TypeSourceInfo *TSInfo = Param->getTypeSourceInfo()) {
1723 TL = TSInfo->getTypeLoc().getUnqualifiedLoc();
1724 while (true) {
1725 // Look through typedefs.
1726 if (TypedefTypeLoc *TypedefTL = dyn_cast<TypedefTypeLoc>(&TL)) {
1727 if (TypeSourceInfo *InnerTSInfo
1728 = TypedefTL->getTypedefDecl()->getTypeSourceInfo()) {
1729 TL = InnerTSInfo->getTypeLoc().getUnqualifiedLoc();
1730 continue;
1731 }
1732 }
1733
1734 // Look through qualified types
1735 if (QualifiedTypeLoc *QualifiedTL = dyn_cast<QualifiedTypeLoc>(&TL)) {
1736 TL = QualifiedTL->getUnqualifiedLoc();
1737 continue;
1738 }
1739
1740 // Try to get the function prototype behind the block pointer type,
1741 // then we're done.
1742 if (BlockPointerTypeLoc *BlockPtr
1743 = dyn_cast<BlockPointerTypeLoc>(&TL)) {
1744 TL = BlockPtr->getPointeeLoc();
1745 Block = dyn_cast<FunctionProtoTypeLoc>(&TL);
1746 }
1747 break;
1748 }
1749 }
1750
1751 if (!Block) {
1752 // We were unable to find a FunctionProtoTypeLoc with parameter names
1753 // for the block; just use the parameter type as a placeholder.
1754 std::string Result;
1755 Param->getType().getUnqualifiedType().
1756 getAsStringInternal(Result, Context.PrintingPolicy);
1757
1758 if (ObjCMethodParam) {
1759 Result = "(" + Result;
1760 Result += ")";
1761 if (Param->getIdentifier())
1762 Result += Param->getIdentifier()->getName();
1763 }
1764
1765 return Result;
1766 }
1767
1768 // We have the function prototype behind the block pointer type, as it was
1769 // written in the source.
1770 std::string Result = "(^)(";
1771 for (unsigned I = 0, N = Block->getNumArgs(); I != N; ++I) {
1772 if (I)
1773 Result += ", ";
1774 Result += FormatFunctionParameter(Context, Block->getArg(I));
1775 }
1776 if (Block->getTypePtr()->isVariadic()) {
1777 if (Block->getNumArgs() > 0)
1778 Result += ", ...";
1779 else
1780 Result += "...";
1781 } else if (Block->getNumArgs() == 0 && !Context.getLangOptions().CPlusPlus)
1782 Result += "void";
1783
1784 Result += ")";
1785 Block->getTypePtr()->getResultType().getAsStringInternal(Result,
1786 Context.PrintingPolicy);
1787 return Result;
1788}
1789
Douglas Gregor3545ff42009-09-21 16:56:56 +00001790/// \brief Add function parameter chunks to the given code completion string.
1791static void AddFunctionParameterChunks(ASTContext &Context,
1792 FunctionDecl *Function,
1793 CodeCompletionString *Result) {
Douglas Gregor9eb77012009-11-07 00:00:49 +00001794 typedef CodeCompletionString::Chunk Chunk;
1795
Douglas Gregor3545ff42009-09-21 16:56:56 +00001796 CodeCompletionString *CCStr = Result;
1797
1798 for (unsigned P = 0, N = Function->getNumParams(); P != N; ++P) {
1799 ParmVarDecl *Param = Function->getParamDecl(P);
1800
1801 if (Param->hasDefaultArg()) {
1802 // When we see an optional default argument, put that argument and
1803 // the remaining default arguments into a new, optional string.
1804 CodeCompletionString *Opt = new CodeCompletionString;
1805 CCStr->AddOptionalChunk(std::auto_ptr<CodeCompletionString>(Opt));
1806 CCStr = Opt;
1807 }
1808
1809 if (P != 0)
Douglas Gregor9eb77012009-11-07 00:00:49 +00001810 CCStr->AddChunk(Chunk(CodeCompletionString::CK_Comma));
Douglas Gregor3545ff42009-09-21 16:56:56 +00001811
1812 // Format the placeholder string.
Douglas Gregore90dd002010-08-24 16:15:59 +00001813 std::string PlaceholderStr = FormatFunctionParameter(Context, Param);
1814
Douglas Gregor3545ff42009-09-21 16:56:56 +00001815 // Add the placeholder string.
Benjamin Kramerb33a97c2009-11-29 20:18:50 +00001816 CCStr->AddPlaceholderChunk(PlaceholderStr);
Douglas Gregor3545ff42009-09-21 16:56:56 +00001817 }
Douglas Gregorba449032009-09-22 21:42:17 +00001818
1819 if (const FunctionProtoType *Proto
1820 = Function->getType()->getAs<FunctionProtoType>())
Douglas Gregordbb71db2010-08-23 23:51:41 +00001821 if (Proto->isVariadic()) {
Douglas Gregorba449032009-09-22 21:42:17 +00001822 CCStr->AddPlaceholderChunk(", ...");
Douglas Gregordbb71db2010-08-23 23:51:41 +00001823
1824 MaybeAddSentinel(Context, Function, CCStr);
1825 }
Douglas Gregor3545ff42009-09-21 16:56:56 +00001826}
1827
1828/// \brief Add template parameter chunks to the given code completion string.
1829static void AddTemplateParameterChunks(ASTContext &Context,
1830 TemplateDecl *Template,
1831 CodeCompletionString *Result,
1832 unsigned MaxParameters = 0) {
Douglas Gregor9eb77012009-11-07 00:00:49 +00001833 typedef CodeCompletionString::Chunk Chunk;
1834
Douglas Gregor3545ff42009-09-21 16:56:56 +00001835 CodeCompletionString *CCStr = Result;
1836 bool FirstParameter = true;
1837
1838 TemplateParameterList *Params = Template->getTemplateParameters();
1839 TemplateParameterList::iterator PEnd = Params->end();
1840 if (MaxParameters)
1841 PEnd = Params->begin() + MaxParameters;
1842 for (TemplateParameterList::iterator P = Params->begin(); P != PEnd; ++P) {
1843 bool HasDefaultArg = false;
1844 std::string PlaceholderStr;
1845 if (TemplateTypeParmDecl *TTP = dyn_cast<TemplateTypeParmDecl>(*P)) {
1846 if (TTP->wasDeclaredWithTypename())
1847 PlaceholderStr = "typename";
1848 else
1849 PlaceholderStr = "class";
1850
1851 if (TTP->getIdentifier()) {
1852 PlaceholderStr += ' ';
1853 PlaceholderStr += TTP->getIdentifier()->getName();
1854 }
1855
1856 HasDefaultArg = TTP->hasDefaultArgument();
1857 } else if (NonTypeTemplateParmDecl *NTTP
1858 = dyn_cast<NonTypeTemplateParmDecl>(*P)) {
1859 if (NTTP->getIdentifier())
1860 PlaceholderStr = NTTP->getIdentifier()->getName();
1861 NTTP->getType().getAsStringInternal(PlaceholderStr,
1862 Context.PrintingPolicy);
1863 HasDefaultArg = NTTP->hasDefaultArgument();
1864 } else {
1865 assert(isa<TemplateTemplateParmDecl>(*P));
1866 TemplateTemplateParmDecl *TTP = cast<TemplateTemplateParmDecl>(*P);
1867
1868 // Since putting the template argument list into the placeholder would
1869 // be very, very long, we just use an abbreviation.
1870 PlaceholderStr = "template<...> class";
1871 if (TTP->getIdentifier()) {
1872 PlaceholderStr += ' ';
1873 PlaceholderStr += TTP->getIdentifier()->getName();
1874 }
1875
1876 HasDefaultArg = TTP->hasDefaultArgument();
1877 }
1878
1879 if (HasDefaultArg) {
1880 // When we see an optional default argument, put that argument and
1881 // the remaining default arguments into a new, optional string.
1882 CodeCompletionString *Opt = new CodeCompletionString;
1883 CCStr->AddOptionalChunk(std::auto_ptr<CodeCompletionString>(Opt));
1884 CCStr = Opt;
1885 }
1886
1887 if (FirstParameter)
1888 FirstParameter = false;
1889 else
Douglas Gregor9eb77012009-11-07 00:00:49 +00001890 CCStr->AddChunk(Chunk(CodeCompletionString::CK_Comma));
Douglas Gregor3545ff42009-09-21 16:56:56 +00001891
1892 // Add the placeholder string.
Benjamin Kramerb33a97c2009-11-29 20:18:50 +00001893 CCStr->AddPlaceholderChunk(PlaceholderStr);
Douglas Gregor3545ff42009-09-21 16:56:56 +00001894 }
1895}
1896
Douglas Gregorf2510672009-09-21 19:57:38 +00001897/// \brief Add a qualifier to the given code-completion string, if the
1898/// provided nested-name-specifier is non-NULL.
Douglas Gregor0f622362009-12-11 18:44:16 +00001899static void
1900AddQualifierToCompletionString(CodeCompletionString *Result,
1901 NestedNameSpecifier *Qualifier,
1902 bool QualifierIsInformative,
1903 ASTContext &Context) {
Douglas Gregorf2510672009-09-21 19:57:38 +00001904 if (!Qualifier)
1905 return;
1906
1907 std::string PrintedNNS;
1908 {
1909 llvm::raw_string_ostream OS(PrintedNNS);
1910 Qualifier->print(OS, Context.PrintingPolicy);
1911 }
Douglas Gregor5bf52692009-09-22 23:15:58 +00001912 if (QualifierIsInformative)
Benjamin Kramerb33a97c2009-11-29 20:18:50 +00001913 Result->AddInformativeChunk(PrintedNNS);
Douglas Gregor5bf52692009-09-22 23:15:58 +00001914 else
Benjamin Kramerb33a97c2009-11-29 20:18:50 +00001915 Result->AddTextChunk(PrintedNNS);
Douglas Gregorf2510672009-09-21 19:57:38 +00001916}
1917
Douglas Gregor0f622362009-12-11 18:44:16 +00001918static void AddFunctionTypeQualsToCompletionString(CodeCompletionString *Result,
1919 FunctionDecl *Function) {
1920 const FunctionProtoType *Proto
1921 = Function->getType()->getAs<FunctionProtoType>();
1922 if (!Proto || !Proto->getTypeQuals())
1923 return;
1924
1925 std::string QualsStr;
1926 if (Proto->getTypeQuals() & Qualifiers::Const)
1927 QualsStr += " const";
1928 if (Proto->getTypeQuals() & Qualifiers::Volatile)
1929 QualsStr += " volatile";
1930 if (Proto->getTypeQuals() & Qualifiers::Restrict)
1931 QualsStr += " restrict";
1932 Result->AddInformativeChunk(QualsStr);
1933}
1934
Douglas Gregor3545ff42009-09-21 16:56:56 +00001935/// \brief If possible, create a new code completion string for the given
1936/// result.
1937///
1938/// \returns Either a new, heap-allocated code completion string describing
1939/// how to use this result, or NULL to indicate that the string or name of the
1940/// result is all that is needed.
1941CodeCompletionString *
Douglas Gregor8e984da2010-08-04 16:47:14 +00001942CodeCompleteConsumer::Result::CreateCodeCompletionString(Sema &S,
1943 CodeCompletionString *Result) {
Douglas Gregor9eb77012009-11-07 00:00:49 +00001944 typedef CodeCompletionString::Chunk Chunk;
1945
Douglas Gregorf09935f2009-12-01 05:55:20 +00001946 if (Kind == RK_Pattern)
Douglas Gregor8e984da2010-08-04 16:47:14 +00001947 return Pattern->Clone(Result);
Douglas Gregorf09935f2009-12-01 05:55:20 +00001948
Douglas Gregor8e984da2010-08-04 16:47:14 +00001949 if (!Result)
1950 Result = new CodeCompletionString;
Douglas Gregorf09935f2009-12-01 05:55:20 +00001951
1952 if (Kind == RK_Keyword) {
1953 Result->AddTypedTextChunk(Keyword);
1954 return Result;
1955 }
Douglas Gregor3545ff42009-09-21 16:56:56 +00001956
Douglas Gregorf329c7c2009-10-30 16:50:04 +00001957 if (Kind == RK_Macro) {
1958 MacroInfo *MI = S.PP.getMacroInfo(Macro);
Douglas Gregorf09935f2009-12-01 05:55:20 +00001959 assert(MI && "Not a macro?");
1960
1961 Result->AddTypedTextChunk(Macro->getName());
1962
1963 if (!MI->isFunctionLike())
1964 return Result;
Douglas Gregorf329c7c2009-10-30 16:50:04 +00001965
1966 // Format a function-like macro with placeholders for the arguments.
Douglas Gregor9eb77012009-11-07 00:00:49 +00001967 Result->AddChunk(Chunk(CodeCompletionString::CK_LeftParen));
Douglas Gregorf329c7c2009-10-30 16:50:04 +00001968 for (MacroInfo::arg_iterator A = MI->arg_begin(), AEnd = MI->arg_end();
1969 A != AEnd; ++A) {
1970 if (A != MI->arg_begin())
Douglas Gregor9eb77012009-11-07 00:00:49 +00001971 Result->AddChunk(Chunk(CodeCompletionString::CK_Comma));
Douglas Gregorf329c7c2009-10-30 16:50:04 +00001972
1973 if (!MI->isVariadic() || A != AEnd - 1) {
1974 // Non-variadic argument.
Benjamin Kramerb33a97c2009-11-29 20:18:50 +00001975 Result->AddPlaceholderChunk((*A)->getName());
Douglas Gregorf329c7c2009-10-30 16:50:04 +00001976 continue;
1977 }
1978
1979 // Variadic argument; cope with the different between GNU and C99
1980 // variadic macros, providing a single placeholder for the rest of the
1981 // arguments.
1982 if ((*A)->isStr("__VA_ARGS__"))
1983 Result->AddPlaceholderChunk("...");
1984 else {
1985 std::string Arg = (*A)->getName();
1986 Arg += "...";
Benjamin Kramerb33a97c2009-11-29 20:18:50 +00001987 Result->AddPlaceholderChunk(Arg);
Douglas Gregorf329c7c2009-10-30 16:50:04 +00001988 }
1989 }
Douglas Gregor9eb77012009-11-07 00:00:49 +00001990 Result->AddChunk(Chunk(CodeCompletionString::CK_RightParen));
Douglas Gregorf329c7c2009-10-30 16:50:04 +00001991 return Result;
1992 }
1993
Douglas Gregorf64acca2010-05-25 21:41:55 +00001994 assert(Kind == RK_Declaration && "Missed a result kind?");
Douglas Gregor3545ff42009-09-21 16:56:56 +00001995 NamedDecl *ND = Declaration;
1996
Douglas Gregor9eb77012009-11-07 00:00:49 +00001997 if (StartsNestedNameSpecifier) {
Benjamin Kramerb33a97c2009-11-29 20:18:50 +00001998 Result->AddTypedTextChunk(ND->getNameAsString());
Douglas Gregor9eb77012009-11-07 00:00:49 +00001999 Result->AddTextChunk("::");
2000 return Result;
2001 }
2002
Douglas Gregorb3fa9192009-12-18 18:53:37 +00002003 AddResultTypeChunk(S.Context, ND, Result);
2004
Douglas Gregor3545ff42009-09-21 16:56:56 +00002005 if (FunctionDecl *Function = dyn_cast<FunctionDecl>(ND)) {
Douglas Gregor5bf52692009-09-22 23:15:58 +00002006 AddQualifierToCompletionString(Result, Qualifier, QualifierIsInformative,
2007 S.Context);
Benjamin Kramerb33a97c2009-11-29 20:18:50 +00002008 Result->AddTypedTextChunk(Function->getNameAsString());
Douglas Gregor9eb77012009-11-07 00:00:49 +00002009 Result->AddChunk(Chunk(CodeCompletionString::CK_LeftParen));
Douglas Gregor3545ff42009-09-21 16:56:56 +00002010 AddFunctionParameterChunks(S.Context, Function, Result);
Douglas Gregor9eb77012009-11-07 00:00:49 +00002011 Result->AddChunk(Chunk(CodeCompletionString::CK_RightParen));
Douglas Gregor0f622362009-12-11 18:44:16 +00002012 AddFunctionTypeQualsToCompletionString(Result, Function);
Douglas Gregor3545ff42009-09-21 16:56:56 +00002013 return Result;
2014 }
2015
2016 if (FunctionTemplateDecl *FunTmpl = dyn_cast<FunctionTemplateDecl>(ND)) {
Douglas Gregor5bf52692009-09-22 23:15:58 +00002017 AddQualifierToCompletionString(Result, Qualifier, QualifierIsInformative,
2018 S.Context);
Douglas Gregor3545ff42009-09-21 16:56:56 +00002019 FunctionDecl *Function = FunTmpl->getTemplatedDecl();
Benjamin Kramerb33a97c2009-11-29 20:18:50 +00002020 Result->AddTypedTextChunk(Function->getNameAsString());
Douglas Gregor3545ff42009-09-21 16:56:56 +00002021
2022 // Figure out which template parameters are deduced (or have default
2023 // arguments).
2024 llvm::SmallVector<bool, 16> Deduced;
2025 S.MarkDeducedTemplateParameters(FunTmpl, Deduced);
2026 unsigned LastDeducibleArgument;
2027 for (LastDeducibleArgument = Deduced.size(); LastDeducibleArgument > 0;
2028 --LastDeducibleArgument) {
2029 if (!Deduced[LastDeducibleArgument - 1]) {
2030 // C++0x: Figure out if the template argument has a default. If so,
2031 // the user doesn't need to type this argument.
2032 // FIXME: We need to abstract template parameters better!
2033 bool HasDefaultArg = false;
2034 NamedDecl *Param = FunTmpl->getTemplateParameters()->getParam(
2035 LastDeducibleArgument - 1);
2036 if (TemplateTypeParmDecl *TTP = dyn_cast<TemplateTypeParmDecl>(Param))
2037 HasDefaultArg = TTP->hasDefaultArgument();
2038 else if (NonTypeTemplateParmDecl *NTTP
2039 = dyn_cast<NonTypeTemplateParmDecl>(Param))
2040 HasDefaultArg = NTTP->hasDefaultArgument();
2041 else {
2042 assert(isa<TemplateTemplateParmDecl>(Param));
2043 HasDefaultArg
Douglas Gregor9eb77012009-11-07 00:00:49 +00002044 = cast<TemplateTemplateParmDecl>(Param)->hasDefaultArgument();
Douglas Gregor3545ff42009-09-21 16:56:56 +00002045 }
2046
2047 if (!HasDefaultArg)
2048 break;
2049 }
2050 }
2051
2052 if (LastDeducibleArgument) {
2053 // Some of the function template arguments cannot be deduced from a
2054 // function call, so we introduce an explicit template argument list
2055 // containing all of the arguments up to the first deducible argument.
Douglas Gregor9eb77012009-11-07 00:00:49 +00002056 Result->AddChunk(Chunk(CodeCompletionString::CK_LeftAngle));
Douglas Gregor3545ff42009-09-21 16:56:56 +00002057 AddTemplateParameterChunks(S.Context, FunTmpl, Result,
2058 LastDeducibleArgument);
Douglas Gregor9eb77012009-11-07 00:00:49 +00002059 Result->AddChunk(Chunk(CodeCompletionString::CK_RightAngle));
Douglas Gregor3545ff42009-09-21 16:56:56 +00002060 }
2061
2062 // Add the function parameters
Douglas Gregor9eb77012009-11-07 00:00:49 +00002063 Result->AddChunk(Chunk(CodeCompletionString::CK_LeftParen));
Douglas Gregor3545ff42009-09-21 16:56:56 +00002064 AddFunctionParameterChunks(S.Context, Function, Result);
Douglas Gregor9eb77012009-11-07 00:00:49 +00002065 Result->AddChunk(Chunk(CodeCompletionString::CK_RightParen));
Douglas Gregor0f622362009-12-11 18:44:16 +00002066 AddFunctionTypeQualsToCompletionString(Result, Function);
Douglas Gregor3545ff42009-09-21 16:56:56 +00002067 return Result;
2068 }
2069
2070 if (TemplateDecl *Template = dyn_cast<TemplateDecl>(ND)) {
Douglas Gregor5bf52692009-09-22 23:15:58 +00002071 AddQualifierToCompletionString(Result, Qualifier, QualifierIsInformative,
2072 S.Context);
Benjamin Kramerb33a97c2009-11-29 20:18:50 +00002073 Result->AddTypedTextChunk(Template->getNameAsString());
Douglas Gregor9eb77012009-11-07 00:00:49 +00002074 Result->AddChunk(Chunk(CodeCompletionString::CK_LeftAngle));
Douglas Gregor3545ff42009-09-21 16:56:56 +00002075 AddTemplateParameterChunks(S.Context, Template, Result);
Douglas Gregor9eb77012009-11-07 00:00:49 +00002076 Result->AddChunk(Chunk(CodeCompletionString::CK_RightAngle));
Douglas Gregor3545ff42009-09-21 16:56:56 +00002077 return Result;
2078 }
2079
Douglas Gregord3c5d792009-11-17 16:44:22 +00002080 if (ObjCMethodDecl *Method = dyn_cast<ObjCMethodDecl>(ND)) {
Douglas Gregord3c5d792009-11-17 16:44:22 +00002081 Selector Sel = Method->getSelector();
2082 if (Sel.isUnarySelector()) {
2083 Result->AddTypedTextChunk(Sel.getIdentifierInfoForSlot(0)->getName());
2084 return Result;
2085 }
2086
Douglas Gregor1b605f72009-11-19 01:08:35 +00002087 std::string SelName = Sel.getIdentifierInfoForSlot(0)->getName().str();
2088 SelName += ':';
2089 if (StartParameter == 0)
2090 Result->AddTypedTextChunk(SelName);
2091 else {
2092 Result->AddInformativeChunk(SelName);
2093
2094 // If there is only one parameter, and we're past it, add an empty
2095 // typed-text chunk since there is nothing to type.
2096 if (Method->param_size() == 1)
2097 Result->AddTypedTextChunk("");
2098 }
Douglas Gregord3c5d792009-11-17 16:44:22 +00002099 unsigned Idx = 0;
2100 for (ObjCMethodDecl::param_iterator P = Method->param_begin(),
2101 PEnd = Method->param_end();
2102 P != PEnd; (void)++P, ++Idx) {
2103 if (Idx > 0) {
Douglas Gregor1b605f72009-11-19 01:08:35 +00002104 std::string Keyword;
2105 if (Idx > StartParameter)
Douglas Gregor6a803932010-01-12 06:38:28 +00002106 Result->AddChunk(CodeCompletionString::CK_HorizontalSpace);
Douglas Gregord3c5d792009-11-17 16:44:22 +00002107 if (IdentifierInfo *II = Sel.getIdentifierInfoForSlot(Idx))
2108 Keyword += II->getName().str();
2109 Keyword += ":";
Douglas Gregor95887f92010-07-08 23:20:03 +00002110 if (Idx < StartParameter || AllParametersAreInformative)
Douglas Gregor1b605f72009-11-19 01:08:35 +00002111 Result->AddInformativeChunk(Keyword);
Douglas Gregor95887f92010-07-08 23:20:03 +00002112 else if (Idx == StartParameter)
Douglas Gregor1b605f72009-11-19 01:08:35 +00002113 Result->AddTypedTextChunk(Keyword);
2114 else
2115 Result->AddTextChunk(Keyword);
Douglas Gregord3c5d792009-11-17 16:44:22 +00002116 }
Douglas Gregor1b605f72009-11-19 01:08:35 +00002117
2118 // If we're before the starting parameter, skip the placeholder.
2119 if (Idx < StartParameter)
2120 continue;
Douglas Gregord3c5d792009-11-17 16:44:22 +00002121
2122 std::string Arg;
Douglas Gregore90dd002010-08-24 16:15:59 +00002123
2124 if ((*P)->getType()->isBlockPointerType() && !DeclaringEntity)
2125 Arg = FormatFunctionParameter(S.Context, *P);
2126 else {
2127 (*P)->getType().getAsStringInternal(Arg, S.Context.PrintingPolicy);
2128 Arg = "(" + Arg + ")";
2129 if (IdentifierInfo *II = (*P)->getIdentifier())
2130 Arg += II->getName().str();
2131 }
2132
Douglas Gregor95887f92010-07-08 23:20:03 +00002133 if (DeclaringEntity)
2134 Result->AddTextChunk(Arg);
2135 else if (AllParametersAreInformative)
Douglas Gregorc8537c52009-11-19 07:41:15 +00002136 Result->AddInformativeChunk(Arg);
2137 else
2138 Result->AddPlaceholderChunk(Arg);
Douglas Gregord3c5d792009-11-17 16:44:22 +00002139 }
2140
Douglas Gregor04c5f972009-12-23 00:21:46 +00002141 if (Method->isVariadic()) {
Douglas Gregor95887f92010-07-08 23:20:03 +00002142 if (DeclaringEntity)
2143 Result->AddTextChunk(", ...");
2144 else if (AllParametersAreInformative)
Douglas Gregor04c5f972009-12-23 00:21:46 +00002145 Result->AddInformativeChunk(", ...");
2146 else
2147 Result->AddPlaceholderChunk(", ...");
Douglas Gregordbb71db2010-08-23 23:51:41 +00002148
2149 MaybeAddSentinel(S.Context, Method, Result);
Douglas Gregor04c5f972009-12-23 00:21:46 +00002150 }
2151
Douglas Gregord3c5d792009-11-17 16:44:22 +00002152 return Result;
2153 }
2154
Douglas Gregorf09935f2009-12-01 05:55:20 +00002155 if (Qualifier)
Douglas Gregor5bf52692009-09-22 23:15:58 +00002156 AddQualifierToCompletionString(Result, Qualifier, QualifierIsInformative,
2157 S.Context);
Douglas Gregorf09935f2009-12-01 05:55:20 +00002158
2159 Result->AddTypedTextChunk(ND->getNameAsString());
2160 return Result;
Douglas Gregor3545ff42009-09-21 16:56:56 +00002161}
2162
Douglas Gregorf0f51982009-09-23 00:34:09 +00002163CodeCompletionString *
2164CodeCompleteConsumer::OverloadCandidate::CreateSignatureString(
2165 unsigned CurrentArg,
2166 Sema &S) const {
Douglas Gregor9eb77012009-11-07 00:00:49 +00002167 typedef CodeCompletionString::Chunk Chunk;
2168
Douglas Gregorf0f51982009-09-23 00:34:09 +00002169 CodeCompletionString *Result = new CodeCompletionString;
2170 FunctionDecl *FDecl = getFunction();
Douglas Gregorb3fa9192009-12-18 18:53:37 +00002171 AddResultTypeChunk(S.Context, FDecl, Result);
Douglas Gregorf0f51982009-09-23 00:34:09 +00002172 const FunctionProtoType *Proto
2173 = dyn_cast<FunctionProtoType>(getFunctionType());
2174 if (!FDecl && !Proto) {
2175 // Function without a prototype. Just give the return type and a
2176 // highlighted ellipsis.
2177 const FunctionType *FT = getFunctionType();
2178 Result->AddTextChunk(
Benjamin Kramerb33a97c2009-11-29 20:18:50 +00002179 FT->getResultType().getAsString(S.Context.PrintingPolicy));
Douglas Gregor9eb77012009-11-07 00:00:49 +00002180 Result->AddChunk(Chunk(CodeCompletionString::CK_LeftParen));
2181 Result->AddChunk(Chunk(CodeCompletionString::CK_CurrentParameter, "..."));
2182 Result->AddChunk(Chunk(CodeCompletionString::CK_RightParen));
Douglas Gregorf0f51982009-09-23 00:34:09 +00002183 return Result;
2184 }
2185
2186 if (FDecl)
Benjamin Kramerb33a97c2009-11-29 20:18:50 +00002187 Result->AddTextChunk(FDecl->getNameAsString());
Douglas Gregorf0f51982009-09-23 00:34:09 +00002188 else
2189 Result->AddTextChunk(
Benjamin Kramerb33a97c2009-11-29 20:18:50 +00002190 Proto->getResultType().getAsString(S.Context.PrintingPolicy));
Douglas Gregorf0f51982009-09-23 00:34:09 +00002191
Douglas Gregor9eb77012009-11-07 00:00:49 +00002192 Result->AddChunk(Chunk(CodeCompletionString::CK_LeftParen));
Douglas Gregorf0f51982009-09-23 00:34:09 +00002193 unsigned NumParams = FDecl? FDecl->getNumParams() : Proto->getNumArgs();
2194 for (unsigned I = 0; I != NumParams; ++I) {
2195 if (I)
Douglas Gregor9eb77012009-11-07 00:00:49 +00002196 Result->AddChunk(Chunk(CodeCompletionString::CK_Comma));
Douglas Gregorf0f51982009-09-23 00:34:09 +00002197
2198 std::string ArgString;
2199 QualType ArgType;
2200
2201 if (FDecl) {
2202 ArgString = FDecl->getParamDecl(I)->getNameAsString();
2203 ArgType = FDecl->getParamDecl(I)->getOriginalType();
2204 } else {
2205 ArgType = Proto->getArgType(I);
2206 }
2207
2208 ArgType.getAsStringInternal(ArgString, S.Context.PrintingPolicy);
2209
2210 if (I == CurrentArg)
Douglas Gregor9eb77012009-11-07 00:00:49 +00002211 Result->AddChunk(Chunk(CodeCompletionString::CK_CurrentParameter,
Benjamin Kramerb33a97c2009-11-29 20:18:50 +00002212 ArgString));
Douglas Gregorf0f51982009-09-23 00:34:09 +00002213 else
Benjamin Kramerb33a97c2009-11-29 20:18:50 +00002214 Result->AddTextChunk(ArgString);
Douglas Gregorf0f51982009-09-23 00:34:09 +00002215 }
2216
2217 if (Proto && Proto->isVariadic()) {
Douglas Gregor9eb77012009-11-07 00:00:49 +00002218 Result->AddChunk(Chunk(CodeCompletionString::CK_Comma));
Douglas Gregorf0f51982009-09-23 00:34:09 +00002219 if (CurrentArg < NumParams)
2220 Result->AddTextChunk("...");
2221 else
Douglas Gregor9eb77012009-11-07 00:00:49 +00002222 Result->AddChunk(Chunk(CodeCompletionString::CK_CurrentParameter, "..."));
Douglas Gregorf0f51982009-09-23 00:34:09 +00002223 }
Douglas Gregor9eb77012009-11-07 00:00:49 +00002224 Result->AddChunk(Chunk(CodeCompletionString::CK_RightParen));
Douglas Gregorf0f51982009-09-23 00:34:09 +00002225
2226 return Result;
2227}
2228
Douglas Gregor3545ff42009-09-21 16:56:56 +00002229namespace {
2230 struct SortCodeCompleteResult {
2231 typedef CodeCompleteConsumer::Result Result;
2232
Douglas Gregor52ce62f2010-01-13 23:24:38 +00002233 /// \brief Retrieve the name that should be used to order a result.
2234 ///
2235 /// If the name needs to be constructed as a string, that string will be
2236 /// saved into Saved and the returned StringRef will refer to it.
2237 static llvm::StringRef getOrderedName(const Result &R,
2238 std::string &Saved) {
2239 switch (R.Kind) {
2240 case Result::RK_Keyword:
2241 return R.Keyword;
2242
2243 case Result::RK_Pattern:
2244 return R.Pattern->getTypedText();
2245
2246 case Result::RK_Macro:
2247 return R.Macro->getName();
2248
2249 case Result::RK_Declaration:
2250 // Handle declarations below.
2251 break;
Douglas Gregor45f83ee2009-11-19 00:01:57 +00002252 }
Douglas Gregor52ce62f2010-01-13 23:24:38 +00002253
2254 DeclarationName Name = R.Declaration->getDeclName();
Douglas Gregor45f83ee2009-11-19 00:01:57 +00002255
Douglas Gregor52ce62f2010-01-13 23:24:38 +00002256 // If the name is a simple identifier (by far the common case), or a
2257 // zero-argument selector, just return a reference to that identifier.
2258 if (IdentifierInfo *Id = Name.getAsIdentifierInfo())
2259 return Id->getName();
2260 if (Name.isObjCZeroArgSelector())
2261 if (IdentifierInfo *Id
2262 = Name.getObjCSelector().getIdentifierInfoForSlot(0))
2263 return Id->getName();
2264
2265 Saved = Name.getAsString();
2266 return Saved;
2267 }
2268
2269 bool operator()(const Result &X, const Result &Y) const {
2270 std::string XSaved, YSaved;
2271 llvm::StringRef XStr = getOrderedName(X, XSaved);
2272 llvm::StringRef YStr = getOrderedName(Y, YSaved);
2273 int cmp = XStr.compare_lower(YStr);
2274 if (cmp)
2275 return cmp < 0;
Douglas Gregor3545ff42009-09-21 16:56:56 +00002276
2277 // Non-hidden names precede hidden names.
2278 if (X.Hidden != Y.Hidden)
2279 return !X.Hidden;
2280
Douglas Gregore412a5a2009-09-23 22:26:46 +00002281 // Non-nested-name-specifiers precede nested-name-specifiers.
2282 if (X.StartsNestedNameSpecifier != Y.StartsNestedNameSpecifier)
2283 return !X.StartsNestedNameSpecifier;
2284
Douglas Gregor3545ff42009-09-21 16:56:56 +00002285 return false;
2286 }
2287 };
2288}
2289
Douglas Gregor6e240332010-08-16 16:18:59 +00002290unsigned clang::getMacroUsagePriority(llvm::StringRef MacroName,
2291 bool PreferredTypeIsPointer) {
2292 unsigned Priority = CCP_Macro;
2293
2294 // Treat the "nil" and "NULL" macros as null pointer constants.
2295 if (MacroName.equals("nil") || MacroName.equals("NULL")) {
2296 Priority = CCP_Constant;
2297 if (PreferredTypeIsPointer)
2298 Priority = Priority / CCF_SimilarTypeMatch;
2299 }
2300
2301 return Priority;
2302}
2303
Douglas Gregor55b037b2010-07-08 20:55:51 +00002304static void AddMacroResults(Preprocessor &PP, ResultBuilder &Results,
2305 bool TargetTypeIsPointer = false) {
2306 typedef CodeCompleteConsumer::Result Result;
2307
Douglas Gregorf329c7c2009-10-30 16:50:04 +00002308 Results.EnterNewScope();
Douglas Gregor9eb77012009-11-07 00:00:49 +00002309 for (Preprocessor::macro_iterator M = PP.macro_begin(),
2310 MEnd = PP.macro_end();
Douglas Gregor55b037b2010-07-08 20:55:51 +00002311 M != MEnd; ++M) {
Douglas Gregor6e240332010-08-16 16:18:59 +00002312 Results.AddResult(Result(M->first,
2313 getMacroUsagePriority(M->first->getName(),
2314 TargetTypeIsPointer)));
Douglas Gregor55b037b2010-07-08 20:55:51 +00002315 }
Douglas Gregorf329c7c2009-10-30 16:50:04 +00002316 Results.ExitScope();
2317}
2318
Douglas Gregorce0e8562010-08-23 21:54:33 +00002319static void AddPrettyFunctionResults(const LangOptions &LangOpts,
2320 ResultBuilder &Results) {
2321 typedef CodeCompleteConsumer::Result Result;
2322
2323 Results.EnterNewScope();
2324 Results.AddResult(Result("__PRETTY_FUNCTION__", CCP_Constant));
2325 Results.AddResult(Result("__FUNCTION__", CCP_Constant));
2326 if (LangOpts.C99 || LangOpts.CPlusPlus0x)
2327 Results.AddResult(Result("__func__", CCP_Constant));
2328 Results.ExitScope();
2329}
2330
Daniel Dunbar242ea9a2009-11-13 08:58:20 +00002331static void HandleCodeCompleteResults(Sema *S,
2332 CodeCompleteConsumer *CodeCompleter,
Douglas Gregor00c37ef2010-08-11 21:23:17 +00002333 CodeCompletionContext Context,
2334 CodeCompleteConsumer::Result *Results,
2335 unsigned NumResults) {
Douglas Gregor3545ff42009-09-21 16:56:56 +00002336 std::stable_sort(Results, Results + NumResults, SortCodeCompleteResult());
2337
2338 if (CodeCompleter)
Douglas Gregor00c37ef2010-08-11 21:23:17 +00002339 CodeCompleter->ProcessCodeCompleteResults(*S, Context, Results, NumResults);
Douglas Gregor45f83ee2009-11-19 00:01:57 +00002340
2341 for (unsigned I = 0; I != NumResults; ++I)
2342 Results[I].Destroy();
Douglas Gregor3545ff42009-09-21 16:56:56 +00002343}
2344
Douglas Gregor00c37ef2010-08-11 21:23:17 +00002345static enum CodeCompletionContext::Kind mapCodeCompletionContext(Sema &S,
2346 Sema::ParserCompletionContext PCC) {
2347 switch (PCC) {
2348 case Action::PCC_Namespace:
2349 return CodeCompletionContext::CCC_TopLevel;
2350
2351 case Action::PCC_Class:
2352 return CodeCompletionContext::CCC_ClassStructUnion;
2353
2354 case Action::PCC_ObjCInterface:
2355 return CodeCompletionContext::CCC_ObjCInterface;
2356
2357 case Action::PCC_ObjCImplementation:
2358 return CodeCompletionContext::CCC_ObjCImplementation;
2359
2360 case Action::PCC_ObjCInstanceVariableList:
2361 return CodeCompletionContext::CCC_ObjCIvarList;
2362
2363 case Action::PCC_Template:
2364 case Action::PCC_MemberTemplate:
2365 case Action::PCC_RecoveryInFunction:
2366 return CodeCompletionContext::CCC_Other;
2367
2368 case Action::PCC_Expression:
2369 case Action::PCC_ForInit:
2370 case Action::PCC_Condition:
2371 return CodeCompletionContext::CCC_Expression;
2372
2373 case Action::PCC_Statement:
2374 return CodeCompletionContext::CCC_Statement;
Douglas Gregorf02e5f32010-08-24 01:11:00 +00002375
2376 case Action::PCC_Type:
2377 return CodeCompletionContext::CCC_Type;
Douglas Gregor00c37ef2010-08-11 21:23:17 +00002378 }
2379
2380 return CodeCompletionContext::CCC_Other;
2381}
2382
Douglas Gregor504a6ae2010-01-10 23:08:15 +00002383void Sema::CodeCompleteOrdinaryName(Scope *S,
Douglas Gregor00c37ef2010-08-11 21:23:17 +00002384 ParserCompletionContext CompletionContext) {
Douglas Gregor92253692009-12-07 09:54:55 +00002385 typedef CodeCompleteConsumer::Result Result;
Douglas Gregorc49f5b22010-08-23 18:23:48 +00002386 ResultBuilder Results(*this);
Douglas Gregor504a6ae2010-01-10 23:08:15 +00002387
2388 // Determine how to filter results, e.g., so that the names of
2389 // values (functions, enumerators, function templates, etc.) are
2390 // only allowed where we can have an expression.
2391 switch (CompletionContext) {
Douglas Gregor00c37ef2010-08-11 21:23:17 +00002392 case PCC_Namespace:
2393 case PCC_Class:
2394 case PCC_ObjCInterface:
2395 case PCC_ObjCImplementation:
2396 case PCC_ObjCInstanceVariableList:
2397 case PCC_Template:
2398 case PCC_MemberTemplate:
Douglas Gregorf02e5f32010-08-24 01:11:00 +00002399 case PCC_Type:
Douglas Gregor504a6ae2010-01-10 23:08:15 +00002400 Results.setFilter(&ResultBuilder::IsOrdinaryNonValueName);
2401 break;
2402
Douglas Gregor00c37ef2010-08-11 21:23:17 +00002403 case PCC_Expression:
2404 case PCC_Statement:
2405 case PCC_ForInit:
2406 case PCC_Condition:
Douglas Gregor70febae2010-05-28 00:49:12 +00002407 if (WantTypesInContext(CompletionContext, getLangOptions()))
2408 Results.setFilter(&ResultBuilder::IsOrdinaryName);
2409 else
2410 Results.setFilter(&ResultBuilder::IsOrdinaryNonTypeName);
Douglas Gregor504a6ae2010-01-10 23:08:15 +00002411 break;
Douglas Gregor6da3db42010-05-25 05:58:43 +00002412
Douglas Gregor00c37ef2010-08-11 21:23:17 +00002413 case PCC_RecoveryInFunction:
Douglas Gregor6da3db42010-05-25 05:58:43 +00002414 // Unfiltered
2415 break;
Douglas Gregor504a6ae2010-01-10 23:08:15 +00002416 }
2417
Douglas Gregorc580c522010-01-14 01:09:38 +00002418 CodeCompletionDeclConsumer Consumer(Results, CurContext);
Douglas Gregor39982192010-08-15 06:18:01 +00002419 LookupVisibleDecls(S, LookupOrdinaryName, Consumer,
2420 CodeCompleter->includeGlobals());
Douglas Gregor92253692009-12-07 09:54:55 +00002421
2422 Results.EnterNewScope();
Douglas Gregorf98e6a22010-01-13 23:51:12 +00002423 AddOrdinaryNameResults(CompletionContext, S, *this, Results);
Douglas Gregor92253692009-12-07 09:54:55 +00002424 Results.ExitScope();
2425
Douglas Gregorce0e8562010-08-23 21:54:33 +00002426 switch (CompletionContext) {
Douglas Gregorf02e5f32010-08-24 01:11:00 +00002427 case PCC_Expression:
2428 case PCC_Statement:
2429 case PCC_RecoveryInFunction:
2430 if (S->getFnParent())
2431 AddPrettyFunctionResults(PP.getLangOptions(), Results);
2432 break;
2433
2434 case PCC_Namespace:
2435 case PCC_Class:
2436 case PCC_ObjCInterface:
2437 case PCC_ObjCImplementation:
2438 case PCC_ObjCInstanceVariableList:
2439 case PCC_Template:
2440 case PCC_MemberTemplate:
2441 case PCC_ForInit:
2442 case PCC_Condition:
2443 case PCC_Type:
2444 break;
Douglas Gregorce0e8562010-08-23 21:54:33 +00002445 }
2446
Douglas Gregor9eb77012009-11-07 00:00:49 +00002447 if (CodeCompleter->includeMacros())
Douglas Gregorf98e6a22010-01-13 23:51:12 +00002448 AddMacroResults(PP, Results);
Douglas Gregorce0e8562010-08-23 21:54:33 +00002449
Douglas Gregor00c37ef2010-08-11 21:23:17 +00002450 HandleCodeCompleteResults(this, CodeCompleter,
2451 mapCodeCompletionContext(*this, CompletionContext),
2452 Results.data(),Results.size());
Douglas Gregor9d64c5e2009-09-21 20:51:25 +00002453}
2454
Douglas Gregorc49f5b22010-08-23 18:23:48 +00002455void Sema::CodeCompleteDeclarator(Scope *S,
2456 bool AllowNonIdentifiers,
2457 bool AllowNestedNameSpecifiers) {
2458 typedef CodeCompleteConsumer::Result Result;
2459 ResultBuilder Results(*this);
2460 Results.EnterNewScope();
2461
2462 // Type qualifiers can come after names.
2463 Results.AddResult(Result("const"));
2464 Results.AddResult(Result("volatile"));
2465 if (getLangOptions().C99)
2466 Results.AddResult(Result("restrict"));
2467
2468 if (getLangOptions().CPlusPlus) {
2469 if (AllowNonIdentifiers) {
2470 Results.AddResult(Result("operator"));
2471 }
2472
2473 // Add nested-name-specifiers.
2474 if (AllowNestedNameSpecifiers) {
2475 Results.allowNestedNameSpecifiers();
2476 CodeCompletionDeclConsumer Consumer(Results, CurContext);
2477 LookupVisibleDecls(S, LookupNestedNameSpecifierName, Consumer,
2478 CodeCompleter->includeGlobals());
2479 }
2480 }
2481 Results.ExitScope();
2482
Douglas Gregor56ccce02010-08-24 04:59:56 +00002483 // Note that we intentionally suppress macro results here, since we do not
2484 // encourage using macros to produce the names of entities.
2485
Douglas Gregorc49f5b22010-08-23 18:23:48 +00002486 HandleCodeCompleteResults(this, CodeCompleter,
2487 AllowNestedNameSpecifiers
2488 ? CodeCompletionContext::CCC_PotentiallyQualifiedName
2489 : CodeCompletionContext::CCC_Name,
2490 Results.data(), Results.size());
2491}
2492
Douglas Gregor68762e72010-08-23 21:17:50 +00002493struct Sema::CodeCompleteExpressionData {
2494 CodeCompleteExpressionData(QualType PreferredType = QualType())
2495 : PreferredType(PreferredType), IntegralConstantExpression(false),
2496 ObjCCollection(false) { }
2497
2498 QualType PreferredType;
2499 bool IntegralConstantExpression;
2500 bool ObjCCollection;
2501 llvm::SmallVector<Decl *, 4> IgnoreDecls;
2502};
2503
Douglas Gregor7aa6b222010-05-30 01:49:25 +00002504/// \brief Perform code-completion in an expression context when we know what
2505/// type we're looking for.
Douglas Gregor85b50632010-07-28 21:50:18 +00002506///
2507/// \param IntegralConstantExpression Only permit integral constant
2508/// expressions.
Douglas Gregor68762e72010-08-23 21:17:50 +00002509void Sema::CodeCompleteExpression(Scope *S,
2510 const CodeCompleteExpressionData &Data) {
Douglas Gregor7aa6b222010-05-30 01:49:25 +00002511 typedef CodeCompleteConsumer::Result Result;
2512 ResultBuilder Results(*this);
2513
Douglas Gregor68762e72010-08-23 21:17:50 +00002514 if (Data.ObjCCollection)
2515 Results.setFilter(&ResultBuilder::IsObjCCollection);
2516 else if (Data.IntegralConstantExpression)
Douglas Gregor85b50632010-07-28 21:50:18 +00002517 Results.setFilter(&ResultBuilder::IsIntegralConstantValue);
Douglas Gregor00c37ef2010-08-11 21:23:17 +00002518 else if (WantTypesInContext(PCC_Expression, getLangOptions()))
Douglas Gregor7aa6b222010-05-30 01:49:25 +00002519 Results.setFilter(&ResultBuilder::IsOrdinaryName);
2520 else
2521 Results.setFilter(&ResultBuilder::IsOrdinaryNonTypeName);
Douglas Gregor68762e72010-08-23 21:17:50 +00002522
2523 if (!Data.PreferredType.isNull())
2524 Results.setPreferredType(Data.PreferredType.getNonReferenceType());
2525
2526 // Ignore any declarations that we were told that we don't care about.
2527 for (unsigned I = 0, N = Data.IgnoreDecls.size(); I != N; ++I)
2528 Results.Ignore(Data.IgnoreDecls[I]);
Douglas Gregor7aa6b222010-05-30 01:49:25 +00002529
2530 CodeCompletionDeclConsumer Consumer(Results, CurContext);
Douglas Gregor39982192010-08-15 06:18:01 +00002531 LookupVisibleDecls(S, LookupOrdinaryName, Consumer,
2532 CodeCompleter->includeGlobals());
Douglas Gregor7aa6b222010-05-30 01:49:25 +00002533
2534 Results.EnterNewScope();
Douglas Gregor00c37ef2010-08-11 21:23:17 +00002535 AddOrdinaryNameResults(PCC_Expression, S, *this, Results);
Douglas Gregor7aa6b222010-05-30 01:49:25 +00002536 Results.ExitScope();
2537
Douglas Gregor55b037b2010-07-08 20:55:51 +00002538 bool PreferredTypeIsPointer = false;
Douglas Gregor68762e72010-08-23 21:17:50 +00002539 if (!Data.PreferredType.isNull())
2540 PreferredTypeIsPointer = Data.PreferredType->isAnyPointerType()
2541 || Data.PreferredType->isMemberPointerType()
2542 || Data.PreferredType->isBlockPointerType();
Douglas Gregor55b037b2010-07-08 20:55:51 +00002543
Douglas Gregorce0e8562010-08-23 21:54:33 +00002544 if (S->getFnParent() &&
2545 !Data.ObjCCollection &&
2546 !Data.IntegralConstantExpression)
2547 AddPrettyFunctionResults(PP.getLangOptions(), Results);
2548
Douglas Gregor7aa6b222010-05-30 01:49:25 +00002549 if (CodeCompleter->includeMacros())
Douglas Gregor55b037b2010-07-08 20:55:51 +00002550 AddMacroResults(PP, Results, PreferredTypeIsPointer);
Douglas Gregor00c37ef2010-08-11 21:23:17 +00002551 HandleCodeCompleteResults(this, CodeCompleter,
Douglas Gregor68762e72010-08-23 21:17:50 +00002552 CodeCompletionContext(CodeCompletionContext::CCC_Expression,
2553 Data.PreferredType),
Douglas Gregor00c37ef2010-08-11 21:23:17 +00002554 Results.data(),Results.size());
Douglas Gregor7aa6b222010-05-30 01:49:25 +00002555}
2556
2557
Douglas Gregor9291bad2009-11-18 01:29:26 +00002558static void AddObjCProperties(ObjCContainerDecl *Container,
Douglas Gregor5d649882009-11-18 22:32:06 +00002559 bool AllowCategories,
Douglas Gregor9291bad2009-11-18 01:29:26 +00002560 DeclContext *CurContext,
2561 ResultBuilder &Results) {
2562 typedef CodeCompleteConsumer::Result Result;
2563
2564 // Add properties in this container.
2565 for (ObjCContainerDecl::prop_iterator P = Container->prop_begin(),
2566 PEnd = Container->prop_end();
2567 P != PEnd;
2568 ++P)
2569 Results.MaybeAddResult(Result(*P, 0), CurContext);
2570
2571 // Add properties in referenced protocols.
2572 if (ObjCProtocolDecl *Protocol = dyn_cast<ObjCProtocolDecl>(Container)) {
2573 for (ObjCProtocolDecl::protocol_iterator P = Protocol->protocol_begin(),
2574 PEnd = Protocol->protocol_end();
2575 P != PEnd; ++P)
Douglas Gregor5d649882009-11-18 22:32:06 +00002576 AddObjCProperties(*P, AllowCategories, CurContext, Results);
Douglas Gregor9291bad2009-11-18 01:29:26 +00002577 } else if (ObjCInterfaceDecl *IFace = dyn_cast<ObjCInterfaceDecl>(Container)){
Douglas Gregor5d649882009-11-18 22:32:06 +00002578 if (AllowCategories) {
2579 // Look through categories.
2580 for (ObjCCategoryDecl *Category = IFace->getCategoryList();
2581 Category; Category = Category->getNextClassCategory())
2582 AddObjCProperties(Category, AllowCategories, CurContext, Results);
2583 }
Douglas Gregor9291bad2009-11-18 01:29:26 +00002584
2585 // Look through protocols.
2586 for (ObjCInterfaceDecl::protocol_iterator I = IFace->protocol_begin(),
2587 E = IFace->protocol_end();
2588 I != E; ++I)
Douglas Gregor5d649882009-11-18 22:32:06 +00002589 AddObjCProperties(*I, AllowCategories, CurContext, Results);
Douglas Gregor9291bad2009-11-18 01:29:26 +00002590
2591 // Look in the superclass.
2592 if (IFace->getSuperClass())
Douglas Gregor5d649882009-11-18 22:32:06 +00002593 AddObjCProperties(IFace->getSuperClass(), AllowCategories, CurContext,
2594 Results);
Douglas Gregor9291bad2009-11-18 01:29:26 +00002595 } else if (const ObjCCategoryDecl *Category
2596 = dyn_cast<ObjCCategoryDecl>(Container)) {
2597 // Look through protocols.
2598 for (ObjCInterfaceDecl::protocol_iterator P = Category->protocol_begin(),
2599 PEnd = Category->protocol_end();
2600 P != PEnd; ++P)
Douglas Gregor5d649882009-11-18 22:32:06 +00002601 AddObjCProperties(*P, AllowCategories, CurContext, Results);
Douglas Gregor9291bad2009-11-18 01:29:26 +00002602 }
2603}
2604
Douglas Gregor2436e712009-09-17 21:32:03 +00002605void Sema::CodeCompleteMemberReferenceExpr(Scope *S, ExprTy *BaseE,
2606 SourceLocation OpLoc,
2607 bool IsArrow) {
2608 if (!BaseE || !CodeCompleter)
2609 return;
2610
Douglas Gregor3545ff42009-09-21 16:56:56 +00002611 typedef CodeCompleteConsumer::Result Result;
2612
Douglas Gregor2436e712009-09-17 21:32:03 +00002613 Expr *Base = static_cast<Expr *>(BaseE);
2614 QualType BaseType = Base->getType();
Douglas Gregor3545ff42009-09-21 16:56:56 +00002615
2616 if (IsArrow) {
2617 if (const PointerType *Ptr = BaseType->getAs<PointerType>())
2618 BaseType = Ptr->getPointeeType();
2619 else if (BaseType->isObjCObjectPointerType())
2620 /*Do nothing*/ ;
2621 else
2622 return;
2623 }
2624
Douglas Gregore412a5a2009-09-23 22:26:46 +00002625 ResultBuilder Results(*this, &ResultBuilder::IsMember);
Douglas Gregor9291bad2009-11-18 01:29:26 +00002626 Results.EnterNewScope();
2627 if (const RecordType *Record = BaseType->getAs<RecordType>()) {
2628 // Access to a C/C++ class, struct, or union.
Douglas Gregor6ae4c522010-01-14 03:21:49 +00002629 Results.allowNestedNameSpecifiers();
Douglas Gregor09bbc652010-01-14 15:47:35 +00002630 CodeCompletionDeclConsumer Consumer(Results, CurContext);
Douglas Gregor39982192010-08-15 06:18:01 +00002631 LookupVisibleDecls(Record->getDecl(), LookupMemberName, Consumer,
2632 CodeCompleter->includeGlobals());
Daniel Dunbar242ea9a2009-11-13 08:58:20 +00002633
Douglas Gregor9291bad2009-11-18 01:29:26 +00002634 if (getLangOptions().CPlusPlus) {
2635 if (!Results.empty()) {
2636 // The "template" keyword can follow "->" or "." in the grammar.
2637 // However, we only want to suggest the template keyword if something
2638 // is dependent.
2639 bool IsDependent = BaseType->isDependentType();
2640 if (!IsDependent) {
2641 for (Scope *DepScope = S; DepScope; DepScope = DepScope->getParent())
2642 if (DeclContext *Ctx = (DeclContext *)DepScope->getEntity()) {
2643 IsDependent = Ctx->isDependentContext();
2644 break;
2645 }
2646 }
Daniel Dunbar242ea9a2009-11-13 08:58:20 +00002647
Douglas Gregor9291bad2009-11-18 01:29:26 +00002648 if (IsDependent)
Douglas Gregor78a21012010-01-14 16:01:26 +00002649 Results.AddResult(Result("template"));
Daniel Dunbar242ea9a2009-11-13 08:58:20 +00002650 }
Daniel Dunbar242ea9a2009-11-13 08:58:20 +00002651 }
Douglas Gregor9291bad2009-11-18 01:29:26 +00002652 } else if (!IsArrow && BaseType->getAsObjCInterfacePointerType()) {
2653 // Objective-C property reference.
2654
2655 // Add property results based on our interface.
2656 const ObjCObjectPointerType *ObjCPtr
2657 = BaseType->getAsObjCInterfacePointerType();
2658 assert(ObjCPtr && "Non-NULL pointer guaranteed above!");
Douglas Gregor5d649882009-11-18 22:32:06 +00002659 AddObjCProperties(ObjCPtr->getInterfaceDecl(), true, CurContext, Results);
Douglas Gregor9291bad2009-11-18 01:29:26 +00002660
2661 // Add properties from the protocols in a qualified interface.
2662 for (ObjCObjectPointerType::qual_iterator I = ObjCPtr->qual_begin(),
2663 E = ObjCPtr->qual_end();
2664 I != E; ++I)
Douglas Gregor5d649882009-11-18 22:32:06 +00002665 AddObjCProperties(*I, true, CurContext, Results);
Douglas Gregor9291bad2009-11-18 01:29:26 +00002666 } else if ((IsArrow && BaseType->isObjCObjectPointerType()) ||
John McCall8b07ec22010-05-15 11:32:37 +00002667 (!IsArrow && BaseType->isObjCObjectType())) {
Douglas Gregor9291bad2009-11-18 01:29:26 +00002668 // Objective-C instance variable access.
2669 ObjCInterfaceDecl *Class = 0;
2670 if (const ObjCObjectPointerType *ObjCPtr
2671 = BaseType->getAs<ObjCObjectPointerType>())
2672 Class = ObjCPtr->getInterfaceDecl();
2673 else
John McCall8b07ec22010-05-15 11:32:37 +00002674 Class = BaseType->getAs<ObjCObjectType>()->getInterface();
Douglas Gregor9291bad2009-11-18 01:29:26 +00002675
2676 // Add all ivars from this class and its superclasses.
Douglas Gregor2b8162b2010-01-14 16:08:12 +00002677 if (Class) {
2678 CodeCompletionDeclConsumer Consumer(Results, CurContext);
2679 Results.setFilter(&ResultBuilder::IsObjCIvar);
Douglas Gregor39982192010-08-15 06:18:01 +00002680 LookupVisibleDecls(Class, LookupMemberName, Consumer,
2681 CodeCompleter->includeGlobals());
Douglas Gregor9291bad2009-11-18 01:29:26 +00002682 }
Douglas Gregor3545ff42009-09-21 16:56:56 +00002683 }
Douglas Gregor9291bad2009-11-18 01:29:26 +00002684
2685 // FIXME: How do we cope with isa?
2686
2687 Results.ExitScope();
Daniel Dunbar242ea9a2009-11-13 08:58:20 +00002688
Daniel Dunbar242ea9a2009-11-13 08:58:20 +00002689 // Hand off the results found for code completion.
Douglas Gregor00c37ef2010-08-11 21:23:17 +00002690 HandleCodeCompleteResults(this, CodeCompleter,
2691 CodeCompletionContext(CodeCompletionContext::CCC_MemberAccess,
2692 BaseType),
2693 Results.data(),Results.size());
Douglas Gregor2436e712009-09-17 21:32:03 +00002694}
2695
Douglas Gregorf45b0cf2009-09-18 15:37:17 +00002696void Sema::CodeCompleteTag(Scope *S, unsigned TagSpec) {
2697 if (!CodeCompleter)
2698 return;
2699
Douglas Gregor3545ff42009-09-21 16:56:56 +00002700 typedef CodeCompleteConsumer::Result Result;
2701 ResultBuilder::LookupFilter Filter = 0;
Douglas Gregor00c37ef2010-08-11 21:23:17 +00002702 enum CodeCompletionContext::Kind ContextKind
2703 = CodeCompletionContext::CCC_Other;
Douglas Gregorf45b0cf2009-09-18 15:37:17 +00002704 switch ((DeclSpec::TST)TagSpec) {
2705 case DeclSpec::TST_enum:
Douglas Gregor3545ff42009-09-21 16:56:56 +00002706 Filter = &ResultBuilder::IsEnum;
Douglas Gregor00c37ef2010-08-11 21:23:17 +00002707 ContextKind = CodeCompletionContext::CCC_EnumTag;
Douglas Gregorf45b0cf2009-09-18 15:37:17 +00002708 break;
2709
2710 case DeclSpec::TST_union:
Douglas Gregor3545ff42009-09-21 16:56:56 +00002711 Filter = &ResultBuilder::IsUnion;
Douglas Gregor00c37ef2010-08-11 21:23:17 +00002712 ContextKind = CodeCompletionContext::CCC_UnionTag;
Douglas Gregorf45b0cf2009-09-18 15:37:17 +00002713 break;
2714
2715 case DeclSpec::TST_struct:
Douglas Gregorf45b0cf2009-09-18 15:37:17 +00002716 case DeclSpec::TST_class:
Douglas Gregor3545ff42009-09-21 16:56:56 +00002717 Filter = &ResultBuilder::IsClassOrStruct;
Douglas Gregor00c37ef2010-08-11 21:23:17 +00002718 ContextKind = CodeCompletionContext::CCC_ClassOrStructTag;
Douglas Gregorf45b0cf2009-09-18 15:37:17 +00002719 break;
2720
2721 default:
2722 assert(false && "Unknown type specifier kind in CodeCompleteTag");
2723 return;
2724 }
Douglas Gregor3545ff42009-09-21 16:56:56 +00002725
John McCalle87beb22010-04-23 18:46:30 +00002726 ResultBuilder Results(*this);
Douglas Gregora6e2edc2010-01-14 03:27:13 +00002727 CodeCompletionDeclConsumer Consumer(Results, CurContext);
John McCalle87beb22010-04-23 18:46:30 +00002728
2729 // First pass: look for tags.
2730 Results.setFilter(Filter);
Douglas Gregor39982192010-08-15 06:18:01 +00002731 LookupVisibleDecls(S, LookupTagName, Consumer,
2732 CodeCompleter->includeGlobals());
John McCalle87beb22010-04-23 18:46:30 +00002733
Douglas Gregor39982192010-08-15 06:18:01 +00002734 if (CodeCompleter->includeGlobals()) {
2735 // Second pass: look for nested name specifiers.
2736 Results.setFilter(&ResultBuilder::IsNestedNameSpecifier);
2737 LookupVisibleDecls(S, LookupNestedNameSpecifierName, Consumer);
2738 }
Douglas Gregor3545ff42009-09-21 16:56:56 +00002739
Douglas Gregor00c37ef2010-08-11 21:23:17 +00002740 HandleCodeCompleteResults(this, CodeCompleter, ContextKind,
2741 Results.data(),Results.size());
Douglas Gregorf45b0cf2009-09-18 15:37:17 +00002742}
2743
Douglas Gregord328d572009-09-21 18:10:23 +00002744void Sema::CodeCompleteCase(Scope *S) {
2745 if (getSwitchStack().empty() || !CodeCompleter)
2746 return;
2747
2748 SwitchStmt *Switch = getSwitchStack().back();
Douglas Gregor85b50632010-07-28 21:50:18 +00002749 if (!Switch->getCond()->getType()->isEnumeralType()) {
Douglas Gregor68762e72010-08-23 21:17:50 +00002750 CodeCompleteExpressionData Data(Switch->getCond()->getType());
2751 Data.IntegralConstantExpression = true;
2752 CodeCompleteExpression(S, Data);
Douglas Gregord328d572009-09-21 18:10:23 +00002753 return;
Douglas Gregor85b50632010-07-28 21:50:18 +00002754 }
Douglas Gregord328d572009-09-21 18:10:23 +00002755
2756 // Code-complete the cases of a switch statement over an enumeration type
2757 // by providing the list of
2758 EnumDecl *Enum = Switch->getCond()->getType()->getAs<EnumType>()->getDecl();
2759
2760 // Determine which enumerators we have already seen in the switch statement.
2761 // FIXME: Ideally, we would also be able to look *past* the code-completion
2762 // token, in case we are code-completing in the middle of the switch and not
2763 // at the end. However, we aren't able to do so at the moment.
2764 llvm::SmallPtrSet<EnumConstantDecl *, 8> EnumeratorsSeen;
Douglas Gregorf2510672009-09-21 19:57:38 +00002765 NestedNameSpecifier *Qualifier = 0;
Douglas Gregord328d572009-09-21 18:10:23 +00002766 for (SwitchCase *SC = Switch->getSwitchCaseList(); SC;
2767 SC = SC->getNextSwitchCase()) {
2768 CaseStmt *Case = dyn_cast<CaseStmt>(SC);
2769 if (!Case)
2770 continue;
2771
2772 Expr *CaseVal = Case->getLHS()->IgnoreParenCasts();
2773 if (DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(CaseVal))
2774 if (EnumConstantDecl *Enumerator
2775 = dyn_cast<EnumConstantDecl>(DRE->getDecl())) {
2776 // We look into the AST of the case statement to determine which
2777 // enumerator was named. Alternatively, we could compute the value of
2778 // the integral constant expression, then compare it against the
2779 // values of each enumerator. However, value-based approach would not
2780 // work as well with C++ templates where enumerators declared within a
2781 // template are type- and value-dependent.
2782 EnumeratorsSeen.insert(Enumerator);
2783
Douglas Gregorf2510672009-09-21 19:57:38 +00002784 // If this is a qualified-id, keep track of the nested-name-specifier
2785 // so that we can reproduce it as part of code completion, e.g.,
Douglas Gregord328d572009-09-21 18:10:23 +00002786 //
2787 // switch (TagD.getKind()) {
2788 // case TagDecl::TK_enum:
2789 // break;
2790 // case XXX
2791 //
Douglas Gregorf2510672009-09-21 19:57:38 +00002792 // At the XXX, our completions are TagDecl::TK_union,
Douglas Gregord328d572009-09-21 18:10:23 +00002793 // TagDecl::TK_struct, and TagDecl::TK_class, rather than TK_union,
2794 // TK_struct, and TK_class.
Douglas Gregor4bd90e52009-10-23 18:54:35 +00002795 Qualifier = DRE->getQualifier();
Douglas Gregord328d572009-09-21 18:10:23 +00002796 }
2797 }
2798
Douglas Gregorf2510672009-09-21 19:57:38 +00002799 if (getLangOptions().CPlusPlus && !Qualifier && EnumeratorsSeen.empty()) {
2800 // If there are no prior enumerators in C++, check whether we have to
2801 // qualify the names of the enumerators that we suggest, because they
2802 // may not be visible in this scope.
2803 Qualifier = getRequiredQualification(Context, CurContext,
2804 Enum->getDeclContext());
2805
2806 // FIXME: Scoped enums need to start with "EnumDecl" as the context!
2807 }
2808
Douglas Gregord328d572009-09-21 18:10:23 +00002809 // Add any enumerators that have not yet been mentioned.
2810 ResultBuilder Results(*this);
2811 Results.EnterNewScope();
2812 for (EnumDecl::enumerator_iterator E = Enum->enumerator_begin(),
2813 EEnd = Enum->enumerator_end();
2814 E != EEnd; ++E) {
2815 if (EnumeratorsSeen.count(*E))
2816 continue;
2817
Douglas Gregorfc59ce12010-01-14 16:14:35 +00002818 Results.AddResult(CodeCompleteConsumer::Result(*E, Qualifier),
2819 CurContext, 0, false);
Douglas Gregord328d572009-09-21 18:10:23 +00002820 }
2821 Results.ExitScope();
Douglas Gregor285560922010-04-06 20:02:15 +00002822
Douglas Gregor9eb77012009-11-07 00:00:49 +00002823 if (CodeCompleter->includeMacros())
Douglas Gregorf98e6a22010-01-13 23:51:12 +00002824 AddMacroResults(PP, Results);
Douglas Gregor00c37ef2010-08-11 21:23:17 +00002825 HandleCodeCompleteResults(this, CodeCompleter,
2826 CodeCompletionContext::CCC_Expression,
2827 Results.data(),Results.size());
Douglas Gregord328d572009-09-21 18:10:23 +00002828}
2829
Douglas Gregorcabea402009-09-22 15:41:20 +00002830namespace {
2831 struct IsBetterOverloadCandidate {
2832 Sema &S;
John McCallbc077cf2010-02-08 23:07:23 +00002833 SourceLocation Loc;
Douglas Gregorcabea402009-09-22 15:41:20 +00002834
2835 public:
John McCallbc077cf2010-02-08 23:07:23 +00002836 explicit IsBetterOverloadCandidate(Sema &S, SourceLocation Loc)
2837 : S(S), Loc(Loc) { }
Douglas Gregorcabea402009-09-22 15:41:20 +00002838
2839 bool
2840 operator()(const OverloadCandidate &X, const OverloadCandidate &Y) const {
John McCall5c32be02010-08-24 20:38:10 +00002841 return isBetterOverloadCandidate(S, X, Y, Loc);
Douglas Gregorcabea402009-09-22 15:41:20 +00002842 }
2843 };
2844}
2845
Douglas Gregor6ed3eb82010-05-30 06:10:08 +00002846static bool anyNullArguments(Expr **Args, unsigned NumArgs) {
2847 if (NumArgs && !Args)
2848 return true;
2849
2850 for (unsigned I = 0; I != NumArgs; ++I)
2851 if (!Args[I])
2852 return true;
2853
2854 return false;
2855}
2856
Douglas Gregorcabea402009-09-22 15:41:20 +00002857void Sema::CodeCompleteCall(Scope *S, ExprTy *FnIn,
2858 ExprTy **ArgsIn, unsigned NumArgs) {
2859 if (!CodeCompleter)
2860 return;
Douglas Gregor3ef59522009-12-11 19:06:04 +00002861
2862 // When we're code-completing for a call, we fall back to ordinary
2863 // name code-completion whenever we can't produce specific
2864 // results. We may want to revisit this strategy in the future,
2865 // e.g., by merging the two kinds of results.
2866
Douglas Gregorcabea402009-09-22 15:41:20 +00002867 Expr *Fn = (Expr *)FnIn;
2868 Expr **Args = (Expr **)ArgsIn;
Douglas Gregor3ef59522009-12-11 19:06:04 +00002869
Douglas Gregorcabea402009-09-22 15:41:20 +00002870 // Ignore type-dependent call expressions entirely.
Douglas Gregor6ed3eb82010-05-30 06:10:08 +00002871 if (!Fn || Fn->isTypeDependent() || anyNullArguments(Args, NumArgs) ||
Douglas Gregor3ef59522009-12-11 19:06:04 +00002872 Expr::hasAnyTypeDependentArguments(Args, NumArgs)) {
Douglas Gregor00c37ef2010-08-11 21:23:17 +00002873 CodeCompleteOrdinaryName(S, PCC_Expression);
Douglas Gregorcabea402009-09-22 15:41:20 +00002874 return;
Douglas Gregor3ef59522009-12-11 19:06:04 +00002875 }
Douglas Gregorcabea402009-09-22 15:41:20 +00002876
John McCall57500772009-12-16 12:17:52 +00002877 // Build an overload candidate set based on the functions we find.
John McCallbc077cf2010-02-08 23:07:23 +00002878 SourceLocation Loc = Fn->getExprLoc();
2879 OverloadCandidateSet CandidateSet(Loc);
John McCall57500772009-12-16 12:17:52 +00002880
Douglas Gregorcabea402009-09-22 15:41:20 +00002881 // FIXME: What if we're calling something that isn't a function declaration?
2882 // FIXME: What if we're calling a pseudo-destructor?
2883 // FIXME: What if we're calling a member function?
2884
Douglas Gregorff59f672010-01-21 15:46:19 +00002885 typedef CodeCompleteConsumer::OverloadCandidate ResultCandidate;
2886 llvm::SmallVector<ResultCandidate, 8> Results;
2887
John McCall57500772009-12-16 12:17:52 +00002888 Expr *NakedFn = Fn->IgnoreParenCasts();
2889 if (UnresolvedLookupExpr *ULE = dyn_cast<UnresolvedLookupExpr>(NakedFn))
2890 AddOverloadedCallCandidates(ULE, Args, NumArgs, CandidateSet,
2891 /*PartialOverloading=*/ true);
2892 else if (DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(NakedFn)) {
2893 FunctionDecl *FDecl = dyn_cast<FunctionDecl>(DRE->getDecl());
Douglas Gregorff59f672010-01-21 15:46:19 +00002894 if (FDecl) {
Douglas Gregor6ed3eb82010-05-30 06:10:08 +00002895 if (!getLangOptions().CPlusPlus ||
2896 !FDecl->getType()->getAs<FunctionProtoType>())
Douglas Gregorff59f672010-01-21 15:46:19 +00002897 Results.push_back(ResultCandidate(FDecl));
2898 else
John McCallb89836b2010-01-26 01:37:31 +00002899 // FIXME: access?
John McCalla0296f72010-03-19 07:35:19 +00002900 AddOverloadCandidate(FDecl, DeclAccessPair::make(FDecl, AS_none),
2901 Args, NumArgs, CandidateSet,
Douglas Gregorb05275a2010-04-16 17:41:49 +00002902 false, /*PartialOverloading*/true);
Douglas Gregorff59f672010-01-21 15:46:19 +00002903 }
John McCall57500772009-12-16 12:17:52 +00002904 }
Douglas Gregorcabea402009-09-22 15:41:20 +00002905
Douglas Gregor7aa6b222010-05-30 01:49:25 +00002906 QualType ParamType;
2907
Douglas Gregorff59f672010-01-21 15:46:19 +00002908 if (!CandidateSet.empty()) {
2909 // Sort the overload candidate set by placing the best overloads first.
2910 std::stable_sort(CandidateSet.begin(), CandidateSet.end(),
John McCallbc077cf2010-02-08 23:07:23 +00002911 IsBetterOverloadCandidate(*this, Loc));
Douglas Gregorcabea402009-09-22 15:41:20 +00002912
Douglas Gregorff59f672010-01-21 15:46:19 +00002913 // Add the remaining viable overload candidates as code-completion reslults.
2914 for (OverloadCandidateSet::iterator Cand = CandidateSet.begin(),
2915 CandEnd = CandidateSet.end();
2916 Cand != CandEnd; ++Cand) {
2917 if (Cand->Viable)
2918 Results.push_back(ResultCandidate(Cand->Function));
2919 }
Douglas Gregor7aa6b222010-05-30 01:49:25 +00002920
2921 // From the viable candidates, try to determine the type of this parameter.
2922 for (unsigned I = 0, N = Results.size(); I != N; ++I) {
2923 if (const FunctionType *FType = Results[I].getFunctionType())
2924 if (const FunctionProtoType *Proto = dyn_cast<FunctionProtoType>(FType))
2925 if (NumArgs < Proto->getNumArgs()) {
2926 if (ParamType.isNull())
2927 ParamType = Proto->getArgType(NumArgs);
2928 else if (!Context.hasSameUnqualifiedType(
2929 ParamType.getNonReferenceType(),
2930 Proto->getArgType(NumArgs).getNonReferenceType())) {
2931 ParamType = QualType();
2932 break;
2933 }
2934 }
2935 }
2936 } else {
2937 // Try to determine the parameter type from the type of the expression
2938 // being called.
2939 QualType FunctionType = Fn->getType();
2940 if (const PointerType *Ptr = FunctionType->getAs<PointerType>())
2941 FunctionType = Ptr->getPointeeType();
2942 else if (const BlockPointerType *BlockPtr
2943 = FunctionType->getAs<BlockPointerType>())
2944 FunctionType = BlockPtr->getPointeeType();
2945 else if (const MemberPointerType *MemPtr
2946 = FunctionType->getAs<MemberPointerType>())
2947 FunctionType = MemPtr->getPointeeType();
2948
2949 if (const FunctionProtoType *Proto
2950 = FunctionType->getAs<FunctionProtoType>()) {
2951 if (NumArgs < Proto->getNumArgs())
2952 ParamType = Proto->getArgType(NumArgs);
2953 }
Douglas Gregorcabea402009-09-22 15:41:20 +00002954 }
Douglas Gregor3ef59522009-12-11 19:06:04 +00002955
Douglas Gregor7aa6b222010-05-30 01:49:25 +00002956 if (ParamType.isNull())
Douglas Gregor00c37ef2010-08-11 21:23:17 +00002957 CodeCompleteOrdinaryName(S, PCC_Expression);
Douglas Gregor7aa6b222010-05-30 01:49:25 +00002958 else
2959 CodeCompleteExpression(S, ParamType);
2960
Douglas Gregorc01890e2010-04-06 20:19:47 +00002961 if (!Results.empty())
Douglas Gregor3ef59522009-12-11 19:06:04 +00002962 CodeCompleter->ProcessOverloadCandidates(*this, NumArgs, Results.data(),
2963 Results.size());
Douglas Gregorcabea402009-09-22 15:41:20 +00002964}
2965
John McCall48871652010-08-21 09:40:31 +00002966void Sema::CodeCompleteInitializer(Scope *S, Decl *D) {
2967 ValueDecl *VD = dyn_cast_or_null<ValueDecl>(D);
Douglas Gregor7aa6b222010-05-30 01:49:25 +00002968 if (!VD) {
Douglas Gregor00c37ef2010-08-11 21:23:17 +00002969 CodeCompleteOrdinaryName(S, PCC_Expression);
Douglas Gregor7aa6b222010-05-30 01:49:25 +00002970 return;
2971 }
2972
2973 CodeCompleteExpression(S, VD->getType());
2974}
2975
2976void Sema::CodeCompleteReturn(Scope *S) {
2977 QualType ResultType;
2978 if (isa<BlockDecl>(CurContext)) {
2979 if (BlockScopeInfo *BSI = getCurBlock())
2980 ResultType = BSI->ReturnType;
2981 } else if (FunctionDecl *Function = dyn_cast<FunctionDecl>(CurContext))
2982 ResultType = Function->getResultType();
2983 else if (ObjCMethodDecl *Method = dyn_cast<ObjCMethodDecl>(CurContext))
2984 ResultType = Method->getResultType();
2985
2986 if (ResultType.isNull())
Douglas Gregor00c37ef2010-08-11 21:23:17 +00002987 CodeCompleteOrdinaryName(S, PCC_Expression);
Douglas Gregor7aa6b222010-05-30 01:49:25 +00002988 else
2989 CodeCompleteExpression(S, ResultType);
2990}
2991
2992void Sema::CodeCompleteAssignmentRHS(Scope *S, ExprTy *LHS) {
2993 if (LHS)
2994 CodeCompleteExpression(S, static_cast<Expr *>(LHS)->getType());
2995 else
Douglas Gregor00c37ef2010-08-11 21:23:17 +00002996 CodeCompleteOrdinaryName(S, PCC_Expression);
Douglas Gregor7aa6b222010-05-30 01:49:25 +00002997}
2998
Jeffrey Yasskinc76498d2010-04-08 16:38:48 +00002999void Sema::CodeCompleteQualifiedId(Scope *S, CXXScopeSpec &SS,
Douglas Gregor2436e712009-09-17 21:32:03 +00003000 bool EnteringContext) {
3001 if (!SS.getScopeRep() || !CodeCompleter)
3002 return;
3003
Douglas Gregor3545ff42009-09-21 16:56:56 +00003004 DeclContext *Ctx = computeDeclContext(SS, EnteringContext);
3005 if (!Ctx)
3006 return;
Douglas Gregor800f2f02009-12-11 18:28:39 +00003007
3008 // Try to instantiate any non-dependent declaration contexts before
3009 // we look in them.
John McCall0b66eb32010-05-01 00:40:08 +00003010 if (!isDependentScopeSpecifier(SS) && RequireCompleteDeclContext(SS, Ctx))
Douglas Gregor800f2f02009-12-11 18:28:39 +00003011 return;
3012
Douglas Gregor3545ff42009-09-21 16:56:56 +00003013 ResultBuilder Results(*this);
Douglas Gregor200c99d2010-01-14 03:35:48 +00003014 CodeCompletionDeclConsumer Consumer(Results, CurContext);
3015 LookupVisibleDecls(Ctx, LookupOrdinaryName, Consumer);
Douglas Gregor3545ff42009-09-21 16:56:56 +00003016
3017 // The "template" keyword can follow "::" in the grammar, but only
3018 // put it into the grammar if the nested-name-specifier is dependent.
3019 NestedNameSpecifier *NNS = (NestedNameSpecifier *)SS.getScopeRep();
3020 if (!Results.empty() && NNS->isDependent())
Douglas Gregor78a21012010-01-14 16:01:26 +00003021 Results.AddResult("template");
Douglas Gregor3545ff42009-09-21 16:56:56 +00003022
Douglas Gregor00c37ef2010-08-11 21:23:17 +00003023 HandleCodeCompleteResults(this, CodeCompleter,
3024 CodeCompletionContext::CCC_Other,
3025 Results.data(),Results.size());
Douglas Gregor2436e712009-09-17 21:32:03 +00003026}
Douglas Gregor7e90c6d2009-09-18 19:03:04 +00003027
3028void Sema::CodeCompleteUsing(Scope *S) {
3029 if (!CodeCompleter)
3030 return;
3031
Douglas Gregor3545ff42009-09-21 16:56:56 +00003032 ResultBuilder Results(*this, &ResultBuilder::IsNestedNameSpecifier);
Douglas Gregor64b12b52009-09-22 23:31:26 +00003033 Results.EnterNewScope();
Douglas Gregor3545ff42009-09-21 16:56:56 +00003034
3035 // If we aren't in class scope, we could see the "namespace" keyword.
3036 if (!S->isClassScope())
Douglas Gregor78a21012010-01-14 16:01:26 +00003037 Results.AddResult(CodeCompleteConsumer::Result("namespace"));
Douglas Gregor3545ff42009-09-21 16:56:56 +00003038
3039 // After "using", we can see anything that would start a
3040 // nested-name-specifier.
Douglas Gregora6e2edc2010-01-14 03:27:13 +00003041 CodeCompletionDeclConsumer Consumer(Results, CurContext);
Douglas Gregor39982192010-08-15 06:18:01 +00003042 LookupVisibleDecls(S, LookupOrdinaryName, Consumer,
3043 CodeCompleter->includeGlobals());
Douglas Gregor64b12b52009-09-22 23:31:26 +00003044 Results.ExitScope();
Douglas Gregor3545ff42009-09-21 16:56:56 +00003045
Douglas Gregor00c37ef2010-08-11 21:23:17 +00003046 HandleCodeCompleteResults(this, CodeCompleter,
3047 CodeCompletionContext::CCC_Other,
3048 Results.data(),Results.size());
Douglas Gregor7e90c6d2009-09-18 19:03:04 +00003049}
3050
3051void Sema::CodeCompleteUsingDirective(Scope *S) {
3052 if (!CodeCompleter)
3053 return;
3054
Douglas Gregor3545ff42009-09-21 16:56:56 +00003055 // After "using namespace", we expect to see a namespace name or namespace
3056 // alias.
3057 ResultBuilder Results(*this, &ResultBuilder::IsNamespaceOrAlias);
Douglas Gregor64b12b52009-09-22 23:31:26 +00003058 Results.EnterNewScope();
Douglas Gregora6e2edc2010-01-14 03:27:13 +00003059 CodeCompletionDeclConsumer Consumer(Results, CurContext);
Douglas Gregor39982192010-08-15 06:18:01 +00003060 LookupVisibleDecls(S, LookupOrdinaryName, Consumer,
3061 CodeCompleter->includeGlobals());
Douglas Gregor64b12b52009-09-22 23:31:26 +00003062 Results.ExitScope();
Douglas Gregor00c37ef2010-08-11 21:23:17 +00003063 HandleCodeCompleteResults(this, CodeCompleter,
Douglas Gregor39982192010-08-15 06:18:01 +00003064 CodeCompletionContext::CCC_Namespace,
Douglas Gregor00c37ef2010-08-11 21:23:17 +00003065 Results.data(),Results.size());
Douglas Gregor7e90c6d2009-09-18 19:03:04 +00003066}
3067
3068void Sema::CodeCompleteNamespaceDecl(Scope *S) {
3069 if (!CodeCompleter)
3070 return;
3071
Douglas Gregor3545ff42009-09-21 16:56:56 +00003072 ResultBuilder Results(*this, &ResultBuilder::IsNamespace);
3073 DeclContext *Ctx = (DeclContext *)S->getEntity();
3074 if (!S->getParent())
3075 Ctx = Context.getTranslationUnitDecl();
3076
3077 if (Ctx && Ctx->isFileContext()) {
3078 // We only want to see those namespaces that have already been defined
3079 // within this scope, because its likely that the user is creating an
3080 // extended namespace declaration. Keep track of the most recent
3081 // definition of each namespace.
3082 std::map<NamespaceDecl *, NamespaceDecl *> OrigToLatest;
3083 for (DeclContext::specific_decl_iterator<NamespaceDecl>
3084 NS(Ctx->decls_begin()), NSEnd(Ctx->decls_end());
3085 NS != NSEnd; ++NS)
3086 OrigToLatest[NS->getOriginalNamespace()] = *NS;
3087
3088 // Add the most recent definition (or extended definition) of each
3089 // namespace to the list of results.
Douglas Gregor64b12b52009-09-22 23:31:26 +00003090 Results.EnterNewScope();
Douglas Gregor3545ff42009-09-21 16:56:56 +00003091 for (std::map<NamespaceDecl *, NamespaceDecl *>::iterator
3092 NS = OrigToLatest.begin(), NSEnd = OrigToLatest.end();
3093 NS != NSEnd; ++NS)
Douglas Gregorfc59ce12010-01-14 16:14:35 +00003094 Results.AddResult(CodeCompleteConsumer::Result(NS->second, 0),
3095 CurContext, 0, false);
Douglas Gregor64b12b52009-09-22 23:31:26 +00003096 Results.ExitScope();
Douglas Gregor3545ff42009-09-21 16:56:56 +00003097 }
3098
Douglas Gregor00c37ef2010-08-11 21:23:17 +00003099 HandleCodeCompleteResults(this, CodeCompleter,
3100 CodeCompletionContext::CCC_Other,
3101 Results.data(),Results.size());
Douglas Gregor7e90c6d2009-09-18 19:03:04 +00003102}
3103
3104void Sema::CodeCompleteNamespaceAliasDecl(Scope *S) {
3105 if (!CodeCompleter)
3106 return;
3107
Douglas Gregor3545ff42009-09-21 16:56:56 +00003108 // After "namespace", we expect to see a namespace or alias.
3109 ResultBuilder Results(*this, &ResultBuilder::IsNamespaceOrAlias);
Douglas Gregora6e2edc2010-01-14 03:27:13 +00003110 CodeCompletionDeclConsumer Consumer(Results, CurContext);
Douglas Gregor39982192010-08-15 06:18:01 +00003111 LookupVisibleDecls(S, LookupOrdinaryName, Consumer,
3112 CodeCompleter->includeGlobals());
Douglas Gregor00c37ef2010-08-11 21:23:17 +00003113 HandleCodeCompleteResults(this, CodeCompleter,
Douglas Gregor39982192010-08-15 06:18:01 +00003114 CodeCompletionContext::CCC_Namespace,
Douglas Gregor00c37ef2010-08-11 21:23:17 +00003115 Results.data(),Results.size());
Douglas Gregor7e90c6d2009-09-18 19:03:04 +00003116}
3117
Douglas Gregorc811ede2009-09-18 20:05:18 +00003118void Sema::CodeCompleteOperatorName(Scope *S) {
3119 if (!CodeCompleter)
3120 return;
Douglas Gregor3545ff42009-09-21 16:56:56 +00003121
3122 typedef CodeCompleteConsumer::Result Result;
3123 ResultBuilder Results(*this, &ResultBuilder::IsType);
Douglas Gregor64b12b52009-09-22 23:31:26 +00003124 Results.EnterNewScope();
Douglas Gregorc811ede2009-09-18 20:05:18 +00003125
Douglas Gregor3545ff42009-09-21 16:56:56 +00003126 // Add the names of overloadable operators.
3127#define OVERLOADED_OPERATOR(Name,Spelling,Token,Unary,Binary,MemberOnly) \
3128 if (std::strcmp(Spelling, "?")) \
Douglas Gregor78a21012010-01-14 16:01:26 +00003129 Results.AddResult(Result(Spelling));
Douglas Gregor3545ff42009-09-21 16:56:56 +00003130#include "clang/Basic/OperatorKinds.def"
3131
3132 // Add any type names visible from the current scope
Douglas Gregor6ae4c522010-01-14 03:21:49 +00003133 Results.allowNestedNameSpecifiers();
Douglas Gregora6e2edc2010-01-14 03:27:13 +00003134 CodeCompletionDeclConsumer Consumer(Results, CurContext);
Douglas Gregor39982192010-08-15 06:18:01 +00003135 LookupVisibleDecls(S, LookupOrdinaryName, Consumer,
3136 CodeCompleter->includeGlobals());
Douglas Gregor3545ff42009-09-21 16:56:56 +00003137
3138 // Add any type specifiers
Douglas Gregorf98e6a22010-01-13 23:51:12 +00003139 AddTypeSpecifierResults(getLangOptions(), Results);
Douglas Gregor64b12b52009-09-22 23:31:26 +00003140 Results.ExitScope();
Douglas Gregor3545ff42009-09-21 16:56:56 +00003141
Douglas Gregor00c37ef2010-08-11 21:23:17 +00003142 HandleCodeCompleteResults(this, CodeCompleter,
Douglas Gregor39982192010-08-15 06:18:01 +00003143 CodeCompletionContext::CCC_Type,
Douglas Gregor00c37ef2010-08-11 21:23:17 +00003144 Results.data(),Results.size());
Douglas Gregorc811ede2009-09-18 20:05:18 +00003145}
Douglas Gregor7e90c6d2009-09-18 19:03:04 +00003146
Douglas Gregorf1934162010-01-13 21:24:21 +00003147// Macro that expands to @Keyword or Keyword, depending on whether NeedAt is
3148// true or false.
3149#define OBJC_AT_KEYWORD_NAME(NeedAt,Keyword) NeedAt? "@" #Keyword : #Keyword
Douglas Gregorf98e6a22010-01-13 23:51:12 +00003150static void AddObjCImplementationResults(const LangOptions &LangOpts,
Douglas Gregorf1934162010-01-13 21:24:21 +00003151 ResultBuilder &Results,
3152 bool NeedAt) {
3153 typedef CodeCompleteConsumer::Result Result;
3154 // Since we have an implementation, we can end it.
Douglas Gregor78a21012010-01-14 16:01:26 +00003155 Results.AddResult(Result(OBJC_AT_KEYWORD_NAME(NeedAt,end)));
Douglas Gregorf1934162010-01-13 21:24:21 +00003156
3157 CodeCompletionString *Pattern = 0;
3158 if (LangOpts.ObjC2) {
3159 // @dynamic
3160 Pattern = new CodeCompletionString;
3161 Pattern->AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt,dynamic));
3162 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
3163 Pattern->AddPlaceholderChunk("property");
Douglas Gregor78a21012010-01-14 16:01:26 +00003164 Results.AddResult(Result(Pattern));
Douglas Gregorf1934162010-01-13 21:24:21 +00003165
3166 // @synthesize
3167 Pattern = new CodeCompletionString;
3168 Pattern->AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt,synthesize));
3169 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
3170 Pattern->AddPlaceholderChunk("property");
Douglas Gregor78a21012010-01-14 16:01:26 +00003171 Results.AddResult(Result(Pattern));
Douglas Gregorf1934162010-01-13 21:24:21 +00003172 }
3173}
3174
Douglas Gregorf98e6a22010-01-13 23:51:12 +00003175static void AddObjCInterfaceResults(const LangOptions &LangOpts,
Douglas Gregorf1934162010-01-13 21:24:21 +00003176 ResultBuilder &Results,
3177 bool NeedAt) {
3178 typedef CodeCompleteConsumer::Result Result;
3179
3180 // Since we have an interface or protocol, we can end it.
Douglas Gregor78a21012010-01-14 16:01:26 +00003181 Results.AddResult(Result(OBJC_AT_KEYWORD_NAME(NeedAt,end)));
Douglas Gregorf1934162010-01-13 21:24:21 +00003182
3183 if (LangOpts.ObjC2) {
3184 // @property
Douglas Gregor78a21012010-01-14 16:01:26 +00003185 Results.AddResult(Result(OBJC_AT_KEYWORD_NAME(NeedAt,property)));
Douglas Gregorf1934162010-01-13 21:24:21 +00003186
3187 // @required
Douglas Gregor78a21012010-01-14 16:01:26 +00003188 Results.AddResult(Result(OBJC_AT_KEYWORD_NAME(NeedAt,required)));
Douglas Gregorf1934162010-01-13 21:24:21 +00003189
3190 // @optional
Douglas Gregor78a21012010-01-14 16:01:26 +00003191 Results.AddResult(Result(OBJC_AT_KEYWORD_NAME(NeedAt,optional)));
Douglas Gregorf1934162010-01-13 21:24:21 +00003192 }
3193}
3194
Douglas Gregorf98e6a22010-01-13 23:51:12 +00003195static void AddObjCTopLevelResults(ResultBuilder &Results, bool NeedAt) {
Douglas Gregorf1934162010-01-13 21:24:21 +00003196 typedef CodeCompleteConsumer::Result Result;
3197 CodeCompletionString *Pattern = 0;
3198
3199 // @class name ;
3200 Pattern = new CodeCompletionString;
3201 Pattern->AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt,class));
3202 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
Douglas Gregorf4c33342010-05-28 00:22:41 +00003203 Pattern->AddPlaceholderChunk("name");
Douglas Gregor78a21012010-01-14 16:01:26 +00003204 Results.AddResult(Result(Pattern));
Douglas Gregorf1934162010-01-13 21:24:21 +00003205
Douglas Gregorf4c33342010-05-28 00:22:41 +00003206 if (Results.includeCodePatterns()) {
3207 // @interface name
3208 // FIXME: Could introduce the whole pattern, including superclasses and
3209 // such.
3210 Pattern = new CodeCompletionString;
3211 Pattern->AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt,interface));
3212 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
3213 Pattern->AddPlaceholderChunk("class");
3214 Results.AddResult(Result(Pattern));
Douglas Gregorf1934162010-01-13 21:24:21 +00003215
Douglas Gregorf4c33342010-05-28 00:22:41 +00003216 // @protocol name
3217 Pattern = new CodeCompletionString;
3218 Pattern->AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt,protocol));
3219 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
3220 Pattern->AddPlaceholderChunk("protocol");
3221 Results.AddResult(Result(Pattern));
3222
3223 // @implementation name
3224 Pattern = new CodeCompletionString;
3225 Pattern->AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt,implementation));
3226 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
3227 Pattern->AddPlaceholderChunk("class");
3228 Results.AddResult(Result(Pattern));
3229 }
Douglas Gregorf1934162010-01-13 21:24:21 +00003230
3231 // @compatibility_alias name
3232 Pattern = new CodeCompletionString;
3233 Pattern->AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt,compatibility_alias));
3234 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
3235 Pattern->AddPlaceholderChunk("alias");
3236 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
3237 Pattern->AddPlaceholderChunk("class");
Douglas Gregor78a21012010-01-14 16:01:26 +00003238 Results.AddResult(Result(Pattern));
Douglas Gregorf1934162010-01-13 21:24:21 +00003239}
3240
John McCall48871652010-08-21 09:40:31 +00003241void Sema::CodeCompleteObjCAtDirective(Scope *S, Decl *ObjCImpDecl,
Douglas Gregorf48706c2009-12-07 09:27:33 +00003242 bool InInterface) {
3243 typedef CodeCompleteConsumer::Result Result;
3244 ResultBuilder Results(*this);
3245 Results.EnterNewScope();
Douglas Gregorf1934162010-01-13 21:24:21 +00003246 if (ObjCImpDecl)
Douglas Gregorf98e6a22010-01-13 23:51:12 +00003247 AddObjCImplementationResults(getLangOptions(), Results, false);
Douglas Gregorf1934162010-01-13 21:24:21 +00003248 else if (InInterface)
Douglas Gregorf98e6a22010-01-13 23:51:12 +00003249 AddObjCInterfaceResults(getLangOptions(), Results, false);
Douglas Gregorf1934162010-01-13 21:24:21 +00003250 else
Douglas Gregorf98e6a22010-01-13 23:51:12 +00003251 AddObjCTopLevelResults(Results, false);
Douglas Gregorf48706c2009-12-07 09:27:33 +00003252 Results.ExitScope();
Douglas Gregor00c37ef2010-08-11 21:23:17 +00003253 HandleCodeCompleteResults(this, CodeCompleter,
3254 CodeCompletionContext::CCC_Other,
3255 Results.data(),Results.size());
Douglas Gregorf48706c2009-12-07 09:27:33 +00003256}
3257
Douglas Gregorf98e6a22010-01-13 23:51:12 +00003258static void AddObjCExpressionResults(ResultBuilder &Results, bool NeedAt) {
Douglas Gregorbc7c5e42009-12-07 09:51:25 +00003259 typedef CodeCompleteConsumer::Result Result;
3260 CodeCompletionString *Pattern = 0;
3261
3262 // @encode ( type-name )
3263 Pattern = new CodeCompletionString;
Douglas Gregorf1934162010-01-13 21:24:21 +00003264 Pattern->AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt,encode));
Douglas Gregorbc7c5e42009-12-07 09:51:25 +00003265 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
3266 Pattern->AddPlaceholderChunk("type-name");
3267 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
Douglas Gregor78a21012010-01-14 16:01:26 +00003268 Results.AddResult(Result(Pattern));
Douglas Gregorbc7c5e42009-12-07 09:51:25 +00003269
3270 // @protocol ( protocol-name )
3271 Pattern = new CodeCompletionString;
Douglas Gregorf1934162010-01-13 21:24:21 +00003272 Pattern->AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt,protocol));
Douglas Gregorbc7c5e42009-12-07 09:51:25 +00003273 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
3274 Pattern->AddPlaceholderChunk("protocol-name");
3275 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
Douglas Gregor78a21012010-01-14 16:01:26 +00003276 Results.AddResult(Result(Pattern));
Douglas Gregorbc7c5e42009-12-07 09:51:25 +00003277
3278 // @selector ( selector )
3279 Pattern = new CodeCompletionString;
Douglas Gregorf1934162010-01-13 21:24:21 +00003280 Pattern->AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt,selector));
Douglas Gregorbc7c5e42009-12-07 09:51:25 +00003281 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
3282 Pattern->AddPlaceholderChunk("selector");
3283 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
Douglas Gregor78a21012010-01-14 16:01:26 +00003284 Results.AddResult(Result(Pattern));
Douglas Gregorbc7c5e42009-12-07 09:51:25 +00003285}
3286
Douglas Gregorf98e6a22010-01-13 23:51:12 +00003287static void AddObjCStatementResults(ResultBuilder &Results, bool NeedAt) {
Douglas Gregorbc7c5e42009-12-07 09:51:25 +00003288 typedef CodeCompleteConsumer::Result Result;
Douglas Gregorbc7c5e42009-12-07 09:51:25 +00003289 CodeCompletionString *Pattern = 0;
Douglas Gregorf1934162010-01-13 21:24:21 +00003290
Douglas Gregorf4c33342010-05-28 00:22:41 +00003291 if (Results.includeCodePatterns()) {
3292 // @try { statements } @catch ( declaration ) { statements } @finally
3293 // { statements }
3294 Pattern = new CodeCompletionString;
3295 Pattern->AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt,try));
3296 Pattern->AddChunk(CodeCompletionString::CK_LeftBrace);
3297 Pattern->AddPlaceholderChunk("statements");
3298 Pattern->AddChunk(CodeCompletionString::CK_RightBrace);
3299 Pattern->AddTextChunk("@catch");
3300 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
3301 Pattern->AddPlaceholderChunk("parameter");
3302 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
3303 Pattern->AddChunk(CodeCompletionString::CK_LeftBrace);
3304 Pattern->AddPlaceholderChunk("statements");
3305 Pattern->AddChunk(CodeCompletionString::CK_RightBrace);
3306 Pattern->AddTextChunk("@finally");
3307 Pattern->AddChunk(CodeCompletionString::CK_LeftBrace);
3308 Pattern->AddPlaceholderChunk("statements");
3309 Pattern->AddChunk(CodeCompletionString::CK_RightBrace);
3310 Results.AddResult(Result(Pattern));
3311 }
Douglas Gregorf1934162010-01-13 21:24:21 +00003312
Douglas Gregorbc7c5e42009-12-07 09:51:25 +00003313 // @throw
3314 Pattern = new CodeCompletionString;
Douglas Gregorf1934162010-01-13 21:24:21 +00003315 Pattern->AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt,throw));
Douglas Gregor6a803932010-01-12 06:38:28 +00003316 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
Douglas Gregorbc7c5e42009-12-07 09:51:25 +00003317 Pattern->AddPlaceholderChunk("expression");
Douglas Gregor78a21012010-01-14 16:01:26 +00003318 Results.AddResult(Result(Pattern));
Douglas Gregorf1934162010-01-13 21:24:21 +00003319
Douglas Gregorf4c33342010-05-28 00:22:41 +00003320 if (Results.includeCodePatterns()) {
3321 // @synchronized ( expression ) { statements }
3322 Pattern = new CodeCompletionString;
3323 Pattern->AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt,synchronized));
3324 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
3325 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
3326 Pattern->AddPlaceholderChunk("expression");
3327 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
3328 Pattern->AddChunk(CodeCompletionString::CK_LeftBrace);
3329 Pattern->AddPlaceholderChunk("statements");
3330 Pattern->AddChunk(CodeCompletionString::CK_RightBrace);
3331 Results.AddResult(Result(Pattern));
3332 }
Douglas Gregorf1934162010-01-13 21:24:21 +00003333}
Douglas Gregorbc7c5e42009-12-07 09:51:25 +00003334
Douglas Gregorf98e6a22010-01-13 23:51:12 +00003335static void AddObjCVisibilityResults(const LangOptions &LangOpts,
Douglas Gregor48d46252010-01-13 21:54:15 +00003336 ResultBuilder &Results,
3337 bool NeedAt) {
Douglas Gregorf1934162010-01-13 21:24:21 +00003338 typedef CodeCompleteConsumer::Result Result;
Douglas Gregor78a21012010-01-14 16:01:26 +00003339 Results.AddResult(Result(OBJC_AT_KEYWORD_NAME(NeedAt,private)));
3340 Results.AddResult(Result(OBJC_AT_KEYWORD_NAME(NeedAt,protected)));
3341 Results.AddResult(Result(OBJC_AT_KEYWORD_NAME(NeedAt,public)));
Douglas Gregor48d46252010-01-13 21:54:15 +00003342 if (LangOpts.ObjC2)
Douglas Gregor78a21012010-01-14 16:01:26 +00003343 Results.AddResult(Result(OBJC_AT_KEYWORD_NAME(NeedAt,package)));
Douglas Gregor48d46252010-01-13 21:54:15 +00003344}
3345
3346void Sema::CodeCompleteObjCAtVisibility(Scope *S) {
3347 ResultBuilder Results(*this);
3348 Results.EnterNewScope();
Douglas Gregorf98e6a22010-01-13 23:51:12 +00003349 AddObjCVisibilityResults(getLangOptions(), Results, false);
Douglas Gregor48d46252010-01-13 21:54:15 +00003350 Results.ExitScope();
Douglas Gregor00c37ef2010-08-11 21:23:17 +00003351 HandleCodeCompleteResults(this, CodeCompleter,
3352 CodeCompletionContext::CCC_Other,
3353 Results.data(),Results.size());
Douglas Gregor48d46252010-01-13 21:54:15 +00003354}
3355
3356void Sema::CodeCompleteObjCAtStatement(Scope *S) {
Douglas Gregorf1934162010-01-13 21:24:21 +00003357 ResultBuilder Results(*this);
3358 Results.EnterNewScope();
Douglas Gregorf98e6a22010-01-13 23:51:12 +00003359 AddObjCStatementResults(Results, false);
3360 AddObjCExpressionResults(Results, false);
Douglas Gregorbc7c5e42009-12-07 09:51:25 +00003361 Results.ExitScope();
Douglas Gregor00c37ef2010-08-11 21:23:17 +00003362 HandleCodeCompleteResults(this, CodeCompleter,
3363 CodeCompletionContext::CCC_Other,
3364 Results.data(),Results.size());
Douglas Gregorbc7c5e42009-12-07 09:51:25 +00003365}
3366
3367void Sema::CodeCompleteObjCAtExpression(Scope *S) {
3368 ResultBuilder Results(*this);
3369 Results.EnterNewScope();
Douglas Gregorf98e6a22010-01-13 23:51:12 +00003370 AddObjCExpressionResults(Results, false);
Douglas Gregorbc7c5e42009-12-07 09:51:25 +00003371 Results.ExitScope();
Douglas Gregor00c37ef2010-08-11 21:23:17 +00003372 HandleCodeCompleteResults(this, CodeCompleter,
3373 CodeCompletionContext::CCC_Other,
3374 Results.data(),Results.size());
Douglas Gregorbc7c5e42009-12-07 09:51:25 +00003375}
3376
Douglas Gregore6078da2009-11-19 00:14:45 +00003377/// \brief Determine whether the addition of the given flag to an Objective-C
3378/// property's attributes will cause a conflict.
3379static bool ObjCPropertyFlagConflicts(unsigned Attributes, unsigned NewFlag) {
3380 // Check if we've already added this flag.
3381 if (Attributes & NewFlag)
3382 return true;
3383
3384 Attributes |= NewFlag;
3385
3386 // Check for collisions with "readonly".
3387 if ((Attributes & ObjCDeclSpec::DQ_PR_readonly) &&
3388 (Attributes & (ObjCDeclSpec::DQ_PR_readwrite |
3389 ObjCDeclSpec::DQ_PR_assign |
3390 ObjCDeclSpec::DQ_PR_copy |
3391 ObjCDeclSpec::DQ_PR_retain)))
3392 return true;
3393
3394 // Check for more than one of { assign, copy, retain }.
3395 unsigned AssignCopyRetMask = Attributes & (ObjCDeclSpec::DQ_PR_assign |
3396 ObjCDeclSpec::DQ_PR_copy |
3397 ObjCDeclSpec::DQ_PR_retain);
3398 if (AssignCopyRetMask &&
3399 AssignCopyRetMask != ObjCDeclSpec::DQ_PR_assign &&
3400 AssignCopyRetMask != ObjCDeclSpec::DQ_PR_copy &&
3401 AssignCopyRetMask != ObjCDeclSpec::DQ_PR_retain)
3402 return true;
3403
3404 return false;
3405}
3406
Douglas Gregor36029f42009-11-18 23:08:07 +00003407void Sema::CodeCompleteObjCPropertyFlags(Scope *S, ObjCDeclSpec &ODS) {
Steve Naroff936354c2009-10-08 21:55:05 +00003408 if (!CodeCompleter)
3409 return;
Douglas Gregor1b605f72009-11-19 01:08:35 +00003410
Steve Naroff936354c2009-10-08 21:55:05 +00003411 unsigned Attributes = ODS.getPropertyAttributes();
3412
3413 typedef CodeCompleteConsumer::Result Result;
3414 ResultBuilder Results(*this);
3415 Results.EnterNewScope();
Douglas Gregore6078da2009-11-19 00:14:45 +00003416 if (!ObjCPropertyFlagConflicts(Attributes, ObjCDeclSpec::DQ_PR_readonly))
Douglas Gregor78a21012010-01-14 16:01:26 +00003417 Results.AddResult(CodeCompleteConsumer::Result("readonly"));
Douglas Gregore6078da2009-11-19 00:14:45 +00003418 if (!ObjCPropertyFlagConflicts(Attributes, ObjCDeclSpec::DQ_PR_assign))
Douglas Gregor78a21012010-01-14 16:01:26 +00003419 Results.AddResult(CodeCompleteConsumer::Result("assign"));
Douglas Gregore6078da2009-11-19 00:14:45 +00003420 if (!ObjCPropertyFlagConflicts(Attributes, ObjCDeclSpec::DQ_PR_readwrite))
Douglas Gregor78a21012010-01-14 16:01:26 +00003421 Results.AddResult(CodeCompleteConsumer::Result("readwrite"));
Douglas Gregore6078da2009-11-19 00:14:45 +00003422 if (!ObjCPropertyFlagConflicts(Attributes, ObjCDeclSpec::DQ_PR_retain))
Douglas Gregor78a21012010-01-14 16:01:26 +00003423 Results.AddResult(CodeCompleteConsumer::Result("retain"));
Douglas Gregore6078da2009-11-19 00:14:45 +00003424 if (!ObjCPropertyFlagConflicts(Attributes, ObjCDeclSpec::DQ_PR_copy))
Douglas Gregor78a21012010-01-14 16:01:26 +00003425 Results.AddResult(CodeCompleteConsumer::Result("copy"));
Douglas Gregore6078da2009-11-19 00:14:45 +00003426 if (!ObjCPropertyFlagConflicts(Attributes, ObjCDeclSpec::DQ_PR_nonatomic))
Douglas Gregor78a21012010-01-14 16:01:26 +00003427 Results.AddResult(CodeCompleteConsumer::Result("nonatomic"));
Douglas Gregore6078da2009-11-19 00:14:45 +00003428 if (!ObjCPropertyFlagConflicts(Attributes, ObjCDeclSpec::DQ_PR_setter)) {
Douglas Gregor45f83ee2009-11-19 00:01:57 +00003429 CodeCompletionString *Setter = new CodeCompletionString;
3430 Setter->AddTypedTextChunk("setter");
3431 Setter->AddTextChunk(" = ");
3432 Setter->AddPlaceholderChunk("method");
Douglas Gregor78a21012010-01-14 16:01:26 +00003433 Results.AddResult(CodeCompleteConsumer::Result(Setter));
Douglas Gregor45f83ee2009-11-19 00:01:57 +00003434 }
Douglas Gregore6078da2009-11-19 00:14:45 +00003435 if (!ObjCPropertyFlagConflicts(Attributes, ObjCDeclSpec::DQ_PR_getter)) {
Douglas Gregor45f83ee2009-11-19 00:01:57 +00003436 CodeCompletionString *Getter = new CodeCompletionString;
3437 Getter->AddTypedTextChunk("getter");
3438 Getter->AddTextChunk(" = ");
3439 Getter->AddPlaceholderChunk("method");
Douglas Gregor78a21012010-01-14 16:01:26 +00003440 Results.AddResult(CodeCompleteConsumer::Result(Getter));
Douglas Gregor45f83ee2009-11-19 00:01:57 +00003441 }
Steve Naroff936354c2009-10-08 21:55:05 +00003442 Results.ExitScope();
Douglas Gregor00c37ef2010-08-11 21:23:17 +00003443 HandleCodeCompleteResults(this, CodeCompleter,
3444 CodeCompletionContext::CCC_Other,
3445 Results.data(),Results.size());
Steve Naroff936354c2009-10-08 21:55:05 +00003446}
Steve Naroffeae65032009-11-07 02:08:14 +00003447
Douglas Gregorc8537c52009-11-19 07:41:15 +00003448/// \brief Descripts the kind of Objective-C method that we want to find
3449/// via code completion.
3450enum ObjCMethodKind {
3451 MK_Any, //< Any kind of method, provided it means other specified criteria.
3452 MK_ZeroArgSelector, //< Zero-argument (unary) selector.
3453 MK_OneArgSelector //< One-argument selector.
3454};
3455
3456static bool isAcceptableObjCMethod(ObjCMethodDecl *Method,
3457 ObjCMethodKind WantKind,
3458 IdentifierInfo **SelIdents,
3459 unsigned NumSelIdents) {
3460 Selector Sel = Method->getSelector();
3461 if (NumSelIdents > Sel.getNumArgs())
3462 return false;
3463
3464 switch (WantKind) {
3465 case MK_Any: break;
3466 case MK_ZeroArgSelector: return Sel.isUnarySelector();
3467 case MK_OneArgSelector: return Sel.getNumArgs() == 1;
3468 }
3469
3470 for (unsigned I = 0; I != NumSelIdents; ++I)
3471 if (SelIdents[I] != Sel.getIdentifierInfoForSlot(I))
3472 return false;
3473
3474 return true;
3475}
3476
Douglas Gregorbab2b3c2009-11-17 23:22:23 +00003477/// \brief Add all of the Objective-C methods in the given Objective-C
3478/// container to the set of results.
3479///
3480/// The container will be a class, protocol, category, or implementation of
3481/// any of the above. This mether will recurse to include methods from
3482/// the superclasses of classes along with their categories, protocols, and
3483/// implementations.
3484///
3485/// \param Container the container in which we'll look to find methods.
3486///
3487/// \param WantInstance whether to add instance methods (only); if false, this
3488/// routine will add factory methods (only).
3489///
3490/// \param CurContext the context in which we're performing the lookup that
3491/// finds methods.
3492///
3493/// \param Results the structure into which we'll add results.
3494static void AddObjCMethods(ObjCContainerDecl *Container,
3495 bool WantInstanceMethods,
Douglas Gregorc8537c52009-11-19 07:41:15 +00003496 ObjCMethodKind WantKind,
Douglas Gregor1b605f72009-11-19 01:08:35 +00003497 IdentifierInfo **SelIdents,
3498 unsigned NumSelIdents,
Douglas Gregorbab2b3c2009-11-17 23:22:23 +00003499 DeclContext *CurContext,
3500 ResultBuilder &Results) {
3501 typedef CodeCompleteConsumer::Result Result;
3502 for (ObjCContainerDecl::method_iterator M = Container->meth_begin(),
3503 MEnd = Container->meth_end();
3504 M != MEnd; ++M) {
Douglas Gregor1b605f72009-11-19 01:08:35 +00003505 if ((*M)->isInstanceMethod() == WantInstanceMethods) {
3506 // Check whether the selector identifiers we've been given are a
3507 // subset of the identifiers for this particular method.
Douglas Gregorc8537c52009-11-19 07:41:15 +00003508 if (!isAcceptableObjCMethod(*M, WantKind, SelIdents, NumSelIdents))
Douglas Gregor1b605f72009-11-19 01:08:35 +00003509 continue;
Douglas Gregorc8537c52009-11-19 07:41:15 +00003510
Douglas Gregor1b605f72009-11-19 01:08:35 +00003511 Result R = Result(*M, 0);
3512 R.StartParameter = NumSelIdents;
Douglas Gregorc8537c52009-11-19 07:41:15 +00003513 R.AllParametersAreInformative = (WantKind != MK_Any);
Douglas Gregor1b605f72009-11-19 01:08:35 +00003514 Results.MaybeAddResult(R, CurContext);
3515 }
Douglas Gregorbab2b3c2009-11-17 23:22:23 +00003516 }
3517
3518 ObjCInterfaceDecl *IFace = dyn_cast<ObjCInterfaceDecl>(Container);
3519 if (!IFace)
3520 return;
3521
3522 // Add methods in protocols.
3523 const ObjCList<ObjCProtocolDecl> &Protocols= IFace->getReferencedProtocols();
3524 for (ObjCList<ObjCProtocolDecl>::iterator I = Protocols.begin(),
3525 E = Protocols.end();
3526 I != E; ++I)
Douglas Gregorc8537c52009-11-19 07:41:15 +00003527 AddObjCMethods(*I, WantInstanceMethods, WantKind, SelIdents, NumSelIdents,
Douglas Gregor1b605f72009-11-19 01:08:35 +00003528 CurContext, Results);
Douglas Gregorbab2b3c2009-11-17 23:22:23 +00003529
3530 // Add methods in categories.
3531 for (ObjCCategoryDecl *CatDecl = IFace->getCategoryList(); CatDecl;
3532 CatDecl = CatDecl->getNextClassCategory()) {
Douglas Gregorc8537c52009-11-19 07:41:15 +00003533 AddObjCMethods(CatDecl, WantInstanceMethods, WantKind, SelIdents,
3534 NumSelIdents, CurContext, Results);
Douglas Gregorbab2b3c2009-11-17 23:22:23 +00003535
3536 // Add a categories protocol methods.
3537 const ObjCList<ObjCProtocolDecl> &Protocols
3538 = CatDecl->getReferencedProtocols();
3539 for (ObjCList<ObjCProtocolDecl>::iterator I = Protocols.begin(),
3540 E = Protocols.end();
3541 I != E; ++I)
Douglas Gregorc8537c52009-11-19 07:41:15 +00003542 AddObjCMethods(*I, WantInstanceMethods, WantKind, SelIdents,
3543 NumSelIdents, CurContext, Results);
Douglas Gregorbab2b3c2009-11-17 23:22:23 +00003544
3545 // Add methods in category implementations.
3546 if (ObjCCategoryImplDecl *Impl = CatDecl->getImplementation())
Douglas Gregorc8537c52009-11-19 07:41:15 +00003547 AddObjCMethods(Impl, WantInstanceMethods, WantKind, SelIdents,
3548 NumSelIdents, CurContext, Results);
Douglas Gregorbab2b3c2009-11-17 23:22:23 +00003549 }
3550
3551 // Add methods in superclass.
3552 if (IFace->getSuperClass())
Douglas Gregorc8537c52009-11-19 07:41:15 +00003553 AddObjCMethods(IFace->getSuperClass(), WantInstanceMethods, WantKind,
3554 SelIdents, NumSelIdents, CurContext, Results);
Douglas Gregorbab2b3c2009-11-17 23:22:23 +00003555
3556 // Add methods in our implementation, if any.
3557 if (ObjCImplementationDecl *Impl = IFace->getImplementation())
Douglas Gregorc8537c52009-11-19 07:41:15 +00003558 AddObjCMethods(Impl, WantInstanceMethods, WantKind, SelIdents,
3559 NumSelIdents, CurContext, Results);
3560}
3561
3562
John McCall48871652010-08-21 09:40:31 +00003563void Sema::CodeCompleteObjCPropertyGetter(Scope *S, Decl *ClassDecl,
3564 Decl **Methods,
Douglas Gregorc8537c52009-11-19 07:41:15 +00003565 unsigned NumMethods) {
3566 typedef CodeCompleteConsumer::Result Result;
3567
3568 // Try to find the interface where getters might live.
John McCall48871652010-08-21 09:40:31 +00003569 ObjCInterfaceDecl *Class = dyn_cast_or_null<ObjCInterfaceDecl>(ClassDecl);
Douglas Gregorc8537c52009-11-19 07:41:15 +00003570 if (!Class) {
3571 if (ObjCCategoryDecl *Category
John McCall48871652010-08-21 09:40:31 +00003572 = dyn_cast_or_null<ObjCCategoryDecl>(ClassDecl))
Douglas Gregorc8537c52009-11-19 07:41:15 +00003573 Class = Category->getClassInterface();
3574
3575 if (!Class)
3576 return;
3577 }
3578
3579 // Find all of the potential getters.
3580 ResultBuilder Results(*this);
3581 Results.EnterNewScope();
3582
3583 // FIXME: We need to do this because Objective-C methods don't get
3584 // pushed into DeclContexts early enough. Argh!
3585 for (unsigned I = 0; I != NumMethods; ++I) {
3586 if (ObjCMethodDecl *Method
John McCall48871652010-08-21 09:40:31 +00003587 = dyn_cast_or_null<ObjCMethodDecl>(Methods[I]))
Douglas Gregorc8537c52009-11-19 07:41:15 +00003588 if (Method->isInstanceMethod() &&
3589 isAcceptableObjCMethod(Method, MK_ZeroArgSelector, 0, 0)) {
3590 Result R = Result(Method, 0);
3591 R.AllParametersAreInformative = true;
3592 Results.MaybeAddResult(R, CurContext);
3593 }
3594 }
3595
3596 AddObjCMethods(Class, true, MK_ZeroArgSelector, 0, 0, CurContext, Results);
3597 Results.ExitScope();
Douglas Gregor00c37ef2010-08-11 21:23:17 +00003598 HandleCodeCompleteResults(this, CodeCompleter,
3599 CodeCompletionContext::CCC_Other,
3600 Results.data(),Results.size());
Douglas Gregorc8537c52009-11-19 07:41:15 +00003601}
3602
John McCall48871652010-08-21 09:40:31 +00003603void Sema::CodeCompleteObjCPropertySetter(Scope *S, Decl *ObjCImplDecl,
3604 Decl **Methods,
Douglas Gregorc8537c52009-11-19 07:41:15 +00003605 unsigned NumMethods) {
3606 typedef CodeCompleteConsumer::Result Result;
3607
3608 // Try to find the interface where setters might live.
3609 ObjCInterfaceDecl *Class
John McCall48871652010-08-21 09:40:31 +00003610 = dyn_cast_or_null<ObjCInterfaceDecl>(ObjCImplDecl);
Douglas Gregorc8537c52009-11-19 07:41:15 +00003611 if (!Class) {
3612 if (ObjCCategoryDecl *Category
John McCall48871652010-08-21 09:40:31 +00003613 = dyn_cast_or_null<ObjCCategoryDecl>(ObjCImplDecl))
Douglas Gregorc8537c52009-11-19 07:41:15 +00003614 Class = Category->getClassInterface();
3615
3616 if (!Class)
3617 return;
3618 }
3619
3620 // Find all of the potential getters.
3621 ResultBuilder Results(*this);
3622 Results.EnterNewScope();
3623
3624 // FIXME: We need to do this because Objective-C methods don't get
3625 // pushed into DeclContexts early enough. Argh!
3626 for (unsigned I = 0; I != NumMethods; ++I) {
3627 if (ObjCMethodDecl *Method
John McCall48871652010-08-21 09:40:31 +00003628 = dyn_cast_or_null<ObjCMethodDecl>(Methods[I]))
Douglas Gregorc8537c52009-11-19 07:41:15 +00003629 if (Method->isInstanceMethod() &&
3630 isAcceptableObjCMethod(Method, MK_OneArgSelector, 0, 0)) {
3631 Result R = Result(Method, 0);
3632 R.AllParametersAreInformative = true;
3633 Results.MaybeAddResult(R, CurContext);
3634 }
3635 }
3636
3637 AddObjCMethods(Class, true, MK_OneArgSelector, 0, 0, CurContext, Results);
3638
3639 Results.ExitScope();
Douglas Gregor00c37ef2010-08-11 21:23:17 +00003640 HandleCodeCompleteResults(this, CodeCompleter,
3641 CodeCompletionContext::CCC_Other,
3642 Results.data(),Results.size());
Douglas Gregorbab2b3c2009-11-17 23:22:23 +00003643}
3644
Douglas Gregor99fa2642010-08-24 01:06:58 +00003645void Sema::CodeCompleteObjCPassingType(Scope *S, ObjCDeclSpec &DS) {
3646 typedef CodeCompleteConsumer::Result Result;
3647 ResultBuilder Results(*this);
3648 Results.EnterNewScope();
3649
3650 // Add context-sensitive, Objective-C parameter-passing keywords.
3651 bool AddedInOut = false;
3652 if ((DS.getObjCDeclQualifier() &
3653 (ObjCDeclSpec::DQ_In | ObjCDeclSpec::DQ_Inout)) == 0) {
3654 Results.AddResult("in");
3655 Results.AddResult("inout");
3656 AddedInOut = true;
3657 }
3658 if ((DS.getObjCDeclQualifier() &
3659 (ObjCDeclSpec::DQ_Out | ObjCDeclSpec::DQ_Inout)) == 0) {
3660 Results.AddResult("out");
3661 if (!AddedInOut)
3662 Results.AddResult("inout");
3663 }
3664 if ((DS.getObjCDeclQualifier() &
3665 (ObjCDeclSpec::DQ_Bycopy | ObjCDeclSpec::DQ_Byref |
3666 ObjCDeclSpec::DQ_Oneway)) == 0) {
3667 Results.AddResult("bycopy");
3668 Results.AddResult("byref");
3669 Results.AddResult("oneway");
3670 }
3671
3672 // Add various builtin type names and specifiers.
3673 AddOrdinaryNameResults(PCC_Type, S, *this, Results);
3674 Results.ExitScope();
3675
3676 // Add the various type names
3677 Results.setFilter(&ResultBuilder::IsOrdinaryNonValueName);
3678 CodeCompletionDeclConsumer Consumer(Results, CurContext);
3679 LookupVisibleDecls(S, LookupOrdinaryName, Consumer,
3680 CodeCompleter->includeGlobals());
3681
3682 if (CodeCompleter->includeMacros())
3683 AddMacroResults(PP, Results);
3684
3685 HandleCodeCompleteResults(this, CodeCompleter,
3686 CodeCompletionContext::CCC_Type,
3687 Results.data(), Results.size());
3688}
3689
Douglas Gregor9d2ddb22010-04-06 19:22:33 +00003690/// \brief When we have an expression with type "id", we may assume
3691/// that it has some more-specific class type based on knowledge of
3692/// common uses of Objective-C. This routine returns that class type,
3693/// or NULL if no better result could be determined.
3694static ObjCInterfaceDecl *GetAssumedMessageSendExprType(Expr *E) {
3695 ObjCMessageExpr *Msg = dyn_cast<ObjCMessageExpr>(E);
3696 if (!Msg)
3697 return 0;
3698
3699 Selector Sel = Msg->getSelector();
3700 if (Sel.isNull())
3701 return 0;
3702
3703 IdentifierInfo *Id = Sel.getIdentifierInfoForSlot(0);
3704 if (!Id)
3705 return 0;
3706
3707 ObjCMethodDecl *Method = Msg->getMethodDecl();
3708 if (!Method)
3709 return 0;
3710
3711 // Determine the class that we're sending the message to.
Douglas Gregor9a129192010-04-21 00:45:42 +00003712 ObjCInterfaceDecl *IFace = 0;
3713 switch (Msg->getReceiverKind()) {
3714 case ObjCMessageExpr::Class:
John McCall8b07ec22010-05-15 11:32:37 +00003715 if (const ObjCObjectType *ObjType
3716 = Msg->getClassReceiver()->getAs<ObjCObjectType>())
3717 IFace = ObjType->getInterface();
Douglas Gregor9a129192010-04-21 00:45:42 +00003718 break;
3719
3720 case ObjCMessageExpr::Instance: {
3721 QualType T = Msg->getInstanceReceiver()->getType();
3722 if (const ObjCObjectPointerType *Ptr = T->getAs<ObjCObjectPointerType>())
3723 IFace = Ptr->getInterfaceDecl();
3724 break;
3725 }
3726
3727 case ObjCMessageExpr::SuperInstance:
3728 case ObjCMessageExpr::SuperClass:
3729 break;
Douglas Gregor9d2ddb22010-04-06 19:22:33 +00003730 }
3731
3732 if (!IFace)
3733 return 0;
3734
3735 ObjCInterfaceDecl *Super = IFace->getSuperClass();
3736 if (Method->isInstanceMethod())
3737 return llvm::StringSwitch<ObjCInterfaceDecl *>(Id->getName())
3738 .Case("retain", IFace)
3739 .Case("autorelease", IFace)
3740 .Case("copy", IFace)
3741 .Case("copyWithZone", IFace)
3742 .Case("mutableCopy", IFace)
3743 .Case("mutableCopyWithZone", IFace)
3744 .Case("awakeFromCoder", IFace)
3745 .Case("replacementObjectFromCoder", IFace)
3746 .Case("class", IFace)
3747 .Case("classForCoder", IFace)
3748 .Case("superclass", Super)
3749 .Default(0);
3750
3751 return llvm::StringSwitch<ObjCInterfaceDecl *>(Id->getName())
3752 .Case("new", IFace)
3753 .Case("alloc", IFace)
3754 .Case("allocWithZone", IFace)
3755 .Case("class", IFace)
3756 .Case("superclass", Super)
3757 .Default(0);
3758}
3759
Douglas Gregora817a192010-05-27 23:06:34 +00003760void Sema::CodeCompleteObjCMessageReceiver(Scope *S) {
3761 typedef CodeCompleteConsumer::Result Result;
3762 ResultBuilder Results(*this);
3763
3764 // Find anything that looks like it could be a message receiver.
3765 Results.setFilter(&ResultBuilder::IsObjCMessageReceiver);
3766 CodeCompletionDeclConsumer Consumer(Results, CurContext);
3767 Results.EnterNewScope();
Douglas Gregor39982192010-08-15 06:18:01 +00003768 LookupVisibleDecls(S, LookupOrdinaryName, Consumer,
3769 CodeCompleter->includeGlobals());
Douglas Gregora817a192010-05-27 23:06:34 +00003770
3771 // If we are in an Objective-C method inside a class that has a superclass,
3772 // add "super" as an option.
3773 if (ObjCMethodDecl *Method = getCurMethodDecl())
3774 if (ObjCInterfaceDecl *Iface = Method->getClassInterface())
3775 if (Iface->getSuperClass())
3776 Results.AddResult(Result("super"));
3777
3778 Results.ExitScope();
3779
3780 if (CodeCompleter->includeMacros())
3781 AddMacroResults(PP, Results);
Douglas Gregor00c37ef2010-08-11 21:23:17 +00003782 HandleCodeCompleteResults(this, CodeCompleter,
3783 CodeCompletionContext::CCC_ObjCMessageReceiver,
3784 Results.data(), Results.size());
Douglas Gregora817a192010-05-27 23:06:34 +00003785
3786}
3787
Douglas Gregor0c78ad92010-04-21 19:57:20 +00003788void Sema::CodeCompleteObjCSuperMessage(Scope *S, SourceLocation SuperLoc,
3789 IdentifierInfo **SelIdents,
3790 unsigned NumSelIdents) {
3791 ObjCInterfaceDecl *CDecl = 0;
3792 if (ObjCMethodDecl *CurMethod = getCurMethodDecl()) {
3793 // Figure out which interface we're in.
3794 CDecl = CurMethod->getClassInterface();
3795 if (!CDecl)
3796 return;
3797
3798 // Find the superclass of this class.
3799 CDecl = CDecl->getSuperClass();
3800 if (!CDecl)
3801 return;
3802
3803 if (CurMethod->isInstanceMethod()) {
3804 // We are inside an instance method, which means that the message
3805 // send [super ...] is actually calling an instance method on the
3806 // current object. Build the super expression and handle this like
3807 // an instance method.
3808 QualType SuperTy = Context.getObjCInterfaceType(CDecl);
3809 SuperTy = Context.getObjCObjectPointerType(SuperTy);
John McCalldadc5752010-08-24 06:29:42 +00003810 ExprResult Super
Douglas Gregor0c78ad92010-04-21 19:57:20 +00003811 = Owned(new (Context) ObjCSuperExpr(SuperLoc, SuperTy));
3812 return CodeCompleteObjCInstanceMessage(S, (Expr *)Super.get(),
3813 SelIdents, NumSelIdents);
3814 }
3815
3816 // Fall through to send to the superclass in CDecl.
3817 } else {
3818 // "super" may be the name of a type or variable. Figure out which
3819 // it is.
3820 IdentifierInfo *Super = &Context.Idents.get("super");
3821 NamedDecl *ND = LookupSingleName(S, Super, SuperLoc,
3822 LookupOrdinaryName);
3823 if ((CDecl = dyn_cast_or_null<ObjCInterfaceDecl>(ND))) {
3824 // "super" names an interface. Use it.
3825 } else if (TypeDecl *TD = dyn_cast_or_null<TypeDecl>(ND)) {
John McCall8b07ec22010-05-15 11:32:37 +00003826 if (const ObjCObjectType *Iface
3827 = Context.getTypeDeclType(TD)->getAs<ObjCObjectType>())
3828 CDecl = Iface->getInterface();
Douglas Gregor0c78ad92010-04-21 19:57:20 +00003829 } else if (ND && isa<UnresolvedUsingTypenameDecl>(ND)) {
3830 // "super" names an unresolved type; we can't be more specific.
3831 } else {
3832 // Assume that "super" names some kind of value and parse that way.
3833 CXXScopeSpec SS;
3834 UnqualifiedId id;
3835 id.setIdentifier(Super, SuperLoc);
John McCalldadc5752010-08-24 06:29:42 +00003836 ExprResult SuperExpr = ActOnIdExpression(S, SS, id, false, false);
Douglas Gregor0c78ad92010-04-21 19:57:20 +00003837 return CodeCompleteObjCInstanceMessage(S, (Expr *)SuperExpr.get(),
3838 SelIdents, NumSelIdents);
3839 }
3840
3841 // Fall through
3842 }
3843
John McCallba7bf592010-08-24 05:47:05 +00003844 ParsedType Receiver;
Douglas Gregor0c78ad92010-04-21 19:57:20 +00003845 if (CDecl)
John McCallba7bf592010-08-24 05:47:05 +00003846 Receiver = ParsedType::make(Context.getObjCInterfaceType(CDecl));
Douglas Gregor0c78ad92010-04-21 19:57:20 +00003847 return CodeCompleteObjCClassMessage(S, Receiver, SelIdents,
3848 NumSelIdents);
3849}
3850
John McCallba7bf592010-08-24 05:47:05 +00003851void Sema::CodeCompleteObjCClassMessage(Scope *S, ParsedType Receiver,
Douglas Gregor1b605f72009-11-19 01:08:35 +00003852 IdentifierInfo **SelIdents,
3853 unsigned NumSelIdents) {
Steve Naroffeae65032009-11-07 02:08:14 +00003854 typedef CodeCompleteConsumer::Result Result;
Douglas Gregor8ce33212009-11-17 17:59:40 +00003855 ObjCInterfaceDecl *CDecl = 0;
3856
Douglas Gregor8ce33212009-11-17 17:59:40 +00003857 // If the given name refers to an interface type, retrieve the
3858 // corresponding declaration.
Douglas Gregor0c78ad92010-04-21 19:57:20 +00003859 if (Receiver) {
3860 QualType T = GetTypeFromParser(Receiver, 0);
3861 if (!T.isNull())
John McCall8b07ec22010-05-15 11:32:37 +00003862 if (const ObjCObjectType *Interface = T->getAs<ObjCObjectType>())
3863 CDecl = Interface->getInterface();
Douglas Gregor8ce33212009-11-17 17:59:40 +00003864 }
3865
Douglas Gregorbab2b3c2009-11-17 23:22:23 +00003866 // Add all of the factory methods in this Objective-C class, its protocols,
3867 // superclasses, categories, implementation, etc.
Steve Naroffeae65032009-11-07 02:08:14 +00003868 ResultBuilder Results(*this);
3869 Results.EnterNewScope();
Douglas Gregor6285f752010-04-06 16:40:00 +00003870
3871 if (CDecl)
3872 AddObjCMethods(CDecl, false, MK_Any, SelIdents, NumSelIdents, CurContext,
3873 Results);
Douglas Gregor0c78ad92010-04-21 19:57:20 +00003874 else {
Douglas Gregor6285f752010-04-06 16:40:00 +00003875 // We're messaging "id" as a type; provide all class/factory methods.
3876
Douglas Gregord720daf2010-04-06 17:30:22 +00003877 // If we have an external source, load the entire class method
Sebastian Redld44cd6a2010-08-18 23:57:06 +00003878 // pool from the AST file.
Douglas Gregord720daf2010-04-06 17:30:22 +00003879 if (ExternalSource) {
John McCall75b960e2010-06-01 09:23:16 +00003880 for (uint32_t I = 0, N = ExternalSource->GetNumExternalSelectors();
3881 I != N; ++I) {
3882 Selector Sel = ExternalSource->GetExternalSelector(I);
Sebastian Redl75d8a322010-08-02 23:18:59 +00003883 if (Sel.isNull() || MethodPool.count(Sel))
Douglas Gregord720daf2010-04-06 17:30:22 +00003884 continue;
3885
Sebastian Redl75d8a322010-08-02 23:18:59 +00003886 ReadMethodPool(Sel);
Douglas Gregord720daf2010-04-06 17:30:22 +00003887 }
3888 }
3889
Sebastian Redl75d8a322010-08-02 23:18:59 +00003890 for (GlobalMethodPool::iterator M = MethodPool.begin(),
3891 MEnd = MethodPool.end();
3892 M != MEnd; ++M) {
3893 for (ObjCMethodList *MethList = &M->second.second;
3894 MethList && MethList->Method;
Douglas Gregor6285f752010-04-06 16:40:00 +00003895 MethList = MethList->Next) {
3896 if (!isAcceptableObjCMethod(MethList->Method, MK_Any, SelIdents,
3897 NumSelIdents))
3898 continue;
3899
3900 Result R(MethList->Method, 0);
3901 R.StartParameter = NumSelIdents;
3902 R.AllParametersAreInformative = false;
3903 Results.MaybeAddResult(R, CurContext);
3904 }
3905 }
3906 }
3907
Steve Naroffeae65032009-11-07 02:08:14 +00003908 Results.ExitScope();
Douglas Gregor00c37ef2010-08-11 21:23:17 +00003909 HandleCodeCompleteResults(this, CodeCompleter,
3910 CodeCompletionContext::CCC_Other,
3911 Results.data(),Results.size());
Steve Naroffeae65032009-11-07 02:08:14 +00003912}
3913
Douglas Gregor1b605f72009-11-19 01:08:35 +00003914void Sema::CodeCompleteObjCInstanceMessage(Scope *S, ExprTy *Receiver,
3915 IdentifierInfo **SelIdents,
3916 unsigned NumSelIdents) {
Steve Naroffeae65032009-11-07 02:08:14 +00003917 typedef CodeCompleteConsumer::Result Result;
Steve Naroffeae65032009-11-07 02:08:14 +00003918
3919 Expr *RecExpr = static_cast<Expr *>(Receiver);
Steve Naroffeae65032009-11-07 02:08:14 +00003920
Douglas Gregorbab2b3c2009-11-17 23:22:23 +00003921 // If necessary, apply function/array conversion to the receiver.
3922 // C99 6.7.5.3p[7,8].
Douglas Gregorb92a1562010-02-03 00:27:59 +00003923 DefaultFunctionArrayLvalueConversion(RecExpr);
Douglas Gregorbab2b3c2009-11-17 23:22:23 +00003924 QualType ReceiverType = RecExpr->getType();
Steve Naroffeae65032009-11-07 02:08:14 +00003925
Douglas Gregorbab2b3c2009-11-17 23:22:23 +00003926 // Build the set of methods we can see.
3927 ResultBuilder Results(*this);
3928 Results.EnterNewScope();
Douglas Gregor9d2ddb22010-04-06 19:22:33 +00003929
3930 // If we're messaging an expression with type "id" or "Class", check
3931 // whether we know something special about the receiver that allows
3932 // us to assume a more-specific receiver type.
3933 if (ReceiverType->isObjCIdType() || ReceiverType->isObjCClassType())
3934 if (ObjCInterfaceDecl *IFace = GetAssumedMessageSendExprType(RecExpr))
3935 ReceiverType = Context.getObjCObjectPointerType(
3936 Context.getObjCInterfaceType(IFace));
Douglas Gregorbab2b3c2009-11-17 23:22:23 +00003937
Douglas Gregora3329fa2009-11-18 00:06:18 +00003938 // Handle messages to Class. This really isn't a message to an instance
3939 // method, so we treat it the same way we would treat a message send to a
3940 // class method.
3941 if (ReceiverType->isObjCClassType() ||
3942 ReceiverType->isObjCQualifiedClassType()) {
3943 if (ObjCMethodDecl *CurMethod = getCurMethodDecl()) {
3944 if (ObjCInterfaceDecl *ClassDecl = CurMethod->getClassInterface())
Douglas Gregorc8537c52009-11-19 07:41:15 +00003945 AddObjCMethods(ClassDecl, false, MK_Any, SelIdents, NumSelIdents,
3946 CurContext, Results);
Douglas Gregora3329fa2009-11-18 00:06:18 +00003947 }
3948 }
3949 // Handle messages to a qualified ID ("id<foo>").
3950 else if (const ObjCObjectPointerType *QualID
3951 = ReceiverType->getAsObjCQualifiedIdType()) {
3952 // Search protocols for instance methods.
3953 for (ObjCObjectPointerType::qual_iterator I = QualID->qual_begin(),
3954 E = QualID->qual_end();
3955 I != E; ++I)
Douglas Gregorc8537c52009-11-19 07:41:15 +00003956 AddObjCMethods(*I, true, MK_Any, SelIdents, NumSelIdents, CurContext,
3957 Results);
Douglas Gregora3329fa2009-11-18 00:06:18 +00003958 }
3959 // Handle messages to a pointer to interface type.
3960 else if (const ObjCObjectPointerType *IFacePtr
3961 = ReceiverType->getAsObjCInterfacePointerType()) {
3962 // Search the class, its superclasses, etc., for instance methods.
Douglas Gregorc8537c52009-11-19 07:41:15 +00003963 AddObjCMethods(IFacePtr->getInterfaceDecl(), true, MK_Any, SelIdents,
3964 NumSelIdents, CurContext, Results);
Douglas Gregora3329fa2009-11-18 00:06:18 +00003965
3966 // Search protocols for instance methods.
3967 for (ObjCObjectPointerType::qual_iterator I = IFacePtr->qual_begin(),
3968 E = IFacePtr->qual_end();
3969 I != E; ++I)
Douglas Gregorc8537c52009-11-19 07:41:15 +00003970 AddObjCMethods(*I, true, MK_Any, SelIdents, NumSelIdents, CurContext,
3971 Results);
Douglas Gregora3329fa2009-11-18 00:06:18 +00003972 }
Douglas Gregor6285f752010-04-06 16:40:00 +00003973 // Handle messages to "id".
3974 else if (ReceiverType->isObjCIdType()) {
Douglas Gregord720daf2010-04-06 17:30:22 +00003975 // We're messaging "id", so provide all instance methods we know
3976 // about as code-completion results.
3977
3978 // If we have an external source, load the entire class method
Sebastian Redld44cd6a2010-08-18 23:57:06 +00003979 // pool from the AST file.
Douglas Gregord720daf2010-04-06 17:30:22 +00003980 if (ExternalSource) {
John McCall75b960e2010-06-01 09:23:16 +00003981 for (uint32_t I = 0, N = ExternalSource->GetNumExternalSelectors();
3982 I != N; ++I) {
3983 Selector Sel = ExternalSource->GetExternalSelector(I);
Sebastian Redl75d8a322010-08-02 23:18:59 +00003984 if (Sel.isNull() || MethodPool.count(Sel))
Douglas Gregord720daf2010-04-06 17:30:22 +00003985 continue;
3986
Sebastian Redl75d8a322010-08-02 23:18:59 +00003987 ReadMethodPool(Sel);
Douglas Gregord720daf2010-04-06 17:30:22 +00003988 }
3989 }
3990
Sebastian Redl75d8a322010-08-02 23:18:59 +00003991 for (GlobalMethodPool::iterator M = MethodPool.begin(),
3992 MEnd = MethodPool.end();
3993 M != MEnd; ++M) {
3994 for (ObjCMethodList *MethList = &M->second.first;
3995 MethList && MethList->Method;
Douglas Gregor6285f752010-04-06 16:40:00 +00003996 MethList = MethList->Next) {
3997 if (!isAcceptableObjCMethod(MethList->Method, MK_Any, SelIdents,
3998 NumSelIdents))
3999 continue;
4000
4001 Result R(MethList->Method, 0);
4002 R.StartParameter = NumSelIdents;
4003 R.AllParametersAreInformative = false;
4004 Results.MaybeAddResult(R, CurContext);
4005 }
4006 }
4007 }
4008
Steve Naroffeae65032009-11-07 02:08:14 +00004009 Results.ExitScope();
Douglas Gregor00c37ef2010-08-11 21:23:17 +00004010 HandleCodeCompleteResults(this, CodeCompleter,
4011 CodeCompletionContext::CCC_Other,
4012 Results.data(),Results.size());
Steve Naroffeae65032009-11-07 02:08:14 +00004013}
Douglas Gregorbaf69612009-11-18 04:19:12 +00004014
Douglas Gregor68762e72010-08-23 21:17:50 +00004015void Sema::CodeCompleteObjCForCollection(Scope *S,
4016 DeclGroupPtrTy IterationVar) {
4017 CodeCompleteExpressionData Data;
4018 Data.ObjCCollection = true;
4019
4020 if (IterationVar.getAsOpaquePtr()) {
4021 DeclGroupRef DG = IterationVar.getAsVal<DeclGroupRef>();
4022 for (DeclGroupRef::iterator I = DG.begin(), End = DG.end(); I != End; ++I) {
4023 if (*I)
4024 Data.IgnoreDecls.push_back(*I);
4025 }
4026 }
4027
4028 CodeCompleteExpression(S, Data);
4029}
4030
Douglas Gregorbaf69612009-11-18 04:19:12 +00004031/// \brief Add all of the protocol declarations that we find in the given
4032/// (translation unit) context.
4033static void AddProtocolResults(DeclContext *Ctx, DeclContext *CurContext,
Douglas Gregor5b4671c2009-11-18 04:49:41 +00004034 bool OnlyForwardDeclarations,
Douglas Gregorbaf69612009-11-18 04:19:12 +00004035 ResultBuilder &Results) {
4036 typedef CodeCompleteConsumer::Result Result;
4037
4038 for (DeclContext::decl_iterator D = Ctx->decls_begin(),
4039 DEnd = Ctx->decls_end();
4040 D != DEnd; ++D) {
4041 // Record any protocols we find.
4042 if (ObjCProtocolDecl *Proto = dyn_cast<ObjCProtocolDecl>(*D))
Douglas Gregor5b4671c2009-11-18 04:49:41 +00004043 if (!OnlyForwardDeclarations || Proto->isForwardDecl())
Douglas Gregorfc59ce12010-01-14 16:14:35 +00004044 Results.AddResult(Result(Proto, 0), CurContext, 0, false);
Douglas Gregorbaf69612009-11-18 04:19:12 +00004045
4046 // Record any forward-declared protocols we find.
4047 if (ObjCForwardProtocolDecl *Forward
4048 = dyn_cast<ObjCForwardProtocolDecl>(*D)) {
4049 for (ObjCForwardProtocolDecl::protocol_iterator
4050 P = Forward->protocol_begin(),
4051 PEnd = Forward->protocol_end();
4052 P != PEnd; ++P)
Douglas Gregor5b4671c2009-11-18 04:49:41 +00004053 if (!OnlyForwardDeclarations || (*P)->isForwardDecl())
Douglas Gregorfc59ce12010-01-14 16:14:35 +00004054 Results.AddResult(Result(*P, 0), CurContext, 0, false);
Douglas Gregorbaf69612009-11-18 04:19:12 +00004055 }
4056 }
4057}
4058
4059void Sema::CodeCompleteObjCProtocolReferences(IdentifierLocPair *Protocols,
4060 unsigned NumProtocols) {
4061 ResultBuilder Results(*this);
4062 Results.EnterNewScope();
4063
4064 // Tell the result set to ignore all of the protocols we have
4065 // already seen.
4066 for (unsigned I = 0; I != NumProtocols; ++I)
Douglas Gregorb2ccf012010-04-15 22:33:43 +00004067 if (ObjCProtocolDecl *Protocol = LookupProtocol(Protocols[I].first,
4068 Protocols[I].second))
Douglas Gregorbaf69612009-11-18 04:19:12 +00004069 Results.Ignore(Protocol);
4070
4071 // Add all protocols.
Douglas Gregor5b4671c2009-11-18 04:49:41 +00004072 AddProtocolResults(Context.getTranslationUnitDecl(), CurContext, false,
4073 Results);
4074
4075 Results.ExitScope();
Douglas Gregor00c37ef2010-08-11 21:23:17 +00004076 HandleCodeCompleteResults(this, CodeCompleter,
4077 CodeCompletionContext::CCC_ObjCProtocolName,
4078 Results.data(),Results.size());
Douglas Gregor5b4671c2009-11-18 04:49:41 +00004079}
4080
4081void Sema::CodeCompleteObjCProtocolDecl(Scope *) {
4082 ResultBuilder Results(*this);
4083 Results.EnterNewScope();
4084
4085 // Add all protocols.
4086 AddProtocolResults(Context.getTranslationUnitDecl(), CurContext, true,
4087 Results);
Douglas Gregorbaf69612009-11-18 04:19:12 +00004088
4089 Results.ExitScope();
Douglas Gregor00c37ef2010-08-11 21:23:17 +00004090 HandleCodeCompleteResults(this, CodeCompleter,
4091 CodeCompletionContext::CCC_ObjCProtocolName,
4092 Results.data(),Results.size());
Douglas Gregorbaf69612009-11-18 04:19:12 +00004093}
Douglas Gregor49c22a72009-11-18 16:26:39 +00004094
4095/// \brief Add all of the Objective-C interface declarations that we find in
4096/// the given (translation unit) context.
4097static void AddInterfaceResults(DeclContext *Ctx, DeclContext *CurContext,
4098 bool OnlyForwardDeclarations,
4099 bool OnlyUnimplemented,
4100 ResultBuilder &Results) {
4101 typedef CodeCompleteConsumer::Result Result;
4102
4103 for (DeclContext::decl_iterator D = Ctx->decls_begin(),
4104 DEnd = Ctx->decls_end();
4105 D != DEnd; ++D) {
Douglas Gregor1c283312010-08-11 12:19:30 +00004106 // Record any interfaces we find.
4107 if (ObjCInterfaceDecl *Class = dyn_cast<ObjCInterfaceDecl>(*D))
4108 if ((!OnlyForwardDeclarations || Class->isForwardDecl()) &&
4109 (!OnlyUnimplemented || !Class->getImplementation()))
4110 Results.AddResult(Result(Class, 0), CurContext, 0, false);
Douglas Gregor49c22a72009-11-18 16:26:39 +00004111
4112 // Record any forward-declared interfaces we find.
4113 if (ObjCClassDecl *Forward = dyn_cast<ObjCClassDecl>(*D)) {
4114 for (ObjCClassDecl::iterator C = Forward->begin(), CEnd = Forward->end();
Douglas Gregor1c283312010-08-11 12:19:30 +00004115 C != CEnd; ++C)
4116 if ((!OnlyForwardDeclarations || C->getInterface()->isForwardDecl()) &&
4117 (!OnlyUnimplemented || !C->getInterface()->getImplementation()))
4118 Results.AddResult(Result(C->getInterface(), 0), CurContext,
Douglas Gregorfc59ce12010-01-14 16:14:35 +00004119 0, false);
Douglas Gregor49c22a72009-11-18 16:26:39 +00004120 }
4121 }
4122}
4123
4124void Sema::CodeCompleteObjCInterfaceDecl(Scope *S) {
4125 ResultBuilder Results(*this);
4126 Results.EnterNewScope();
4127
4128 // Add all classes.
4129 AddInterfaceResults(Context.getTranslationUnitDecl(), CurContext, true,
4130 false, Results);
4131
4132 Results.ExitScope();
Douglas Gregor00c37ef2010-08-11 21:23:17 +00004133 HandleCodeCompleteResults(this, CodeCompleter,
4134 CodeCompletionContext::CCC_Other,
4135 Results.data(),Results.size());
Douglas Gregor49c22a72009-11-18 16:26:39 +00004136}
4137
Douglas Gregorb2ccf012010-04-15 22:33:43 +00004138void Sema::CodeCompleteObjCSuperclass(Scope *S, IdentifierInfo *ClassName,
4139 SourceLocation ClassNameLoc) {
Douglas Gregor49c22a72009-11-18 16:26:39 +00004140 ResultBuilder Results(*this);
4141 Results.EnterNewScope();
4142
4143 // Make sure that we ignore the class we're currently defining.
4144 NamedDecl *CurClass
Douglas Gregorb2ccf012010-04-15 22:33:43 +00004145 = LookupSingleName(TUScope, ClassName, ClassNameLoc, LookupOrdinaryName);
Douglas Gregor5d34fd32009-11-18 19:08:43 +00004146 if (CurClass && isa<ObjCInterfaceDecl>(CurClass))
Douglas Gregor49c22a72009-11-18 16:26:39 +00004147 Results.Ignore(CurClass);
4148
4149 // Add all classes.
4150 AddInterfaceResults(Context.getTranslationUnitDecl(), CurContext, false,
4151 false, Results);
4152
4153 Results.ExitScope();
Douglas Gregor00c37ef2010-08-11 21:23:17 +00004154 HandleCodeCompleteResults(this, CodeCompleter,
4155 CodeCompletionContext::CCC_Other,
4156 Results.data(),Results.size());
Douglas Gregor49c22a72009-11-18 16:26:39 +00004157}
4158
4159void Sema::CodeCompleteObjCImplementationDecl(Scope *S) {
4160 ResultBuilder Results(*this);
4161 Results.EnterNewScope();
4162
4163 // Add all unimplemented classes.
4164 AddInterfaceResults(Context.getTranslationUnitDecl(), CurContext, false,
4165 true, Results);
4166
4167 Results.ExitScope();
Douglas Gregor00c37ef2010-08-11 21:23:17 +00004168 HandleCodeCompleteResults(this, CodeCompleter,
4169 CodeCompletionContext::CCC_Other,
4170 Results.data(),Results.size());
Douglas Gregor49c22a72009-11-18 16:26:39 +00004171}
Douglas Gregor5d34fd32009-11-18 19:08:43 +00004172
4173void Sema::CodeCompleteObjCInterfaceCategory(Scope *S,
Douglas Gregorb2ccf012010-04-15 22:33:43 +00004174 IdentifierInfo *ClassName,
4175 SourceLocation ClassNameLoc) {
Douglas Gregor5d34fd32009-11-18 19:08:43 +00004176 typedef CodeCompleteConsumer::Result Result;
4177
4178 ResultBuilder Results(*this);
4179
4180 // Ignore any categories we find that have already been implemented by this
4181 // interface.
4182 llvm::SmallPtrSet<IdentifierInfo *, 16> CategoryNames;
4183 NamedDecl *CurClass
Douglas Gregorb2ccf012010-04-15 22:33:43 +00004184 = LookupSingleName(TUScope, ClassName, ClassNameLoc, LookupOrdinaryName);
Douglas Gregor5d34fd32009-11-18 19:08:43 +00004185 if (ObjCInterfaceDecl *Class = dyn_cast_or_null<ObjCInterfaceDecl>(CurClass))
4186 for (ObjCCategoryDecl *Category = Class->getCategoryList(); Category;
4187 Category = Category->getNextClassCategory())
4188 CategoryNames.insert(Category->getIdentifier());
4189
4190 // Add all of the categories we know about.
4191 Results.EnterNewScope();
4192 TranslationUnitDecl *TU = Context.getTranslationUnitDecl();
4193 for (DeclContext::decl_iterator D = TU->decls_begin(),
4194 DEnd = TU->decls_end();
4195 D != DEnd; ++D)
4196 if (ObjCCategoryDecl *Category = dyn_cast<ObjCCategoryDecl>(*D))
4197 if (CategoryNames.insert(Category->getIdentifier()))
Douglas Gregorfc59ce12010-01-14 16:14:35 +00004198 Results.AddResult(Result(Category, 0), CurContext, 0, false);
Douglas Gregor5d34fd32009-11-18 19:08:43 +00004199 Results.ExitScope();
4200
Douglas Gregor00c37ef2010-08-11 21:23:17 +00004201 HandleCodeCompleteResults(this, CodeCompleter,
4202 CodeCompletionContext::CCC_Other,
4203 Results.data(),Results.size());
Douglas Gregor5d34fd32009-11-18 19:08:43 +00004204}
4205
4206void Sema::CodeCompleteObjCImplementationCategory(Scope *S,
Douglas Gregorb2ccf012010-04-15 22:33:43 +00004207 IdentifierInfo *ClassName,
4208 SourceLocation ClassNameLoc) {
Douglas Gregor5d34fd32009-11-18 19:08:43 +00004209 typedef CodeCompleteConsumer::Result Result;
4210
4211 // Find the corresponding interface. If we couldn't find the interface, the
4212 // program itself is ill-formed. However, we'll try to be helpful still by
4213 // providing the list of all of the categories we know about.
4214 NamedDecl *CurClass
Douglas Gregorb2ccf012010-04-15 22:33:43 +00004215 = LookupSingleName(TUScope, ClassName, ClassNameLoc, LookupOrdinaryName);
Douglas Gregor5d34fd32009-11-18 19:08:43 +00004216 ObjCInterfaceDecl *Class = dyn_cast_or_null<ObjCInterfaceDecl>(CurClass);
4217 if (!Class)
Douglas Gregorb2ccf012010-04-15 22:33:43 +00004218 return CodeCompleteObjCInterfaceCategory(S, ClassName, ClassNameLoc);
Douglas Gregor5d34fd32009-11-18 19:08:43 +00004219
4220 ResultBuilder Results(*this);
4221
4222 // Add all of the categories that have have corresponding interface
4223 // declarations in this class and any of its superclasses, except for
4224 // already-implemented categories in the class itself.
4225 llvm::SmallPtrSet<IdentifierInfo *, 16> CategoryNames;
4226 Results.EnterNewScope();
4227 bool IgnoreImplemented = true;
4228 while (Class) {
4229 for (ObjCCategoryDecl *Category = Class->getCategoryList(); Category;
4230 Category = Category->getNextClassCategory())
4231 if ((!IgnoreImplemented || !Category->getImplementation()) &&
4232 CategoryNames.insert(Category->getIdentifier()))
Douglas Gregorfc59ce12010-01-14 16:14:35 +00004233 Results.AddResult(Result(Category, 0), CurContext, 0, false);
Douglas Gregor5d34fd32009-11-18 19:08:43 +00004234
4235 Class = Class->getSuperClass();
4236 IgnoreImplemented = false;
4237 }
4238 Results.ExitScope();
4239
Douglas Gregor00c37ef2010-08-11 21:23:17 +00004240 HandleCodeCompleteResults(this, CodeCompleter,
4241 CodeCompletionContext::CCC_Other,
4242 Results.data(),Results.size());
Douglas Gregor5d34fd32009-11-18 19:08:43 +00004243}
Douglas Gregor5d649882009-11-18 22:32:06 +00004244
John McCall48871652010-08-21 09:40:31 +00004245void Sema::CodeCompleteObjCPropertyDefinition(Scope *S, Decl *ObjCImpDecl) {
Douglas Gregor5d649882009-11-18 22:32:06 +00004246 typedef CodeCompleteConsumer::Result Result;
4247 ResultBuilder Results(*this);
4248
4249 // Figure out where this @synthesize lives.
4250 ObjCContainerDecl *Container
John McCall48871652010-08-21 09:40:31 +00004251 = dyn_cast_or_null<ObjCContainerDecl>(ObjCImpDecl);
Douglas Gregor5d649882009-11-18 22:32:06 +00004252 if (!Container ||
4253 (!isa<ObjCImplementationDecl>(Container) &&
4254 !isa<ObjCCategoryImplDecl>(Container)))
4255 return;
4256
4257 // Ignore any properties that have already been implemented.
4258 for (DeclContext::decl_iterator D = Container->decls_begin(),
4259 DEnd = Container->decls_end();
4260 D != DEnd; ++D)
4261 if (ObjCPropertyImplDecl *PropertyImpl = dyn_cast<ObjCPropertyImplDecl>(*D))
4262 Results.Ignore(PropertyImpl->getPropertyDecl());
4263
4264 // Add any properties that we find.
4265 Results.EnterNewScope();
4266 if (ObjCImplementationDecl *ClassImpl
4267 = dyn_cast<ObjCImplementationDecl>(Container))
4268 AddObjCProperties(ClassImpl->getClassInterface(), false, CurContext,
4269 Results);
4270 else
4271 AddObjCProperties(cast<ObjCCategoryImplDecl>(Container)->getCategoryDecl(),
4272 false, CurContext, Results);
4273 Results.ExitScope();
4274
Douglas Gregor00c37ef2010-08-11 21:23:17 +00004275 HandleCodeCompleteResults(this, CodeCompleter,
4276 CodeCompletionContext::CCC_Other,
4277 Results.data(),Results.size());
Douglas Gregor5d649882009-11-18 22:32:06 +00004278}
4279
4280void Sema::CodeCompleteObjCPropertySynthesizeIvar(Scope *S,
4281 IdentifierInfo *PropertyName,
John McCall48871652010-08-21 09:40:31 +00004282 Decl *ObjCImpDecl) {
Douglas Gregor5d649882009-11-18 22:32:06 +00004283 typedef CodeCompleteConsumer::Result Result;
4284 ResultBuilder Results(*this);
4285
4286 // Figure out where this @synthesize lives.
4287 ObjCContainerDecl *Container
John McCall48871652010-08-21 09:40:31 +00004288 = dyn_cast_or_null<ObjCContainerDecl>(ObjCImpDecl);
Douglas Gregor5d649882009-11-18 22:32:06 +00004289 if (!Container ||
4290 (!isa<ObjCImplementationDecl>(Container) &&
4291 !isa<ObjCCategoryImplDecl>(Container)))
4292 return;
4293
4294 // Figure out which interface we're looking into.
4295 ObjCInterfaceDecl *Class = 0;
4296 if (ObjCImplementationDecl *ClassImpl
4297 = dyn_cast<ObjCImplementationDecl>(Container))
4298 Class = ClassImpl->getClassInterface();
4299 else
4300 Class = cast<ObjCCategoryImplDecl>(Container)->getCategoryDecl()
4301 ->getClassInterface();
4302
4303 // Add all of the instance variables in this class and its superclasses.
4304 Results.EnterNewScope();
4305 for(; Class; Class = Class->getSuperClass()) {
4306 // FIXME: We could screen the type of each ivar for compatibility with
4307 // the property, but is that being too paternal?
4308 for (ObjCInterfaceDecl::ivar_iterator IVar = Class->ivar_begin(),
4309 IVarEnd = Class->ivar_end();
4310 IVar != IVarEnd; ++IVar)
Douglas Gregorfc59ce12010-01-14 16:14:35 +00004311 Results.AddResult(Result(*IVar, 0), CurContext, 0, false);
Douglas Gregor5d649882009-11-18 22:32:06 +00004312 }
4313 Results.ExitScope();
4314
Douglas Gregor00c37ef2010-08-11 21:23:17 +00004315 HandleCodeCompleteResults(this, CodeCompleter,
4316 CodeCompletionContext::CCC_Other,
4317 Results.data(),Results.size());
Douglas Gregor5d649882009-11-18 22:32:06 +00004318}
Douglas Gregor636a61e2010-04-07 00:21:17 +00004319
4320typedef llvm::DenseMap<Selector, ObjCMethodDecl *> KnownMethodsMap;
4321
4322/// \brief Find all of the methods that reside in the given container
4323/// (and its superclasses, protocols, etc.) that meet the given
4324/// criteria. Insert those methods into the map of known methods,
4325/// indexed by selector so they can be easily found.
4326static void FindImplementableMethods(ASTContext &Context,
4327 ObjCContainerDecl *Container,
4328 bool WantInstanceMethods,
4329 QualType ReturnType,
4330 bool IsInImplementation,
4331 KnownMethodsMap &KnownMethods) {
4332 if (ObjCInterfaceDecl *IFace = dyn_cast<ObjCInterfaceDecl>(Container)) {
4333 // Recurse into protocols.
4334 const ObjCList<ObjCProtocolDecl> &Protocols
4335 = IFace->getReferencedProtocols();
4336 for (ObjCList<ObjCProtocolDecl>::iterator I = Protocols.begin(),
4337 E = Protocols.end();
4338 I != E; ++I)
4339 FindImplementableMethods(Context, *I, WantInstanceMethods, ReturnType,
4340 IsInImplementation, KnownMethods);
4341
4342 // If we're not in the implementation of a class, also visit the
4343 // superclass.
4344 if (!IsInImplementation && IFace->getSuperClass())
4345 FindImplementableMethods(Context, IFace->getSuperClass(),
4346 WantInstanceMethods, ReturnType,
4347 IsInImplementation, KnownMethods);
4348
4349 // Add methods from any class extensions (but not from categories;
4350 // those should go into category implementations).
Fariborz Jahanian3bf0ded2010-06-22 23:20:40 +00004351 for (const ObjCCategoryDecl *Cat = IFace->getFirstClassExtension(); Cat;
4352 Cat = Cat->getNextClassExtension())
4353 FindImplementableMethods(Context, const_cast<ObjCCategoryDecl*>(Cat),
4354 WantInstanceMethods, ReturnType,
Douglas Gregor636a61e2010-04-07 00:21:17 +00004355 IsInImplementation, KnownMethods);
Douglas Gregor636a61e2010-04-07 00:21:17 +00004356 }
4357
4358 if (ObjCCategoryDecl *Category = dyn_cast<ObjCCategoryDecl>(Container)) {
4359 // Recurse into protocols.
4360 const ObjCList<ObjCProtocolDecl> &Protocols
4361 = Category->getReferencedProtocols();
4362 for (ObjCList<ObjCProtocolDecl>::iterator I = Protocols.begin(),
4363 E = Protocols.end();
4364 I != E; ++I)
4365 FindImplementableMethods(Context, *I, WantInstanceMethods, ReturnType,
4366 IsInImplementation, KnownMethods);
4367 }
4368
4369 if (ObjCProtocolDecl *Protocol = dyn_cast<ObjCProtocolDecl>(Container)) {
4370 // Recurse into protocols.
4371 const ObjCList<ObjCProtocolDecl> &Protocols
4372 = Protocol->getReferencedProtocols();
4373 for (ObjCList<ObjCProtocolDecl>::iterator I = Protocols.begin(),
4374 E = Protocols.end();
4375 I != E; ++I)
4376 FindImplementableMethods(Context, *I, WantInstanceMethods, ReturnType,
4377 IsInImplementation, KnownMethods);
4378 }
4379
4380 // Add methods in this container. This operation occurs last because
4381 // we want the methods from this container to override any methods
4382 // we've previously seen with the same selector.
4383 for (ObjCContainerDecl::method_iterator M = Container->meth_begin(),
4384 MEnd = Container->meth_end();
4385 M != MEnd; ++M) {
4386 if ((*M)->isInstanceMethod() == WantInstanceMethods) {
4387 if (!ReturnType.isNull() &&
4388 !Context.hasSameUnqualifiedType(ReturnType, (*M)->getResultType()))
4389 continue;
4390
4391 KnownMethods[(*M)->getSelector()] = *M;
4392 }
4393 }
4394}
4395
4396void Sema::CodeCompleteObjCMethodDecl(Scope *S,
4397 bool IsInstanceMethod,
John McCallba7bf592010-08-24 05:47:05 +00004398 ParsedType ReturnTy,
John McCall48871652010-08-21 09:40:31 +00004399 Decl *IDecl) {
Douglas Gregor636a61e2010-04-07 00:21:17 +00004400 // Determine the return type of the method we're declaring, if
4401 // provided.
4402 QualType ReturnType = GetTypeFromParser(ReturnTy);
4403
4404 // Determine where we should start searching for methods, and where we
4405 ObjCContainerDecl *SearchDecl = 0, *CurrentDecl = 0;
4406 bool IsInImplementation = false;
John McCall48871652010-08-21 09:40:31 +00004407 if (Decl *D = IDecl) {
Douglas Gregor636a61e2010-04-07 00:21:17 +00004408 if (ObjCImplementationDecl *Impl = dyn_cast<ObjCImplementationDecl>(D)) {
4409 SearchDecl = Impl->getClassInterface();
4410 CurrentDecl = Impl;
4411 IsInImplementation = true;
4412 } else if (ObjCCategoryImplDecl *CatImpl
4413 = dyn_cast<ObjCCategoryImplDecl>(D)) {
4414 SearchDecl = CatImpl->getCategoryDecl();
4415 CurrentDecl = CatImpl;
4416 IsInImplementation = true;
4417 } else {
4418 SearchDecl = dyn_cast<ObjCContainerDecl>(D);
4419 CurrentDecl = SearchDecl;
4420 }
4421 }
4422
4423 if (!SearchDecl && S) {
4424 if (DeclContext *DC = static_cast<DeclContext *>(S->getEntity())) {
4425 SearchDecl = dyn_cast<ObjCContainerDecl>(DC);
4426 CurrentDecl = SearchDecl;
4427 }
4428 }
4429
4430 if (!SearchDecl || !CurrentDecl) {
Douglas Gregor00c37ef2010-08-11 21:23:17 +00004431 HandleCodeCompleteResults(this, CodeCompleter,
4432 CodeCompletionContext::CCC_Other,
4433 0, 0);
Douglas Gregor636a61e2010-04-07 00:21:17 +00004434 return;
4435 }
4436
4437 // Find all of the methods that we could declare/implement here.
4438 KnownMethodsMap KnownMethods;
4439 FindImplementableMethods(Context, SearchDecl, IsInstanceMethod,
4440 ReturnType, IsInImplementation, KnownMethods);
4441
4442 // Erase any methods that have already been declared or
4443 // implemented here.
4444 for (ObjCContainerDecl::method_iterator M = CurrentDecl->meth_begin(),
4445 MEnd = CurrentDecl->meth_end();
4446 M != MEnd; ++M) {
4447 if ((*M)->isInstanceMethod() != IsInstanceMethod)
4448 continue;
4449
4450 KnownMethodsMap::iterator Pos = KnownMethods.find((*M)->getSelector());
4451 if (Pos != KnownMethods.end())
4452 KnownMethods.erase(Pos);
4453 }
4454
4455 // Add declarations or definitions for each of the known methods.
4456 typedef CodeCompleteConsumer::Result Result;
4457 ResultBuilder Results(*this);
4458 Results.EnterNewScope();
4459 PrintingPolicy Policy(Context.PrintingPolicy);
4460 Policy.AnonymousTagLocations = false;
4461 for (KnownMethodsMap::iterator M = KnownMethods.begin(),
4462 MEnd = KnownMethods.end();
4463 M != MEnd; ++M) {
4464 ObjCMethodDecl *Method = M->second;
4465 CodeCompletionString *Pattern = new CodeCompletionString;
4466
4467 // If the result type was not already provided, add it to the
4468 // pattern as (type).
4469 if (ReturnType.isNull()) {
4470 std::string TypeStr;
4471 Method->getResultType().getAsStringInternal(TypeStr, Policy);
4472 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
4473 Pattern->AddTextChunk(TypeStr);
4474 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
4475 }
4476
4477 Selector Sel = Method->getSelector();
4478
4479 // Add the first part of the selector to the pattern.
4480 Pattern->AddTypedTextChunk(Sel.getIdentifierInfoForSlot(0)->getName());
4481
4482 // Add parameters to the pattern.
4483 unsigned I = 0;
4484 for (ObjCMethodDecl::param_iterator P = Method->param_begin(),
4485 PEnd = Method->param_end();
4486 P != PEnd; (void)++P, ++I) {
4487 // Add the part of the selector name.
4488 if (I == 0)
4489 Pattern->AddChunk(CodeCompletionString::CK_Colon);
4490 else if (I < Sel.getNumArgs()) {
4491 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
Douglas Gregorb0ce9b72010-08-17 15:53:35 +00004492 Pattern->AddTextChunk(Sel.getIdentifierInfoForSlot(I)->getName());
Douglas Gregor636a61e2010-04-07 00:21:17 +00004493 Pattern->AddChunk(CodeCompletionString::CK_Colon);
4494 } else
4495 break;
4496
4497 // Add the parameter type.
4498 std::string TypeStr;
4499 (*P)->getOriginalType().getAsStringInternal(TypeStr, Policy);
4500 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
4501 Pattern->AddTextChunk(TypeStr);
4502 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
4503
4504 if (IdentifierInfo *Id = (*P)->getIdentifier())
4505 Pattern->AddTextChunk(Id->getName());
4506 }
4507
4508 if (Method->isVariadic()) {
4509 if (Method->param_size() > 0)
4510 Pattern->AddChunk(CodeCompletionString::CK_Comma);
4511 Pattern->AddTextChunk("...");
4512 }
4513
Douglas Gregord37c59d2010-05-28 00:57:46 +00004514 if (IsInImplementation && Results.includeCodePatterns()) {
Douglas Gregor636a61e2010-04-07 00:21:17 +00004515 // We will be defining the method here, so add a compound statement.
4516 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
4517 Pattern->AddChunk(CodeCompletionString::CK_LeftBrace);
4518 Pattern->AddChunk(CodeCompletionString::CK_VerticalSpace);
4519 if (!Method->getResultType()->isVoidType()) {
4520 // If the result type is not void, add a return clause.
4521 Pattern->AddTextChunk("return");
4522 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
4523 Pattern->AddPlaceholderChunk("expression");
4524 Pattern->AddChunk(CodeCompletionString::CK_SemiColon);
4525 } else
4526 Pattern->AddPlaceholderChunk("statements");
4527
4528 Pattern->AddChunk(CodeCompletionString::CK_VerticalSpace);
4529 Pattern->AddChunk(CodeCompletionString::CK_RightBrace);
4530 }
4531
Douglas Gregor7116a8c2010-08-17 16:06:07 +00004532 Results.AddResult(Result(Pattern, CCP_CodePattern,
4533 Method->isInstanceMethod()
4534 ? CXCursor_ObjCInstanceMethodDecl
4535 : CXCursor_ObjCClassMethodDecl));
Douglas Gregor636a61e2010-04-07 00:21:17 +00004536 }
4537
4538 Results.ExitScope();
4539
Douglas Gregor00c37ef2010-08-11 21:23:17 +00004540 HandleCodeCompleteResults(this, CodeCompleter,
4541 CodeCompletionContext::CCC_Other,
4542 Results.data(),Results.size());
Douglas Gregor636a61e2010-04-07 00:21:17 +00004543}
Douglas Gregor95887f92010-07-08 23:20:03 +00004544
4545void Sema::CodeCompleteObjCMethodDeclSelector(Scope *S,
4546 bool IsInstanceMethod,
Douglas Gregor45879692010-07-08 23:37:41 +00004547 bool AtParameterName,
John McCallba7bf592010-08-24 05:47:05 +00004548 ParsedType ReturnTy,
Douglas Gregor95887f92010-07-08 23:20:03 +00004549 IdentifierInfo **SelIdents,
4550 unsigned NumSelIdents) {
Douglas Gregor95887f92010-07-08 23:20:03 +00004551 // If we have an external source, load the entire class method
Sebastian Redld44cd6a2010-08-18 23:57:06 +00004552 // pool from the AST file.
Douglas Gregor95887f92010-07-08 23:20:03 +00004553 if (ExternalSource) {
4554 for (uint32_t I = 0, N = ExternalSource->GetNumExternalSelectors();
4555 I != N; ++I) {
4556 Selector Sel = ExternalSource->GetExternalSelector(I);
Sebastian Redl75d8a322010-08-02 23:18:59 +00004557 if (Sel.isNull() || MethodPool.count(Sel))
Douglas Gregor95887f92010-07-08 23:20:03 +00004558 continue;
Sebastian Redl75d8a322010-08-02 23:18:59 +00004559
4560 ReadMethodPool(Sel);
Douglas Gregor95887f92010-07-08 23:20:03 +00004561 }
4562 }
4563
4564 // Build the set of methods we can see.
4565 typedef CodeCompleteConsumer::Result Result;
4566 ResultBuilder Results(*this);
4567
4568 if (ReturnTy)
4569 Results.setPreferredType(GetTypeFromParser(ReturnTy).getNonReferenceType());
Sebastian Redl75d8a322010-08-02 23:18:59 +00004570
Douglas Gregor95887f92010-07-08 23:20:03 +00004571 Results.EnterNewScope();
Sebastian Redl75d8a322010-08-02 23:18:59 +00004572 for (GlobalMethodPool::iterator M = MethodPool.begin(),
4573 MEnd = MethodPool.end();
4574 M != MEnd; ++M) {
4575 for (ObjCMethodList *MethList = IsInstanceMethod ? &M->second.first :
4576 &M->second.second;
4577 MethList && MethList->Method;
Douglas Gregor95887f92010-07-08 23:20:03 +00004578 MethList = MethList->Next) {
4579 if (!isAcceptableObjCMethod(MethList->Method, MK_Any, SelIdents,
4580 NumSelIdents))
4581 continue;
4582
Douglas Gregor45879692010-07-08 23:37:41 +00004583 if (AtParameterName) {
4584 // Suggest parameter names we've seen before.
4585 if (NumSelIdents && NumSelIdents <= MethList->Method->param_size()) {
4586 ParmVarDecl *Param = MethList->Method->param_begin()[NumSelIdents-1];
4587 if (Param->getIdentifier()) {
4588 CodeCompletionString *Pattern = new CodeCompletionString;
4589 Pattern->AddTypedTextChunk(Param->getIdentifier()->getName());
4590 Results.AddResult(Pattern);
4591 }
4592 }
4593
4594 continue;
4595 }
4596
Douglas Gregor95887f92010-07-08 23:20:03 +00004597 Result R(MethList->Method, 0);
4598 R.StartParameter = NumSelIdents;
4599 R.AllParametersAreInformative = false;
4600 R.DeclaringEntity = true;
4601 Results.MaybeAddResult(R, CurContext);
4602 }
4603 }
4604
4605 Results.ExitScope();
Douglas Gregor00c37ef2010-08-11 21:23:17 +00004606 HandleCodeCompleteResults(this, CodeCompleter,
4607 CodeCompletionContext::CCC_Other,
4608 Results.data(),Results.size());
Douglas Gregor95887f92010-07-08 23:20:03 +00004609}
Douglas Gregorb14904c2010-08-13 22:48:40 +00004610
Douglas Gregor3a7ad252010-08-24 19:08:16 +00004611void Sema::CodeCompletePreprocessorDirective(Scope *S, bool InConditional) {
4612 ResultBuilder Results(*this);
4613 Results.EnterNewScope();
4614
4615 // #if <condition>
4616 CodeCompletionString *Pattern = new CodeCompletionString;
4617 Pattern->AddTypedTextChunk("if");
4618 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
4619 Pattern->AddPlaceholderChunk("condition");
4620 Results.AddResult(Pattern);
4621
4622 // #ifdef <macro>
4623 Pattern = new CodeCompletionString;
4624 Pattern->AddTypedTextChunk("ifdef");
4625 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
4626 Pattern->AddPlaceholderChunk("macro");
4627 Results.AddResult(Pattern);
4628
4629 // #ifndef <macro>
4630 Pattern = new CodeCompletionString;
4631 Pattern->AddTypedTextChunk("ifndef");
4632 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
4633 Pattern->AddPlaceholderChunk("macro");
4634 Results.AddResult(Pattern);
4635
4636 if (InConditional) {
4637 // #elif <condition>
4638 Pattern = new CodeCompletionString;
4639 Pattern->AddTypedTextChunk("elif");
4640 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
4641 Pattern->AddPlaceholderChunk("condition");
4642 Results.AddResult(Pattern);
4643
4644 // #else
4645 Pattern = new CodeCompletionString;
4646 Pattern->AddTypedTextChunk("else");
4647 Results.AddResult(Pattern);
4648
4649 // #endif
4650 Pattern = new CodeCompletionString;
4651 Pattern->AddTypedTextChunk("endif");
4652 Results.AddResult(Pattern);
4653 }
4654
4655 // #include "header"
4656 Pattern = new CodeCompletionString;
4657 Pattern->AddTypedTextChunk("include");
4658 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
4659 Pattern->AddTextChunk("\"");
4660 Pattern->AddPlaceholderChunk("header");
4661 Pattern->AddTextChunk("\"");
4662 Results.AddResult(Pattern);
4663
4664 // #include <header>
4665 Pattern = new CodeCompletionString;
4666 Pattern->AddTypedTextChunk("include");
4667 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
4668 Pattern->AddTextChunk("<");
4669 Pattern->AddPlaceholderChunk("header");
4670 Pattern->AddTextChunk(">");
4671 Results.AddResult(Pattern);
4672
4673 // #define <macro>
4674 Pattern = new CodeCompletionString;
4675 Pattern->AddTypedTextChunk("define");
4676 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
4677 Pattern->AddPlaceholderChunk("macro");
4678 Results.AddResult(Pattern);
4679
4680 // #define <macro>(<args>)
4681 Pattern = new CodeCompletionString;
4682 Pattern->AddTypedTextChunk("define");
4683 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
4684 Pattern->AddPlaceholderChunk("macro");
4685 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
4686 Pattern->AddPlaceholderChunk("args");
4687 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
4688 Results.AddResult(Pattern);
4689
4690 // #undef <macro>
4691 Pattern = new CodeCompletionString;
4692 Pattern->AddTypedTextChunk("undef");
4693 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
4694 Pattern->AddPlaceholderChunk("macro");
4695 Results.AddResult(Pattern);
4696
4697 // #line <number>
4698 Pattern = new CodeCompletionString;
4699 Pattern->AddTypedTextChunk("line");
4700 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
4701 Pattern->AddPlaceholderChunk("number");
4702 Results.AddResult(Pattern);
4703
4704 // #line <number> "filename"
4705 Pattern = new CodeCompletionString;
4706 Pattern->AddTypedTextChunk("line");
4707 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
4708 Pattern->AddPlaceholderChunk("number");
4709 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
4710 Pattern->AddTextChunk("\"");
4711 Pattern->AddPlaceholderChunk("filename");
4712 Pattern->AddTextChunk("\"");
4713 Results.AddResult(Pattern);
4714
4715 // #error <message>
4716 Pattern = new CodeCompletionString;
4717 Pattern->AddTypedTextChunk("error");
4718 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
4719 Pattern->AddPlaceholderChunk("message");
4720 Results.AddResult(Pattern);
4721
4722 // #pragma <arguments>
4723 Pattern = new CodeCompletionString;
4724 Pattern->AddTypedTextChunk("pragma");
4725 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
4726 Pattern->AddPlaceholderChunk("arguments");
4727 Results.AddResult(Pattern);
4728
4729 if (getLangOptions().ObjC1) {
4730 // #import "header"
4731 Pattern = new CodeCompletionString;
4732 Pattern->AddTypedTextChunk("import");
4733 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
4734 Pattern->AddTextChunk("\"");
4735 Pattern->AddPlaceholderChunk("header");
4736 Pattern->AddTextChunk("\"");
4737 Results.AddResult(Pattern);
4738
4739 // #import <header>
4740 Pattern = new CodeCompletionString;
4741 Pattern->AddTypedTextChunk("import");
4742 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
4743 Pattern->AddTextChunk("<");
4744 Pattern->AddPlaceholderChunk("header");
4745 Pattern->AddTextChunk(">");
4746 Results.AddResult(Pattern);
4747 }
4748
4749 // #include_next "header"
4750 Pattern = new CodeCompletionString;
4751 Pattern->AddTypedTextChunk("include_next");
4752 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
4753 Pattern->AddTextChunk("\"");
4754 Pattern->AddPlaceholderChunk("header");
4755 Pattern->AddTextChunk("\"");
4756 Results.AddResult(Pattern);
4757
4758 // #include_next <header>
4759 Pattern = new CodeCompletionString;
4760 Pattern->AddTypedTextChunk("include_next");
4761 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
4762 Pattern->AddTextChunk("<");
4763 Pattern->AddPlaceholderChunk("header");
4764 Pattern->AddTextChunk(">");
4765 Results.AddResult(Pattern);
4766
4767 // #warning <message>
4768 Pattern = new CodeCompletionString;
4769 Pattern->AddTypedTextChunk("warning");
4770 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
4771 Pattern->AddPlaceholderChunk("message");
4772 Results.AddResult(Pattern);
4773
4774 // Note: #ident and #sccs are such crazy anachronisms that we don't provide
4775 // completions for them. And __include_macros is a Clang-internal extension
4776 // that we don't want to encourage anyone to use.
4777
4778 // FIXME: we don't support #assert or #unassert, so don't suggest them.
4779 Results.ExitScope();
4780
4781 // FIXME: Create a new code-completion context for this?
4782 HandleCodeCompleteResults(this, CodeCompleter,
4783 CodeCompletionContext::CCC_Other,
4784 Results.data(), Results.size());
4785}
4786
4787void Sema::CodeCompleteInPreprocessorConditionalExclusion(Scope *S) {
4788 CodeCompleteOrdinaryName(S, Action::PCC_RecoveryInFunction);
4789}
4790
Douglas Gregor12785102010-08-24 20:21:13 +00004791void Sema::CodeCompletePreprocessorMacroName(Scope *S, bool IsDefinition) {
4792 typedef CodeCompleteConsumer::Result Result;
4793 ResultBuilder Results(*this);
4794 if (!IsDefinition && (!CodeCompleter || CodeCompleter->includeMacros())) {
4795 // Add just the names of macros, not their arguments.
4796 Results.EnterNewScope();
4797 for (Preprocessor::macro_iterator M = PP.macro_begin(),
4798 MEnd = PP.macro_end();
4799 M != MEnd; ++M) {
4800 CodeCompletionString *Pattern = new CodeCompletionString;
4801 Pattern->AddTypedTextChunk(M->first->getName());
4802 Results.AddResult(Pattern);
4803 }
4804 Results.ExitScope();
4805 } else if (IsDefinition) {
4806 // FIXME: Can we detect when the user just wrote an include guard above?
4807 }
4808
4809 HandleCodeCompleteResults(this, CodeCompleter,
4810 IsDefinition? CodeCompletionContext::CCC_MacroName
4811 : CodeCompletionContext::CCC_MacroNameUse,
4812 Results.data(), Results.size());
4813}
4814
Douglas Gregorb14904c2010-08-13 22:48:40 +00004815void Sema::GatherGlobalCodeCompletions(
4816 llvm::SmallVectorImpl<CodeCompleteConsumer::Result> &Results) {
4817 ResultBuilder Builder(*this);
4818
Douglas Gregor39982192010-08-15 06:18:01 +00004819 if (!CodeCompleter || CodeCompleter->includeGlobals()) {
4820 CodeCompletionDeclConsumer Consumer(Builder,
4821 Context.getTranslationUnitDecl());
4822 LookupVisibleDecls(Context.getTranslationUnitDecl(), LookupAnyName,
4823 Consumer);
4824 }
Douglas Gregorb14904c2010-08-13 22:48:40 +00004825
4826 if (!CodeCompleter || CodeCompleter->includeMacros())
4827 AddMacroResults(PP, Builder);
4828
4829 Results.clear();
4830 Results.insert(Results.end(),
4831 Builder.data(), Builder.data() + Builder.size());
4832}