blob: 1d91c3fa812a4e22d49eb0b94dd672e6b6f6205a [file] [log] [blame]
Douglas Gregor81b747b2009-09-17 21:32:03 +00001//===---------------- SemaCodeComplete.cpp - Code Completion ----*- C++ -*-===//
2//
3// The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9//
10// This file defines the code-completion semantic actions.
11//
12//===----------------------------------------------------------------------===//
Douglas Gregore737f502010-08-12 20:07:10 +000013#include "clang/Sema/Sema.h"
14#include "clang/Sema/Lookup.h"
Douglas Gregor81b747b2009-09-17 21:32:03 +000015#include "clang/Sema/CodeCompleteConsumer.h"
Douglas Gregor719770d2010-04-06 17:30:22 +000016#include "clang/Sema/ExternalSemaSource.h"
Douglas Gregorb9d0ef72009-09-21 19:57:38 +000017#include "clang/AST/ExprCXX.h"
Douglas Gregor24a069f2009-11-17 17:59:40 +000018#include "clang/AST/ExprObjC.h"
Douglas Gregor3f7c7f42009-10-30 16:50:04 +000019#include "clang/Lex/MacroInfo.h"
20#include "clang/Lex/Preprocessor.h"
Douglas Gregor86d9a522009-09-21 16:56:56 +000021#include "llvm/ADT/SmallPtrSet.h"
Douglas Gregor6a684032009-09-28 03:51:44 +000022#include "llvm/ADT/StringExtras.h"
Douglas Gregor22f56992010-04-06 19:22:33 +000023#include "llvm/ADT/StringSwitch.h"
Douglas Gregor86d9a522009-09-21 16:56:56 +000024#include <list>
25#include <map>
26#include <vector>
Douglas Gregor81b747b2009-09-17 21:32:03 +000027
28using namespace clang;
29
Douglas Gregor86d9a522009-09-21 16:56:56 +000030namespace {
31 /// \brief A container of code-completion results.
32 class ResultBuilder {
33 public:
34 /// \brief The type of a name-lookup filter, which can be provided to the
35 /// name-lookup routines to specify which declarations should be included in
36 /// the result set (when it returns true) and which declarations should be
37 /// filtered out (returns false).
38 typedef bool (ResultBuilder::*LookupFilter)(NamedDecl *) const;
39
40 typedef CodeCompleteConsumer::Result Result;
41
42 private:
43 /// \brief The actual results we have found.
44 std::vector<Result> Results;
45
46 /// \brief A record of all of the declarations we have found and placed
47 /// into the result set, used to ensure that no declaration ever gets into
48 /// the result set twice.
49 llvm::SmallPtrSet<Decl*, 16> AllDeclsFound;
50
Douglas Gregorfbcb5d62009-12-06 20:23:50 +000051 typedef std::pair<NamedDecl *, unsigned> DeclIndexPair;
52
53 /// \brief An entry in the shadow map, which is optimized to store
54 /// a single (declaration, index) mapping (the common case) but
55 /// can also store a list of (declaration, index) mappings.
56 class ShadowMapEntry {
57 typedef llvm::SmallVector<DeclIndexPair, 4> DeclIndexPairVector;
58
59 /// \brief Contains either the solitary NamedDecl * or a vector
60 /// of (declaration, index) pairs.
61 llvm::PointerUnion<NamedDecl *, DeclIndexPairVector*> DeclOrVector;
62
63 /// \brief When the entry contains a single declaration, this is
64 /// the index associated with that entry.
65 unsigned SingleDeclIndex;
66
67 public:
68 ShadowMapEntry() : DeclOrVector(), SingleDeclIndex(0) { }
69
70 void Add(NamedDecl *ND, unsigned Index) {
71 if (DeclOrVector.isNull()) {
72 // 0 - > 1 elements: just set the single element information.
73 DeclOrVector = ND;
74 SingleDeclIndex = Index;
75 return;
76 }
77
78 if (NamedDecl *PrevND = DeclOrVector.dyn_cast<NamedDecl *>()) {
79 // 1 -> 2 elements: create the vector of results and push in the
80 // existing declaration.
81 DeclIndexPairVector *Vec = new DeclIndexPairVector;
82 Vec->push_back(DeclIndexPair(PrevND, SingleDeclIndex));
83 DeclOrVector = Vec;
84 }
85
86 // Add the new element to the end of the vector.
87 DeclOrVector.get<DeclIndexPairVector*>()->push_back(
88 DeclIndexPair(ND, Index));
89 }
90
91 void Destroy() {
92 if (DeclIndexPairVector *Vec
93 = DeclOrVector.dyn_cast<DeclIndexPairVector *>()) {
94 delete Vec;
95 DeclOrVector = ((NamedDecl *)0);
96 }
97 }
98
99 // Iteration.
100 class iterator;
101 iterator begin() const;
102 iterator end() const;
103 };
104
Douglas Gregor86d9a522009-09-21 16:56:56 +0000105 /// \brief A mapping from declaration names to the declarations that have
106 /// this name within a particular scope and their index within the list of
107 /// results.
Douglas Gregorfbcb5d62009-12-06 20:23:50 +0000108 typedef llvm::DenseMap<DeclarationName, ShadowMapEntry> ShadowMap;
Douglas Gregor86d9a522009-09-21 16:56:56 +0000109
110 /// \brief The semantic analysis object for which results are being
111 /// produced.
112 Sema &SemaRef;
113
114 /// \brief If non-NULL, a filter function used to remove any code-completion
115 /// results that are not desirable.
116 LookupFilter Filter;
Douglas Gregor45bcd432010-01-14 03:21:49 +0000117
118 /// \brief Whether we should allow declarations as
119 /// nested-name-specifiers that would otherwise be filtered out.
120 bool AllowNestedNameSpecifiers;
121
Douglas Gregor5ac3bdb2010-05-30 01:49:25 +0000122 /// \brief If set, the type that we would prefer our resulting value
123 /// declarations to have.
124 ///
125 /// Closely matching the preferred type gives a boost to a result's
126 /// priority.
127 CanQualType PreferredType;
128
Douglas Gregor86d9a522009-09-21 16:56:56 +0000129 /// \brief A list of shadow maps, which is used to model name hiding at
130 /// different levels of, e.g., the inheritance hierarchy.
131 std::list<ShadowMap> ShadowMaps;
132
Douglas Gregor1f5537a2010-07-08 23:20:03 +0000133 void AdjustResultPriorityForPreferredType(Result &R);
134
Douglas Gregor86d9a522009-09-21 16:56:56 +0000135 public:
136 explicit ResultBuilder(Sema &SemaRef, LookupFilter Filter = 0)
Douglas Gregor45bcd432010-01-14 03:21:49 +0000137 : SemaRef(SemaRef), Filter(Filter), AllowNestedNameSpecifiers(false) { }
Douglas Gregor86d9a522009-09-21 16:56:56 +0000138
Douglas Gregord8e8a582010-05-25 21:41:55 +0000139 /// \brief Whether we should include code patterns in the completion
140 /// results.
141 bool includeCodePatterns() const {
142 return SemaRef.CodeCompleter &&
143 SemaRef.CodeCompleter->includeCodePatterns();
144 }
145
Douglas Gregor86d9a522009-09-21 16:56:56 +0000146 /// \brief Set the filter used for code-completion results.
147 void setFilter(LookupFilter Filter) {
148 this->Filter = Filter;
149 }
150
151 typedef std::vector<Result>::iterator iterator;
152 iterator begin() { return Results.begin(); }
153 iterator end() { return Results.end(); }
154
155 Result *data() { return Results.empty()? 0 : &Results.front(); }
156 unsigned size() const { return Results.size(); }
157 bool empty() const { return Results.empty(); }
158
Douglas Gregor5ac3bdb2010-05-30 01:49:25 +0000159 /// \brief Specify the preferred type.
160 void setPreferredType(QualType T) {
161 PreferredType = SemaRef.Context.getCanonicalType(T);
162 }
163
Douglas Gregor45bcd432010-01-14 03:21:49 +0000164 /// \brief Specify whether nested-name-specifiers are allowed.
165 void allowNestedNameSpecifiers(bool Allow = true) {
166 AllowNestedNameSpecifiers = Allow;
167 }
168
Douglas Gregore495b7f2010-01-14 00:20:49 +0000169 /// \brief Determine whether the given declaration is at all interesting
170 /// as a code-completion result.
Douglas Gregor45bcd432010-01-14 03:21:49 +0000171 ///
172 /// \param ND the declaration that we are inspecting.
173 ///
174 /// \param AsNestedNameSpecifier will be set true if this declaration is
175 /// only interesting when it is a nested-name-specifier.
176 bool isInterestingDecl(NamedDecl *ND, bool &AsNestedNameSpecifier) const;
Douglas Gregor6660d842010-01-14 00:41:07 +0000177
178 /// \brief Check whether the result is hidden by the Hiding declaration.
179 ///
180 /// \returns true if the result is hidden and cannot be found, false if
181 /// the hidden result could still be found. When false, \p R may be
182 /// modified to describe how the result can be found (e.g., via extra
183 /// qualification).
184 bool CheckHiddenResult(Result &R, DeclContext *CurContext,
185 NamedDecl *Hiding);
186
Douglas Gregor86d9a522009-09-21 16:56:56 +0000187 /// \brief Add a new result to this result set (if it isn't already in one
188 /// of the shadow maps), or replace an existing result (for, e.g., a
189 /// redeclaration).
Douglas Gregor456c4a12009-09-21 20:12:40 +0000190 ///
Douglas Gregor1ca6ae82010-01-14 01:09:38 +0000191 /// \param CurContext the result to add (if it is unique).
Douglas Gregor456c4a12009-09-21 20:12:40 +0000192 ///
193 /// \param R the context in which this result will be named.
194 void MaybeAddResult(Result R, DeclContext *CurContext = 0);
Douglas Gregor86d9a522009-09-21 16:56:56 +0000195
Douglas Gregor1ca6ae82010-01-14 01:09:38 +0000196 /// \brief Add a new result to this result set, where we already know
197 /// the hiding declation (if any).
198 ///
199 /// \param R the result to add (if it is unique).
200 ///
201 /// \param CurContext the context in which this result will be named.
202 ///
203 /// \param Hiding the declaration that hides the result.
Douglas Gregor0cc84042010-01-14 15:47:35 +0000204 ///
205 /// \param InBaseClass whether the result was found in a base
206 /// class of the searched context.
207 void AddResult(Result R, DeclContext *CurContext, NamedDecl *Hiding,
208 bool InBaseClass);
Douglas Gregor1ca6ae82010-01-14 01:09:38 +0000209
Douglas Gregora4477812010-01-14 16:01:26 +0000210 /// \brief Add a new non-declaration result to this result set.
211 void AddResult(Result R);
212
Douglas Gregor86d9a522009-09-21 16:56:56 +0000213 /// \brief Enter into a new scope.
214 void EnterNewScope();
215
216 /// \brief Exit from the current scope.
217 void ExitScope();
218
Douglas Gregor55385fe2009-11-18 04:19:12 +0000219 /// \brief Ignore this declaration, if it is seen again.
220 void Ignore(Decl *D) { AllDeclsFound.insert(D->getCanonicalDecl()); }
221
Douglas Gregor86d9a522009-09-21 16:56:56 +0000222 /// \name Name lookup predicates
223 ///
224 /// These predicates can be passed to the name lookup functions to filter the
225 /// results of name lookup. All of the predicates have the same type, so that
226 ///
227 //@{
Douglas Gregor791215b2009-09-21 20:51:25 +0000228 bool IsOrdinaryName(NamedDecl *ND) const;
Douglas Gregor4710e5b2010-05-28 00:49:12 +0000229 bool IsOrdinaryNonTypeName(NamedDecl *ND) const;
Douglas Gregorf9578432010-07-28 21:50:18 +0000230 bool IsIntegralConstantValue(NamedDecl *ND) const;
Douglas Gregor01dfea02010-01-10 23:08:15 +0000231 bool IsOrdinaryNonValueName(NamedDecl *ND) const;
Douglas Gregor86d9a522009-09-21 16:56:56 +0000232 bool IsNestedNameSpecifier(NamedDecl *ND) const;
233 bool IsEnum(NamedDecl *ND) const;
234 bool IsClassOrStruct(NamedDecl *ND) const;
235 bool IsUnion(NamedDecl *ND) const;
236 bool IsNamespace(NamedDecl *ND) const;
237 bool IsNamespaceOrAlias(NamedDecl *ND) const;
238 bool IsType(NamedDecl *ND) const;
Douglas Gregoreb5758b2009-09-23 22:26:46 +0000239 bool IsMember(NamedDecl *ND) const;
Douglas Gregor80f4f4c2010-01-14 16:08:12 +0000240 bool IsObjCIvar(NamedDecl *ND) const;
Douglas Gregor8e254cf2010-05-27 23:06:34 +0000241 bool IsObjCMessageReceiver(NamedDecl *ND) const;
Douglas Gregorfb629412010-08-23 21:17:50 +0000242 bool IsObjCCollection(NamedDecl *ND) const;
Douglas Gregor86d9a522009-09-21 16:56:56 +0000243 //@}
244 };
245}
246
Douglas Gregorfbcb5d62009-12-06 20:23:50 +0000247class ResultBuilder::ShadowMapEntry::iterator {
248 llvm::PointerUnion<NamedDecl*, const DeclIndexPair*> DeclOrIterator;
249 unsigned SingleDeclIndex;
250
251public:
252 typedef DeclIndexPair value_type;
253 typedef value_type reference;
254 typedef std::ptrdiff_t difference_type;
255 typedef std::input_iterator_tag iterator_category;
256
257 class pointer {
258 DeclIndexPair Value;
259
260 public:
261 pointer(const DeclIndexPair &Value) : Value(Value) { }
262
263 const DeclIndexPair *operator->() const {
264 return &Value;
265 }
266 };
267
268 iterator() : DeclOrIterator((NamedDecl *)0), SingleDeclIndex(0) { }
269
270 iterator(NamedDecl *SingleDecl, unsigned Index)
271 : DeclOrIterator(SingleDecl), SingleDeclIndex(Index) { }
272
273 iterator(const DeclIndexPair *Iterator)
274 : DeclOrIterator(Iterator), SingleDeclIndex(0) { }
275
276 iterator &operator++() {
277 if (DeclOrIterator.is<NamedDecl *>()) {
278 DeclOrIterator = (NamedDecl *)0;
279 SingleDeclIndex = 0;
280 return *this;
281 }
282
283 const DeclIndexPair *I = DeclOrIterator.get<const DeclIndexPair*>();
284 ++I;
285 DeclOrIterator = I;
286 return *this;
287 }
288
289 iterator operator++(int) {
290 iterator tmp(*this);
291 ++(*this);
292 return tmp;
293 }
294
295 reference operator*() const {
296 if (NamedDecl *ND = DeclOrIterator.dyn_cast<NamedDecl *>())
297 return reference(ND, SingleDeclIndex);
298
Douglas Gregord490f952009-12-06 21:27:58 +0000299 return *DeclOrIterator.get<const DeclIndexPair*>();
Douglas Gregorfbcb5d62009-12-06 20:23:50 +0000300 }
301
302 pointer operator->() const {
303 return pointer(**this);
304 }
305
306 friend bool operator==(const iterator &X, const iterator &Y) {
Douglas Gregord490f952009-12-06 21:27:58 +0000307 return X.DeclOrIterator.getOpaqueValue()
308 == Y.DeclOrIterator.getOpaqueValue() &&
Douglas Gregorfbcb5d62009-12-06 20:23:50 +0000309 X.SingleDeclIndex == Y.SingleDeclIndex;
310 }
311
312 friend bool operator!=(const iterator &X, const iterator &Y) {
Douglas Gregord490f952009-12-06 21:27:58 +0000313 return !(X == Y);
Douglas Gregorfbcb5d62009-12-06 20:23:50 +0000314 }
315};
316
Douglas Gregorfbcb5d62009-12-06 20:23:50 +0000317ResultBuilder::ShadowMapEntry::iterator
318ResultBuilder::ShadowMapEntry::begin() const {
319 if (DeclOrVector.isNull())
320 return iterator();
321
322 if (NamedDecl *ND = DeclOrVector.dyn_cast<NamedDecl *>())
323 return iterator(ND, SingleDeclIndex);
324
325 return iterator(DeclOrVector.get<DeclIndexPairVector *>()->begin());
326}
327
328ResultBuilder::ShadowMapEntry::iterator
329ResultBuilder::ShadowMapEntry::end() const {
330 if (DeclOrVector.is<NamedDecl *>() || DeclOrVector.isNull())
331 return iterator();
332
333 return iterator(DeclOrVector.get<DeclIndexPairVector *>()->end());
334}
335
Douglas Gregor456c4a12009-09-21 20:12:40 +0000336/// \brief Compute the qualification required to get from the current context
337/// (\p CurContext) to the target context (\p TargetContext).
338///
339/// \param Context the AST context in which the qualification will be used.
340///
341/// \param CurContext the context where an entity is being named, which is
342/// typically based on the current scope.
343///
344/// \param TargetContext the context in which the named entity actually
345/// resides.
346///
347/// \returns a nested name specifier that refers into the target context, or
348/// NULL if no qualification is needed.
349static NestedNameSpecifier *
350getRequiredQualification(ASTContext &Context,
351 DeclContext *CurContext,
352 DeclContext *TargetContext) {
353 llvm::SmallVector<DeclContext *, 4> TargetParents;
354
355 for (DeclContext *CommonAncestor = TargetContext;
356 CommonAncestor && !CommonAncestor->Encloses(CurContext);
357 CommonAncestor = CommonAncestor->getLookupParent()) {
358 if (CommonAncestor->isTransparentContext() ||
359 CommonAncestor->isFunctionOrMethod())
360 continue;
361
362 TargetParents.push_back(CommonAncestor);
363 }
364
365 NestedNameSpecifier *Result = 0;
366 while (!TargetParents.empty()) {
367 DeclContext *Parent = TargetParents.back();
368 TargetParents.pop_back();
369
Douglas Gregorfb629412010-08-23 21:17:50 +0000370 if (NamespaceDecl *Namespace = dyn_cast<NamespaceDecl>(Parent)) {
371 if (!Namespace->getIdentifier())
372 continue;
373
Douglas Gregor456c4a12009-09-21 20:12:40 +0000374 Result = NestedNameSpecifier::Create(Context, Result, Namespace);
Douglas Gregorfb629412010-08-23 21:17:50 +0000375 }
Douglas Gregor456c4a12009-09-21 20:12:40 +0000376 else if (TagDecl *TD = dyn_cast<TagDecl>(Parent))
377 Result = NestedNameSpecifier::Create(Context, Result,
378 false,
379 Context.getTypeDeclType(TD).getTypePtr());
Douglas Gregor0c8296d2009-11-07 00:00:49 +0000380 }
Douglas Gregor456c4a12009-09-21 20:12:40 +0000381 return Result;
382}
383
Douglas Gregor45bcd432010-01-14 03:21:49 +0000384bool ResultBuilder::isInterestingDecl(NamedDecl *ND,
385 bool &AsNestedNameSpecifier) const {
386 AsNestedNameSpecifier = false;
387
Douglas Gregore495b7f2010-01-14 00:20:49 +0000388 ND = ND->getUnderlyingDecl();
389 unsigned IDNS = ND->getIdentifierNamespace();
Douglas Gregorf52cede2009-10-09 22:16:47 +0000390
391 // Skip unnamed entities.
Douglas Gregore495b7f2010-01-14 00:20:49 +0000392 if (!ND->getDeclName())
393 return false;
Douglas Gregor86d9a522009-09-21 16:56:56 +0000394
395 // Friend declarations and declarations introduced due to friends are never
396 // added as results.
John McCall92b7f702010-03-11 07:50:04 +0000397 if (IDNS & (Decl::IDNS_OrdinaryFriend | Decl::IDNS_TagFriend))
Douglas Gregore495b7f2010-01-14 00:20:49 +0000398 return false;
399
Douglas Gregor76282942009-12-11 17:31:05 +0000400 // Class template (partial) specializations are never added as results.
Douglas Gregore495b7f2010-01-14 00:20:49 +0000401 if (isa<ClassTemplateSpecializationDecl>(ND) ||
402 isa<ClassTemplatePartialSpecializationDecl>(ND))
403 return false;
Douglas Gregor86d9a522009-09-21 16:56:56 +0000404
Douglas Gregor76282942009-12-11 17:31:05 +0000405 // Using declarations themselves are never added as results.
Douglas Gregore495b7f2010-01-14 00:20:49 +0000406 if (isa<UsingDecl>(ND))
407 return false;
408
409 // Some declarations have reserved names that we don't want to ever show.
410 if (const IdentifierInfo *Id = ND->getIdentifier()) {
Douglas Gregor86d9a522009-09-21 16:56:56 +0000411 // __va_list_tag is a freak of nature. Find it and skip it.
412 if (Id->isStr("__va_list_tag") || Id->isStr("__builtin_va_list"))
Douglas Gregore495b7f2010-01-14 00:20:49 +0000413 return false;
Douglas Gregor86d9a522009-09-21 16:56:56 +0000414
Douglas Gregorf52cede2009-10-09 22:16:47 +0000415 // Filter out names reserved for the implementation (C99 7.1.3,
Douglas Gregor797efb52010-07-14 17:44:04 +0000416 // C++ [lib.global.names]) if they come from a system header.
Daniel Dunbare013d682009-10-18 20:26:12 +0000417 //
418 // FIXME: Add predicate for this.
Douglas Gregorf52cede2009-10-09 22:16:47 +0000419 if (Id->getLength() >= 2) {
Daniel Dunbare013d682009-10-18 20:26:12 +0000420 const char *Name = Id->getNameStart();
Douglas Gregorf52cede2009-10-09 22:16:47 +0000421 if (Name[0] == '_' &&
Douglas Gregor797efb52010-07-14 17:44:04 +0000422 (Name[1] == '_' || (Name[1] >= 'A' && Name[1] <= 'Z')) &&
423 (ND->getLocation().isInvalid() ||
424 SemaRef.SourceMgr.isInSystemHeader(
425 SemaRef.SourceMgr.getSpellingLoc(ND->getLocation()))))
Douglas Gregore495b7f2010-01-14 00:20:49 +0000426 return false;
Douglas Gregorf52cede2009-10-09 22:16:47 +0000427 }
Douglas Gregor86d9a522009-09-21 16:56:56 +0000428 }
Douglas Gregore495b7f2010-01-14 00:20:49 +0000429
Douglas Gregor86d9a522009-09-21 16:56:56 +0000430 // C++ constructors are never found by name lookup.
Douglas Gregore495b7f2010-01-14 00:20:49 +0000431 if (isa<CXXConstructorDecl>(ND))
432 return false;
Douglas Gregor86d9a522009-09-21 16:56:56 +0000433
Douglas Gregora5fb7c32010-08-16 23:05:20 +0000434 if (Filter == &ResultBuilder::IsNestedNameSpecifier ||
435 ((isa<NamespaceDecl>(ND) || isa<NamespaceAliasDecl>(ND)) &&
436 Filter != &ResultBuilder::IsNamespace &&
437 Filter != &ResultBuilder::IsNamespaceOrAlias))
438 AsNestedNameSpecifier = true;
439
Douglas Gregor86d9a522009-09-21 16:56:56 +0000440 // Filter out any unwanted results.
Douglas Gregor45bcd432010-01-14 03:21:49 +0000441 if (Filter && !(this->*Filter)(ND)) {
442 // Check whether it is interesting as a nested-name-specifier.
443 if (AllowNestedNameSpecifiers && SemaRef.getLangOptions().CPlusPlus &&
444 IsNestedNameSpecifier(ND) &&
445 (Filter != &ResultBuilder::IsMember ||
446 (isa<CXXRecordDecl>(ND) &&
447 cast<CXXRecordDecl>(ND)->isInjectedClassName()))) {
448 AsNestedNameSpecifier = true;
449 return true;
450 }
451
Douglas Gregore495b7f2010-01-14 00:20:49 +0000452 return false;
Douglas Gregora5fb7c32010-08-16 23:05:20 +0000453 }
Douglas Gregore495b7f2010-01-14 00:20:49 +0000454 // ... then it must be interesting!
455 return true;
456}
457
Douglas Gregor6660d842010-01-14 00:41:07 +0000458bool ResultBuilder::CheckHiddenResult(Result &R, DeclContext *CurContext,
459 NamedDecl *Hiding) {
460 // In C, there is no way to refer to a hidden name.
461 // FIXME: This isn't true; we can find a tag name hidden by an ordinary
462 // name if we introduce the tag type.
463 if (!SemaRef.getLangOptions().CPlusPlus)
464 return true;
465
466 DeclContext *HiddenCtx = R.Declaration->getDeclContext()->getLookupContext();
467
468 // There is no way to qualify a name declared in a function or method.
469 if (HiddenCtx->isFunctionOrMethod())
470 return true;
471
472 if (HiddenCtx == Hiding->getDeclContext()->getLookupContext())
473 return true;
474
475 // We can refer to the result with the appropriate qualification. Do it.
476 R.Hidden = true;
477 R.QualifierIsInformative = false;
478
479 if (!R.Qualifier)
480 R.Qualifier = getRequiredQualification(SemaRef.Context,
481 CurContext,
482 R.Declaration->getDeclContext());
483 return false;
484}
485
Douglas Gregor1f5537a2010-07-08 23:20:03 +0000486/// \brief A simplified classification of types used to determine whether two
487/// types are "similar enough" when adjusting priorities.
Douglas Gregor1827e102010-08-16 16:18:59 +0000488SimplifiedTypeClass clang::getSimplifiedTypeClass(CanQualType T) {
Douglas Gregor1f5537a2010-07-08 23:20:03 +0000489 switch (T->getTypeClass()) {
490 case Type::Builtin:
491 switch (cast<BuiltinType>(T)->getKind()) {
492 case BuiltinType::Void:
493 return STC_Void;
494
495 case BuiltinType::NullPtr:
496 return STC_Pointer;
497
498 case BuiltinType::Overload:
499 case BuiltinType::Dependent:
500 case BuiltinType::UndeducedAuto:
501 return STC_Other;
502
503 case BuiltinType::ObjCId:
504 case BuiltinType::ObjCClass:
505 case BuiltinType::ObjCSel:
506 return STC_ObjectiveC;
507
508 default:
509 return STC_Arithmetic;
510 }
511 return STC_Other;
512
513 case Type::Complex:
514 return STC_Arithmetic;
515
516 case Type::Pointer:
517 return STC_Pointer;
518
519 case Type::BlockPointer:
520 return STC_Block;
521
522 case Type::LValueReference:
523 case Type::RValueReference:
524 return getSimplifiedTypeClass(T->getAs<ReferenceType>()->getPointeeType());
525
526 case Type::ConstantArray:
527 case Type::IncompleteArray:
528 case Type::VariableArray:
529 case Type::DependentSizedArray:
530 return STC_Array;
531
532 case Type::DependentSizedExtVector:
533 case Type::Vector:
534 case Type::ExtVector:
535 return STC_Arithmetic;
536
537 case Type::FunctionProto:
538 case Type::FunctionNoProto:
539 return STC_Function;
540
541 case Type::Record:
542 return STC_Record;
543
544 case Type::Enum:
545 return STC_Arithmetic;
546
547 case Type::ObjCObject:
548 case Type::ObjCInterface:
549 case Type::ObjCObjectPointer:
550 return STC_ObjectiveC;
551
552 default:
553 return STC_Other;
554 }
555}
556
557/// \brief Get the type that a given expression will have if this declaration
558/// is used as an expression in its "typical" code-completion form.
Douglas Gregor1827e102010-08-16 16:18:59 +0000559QualType clang::getDeclUsageType(ASTContext &C, NamedDecl *ND) {
Douglas Gregor1f5537a2010-07-08 23:20:03 +0000560 ND = cast<NamedDecl>(ND->getUnderlyingDecl());
561
562 if (TypeDecl *Type = dyn_cast<TypeDecl>(ND))
563 return C.getTypeDeclType(Type);
564 if (ObjCInterfaceDecl *Iface = dyn_cast<ObjCInterfaceDecl>(ND))
565 return C.getObjCInterfaceType(Iface);
566
567 QualType T;
568 if (FunctionDecl *Function = dyn_cast<FunctionDecl>(ND))
Douglas Gregor5291c3c2010-07-13 08:18:22 +0000569 T = Function->getCallResultType();
Douglas Gregor1f5537a2010-07-08 23:20:03 +0000570 else if (ObjCMethodDecl *Method = dyn_cast<ObjCMethodDecl>(ND))
Douglas Gregor5291c3c2010-07-13 08:18:22 +0000571 T = Method->getSendResultType();
Douglas Gregor1f5537a2010-07-08 23:20:03 +0000572 else if (FunctionTemplateDecl *FunTmpl = dyn_cast<FunctionTemplateDecl>(ND))
Douglas Gregor5291c3c2010-07-13 08:18:22 +0000573 T = FunTmpl->getTemplatedDecl()->getCallResultType();
Douglas Gregor1f5537a2010-07-08 23:20:03 +0000574 else if (EnumConstantDecl *Enumerator = dyn_cast<EnumConstantDecl>(ND))
575 T = C.getTypeDeclType(cast<EnumDecl>(Enumerator->getDeclContext()));
576 else if (ObjCPropertyDecl *Property = dyn_cast<ObjCPropertyDecl>(ND))
577 T = Property->getType();
578 else if (ValueDecl *Value = dyn_cast<ValueDecl>(ND))
579 T = Value->getType();
580 else
581 return QualType();
582
583 return T.getNonReferenceType();
584}
585
586void ResultBuilder::AdjustResultPriorityForPreferredType(Result &R) {
587 QualType T = getDeclUsageType(SemaRef.Context, R.Declaration);
588 if (T.isNull())
589 return;
590
591 CanQualType TC = SemaRef.Context.getCanonicalType(T);
592 // Check for exactly-matching types (modulo qualifiers).
593 if (SemaRef.Context.hasSameUnqualifiedType(PreferredType, TC))
594 R.Priority /= CCF_ExactTypeMatch;
595 // Check for nearly-matching types, based on classification of each.
596 else if ((getSimplifiedTypeClass(PreferredType)
597 == getSimplifiedTypeClass(TC)) &&
598 !(PreferredType->isEnumeralType() && TC->isEnumeralType()))
599 R.Priority /= CCF_SimilarTypeMatch;
600}
601
Douglas Gregore495b7f2010-01-14 00:20:49 +0000602void ResultBuilder::MaybeAddResult(Result R, DeclContext *CurContext) {
603 assert(!ShadowMaps.empty() && "Must enter into a results scope");
604
605 if (R.Kind != Result::RK_Declaration) {
606 // For non-declaration results, just add the result.
607 Results.push_back(R);
608 return;
609 }
610
611 // Look through using declarations.
612 if (UsingShadowDecl *Using = dyn_cast<UsingShadowDecl>(R.Declaration)) {
613 MaybeAddResult(Result(Using->getTargetDecl(), R.Qualifier), CurContext);
614 return;
615 }
616
617 Decl *CanonDecl = R.Declaration->getCanonicalDecl();
618 unsigned IDNS = CanonDecl->getIdentifierNamespace();
619
Douglas Gregor45bcd432010-01-14 03:21:49 +0000620 bool AsNestedNameSpecifier = false;
621 if (!isInterestingDecl(R.Declaration, AsNestedNameSpecifier))
Douglas Gregore495b7f2010-01-14 00:20:49 +0000622 return;
623
Douglas Gregor86d9a522009-09-21 16:56:56 +0000624 ShadowMap &SMap = ShadowMaps.back();
Douglas Gregorfbcb5d62009-12-06 20:23:50 +0000625 ShadowMapEntry::iterator I, IEnd;
626 ShadowMap::iterator NamePos = SMap.find(R.Declaration->getDeclName());
627 if (NamePos != SMap.end()) {
628 I = NamePos->second.begin();
629 IEnd = NamePos->second.end();
630 }
631
632 for (; I != IEnd; ++I) {
633 NamedDecl *ND = I->first;
634 unsigned Index = I->second;
Douglas Gregor86d9a522009-09-21 16:56:56 +0000635 if (ND->getCanonicalDecl() == CanonDecl) {
636 // This is a redeclaration. Always pick the newer declaration.
Douglas Gregor86d9a522009-09-21 16:56:56 +0000637 Results[Index].Declaration = R.Declaration;
638
Douglas Gregor86d9a522009-09-21 16:56:56 +0000639 // We're done.
640 return;
641 }
642 }
643
644 // This is a new declaration in this scope. However, check whether this
645 // declaration name is hidden by a similarly-named declaration in an outer
646 // scope.
647 std::list<ShadowMap>::iterator SM, SMEnd = ShadowMaps.end();
648 --SMEnd;
649 for (SM = ShadowMaps.begin(); SM != SMEnd; ++SM) {
Douglas Gregorfbcb5d62009-12-06 20:23:50 +0000650 ShadowMapEntry::iterator I, IEnd;
651 ShadowMap::iterator NamePos = SM->find(R.Declaration->getDeclName());
652 if (NamePos != SM->end()) {
653 I = NamePos->second.begin();
654 IEnd = NamePos->second.end();
655 }
656 for (; I != IEnd; ++I) {
Douglas Gregor86d9a522009-09-21 16:56:56 +0000657 // A tag declaration does not hide a non-tag declaration.
John McCall0d6b1642010-04-23 18:46:30 +0000658 if (I->first->hasTagIdentifierNamespace() &&
Douglas Gregor86d9a522009-09-21 16:56:56 +0000659 (IDNS & (Decl::IDNS_Member | Decl::IDNS_Ordinary |
660 Decl::IDNS_ObjCProtocol)))
661 continue;
662
663 // Protocols are in distinct namespaces from everything else.
Douglas Gregorfbcb5d62009-12-06 20:23:50 +0000664 if (((I->first->getIdentifierNamespace() & Decl::IDNS_ObjCProtocol)
Douglas Gregor86d9a522009-09-21 16:56:56 +0000665 || (IDNS & Decl::IDNS_ObjCProtocol)) &&
Douglas Gregorfbcb5d62009-12-06 20:23:50 +0000666 I->first->getIdentifierNamespace() != IDNS)
Douglas Gregor86d9a522009-09-21 16:56:56 +0000667 continue;
668
669 // The newly-added result is hidden by an entry in the shadow map.
Douglas Gregor6660d842010-01-14 00:41:07 +0000670 if (CheckHiddenResult(R, CurContext, I->first))
Douglas Gregor86d9a522009-09-21 16:56:56 +0000671 return;
Douglas Gregor86d9a522009-09-21 16:56:56 +0000672
673 break;
674 }
675 }
676
677 // Make sure that any given declaration only shows up in the result set once.
678 if (!AllDeclsFound.insert(CanonDecl))
679 return;
680
Douglas Gregoreb5758b2009-09-23 22:26:46 +0000681 // If the filter is for nested-name-specifiers, then this result starts a
682 // nested-name-specifier.
Douglas Gregor12e13132010-05-26 22:00:08 +0000683 if (AsNestedNameSpecifier) {
Douglas Gregoreb5758b2009-09-23 22:26:46 +0000684 R.StartsNestedNameSpecifier = true;
Douglas Gregor12e13132010-05-26 22:00:08 +0000685 R.Priority = CCP_NestedNameSpecifier;
Douglas Gregor1f5537a2010-07-08 23:20:03 +0000686 } else if (!PreferredType.isNull())
687 AdjustResultPriorityForPreferredType(R);
688
Douglas Gregor0563c262009-09-22 23:15:58 +0000689 // If this result is supposed to have an informative qualifier, add one.
Douglas Gregoreb5758b2009-09-23 22:26:46 +0000690 if (R.QualifierIsInformative && !R.Qualifier &&
691 !R.StartsNestedNameSpecifier) {
Douglas Gregor0563c262009-09-22 23:15:58 +0000692 DeclContext *Ctx = R.Declaration->getDeclContext();
693 if (NamespaceDecl *Namespace = dyn_cast<NamespaceDecl>(Ctx))
694 R.Qualifier = NestedNameSpecifier::Create(SemaRef.Context, 0, Namespace);
695 else if (TagDecl *Tag = dyn_cast<TagDecl>(Ctx))
696 R.Qualifier = NestedNameSpecifier::Create(SemaRef.Context, 0, false,
697 SemaRef.Context.getTypeDeclType(Tag).getTypePtr());
698 else
699 R.QualifierIsInformative = false;
700 }
Douglas Gregoreb5758b2009-09-23 22:26:46 +0000701
Douglas Gregor86d9a522009-09-21 16:56:56 +0000702 // Insert this result into the set of results and into the current shadow
703 // map.
Douglas Gregorfbcb5d62009-12-06 20:23:50 +0000704 SMap[R.Declaration->getDeclName()].Add(R.Declaration, Results.size());
Douglas Gregor86d9a522009-09-21 16:56:56 +0000705 Results.push_back(R);
706}
707
Douglas Gregor1ca6ae82010-01-14 01:09:38 +0000708void ResultBuilder::AddResult(Result R, DeclContext *CurContext,
Douglas Gregor0cc84042010-01-14 15:47:35 +0000709 NamedDecl *Hiding, bool InBaseClass = false) {
Douglas Gregora4477812010-01-14 16:01:26 +0000710 if (R.Kind != Result::RK_Declaration) {
711 // For non-declaration results, just add the result.
712 Results.push_back(R);
713 return;
714 }
715
Douglas Gregor1ca6ae82010-01-14 01:09:38 +0000716 // Look through using declarations.
717 if (UsingShadowDecl *Using = dyn_cast<UsingShadowDecl>(R.Declaration)) {
718 AddResult(Result(Using->getTargetDecl(), R.Qualifier), CurContext, Hiding);
719 return;
720 }
721
Douglas Gregor45bcd432010-01-14 03:21:49 +0000722 bool AsNestedNameSpecifier = false;
723 if (!isInterestingDecl(R.Declaration, AsNestedNameSpecifier))
Douglas Gregor1ca6ae82010-01-14 01:09:38 +0000724 return;
725
726 if (Hiding && CheckHiddenResult(R, CurContext, Hiding))
727 return;
728
729 // Make sure that any given declaration only shows up in the result set once.
730 if (!AllDeclsFound.insert(R.Declaration->getCanonicalDecl()))
731 return;
732
733 // If the filter is for nested-name-specifiers, then this result starts a
734 // nested-name-specifier.
Douglas Gregor12e13132010-05-26 22:00:08 +0000735 if (AsNestedNameSpecifier) {
Douglas Gregor1ca6ae82010-01-14 01:09:38 +0000736 R.StartsNestedNameSpecifier = true;
Douglas Gregor12e13132010-05-26 22:00:08 +0000737 R.Priority = CCP_NestedNameSpecifier;
738 }
Douglas Gregor0cc84042010-01-14 15:47:35 +0000739 else if (Filter == &ResultBuilder::IsMember && !R.Qualifier && InBaseClass &&
740 isa<CXXRecordDecl>(R.Declaration->getDeclContext()
741 ->getLookupContext()))
742 R.QualifierIsInformative = true;
743
Douglas Gregor1ca6ae82010-01-14 01:09:38 +0000744 // If this result is supposed to have an informative qualifier, add one.
745 if (R.QualifierIsInformative && !R.Qualifier &&
746 !R.StartsNestedNameSpecifier) {
747 DeclContext *Ctx = R.Declaration->getDeclContext();
748 if (NamespaceDecl *Namespace = dyn_cast<NamespaceDecl>(Ctx))
749 R.Qualifier = NestedNameSpecifier::Create(SemaRef.Context, 0, Namespace);
750 else if (TagDecl *Tag = dyn_cast<TagDecl>(Ctx))
751 R.Qualifier = NestedNameSpecifier::Create(SemaRef.Context, 0, false,
Douglas Gregor45bcd432010-01-14 03:21:49 +0000752 SemaRef.Context.getTypeDeclType(Tag).getTypePtr());
Douglas Gregor1ca6ae82010-01-14 01:09:38 +0000753 else
754 R.QualifierIsInformative = false;
755 }
756
Douglas Gregor12e13132010-05-26 22:00:08 +0000757 // Adjust the priority if this result comes from a base class.
758 if (InBaseClass)
759 R.Priority += CCD_InBaseClass;
760
Douglas Gregor1f5537a2010-07-08 23:20:03 +0000761 if (!PreferredType.isNull())
762 AdjustResultPriorityForPreferredType(R);
Douglas Gregor5ac3bdb2010-05-30 01:49:25 +0000763
Douglas Gregor1ca6ae82010-01-14 01:09:38 +0000764 // Insert this result into the set of results.
765 Results.push_back(R);
766}
767
Douglas Gregora4477812010-01-14 16:01:26 +0000768void ResultBuilder::AddResult(Result R) {
769 assert(R.Kind != Result::RK_Declaration &&
770 "Declaration results need more context");
771 Results.push_back(R);
772}
773
Douglas Gregor86d9a522009-09-21 16:56:56 +0000774/// \brief Enter into a new scope.
775void ResultBuilder::EnterNewScope() {
776 ShadowMaps.push_back(ShadowMap());
777}
778
779/// \brief Exit from the current scope.
780void ResultBuilder::ExitScope() {
Douglas Gregorfbcb5d62009-12-06 20:23:50 +0000781 for (ShadowMap::iterator E = ShadowMaps.back().begin(),
782 EEnd = ShadowMaps.back().end();
783 E != EEnd;
784 ++E)
785 E->second.Destroy();
786
Douglas Gregor86d9a522009-09-21 16:56:56 +0000787 ShadowMaps.pop_back();
788}
789
Douglas Gregor791215b2009-09-21 20:51:25 +0000790/// \brief Determines whether this given declaration will be found by
791/// ordinary name lookup.
792bool ResultBuilder::IsOrdinaryName(NamedDecl *ND) const {
Douglas Gregor4710e5b2010-05-28 00:49:12 +0000793 ND = cast<NamedDecl>(ND->getUnderlyingDecl());
794
Douglas Gregor791215b2009-09-21 20:51:25 +0000795 unsigned IDNS = Decl::IDNS_Ordinary;
796 if (SemaRef.getLangOptions().CPlusPlus)
Douglas Gregor9b30b262010-06-15 20:26:51 +0000797 IDNS |= Decl::IDNS_Tag | Decl::IDNS_Namespace | Decl::IDNS_Member;
Douglas Gregor1ca6ae82010-01-14 01:09:38 +0000798 else if (SemaRef.getLangOptions().ObjC1 && isa<ObjCIvarDecl>(ND))
799 return true;
800
Douglas Gregor791215b2009-09-21 20:51:25 +0000801 return ND->getIdentifierNamespace() & IDNS;
802}
803
Douglas Gregor01dfea02010-01-10 23:08:15 +0000804/// \brief Determines whether this given declaration will be found by
Douglas Gregor4710e5b2010-05-28 00:49:12 +0000805/// ordinary name lookup but is not a type name.
806bool ResultBuilder::IsOrdinaryNonTypeName(NamedDecl *ND) const {
807 ND = cast<NamedDecl>(ND->getUnderlyingDecl());
808 if (isa<TypeDecl>(ND) || isa<ObjCInterfaceDecl>(ND))
809 return false;
810
811 unsigned IDNS = Decl::IDNS_Ordinary;
812 if (SemaRef.getLangOptions().CPlusPlus)
Douglas Gregor9b30b262010-06-15 20:26:51 +0000813 IDNS |= Decl::IDNS_Tag | Decl::IDNS_Namespace | Decl::IDNS_Member;
Douglas Gregor4710e5b2010-05-28 00:49:12 +0000814 else if (SemaRef.getLangOptions().ObjC1 && isa<ObjCIvarDecl>(ND))
815 return true;
816
817 return ND->getIdentifierNamespace() & IDNS;
818}
819
Douglas Gregorf9578432010-07-28 21:50:18 +0000820bool ResultBuilder::IsIntegralConstantValue(NamedDecl *ND) const {
821 if (!IsOrdinaryNonTypeName(ND))
822 return 0;
823
824 if (ValueDecl *VD = dyn_cast<ValueDecl>(ND->getUnderlyingDecl()))
825 if (VD->getType()->isIntegralOrEnumerationType())
826 return true;
827
828 return false;
829}
830
Douglas Gregor4710e5b2010-05-28 00:49:12 +0000831/// \brief Determines whether this given declaration will be found by
Douglas Gregor01dfea02010-01-10 23:08:15 +0000832/// ordinary name lookup.
833bool ResultBuilder::IsOrdinaryNonValueName(NamedDecl *ND) const {
Douglas Gregor4710e5b2010-05-28 00:49:12 +0000834 ND = cast<NamedDecl>(ND->getUnderlyingDecl());
835
Douglas Gregor01dfea02010-01-10 23:08:15 +0000836 unsigned IDNS = Decl::IDNS_Ordinary;
837 if (SemaRef.getLangOptions().CPlusPlus)
John McCall0d6b1642010-04-23 18:46:30 +0000838 IDNS |= Decl::IDNS_Tag | Decl::IDNS_Namespace;
Douglas Gregor01dfea02010-01-10 23:08:15 +0000839
840 return (ND->getIdentifierNamespace() & IDNS) &&
Douglas Gregor4710e5b2010-05-28 00:49:12 +0000841 !isa<ValueDecl>(ND) && !isa<FunctionTemplateDecl>(ND) &&
842 !isa<ObjCPropertyDecl>(ND);
Douglas Gregor01dfea02010-01-10 23:08:15 +0000843}
844
Douglas Gregor86d9a522009-09-21 16:56:56 +0000845/// \brief Determines whether the given declaration is suitable as the
846/// start of a C++ nested-name-specifier, e.g., a class or namespace.
847bool ResultBuilder::IsNestedNameSpecifier(NamedDecl *ND) const {
848 // Allow us to find class templates, too.
849 if (ClassTemplateDecl *ClassTemplate = dyn_cast<ClassTemplateDecl>(ND))
850 ND = ClassTemplate->getTemplatedDecl();
851
852 return SemaRef.isAcceptableNestedNameSpecifier(ND);
853}
854
855/// \brief Determines whether the given declaration is an enumeration.
856bool ResultBuilder::IsEnum(NamedDecl *ND) const {
857 return isa<EnumDecl>(ND);
858}
859
860/// \brief Determines whether the given declaration is a class or struct.
861bool ResultBuilder::IsClassOrStruct(NamedDecl *ND) const {
862 // Allow us to find class templates, too.
863 if (ClassTemplateDecl *ClassTemplate = dyn_cast<ClassTemplateDecl>(ND))
864 ND = ClassTemplate->getTemplatedDecl();
865
866 if (RecordDecl *RD = dyn_cast<RecordDecl>(ND))
Abramo Bagnara465d41b2010-05-11 21:36:43 +0000867 return RD->getTagKind() == TTK_Class ||
868 RD->getTagKind() == TTK_Struct;
Douglas Gregor86d9a522009-09-21 16:56:56 +0000869
870 return false;
871}
872
873/// \brief Determines whether the given declaration is a union.
874bool ResultBuilder::IsUnion(NamedDecl *ND) const {
875 // Allow us to find class templates, too.
876 if (ClassTemplateDecl *ClassTemplate = dyn_cast<ClassTemplateDecl>(ND))
877 ND = ClassTemplate->getTemplatedDecl();
878
879 if (RecordDecl *RD = dyn_cast<RecordDecl>(ND))
Abramo Bagnara465d41b2010-05-11 21:36:43 +0000880 return RD->getTagKind() == TTK_Union;
Douglas Gregor86d9a522009-09-21 16:56:56 +0000881
882 return false;
883}
884
885/// \brief Determines whether the given declaration is a namespace.
886bool ResultBuilder::IsNamespace(NamedDecl *ND) const {
887 return isa<NamespaceDecl>(ND);
888}
889
890/// \brief Determines whether the given declaration is a namespace or
891/// namespace alias.
892bool ResultBuilder::IsNamespaceOrAlias(NamedDecl *ND) const {
893 return isa<NamespaceDecl>(ND) || isa<NamespaceAliasDecl>(ND);
894}
895
Douglas Gregor76282942009-12-11 17:31:05 +0000896/// \brief Determines whether the given declaration is a type.
Douglas Gregor86d9a522009-09-21 16:56:56 +0000897bool ResultBuilder::IsType(NamedDecl *ND) const {
898 return isa<TypeDecl>(ND);
899}
900
Douglas Gregor76282942009-12-11 17:31:05 +0000901/// \brief Determines which members of a class should be visible via
902/// "." or "->". Only value declarations, nested name specifiers, and
903/// using declarations thereof should show up.
Douglas Gregoreb5758b2009-09-23 22:26:46 +0000904bool ResultBuilder::IsMember(NamedDecl *ND) const {
Douglas Gregor76282942009-12-11 17:31:05 +0000905 if (UsingShadowDecl *Using = dyn_cast<UsingShadowDecl>(ND))
906 ND = Using->getTargetDecl();
907
Douglas Gregorce821962009-12-11 18:14:22 +0000908 return isa<ValueDecl>(ND) || isa<FunctionTemplateDecl>(ND) ||
909 isa<ObjCPropertyDecl>(ND);
Douglas Gregoreb5758b2009-09-23 22:26:46 +0000910}
911
Douglas Gregor8e254cf2010-05-27 23:06:34 +0000912static bool isObjCReceiverType(ASTContext &C, QualType T) {
913 T = C.getCanonicalType(T);
914 switch (T->getTypeClass()) {
915 case Type::ObjCObject:
916 case Type::ObjCInterface:
917 case Type::ObjCObjectPointer:
918 return true;
919
920 case Type::Builtin:
921 switch (cast<BuiltinType>(T)->getKind()) {
922 case BuiltinType::ObjCId:
923 case BuiltinType::ObjCClass:
924 case BuiltinType::ObjCSel:
925 return true;
926
927 default:
928 break;
929 }
930 return false;
931
932 default:
933 break;
934 }
935
936 if (!C.getLangOptions().CPlusPlus)
937 return false;
938
939 // FIXME: We could perform more analysis here to determine whether a
940 // particular class type has any conversions to Objective-C types. For now,
941 // just accept all class types.
942 return T->isDependentType() || T->isRecordType();
943}
944
945bool ResultBuilder::IsObjCMessageReceiver(NamedDecl *ND) const {
946 QualType T = getDeclUsageType(SemaRef.Context, ND);
947 if (T.isNull())
948 return false;
949
950 T = SemaRef.Context.getBaseElementType(T);
951 return isObjCReceiverType(SemaRef.Context, T);
952}
953
Douglas Gregorfb629412010-08-23 21:17:50 +0000954bool ResultBuilder::IsObjCCollection(NamedDecl *ND) const {
955 if ((SemaRef.getLangOptions().CPlusPlus && !IsOrdinaryName(ND)) ||
956 (!SemaRef.getLangOptions().CPlusPlus && !IsOrdinaryNonTypeName(ND)))
957 return false;
958
959 QualType T = getDeclUsageType(SemaRef.Context, ND);
960 if (T.isNull())
961 return false;
962
963 T = SemaRef.Context.getBaseElementType(T);
964 return T->isObjCObjectType() || T->isObjCObjectPointerType() ||
965 T->isObjCIdType() ||
966 (SemaRef.getLangOptions().CPlusPlus && T->isRecordType());
967}
Douglas Gregor8e254cf2010-05-27 23:06:34 +0000968
Douglas Gregor80f4f4c2010-01-14 16:08:12 +0000969/// \rief Determines whether the given declaration is an Objective-C
970/// instance variable.
971bool ResultBuilder::IsObjCIvar(NamedDecl *ND) const {
972 return isa<ObjCIvarDecl>(ND);
973}
974
Douglas Gregor1ca6ae82010-01-14 01:09:38 +0000975namespace {
976 /// \brief Visible declaration consumer that adds a code-completion result
977 /// for each visible declaration.
978 class CodeCompletionDeclConsumer : public VisibleDeclConsumer {
979 ResultBuilder &Results;
980 DeclContext *CurContext;
981
982 public:
983 CodeCompletionDeclConsumer(ResultBuilder &Results, DeclContext *CurContext)
984 : Results(Results), CurContext(CurContext) { }
985
Douglas Gregor0cc84042010-01-14 15:47:35 +0000986 virtual void FoundDecl(NamedDecl *ND, NamedDecl *Hiding, bool InBaseClass) {
987 Results.AddResult(ND, CurContext, Hiding, InBaseClass);
Douglas Gregor1ca6ae82010-01-14 01:09:38 +0000988 }
989 };
990}
991
Douglas Gregor86d9a522009-09-21 16:56:56 +0000992/// \brief Add type specifiers for the current language as keyword results.
Douglas Gregorbca403c2010-01-13 23:51:12 +0000993static void AddTypeSpecifierResults(const LangOptions &LangOpts,
Douglas Gregor86d9a522009-09-21 16:56:56 +0000994 ResultBuilder &Results) {
995 typedef CodeCompleteConsumer::Result Result;
Douglas Gregor12e13132010-05-26 22:00:08 +0000996 Results.AddResult(Result("short", CCP_Type));
997 Results.AddResult(Result("long", CCP_Type));
998 Results.AddResult(Result("signed", CCP_Type));
999 Results.AddResult(Result("unsigned", CCP_Type));
1000 Results.AddResult(Result("void", CCP_Type));
1001 Results.AddResult(Result("char", CCP_Type));
1002 Results.AddResult(Result("int", CCP_Type));
1003 Results.AddResult(Result("float", CCP_Type));
1004 Results.AddResult(Result("double", CCP_Type));
1005 Results.AddResult(Result("enum", CCP_Type));
1006 Results.AddResult(Result("struct", CCP_Type));
1007 Results.AddResult(Result("union", CCP_Type));
1008 Results.AddResult(Result("const", CCP_Type));
1009 Results.AddResult(Result("volatile", CCP_Type));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001010
Douglas Gregor86d9a522009-09-21 16:56:56 +00001011 if (LangOpts.C99) {
1012 // C99-specific
Douglas Gregor12e13132010-05-26 22:00:08 +00001013 Results.AddResult(Result("_Complex", CCP_Type));
1014 Results.AddResult(Result("_Imaginary", CCP_Type));
1015 Results.AddResult(Result("_Bool", CCP_Type));
1016 Results.AddResult(Result("restrict", CCP_Type));
Douglas Gregor86d9a522009-09-21 16:56:56 +00001017 }
1018
1019 if (LangOpts.CPlusPlus) {
1020 // C++-specific
Douglas Gregor12e13132010-05-26 22:00:08 +00001021 Results.AddResult(Result("bool", CCP_Type));
1022 Results.AddResult(Result("class", CCP_Type));
1023 Results.AddResult(Result("wchar_t", CCP_Type));
Douglas Gregor86d9a522009-09-21 16:56:56 +00001024
Douglas Gregorc8bddde2010-05-28 00:22:41 +00001025 // typename qualified-id
1026 CodeCompletionString *Pattern = new CodeCompletionString;
1027 Pattern->AddTypedTextChunk("typename");
1028 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
1029 Pattern->AddPlaceholderChunk("qualifier");
1030 Pattern->AddTextChunk("::");
1031 Pattern->AddPlaceholderChunk("name");
1032 Results.AddResult(Result(Pattern));
Douglas Gregord8e8a582010-05-25 21:41:55 +00001033
Douglas Gregor86d9a522009-09-21 16:56:56 +00001034 if (LangOpts.CPlusPlus0x) {
Douglas Gregor12e13132010-05-26 22:00:08 +00001035 Results.AddResult(Result("auto", CCP_Type));
1036 Results.AddResult(Result("char16_t", CCP_Type));
1037 Results.AddResult(Result("char32_t", CCP_Type));
Douglas Gregorc8bddde2010-05-28 00:22:41 +00001038
1039 CodeCompletionString *Pattern = new CodeCompletionString;
1040 Pattern->AddTypedTextChunk("decltype");
1041 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
1042 Pattern->AddPlaceholderChunk("expression");
1043 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
1044 Results.AddResult(Result(Pattern));
Douglas Gregor86d9a522009-09-21 16:56:56 +00001045 }
1046 }
1047
1048 // GNU extensions
1049 if (LangOpts.GNUMode) {
1050 // FIXME: Enable when we actually support decimal floating point.
Douglas Gregora4477812010-01-14 16:01:26 +00001051 // Results.AddResult(Result("_Decimal32"));
1052 // Results.AddResult(Result("_Decimal64"));
1053 // Results.AddResult(Result("_Decimal128"));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001054
Douglas Gregorc8bddde2010-05-28 00:22:41 +00001055 CodeCompletionString *Pattern = new CodeCompletionString;
1056 Pattern->AddTypedTextChunk("typeof");
1057 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
1058 Pattern->AddPlaceholderChunk("expression");
1059 Results.AddResult(Result(Pattern));
1060
1061 Pattern = new CodeCompletionString;
1062 Pattern->AddTypedTextChunk("typeof");
1063 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
1064 Pattern->AddPlaceholderChunk("type");
1065 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
1066 Results.AddResult(Result(Pattern));
Douglas Gregor86d9a522009-09-21 16:56:56 +00001067 }
1068}
1069
Douglas Gregore6b1bb62010-08-11 21:23:17 +00001070static void AddStorageSpecifiers(Action::ParserCompletionContext CCC,
Douglas Gregor01dfea02010-01-10 23:08:15 +00001071 const LangOptions &LangOpts,
Douglas Gregor01dfea02010-01-10 23:08:15 +00001072 ResultBuilder &Results) {
1073 typedef CodeCompleteConsumer::Result Result;
1074 // Note: we don't suggest either "auto" or "register", because both
1075 // are pointless as storage specifiers. Elsewhere, we suggest "auto"
1076 // in C++0x as a type specifier.
Douglas Gregora4477812010-01-14 16:01:26 +00001077 Results.AddResult(Result("extern"));
1078 Results.AddResult(Result("static"));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001079}
1080
Douglas Gregore6b1bb62010-08-11 21:23:17 +00001081static void AddFunctionSpecifiers(Action::ParserCompletionContext CCC,
Douglas Gregor01dfea02010-01-10 23:08:15 +00001082 const LangOptions &LangOpts,
Douglas Gregor01dfea02010-01-10 23:08:15 +00001083 ResultBuilder &Results) {
1084 typedef CodeCompleteConsumer::Result Result;
1085 switch (CCC) {
Douglas Gregore6b1bb62010-08-11 21:23:17 +00001086 case Action::PCC_Class:
1087 case Action::PCC_MemberTemplate:
Douglas Gregor01dfea02010-01-10 23:08:15 +00001088 if (LangOpts.CPlusPlus) {
Douglas Gregora4477812010-01-14 16:01:26 +00001089 Results.AddResult(Result("explicit"));
1090 Results.AddResult(Result("friend"));
1091 Results.AddResult(Result("mutable"));
1092 Results.AddResult(Result("virtual"));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001093 }
1094 // Fall through
1095
Douglas Gregore6b1bb62010-08-11 21:23:17 +00001096 case Action::PCC_ObjCInterface:
1097 case Action::PCC_ObjCImplementation:
1098 case Action::PCC_Namespace:
1099 case Action::PCC_Template:
Douglas Gregor01dfea02010-01-10 23:08:15 +00001100 if (LangOpts.CPlusPlus || LangOpts.C99)
Douglas Gregora4477812010-01-14 16:01:26 +00001101 Results.AddResult(Result("inline"));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001102 break;
1103
Douglas Gregore6b1bb62010-08-11 21:23:17 +00001104 case Action::PCC_ObjCInstanceVariableList:
1105 case Action::PCC_Expression:
1106 case Action::PCC_Statement:
1107 case Action::PCC_ForInit:
1108 case Action::PCC_Condition:
1109 case Action::PCC_RecoveryInFunction:
Douglas Gregor01dfea02010-01-10 23:08:15 +00001110 break;
1111 }
1112}
1113
Douglas Gregorbca403c2010-01-13 23:51:12 +00001114static void AddObjCExpressionResults(ResultBuilder &Results, bool NeedAt);
1115static void AddObjCStatementResults(ResultBuilder &Results, bool NeedAt);
1116static void AddObjCVisibilityResults(const LangOptions &LangOpts,
Douglas Gregorc38c3e12010-01-13 21:54:15 +00001117 ResultBuilder &Results,
1118 bool NeedAt);
Douglas Gregorbca403c2010-01-13 23:51:12 +00001119static void AddObjCImplementationResults(const LangOptions &LangOpts,
Douglas Gregorb6ac2452010-01-13 21:24:21 +00001120 ResultBuilder &Results,
1121 bool NeedAt);
Douglas Gregorbca403c2010-01-13 23:51:12 +00001122static void AddObjCInterfaceResults(const LangOptions &LangOpts,
Douglas Gregorb6ac2452010-01-13 21:24:21 +00001123 ResultBuilder &Results,
1124 bool NeedAt);
Douglas Gregorbca403c2010-01-13 23:51:12 +00001125static void AddObjCTopLevelResults(ResultBuilder &Results, bool NeedAt);
Douglas Gregorb6ac2452010-01-13 21:24:21 +00001126
Douglas Gregorc8bddde2010-05-28 00:22:41 +00001127static void AddTypedefResult(ResultBuilder &Results) {
1128 CodeCompletionString *Pattern = new CodeCompletionString;
1129 Pattern->AddTypedTextChunk("typedef");
1130 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
1131 Pattern->AddPlaceholderChunk("type");
1132 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
1133 Pattern->AddPlaceholderChunk("name");
1134 Results.AddResult(CodeCompleteConsumer::Result(Pattern));
1135}
1136
Douglas Gregore6b1bb62010-08-11 21:23:17 +00001137static bool WantTypesInContext(Action::ParserCompletionContext CCC,
Douglas Gregor4710e5b2010-05-28 00:49:12 +00001138 const LangOptions &LangOpts) {
1139 if (LangOpts.CPlusPlus)
1140 return true;
1141
1142 switch (CCC) {
Douglas Gregore6b1bb62010-08-11 21:23:17 +00001143 case Action::PCC_Namespace:
1144 case Action::PCC_Class:
1145 case Action::PCC_ObjCInstanceVariableList:
1146 case Action::PCC_Template:
1147 case Action::PCC_MemberTemplate:
1148 case Action::PCC_Statement:
1149 case Action::PCC_RecoveryInFunction:
Douglas Gregor4710e5b2010-05-28 00:49:12 +00001150 return true;
1151
Douglas Gregore6b1bb62010-08-11 21:23:17 +00001152 case Action::PCC_ObjCInterface:
1153 case Action::PCC_ObjCImplementation:
1154 case Action::PCC_Expression:
1155 case Action::PCC_Condition:
Douglas Gregor4710e5b2010-05-28 00:49:12 +00001156 return false;
1157
Douglas Gregore6b1bb62010-08-11 21:23:17 +00001158 case Action::PCC_ForInit:
Douglas Gregor4710e5b2010-05-28 00:49:12 +00001159 return LangOpts.ObjC1 || LangOpts.C99;
1160 }
1161
1162 return false;
1163}
1164
Douglas Gregor01dfea02010-01-10 23:08:15 +00001165/// \brief Add language constructs that show up for "ordinary" names.
Douglas Gregore6b1bb62010-08-11 21:23:17 +00001166static void AddOrdinaryNameResults(Action::ParserCompletionContext CCC,
Douglas Gregor01dfea02010-01-10 23:08:15 +00001167 Scope *S,
1168 Sema &SemaRef,
Douglas Gregor01dfea02010-01-10 23:08:15 +00001169 ResultBuilder &Results) {
1170 typedef CodeCompleteConsumer::Result Result;
1171 switch (CCC) {
Douglas Gregore6b1bb62010-08-11 21:23:17 +00001172 case Action::PCC_Namespace:
Douglas Gregorc8bddde2010-05-28 00:22:41 +00001173 if (SemaRef.getLangOptions().CPlusPlus) {
1174 CodeCompletionString *Pattern = 0;
1175
1176 if (Results.includeCodePatterns()) {
1177 // namespace <identifier> { declarations }
1178 CodeCompletionString *Pattern = new CodeCompletionString;
1179 Pattern->AddTypedTextChunk("namespace");
1180 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
1181 Pattern->AddPlaceholderChunk("identifier");
1182 Pattern->AddChunk(CodeCompletionString::CK_LeftBrace);
1183 Pattern->AddPlaceholderChunk("declarations");
1184 Pattern->AddChunk(CodeCompletionString::CK_VerticalSpace);
1185 Pattern->AddChunk(CodeCompletionString::CK_RightBrace);
1186 Results.AddResult(Result(Pattern));
1187 }
1188
Douglas Gregor01dfea02010-01-10 23:08:15 +00001189 // namespace identifier = identifier ;
1190 Pattern = new CodeCompletionString;
1191 Pattern->AddTypedTextChunk("namespace");
1192 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
Douglas Gregorc8bddde2010-05-28 00:22:41 +00001193 Pattern->AddPlaceholderChunk("name");
Douglas Gregor01dfea02010-01-10 23:08:15 +00001194 Pattern->AddChunk(CodeCompletionString::CK_Equal);
Douglas Gregorc8bddde2010-05-28 00:22:41 +00001195 Pattern->AddPlaceholderChunk("namespace");
Douglas Gregora4477812010-01-14 16:01:26 +00001196 Results.AddResult(Result(Pattern));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001197
1198 // Using directives
1199 Pattern = new CodeCompletionString;
1200 Pattern->AddTypedTextChunk("using");
1201 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
1202 Pattern->AddTextChunk("namespace");
1203 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
1204 Pattern->AddPlaceholderChunk("identifier");
Douglas Gregora4477812010-01-14 16:01:26 +00001205 Results.AddResult(Result(Pattern));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001206
1207 // asm(string-literal)
1208 Pattern = new CodeCompletionString;
1209 Pattern->AddTypedTextChunk("asm");
1210 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
1211 Pattern->AddPlaceholderChunk("string-literal");
1212 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
Douglas Gregora4477812010-01-14 16:01:26 +00001213 Results.AddResult(Result(Pattern));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001214
Douglas Gregorc8bddde2010-05-28 00:22:41 +00001215 if (Results.includeCodePatterns()) {
1216 // Explicit template instantiation
1217 Pattern = new CodeCompletionString;
1218 Pattern->AddTypedTextChunk("template");
1219 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
1220 Pattern->AddPlaceholderChunk("declaration");
1221 Results.AddResult(Result(Pattern));
1222 }
Douglas Gregor01dfea02010-01-10 23:08:15 +00001223 }
Douglas Gregorb6ac2452010-01-13 21:24:21 +00001224
1225 if (SemaRef.getLangOptions().ObjC1)
Douglas Gregorbca403c2010-01-13 23:51:12 +00001226 AddObjCTopLevelResults(Results, true);
Douglas Gregorb6ac2452010-01-13 21:24:21 +00001227
Douglas Gregorc8bddde2010-05-28 00:22:41 +00001228 AddTypedefResult(Results);
Douglas Gregor01dfea02010-01-10 23:08:15 +00001229 // Fall through
1230
Douglas Gregore6b1bb62010-08-11 21:23:17 +00001231 case Action::PCC_Class:
Douglas Gregorc8bddde2010-05-28 00:22:41 +00001232 if (SemaRef.getLangOptions().CPlusPlus) {
Douglas Gregor01dfea02010-01-10 23:08:15 +00001233 // Using declaration
1234 CodeCompletionString *Pattern = new CodeCompletionString;
1235 Pattern->AddTypedTextChunk("using");
1236 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
Douglas Gregorc8bddde2010-05-28 00:22:41 +00001237 Pattern->AddPlaceholderChunk("qualifier");
1238 Pattern->AddTextChunk("::");
1239 Pattern->AddPlaceholderChunk("name");
Douglas Gregora4477812010-01-14 16:01:26 +00001240 Results.AddResult(Result(Pattern));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001241
Douglas Gregorc8bddde2010-05-28 00:22:41 +00001242 // using typename qualifier::name (only in a dependent context)
Douglas Gregor01dfea02010-01-10 23:08:15 +00001243 if (SemaRef.CurContext->isDependentContext()) {
1244 Pattern = new CodeCompletionString;
1245 Pattern->AddTypedTextChunk("using");
1246 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
1247 Pattern->AddTextChunk("typename");
1248 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
Douglas Gregorc8bddde2010-05-28 00:22:41 +00001249 Pattern->AddPlaceholderChunk("qualifier");
1250 Pattern->AddTextChunk("::");
1251 Pattern->AddPlaceholderChunk("name");
Douglas Gregora4477812010-01-14 16:01:26 +00001252 Results.AddResult(Result(Pattern));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001253 }
1254
Douglas Gregore6b1bb62010-08-11 21:23:17 +00001255 if (CCC == Action::PCC_Class) {
Douglas Gregorc8bddde2010-05-28 00:22:41 +00001256 AddTypedefResult(Results);
1257
Douglas Gregor01dfea02010-01-10 23:08:15 +00001258 // public:
1259 Pattern = new CodeCompletionString;
1260 Pattern->AddTypedTextChunk("public");
1261 Pattern->AddChunk(CodeCompletionString::CK_Colon);
Douglas Gregora4477812010-01-14 16:01:26 +00001262 Results.AddResult(Result(Pattern));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001263
1264 // protected:
1265 Pattern = new CodeCompletionString;
1266 Pattern->AddTypedTextChunk("protected");
1267 Pattern->AddChunk(CodeCompletionString::CK_Colon);
Douglas Gregora4477812010-01-14 16:01:26 +00001268 Results.AddResult(Result(Pattern));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001269
1270 // private:
1271 Pattern = new CodeCompletionString;
1272 Pattern->AddTypedTextChunk("private");
1273 Pattern->AddChunk(CodeCompletionString::CK_Colon);
Douglas Gregora4477812010-01-14 16:01:26 +00001274 Results.AddResult(Result(Pattern));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001275 }
1276 }
1277 // Fall through
1278
Douglas Gregore6b1bb62010-08-11 21:23:17 +00001279 case Action::PCC_Template:
1280 case Action::PCC_MemberTemplate:
Douglas Gregord8e8a582010-05-25 21:41:55 +00001281 if (SemaRef.getLangOptions().CPlusPlus && Results.includeCodePatterns()) {
Douglas Gregor01dfea02010-01-10 23:08:15 +00001282 // template < parameters >
1283 CodeCompletionString *Pattern = new CodeCompletionString;
1284 Pattern->AddTypedTextChunk("template");
1285 Pattern->AddChunk(CodeCompletionString::CK_LeftAngle);
1286 Pattern->AddPlaceholderChunk("parameters");
1287 Pattern->AddChunk(CodeCompletionString::CK_RightAngle);
Douglas Gregora4477812010-01-14 16:01:26 +00001288 Results.AddResult(Result(Pattern));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001289 }
1290
Douglas Gregorbca403c2010-01-13 23:51:12 +00001291 AddStorageSpecifiers(CCC, SemaRef.getLangOptions(), Results);
1292 AddFunctionSpecifiers(CCC, SemaRef.getLangOptions(), Results);
Douglas Gregor01dfea02010-01-10 23:08:15 +00001293 break;
1294
Douglas Gregore6b1bb62010-08-11 21:23:17 +00001295 case Action::PCC_ObjCInterface:
Douglas Gregorbca403c2010-01-13 23:51:12 +00001296 AddObjCInterfaceResults(SemaRef.getLangOptions(), Results, true);
1297 AddStorageSpecifiers(CCC, SemaRef.getLangOptions(), Results);
1298 AddFunctionSpecifiers(CCC, SemaRef.getLangOptions(), Results);
Douglas Gregorb6ac2452010-01-13 21:24:21 +00001299 break;
1300
Douglas Gregore6b1bb62010-08-11 21:23:17 +00001301 case Action::PCC_ObjCImplementation:
Douglas Gregorbca403c2010-01-13 23:51:12 +00001302 AddObjCImplementationResults(SemaRef.getLangOptions(), Results, true);
1303 AddStorageSpecifiers(CCC, SemaRef.getLangOptions(), Results);
1304 AddFunctionSpecifiers(CCC, SemaRef.getLangOptions(), Results);
Douglas Gregorb6ac2452010-01-13 21:24:21 +00001305 break;
1306
Douglas Gregore6b1bb62010-08-11 21:23:17 +00001307 case Action::PCC_ObjCInstanceVariableList:
Douglas Gregorbca403c2010-01-13 23:51:12 +00001308 AddObjCVisibilityResults(SemaRef.getLangOptions(), Results, true);
Douglas Gregorc38c3e12010-01-13 21:54:15 +00001309 break;
1310
Douglas Gregore6b1bb62010-08-11 21:23:17 +00001311 case Action::PCC_RecoveryInFunction:
1312 case Action::PCC_Statement: {
Douglas Gregorc8bddde2010-05-28 00:22:41 +00001313 AddTypedefResult(Results);
Douglas Gregor01dfea02010-01-10 23:08:15 +00001314
1315 CodeCompletionString *Pattern = 0;
Douglas Gregord8e8a582010-05-25 21:41:55 +00001316 if (SemaRef.getLangOptions().CPlusPlus && Results.includeCodePatterns()) {
Douglas Gregor01dfea02010-01-10 23:08:15 +00001317 Pattern = new CodeCompletionString;
1318 Pattern->AddTypedTextChunk("try");
1319 Pattern->AddChunk(CodeCompletionString::CK_LeftBrace);
1320 Pattern->AddPlaceholderChunk("statements");
1321 Pattern->AddChunk(CodeCompletionString::CK_VerticalSpace);
1322 Pattern->AddChunk(CodeCompletionString::CK_RightBrace);
1323 Pattern->AddTextChunk("catch");
1324 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
1325 Pattern->AddPlaceholderChunk("declaration");
1326 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
1327 Pattern->AddChunk(CodeCompletionString::CK_LeftBrace);
1328 Pattern->AddPlaceholderChunk("statements");
1329 Pattern->AddChunk(CodeCompletionString::CK_VerticalSpace);
1330 Pattern->AddChunk(CodeCompletionString::CK_RightBrace);
Douglas Gregora4477812010-01-14 16:01:26 +00001331 Results.AddResult(Result(Pattern));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001332 }
Douglas Gregorb6ac2452010-01-13 21:24:21 +00001333 if (SemaRef.getLangOptions().ObjC1)
Douglas Gregorbca403c2010-01-13 23:51:12 +00001334 AddObjCStatementResults(Results, true);
Douglas Gregorb6ac2452010-01-13 21:24:21 +00001335
Douglas Gregord8e8a582010-05-25 21:41:55 +00001336 if (Results.includeCodePatterns()) {
1337 // if (condition) { statements }
1338 Pattern = new CodeCompletionString;
1339 Pattern->AddTypedTextChunk("if");
1340 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
1341 if (SemaRef.getLangOptions().CPlusPlus)
1342 Pattern->AddPlaceholderChunk("condition");
1343 else
1344 Pattern->AddPlaceholderChunk("expression");
1345 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
1346 Pattern->AddChunk(CodeCompletionString::CK_LeftBrace);
1347 Pattern->AddPlaceholderChunk("statements");
1348 Pattern->AddChunk(CodeCompletionString::CK_VerticalSpace);
1349 Pattern->AddChunk(CodeCompletionString::CK_RightBrace);
1350 Results.AddResult(Result(Pattern));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001351
Douglas Gregord8e8a582010-05-25 21:41:55 +00001352 // switch (condition) { }
1353 Pattern = new CodeCompletionString;
1354 Pattern->AddTypedTextChunk("switch");
1355 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
1356 if (SemaRef.getLangOptions().CPlusPlus)
1357 Pattern->AddPlaceholderChunk("condition");
1358 else
1359 Pattern->AddPlaceholderChunk("expression");
1360 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
1361 Pattern->AddChunk(CodeCompletionString::CK_LeftBrace);
1362 Pattern->AddChunk(CodeCompletionString::CK_VerticalSpace);
1363 Pattern->AddChunk(CodeCompletionString::CK_RightBrace);
1364 Results.AddResult(Result(Pattern));
1365 }
1366
Douglas Gregor01dfea02010-01-10 23:08:15 +00001367 // Switch-specific statements.
Douglas Gregorc8bddde2010-05-28 00:22:41 +00001368 if (!SemaRef.getSwitchStack().empty()) {
Douglas Gregor01dfea02010-01-10 23:08:15 +00001369 // case expression:
1370 Pattern = new CodeCompletionString;
1371 Pattern->AddTypedTextChunk("case");
Douglas Gregorc8bddde2010-05-28 00:22:41 +00001372 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
Douglas Gregor01dfea02010-01-10 23:08:15 +00001373 Pattern->AddPlaceholderChunk("expression");
1374 Pattern->AddChunk(CodeCompletionString::CK_Colon);
Douglas Gregora4477812010-01-14 16:01:26 +00001375 Results.AddResult(Result(Pattern));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001376
1377 // default:
1378 Pattern = new CodeCompletionString;
1379 Pattern->AddTypedTextChunk("default");
1380 Pattern->AddChunk(CodeCompletionString::CK_Colon);
Douglas Gregora4477812010-01-14 16:01:26 +00001381 Results.AddResult(Result(Pattern));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001382 }
1383
Douglas Gregord8e8a582010-05-25 21:41:55 +00001384 if (Results.includeCodePatterns()) {
1385 /// while (condition) { statements }
1386 Pattern = new CodeCompletionString;
1387 Pattern->AddTypedTextChunk("while");
1388 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
1389 if (SemaRef.getLangOptions().CPlusPlus)
1390 Pattern->AddPlaceholderChunk("condition");
1391 else
1392 Pattern->AddPlaceholderChunk("expression");
1393 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
1394 Pattern->AddChunk(CodeCompletionString::CK_LeftBrace);
1395 Pattern->AddPlaceholderChunk("statements");
1396 Pattern->AddChunk(CodeCompletionString::CK_VerticalSpace);
1397 Pattern->AddChunk(CodeCompletionString::CK_RightBrace);
1398 Results.AddResult(Result(Pattern));
1399
1400 // do { statements } while ( expression );
1401 Pattern = new CodeCompletionString;
1402 Pattern->AddTypedTextChunk("do");
1403 Pattern->AddChunk(CodeCompletionString::CK_LeftBrace);
1404 Pattern->AddPlaceholderChunk("statements");
1405 Pattern->AddChunk(CodeCompletionString::CK_VerticalSpace);
1406 Pattern->AddChunk(CodeCompletionString::CK_RightBrace);
1407 Pattern->AddTextChunk("while");
1408 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
Douglas Gregor01dfea02010-01-10 23:08:15 +00001409 Pattern->AddPlaceholderChunk("expression");
Douglas Gregord8e8a582010-05-25 21:41:55 +00001410 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
1411 Results.AddResult(Result(Pattern));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001412
Douglas Gregord8e8a582010-05-25 21:41:55 +00001413 // for ( for-init-statement ; condition ; expression ) { statements }
1414 Pattern = new CodeCompletionString;
1415 Pattern->AddTypedTextChunk("for");
1416 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
1417 if (SemaRef.getLangOptions().CPlusPlus || SemaRef.getLangOptions().C99)
1418 Pattern->AddPlaceholderChunk("init-statement");
1419 else
1420 Pattern->AddPlaceholderChunk("init-expression");
1421 Pattern->AddChunk(CodeCompletionString::CK_SemiColon);
1422 Pattern->AddPlaceholderChunk("condition");
1423 Pattern->AddChunk(CodeCompletionString::CK_SemiColon);
1424 Pattern->AddPlaceholderChunk("inc-expression");
1425 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
1426 Pattern->AddChunk(CodeCompletionString::CK_LeftBrace);
1427 Pattern->AddPlaceholderChunk("statements");
1428 Pattern->AddChunk(CodeCompletionString::CK_VerticalSpace);
1429 Pattern->AddChunk(CodeCompletionString::CK_RightBrace);
1430 Results.AddResult(Result(Pattern));
1431 }
Douglas Gregor01dfea02010-01-10 23:08:15 +00001432
1433 if (S->getContinueParent()) {
1434 // continue ;
1435 Pattern = new CodeCompletionString;
1436 Pattern->AddTypedTextChunk("continue");
Douglas Gregora4477812010-01-14 16:01:26 +00001437 Results.AddResult(Result(Pattern));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001438 }
1439
1440 if (S->getBreakParent()) {
1441 // break ;
1442 Pattern = new CodeCompletionString;
1443 Pattern->AddTypedTextChunk("break");
Douglas Gregora4477812010-01-14 16:01:26 +00001444 Results.AddResult(Result(Pattern));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001445 }
1446
1447 // "return expression ;" or "return ;", depending on whether we
1448 // know the function is void or not.
1449 bool isVoid = false;
1450 if (FunctionDecl *Function = dyn_cast<FunctionDecl>(SemaRef.CurContext))
1451 isVoid = Function->getResultType()->isVoidType();
1452 else if (ObjCMethodDecl *Method
1453 = dyn_cast<ObjCMethodDecl>(SemaRef.CurContext))
1454 isVoid = Method->getResultType()->isVoidType();
Douglas Gregor9ea9bdb2010-03-01 23:15:13 +00001455 else if (SemaRef.getCurBlock() &&
1456 !SemaRef.getCurBlock()->ReturnType.isNull())
1457 isVoid = SemaRef.getCurBlock()->ReturnType->isVoidType();
Douglas Gregor01dfea02010-01-10 23:08:15 +00001458 Pattern = new CodeCompletionString;
1459 Pattern->AddTypedTextChunk("return");
Douglas Gregor93298002010-02-18 04:06:48 +00001460 if (!isVoid) {
1461 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
Douglas Gregor01dfea02010-01-10 23:08:15 +00001462 Pattern->AddPlaceholderChunk("expression");
Douglas Gregor93298002010-02-18 04:06:48 +00001463 }
Douglas Gregora4477812010-01-14 16:01:26 +00001464 Results.AddResult(Result(Pattern));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001465
Douglas Gregorc8bddde2010-05-28 00:22:41 +00001466 // goto identifier ;
1467 Pattern = new CodeCompletionString;
1468 Pattern->AddTypedTextChunk("goto");
1469 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
1470 Pattern->AddPlaceholderChunk("label");
1471 Results.AddResult(Result(Pattern));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001472
Douglas Gregorc8bddde2010-05-28 00:22:41 +00001473 // Using directives
1474 Pattern = new CodeCompletionString;
1475 Pattern->AddTypedTextChunk("using");
1476 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
1477 Pattern->AddTextChunk("namespace");
1478 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
1479 Pattern->AddPlaceholderChunk("identifier");
1480 Results.AddResult(Result(Pattern));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001481 }
1482
1483 // Fall through (for statement expressions).
Douglas Gregore6b1bb62010-08-11 21:23:17 +00001484 case Action::PCC_ForInit:
1485 case Action::PCC_Condition:
Douglas Gregorbca403c2010-01-13 23:51:12 +00001486 AddStorageSpecifiers(CCC, SemaRef.getLangOptions(), Results);
Douglas Gregor01dfea02010-01-10 23:08:15 +00001487 // Fall through: conditions and statements can have expressions.
1488
Douglas Gregore6b1bb62010-08-11 21:23:17 +00001489 case Action::PCC_Expression: {
Douglas Gregor01dfea02010-01-10 23:08:15 +00001490 CodeCompletionString *Pattern = 0;
1491 if (SemaRef.getLangOptions().CPlusPlus) {
1492 // 'this', if we're in a non-static member function.
1493 if (CXXMethodDecl *Method = dyn_cast<CXXMethodDecl>(SemaRef.CurContext))
1494 if (!Method->isStatic())
Douglas Gregora4477812010-01-14 16:01:26 +00001495 Results.AddResult(Result("this"));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001496
1497 // true, false
Douglas Gregora4477812010-01-14 16:01:26 +00001498 Results.AddResult(Result("true"));
1499 Results.AddResult(Result("false"));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001500
Douglas Gregorc8bddde2010-05-28 00:22:41 +00001501 // dynamic_cast < type-id > ( expression )
1502 Pattern = new CodeCompletionString;
1503 Pattern->AddTypedTextChunk("dynamic_cast");
1504 Pattern->AddChunk(CodeCompletionString::CK_LeftAngle);
1505 Pattern->AddPlaceholderChunk("type");
1506 Pattern->AddChunk(CodeCompletionString::CK_RightAngle);
1507 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
1508 Pattern->AddPlaceholderChunk("expression");
1509 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
1510 Results.AddResult(Result(Pattern));
1511
1512 // static_cast < type-id > ( expression )
1513 Pattern = new CodeCompletionString;
1514 Pattern->AddTypedTextChunk("static_cast");
1515 Pattern->AddChunk(CodeCompletionString::CK_LeftAngle);
1516 Pattern->AddPlaceholderChunk("type");
1517 Pattern->AddChunk(CodeCompletionString::CK_RightAngle);
1518 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
1519 Pattern->AddPlaceholderChunk("expression");
1520 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
1521 Results.AddResult(Result(Pattern));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001522
Douglas Gregorc8bddde2010-05-28 00:22:41 +00001523 // reinterpret_cast < type-id > ( expression )
1524 Pattern = new CodeCompletionString;
1525 Pattern->AddTypedTextChunk("reinterpret_cast");
1526 Pattern->AddChunk(CodeCompletionString::CK_LeftAngle);
1527 Pattern->AddPlaceholderChunk("type");
1528 Pattern->AddChunk(CodeCompletionString::CK_RightAngle);
1529 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
1530 Pattern->AddPlaceholderChunk("expression");
1531 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
1532 Results.AddResult(Result(Pattern));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001533
Douglas Gregorc8bddde2010-05-28 00:22:41 +00001534 // const_cast < type-id > ( expression )
1535 Pattern = new CodeCompletionString;
1536 Pattern->AddTypedTextChunk("const_cast");
1537 Pattern->AddChunk(CodeCompletionString::CK_LeftAngle);
1538 Pattern->AddPlaceholderChunk("type");
1539 Pattern->AddChunk(CodeCompletionString::CK_RightAngle);
1540 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
1541 Pattern->AddPlaceholderChunk("expression");
1542 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
1543 Results.AddResult(Result(Pattern));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001544
Douglas Gregorc8bddde2010-05-28 00:22:41 +00001545 // typeid ( expression-or-type )
1546 Pattern = new CodeCompletionString;
1547 Pattern->AddTypedTextChunk("typeid");
1548 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
1549 Pattern->AddPlaceholderChunk("expression-or-type");
1550 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
1551 Results.AddResult(Result(Pattern));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001552
Douglas Gregorc8bddde2010-05-28 00:22:41 +00001553 // new T ( ... )
1554 Pattern = new CodeCompletionString;
1555 Pattern->AddTypedTextChunk("new");
1556 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
1557 Pattern->AddPlaceholderChunk("type");
1558 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
1559 Pattern->AddPlaceholderChunk("expressions");
1560 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
1561 Results.AddResult(Result(Pattern));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001562
Douglas Gregorc8bddde2010-05-28 00:22:41 +00001563 // new T [ ] ( ... )
1564 Pattern = new CodeCompletionString;
1565 Pattern->AddTypedTextChunk("new");
1566 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
1567 Pattern->AddPlaceholderChunk("type");
1568 Pattern->AddChunk(CodeCompletionString::CK_LeftBracket);
1569 Pattern->AddPlaceholderChunk("size");
1570 Pattern->AddChunk(CodeCompletionString::CK_RightBracket);
1571 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
1572 Pattern->AddPlaceholderChunk("expressions");
1573 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
1574 Results.AddResult(Result(Pattern));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001575
Douglas Gregorc8bddde2010-05-28 00:22:41 +00001576 // delete expression
1577 Pattern = new CodeCompletionString;
1578 Pattern->AddTypedTextChunk("delete");
1579 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
1580 Pattern->AddPlaceholderChunk("expression");
1581 Results.AddResult(Result(Pattern));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001582
Douglas Gregorc8bddde2010-05-28 00:22:41 +00001583 // delete [] expression
1584 Pattern = new CodeCompletionString;
1585 Pattern->AddTypedTextChunk("delete");
1586 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
1587 Pattern->AddChunk(CodeCompletionString::CK_LeftBracket);
1588 Pattern->AddChunk(CodeCompletionString::CK_RightBracket);
1589 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
1590 Pattern->AddPlaceholderChunk("expression");
1591 Results.AddResult(Result(Pattern));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001592
Douglas Gregorc8bddde2010-05-28 00:22:41 +00001593 // throw expression
1594 Pattern = new CodeCompletionString;
1595 Pattern->AddTypedTextChunk("throw");
1596 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
1597 Pattern->AddPlaceholderChunk("expression");
1598 Results.AddResult(Result(Pattern));
Douglas Gregor12e13132010-05-26 22:00:08 +00001599
1600 // FIXME: Rethrow?
Douglas Gregor01dfea02010-01-10 23:08:15 +00001601 }
1602
1603 if (SemaRef.getLangOptions().ObjC1) {
1604 // Add "super", if we're in an Objective-C class with a superclass.
Ted Kremenek681e2562010-05-31 21:43:10 +00001605 if (ObjCMethodDecl *Method = SemaRef.getCurMethodDecl()) {
1606 // The interface can be NULL.
1607 if (ObjCInterfaceDecl *ID = Method->getClassInterface())
1608 if (ID->getSuperClass())
1609 Results.AddResult(Result("super"));
1610 }
1611
Douglas Gregorbca403c2010-01-13 23:51:12 +00001612 AddObjCExpressionResults(Results, true);
Douglas Gregor01dfea02010-01-10 23:08:15 +00001613 }
1614
Douglas Gregorc8bddde2010-05-28 00:22:41 +00001615 // sizeof expression
1616 Pattern = new CodeCompletionString;
1617 Pattern->AddTypedTextChunk("sizeof");
1618 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
1619 Pattern->AddPlaceholderChunk("expression-or-type");
1620 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
1621 Results.AddResult(Result(Pattern));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001622 break;
1623 }
1624 }
1625
Douglas Gregor4710e5b2010-05-28 00:49:12 +00001626 if (WantTypesInContext(CCC, SemaRef.getLangOptions()))
1627 AddTypeSpecifierResults(SemaRef.getLangOptions(), Results);
Douglas Gregor01dfea02010-01-10 23:08:15 +00001628
1629 if (SemaRef.getLangOptions().CPlusPlus)
Douglas Gregora4477812010-01-14 16:01:26 +00001630 Results.AddResult(Result("operator"));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001631}
1632
Douglas Gregorff5ce6e2009-12-18 18:53:37 +00001633/// \brief If the given declaration has an associated type, add it as a result
1634/// type chunk.
1635static void AddResultTypeChunk(ASTContext &Context,
1636 NamedDecl *ND,
1637 CodeCompletionString *Result) {
1638 if (!ND)
1639 return;
1640
1641 // Determine the type of the declaration (if it has a type).
1642 QualType T;
1643 if (FunctionDecl *Function = dyn_cast<FunctionDecl>(ND))
1644 T = Function->getResultType();
1645 else if (ObjCMethodDecl *Method = dyn_cast<ObjCMethodDecl>(ND))
1646 T = Method->getResultType();
1647 else if (FunctionTemplateDecl *FunTmpl = dyn_cast<FunctionTemplateDecl>(ND))
1648 T = FunTmpl->getTemplatedDecl()->getResultType();
1649 else if (EnumConstantDecl *Enumerator = dyn_cast<EnumConstantDecl>(ND))
1650 T = Context.getTypeDeclType(cast<TypeDecl>(Enumerator->getDeclContext()));
1651 else if (isa<UnresolvedUsingValueDecl>(ND)) {
1652 /* Do nothing: ignore unresolved using declarations*/
1653 } else if (ValueDecl *Value = dyn_cast<ValueDecl>(ND))
1654 T = Value->getType();
1655 else if (ObjCPropertyDecl *Property = dyn_cast<ObjCPropertyDecl>(ND))
1656 T = Property->getType();
1657
1658 if (T.isNull() || Context.hasSameType(T, Context.DependentTy))
1659 return;
1660
Douglas Gregor84139d62010-04-05 21:25:31 +00001661 PrintingPolicy Policy(Context.PrintingPolicy);
1662 Policy.AnonymousTagLocations = false;
1663
Douglas Gregorff5ce6e2009-12-18 18:53:37 +00001664 std::string TypeStr;
Douglas Gregor84139d62010-04-05 21:25:31 +00001665 T.getAsStringInternal(TypeStr, Policy);
Douglas Gregorff5ce6e2009-12-18 18:53:37 +00001666 Result->AddResultTypeChunk(TypeStr);
1667}
1668
Douglas Gregor86d9a522009-09-21 16:56:56 +00001669/// \brief Add function parameter chunks to the given code completion string.
1670static void AddFunctionParameterChunks(ASTContext &Context,
1671 FunctionDecl *Function,
1672 CodeCompletionString *Result) {
Douglas Gregor0c8296d2009-11-07 00:00:49 +00001673 typedef CodeCompletionString::Chunk Chunk;
1674
Douglas Gregor86d9a522009-09-21 16:56:56 +00001675 CodeCompletionString *CCStr = Result;
1676
1677 for (unsigned P = 0, N = Function->getNumParams(); P != N; ++P) {
1678 ParmVarDecl *Param = Function->getParamDecl(P);
1679
1680 if (Param->hasDefaultArg()) {
1681 // When we see an optional default argument, put that argument and
1682 // the remaining default arguments into a new, optional string.
1683 CodeCompletionString *Opt = new CodeCompletionString;
1684 CCStr->AddOptionalChunk(std::auto_ptr<CodeCompletionString>(Opt));
1685 CCStr = Opt;
1686 }
1687
1688 if (P != 0)
Douglas Gregor0c8296d2009-11-07 00:00:49 +00001689 CCStr->AddChunk(Chunk(CodeCompletionString::CK_Comma));
Douglas Gregor86d9a522009-09-21 16:56:56 +00001690
1691 // Format the placeholder string.
1692 std::string PlaceholderStr;
1693 if (Param->getIdentifier())
1694 PlaceholderStr = Param->getIdentifier()->getName();
1695
1696 Param->getType().getAsStringInternal(PlaceholderStr,
1697 Context.PrintingPolicy);
1698
1699 // Add the placeholder string.
Benjamin Kramer660cc182009-11-29 20:18:50 +00001700 CCStr->AddPlaceholderChunk(PlaceholderStr);
Douglas Gregor86d9a522009-09-21 16:56:56 +00001701 }
Douglas Gregorb3d45252009-09-22 21:42:17 +00001702
1703 if (const FunctionProtoType *Proto
1704 = Function->getType()->getAs<FunctionProtoType>())
1705 if (Proto->isVariadic())
1706 CCStr->AddPlaceholderChunk(", ...");
Douglas Gregor86d9a522009-09-21 16:56:56 +00001707}
1708
1709/// \brief Add template parameter chunks to the given code completion string.
1710static void AddTemplateParameterChunks(ASTContext &Context,
1711 TemplateDecl *Template,
1712 CodeCompletionString *Result,
1713 unsigned MaxParameters = 0) {
Douglas Gregor0c8296d2009-11-07 00:00:49 +00001714 typedef CodeCompletionString::Chunk Chunk;
1715
Douglas Gregor86d9a522009-09-21 16:56:56 +00001716 CodeCompletionString *CCStr = Result;
1717 bool FirstParameter = true;
1718
1719 TemplateParameterList *Params = Template->getTemplateParameters();
1720 TemplateParameterList::iterator PEnd = Params->end();
1721 if (MaxParameters)
1722 PEnd = Params->begin() + MaxParameters;
1723 for (TemplateParameterList::iterator P = Params->begin(); P != PEnd; ++P) {
1724 bool HasDefaultArg = false;
1725 std::string PlaceholderStr;
1726 if (TemplateTypeParmDecl *TTP = dyn_cast<TemplateTypeParmDecl>(*P)) {
1727 if (TTP->wasDeclaredWithTypename())
1728 PlaceholderStr = "typename";
1729 else
1730 PlaceholderStr = "class";
1731
1732 if (TTP->getIdentifier()) {
1733 PlaceholderStr += ' ';
1734 PlaceholderStr += TTP->getIdentifier()->getName();
1735 }
1736
1737 HasDefaultArg = TTP->hasDefaultArgument();
1738 } else if (NonTypeTemplateParmDecl *NTTP
1739 = dyn_cast<NonTypeTemplateParmDecl>(*P)) {
1740 if (NTTP->getIdentifier())
1741 PlaceholderStr = NTTP->getIdentifier()->getName();
1742 NTTP->getType().getAsStringInternal(PlaceholderStr,
1743 Context.PrintingPolicy);
1744 HasDefaultArg = NTTP->hasDefaultArgument();
1745 } else {
1746 assert(isa<TemplateTemplateParmDecl>(*P));
1747 TemplateTemplateParmDecl *TTP = cast<TemplateTemplateParmDecl>(*P);
1748
1749 // Since putting the template argument list into the placeholder would
1750 // be very, very long, we just use an abbreviation.
1751 PlaceholderStr = "template<...> class";
1752 if (TTP->getIdentifier()) {
1753 PlaceholderStr += ' ';
1754 PlaceholderStr += TTP->getIdentifier()->getName();
1755 }
1756
1757 HasDefaultArg = TTP->hasDefaultArgument();
1758 }
1759
1760 if (HasDefaultArg) {
1761 // When we see an optional default argument, put that argument and
1762 // the remaining default arguments into a new, optional string.
1763 CodeCompletionString *Opt = new CodeCompletionString;
1764 CCStr->AddOptionalChunk(std::auto_ptr<CodeCompletionString>(Opt));
1765 CCStr = Opt;
1766 }
1767
1768 if (FirstParameter)
1769 FirstParameter = false;
1770 else
Douglas Gregor0c8296d2009-11-07 00:00:49 +00001771 CCStr->AddChunk(Chunk(CodeCompletionString::CK_Comma));
Douglas Gregor86d9a522009-09-21 16:56:56 +00001772
1773 // Add the placeholder string.
Benjamin Kramer660cc182009-11-29 20:18:50 +00001774 CCStr->AddPlaceholderChunk(PlaceholderStr);
Douglas Gregor86d9a522009-09-21 16:56:56 +00001775 }
1776}
1777
Douglas Gregorb9d0ef72009-09-21 19:57:38 +00001778/// \brief Add a qualifier to the given code-completion string, if the
1779/// provided nested-name-specifier is non-NULL.
Douglas Gregora61a8792009-12-11 18:44:16 +00001780static void
1781AddQualifierToCompletionString(CodeCompletionString *Result,
1782 NestedNameSpecifier *Qualifier,
1783 bool QualifierIsInformative,
1784 ASTContext &Context) {
Douglas Gregorb9d0ef72009-09-21 19:57:38 +00001785 if (!Qualifier)
1786 return;
1787
1788 std::string PrintedNNS;
1789 {
1790 llvm::raw_string_ostream OS(PrintedNNS);
1791 Qualifier->print(OS, Context.PrintingPolicy);
1792 }
Douglas Gregor0563c262009-09-22 23:15:58 +00001793 if (QualifierIsInformative)
Benjamin Kramer660cc182009-11-29 20:18:50 +00001794 Result->AddInformativeChunk(PrintedNNS);
Douglas Gregor0563c262009-09-22 23:15:58 +00001795 else
Benjamin Kramer660cc182009-11-29 20:18:50 +00001796 Result->AddTextChunk(PrintedNNS);
Douglas Gregorb9d0ef72009-09-21 19:57:38 +00001797}
1798
Douglas Gregora61a8792009-12-11 18:44:16 +00001799static void AddFunctionTypeQualsToCompletionString(CodeCompletionString *Result,
1800 FunctionDecl *Function) {
1801 const FunctionProtoType *Proto
1802 = Function->getType()->getAs<FunctionProtoType>();
1803 if (!Proto || !Proto->getTypeQuals())
1804 return;
1805
1806 std::string QualsStr;
1807 if (Proto->getTypeQuals() & Qualifiers::Const)
1808 QualsStr += " const";
1809 if (Proto->getTypeQuals() & Qualifiers::Volatile)
1810 QualsStr += " volatile";
1811 if (Proto->getTypeQuals() & Qualifiers::Restrict)
1812 QualsStr += " restrict";
1813 Result->AddInformativeChunk(QualsStr);
1814}
1815
Douglas Gregor86d9a522009-09-21 16:56:56 +00001816/// \brief If possible, create a new code completion string for the given
1817/// result.
1818///
1819/// \returns Either a new, heap-allocated code completion string describing
1820/// how to use this result, or NULL to indicate that the string or name of the
1821/// result is all that is needed.
1822CodeCompletionString *
Douglas Gregor1abc6bc2010-08-04 16:47:14 +00001823CodeCompleteConsumer::Result::CreateCodeCompletionString(Sema &S,
1824 CodeCompletionString *Result) {
Douglas Gregor0c8296d2009-11-07 00:00:49 +00001825 typedef CodeCompletionString::Chunk Chunk;
1826
Douglas Gregor2b4074f2009-12-01 05:55:20 +00001827 if (Kind == RK_Pattern)
Douglas Gregor1abc6bc2010-08-04 16:47:14 +00001828 return Pattern->Clone(Result);
Douglas Gregor2b4074f2009-12-01 05:55:20 +00001829
Douglas Gregor1abc6bc2010-08-04 16:47:14 +00001830 if (!Result)
1831 Result = new CodeCompletionString;
Douglas Gregor2b4074f2009-12-01 05:55:20 +00001832
1833 if (Kind == RK_Keyword) {
1834 Result->AddTypedTextChunk(Keyword);
1835 return Result;
1836 }
Douglas Gregor86d9a522009-09-21 16:56:56 +00001837
Douglas Gregor3f7c7f42009-10-30 16:50:04 +00001838 if (Kind == RK_Macro) {
1839 MacroInfo *MI = S.PP.getMacroInfo(Macro);
Douglas Gregor2b4074f2009-12-01 05:55:20 +00001840 assert(MI && "Not a macro?");
1841
1842 Result->AddTypedTextChunk(Macro->getName());
1843
1844 if (!MI->isFunctionLike())
1845 return Result;
Douglas Gregor3f7c7f42009-10-30 16:50:04 +00001846
1847 // Format a function-like macro with placeholders for the arguments.
Douglas Gregor0c8296d2009-11-07 00:00:49 +00001848 Result->AddChunk(Chunk(CodeCompletionString::CK_LeftParen));
Douglas Gregor3f7c7f42009-10-30 16:50:04 +00001849 for (MacroInfo::arg_iterator A = MI->arg_begin(), AEnd = MI->arg_end();
1850 A != AEnd; ++A) {
1851 if (A != MI->arg_begin())
Douglas Gregor0c8296d2009-11-07 00:00:49 +00001852 Result->AddChunk(Chunk(CodeCompletionString::CK_Comma));
Douglas Gregor3f7c7f42009-10-30 16:50:04 +00001853
1854 if (!MI->isVariadic() || A != AEnd - 1) {
1855 // Non-variadic argument.
Benjamin Kramer660cc182009-11-29 20:18:50 +00001856 Result->AddPlaceholderChunk((*A)->getName());
Douglas Gregor3f7c7f42009-10-30 16:50:04 +00001857 continue;
1858 }
1859
1860 // Variadic argument; cope with the different between GNU and C99
1861 // variadic macros, providing a single placeholder for the rest of the
1862 // arguments.
1863 if ((*A)->isStr("__VA_ARGS__"))
1864 Result->AddPlaceholderChunk("...");
1865 else {
1866 std::string Arg = (*A)->getName();
1867 Arg += "...";
Benjamin Kramer660cc182009-11-29 20:18:50 +00001868 Result->AddPlaceholderChunk(Arg);
Douglas Gregor3f7c7f42009-10-30 16:50:04 +00001869 }
1870 }
Douglas Gregor0c8296d2009-11-07 00:00:49 +00001871 Result->AddChunk(Chunk(CodeCompletionString::CK_RightParen));
Douglas Gregor3f7c7f42009-10-30 16:50:04 +00001872 return Result;
1873 }
1874
Douglas Gregord8e8a582010-05-25 21:41:55 +00001875 assert(Kind == RK_Declaration && "Missed a result kind?");
Douglas Gregor86d9a522009-09-21 16:56:56 +00001876 NamedDecl *ND = Declaration;
1877
Douglas Gregor0c8296d2009-11-07 00:00:49 +00001878 if (StartsNestedNameSpecifier) {
Benjamin Kramer660cc182009-11-29 20:18:50 +00001879 Result->AddTypedTextChunk(ND->getNameAsString());
Douglas Gregor0c8296d2009-11-07 00:00:49 +00001880 Result->AddTextChunk("::");
1881 return Result;
1882 }
1883
Douglas Gregorff5ce6e2009-12-18 18:53:37 +00001884 AddResultTypeChunk(S.Context, ND, Result);
1885
Douglas Gregor86d9a522009-09-21 16:56:56 +00001886 if (FunctionDecl *Function = dyn_cast<FunctionDecl>(ND)) {
Douglas Gregor0563c262009-09-22 23:15:58 +00001887 AddQualifierToCompletionString(Result, Qualifier, QualifierIsInformative,
1888 S.Context);
Benjamin Kramer660cc182009-11-29 20:18:50 +00001889 Result->AddTypedTextChunk(Function->getNameAsString());
Douglas Gregor0c8296d2009-11-07 00:00:49 +00001890 Result->AddChunk(Chunk(CodeCompletionString::CK_LeftParen));
Douglas Gregor86d9a522009-09-21 16:56:56 +00001891 AddFunctionParameterChunks(S.Context, Function, Result);
Douglas Gregor0c8296d2009-11-07 00:00:49 +00001892 Result->AddChunk(Chunk(CodeCompletionString::CK_RightParen));
Douglas Gregora61a8792009-12-11 18:44:16 +00001893 AddFunctionTypeQualsToCompletionString(Result, Function);
Douglas Gregor86d9a522009-09-21 16:56:56 +00001894 return Result;
1895 }
1896
1897 if (FunctionTemplateDecl *FunTmpl = dyn_cast<FunctionTemplateDecl>(ND)) {
Douglas Gregor0563c262009-09-22 23:15:58 +00001898 AddQualifierToCompletionString(Result, Qualifier, QualifierIsInformative,
1899 S.Context);
Douglas Gregor86d9a522009-09-21 16:56:56 +00001900 FunctionDecl *Function = FunTmpl->getTemplatedDecl();
Benjamin Kramer660cc182009-11-29 20:18:50 +00001901 Result->AddTypedTextChunk(Function->getNameAsString());
Douglas Gregor86d9a522009-09-21 16:56:56 +00001902
1903 // Figure out which template parameters are deduced (or have default
1904 // arguments).
1905 llvm::SmallVector<bool, 16> Deduced;
1906 S.MarkDeducedTemplateParameters(FunTmpl, Deduced);
1907 unsigned LastDeducibleArgument;
1908 for (LastDeducibleArgument = Deduced.size(); LastDeducibleArgument > 0;
1909 --LastDeducibleArgument) {
1910 if (!Deduced[LastDeducibleArgument - 1]) {
1911 // C++0x: Figure out if the template argument has a default. If so,
1912 // the user doesn't need to type this argument.
1913 // FIXME: We need to abstract template parameters better!
1914 bool HasDefaultArg = false;
1915 NamedDecl *Param = FunTmpl->getTemplateParameters()->getParam(
1916 LastDeducibleArgument - 1);
1917 if (TemplateTypeParmDecl *TTP = dyn_cast<TemplateTypeParmDecl>(Param))
1918 HasDefaultArg = TTP->hasDefaultArgument();
1919 else if (NonTypeTemplateParmDecl *NTTP
1920 = dyn_cast<NonTypeTemplateParmDecl>(Param))
1921 HasDefaultArg = NTTP->hasDefaultArgument();
1922 else {
1923 assert(isa<TemplateTemplateParmDecl>(Param));
1924 HasDefaultArg
Douglas Gregor0c8296d2009-11-07 00:00:49 +00001925 = cast<TemplateTemplateParmDecl>(Param)->hasDefaultArgument();
Douglas Gregor86d9a522009-09-21 16:56:56 +00001926 }
1927
1928 if (!HasDefaultArg)
1929 break;
1930 }
1931 }
1932
1933 if (LastDeducibleArgument) {
1934 // Some of the function template arguments cannot be deduced from a
1935 // function call, so we introduce an explicit template argument list
1936 // containing all of the arguments up to the first deducible argument.
Douglas Gregor0c8296d2009-11-07 00:00:49 +00001937 Result->AddChunk(Chunk(CodeCompletionString::CK_LeftAngle));
Douglas Gregor86d9a522009-09-21 16:56:56 +00001938 AddTemplateParameterChunks(S.Context, FunTmpl, Result,
1939 LastDeducibleArgument);
Douglas Gregor0c8296d2009-11-07 00:00:49 +00001940 Result->AddChunk(Chunk(CodeCompletionString::CK_RightAngle));
Douglas Gregor86d9a522009-09-21 16:56:56 +00001941 }
1942
1943 // Add the function parameters
Douglas Gregor0c8296d2009-11-07 00:00:49 +00001944 Result->AddChunk(Chunk(CodeCompletionString::CK_LeftParen));
Douglas Gregor86d9a522009-09-21 16:56:56 +00001945 AddFunctionParameterChunks(S.Context, Function, Result);
Douglas Gregor0c8296d2009-11-07 00:00:49 +00001946 Result->AddChunk(Chunk(CodeCompletionString::CK_RightParen));
Douglas Gregora61a8792009-12-11 18:44:16 +00001947 AddFunctionTypeQualsToCompletionString(Result, Function);
Douglas Gregor86d9a522009-09-21 16:56:56 +00001948 return Result;
1949 }
1950
1951 if (TemplateDecl *Template = dyn_cast<TemplateDecl>(ND)) {
Douglas Gregor0563c262009-09-22 23:15:58 +00001952 AddQualifierToCompletionString(Result, Qualifier, QualifierIsInformative,
1953 S.Context);
Benjamin Kramer660cc182009-11-29 20:18:50 +00001954 Result->AddTypedTextChunk(Template->getNameAsString());
Douglas Gregor0c8296d2009-11-07 00:00:49 +00001955 Result->AddChunk(Chunk(CodeCompletionString::CK_LeftAngle));
Douglas Gregor86d9a522009-09-21 16:56:56 +00001956 AddTemplateParameterChunks(S.Context, Template, Result);
Douglas Gregor0c8296d2009-11-07 00:00:49 +00001957 Result->AddChunk(Chunk(CodeCompletionString::CK_RightAngle));
Douglas Gregor86d9a522009-09-21 16:56:56 +00001958 return Result;
1959 }
1960
Douglas Gregor9630eb62009-11-17 16:44:22 +00001961 if (ObjCMethodDecl *Method = dyn_cast<ObjCMethodDecl>(ND)) {
Douglas Gregor9630eb62009-11-17 16:44:22 +00001962 Selector Sel = Method->getSelector();
1963 if (Sel.isUnarySelector()) {
1964 Result->AddTypedTextChunk(Sel.getIdentifierInfoForSlot(0)->getName());
1965 return Result;
1966 }
1967
Douglas Gregord3c68542009-11-19 01:08:35 +00001968 std::string SelName = Sel.getIdentifierInfoForSlot(0)->getName().str();
1969 SelName += ':';
1970 if (StartParameter == 0)
1971 Result->AddTypedTextChunk(SelName);
1972 else {
1973 Result->AddInformativeChunk(SelName);
1974
1975 // If there is only one parameter, and we're past it, add an empty
1976 // typed-text chunk since there is nothing to type.
1977 if (Method->param_size() == 1)
1978 Result->AddTypedTextChunk("");
1979 }
Douglas Gregor9630eb62009-11-17 16:44:22 +00001980 unsigned Idx = 0;
1981 for (ObjCMethodDecl::param_iterator P = Method->param_begin(),
1982 PEnd = Method->param_end();
1983 P != PEnd; (void)++P, ++Idx) {
1984 if (Idx > 0) {
Douglas Gregord3c68542009-11-19 01:08:35 +00001985 std::string Keyword;
1986 if (Idx > StartParameter)
Douglas Gregor834389b2010-01-12 06:38:28 +00001987 Result->AddChunk(CodeCompletionString::CK_HorizontalSpace);
Douglas Gregor9630eb62009-11-17 16:44:22 +00001988 if (IdentifierInfo *II = Sel.getIdentifierInfoForSlot(Idx))
1989 Keyword += II->getName().str();
1990 Keyword += ":";
Douglas Gregor1f5537a2010-07-08 23:20:03 +00001991 if (Idx < StartParameter || AllParametersAreInformative)
Douglas Gregord3c68542009-11-19 01:08:35 +00001992 Result->AddInformativeChunk(Keyword);
Douglas Gregor1f5537a2010-07-08 23:20:03 +00001993 else if (Idx == StartParameter)
Douglas Gregord3c68542009-11-19 01:08:35 +00001994 Result->AddTypedTextChunk(Keyword);
1995 else
1996 Result->AddTextChunk(Keyword);
Douglas Gregor9630eb62009-11-17 16:44:22 +00001997 }
Douglas Gregord3c68542009-11-19 01:08:35 +00001998
1999 // If we're before the starting parameter, skip the placeholder.
2000 if (Idx < StartParameter)
2001 continue;
Douglas Gregor9630eb62009-11-17 16:44:22 +00002002
2003 std::string Arg;
2004 (*P)->getType().getAsStringInternal(Arg, S.Context.PrintingPolicy);
2005 Arg = "(" + Arg + ")";
2006 if (IdentifierInfo *II = (*P)->getIdentifier())
2007 Arg += II->getName().str();
Douglas Gregor1f5537a2010-07-08 23:20:03 +00002008 if (DeclaringEntity)
2009 Result->AddTextChunk(Arg);
2010 else if (AllParametersAreInformative)
Douglas Gregor4ad96852009-11-19 07:41:15 +00002011 Result->AddInformativeChunk(Arg);
2012 else
2013 Result->AddPlaceholderChunk(Arg);
Douglas Gregor9630eb62009-11-17 16:44:22 +00002014 }
2015
Douglas Gregor2a17af02009-12-23 00:21:46 +00002016 if (Method->isVariadic()) {
Douglas Gregor1f5537a2010-07-08 23:20:03 +00002017 if (DeclaringEntity)
2018 Result->AddTextChunk(", ...");
2019 else if (AllParametersAreInformative)
Douglas Gregor2a17af02009-12-23 00:21:46 +00002020 Result->AddInformativeChunk(", ...");
2021 else
2022 Result->AddPlaceholderChunk(", ...");
2023 }
2024
Douglas Gregor9630eb62009-11-17 16:44:22 +00002025 return Result;
2026 }
2027
Douglas Gregor2b4074f2009-12-01 05:55:20 +00002028 if (Qualifier)
Douglas Gregor0563c262009-09-22 23:15:58 +00002029 AddQualifierToCompletionString(Result, Qualifier, QualifierIsInformative,
2030 S.Context);
Douglas Gregor2b4074f2009-12-01 05:55:20 +00002031
2032 Result->AddTypedTextChunk(ND->getNameAsString());
2033 return Result;
Douglas Gregor86d9a522009-09-21 16:56:56 +00002034}
2035
Douglas Gregor86d802e2009-09-23 00:34:09 +00002036CodeCompletionString *
2037CodeCompleteConsumer::OverloadCandidate::CreateSignatureString(
2038 unsigned CurrentArg,
2039 Sema &S) const {
Douglas Gregor0c8296d2009-11-07 00:00:49 +00002040 typedef CodeCompletionString::Chunk Chunk;
2041
Douglas Gregor86d802e2009-09-23 00:34:09 +00002042 CodeCompletionString *Result = new CodeCompletionString;
2043 FunctionDecl *FDecl = getFunction();
Douglas Gregorff5ce6e2009-12-18 18:53:37 +00002044 AddResultTypeChunk(S.Context, FDecl, Result);
Douglas Gregor86d802e2009-09-23 00:34:09 +00002045 const FunctionProtoType *Proto
2046 = dyn_cast<FunctionProtoType>(getFunctionType());
2047 if (!FDecl && !Proto) {
2048 // Function without a prototype. Just give the return type and a
2049 // highlighted ellipsis.
2050 const FunctionType *FT = getFunctionType();
2051 Result->AddTextChunk(
Benjamin Kramer660cc182009-11-29 20:18:50 +00002052 FT->getResultType().getAsString(S.Context.PrintingPolicy));
Douglas Gregor0c8296d2009-11-07 00:00:49 +00002053 Result->AddChunk(Chunk(CodeCompletionString::CK_LeftParen));
2054 Result->AddChunk(Chunk(CodeCompletionString::CK_CurrentParameter, "..."));
2055 Result->AddChunk(Chunk(CodeCompletionString::CK_RightParen));
Douglas Gregor86d802e2009-09-23 00:34:09 +00002056 return Result;
2057 }
2058
2059 if (FDecl)
Benjamin Kramer660cc182009-11-29 20:18:50 +00002060 Result->AddTextChunk(FDecl->getNameAsString());
Douglas Gregor86d802e2009-09-23 00:34:09 +00002061 else
2062 Result->AddTextChunk(
Benjamin Kramer660cc182009-11-29 20:18:50 +00002063 Proto->getResultType().getAsString(S.Context.PrintingPolicy));
Douglas Gregor86d802e2009-09-23 00:34:09 +00002064
Douglas Gregor0c8296d2009-11-07 00:00:49 +00002065 Result->AddChunk(Chunk(CodeCompletionString::CK_LeftParen));
Douglas Gregor86d802e2009-09-23 00:34:09 +00002066 unsigned NumParams = FDecl? FDecl->getNumParams() : Proto->getNumArgs();
2067 for (unsigned I = 0; I != NumParams; ++I) {
2068 if (I)
Douglas Gregor0c8296d2009-11-07 00:00:49 +00002069 Result->AddChunk(Chunk(CodeCompletionString::CK_Comma));
Douglas Gregor86d802e2009-09-23 00:34:09 +00002070
2071 std::string ArgString;
2072 QualType ArgType;
2073
2074 if (FDecl) {
2075 ArgString = FDecl->getParamDecl(I)->getNameAsString();
2076 ArgType = FDecl->getParamDecl(I)->getOriginalType();
2077 } else {
2078 ArgType = Proto->getArgType(I);
2079 }
2080
2081 ArgType.getAsStringInternal(ArgString, S.Context.PrintingPolicy);
2082
2083 if (I == CurrentArg)
Douglas Gregor0c8296d2009-11-07 00:00:49 +00002084 Result->AddChunk(Chunk(CodeCompletionString::CK_CurrentParameter,
Benjamin Kramer660cc182009-11-29 20:18:50 +00002085 ArgString));
Douglas Gregor86d802e2009-09-23 00:34:09 +00002086 else
Benjamin Kramer660cc182009-11-29 20:18:50 +00002087 Result->AddTextChunk(ArgString);
Douglas Gregor86d802e2009-09-23 00:34:09 +00002088 }
2089
2090 if (Proto && Proto->isVariadic()) {
Douglas Gregor0c8296d2009-11-07 00:00:49 +00002091 Result->AddChunk(Chunk(CodeCompletionString::CK_Comma));
Douglas Gregor86d802e2009-09-23 00:34:09 +00002092 if (CurrentArg < NumParams)
2093 Result->AddTextChunk("...");
2094 else
Douglas Gregor0c8296d2009-11-07 00:00:49 +00002095 Result->AddChunk(Chunk(CodeCompletionString::CK_CurrentParameter, "..."));
Douglas Gregor86d802e2009-09-23 00:34:09 +00002096 }
Douglas Gregor0c8296d2009-11-07 00:00:49 +00002097 Result->AddChunk(Chunk(CodeCompletionString::CK_RightParen));
Douglas Gregor86d802e2009-09-23 00:34:09 +00002098
2099 return Result;
2100}
2101
Douglas Gregor86d9a522009-09-21 16:56:56 +00002102namespace {
2103 struct SortCodeCompleteResult {
2104 typedef CodeCompleteConsumer::Result Result;
2105
Douglas Gregorab0b4f12010-01-13 23:24:38 +00002106 /// \brief Retrieve the name that should be used to order a result.
2107 ///
2108 /// If the name needs to be constructed as a string, that string will be
2109 /// saved into Saved and the returned StringRef will refer to it.
2110 static llvm::StringRef getOrderedName(const Result &R,
2111 std::string &Saved) {
2112 switch (R.Kind) {
2113 case Result::RK_Keyword:
2114 return R.Keyword;
2115
2116 case Result::RK_Pattern:
2117 return R.Pattern->getTypedText();
2118
2119 case Result::RK_Macro:
2120 return R.Macro->getName();
2121
2122 case Result::RK_Declaration:
2123 // Handle declarations below.
2124 break;
Douglas Gregor54f01612009-11-19 00:01:57 +00002125 }
Douglas Gregorab0b4f12010-01-13 23:24:38 +00002126
2127 DeclarationName Name = R.Declaration->getDeclName();
Douglas Gregor54f01612009-11-19 00:01:57 +00002128
Douglas Gregorab0b4f12010-01-13 23:24:38 +00002129 // If the name is a simple identifier (by far the common case), or a
2130 // zero-argument selector, just return a reference to that identifier.
2131 if (IdentifierInfo *Id = Name.getAsIdentifierInfo())
2132 return Id->getName();
2133 if (Name.isObjCZeroArgSelector())
2134 if (IdentifierInfo *Id
2135 = Name.getObjCSelector().getIdentifierInfoForSlot(0))
2136 return Id->getName();
2137
2138 Saved = Name.getAsString();
2139 return Saved;
2140 }
2141
2142 bool operator()(const Result &X, const Result &Y) const {
2143 std::string XSaved, YSaved;
2144 llvm::StringRef XStr = getOrderedName(X, XSaved);
2145 llvm::StringRef YStr = getOrderedName(Y, YSaved);
2146 int cmp = XStr.compare_lower(YStr);
2147 if (cmp)
2148 return cmp < 0;
Douglas Gregor86d9a522009-09-21 16:56:56 +00002149
2150 // Non-hidden names precede hidden names.
2151 if (X.Hidden != Y.Hidden)
2152 return !X.Hidden;
2153
Douglas Gregoreb5758b2009-09-23 22:26:46 +00002154 // Non-nested-name-specifiers precede nested-name-specifiers.
2155 if (X.StartsNestedNameSpecifier != Y.StartsNestedNameSpecifier)
2156 return !X.StartsNestedNameSpecifier;
2157
Douglas Gregor86d9a522009-09-21 16:56:56 +00002158 return false;
2159 }
2160 };
2161}
2162
Douglas Gregor1827e102010-08-16 16:18:59 +00002163unsigned clang::getMacroUsagePriority(llvm::StringRef MacroName,
2164 bool PreferredTypeIsPointer) {
2165 unsigned Priority = CCP_Macro;
2166
2167 // Treat the "nil" and "NULL" macros as null pointer constants.
2168 if (MacroName.equals("nil") || MacroName.equals("NULL")) {
2169 Priority = CCP_Constant;
2170 if (PreferredTypeIsPointer)
2171 Priority = Priority / CCF_SimilarTypeMatch;
2172 }
2173
2174 return Priority;
2175}
2176
Douglas Gregor590c7d52010-07-08 20:55:51 +00002177static void AddMacroResults(Preprocessor &PP, ResultBuilder &Results,
2178 bool TargetTypeIsPointer = false) {
2179 typedef CodeCompleteConsumer::Result Result;
2180
Douglas Gregor3f7c7f42009-10-30 16:50:04 +00002181 Results.EnterNewScope();
Douglas Gregor0c8296d2009-11-07 00:00:49 +00002182 for (Preprocessor::macro_iterator M = PP.macro_begin(),
2183 MEnd = PP.macro_end();
Douglas Gregor590c7d52010-07-08 20:55:51 +00002184 M != MEnd; ++M) {
Douglas Gregor1827e102010-08-16 16:18:59 +00002185 Results.AddResult(Result(M->first,
2186 getMacroUsagePriority(M->first->getName(),
2187 TargetTypeIsPointer)));
Douglas Gregor590c7d52010-07-08 20:55:51 +00002188 }
Douglas Gregor3f7c7f42009-10-30 16:50:04 +00002189 Results.ExitScope();
2190}
2191
Daniel Dunbar3a2838d2009-11-13 08:58:20 +00002192static void HandleCodeCompleteResults(Sema *S,
2193 CodeCompleteConsumer *CodeCompleter,
Douglas Gregore6b1bb62010-08-11 21:23:17 +00002194 CodeCompletionContext Context,
2195 CodeCompleteConsumer::Result *Results,
2196 unsigned NumResults) {
Douglas Gregor86d9a522009-09-21 16:56:56 +00002197 std::stable_sort(Results, Results + NumResults, SortCodeCompleteResult());
2198
2199 if (CodeCompleter)
Douglas Gregore6b1bb62010-08-11 21:23:17 +00002200 CodeCompleter->ProcessCodeCompleteResults(*S, Context, Results, NumResults);
Douglas Gregor54f01612009-11-19 00:01:57 +00002201
2202 for (unsigned I = 0; I != NumResults; ++I)
2203 Results[I].Destroy();
Douglas Gregor86d9a522009-09-21 16:56:56 +00002204}
2205
Douglas Gregore6b1bb62010-08-11 21:23:17 +00002206static enum CodeCompletionContext::Kind mapCodeCompletionContext(Sema &S,
2207 Sema::ParserCompletionContext PCC) {
2208 switch (PCC) {
2209 case Action::PCC_Namespace:
2210 return CodeCompletionContext::CCC_TopLevel;
2211
2212 case Action::PCC_Class:
2213 return CodeCompletionContext::CCC_ClassStructUnion;
2214
2215 case Action::PCC_ObjCInterface:
2216 return CodeCompletionContext::CCC_ObjCInterface;
2217
2218 case Action::PCC_ObjCImplementation:
2219 return CodeCompletionContext::CCC_ObjCImplementation;
2220
2221 case Action::PCC_ObjCInstanceVariableList:
2222 return CodeCompletionContext::CCC_ObjCIvarList;
2223
2224 case Action::PCC_Template:
2225 case Action::PCC_MemberTemplate:
2226 case Action::PCC_RecoveryInFunction:
2227 return CodeCompletionContext::CCC_Other;
2228
2229 case Action::PCC_Expression:
2230 case Action::PCC_ForInit:
2231 case Action::PCC_Condition:
2232 return CodeCompletionContext::CCC_Expression;
2233
2234 case Action::PCC_Statement:
2235 return CodeCompletionContext::CCC_Statement;
2236 }
2237
2238 return CodeCompletionContext::CCC_Other;
2239}
2240
Douglas Gregor01dfea02010-01-10 23:08:15 +00002241void Sema::CodeCompleteOrdinaryName(Scope *S,
Douglas Gregore6b1bb62010-08-11 21:23:17 +00002242 ParserCompletionContext CompletionContext) {
Douglas Gregor2a7925c2009-12-07 09:54:55 +00002243 typedef CodeCompleteConsumer::Result Result;
Douglas Gregor2ccccb32010-08-23 18:23:48 +00002244 ResultBuilder Results(*this);
Douglas Gregor01dfea02010-01-10 23:08:15 +00002245
2246 // Determine how to filter results, e.g., so that the names of
2247 // values (functions, enumerators, function templates, etc.) are
2248 // only allowed where we can have an expression.
2249 switch (CompletionContext) {
Douglas Gregore6b1bb62010-08-11 21:23:17 +00002250 case PCC_Namespace:
2251 case PCC_Class:
2252 case PCC_ObjCInterface:
2253 case PCC_ObjCImplementation:
2254 case PCC_ObjCInstanceVariableList:
2255 case PCC_Template:
2256 case PCC_MemberTemplate:
Douglas Gregor01dfea02010-01-10 23:08:15 +00002257 Results.setFilter(&ResultBuilder::IsOrdinaryNonValueName);
2258 break;
2259
Douglas Gregore6b1bb62010-08-11 21:23:17 +00002260 case PCC_Expression:
2261 case PCC_Statement:
2262 case PCC_ForInit:
2263 case PCC_Condition:
Douglas Gregor4710e5b2010-05-28 00:49:12 +00002264 if (WantTypesInContext(CompletionContext, getLangOptions()))
2265 Results.setFilter(&ResultBuilder::IsOrdinaryName);
2266 else
2267 Results.setFilter(&ResultBuilder::IsOrdinaryNonTypeName);
Douglas Gregor01dfea02010-01-10 23:08:15 +00002268 break;
Douglas Gregordc845342010-05-25 05:58:43 +00002269
Douglas Gregore6b1bb62010-08-11 21:23:17 +00002270 case PCC_RecoveryInFunction:
Douglas Gregordc845342010-05-25 05:58:43 +00002271 // Unfiltered
2272 break;
Douglas Gregor01dfea02010-01-10 23:08:15 +00002273 }
2274
Douglas Gregor1ca6ae82010-01-14 01:09:38 +00002275 CodeCompletionDeclConsumer Consumer(Results, CurContext);
Douglas Gregor8071e422010-08-15 06:18:01 +00002276 LookupVisibleDecls(S, LookupOrdinaryName, Consumer,
2277 CodeCompleter->includeGlobals());
Douglas Gregor2a7925c2009-12-07 09:54:55 +00002278
2279 Results.EnterNewScope();
Douglas Gregorbca403c2010-01-13 23:51:12 +00002280 AddOrdinaryNameResults(CompletionContext, S, *this, Results);
Douglas Gregor2a7925c2009-12-07 09:54:55 +00002281 Results.ExitScope();
2282
Douglas Gregor0c8296d2009-11-07 00:00:49 +00002283 if (CodeCompleter->includeMacros())
Douglas Gregorbca403c2010-01-13 23:51:12 +00002284 AddMacroResults(PP, Results);
Douglas Gregore6b1bb62010-08-11 21:23:17 +00002285 HandleCodeCompleteResults(this, CodeCompleter,
2286 mapCodeCompletionContext(*this, CompletionContext),
2287 Results.data(),Results.size());
Douglas Gregor791215b2009-09-21 20:51:25 +00002288}
2289
Douglas Gregor2ccccb32010-08-23 18:23:48 +00002290void Sema::CodeCompleteDeclarator(Scope *S,
2291 bool AllowNonIdentifiers,
2292 bool AllowNestedNameSpecifiers) {
2293 typedef CodeCompleteConsumer::Result Result;
2294 ResultBuilder Results(*this);
2295 Results.EnterNewScope();
2296
2297 // Type qualifiers can come after names.
2298 Results.AddResult(Result("const"));
2299 Results.AddResult(Result("volatile"));
2300 if (getLangOptions().C99)
2301 Results.AddResult(Result("restrict"));
2302
2303 if (getLangOptions().CPlusPlus) {
2304 if (AllowNonIdentifiers) {
2305 Results.AddResult(Result("operator"));
2306 }
2307
2308 // Add nested-name-specifiers.
2309 if (AllowNestedNameSpecifiers) {
2310 Results.allowNestedNameSpecifiers();
2311 CodeCompletionDeclConsumer Consumer(Results, CurContext);
2312 LookupVisibleDecls(S, LookupNestedNameSpecifierName, Consumer,
2313 CodeCompleter->includeGlobals());
2314 }
2315 }
2316 Results.ExitScope();
2317
Douglas Gregor2ccccb32010-08-23 18:23:48 +00002318 HandleCodeCompleteResults(this, CodeCompleter,
2319 AllowNestedNameSpecifiers
2320 ? CodeCompletionContext::CCC_PotentiallyQualifiedName
2321 : CodeCompletionContext::CCC_Name,
2322 Results.data(), Results.size());
2323}
2324
Douglas Gregorfb629412010-08-23 21:17:50 +00002325struct Sema::CodeCompleteExpressionData {
2326 CodeCompleteExpressionData(QualType PreferredType = QualType())
2327 : PreferredType(PreferredType), IntegralConstantExpression(false),
2328 ObjCCollection(false) { }
2329
2330 QualType PreferredType;
2331 bool IntegralConstantExpression;
2332 bool ObjCCollection;
2333 llvm::SmallVector<Decl *, 4> IgnoreDecls;
2334};
2335
Douglas Gregor5ac3bdb2010-05-30 01:49:25 +00002336/// \brief Perform code-completion in an expression context when we know what
2337/// type we're looking for.
Douglas Gregorf9578432010-07-28 21:50:18 +00002338///
2339/// \param IntegralConstantExpression Only permit integral constant
2340/// expressions.
Douglas Gregorfb629412010-08-23 21:17:50 +00002341void Sema::CodeCompleteExpression(Scope *S,
2342 const CodeCompleteExpressionData &Data) {
Douglas Gregor5ac3bdb2010-05-30 01:49:25 +00002343 typedef CodeCompleteConsumer::Result Result;
2344 ResultBuilder Results(*this);
2345
Douglas Gregorfb629412010-08-23 21:17:50 +00002346 if (Data.ObjCCollection)
2347 Results.setFilter(&ResultBuilder::IsObjCCollection);
2348 else if (Data.IntegralConstantExpression)
Douglas Gregorf9578432010-07-28 21:50:18 +00002349 Results.setFilter(&ResultBuilder::IsIntegralConstantValue);
Douglas Gregore6b1bb62010-08-11 21:23:17 +00002350 else if (WantTypesInContext(PCC_Expression, getLangOptions()))
Douglas Gregor5ac3bdb2010-05-30 01:49:25 +00002351 Results.setFilter(&ResultBuilder::IsOrdinaryName);
2352 else
2353 Results.setFilter(&ResultBuilder::IsOrdinaryNonTypeName);
Douglas Gregorfb629412010-08-23 21:17:50 +00002354
2355 if (!Data.PreferredType.isNull())
2356 Results.setPreferredType(Data.PreferredType.getNonReferenceType());
2357
2358 // Ignore any declarations that we were told that we don't care about.
2359 for (unsigned I = 0, N = Data.IgnoreDecls.size(); I != N; ++I)
2360 Results.Ignore(Data.IgnoreDecls[I]);
Douglas Gregor5ac3bdb2010-05-30 01:49:25 +00002361
2362 CodeCompletionDeclConsumer Consumer(Results, CurContext);
Douglas Gregor8071e422010-08-15 06:18:01 +00002363 LookupVisibleDecls(S, LookupOrdinaryName, Consumer,
2364 CodeCompleter->includeGlobals());
Douglas Gregor5ac3bdb2010-05-30 01:49:25 +00002365
2366 Results.EnterNewScope();
Douglas Gregore6b1bb62010-08-11 21:23:17 +00002367 AddOrdinaryNameResults(PCC_Expression, S, *this, Results);
Douglas Gregor5ac3bdb2010-05-30 01:49:25 +00002368 Results.ExitScope();
2369
Douglas Gregor590c7d52010-07-08 20:55:51 +00002370 bool PreferredTypeIsPointer = false;
Douglas Gregorfb629412010-08-23 21:17:50 +00002371 if (!Data.PreferredType.isNull())
2372 PreferredTypeIsPointer = Data.PreferredType->isAnyPointerType()
2373 || Data.PreferredType->isMemberPointerType()
2374 || Data.PreferredType->isBlockPointerType();
Douglas Gregor590c7d52010-07-08 20:55:51 +00002375
Douglas Gregor5ac3bdb2010-05-30 01:49:25 +00002376 if (CodeCompleter->includeMacros())
Douglas Gregor590c7d52010-07-08 20:55:51 +00002377 AddMacroResults(PP, Results, PreferredTypeIsPointer);
Douglas Gregore6b1bb62010-08-11 21:23:17 +00002378 HandleCodeCompleteResults(this, CodeCompleter,
Douglas Gregorfb629412010-08-23 21:17:50 +00002379 CodeCompletionContext(CodeCompletionContext::CCC_Expression,
2380 Data.PreferredType),
Douglas Gregore6b1bb62010-08-11 21:23:17 +00002381 Results.data(),Results.size());
Douglas Gregor5ac3bdb2010-05-30 01:49:25 +00002382}
2383
2384
Douglas Gregor95ac6552009-11-18 01:29:26 +00002385static void AddObjCProperties(ObjCContainerDecl *Container,
Douglas Gregor322328b2009-11-18 22:32:06 +00002386 bool AllowCategories,
Douglas Gregor95ac6552009-11-18 01:29:26 +00002387 DeclContext *CurContext,
2388 ResultBuilder &Results) {
2389 typedef CodeCompleteConsumer::Result Result;
2390
2391 // Add properties in this container.
2392 for (ObjCContainerDecl::prop_iterator P = Container->prop_begin(),
2393 PEnd = Container->prop_end();
2394 P != PEnd;
2395 ++P)
2396 Results.MaybeAddResult(Result(*P, 0), CurContext);
2397
2398 // Add properties in referenced protocols.
2399 if (ObjCProtocolDecl *Protocol = dyn_cast<ObjCProtocolDecl>(Container)) {
2400 for (ObjCProtocolDecl::protocol_iterator P = Protocol->protocol_begin(),
2401 PEnd = Protocol->protocol_end();
2402 P != PEnd; ++P)
Douglas Gregor322328b2009-11-18 22:32:06 +00002403 AddObjCProperties(*P, AllowCategories, CurContext, Results);
Douglas Gregor95ac6552009-11-18 01:29:26 +00002404 } else if (ObjCInterfaceDecl *IFace = dyn_cast<ObjCInterfaceDecl>(Container)){
Douglas Gregor322328b2009-11-18 22:32:06 +00002405 if (AllowCategories) {
2406 // Look through categories.
2407 for (ObjCCategoryDecl *Category = IFace->getCategoryList();
2408 Category; Category = Category->getNextClassCategory())
2409 AddObjCProperties(Category, AllowCategories, CurContext, Results);
2410 }
Douglas Gregor95ac6552009-11-18 01:29:26 +00002411
2412 // Look through protocols.
2413 for (ObjCInterfaceDecl::protocol_iterator I = IFace->protocol_begin(),
2414 E = IFace->protocol_end();
2415 I != E; ++I)
Douglas Gregor322328b2009-11-18 22:32:06 +00002416 AddObjCProperties(*I, AllowCategories, CurContext, Results);
Douglas Gregor95ac6552009-11-18 01:29:26 +00002417
2418 // Look in the superclass.
2419 if (IFace->getSuperClass())
Douglas Gregor322328b2009-11-18 22:32:06 +00002420 AddObjCProperties(IFace->getSuperClass(), AllowCategories, CurContext,
2421 Results);
Douglas Gregor95ac6552009-11-18 01:29:26 +00002422 } else if (const ObjCCategoryDecl *Category
2423 = dyn_cast<ObjCCategoryDecl>(Container)) {
2424 // Look through protocols.
2425 for (ObjCInterfaceDecl::protocol_iterator P = Category->protocol_begin(),
2426 PEnd = Category->protocol_end();
2427 P != PEnd; ++P)
Douglas Gregor322328b2009-11-18 22:32:06 +00002428 AddObjCProperties(*P, AllowCategories, CurContext, Results);
Douglas Gregor95ac6552009-11-18 01:29:26 +00002429 }
2430}
2431
Douglas Gregor81b747b2009-09-17 21:32:03 +00002432void Sema::CodeCompleteMemberReferenceExpr(Scope *S, ExprTy *BaseE,
2433 SourceLocation OpLoc,
2434 bool IsArrow) {
2435 if (!BaseE || !CodeCompleter)
2436 return;
2437
Douglas Gregor86d9a522009-09-21 16:56:56 +00002438 typedef CodeCompleteConsumer::Result Result;
2439
Douglas Gregor81b747b2009-09-17 21:32:03 +00002440 Expr *Base = static_cast<Expr *>(BaseE);
2441 QualType BaseType = Base->getType();
Douglas Gregor86d9a522009-09-21 16:56:56 +00002442
2443 if (IsArrow) {
2444 if (const PointerType *Ptr = BaseType->getAs<PointerType>())
2445 BaseType = Ptr->getPointeeType();
2446 else if (BaseType->isObjCObjectPointerType())
2447 /*Do nothing*/ ;
2448 else
2449 return;
2450 }
2451
Douglas Gregoreb5758b2009-09-23 22:26:46 +00002452 ResultBuilder Results(*this, &ResultBuilder::IsMember);
Douglas Gregor95ac6552009-11-18 01:29:26 +00002453 Results.EnterNewScope();
2454 if (const RecordType *Record = BaseType->getAs<RecordType>()) {
2455 // Access to a C/C++ class, struct, or union.
Douglas Gregor45bcd432010-01-14 03:21:49 +00002456 Results.allowNestedNameSpecifiers();
Douglas Gregor0cc84042010-01-14 15:47:35 +00002457 CodeCompletionDeclConsumer Consumer(Results, CurContext);
Douglas Gregor8071e422010-08-15 06:18:01 +00002458 LookupVisibleDecls(Record->getDecl(), LookupMemberName, Consumer,
2459 CodeCompleter->includeGlobals());
Daniel Dunbar3a2838d2009-11-13 08:58:20 +00002460
Douglas Gregor95ac6552009-11-18 01:29:26 +00002461 if (getLangOptions().CPlusPlus) {
2462 if (!Results.empty()) {
2463 // The "template" keyword can follow "->" or "." in the grammar.
2464 // However, we only want to suggest the template keyword if something
2465 // is dependent.
2466 bool IsDependent = BaseType->isDependentType();
2467 if (!IsDependent) {
2468 for (Scope *DepScope = S; DepScope; DepScope = DepScope->getParent())
2469 if (DeclContext *Ctx = (DeclContext *)DepScope->getEntity()) {
2470 IsDependent = Ctx->isDependentContext();
2471 break;
2472 }
2473 }
Daniel Dunbar3a2838d2009-11-13 08:58:20 +00002474
Douglas Gregor95ac6552009-11-18 01:29:26 +00002475 if (IsDependent)
Douglas Gregora4477812010-01-14 16:01:26 +00002476 Results.AddResult(Result("template"));
Daniel Dunbar3a2838d2009-11-13 08:58:20 +00002477 }
Daniel Dunbar3a2838d2009-11-13 08:58:20 +00002478 }
Douglas Gregor95ac6552009-11-18 01:29:26 +00002479 } else if (!IsArrow && BaseType->getAsObjCInterfacePointerType()) {
2480 // Objective-C property reference.
2481
2482 // Add property results based on our interface.
2483 const ObjCObjectPointerType *ObjCPtr
2484 = BaseType->getAsObjCInterfacePointerType();
2485 assert(ObjCPtr && "Non-NULL pointer guaranteed above!");
Douglas Gregor322328b2009-11-18 22:32:06 +00002486 AddObjCProperties(ObjCPtr->getInterfaceDecl(), true, CurContext, Results);
Douglas Gregor95ac6552009-11-18 01:29:26 +00002487
2488 // Add properties from the protocols in a qualified interface.
2489 for (ObjCObjectPointerType::qual_iterator I = ObjCPtr->qual_begin(),
2490 E = ObjCPtr->qual_end();
2491 I != E; ++I)
Douglas Gregor322328b2009-11-18 22:32:06 +00002492 AddObjCProperties(*I, true, CurContext, Results);
Douglas Gregor95ac6552009-11-18 01:29:26 +00002493 } else if ((IsArrow && BaseType->isObjCObjectPointerType()) ||
John McCallc12c5bb2010-05-15 11:32:37 +00002494 (!IsArrow && BaseType->isObjCObjectType())) {
Douglas Gregor95ac6552009-11-18 01:29:26 +00002495 // Objective-C instance variable access.
2496 ObjCInterfaceDecl *Class = 0;
2497 if (const ObjCObjectPointerType *ObjCPtr
2498 = BaseType->getAs<ObjCObjectPointerType>())
2499 Class = ObjCPtr->getInterfaceDecl();
2500 else
John McCallc12c5bb2010-05-15 11:32:37 +00002501 Class = BaseType->getAs<ObjCObjectType>()->getInterface();
Douglas Gregor95ac6552009-11-18 01:29:26 +00002502
2503 // Add all ivars from this class and its superclasses.
Douglas Gregor80f4f4c2010-01-14 16:08:12 +00002504 if (Class) {
2505 CodeCompletionDeclConsumer Consumer(Results, CurContext);
2506 Results.setFilter(&ResultBuilder::IsObjCIvar);
Douglas Gregor8071e422010-08-15 06:18:01 +00002507 LookupVisibleDecls(Class, LookupMemberName, Consumer,
2508 CodeCompleter->includeGlobals());
Douglas Gregor95ac6552009-11-18 01:29:26 +00002509 }
Douglas Gregor86d9a522009-09-21 16:56:56 +00002510 }
Douglas Gregor95ac6552009-11-18 01:29:26 +00002511
2512 // FIXME: How do we cope with isa?
2513
2514 Results.ExitScope();
Daniel Dunbar3a2838d2009-11-13 08:58:20 +00002515
Daniel Dunbar3a2838d2009-11-13 08:58:20 +00002516 // Hand off the results found for code completion.
Douglas Gregore6b1bb62010-08-11 21:23:17 +00002517 HandleCodeCompleteResults(this, CodeCompleter,
2518 CodeCompletionContext(CodeCompletionContext::CCC_MemberAccess,
2519 BaseType),
2520 Results.data(),Results.size());
Douglas Gregor81b747b2009-09-17 21:32:03 +00002521}
2522
Douglas Gregor374929f2009-09-18 15:37:17 +00002523void Sema::CodeCompleteTag(Scope *S, unsigned TagSpec) {
2524 if (!CodeCompleter)
2525 return;
2526
Douglas Gregor86d9a522009-09-21 16:56:56 +00002527 typedef CodeCompleteConsumer::Result Result;
2528 ResultBuilder::LookupFilter Filter = 0;
Douglas Gregore6b1bb62010-08-11 21:23:17 +00002529 enum CodeCompletionContext::Kind ContextKind
2530 = CodeCompletionContext::CCC_Other;
Douglas Gregor374929f2009-09-18 15:37:17 +00002531 switch ((DeclSpec::TST)TagSpec) {
2532 case DeclSpec::TST_enum:
Douglas Gregor86d9a522009-09-21 16:56:56 +00002533 Filter = &ResultBuilder::IsEnum;
Douglas Gregore6b1bb62010-08-11 21:23:17 +00002534 ContextKind = CodeCompletionContext::CCC_EnumTag;
Douglas Gregor374929f2009-09-18 15:37:17 +00002535 break;
2536
2537 case DeclSpec::TST_union:
Douglas Gregor86d9a522009-09-21 16:56:56 +00002538 Filter = &ResultBuilder::IsUnion;
Douglas Gregore6b1bb62010-08-11 21:23:17 +00002539 ContextKind = CodeCompletionContext::CCC_UnionTag;
Douglas Gregor374929f2009-09-18 15:37:17 +00002540 break;
2541
2542 case DeclSpec::TST_struct:
Douglas Gregor374929f2009-09-18 15:37:17 +00002543 case DeclSpec::TST_class:
Douglas Gregor86d9a522009-09-21 16:56:56 +00002544 Filter = &ResultBuilder::IsClassOrStruct;
Douglas Gregore6b1bb62010-08-11 21:23:17 +00002545 ContextKind = CodeCompletionContext::CCC_ClassOrStructTag;
Douglas Gregor374929f2009-09-18 15:37:17 +00002546 break;
2547
2548 default:
2549 assert(false && "Unknown type specifier kind in CodeCompleteTag");
2550 return;
2551 }
Douglas Gregor86d9a522009-09-21 16:56:56 +00002552
John McCall0d6b1642010-04-23 18:46:30 +00002553 ResultBuilder Results(*this);
Douglas Gregor5d2fc402010-01-14 03:27:13 +00002554 CodeCompletionDeclConsumer Consumer(Results, CurContext);
John McCall0d6b1642010-04-23 18:46:30 +00002555
2556 // First pass: look for tags.
2557 Results.setFilter(Filter);
Douglas Gregor8071e422010-08-15 06:18:01 +00002558 LookupVisibleDecls(S, LookupTagName, Consumer,
2559 CodeCompleter->includeGlobals());
John McCall0d6b1642010-04-23 18:46:30 +00002560
Douglas Gregor8071e422010-08-15 06:18:01 +00002561 if (CodeCompleter->includeGlobals()) {
2562 // Second pass: look for nested name specifiers.
2563 Results.setFilter(&ResultBuilder::IsNestedNameSpecifier);
2564 LookupVisibleDecls(S, LookupNestedNameSpecifierName, Consumer);
2565 }
Douglas Gregor86d9a522009-09-21 16:56:56 +00002566
Douglas Gregore6b1bb62010-08-11 21:23:17 +00002567 HandleCodeCompleteResults(this, CodeCompleter, ContextKind,
2568 Results.data(),Results.size());
Douglas Gregor374929f2009-09-18 15:37:17 +00002569}
2570
Douglas Gregor3e1005f2009-09-21 18:10:23 +00002571void Sema::CodeCompleteCase(Scope *S) {
2572 if (getSwitchStack().empty() || !CodeCompleter)
2573 return;
2574
2575 SwitchStmt *Switch = getSwitchStack().back();
Douglas Gregorf9578432010-07-28 21:50:18 +00002576 if (!Switch->getCond()->getType()->isEnumeralType()) {
Douglas Gregorfb629412010-08-23 21:17:50 +00002577 CodeCompleteExpressionData Data(Switch->getCond()->getType());
2578 Data.IntegralConstantExpression = true;
2579 CodeCompleteExpression(S, Data);
Douglas Gregor3e1005f2009-09-21 18:10:23 +00002580 return;
Douglas Gregorf9578432010-07-28 21:50:18 +00002581 }
Douglas Gregor3e1005f2009-09-21 18:10:23 +00002582
2583 // Code-complete the cases of a switch statement over an enumeration type
2584 // by providing the list of
2585 EnumDecl *Enum = Switch->getCond()->getType()->getAs<EnumType>()->getDecl();
2586
2587 // Determine which enumerators we have already seen in the switch statement.
2588 // FIXME: Ideally, we would also be able to look *past* the code-completion
2589 // token, in case we are code-completing in the middle of the switch and not
2590 // at the end. However, we aren't able to do so at the moment.
2591 llvm::SmallPtrSet<EnumConstantDecl *, 8> EnumeratorsSeen;
Douglas Gregorb9d0ef72009-09-21 19:57:38 +00002592 NestedNameSpecifier *Qualifier = 0;
Douglas Gregor3e1005f2009-09-21 18:10:23 +00002593 for (SwitchCase *SC = Switch->getSwitchCaseList(); SC;
2594 SC = SC->getNextSwitchCase()) {
2595 CaseStmt *Case = dyn_cast<CaseStmt>(SC);
2596 if (!Case)
2597 continue;
2598
2599 Expr *CaseVal = Case->getLHS()->IgnoreParenCasts();
2600 if (DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(CaseVal))
2601 if (EnumConstantDecl *Enumerator
2602 = dyn_cast<EnumConstantDecl>(DRE->getDecl())) {
2603 // We look into the AST of the case statement to determine which
2604 // enumerator was named. Alternatively, we could compute the value of
2605 // the integral constant expression, then compare it against the
2606 // values of each enumerator. However, value-based approach would not
2607 // work as well with C++ templates where enumerators declared within a
2608 // template are type- and value-dependent.
2609 EnumeratorsSeen.insert(Enumerator);
2610
Douglas Gregorb9d0ef72009-09-21 19:57:38 +00002611 // If this is a qualified-id, keep track of the nested-name-specifier
2612 // so that we can reproduce it as part of code completion, e.g.,
Douglas Gregor3e1005f2009-09-21 18:10:23 +00002613 //
2614 // switch (TagD.getKind()) {
2615 // case TagDecl::TK_enum:
2616 // break;
2617 // case XXX
2618 //
Douglas Gregorb9d0ef72009-09-21 19:57:38 +00002619 // At the XXX, our completions are TagDecl::TK_union,
Douglas Gregor3e1005f2009-09-21 18:10:23 +00002620 // TagDecl::TK_struct, and TagDecl::TK_class, rather than TK_union,
2621 // TK_struct, and TK_class.
Douglas Gregora2813ce2009-10-23 18:54:35 +00002622 Qualifier = DRE->getQualifier();
Douglas Gregor3e1005f2009-09-21 18:10:23 +00002623 }
2624 }
2625
Douglas Gregorb9d0ef72009-09-21 19:57:38 +00002626 if (getLangOptions().CPlusPlus && !Qualifier && EnumeratorsSeen.empty()) {
2627 // If there are no prior enumerators in C++, check whether we have to
2628 // qualify the names of the enumerators that we suggest, because they
2629 // may not be visible in this scope.
2630 Qualifier = getRequiredQualification(Context, CurContext,
2631 Enum->getDeclContext());
2632
2633 // FIXME: Scoped enums need to start with "EnumDecl" as the context!
2634 }
2635
Douglas Gregor3e1005f2009-09-21 18:10:23 +00002636 // Add any enumerators that have not yet been mentioned.
2637 ResultBuilder Results(*this);
2638 Results.EnterNewScope();
2639 for (EnumDecl::enumerator_iterator E = Enum->enumerator_begin(),
2640 EEnd = Enum->enumerator_end();
2641 E != EEnd; ++E) {
2642 if (EnumeratorsSeen.count(*E))
2643 continue;
2644
Douglas Gregor608300b2010-01-14 16:14:35 +00002645 Results.AddResult(CodeCompleteConsumer::Result(*E, Qualifier),
2646 CurContext, 0, false);
Douglas Gregor3e1005f2009-09-21 18:10:23 +00002647 }
2648 Results.ExitScope();
Douglas Gregor2f880e42010-04-06 20:02:15 +00002649
Douglas Gregor0c8296d2009-11-07 00:00:49 +00002650 if (CodeCompleter->includeMacros())
Douglas Gregorbca403c2010-01-13 23:51:12 +00002651 AddMacroResults(PP, Results);
Douglas Gregore6b1bb62010-08-11 21:23:17 +00002652 HandleCodeCompleteResults(this, CodeCompleter,
2653 CodeCompletionContext::CCC_Expression,
2654 Results.data(),Results.size());
Douglas Gregor3e1005f2009-09-21 18:10:23 +00002655}
2656
Douglas Gregor9c6a0e92009-09-22 15:41:20 +00002657namespace {
2658 struct IsBetterOverloadCandidate {
2659 Sema &S;
John McCall5769d612010-02-08 23:07:23 +00002660 SourceLocation Loc;
Douglas Gregor9c6a0e92009-09-22 15:41:20 +00002661
2662 public:
John McCall5769d612010-02-08 23:07:23 +00002663 explicit IsBetterOverloadCandidate(Sema &S, SourceLocation Loc)
2664 : S(S), Loc(Loc) { }
Douglas Gregor9c6a0e92009-09-22 15:41:20 +00002665
2666 bool
2667 operator()(const OverloadCandidate &X, const OverloadCandidate &Y) const {
John McCall5769d612010-02-08 23:07:23 +00002668 return S.isBetterOverloadCandidate(X, Y, Loc);
Douglas Gregor9c6a0e92009-09-22 15:41:20 +00002669 }
2670 };
2671}
2672
Douglas Gregord28dcd72010-05-30 06:10:08 +00002673static bool anyNullArguments(Expr **Args, unsigned NumArgs) {
2674 if (NumArgs && !Args)
2675 return true;
2676
2677 for (unsigned I = 0; I != NumArgs; ++I)
2678 if (!Args[I])
2679 return true;
2680
2681 return false;
2682}
2683
Douglas Gregor9c6a0e92009-09-22 15:41:20 +00002684void Sema::CodeCompleteCall(Scope *S, ExprTy *FnIn,
2685 ExprTy **ArgsIn, unsigned NumArgs) {
2686 if (!CodeCompleter)
2687 return;
Douglas Gregoref96eac2009-12-11 19:06:04 +00002688
2689 // When we're code-completing for a call, we fall back to ordinary
2690 // name code-completion whenever we can't produce specific
2691 // results. We may want to revisit this strategy in the future,
2692 // e.g., by merging the two kinds of results.
2693
Douglas Gregor9c6a0e92009-09-22 15:41:20 +00002694 Expr *Fn = (Expr *)FnIn;
2695 Expr **Args = (Expr **)ArgsIn;
Douglas Gregoref96eac2009-12-11 19:06:04 +00002696
Douglas Gregor9c6a0e92009-09-22 15:41:20 +00002697 // Ignore type-dependent call expressions entirely.
Douglas Gregord28dcd72010-05-30 06:10:08 +00002698 if (!Fn || Fn->isTypeDependent() || anyNullArguments(Args, NumArgs) ||
Douglas Gregoref96eac2009-12-11 19:06:04 +00002699 Expr::hasAnyTypeDependentArguments(Args, NumArgs)) {
Douglas Gregore6b1bb62010-08-11 21:23:17 +00002700 CodeCompleteOrdinaryName(S, PCC_Expression);
Douglas Gregor9c6a0e92009-09-22 15:41:20 +00002701 return;
Douglas Gregoref96eac2009-12-11 19:06:04 +00002702 }
Douglas Gregor9c6a0e92009-09-22 15:41:20 +00002703
John McCall3b4294e2009-12-16 12:17:52 +00002704 // Build an overload candidate set based on the functions we find.
John McCall5769d612010-02-08 23:07:23 +00002705 SourceLocation Loc = Fn->getExprLoc();
2706 OverloadCandidateSet CandidateSet(Loc);
John McCall3b4294e2009-12-16 12:17:52 +00002707
Douglas Gregor9c6a0e92009-09-22 15:41:20 +00002708 // FIXME: What if we're calling something that isn't a function declaration?
2709 // FIXME: What if we're calling a pseudo-destructor?
2710 // FIXME: What if we're calling a member function?
2711
Douglas Gregorc0265402010-01-21 15:46:19 +00002712 typedef CodeCompleteConsumer::OverloadCandidate ResultCandidate;
2713 llvm::SmallVector<ResultCandidate, 8> Results;
2714
John McCall3b4294e2009-12-16 12:17:52 +00002715 Expr *NakedFn = Fn->IgnoreParenCasts();
2716 if (UnresolvedLookupExpr *ULE = dyn_cast<UnresolvedLookupExpr>(NakedFn))
2717 AddOverloadedCallCandidates(ULE, Args, NumArgs, CandidateSet,
2718 /*PartialOverloading=*/ true);
2719 else if (DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(NakedFn)) {
2720 FunctionDecl *FDecl = dyn_cast<FunctionDecl>(DRE->getDecl());
Douglas Gregorc0265402010-01-21 15:46:19 +00002721 if (FDecl) {
Douglas Gregord28dcd72010-05-30 06:10:08 +00002722 if (!getLangOptions().CPlusPlus ||
2723 !FDecl->getType()->getAs<FunctionProtoType>())
Douglas Gregorc0265402010-01-21 15:46:19 +00002724 Results.push_back(ResultCandidate(FDecl));
2725 else
John McCall86820f52010-01-26 01:37:31 +00002726 // FIXME: access?
John McCall9aa472c2010-03-19 07:35:19 +00002727 AddOverloadCandidate(FDecl, DeclAccessPair::make(FDecl, AS_none),
2728 Args, NumArgs, CandidateSet,
Douglas Gregorc27d6c52010-04-16 17:41:49 +00002729 false, /*PartialOverloading*/true);
Douglas Gregorc0265402010-01-21 15:46:19 +00002730 }
John McCall3b4294e2009-12-16 12:17:52 +00002731 }
Douglas Gregor9c6a0e92009-09-22 15:41:20 +00002732
Douglas Gregor5ac3bdb2010-05-30 01:49:25 +00002733 QualType ParamType;
2734
Douglas Gregorc0265402010-01-21 15:46:19 +00002735 if (!CandidateSet.empty()) {
2736 // Sort the overload candidate set by placing the best overloads first.
2737 std::stable_sort(CandidateSet.begin(), CandidateSet.end(),
John McCall5769d612010-02-08 23:07:23 +00002738 IsBetterOverloadCandidate(*this, Loc));
Douglas Gregor9c6a0e92009-09-22 15:41:20 +00002739
Douglas Gregorc0265402010-01-21 15:46:19 +00002740 // Add the remaining viable overload candidates as code-completion reslults.
2741 for (OverloadCandidateSet::iterator Cand = CandidateSet.begin(),
2742 CandEnd = CandidateSet.end();
2743 Cand != CandEnd; ++Cand) {
2744 if (Cand->Viable)
2745 Results.push_back(ResultCandidate(Cand->Function));
2746 }
Douglas Gregor5ac3bdb2010-05-30 01:49:25 +00002747
2748 // From the viable candidates, try to determine the type of this parameter.
2749 for (unsigned I = 0, N = Results.size(); I != N; ++I) {
2750 if (const FunctionType *FType = Results[I].getFunctionType())
2751 if (const FunctionProtoType *Proto = dyn_cast<FunctionProtoType>(FType))
2752 if (NumArgs < Proto->getNumArgs()) {
2753 if (ParamType.isNull())
2754 ParamType = Proto->getArgType(NumArgs);
2755 else if (!Context.hasSameUnqualifiedType(
2756 ParamType.getNonReferenceType(),
2757 Proto->getArgType(NumArgs).getNonReferenceType())) {
2758 ParamType = QualType();
2759 break;
2760 }
2761 }
2762 }
2763 } else {
2764 // Try to determine the parameter type from the type of the expression
2765 // being called.
2766 QualType FunctionType = Fn->getType();
2767 if (const PointerType *Ptr = FunctionType->getAs<PointerType>())
2768 FunctionType = Ptr->getPointeeType();
2769 else if (const BlockPointerType *BlockPtr
2770 = FunctionType->getAs<BlockPointerType>())
2771 FunctionType = BlockPtr->getPointeeType();
2772 else if (const MemberPointerType *MemPtr
2773 = FunctionType->getAs<MemberPointerType>())
2774 FunctionType = MemPtr->getPointeeType();
2775
2776 if (const FunctionProtoType *Proto
2777 = FunctionType->getAs<FunctionProtoType>()) {
2778 if (NumArgs < Proto->getNumArgs())
2779 ParamType = Proto->getArgType(NumArgs);
2780 }
Douglas Gregor9c6a0e92009-09-22 15:41:20 +00002781 }
Douglas Gregoref96eac2009-12-11 19:06:04 +00002782
Douglas Gregor5ac3bdb2010-05-30 01:49:25 +00002783 if (ParamType.isNull())
Douglas Gregore6b1bb62010-08-11 21:23:17 +00002784 CodeCompleteOrdinaryName(S, PCC_Expression);
Douglas Gregor5ac3bdb2010-05-30 01:49:25 +00002785 else
2786 CodeCompleteExpression(S, ParamType);
2787
Douglas Gregor2e4c7a52010-04-06 20:19:47 +00002788 if (!Results.empty())
Douglas Gregoref96eac2009-12-11 19:06:04 +00002789 CodeCompleter->ProcessOverloadCandidates(*this, NumArgs, Results.data(),
2790 Results.size());
Douglas Gregor9c6a0e92009-09-22 15:41:20 +00002791}
2792
John McCalld226f652010-08-21 09:40:31 +00002793void Sema::CodeCompleteInitializer(Scope *S, Decl *D) {
2794 ValueDecl *VD = dyn_cast_or_null<ValueDecl>(D);
Douglas Gregor5ac3bdb2010-05-30 01:49:25 +00002795 if (!VD) {
Douglas Gregore6b1bb62010-08-11 21:23:17 +00002796 CodeCompleteOrdinaryName(S, PCC_Expression);
Douglas Gregor5ac3bdb2010-05-30 01:49:25 +00002797 return;
2798 }
2799
2800 CodeCompleteExpression(S, VD->getType());
2801}
2802
2803void Sema::CodeCompleteReturn(Scope *S) {
2804 QualType ResultType;
2805 if (isa<BlockDecl>(CurContext)) {
2806 if (BlockScopeInfo *BSI = getCurBlock())
2807 ResultType = BSI->ReturnType;
2808 } else if (FunctionDecl *Function = dyn_cast<FunctionDecl>(CurContext))
2809 ResultType = Function->getResultType();
2810 else if (ObjCMethodDecl *Method = dyn_cast<ObjCMethodDecl>(CurContext))
2811 ResultType = Method->getResultType();
2812
2813 if (ResultType.isNull())
Douglas Gregore6b1bb62010-08-11 21:23:17 +00002814 CodeCompleteOrdinaryName(S, PCC_Expression);
Douglas Gregor5ac3bdb2010-05-30 01:49:25 +00002815 else
2816 CodeCompleteExpression(S, ResultType);
2817}
2818
2819void Sema::CodeCompleteAssignmentRHS(Scope *S, ExprTy *LHS) {
2820 if (LHS)
2821 CodeCompleteExpression(S, static_cast<Expr *>(LHS)->getType());
2822 else
Douglas Gregore6b1bb62010-08-11 21:23:17 +00002823 CodeCompleteOrdinaryName(S, PCC_Expression);
Douglas Gregor5ac3bdb2010-05-30 01:49:25 +00002824}
2825
Jeffrey Yasskin9ab14542010-04-08 16:38:48 +00002826void Sema::CodeCompleteQualifiedId(Scope *S, CXXScopeSpec &SS,
Douglas Gregor81b747b2009-09-17 21:32:03 +00002827 bool EnteringContext) {
2828 if (!SS.getScopeRep() || !CodeCompleter)
2829 return;
2830
Douglas Gregor86d9a522009-09-21 16:56:56 +00002831 DeclContext *Ctx = computeDeclContext(SS, EnteringContext);
2832 if (!Ctx)
2833 return;
Douglas Gregord1cd31a2009-12-11 18:28:39 +00002834
2835 // Try to instantiate any non-dependent declaration contexts before
2836 // we look in them.
John McCall77bb1aa2010-05-01 00:40:08 +00002837 if (!isDependentScopeSpecifier(SS) && RequireCompleteDeclContext(SS, Ctx))
Douglas Gregord1cd31a2009-12-11 18:28:39 +00002838 return;
2839
Douglas Gregor86d9a522009-09-21 16:56:56 +00002840 ResultBuilder Results(*this);
Douglas Gregordef91072010-01-14 03:35:48 +00002841 CodeCompletionDeclConsumer Consumer(Results, CurContext);
2842 LookupVisibleDecls(Ctx, LookupOrdinaryName, Consumer);
Douglas Gregor86d9a522009-09-21 16:56:56 +00002843
2844 // The "template" keyword can follow "::" in the grammar, but only
2845 // put it into the grammar if the nested-name-specifier is dependent.
2846 NestedNameSpecifier *NNS = (NestedNameSpecifier *)SS.getScopeRep();
2847 if (!Results.empty() && NNS->isDependent())
Douglas Gregora4477812010-01-14 16:01:26 +00002848 Results.AddResult("template");
Douglas Gregor86d9a522009-09-21 16:56:56 +00002849
Douglas Gregore6b1bb62010-08-11 21:23:17 +00002850 HandleCodeCompleteResults(this, CodeCompleter,
2851 CodeCompletionContext::CCC_Other,
2852 Results.data(),Results.size());
Douglas Gregor81b747b2009-09-17 21:32:03 +00002853}
Douglas Gregor49f40bd2009-09-18 19:03:04 +00002854
2855void Sema::CodeCompleteUsing(Scope *S) {
2856 if (!CodeCompleter)
2857 return;
2858
Douglas Gregor86d9a522009-09-21 16:56:56 +00002859 ResultBuilder Results(*this, &ResultBuilder::IsNestedNameSpecifier);
Douglas Gregor8e0a0e42009-09-22 23:31:26 +00002860 Results.EnterNewScope();
Douglas Gregor86d9a522009-09-21 16:56:56 +00002861
2862 // If we aren't in class scope, we could see the "namespace" keyword.
2863 if (!S->isClassScope())
Douglas Gregora4477812010-01-14 16:01:26 +00002864 Results.AddResult(CodeCompleteConsumer::Result("namespace"));
Douglas Gregor86d9a522009-09-21 16:56:56 +00002865
2866 // After "using", we can see anything that would start a
2867 // nested-name-specifier.
Douglas Gregor5d2fc402010-01-14 03:27:13 +00002868 CodeCompletionDeclConsumer Consumer(Results, CurContext);
Douglas Gregor8071e422010-08-15 06:18:01 +00002869 LookupVisibleDecls(S, LookupOrdinaryName, Consumer,
2870 CodeCompleter->includeGlobals());
Douglas Gregor8e0a0e42009-09-22 23:31:26 +00002871 Results.ExitScope();
Douglas Gregor86d9a522009-09-21 16:56:56 +00002872
Douglas Gregore6b1bb62010-08-11 21:23:17 +00002873 HandleCodeCompleteResults(this, CodeCompleter,
2874 CodeCompletionContext::CCC_Other,
2875 Results.data(),Results.size());
Douglas Gregor49f40bd2009-09-18 19:03:04 +00002876}
2877
2878void Sema::CodeCompleteUsingDirective(Scope *S) {
2879 if (!CodeCompleter)
2880 return;
2881
Douglas Gregor86d9a522009-09-21 16:56:56 +00002882 // After "using namespace", we expect to see a namespace name or namespace
2883 // alias.
2884 ResultBuilder Results(*this, &ResultBuilder::IsNamespaceOrAlias);
Douglas Gregor8e0a0e42009-09-22 23:31:26 +00002885 Results.EnterNewScope();
Douglas Gregor5d2fc402010-01-14 03:27:13 +00002886 CodeCompletionDeclConsumer Consumer(Results, CurContext);
Douglas Gregor8071e422010-08-15 06:18:01 +00002887 LookupVisibleDecls(S, LookupOrdinaryName, Consumer,
2888 CodeCompleter->includeGlobals());
Douglas Gregor8e0a0e42009-09-22 23:31:26 +00002889 Results.ExitScope();
Douglas Gregore6b1bb62010-08-11 21:23:17 +00002890 HandleCodeCompleteResults(this, CodeCompleter,
Douglas Gregor8071e422010-08-15 06:18:01 +00002891 CodeCompletionContext::CCC_Namespace,
Douglas Gregore6b1bb62010-08-11 21:23:17 +00002892 Results.data(),Results.size());
Douglas Gregor49f40bd2009-09-18 19:03:04 +00002893}
2894
2895void Sema::CodeCompleteNamespaceDecl(Scope *S) {
2896 if (!CodeCompleter)
2897 return;
2898
Douglas Gregor86d9a522009-09-21 16:56:56 +00002899 ResultBuilder Results(*this, &ResultBuilder::IsNamespace);
2900 DeclContext *Ctx = (DeclContext *)S->getEntity();
2901 if (!S->getParent())
2902 Ctx = Context.getTranslationUnitDecl();
2903
2904 if (Ctx && Ctx->isFileContext()) {
2905 // We only want to see those namespaces that have already been defined
2906 // within this scope, because its likely that the user is creating an
2907 // extended namespace declaration. Keep track of the most recent
2908 // definition of each namespace.
2909 std::map<NamespaceDecl *, NamespaceDecl *> OrigToLatest;
2910 for (DeclContext::specific_decl_iterator<NamespaceDecl>
2911 NS(Ctx->decls_begin()), NSEnd(Ctx->decls_end());
2912 NS != NSEnd; ++NS)
2913 OrigToLatest[NS->getOriginalNamespace()] = *NS;
2914
2915 // Add the most recent definition (or extended definition) of each
2916 // namespace to the list of results.
Douglas Gregor8e0a0e42009-09-22 23:31:26 +00002917 Results.EnterNewScope();
Douglas Gregor86d9a522009-09-21 16:56:56 +00002918 for (std::map<NamespaceDecl *, NamespaceDecl *>::iterator
2919 NS = OrigToLatest.begin(), NSEnd = OrigToLatest.end();
2920 NS != NSEnd; ++NS)
Douglas Gregor608300b2010-01-14 16:14:35 +00002921 Results.AddResult(CodeCompleteConsumer::Result(NS->second, 0),
2922 CurContext, 0, false);
Douglas Gregor8e0a0e42009-09-22 23:31:26 +00002923 Results.ExitScope();
Douglas Gregor86d9a522009-09-21 16:56:56 +00002924 }
2925
Douglas Gregore6b1bb62010-08-11 21:23:17 +00002926 HandleCodeCompleteResults(this, CodeCompleter,
2927 CodeCompletionContext::CCC_Other,
2928 Results.data(),Results.size());
Douglas Gregor49f40bd2009-09-18 19:03:04 +00002929}
2930
2931void Sema::CodeCompleteNamespaceAliasDecl(Scope *S) {
2932 if (!CodeCompleter)
2933 return;
2934
Douglas Gregor86d9a522009-09-21 16:56:56 +00002935 // After "namespace", we expect to see a namespace or alias.
2936 ResultBuilder Results(*this, &ResultBuilder::IsNamespaceOrAlias);
Douglas Gregor5d2fc402010-01-14 03:27:13 +00002937 CodeCompletionDeclConsumer Consumer(Results, CurContext);
Douglas Gregor8071e422010-08-15 06:18:01 +00002938 LookupVisibleDecls(S, LookupOrdinaryName, Consumer,
2939 CodeCompleter->includeGlobals());
Douglas Gregore6b1bb62010-08-11 21:23:17 +00002940 HandleCodeCompleteResults(this, CodeCompleter,
Douglas Gregor8071e422010-08-15 06:18:01 +00002941 CodeCompletionContext::CCC_Namespace,
Douglas Gregore6b1bb62010-08-11 21:23:17 +00002942 Results.data(),Results.size());
Douglas Gregor49f40bd2009-09-18 19:03:04 +00002943}
2944
Douglas Gregored8d3222009-09-18 20:05:18 +00002945void Sema::CodeCompleteOperatorName(Scope *S) {
2946 if (!CodeCompleter)
2947 return;
Douglas Gregor86d9a522009-09-21 16:56:56 +00002948
2949 typedef CodeCompleteConsumer::Result Result;
2950 ResultBuilder Results(*this, &ResultBuilder::IsType);
Douglas Gregor8e0a0e42009-09-22 23:31:26 +00002951 Results.EnterNewScope();
Douglas Gregored8d3222009-09-18 20:05:18 +00002952
Douglas Gregor86d9a522009-09-21 16:56:56 +00002953 // Add the names of overloadable operators.
2954#define OVERLOADED_OPERATOR(Name,Spelling,Token,Unary,Binary,MemberOnly) \
2955 if (std::strcmp(Spelling, "?")) \
Douglas Gregora4477812010-01-14 16:01:26 +00002956 Results.AddResult(Result(Spelling));
Douglas Gregor86d9a522009-09-21 16:56:56 +00002957#include "clang/Basic/OperatorKinds.def"
2958
2959 // Add any type names visible from the current scope
Douglas Gregor45bcd432010-01-14 03:21:49 +00002960 Results.allowNestedNameSpecifiers();
Douglas Gregor5d2fc402010-01-14 03:27:13 +00002961 CodeCompletionDeclConsumer Consumer(Results, CurContext);
Douglas Gregor8071e422010-08-15 06:18:01 +00002962 LookupVisibleDecls(S, LookupOrdinaryName, Consumer,
2963 CodeCompleter->includeGlobals());
Douglas Gregor86d9a522009-09-21 16:56:56 +00002964
2965 // Add any type specifiers
Douglas Gregorbca403c2010-01-13 23:51:12 +00002966 AddTypeSpecifierResults(getLangOptions(), Results);
Douglas Gregor8e0a0e42009-09-22 23:31:26 +00002967 Results.ExitScope();
Douglas Gregor86d9a522009-09-21 16:56:56 +00002968
Douglas Gregore6b1bb62010-08-11 21:23:17 +00002969 HandleCodeCompleteResults(this, CodeCompleter,
Douglas Gregor8071e422010-08-15 06:18:01 +00002970 CodeCompletionContext::CCC_Type,
Douglas Gregore6b1bb62010-08-11 21:23:17 +00002971 Results.data(),Results.size());
Douglas Gregored8d3222009-09-18 20:05:18 +00002972}
Douglas Gregor49f40bd2009-09-18 19:03:04 +00002973
Douglas Gregorb6ac2452010-01-13 21:24:21 +00002974// Macro that expands to @Keyword or Keyword, depending on whether NeedAt is
2975// true or false.
2976#define OBJC_AT_KEYWORD_NAME(NeedAt,Keyword) NeedAt? "@" #Keyword : #Keyword
Douglas Gregorbca403c2010-01-13 23:51:12 +00002977static void AddObjCImplementationResults(const LangOptions &LangOpts,
Douglas Gregorb6ac2452010-01-13 21:24:21 +00002978 ResultBuilder &Results,
2979 bool NeedAt) {
2980 typedef CodeCompleteConsumer::Result Result;
2981 // Since we have an implementation, we can end it.
Douglas Gregora4477812010-01-14 16:01:26 +00002982 Results.AddResult(Result(OBJC_AT_KEYWORD_NAME(NeedAt,end)));
Douglas Gregorb6ac2452010-01-13 21:24:21 +00002983
2984 CodeCompletionString *Pattern = 0;
2985 if (LangOpts.ObjC2) {
2986 // @dynamic
2987 Pattern = new CodeCompletionString;
2988 Pattern->AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt,dynamic));
2989 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
2990 Pattern->AddPlaceholderChunk("property");
Douglas Gregora4477812010-01-14 16:01:26 +00002991 Results.AddResult(Result(Pattern));
Douglas Gregorb6ac2452010-01-13 21:24:21 +00002992
2993 // @synthesize
2994 Pattern = new CodeCompletionString;
2995 Pattern->AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt,synthesize));
2996 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
2997 Pattern->AddPlaceholderChunk("property");
Douglas Gregora4477812010-01-14 16:01:26 +00002998 Results.AddResult(Result(Pattern));
Douglas Gregorb6ac2452010-01-13 21:24:21 +00002999 }
3000}
3001
Douglas Gregorbca403c2010-01-13 23:51:12 +00003002static void AddObjCInterfaceResults(const LangOptions &LangOpts,
Douglas Gregorb6ac2452010-01-13 21:24:21 +00003003 ResultBuilder &Results,
3004 bool NeedAt) {
3005 typedef CodeCompleteConsumer::Result Result;
3006
3007 // Since we have an interface or protocol, we can end it.
Douglas Gregora4477812010-01-14 16:01:26 +00003008 Results.AddResult(Result(OBJC_AT_KEYWORD_NAME(NeedAt,end)));
Douglas Gregorb6ac2452010-01-13 21:24:21 +00003009
3010 if (LangOpts.ObjC2) {
3011 // @property
Douglas Gregora4477812010-01-14 16:01:26 +00003012 Results.AddResult(Result(OBJC_AT_KEYWORD_NAME(NeedAt,property)));
Douglas Gregorb6ac2452010-01-13 21:24:21 +00003013
3014 // @required
Douglas Gregora4477812010-01-14 16:01:26 +00003015 Results.AddResult(Result(OBJC_AT_KEYWORD_NAME(NeedAt,required)));
Douglas Gregorb6ac2452010-01-13 21:24:21 +00003016
3017 // @optional
Douglas Gregora4477812010-01-14 16:01:26 +00003018 Results.AddResult(Result(OBJC_AT_KEYWORD_NAME(NeedAt,optional)));
Douglas Gregorb6ac2452010-01-13 21:24:21 +00003019 }
3020}
3021
Douglas Gregorbca403c2010-01-13 23:51:12 +00003022static void AddObjCTopLevelResults(ResultBuilder &Results, bool NeedAt) {
Douglas Gregorb6ac2452010-01-13 21:24:21 +00003023 typedef CodeCompleteConsumer::Result Result;
3024 CodeCompletionString *Pattern = 0;
3025
3026 // @class name ;
3027 Pattern = new CodeCompletionString;
3028 Pattern->AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt,class));
3029 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
Douglas Gregorc8bddde2010-05-28 00:22:41 +00003030 Pattern->AddPlaceholderChunk("name");
Douglas Gregora4477812010-01-14 16:01:26 +00003031 Results.AddResult(Result(Pattern));
Douglas Gregorb6ac2452010-01-13 21:24:21 +00003032
Douglas Gregorc8bddde2010-05-28 00:22:41 +00003033 if (Results.includeCodePatterns()) {
3034 // @interface name
3035 // FIXME: Could introduce the whole pattern, including superclasses and
3036 // such.
3037 Pattern = new CodeCompletionString;
3038 Pattern->AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt,interface));
3039 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
3040 Pattern->AddPlaceholderChunk("class");
3041 Results.AddResult(Result(Pattern));
Douglas Gregorb6ac2452010-01-13 21:24:21 +00003042
Douglas Gregorc8bddde2010-05-28 00:22:41 +00003043 // @protocol name
3044 Pattern = new CodeCompletionString;
3045 Pattern->AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt,protocol));
3046 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
3047 Pattern->AddPlaceholderChunk("protocol");
3048 Results.AddResult(Result(Pattern));
3049
3050 // @implementation name
3051 Pattern = new CodeCompletionString;
3052 Pattern->AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt,implementation));
3053 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
3054 Pattern->AddPlaceholderChunk("class");
3055 Results.AddResult(Result(Pattern));
3056 }
Douglas Gregorb6ac2452010-01-13 21:24:21 +00003057
3058 // @compatibility_alias name
3059 Pattern = new CodeCompletionString;
3060 Pattern->AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt,compatibility_alias));
3061 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
3062 Pattern->AddPlaceholderChunk("alias");
3063 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
3064 Pattern->AddPlaceholderChunk("class");
Douglas Gregora4477812010-01-14 16:01:26 +00003065 Results.AddResult(Result(Pattern));
Douglas Gregorb6ac2452010-01-13 21:24:21 +00003066}
3067
John McCalld226f652010-08-21 09:40:31 +00003068void Sema::CodeCompleteObjCAtDirective(Scope *S, Decl *ObjCImpDecl,
Douglas Gregorc464ae82009-12-07 09:27:33 +00003069 bool InInterface) {
3070 typedef CodeCompleteConsumer::Result Result;
3071 ResultBuilder Results(*this);
3072 Results.EnterNewScope();
Douglas Gregorb6ac2452010-01-13 21:24:21 +00003073 if (ObjCImpDecl)
Douglas Gregorbca403c2010-01-13 23:51:12 +00003074 AddObjCImplementationResults(getLangOptions(), Results, false);
Douglas Gregorb6ac2452010-01-13 21:24:21 +00003075 else if (InInterface)
Douglas Gregorbca403c2010-01-13 23:51:12 +00003076 AddObjCInterfaceResults(getLangOptions(), Results, false);
Douglas Gregorb6ac2452010-01-13 21:24:21 +00003077 else
Douglas Gregorbca403c2010-01-13 23:51:12 +00003078 AddObjCTopLevelResults(Results, false);
Douglas Gregorc464ae82009-12-07 09:27:33 +00003079 Results.ExitScope();
Douglas Gregore6b1bb62010-08-11 21:23:17 +00003080 HandleCodeCompleteResults(this, CodeCompleter,
3081 CodeCompletionContext::CCC_Other,
3082 Results.data(),Results.size());
Douglas Gregorc464ae82009-12-07 09:27:33 +00003083}
3084
Douglas Gregorbca403c2010-01-13 23:51:12 +00003085static void AddObjCExpressionResults(ResultBuilder &Results, bool NeedAt) {
Douglas Gregor9a0c85e2009-12-07 09:51:25 +00003086 typedef CodeCompleteConsumer::Result Result;
3087 CodeCompletionString *Pattern = 0;
3088
3089 // @encode ( type-name )
3090 Pattern = new CodeCompletionString;
Douglas Gregorb6ac2452010-01-13 21:24:21 +00003091 Pattern->AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt,encode));
Douglas Gregor9a0c85e2009-12-07 09:51:25 +00003092 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
3093 Pattern->AddPlaceholderChunk("type-name");
3094 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
Douglas Gregora4477812010-01-14 16:01:26 +00003095 Results.AddResult(Result(Pattern));
Douglas Gregor9a0c85e2009-12-07 09:51:25 +00003096
3097 // @protocol ( protocol-name )
3098 Pattern = new CodeCompletionString;
Douglas Gregorb6ac2452010-01-13 21:24:21 +00003099 Pattern->AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt,protocol));
Douglas Gregor9a0c85e2009-12-07 09:51:25 +00003100 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
3101 Pattern->AddPlaceholderChunk("protocol-name");
3102 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
Douglas Gregora4477812010-01-14 16:01:26 +00003103 Results.AddResult(Result(Pattern));
Douglas Gregor9a0c85e2009-12-07 09:51:25 +00003104
3105 // @selector ( selector )
3106 Pattern = new CodeCompletionString;
Douglas Gregorb6ac2452010-01-13 21:24:21 +00003107 Pattern->AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt,selector));
Douglas Gregor9a0c85e2009-12-07 09:51:25 +00003108 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
3109 Pattern->AddPlaceholderChunk("selector");
3110 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
Douglas Gregora4477812010-01-14 16:01:26 +00003111 Results.AddResult(Result(Pattern));
Douglas Gregor9a0c85e2009-12-07 09:51:25 +00003112}
3113
Douglas Gregorbca403c2010-01-13 23:51:12 +00003114static void AddObjCStatementResults(ResultBuilder &Results, bool NeedAt) {
Douglas Gregor9a0c85e2009-12-07 09:51:25 +00003115 typedef CodeCompleteConsumer::Result Result;
Douglas Gregor9a0c85e2009-12-07 09:51:25 +00003116 CodeCompletionString *Pattern = 0;
Douglas Gregorb6ac2452010-01-13 21:24:21 +00003117
Douglas Gregorc8bddde2010-05-28 00:22:41 +00003118 if (Results.includeCodePatterns()) {
3119 // @try { statements } @catch ( declaration ) { statements } @finally
3120 // { statements }
3121 Pattern = new CodeCompletionString;
3122 Pattern->AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt,try));
3123 Pattern->AddChunk(CodeCompletionString::CK_LeftBrace);
3124 Pattern->AddPlaceholderChunk("statements");
3125 Pattern->AddChunk(CodeCompletionString::CK_RightBrace);
3126 Pattern->AddTextChunk("@catch");
3127 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
3128 Pattern->AddPlaceholderChunk("parameter");
3129 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
3130 Pattern->AddChunk(CodeCompletionString::CK_LeftBrace);
3131 Pattern->AddPlaceholderChunk("statements");
3132 Pattern->AddChunk(CodeCompletionString::CK_RightBrace);
3133 Pattern->AddTextChunk("@finally");
3134 Pattern->AddChunk(CodeCompletionString::CK_LeftBrace);
3135 Pattern->AddPlaceholderChunk("statements");
3136 Pattern->AddChunk(CodeCompletionString::CK_RightBrace);
3137 Results.AddResult(Result(Pattern));
3138 }
Douglas Gregorb6ac2452010-01-13 21:24:21 +00003139
Douglas Gregor9a0c85e2009-12-07 09:51:25 +00003140 // @throw
3141 Pattern = new CodeCompletionString;
Douglas Gregorb6ac2452010-01-13 21:24:21 +00003142 Pattern->AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt,throw));
Douglas Gregor834389b2010-01-12 06:38:28 +00003143 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
Douglas Gregor9a0c85e2009-12-07 09:51:25 +00003144 Pattern->AddPlaceholderChunk("expression");
Douglas Gregora4477812010-01-14 16:01:26 +00003145 Results.AddResult(Result(Pattern));
Douglas Gregorb6ac2452010-01-13 21:24:21 +00003146
Douglas Gregorc8bddde2010-05-28 00:22:41 +00003147 if (Results.includeCodePatterns()) {
3148 // @synchronized ( expression ) { statements }
3149 Pattern = new CodeCompletionString;
3150 Pattern->AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt,synchronized));
3151 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
3152 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
3153 Pattern->AddPlaceholderChunk("expression");
3154 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
3155 Pattern->AddChunk(CodeCompletionString::CK_LeftBrace);
3156 Pattern->AddPlaceholderChunk("statements");
3157 Pattern->AddChunk(CodeCompletionString::CK_RightBrace);
3158 Results.AddResult(Result(Pattern));
3159 }
Douglas Gregorb6ac2452010-01-13 21:24:21 +00003160}
Douglas Gregor9a0c85e2009-12-07 09:51:25 +00003161
Douglas Gregorbca403c2010-01-13 23:51:12 +00003162static void AddObjCVisibilityResults(const LangOptions &LangOpts,
Douglas Gregorc38c3e12010-01-13 21:54:15 +00003163 ResultBuilder &Results,
3164 bool NeedAt) {
Douglas Gregorb6ac2452010-01-13 21:24:21 +00003165 typedef CodeCompleteConsumer::Result Result;
Douglas Gregora4477812010-01-14 16:01:26 +00003166 Results.AddResult(Result(OBJC_AT_KEYWORD_NAME(NeedAt,private)));
3167 Results.AddResult(Result(OBJC_AT_KEYWORD_NAME(NeedAt,protected)));
3168 Results.AddResult(Result(OBJC_AT_KEYWORD_NAME(NeedAt,public)));
Douglas Gregorc38c3e12010-01-13 21:54:15 +00003169 if (LangOpts.ObjC2)
Douglas Gregora4477812010-01-14 16:01:26 +00003170 Results.AddResult(Result(OBJC_AT_KEYWORD_NAME(NeedAt,package)));
Douglas Gregorc38c3e12010-01-13 21:54:15 +00003171}
3172
3173void Sema::CodeCompleteObjCAtVisibility(Scope *S) {
3174 ResultBuilder Results(*this);
3175 Results.EnterNewScope();
Douglas Gregorbca403c2010-01-13 23:51:12 +00003176 AddObjCVisibilityResults(getLangOptions(), Results, false);
Douglas Gregorc38c3e12010-01-13 21:54:15 +00003177 Results.ExitScope();
Douglas Gregore6b1bb62010-08-11 21:23:17 +00003178 HandleCodeCompleteResults(this, CodeCompleter,
3179 CodeCompletionContext::CCC_Other,
3180 Results.data(),Results.size());
Douglas Gregorc38c3e12010-01-13 21:54:15 +00003181}
3182
3183void Sema::CodeCompleteObjCAtStatement(Scope *S) {
Douglas Gregorb6ac2452010-01-13 21:24:21 +00003184 ResultBuilder Results(*this);
3185 Results.EnterNewScope();
Douglas Gregorbca403c2010-01-13 23:51:12 +00003186 AddObjCStatementResults(Results, false);
3187 AddObjCExpressionResults(Results, false);
Douglas Gregor9a0c85e2009-12-07 09:51:25 +00003188 Results.ExitScope();
Douglas Gregore6b1bb62010-08-11 21:23:17 +00003189 HandleCodeCompleteResults(this, CodeCompleter,
3190 CodeCompletionContext::CCC_Other,
3191 Results.data(),Results.size());
Douglas Gregor9a0c85e2009-12-07 09:51:25 +00003192}
3193
3194void Sema::CodeCompleteObjCAtExpression(Scope *S) {
3195 ResultBuilder Results(*this);
3196 Results.EnterNewScope();
Douglas Gregorbca403c2010-01-13 23:51:12 +00003197 AddObjCExpressionResults(Results, false);
Douglas Gregor9a0c85e2009-12-07 09:51:25 +00003198 Results.ExitScope();
Douglas Gregore6b1bb62010-08-11 21:23:17 +00003199 HandleCodeCompleteResults(this, CodeCompleter,
3200 CodeCompletionContext::CCC_Other,
3201 Results.data(),Results.size());
Douglas Gregor9a0c85e2009-12-07 09:51:25 +00003202}
3203
Douglas Gregor988358f2009-11-19 00:14:45 +00003204/// \brief Determine whether the addition of the given flag to an Objective-C
3205/// property's attributes will cause a conflict.
3206static bool ObjCPropertyFlagConflicts(unsigned Attributes, unsigned NewFlag) {
3207 // Check if we've already added this flag.
3208 if (Attributes & NewFlag)
3209 return true;
3210
3211 Attributes |= NewFlag;
3212
3213 // Check for collisions with "readonly".
3214 if ((Attributes & ObjCDeclSpec::DQ_PR_readonly) &&
3215 (Attributes & (ObjCDeclSpec::DQ_PR_readwrite |
3216 ObjCDeclSpec::DQ_PR_assign |
3217 ObjCDeclSpec::DQ_PR_copy |
3218 ObjCDeclSpec::DQ_PR_retain)))
3219 return true;
3220
3221 // Check for more than one of { assign, copy, retain }.
3222 unsigned AssignCopyRetMask = Attributes & (ObjCDeclSpec::DQ_PR_assign |
3223 ObjCDeclSpec::DQ_PR_copy |
3224 ObjCDeclSpec::DQ_PR_retain);
3225 if (AssignCopyRetMask &&
3226 AssignCopyRetMask != ObjCDeclSpec::DQ_PR_assign &&
3227 AssignCopyRetMask != ObjCDeclSpec::DQ_PR_copy &&
3228 AssignCopyRetMask != ObjCDeclSpec::DQ_PR_retain)
3229 return true;
3230
3231 return false;
3232}
3233
Douglas Gregora93b1082009-11-18 23:08:07 +00003234void Sema::CodeCompleteObjCPropertyFlags(Scope *S, ObjCDeclSpec &ODS) {
Steve Naroffece8e712009-10-08 21:55:05 +00003235 if (!CodeCompleter)
3236 return;
Douglas Gregord3c68542009-11-19 01:08:35 +00003237
Steve Naroffece8e712009-10-08 21:55:05 +00003238 unsigned Attributes = ODS.getPropertyAttributes();
3239
3240 typedef CodeCompleteConsumer::Result Result;
3241 ResultBuilder Results(*this);
3242 Results.EnterNewScope();
Douglas Gregor988358f2009-11-19 00:14:45 +00003243 if (!ObjCPropertyFlagConflicts(Attributes, ObjCDeclSpec::DQ_PR_readonly))
Douglas Gregora4477812010-01-14 16:01:26 +00003244 Results.AddResult(CodeCompleteConsumer::Result("readonly"));
Douglas Gregor988358f2009-11-19 00:14:45 +00003245 if (!ObjCPropertyFlagConflicts(Attributes, ObjCDeclSpec::DQ_PR_assign))
Douglas Gregora4477812010-01-14 16:01:26 +00003246 Results.AddResult(CodeCompleteConsumer::Result("assign"));
Douglas Gregor988358f2009-11-19 00:14:45 +00003247 if (!ObjCPropertyFlagConflicts(Attributes, ObjCDeclSpec::DQ_PR_readwrite))
Douglas Gregora4477812010-01-14 16:01:26 +00003248 Results.AddResult(CodeCompleteConsumer::Result("readwrite"));
Douglas Gregor988358f2009-11-19 00:14:45 +00003249 if (!ObjCPropertyFlagConflicts(Attributes, ObjCDeclSpec::DQ_PR_retain))
Douglas Gregora4477812010-01-14 16:01:26 +00003250 Results.AddResult(CodeCompleteConsumer::Result("retain"));
Douglas Gregor988358f2009-11-19 00:14:45 +00003251 if (!ObjCPropertyFlagConflicts(Attributes, ObjCDeclSpec::DQ_PR_copy))
Douglas Gregora4477812010-01-14 16:01:26 +00003252 Results.AddResult(CodeCompleteConsumer::Result("copy"));
Douglas Gregor988358f2009-11-19 00:14:45 +00003253 if (!ObjCPropertyFlagConflicts(Attributes, ObjCDeclSpec::DQ_PR_nonatomic))
Douglas Gregora4477812010-01-14 16:01:26 +00003254 Results.AddResult(CodeCompleteConsumer::Result("nonatomic"));
Douglas Gregor988358f2009-11-19 00:14:45 +00003255 if (!ObjCPropertyFlagConflicts(Attributes, ObjCDeclSpec::DQ_PR_setter)) {
Douglas Gregor54f01612009-11-19 00:01:57 +00003256 CodeCompletionString *Setter = new CodeCompletionString;
3257 Setter->AddTypedTextChunk("setter");
3258 Setter->AddTextChunk(" = ");
3259 Setter->AddPlaceholderChunk("method");
Douglas Gregora4477812010-01-14 16:01:26 +00003260 Results.AddResult(CodeCompleteConsumer::Result(Setter));
Douglas Gregor54f01612009-11-19 00:01:57 +00003261 }
Douglas Gregor988358f2009-11-19 00:14:45 +00003262 if (!ObjCPropertyFlagConflicts(Attributes, ObjCDeclSpec::DQ_PR_getter)) {
Douglas Gregor54f01612009-11-19 00:01:57 +00003263 CodeCompletionString *Getter = new CodeCompletionString;
3264 Getter->AddTypedTextChunk("getter");
3265 Getter->AddTextChunk(" = ");
3266 Getter->AddPlaceholderChunk("method");
Douglas Gregora4477812010-01-14 16:01:26 +00003267 Results.AddResult(CodeCompleteConsumer::Result(Getter));
Douglas Gregor54f01612009-11-19 00:01:57 +00003268 }
Steve Naroffece8e712009-10-08 21:55:05 +00003269 Results.ExitScope();
Douglas Gregore6b1bb62010-08-11 21:23:17 +00003270 HandleCodeCompleteResults(this, CodeCompleter,
3271 CodeCompletionContext::CCC_Other,
3272 Results.data(),Results.size());
Steve Naroffece8e712009-10-08 21:55:05 +00003273}
Steve Naroffc4df6d22009-11-07 02:08:14 +00003274
Douglas Gregor4ad96852009-11-19 07:41:15 +00003275/// \brief Descripts the kind of Objective-C method that we want to find
3276/// via code completion.
3277enum ObjCMethodKind {
3278 MK_Any, //< Any kind of method, provided it means other specified criteria.
3279 MK_ZeroArgSelector, //< Zero-argument (unary) selector.
3280 MK_OneArgSelector //< One-argument selector.
3281};
3282
3283static bool isAcceptableObjCMethod(ObjCMethodDecl *Method,
3284 ObjCMethodKind WantKind,
3285 IdentifierInfo **SelIdents,
3286 unsigned NumSelIdents) {
3287 Selector Sel = Method->getSelector();
3288 if (NumSelIdents > Sel.getNumArgs())
3289 return false;
3290
3291 switch (WantKind) {
3292 case MK_Any: break;
3293 case MK_ZeroArgSelector: return Sel.isUnarySelector();
3294 case MK_OneArgSelector: return Sel.getNumArgs() == 1;
3295 }
3296
3297 for (unsigned I = 0; I != NumSelIdents; ++I)
3298 if (SelIdents[I] != Sel.getIdentifierInfoForSlot(I))
3299 return false;
3300
3301 return true;
3302}
3303
Douglas Gregor36ecb042009-11-17 23:22:23 +00003304/// \brief Add all of the Objective-C methods in the given Objective-C
3305/// container to the set of results.
3306///
3307/// The container will be a class, protocol, category, or implementation of
3308/// any of the above. This mether will recurse to include methods from
3309/// the superclasses of classes along with their categories, protocols, and
3310/// implementations.
3311///
3312/// \param Container the container in which we'll look to find methods.
3313///
3314/// \param WantInstance whether to add instance methods (only); if false, this
3315/// routine will add factory methods (only).
3316///
3317/// \param CurContext the context in which we're performing the lookup that
3318/// finds methods.
3319///
3320/// \param Results the structure into which we'll add results.
3321static void AddObjCMethods(ObjCContainerDecl *Container,
3322 bool WantInstanceMethods,
Douglas Gregor4ad96852009-11-19 07:41:15 +00003323 ObjCMethodKind WantKind,
Douglas Gregord3c68542009-11-19 01:08:35 +00003324 IdentifierInfo **SelIdents,
3325 unsigned NumSelIdents,
Douglas Gregor36ecb042009-11-17 23:22:23 +00003326 DeclContext *CurContext,
3327 ResultBuilder &Results) {
3328 typedef CodeCompleteConsumer::Result Result;
3329 for (ObjCContainerDecl::method_iterator M = Container->meth_begin(),
3330 MEnd = Container->meth_end();
3331 M != MEnd; ++M) {
Douglas Gregord3c68542009-11-19 01:08:35 +00003332 if ((*M)->isInstanceMethod() == WantInstanceMethods) {
3333 // Check whether the selector identifiers we've been given are a
3334 // subset of the identifiers for this particular method.
Douglas Gregor4ad96852009-11-19 07:41:15 +00003335 if (!isAcceptableObjCMethod(*M, WantKind, SelIdents, NumSelIdents))
Douglas Gregord3c68542009-11-19 01:08:35 +00003336 continue;
Douglas Gregor4ad96852009-11-19 07:41:15 +00003337
Douglas Gregord3c68542009-11-19 01:08:35 +00003338 Result R = Result(*M, 0);
3339 R.StartParameter = NumSelIdents;
Douglas Gregor4ad96852009-11-19 07:41:15 +00003340 R.AllParametersAreInformative = (WantKind != MK_Any);
Douglas Gregord3c68542009-11-19 01:08:35 +00003341 Results.MaybeAddResult(R, CurContext);
3342 }
Douglas Gregor36ecb042009-11-17 23:22:23 +00003343 }
3344
3345 ObjCInterfaceDecl *IFace = dyn_cast<ObjCInterfaceDecl>(Container);
3346 if (!IFace)
3347 return;
3348
3349 // Add methods in protocols.
3350 const ObjCList<ObjCProtocolDecl> &Protocols= IFace->getReferencedProtocols();
3351 for (ObjCList<ObjCProtocolDecl>::iterator I = Protocols.begin(),
3352 E = Protocols.end();
3353 I != E; ++I)
Douglas Gregor4ad96852009-11-19 07:41:15 +00003354 AddObjCMethods(*I, WantInstanceMethods, WantKind, SelIdents, NumSelIdents,
Douglas Gregord3c68542009-11-19 01:08:35 +00003355 CurContext, Results);
Douglas Gregor36ecb042009-11-17 23:22:23 +00003356
3357 // Add methods in categories.
3358 for (ObjCCategoryDecl *CatDecl = IFace->getCategoryList(); CatDecl;
3359 CatDecl = CatDecl->getNextClassCategory()) {
Douglas Gregor4ad96852009-11-19 07:41:15 +00003360 AddObjCMethods(CatDecl, WantInstanceMethods, WantKind, SelIdents,
3361 NumSelIdents, CurContext, Results);
Douglas Gregor36ecb042009-11-17 23:22:23 +00003362
3363 // Add a categories protocol methods.
3364 const ObjCList<ObjCProtocolDecl> &Protocols
3365 = CatDecl->getReferencedProtocols();
3366 for (ObjCList<ObjCProtocolDecl>::iterator I = Protocols.begin(),
3367 E = Protocols.end();
3368 I != E; ++I)
Douglas Gregor4ad96852009-11-19 07:41:15 +00003369 AddObjCMethods(*I, WantInstanceMethods, WantKind, SelIdents,
3370 NumSelIdents, CurContext, Results);
Douglas Gregor36ecb042009-11-17 23:22:23 +00003371
3372 // Add methods in category implementations.
3373 if (ObjCCategoryImplDecl *Impl = CatDecl->getImplementation())
Douglas Gregor4ad96852009-11-19 07:41:15 +00003374 AddObjCMethods(Impl, WantInstanceMethods, WantKind, SelIdents,
3375 NumSelIdents, CurContext, Results);
Douglas Gregor36ecb042009-11-17 23:22:23 +00003376 }
3377
3378 // Add methods in superclass.
3379 if (IFace->getSuperClass())
Douglas Gregor4ad96852009-11-19 07:41:15 +00003380 AddObjCMethods(IFace->getSuperClass(), WantInstanceMethods, WantKind,
3381 SelIdents, NumSelIdents, CurContext, Results);
Douglas Gregor36ecb042009-11-17 23:22:23 +00003382
3383 // Add methods in our implementation, if any.
3384 if (ObjCImplementationDecl *Impl = IFace->getImplementation())
Douglas Gregor4ad96852009-11-19 07:41:15 +00003385 AddObjCMethods(Impl, WantInstanceMethods, WantKind, SelIdents,
3386 NumSelIdents, CurContext, Results);
3387}
3388
3389
John McCalld226f652010-08-21 09:40:31 +00003390void Sema::CodeCompleteObjCPropertyGetter(Scope *S, Decl *ClassDecl,
3391 Decl **Methods,
Douglas Gregor4ad96852009-11-19 07:41:15 +00003392 unsigned NumMethods) {
3393 typedef CodeCompleteConsumer::Result Result;
3394
3395 // Try to find the interface where getters might live.
John McCalld226f652010-08-21 09:40:31 +00003396 ObjCInterfaceDecl *Class = dyn_cast_or_null<ObjCInterfaceDecl>(ClassDecl);
Douglas Gregor4ad96852009-11-19 07:41:15 +00003397 if (!Class) {
3398 if (ObjCCategoryDecl *Category
John McCalld226f652010-08-21 09:40:31 +00003399 = dyn_cast_or_null<ObjCCategoryDecl>(ClassDecl))
Douglas Gregor4ad96852009-11-19 07:41:15 +00003400 Class = Category->getClassInterface();
3401
3402 if (!Class)
3403 return;
3404 }
3405
3406 // Find all of the potential getters.
3407 ResultBuilder Results(*this);
3408 Results.EnterNewScope();
3409
3410 // FIXME: We need to do this because Objective-C methods don't get
3411 // pushed into DeclContexts early enough. Argh!
3412 for (unsigned I = 0; I != NumMethods; ++I) {
3413 if (ObjCMethodDecl *Method
John McCalld226f652010-08-21 09:40:31 +00003414 = dyn_cast_or_null<ObjCMethodDecl>(Methods[I]))
Douglas Gregor4ad96852009-11-19 07:41:15 +00003415 if (Method->isInstanceMethod() &&
3416 isAcceptableObjCMethod(Method, MK_ZeroArgSelector, 0, 0)) {
3417 Result R = Result(Method, 0);
3418 R.AllParametersAreInformative = true;
3419 Results.MaybeAddResult(R, CurContext);
3420 }
3421 }
3422
3423 AddObjCMethods(Class, true, MK_ZeroArgSelector, 0, 0, CurContext, Results);
3424 Results.ExitScope();
Douglas Gregore6b1bb62010-08-11 21:23:17 +00003425 HandleCodeCompleteResults(this, CodeCompleter,
3426 CodeCompletionContext::CCC_Other,
3427 Results.data(),Results.size());
Douglas Gregor4ad96852009-11-19 07:41:15 +00003428}
3429
John McCalld226f652010-08-21 09:40:31 +00003430void Sema::CodeCompleteObjCPropertySetter(Scope *S, Decl *ObjCImplDecl,
3431 Decl **Methods,
Douglas Gregor4ad96852009-11-19 07:41:15 +00003432 unsigned NumMethods) {
3433 typedef CodeCompleteConsumer::Result Result;
3434
3435 // Try to find the interface where setters might live.
3436 ObjCInterfaceDecl *Class
John McCalld226f652010-08-21 09:40:31 +00003437 = dyn_cast_or_null<ObjCInterfaceDecl>(ObjCImplDecl);
Douglas Gregor4ad96852009-11-19 07:41:15 +00003438 if (!Class) {
3439 if (ObjCCategoryDecl *Category
John McCalld226f652010-08-21 09:40:31 +00003440 = dyn_cast_or_null<ObjCCategoryDecl>(ObjCImplDecl))
Douglas Gregor4ad96852009-11-19 07:41:15 +00003441 Class = Category->getClassInterface();
3442
3443 if (!Class)
3444 return;
3445 }
3446
3447 // Find all of the potential getters.
3448 ResultBuilder Results(*this);
3449 Results.EnterNewScope();
3450
3451 // FIXME: We need to do this because Objective-C methods don't get
3452 // pushed into DeclContexts early enough. Argh!
3453 for (unsigned I = 0; I != NumMethods; ++I) {
3454 if (ObjCMethodDecl *Method
John McCalld226f652010-08-21 09:40:31 +00003455 = dyn_cast_or_null<ObjCMethodDecl>(Methods[I]))
Douglas Gregor4ad96852009-11-19 07:41:15 +00003456 if (Method->isInstanceMethod() &&
3457 isAcceptableObjCMethod(Method, MK_OneArgSelector, 0, 0)) {
3458 Result R = Result(Method, 0);
3459 R.AllParametersAreInformative = true;
3460 Results.MaybeAddResult(R, CurContext);
3461 }
3462 }
3463
3464 AddObjCMethods(Class, true, MK_OneArgSelector, 0, 0, CurContext, Results);
3465
3466 Results.ExitScope();
Douglas Gregore6b1bb62010-08-11 21:23:17 +00003467 HandleCodeCompleteResults(this, CodeCompleter,
3468 CodeCompletionContext::CCC_Other,
3469 Results.data(),Results.size());
Douglas Gregor36ecb042009-11-17 23:22:23 +00003470}
3471
Douglas Gregor22f56992010-04-06 19:22:33 +00003472/// \brief When we have an expression with type "id", we may assume
3473/// that it has some more-specific class type based on knowledge of
3474/// common uses of Objective-C. This routine returns that class type,
3475/// or NULL if no better result could be determined.
3476static ObjCInterfaceDecl *GetAssumedMessageSendExprType(Expr *E) {
3477 ObjCMessageExpr *Msg = dyn_cast<ObjCMessageExpr>(E);
3478 if (!Msg)
3479 return 0;
3480
3481 Selector Sel = Msg->getSelector();
3482 if (Sel.isNull())
3483 return 0;
3484
3485 IdentifierInfo *Id = Sel.getIdentifierInfoForSlot(0);
3486 if (!Id)
3487 return 0;
3488
3489 ObjCMethodDecl *Method = Msg->getMethodDecl();
3490 if (!Method)
3491 return 0;
3492
3493 // Determine the class that we're sending the message to.
Douglas Gregor04badcf2010-04-21 00:45:42 +00003494 ObjCInterfaceDecl *IFace = 0;
3495 switch (Msg->getReceiverKind()) {
3496 case ObjCMessageExpr::Class:
John McCallc12c5bb2010-05-15 11:32:37 +00003497 if (const ObjCObjectType *ObjType
3498 = Msg->getClassReceiver()->getAs<ObjCObjectType>())
3499 IFace = ObjType->getInterface();
Douglas Gregor04badcf2010-04-21 00:45:42 +00003500 break;
3501
3502 case ObjCMessageExpr::Instance: {
3503 QualType T = Msg->getInstanceReceiver()->getType();
3504 if (const ObjCObjectPointerType *Ptr = T->getAs<ObjCObjectPointerType>())
3505 IFace = Ptr->getInterfaceDecl();
3506 break;
3507 }
3508
3509 case ObjCMessageExpr::SuperInstance:
3510 case ObjCMessageExpr::SuperClass:
3511 break;
Douglas Gregor22f56992010-04-06 19:22:33 +00003512 }
3513
3514 if (!IFace)
3515 return 0;
3516
3517 ObjCInterfaceDecl *Super = IFace->getSuperClass();
3518 if (Method->isInstanceMethod())
3519 return llvm::StringSwitch<ObjCInterfaceDecl *>(Id->getName())
3520 .Case("retain", IFace)
3521 .Case("autorelease", IFace)
3522 .Case("copy", IFace)
3523 .Case("copyWithZone", IFace)
3524 .Case("mutableCopy", IFace)
3525 .Case("mutableCopyWithZone", IFace)
3526 .Case("awakeFromCoder", IFace)
3527 .Case("replacementObjectFromCoder", IFace)
3528 .Case("class", IFace)
3529 .Case("classForCoder", IFace)
3530 .Case("superclass", Super)
3531 .Default(0);
3532
3533 return llvm::StringSwitch<ObjCInterfaceDecl *>(Id->getName())
3534 .Case("new", IFace)
3535 .Case("alloc", IFace)
3536 .Case("allocWithZone", IFace)
3537 .Case("class", IFace)
3538 .Case("superclass", Super)
3539 .Default(0);
3540}
3541
Douglas Gregor8e254cf2010-05-27 23:06:34 +00003542void Sema::CodeCompleteObjCMessageReceiver(Scope *S) {
3543 typedef CodeCompleteConsumer::Result Result;
3544 ResultBuilder Results(*this);
3545
3546 // Find anything that looks like it could be a message receiver.
3547 Results.setFilter(&ResultBuilder::IsObjCMessageReceiver);
3548 CodeCompletionDeclConsumer Consumer(Results, CurContext);
3549 Results.EnterNewScope();
Douglas Gregor8071e422010-08-15 06:18:01 +00003550 LookupVisibleDecls(S, LookupOrdinaryName, Consumer,
3551 CodeCompleter->includeGlobals());
Douglas Gregor8e254cf2010-05-27 23:06:34 +00003552
3553 // If we are in an Objective-C method inside a class that has a superclass,
3554 // add "super" as an option.
3555 if (ObjCMethodDecl *Method = getCurMethodDecl())
3556 if (ObjCInterfaceDecl *Iface = Method->getClassInterface())
3557 if (Iface->getSuperClass())
3558 Results.AddResult(Result("super"));
3559
3560 Results.ExitScope();
3561
3562 if (CodeCompleter->includeMacros())
3563 AddMacroResults(PP, Results);
Douglas Gregore6b1bb62010-08-11 21:23:17 +00003564 HandleCodeCompleteResults(this, CodeCompleter,
3565 CodeCompletionContext::CCC_ObjCMessageReceiver,
3566 Results.data(), Results.size());
Douglas Gregor8e254cf2010-05-27 23:06:34 +00003567
3568}
3569
Douglas Gregor2725ca82010-04-21 19:57:20 +00003570void Sema::CodeCompleteObjCSuperMessage(Scope *S, SourceLocation SuperLoc,
3571 IdentifierInfo **SelIdents,
3572 unsigned NumSelIdents) {
3573 ObjCInterfaceDecl *CDecl = 0;
3574 if (ObjCMethodDecl *CurMethod = getCurMethodDecl()) {
3575 // Figure out which interface we're in.
3576 CDecl = CurMethod->getClassInterface();
3577 if (!CDecl)
3578 return;
3579
3580 // Find the superclass of this class.
3581 CDecl = CDecl->getSuperClass();
3582 if (!CDecl)
3583 return;
3584
3585 if (CurMethod->isInstanceMethod()) {
3586 // We are inside an instance method, which means that the message
3587 // send [super ...] is actually calling an instance method on the
3588 // current object. Build the super expression and handle this like
3589 // an instance method.
3590 QualType SuperTy = Context.getObjCInterfaceType(CDecl);
3591 SuperTy = Context.getObjCObjectPointerType(SuperTy);
3592 OwningExprResult Super
3593 = Owned(new (Context) ObjCSuperExpr(SuperLoc, SuperTy));
3594 return CodeCompleteObjCInstanceMessage(S, (Expr *)Super.get(),
3595 SelIdents, NumSelIdents);
3596 }
3597
3598 // Fall through to send to the superclass in CDecl.
3599 } else {
3600 // "super" may be the name of a type or variable. Figure out which
3601 // it is.
3602 IdentifierInfo *Super = &Context.Idents.get("super");
3603 NamedDecl *ND = LookupSingleName(S, Super, SuperLoc,
3604 LookupOrdinaryName);
3605 if ((CDecl = dyn_cast_or_null<ObjCInterfaceDecl>(ND))) {
3606 // "super" names an interface. Use it.
3607 } else if (TypeDecl *TD = dyn_cast_or_null<TypeDecl>(ND)) {
John McCallc12c5bb2010-05-15 11:32:37 +00003608 if (const ObjCObjectType *Iface
3609 = Context.getTypeDeclType(TD)->getAs<ObjCObjectType>())
3610 CDecl = Iface->getInterface();
Douglas Gregor2725ca82010-04-21 19:57:20 +00003611 } else if (ND && isa<UnresolvedUsingTypenameDecl>(ND)) {
3612 // "super" names an unresolved type; we can't be more specific.
3613 } else {
3614 // Assume that "super" names some kind of value and parse that way.
3615 CXXScopeSpec SS;
3616 UnqualifiedId id;
3617 id.setIdentifier(Super, SuperLoc);
3618 OwningExprResult SuperExpr = ActOnIdExpression(S, SS, id, false, false);
3619 return CodeCompleteObjCInstanceMessage(S, (Expr *)SuperExpr.get(),
3620 SelIdents, NumSelIdents);
3621 }
3622
3623 // Fall through
3624 }
3625
3626 TypeTy *Receiver = 0;
3627 if (CDecl)
3628 Receiver = Context.getObjCInterfaceType(CDecl).getAsOpaquePtr();
3629 return CodeCompleteObjCClassMessage(S, Receiver, SelIdents,
3630 NumSelIdents);
3631}
3632
3633void Sema::CodeCompleteObjCClassMessage(Scope *S, TypeTy *Receiver,
Douglas Gregord3c68542009-11-19 01:08:35 +00003634 IdentifierInfo **SelIdents,
3635 unsigned NumSelIdents) {
Steve Naroffc4df6d22009-11-07 02:08:14 +00003636 typedef CodeCompleteConsumer::Result Result;
Douglas Gregor24a069f2009-11-17 17:59:40 +00003637 ObjCInterfaceDecl *CDecl = 0;
3638
Douglas Gregor24a069f2009-11-17 17:59:40 +00003639 // If the given name refers to an interface type, retrieve the
3640 // corresponding declaration.
Douglas Gregor2725ca82010-04-21 19:57:20 +00003641 if (Receiver) {
3642 QualType T = GetTypeFromParser(Receiver, 0);
3643 if (!T.isNull())
John McCallc12c5bb2010-05-15 11:32:37 +00003644 if (const ObjCObjectType *Interface = T->getAs<ObjCObjectType>())
3645 CDecl = Interface->getInterface();
Douglas Gregor24a069f2009-11-17 17:59:40 +00003646 }
3647
Douglas Gregor36ecb042009-11-17 23:22:23 +00003648 // Add all of the factory methods in this Objective-C class, its protocols,
3649 // superclasses, categories, implementation, etc.
Steve Naroffc4df6d22009-11-07 02:08:14 +00003650 ResultBuilder Results(*this);
3651 Results.EnterNewScope();
Douglas Gregor13438f92010-04-06 16:40:00 +00003652
3653 if (CDecl)
3654 AddObjCMethods(CDecl, false, MK_Any, SelIdents, NumSelIdents, CurContext,
3655 Results);
Douglas Gregor2725ca82010-04-21 19:57:20 +00003656 else {
Douglas Gregor13438f92010-04-06 16:40:00 +00003657 // We're messaging "id" as a type; provide all class/factory methods.
3658
Douglas Gregor719770d2010-04-06 17:30:22 +00003659 // If we have an external source, load the entire class method
Sebastian Redl3c7f4132010-08-18 23:57:06 +00003660 // pool from the AST file.
Douglas Gregor719770d2010-04-06 17:30:22 +00003661 if (ExternalSource) {
John McCall76bd1f32010-06-01 09:23:16 +00003662 for (uint32_t I = 0, N = ExternalSource->GetNumExternalSelectors();
3663 I != N; ++I) {
3664 Selector Sel = ExternalSource->GetExternalSelector(I);
Sebastian Redldb9d2142010-08-02 23:18:59 +00003665 if (Sel.isNull() || MethodPool.count(Sel))
Douglas Gregor719770d2010-04-06 17:30:22 +00003666 continue;
3667
Sebastian Redldb9d2142010-08-02 23:18:59 +00003668 ReadMethodPool(Sel);
Douglas Gregor719770d2010-04-06 17:30:22 +00003669 }
3670 }
3671
Sebastian Redldb9d2142010-08-02 23:18:59 +00003672 for (GlobalMethodPool::iterator M = MethodPool.begin(),
3673 MEnd = MethodPool.end();
3674 M != MEnd; ++M) {
3675 for (ObjCMethodList *MethList = &M->second.second;
3676 MethList && MethList->Method;
Douglas Gregor13438f92010-04-06 16:40:00 +00003677 MethList = MethList->Next) {
3678 if (!isAcceptableObjCMethod(MethList->Method, MK_Any, SelIdents,
3679 NumSelIdents))
3680 continue;
3681
3682 Result R(MethList->Method, 0);
3683 R.StartParameter = NumSelIdents;
3684 R.AllParametersAreInformative = false;
3685 Results.MaybeAddResult(R, CurContext);
3686 }
3687 }
3688 }
3689
Steve Naroffc4df6d22009-11-07 02:08:14 +00003690 Results.ExitScope();
Douglas Gregore6b1bb62010-08-11 21:23:17 +00003691 HandleCodeCompleteResults(this, CodeCompleter,
3692 CodeCompletionContext::CCC_Other,
3693 Results.data(),Results.size());
Steve Naroffc4df6d22009-11-07 02:08:14 +00003694}
3695
Douglas Gregord3c68542009-11-19 01:08:35 +00003696void Sema::CodeCompleteObjCInstanceMessage(Scope *S, ExprTy *Receiver,
3697 IdentifierInfo **SelIdents,
3698 unsigned NumSelIdents) {
Steve Naroffc4df6d22009-11-07 02:08:14 +00003699 typedef CodeCompleteConsumer::Result Result;
Steve Naroffc4df6d22009-11-07 02:08:14 +00003700
3701 Expr *RecExpr = static_cast<Expr *>(Receiver);
Steve Naroffc4df6d22009-11-07 02:08:14 +00003702
Douglas Gregor36ecb042009-11-17 23:22:23 +00003703 // If necessary, apply function/array conversion to the receiver.
3704 // C99 6.7.5.3p[7,8].
Douglas Gregora873dfc2010-02-03 00:27:59 +00003705 DefaultFunctionArrayLvalueConversion(RecExpr);
Douglas Gregor36ecb042009-11-17 23:22:23 +00003706 QualType ReceiverType = RecExpr->getType();
Steve Naroffc4df6d22009-11-07 02:08:14 +00003707
Douglas Gregor36ecb042009-11-17 23:22:23 +00003708 // Build the set of methods we can see.
3709 ResultBuilder Results(*this);
3710 Results.EnterNewScope();
Douglas Gregor22f56992010-04-06 19:22:33 +00003711
3712 // If we're messaging an expression with type "id" or "Class", check
3713 // whether we know something special about the receiver that allows
3714 // us to assume a more-specific receiver type.
3715 if (ReceiverType->isObjCIdType() || ReceiverType->isObjCClassType())
3716 if (ObjCInterfaceDecl *IFace = GetAssumedMessageSendExprType(RecExpr))
3717 ReceiverType = Context.getObjCObjectPointerType(
3718 Context.getObjCInterfaceType(IFace));
Douglas Gregor36ecb042009-11-17 23:22:23 +00003719
Douglas Gregorf74a4192009-11-18 00:06:18 +00003720 // Handle messages to Class. This really isn't a message to an instance
3721 // method, so we treat it the same way we would treat a message send to a
3722 // class method.
3723 if (ReceiverType->isObjCClassType() ||
3724 ReceiverType->isObjCQualifiedClassType()) {
3725 if (ObjCMethodDecl *CurMethod = getCurMethodDecl()) {
3726 if (ObjCInterfaceDecl *ClassDecl = CurMethod->getClassInterface())
Douglas Gregor4ad96852009-11-19 07:41:15 +00003727 AddObjCMethods(ClassDecl, false, MK_Any, SelIdents, NumSelIdents,
3728 CurContext, Results);
Douglas Gregorf74a4192009-11-18 00:06:18 +00003729 }
3730 }
3731 // Handle messages to a qualified ID ("id<foo>").
3732 else if (const ObjCObjectPointerType *QualID
3733 = ReceiverType->getAsObjCQualifiedIdType()) {
3734 // Search protocols for instance methods.
3735 for (ObjCObjectPointerType::qual_iterator I = QualID->qual_begin(),
3736 E = QualID->qual_end();
3737 I != E; ++I)
Douglas Gregor4ad96852009-11-19 07:41:15 +00003738 AddObjCMethods(*I, true, MK_Any, SelIdents, NumSelIdents, CurContext,
3739 Results);
Douglas Gregorf74a4192009-11-18 00:06:18 +00003740 }
3741 // Handle messages to a pointer to interface type.
3742 else if (const ObjCObjectPointerType *IFacePtr
3743 = ReceiverType->getAsObjCInterfacePointerType()) {
3744 // Search the class, its superclasses, etc., for instance methods.
Douglas Gregor4ad96852009-11-19 07:41:15 +00003745 AddObjCMethods(IFacePtr->getInterfaceDecl(), true, MK_Any, SelIdents,
3746 NumSelIdents, CurContext, Results);
Douglas Gregorf74a4192009-11-18 00:06:18 +00003747
3748 // Search protocols for instance methods.
3749 for (ObjCObjectPointerType::qual_iterator I = IFacePtr->qual_begin(),
3750 E = IFacePtr->qual_end();
3751 I != E; ++I)
Douglas Gregor4ad96852009-11-19 07:41:15 +00003752 AddObjCMethods(*I, true, MK_Any, SelIdents, NumSelIdents, CurContext,
3753 Results);
Douglas Gregorf74a4192009-11-18 00:06:18 +00003754 }
Douglas Gregor13438f92010-04-06 16:40:00 +00003755 // Handle messages to "id".
3756 else if (ReceiverType->isObjCIdType()) {
Douglas Gregor719770d2010-04-06 17:30:22 +00003757 // We're messaging "id", so provide all instance methods we know
3758 // about as code-completion results.
3759
3760 // If we have an external source, load the entire class method
Sebastian Redl3c7f4132010-08-18 23:57:06 +00003761 // pool from the AST file.
Douglas Gregor719770d2010-04-06 17:30:22 +00003762 if (ExternalSource) {
John McCall76bd1f32010-06-01 09:23:16 +00003763 for (uint32_t I = 0, N = ExternalSource->GetNumExternalSelectors();
3764 I != N; ++I) {
3765 Selector Sel = ExternalSource->GetExternalSelector(I);
Sebastian Redldb9d2142010-08-02 23:18:59 +00003766 if (Sel.isNull() || MethodPool.count(Sel))
Douglas Gregor719770d2010-04-06 17:30:22 +00003767 continue;
3768
Sebastian Redldb9d2142010-08-02 23:18:59 +00003769 ReadMethodPool(Sel);
Douglas Gregor719770d2010-04-06 17:30:22 +00003770 }
3771 }
3772
Sebastian Redldb9d2142010-08-02 23:18:59 +00003773 for (GlobalMethodPool::iterator M = MethodPool.begin(),
3774 MEnd = MethodPool.end();
3775 M != MEnd; ++M) {
3776 for (ObjCMethodList *MethList = &M->second.first;
3777 MethList && MethList->Method;
Douglas Gregor13438f92010-04-06 16:40:00 +00003778 MethList = MethList->Next) {
3779 if (!isAcceptableObjCMethod(MethList->Method, MK_Any, SelIdents,
3780 NumSelIdents))
3781 continue;
3782
3783 Result R(MethList->Method, 0);
3784 R.StartParameter = NumSelIdents;
3785 R.AllParametersAreInformative = false;
3786 Results.MaybeAddResult(R, CurContext);
3787 }
3788 }
3789 }
3790
Steve Naroffc4df6d22009-11-07 02:08:14 +00003791 Results.ExitScope();
Douglas Gregore6b1bb62010-08-11 21:23:17 +00003792 HandleCodeCompleteResults(this, CodeCompleter,
3793 CodeCompletionContext::CCC_Other,
3794 Results.data(),Results.size());
Steve Naroffc4df6d22009-11-07 02:08:14 +00003795}
Douglas Gregor55385fe2009-11-18 04:19:12 +00003796
Douglas Gregorfb629412010-08-23 21:17:50 +00003797void Sema::CodeCompleteObjCForCollection(Scope *S,
3798 DeclGroupPtrTy IterationVar) {
3799 CodeCompleteExpressionData Data;
3800 Data.ObjCCollection = true;
3801
3802 if (IterationVar.getAsOpaquePtr()) {
3803 DeclGroupRef DG = IterationVar.getAsVal<DeclGroupRef>();
3804 for (DeclGroupRef::iterator I = DG.begin(), End = DG.end(); I != End; ++I) {
3805 if (*I)
3806 Data.IgnoreDecls.push_back(*I);
3807 }
3808 }
3809
3810 CodeCompleteExpression(S, Data);
3811}
3812
Douglas Gregor55385fe2009-11-18 04:19:12 +00003813/// \brief Add all of the protocol declarations that we find in the given
3814/// (translation unit) context.
3815static void AddProtocolResults(DeclContext *Ctx, DeclContext *CurContext,
Douglas Gregor083128f2009-11-18 04:49:41 +00003816 bool OnlyForwardDeclarations,
Douglas Gregor55385fe2009-11-18 04:19:12 +00003817 ResultBuilder &Results) {
3818 typedef CodeCompleteConsumer::Result Result;
3819
3820 for (DeclContext::decl_iterator D = Ctx->decls_begin(),
3821 DEnd = Ctx->decls_end();
3822 D != DEnd; ++D) {
3823 // Record any protocols we find.
3824 if (ObjCProtocolDecl *Proto = dyn_cast<ObjCProtocolDecl>(*D))
Douglas Gregor083128f2009-11-18 04:49:41 +00003825 if (!OnlyForwardDeclarations || Proto->isForwardDecl())
Douglas Gregor608300b2010-01-14 16:14:35 +00003826 Results.AddResult(Result(Proto, 0), CurContext, 0, false);
Douglas Gregor55385fe2009-11-18 04:19:12 +00003827
3828 // Record any forward-declared protocols we find.
3829 if (ObjCForwardProtocolDecl *Forward
3830 = dyn_cast<ObjCForwardProtocolDecl>(*D)) {
3831 for (ObjCForwardProtocolDecl::protocol_iterator
3832 P = Forward->protocol_begin(),
3833 PEnd = Forward->protocol_end();
3834 P != PEnd; ++P)
Douglas Gregor083128f2009-11-18 04:49:41 +00003835 if (!OnlyForwardDeclarations || (*P)->isForwardDecl())
Douglas Gregor608300b2010-01-14 16:14:35 +00003836 Results.AddResult(Result(*P, 0), CurContext, 0, false);
Douglas Gregor55385fe2009-11-18 04:19:12 +00003837 }
3838 }
3839}
3840
3841void Sema::CodeCompleteObjCProtocolReferences(IdentifierLocPair *Protocols,
3842 unsigned NumProtocols) {
3843 ResultBuilder Results(*this);
3844 Results.EnterNewScope();
3845
3846 // Tell the result set to ignore all of the protocols we have
3847 // already seen.
3848 for (unsigned I = 0; I != NumProtocols; ++I)
Douglas Gregorc83c6872010-04-15 22:33:43 +00003849 if (ObjCProtocolDecl *Protocol = LookupProtocol(Protocols[I].first,
3850 Protocols[I].second))
Douglas Gregor55385fe2009-11-18 04:19:12 +00003851 Results.Ignore(Protocol);
3852
3853 // Add all protocols.
Douglas Gregor083128f2009-11-18 04:49:41 +00003854 AddProtocolResults(Context.getTranslationUnitDecl(), CurContext, false,
3855 Results);
3856
3857 Results.ExitScope();
Douglas Gregore6b1bb62010-08-11 21:23:17 +00003858 HandleCodeCompleteResults(this, CodeCompleter,
3859 CodeCompletionContext::CCC_ObjCProtocolName,
3860 Results.data(),Results.size());
Douglas Gregor083128f2009-11-18 04:49:41 +00003861}
3862
3863void Sema::CodeCompleteObjCProtocolDecl(Scope *) {
3864 ResultBuilder Results(*this);
3865 Results.EnterNewScope();
3866
3867 // Add all protocols.
3868 AddProtocolResults(Context.getTranslationUnitDecl(), CurContext, true,
3869 Results);
Douglas Gregor55385fe2009-11-18 04:19:12 +00003870
3871 Results.ExitScope();
Douglas Gregore6b1bb62010-08-11 21:23:17 +00003872 HandleCodeCompleteResults(this, CodeCompleter,
3873 CodeCompletionContext::CCC_ObjCProtocolName,
3874 Results.data(),Results.size());
Douglas Gregor55385fe2009-11-18 04:19:12 +00003875}
Douglas Gregor3b49aca2009-11-18 16:26:39 +00003876
3877/// \brief Add all of the Objective-C interface declarations that we find in
3878/// the given (translation unit) context.
3879static void AddInterfaceResults(DeclContext *Ctx, DeclContext *CurContext,
3880 bool OnlyForwardDeclarations,
3881 bool OnlyUnimplemented,
3882 ResultBuilder &Results) {
3883 typedef CodeCompleteConsumer::Result Result;
3884
3885 for (DeclContext::decl_iterator D = Ctx->decls_begin(),
3886 DEnd = Ctx->decls_end();
3887 D != DEnd; ++D) {
Douglas Gregordeacbdc2010-08-11 12:19:30 +00003888 // Record any interfaces we find.
3889 if (ObjCInterfaceDecl *Class = dyn_cast<ObjCInterfaceDecl>(*D))
3890 if ((!OnlyForwardDeclarations || Class->isForwardDecl()) &&
3891 (!OnlyUnimplemented || !Class->getImplementation()))
3892 Results.AddResult(Result(Class, 0), CurContext, 0, false);
Douglas Gregor3b49aca2009-11-18 16:26:39 +00003893
3894 // Record any forward-declared interfaces we find.
3895 if (ObjCClassDecl *Forward = dyn_cast<ObjCClassDecl>(*D)) {
3896 for (ObjCClassDecl::iterator C = Forward->begin(), CEnd = Forward->end();
Douglas Gregordeacbdc2010-08-11 12:19:30 +00003897 C != CEnd; ++C)
3898 if ((!OnlyForwardDeclarations || C->getInterface()->isForwardDecl()) &&
3899 (!OnlyUnimplemented || !C->getInterface()->getImplementation()))
3900 Results.AddResult(Result(C->getInterface(), 0), CurContext,
Douglas Gregor608300b2010-01-14 16:14:35 +00003901 0, false);
Douglas Gregor3b49aca2009-11-18 16:26:39 +00003902 }
3903 }
3904}
3905
3906void Sema::CodeCompleteObjCInterfaceDecl(Scope *S) {
3907 ResultBuilder Results(*this);
3908 Results.EnterNewScope();
3909
3910 // Add all classes.
3911 AddInterfaceResults(Context.getTranslationUnitDecl(), CurContext, true,
3912 false, Results);
3913
3914 Results.ExitScope();
Douglas Gregore6b1bb62010-08-11 21:23:17 +00003915 HandleCodeCompleteResults(this, CodeCompleter,
3916 CodeCompletionContext::CCC_Other,
3917 Results.data(),Results.size());
Douglas Gregor3b49aca2009-11-18 16:26:39 +00003918}
3919
Douglas Gregorc83c6872010-04-15 22:33:43 +00003920void Sema::CodeCompleteObjCSuperclass(Scope *S, IdentifierInfo *ClassName,
3921 SourceLocation ClassNameLoc) {
Douglas Gregor3b49aca2009-11-18 16:26:39 +00003922 ResultBuilder Results(*this);
3923 Results.EnterNewScope();
3924
3925 // Make sure that we ignore the class we're currently defining.
3926 NamedDecl *CurClass
Douglas Gregorc83c6872010-04-15 22:33:43 +00003927 = LookupSingleName(TUScope, ClassName, ClassNameLoc, LookupOrdinaryName);
Douglas Gregor33ced0b2009-11-18 19:08:43 +00003928 if (CurClass && isa<ObjCInterfaceDecl>(CurClass))
Douglas Gregor3b49aca2009-11-18 16:26:39 +00003929 Results.Ignore(CurClass);
3930
3931 // Add all classes.
3932 AddInterfaceResults(Context.getTranslationUnitDecl(), CurContext, false,
3933 false, Results);
3934
3935 Results.ExitScope();
Douglas Gregore6b1bb62010-08-11 21:23:17 +00003936 HandleCodeCompleteResults(this, CodeCompleter,
3937 CodeCompletionContext::CCC_Other,
3938 Results.data(),Results.size());
Douglas Gregor3b49aca2009-11-18 16:26:39 +00003939}
3940
3941void Sema::CodeCompleteObjCImplementationDecl(Scope *S) {
3942 ResultBuilder Results(*this);
3943 Results.EnterNewScope();
3944
3945 // Add all unimplemented classes.
3946 AddInterfaceResults(Context.getTranslationUnitDecl(), CurContext, false,
3947 true, Results);
3948
3949 Results.ExitScope();
Douglas Gregore6b1bb62010-08-11 21:23:17 +00003950 HandleCodeCompleteResults(this, CodeCompleter,
3951 CodeCompletionContext::CCC_Other,
3952 Results.data(),Results.size());
Douglas Gregor3b49aca2009-11-18 16:26:39 +00003953}
Douglas Gregor33ced0b2009-11-18 19:08:43 +00003954
3955void Sema::CodeCompleteObjCInterfaceCategory(Scope *S,
Douglas Gregorc83c6872010-04-15 22:33:43 +00003956 IdentifierInfo *ClassName,
3957 SourceLocation ClassNameLoc) {
Douglas Gregor33ced0b2009-11-18 19:08:43 +00003958 typedef CodeCompleteConsumer::Result Result;
3959
3960 ResultBuilder Results(*this);
3961
3962 // Ignore any categories we find that have already been implemented by this
3963 // interface.
3964 llvm::SmallPtrSet<IdentifierInfo *, 16> CategoryNames;
3965 NamedDecl *CurClass
Douglas Gregorc83c6872010-04-15 22:33:43 +00003966 = LookupSingleName(TUScope, ClassName, ClassNameLoc, LookupOrdinaryName);
Douglas Gregor33ced0b2009-11-18 19:08:43 +00003967 if (ObjCInterfaceDecl *Class = dyn_cast_or_null<ObjCInterfaceDecl>(CurClass))
3968 for (ObjCCategoryDecl *Category = Class->getCategoryList(); Category;
3969 Category = Category->getNextClassCategory())
3970 CategoryNames.insert(Category->getIdentifier());
3971
3972 // Add all of the categories we know about.
3973 Results.EnterNewScope();
3974 TranslationUnitDecl *TU = Context.getTranslationUnitDecl();
3975 for (DeclContext::decl_iterator D = TU->decls_begin(),
3976 DEnd = TU->decls_end();
3977 D != DEnd; ++D)
3978 if (ObjCCategoryDecl *Category = dyn_cast<ObjCCategoryDecl>(*D))
3979 if (CategoryNames.insert(Category->getIdentifier()))
Douglas Gregor608300b2010-01-14 16:14:35 +00003980 Results.AddResult(Result(Category, 0), CurContext, 0, false);
Douglas Gregor33ced0b2009-11-18 19:08:43 +00003981 Results.ExitScope();
3982
Douglas Gregore6b1bb62010-08-11 21:23:17 +00003983 HandleCodeCompleteResults(this, CodeCompleter,
3984 CodeCompletionContext::CCC_Other,
3985 Results.data(),Results.size());
Douglas Gregor33ced0b2009-11-18 19:08:43 +00003986}
3987
3988void Sema::CodeCompleteObjCImplementationCategory(Scope *S,
Douglas Gregorc83c6872010-04-15 22:33:43 +00003989 IdentifierInfo *ClassName,
3990 SourceLocation ClassNameLoc) {
Douglas Gregor33ced0b2009-11-18 19:08:43 +00003991 typedef CodeCompleteConsumer::Result Result;
3992
3993 // Find the corresponding interface. If we couldn't find the interface, the
3994 // program itself is ill-formed. However, we'll try to be helpful still by
3995 // providing the list of all of the categories we know about.
3996 NamedDecl *CurClass
Douglas Gregorc83c6872010-04-15 22:33:43 +00003997 = LookupSingleName(TUScope, ClassName, ClassNameLoc, LookupOrdinaryName);
Douglas Gregor33ced0b2009-11-18 19:08:43 +00003998 ObjCInterfaceDecl *Class = dyn_cast_or_null<ObjCInterfaceDecl>(CurClass);
3999 if (!Class)
Douglas Gregorc83c6872010-04-15 22:33:43 +00004000 return CodeCompleteObjCInterfaceCategory(S, ClassName, ClassNameLoc);
Douglas Gregor33ced0b2009-11-18 19:08:43 +00004001
4002 ResultBuilder Results(*this);
4003
4004 // Add all of the categories that have have corresponding interface
4005 // declarations in this class and any of its superclasses, except for
4006 // already-implemented categories in the class itself.
4007 llvm::SmallPtrSet<IdentifierInfo *, 16> CategoryNames;
4008 Results.EnterNewScope();
4009 bool IgnoreImplemented = true;
4010 while (Class) {
4011 for (ObjCCategoryDecl *Category = Class->getCategoryList(); Category;
4012 Category = Category->getNextClassCategory())
4013 if ((!IgnoreImplemented || !Category->getImplementation()) &&
4014 CategoryNames.insert(Category->getIdentifier()))
Douglas Gregor608300b2010-01-14 16:14:35 +00004015 Results.AddResult(Result(Category, 0), CurContext, 0, false);
Douglas Gregor33ced0b2009-11-18 19:08:43 +00004016
4017 Class = Class->getSuperClass();
4018 IgnoreImplemented = false;
4019 }
4020 Results.ExitScope();
4021
Douglas Gregore6b1bb62010-08-11 21:23:17 +00004022 HandleCodeCompleteResults(this, CodeCompleter,
4023 CodeCompletionContext::CCC_Other,
4024 Results.data(),Results.size());
Douglas Gregor33ced0b2009-11-18 19:08:43 +00004025}
Douglas Gregor322328b2009-11-18 22:32:06 +00004026
John McCalld226f652010-08-21 09:40:31 +00004027void Sema::CodeCompleteObjCPropertyDefinition(Scope *S, Decl *ObjCImpDecl) {
Douglas Gregor322328b2009-11-18 22:32:06 +00004028 typedef CodeCompleteConsumer::Result Result;
4029 ResultBuilder Results(*this);
4030
4031 // Figure out where this @synthesize lives.
4032 ObjCContainerDecl *Container
John McCalld226f652010-08-21 09:40:31 +00004033 = dyn_cast_or_null<ObjCContainerDecl>(ObjCImpDecl);
Douglas Gregor322328b2009-11-18 22:32:06 +00004034 if (!Container ||
4035 (!isa<ObjCImplementationDecl>(Container) &&
4036 !isa<ObjCCategoryImplDecl>(Container)))
4037 return;
4038
4039 // Ignore any properties that have already been implemented.
4040 for (DeclContext::decl_iterator D = Container->decls_begin(),
4041 DEnd = Container->decls_end();
4042 D != DEnd; ++D)
4043 if (ObjCPropertyImplDecl *PropertyImpl = dyn_cast<ObjCPropertyImplDecl>(*D))
4044 Results.Ignore(PropertyImpl->getPropertyDecl());
4045
4046 // Add any properties that we find.
4047 Results.EnterNewScope();
4048 if (ObjCImplementationDecl *ClassImpl
4049 = dyn_cast<ObjCImplementationDecl>(Container))
4050 AddObjCProperties(ClassImpl->getClassInterface(), false, CurContext,
4051 Results);
4052 else
4053 AddObjCProperties(cast<ObjCCategoryImplDecl>(Container)->getCategoryDecl(),
4054 false, CurContext, Results);
4055 Results.ExitScope();
4056
Douglas Gregore6b1bb62010-08-11 21:23:17 +00004057 HandleCodeCompleteResults(this, CodeCompleter,
4058 CodeCompletionContext::CCC_Other,
4059 Results.data(),Results.size());
Douglas Gregor322328b2009-11-18 22:32:06 +00004060}
4061
4062void Sema::CodeCompleteObjCPropertySynthesizeIvar(Scope *S,
4063 IdentifierInfo *PropertyName,
John McCalld226f652010-08-21 09:40:31 +00004064 Decl *ObjCImpDecl) {
Douglas Gregor322328b2009-11-18 22:32:06 +00004065 typedef CodeCompleteConsumer::Result Result;
4066 ResultBuilder Results(*this);
4067
4068 // Figure out where this @synthesize lives.
4069 ObjCContainerDecl *Container
John McCalld226f652010-08-21 09:40:31 +00004070 = dyn_cast_or_null<ObjCContainerDecl>(ObjCImpDecl);
Douglas Gregor322328b2009-11-18 22:32:06 +00004071 if (!Container ||
4072 (!isa<ObjCImplementationDecl>(Container) &&
4073 !isa<ObjCCategoryImplDecl>(Container)))
4074 return;
4075
4076 // Figure out which interface we're looking into.
4077 ObjCInterfaceDecl *Class = 0;
4078 if (ObjCImplementationDecl *ClassImpl
4079 = dyn_cast<ObjCImplementationDecl>(Container))
4080 Class = ClassImpl->getClassInterface();
4081 else
4082 Class = cast<ObjCCategoryImplDecl>(Container)->getCategoryDecl()
4083 ->getClassInterface();
4084
4085 // Add all of the instance variables in this class and its superclasses.
4086 Results.EnterNewScope();
4087 for(; Class; Class = Class->getSuperClass()) {
4088 // FIXME: We could screen the type of each ivar for compatibility with
4089 // the property, but is that being too paternal?
4090 for (ObjCInterfaceDecl::ivar_iterator IVar = Class->ivar_begin(),
4091 IVarEnd = Class->ivar_end();
4092 IVar != IVarEnd; ++IVar)
Douglas Gregor608300b2010-01-14 16:14:35 +00004093 Results.AddResult(Result(*IVar, 0), CurContext, 0, false);
Douglas Gregor322328b2009-11-18 22:32:06 +00004094 }
4095 Results.ExitScope();
4096
Douglas Gregore6b1bb62010-08-11 21:23:17 +00004097 HandleCodeCompleteResults(this, CodeCompleter,
4098 CodeCompletionContext::CCC_Other,
4099 Results.data(),Results.size());
Douglas Gregor322328b2009-11-18 22:32:06 +00004100}
Douglas Gregore8f5a172010-04-07 00:21:17 +00004101
4102typedef llvm::DenseMap<Selector, ObjCMethodDecl *> KnownMethodsMap;
4103
4104/// \brief Find all of the methods that reside in the given container
4105/// (and its superclasses, protocols, etc.) that meet the given
4106/// criteria. Insert those methods into the map of known methods,
4107/// indexed by selector so they can be easily found.
4108static void FindImplementableMethods(ASTContext &Context,
4109 ObjCContainerDecl *Container,
4110 bool WantInstanceMethods,
4111 QualType ReturnType,
4112 bool IsInImplementation,
4113 KnownMethodsMap &KnownMethods) {
4114 if (ObjCInterfaceDecl *IFace = dyn_cast<ObjCInterfaceDecl>(Container)) {
4115 // Recurse into protocols.
4116 const ObjCList<ObjCProtocolDecl> &Protocols
4117 = IFace->getReferencedProtocols();
4118 for (ObjCList<ObjCProtocolDecl>::iterator I = Protocols.begin(),
4119 E = Protocols.end();
4120 I != E; ++I)
4121 FindImplementableMethods(Context, *I, WantInstanceMethods, ReturnType,
4122 IsInImplementation, KnownMethods);
4123
4124 // If we're not in the implementation of a class, also visit the
4125 // superclass.
4126 if (!IsInImplementation && IFace->getSuperClass())
4127 FindImplementableMethods(Context, IFace->getSuperClass(),
4128 WantInstanceMethods, ReturnType,
4129 IsInImplementation, KnownMethods);
4130
4131 // Add methods from any class extensions (but not from categories;
4132 // those should go into category implementations).
Fariborz Jahanian80aa1cd2010-06-22 23:20:40 +00004133 for (const ObjCCategoryDecl *Cat = IFace->getFirstClassExtension(); Cat;
4134 Cat = Cat->getNextClassExtension())
4135 FindImplementableMethods(Context, const_cast<ObjCCategoryDecl*>(Cat),
4136 WantInstanceMethods, ReturnType,
Douglas Gregore8f5a172010-04-07 00:21:17 +00004137 IsInImplementation, KnownMethods);
Douglas Gregore8f5a172010-04-07 00:21:17 +00004138 }
4139
4140 if (ObjCCategoryDecl *Category = dyn_cast<ObjCCategoryDecl>(Container)) {
4141 // Recurse into protocols.
4142 const ObjCList<ObjCProtocolDecl> &Protocols
4143 = Category->getReferencedProtocols();
4144 for (ObjCList<ObjCProtocolDecl>::iterator I = Protocols.begin(),
4145 E = Protocols.end();
4146 I != E; ++I)
4147 FindImplementableMethods(Context, *I, WantInstanceMethods, ReturnType,
4148 IsInImplementation, KnownMethods);
4149 }
4150
4151 if (ObjCProtocolDecl *Protocol = dyn_cast<ObjCProtocolDecl>(Container)) {
4152 // Recurse into protocols.
4153 const ObjCList<ObjCProtocolDecl> &Protocols
4154 = Protocol->getReferencedProtocols();
4155 for (ObjCList<ObjCProtocolDecl>::iterator I = Protocols.begin(),
4156 E = Protocols.end();
4157 I != E; ++I)
4158 FindImplementableMethods(Context, *I, WantInstanceMethods, ReturnType,
4159 IsInImplementation, KnownMethods);
4160 }
4161
4162 // Add methods in this container. This operation occurs last because
4163 // we want the methods from this container to override any methods
4164 // we've previously seen with the same selector.
4165 for (ObjCContainerDecl::method_iterator M = Container->meth_begin(),
4166 MEnd = Container->meth_end();
4167 M != MEnd; ++M) {
4168 if ((*M)->isInstanceMethod() == WantInstanceMethods) {
4169 if (!ReturnType.isNull() &&
4170 !Context.hasSameUnqualifiedType(ReturnType, (*M)->getResultType()))
4171 continue;
4172
4173 KnownMethods[(*M)->getSelector()] = *M;
4174 }
4175 }
4176}
4177
4178void Sema::CodeCompleteObjCMethodDecl(Scope *S,
4179 bool IsInstanceMethod,
4180 TypeTy *ReturnTy,
John McCalld226f652010-08-21 09:40:31 +00004181 Decl *IDecl) {
Douglas Gregore8f5a172010-04-07 00:21:17 +00004182 // Determine the return type of the method we're declaring, if
4183 // provided.
4184 QualType ReturnType = GetTypeFromParser(ReturnTy);
4185
4186 // Determine where we should start searching for methods, and where we
4187 ObjCContainerDecl *SearchDecl = 0, *CurrentDecl = 0;
4188 bool IsInImplementation = false;
John McCalld226f652010-08-21 09:40:31 +00004189 if (Decl *D = IDecl) {
Douglas Gregore8f5a172010-04-07 00:21:17 +00004190 if (ObjCImplementationDecl *Impl = dyn_cast<ObjCImplementationDecl>(D)) {
4191 SearchDecl = Impl->getClassInterface();
4192 CurrentDecl = Impl;
4193 IsInImplementation = true;
4194 } else if (ObjCCategoryImplDecl *CatImpl
4195 = dyn_cast<ObjCCategoryImplDecl>(D)) {
4196 SearchDecl = CatImpl->getCategoryDecl();
4197 CurrentDecl = CatImpl;
4198 IsInImplementation = true;
4199 } else {
4200 SearchDecl = dyn_cast<ObjCContainerDecl>(D);
4201 CurrentDecl = SearchDecl;
4202 }
4203 }
4204
4205 if (!SearchDecl && S) {
4206 if (DeclContext *DC = static_cast<DeclContext *>(S->getEntity())) {
4207 SearchDecl = dyn_cast<ObjCContainerDecl>(DC);
4208 CurrentDecl = SearchDecl;
4209 }
4210 }
4211
4212 if (!SearchDecl || !CurrentDecl) {
Douglas Gregore6b1bb62010-08-11 21:23:17 +00004213 HandleCodeCompleteResults(this, CodeCompleter,
4214 CodeCompletionContext::CCC_Other,
4215 0, 0);
Douglas Gregore8f5a172010-04-07 00:21:17 +00004216 return;
4217 }
4218
4219 // Find all of the methods that we could declare/implement here.
4220 KnownMethodsMap KnownMethods;
4221 FindImplementableMethods(Context, SearchDecl, IsInstanceMethod,
4222 ReturnType, IsInImplementation, KnownMethods);
4223
4224 // Erase any methods that have already been declared or
4225 // implemented here.
4226 for (ObjCContainerDecl::method_iterator M = CurrentDecl->meth_begin(),
4227 MEnd = CurrentDecl->meth_end();
4228 M != MEnd; ++M) {
4229 if ((*M)->isInstanceMethod() != IsInstanceMethod)
4230 continue;
4231
4232 KnownMethodsMap::iterator Pos = KnownMethods.find((*M)->getSelector());
4233 if (Pos != KnownMethods.end())
4234 KnownMethods.erase(Pos);
4235 }
4236
4237 // Add declarations or definitions for each of the known methods.
4238 typedef CodeCompleteConsumer::Result Result;
4239 ResultBuilder Results(*this);
4240 Results.EnterNewScope();
4241 PrintingPolicy Policy(Context.PrintingPolicy);
4242 Policy.AnonymousTagLocations = false;
4243 for (KnownMethodsMap::iterator M = KnownMethods.begin(),
4244 MEnd = KnownMethods.end();
4245 M != MEnd; ++M) {
4246 ObjCMethodDecl *Method = M->second;
4247 CodeCompletionString *Pattern = new CodeCompletionString;
4248
4249 // If the result type was not already provided, add it to the
4250 // pattern as (type).
4251 if (ReturnType.isNull()) {
4252 std::string TypeStr;
4253 Method->getResultType().getAsStringInternal(TypeStr, Policy);
4254 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
4255 Pattern->AddTextChunk(TypeStr);
4256 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
4257 }
4258
4259 Selector Sel = Method->getSelector();
4260
4261 // Add the first part of the selector to the pattern.
4262 Pattern->AddTypedTextChunk(Sel.getIdentifierInfoForSlot(0)->getName());
4263
4264 // Add parameters to the pattern.
4265 unsigned I = 0;
4266 for (ObjCMethodDecl::param_iterator P = Method->param_begin(),
4267 PEnd = Method->param_end();
4268 P != PEnd; (void)++P, ++I) {
4269 // Add the part of the selector name.
4270 if (I == 0)
4271 Pattern->AddChunk(CodeCompletionString::CK_Colon);
4272 else if (I < Sel.getNumArgs()) {
4273 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
Douglas Gregor47c03a72010-08-17 15:53:35 +00004274 Pattern->AddTextChunk(Sel.getIdentifierInfoForSlot(I)->getName());
Douglas Gregore8f5a172010-04-07 00:21:17 +00004275 Pattern->AddChunk(CodeCompletionString::CK_Colon);
4276 } else
4277 break;
4278
4279 // Add the parameter type.
4280 std::string TypeStr;
4281 (*P)->getOriginalType().getAsStringInternal(TypeStr, Policy);
4282 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
4283 Pattern->AddTextChunk(TypeStr);
4284 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
4285
4286 if (IdentifierInfo *Id = (*P)->getIdentifier())
4287 Pattern->AddTextChunk(Id->getName());
4288 }
4289
4290 if (Method->isVariadic()) {
4291 if (Method->param_size() > 0)
4292 Pattern->AddChunk(CodeCompletionString::CK_Comma);
4293 Pattern->AddTextChunk("...");
4294 }
4295
Douglas Gregor447107d2010-05-28 00:57:46 +00004296 if (IsInImplementation && Results.includeCodePatterns()) {
Douglas Gregore8f5a172010-04-07 00:21:17 +00004297 // We will be defining the method here, so add a compound statement.
4298 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
4299 Pattern->AddChunk(CodeCompletionString::CK_LeftBrace);
4300 Pattern->AddChunk(CodeCompletionString::CK_VerticalSpace);
4301 if (!Method->getResultType()->isVoidType()) {
4302 // If the result type is not void, add a return clause.
4303 Pattern->AddTextChunk("return");
4304 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
4305 Pattern->AddPlaceholderChunk("expression");
4306 Pattern->AddChunk(CodeCompletionString::CK_SemiColon);
4307 } else
4308 Pattern->AddPlaceholderChunk("statements");
4309
4310 Pattern->AddChunk(CodeCompletionString::CK_VerticalSpace);
4311 Pattern->AddChunk(CodeCompletionString::CK_RightBrace);
4312 }
4313
Douglas Gregor16ed9ad2010-08-17 16:06:07 +00004314 Results.AddResult(Result(Pattern, CCP_CodePattern,
4315 Method->isInstanceMethod()
4316 ? CXCursor_ObjCInstanceMethodDecl
4317 : CXCursor_ObjCClassMethodDecl));
Douglas Gregore8f5a172010-04-07 00:21:17 +00004318 }
4319
4320 Results.ExitScope();
4321
Douglas Gregore6b1bb62010-08-11 21:23:17 +00004322 HandleCodeCompleteResults(this, CodeCompleter,
4323 CodeCompletionContext::CCC_Other,
4324 Results.data(),Results.size());
Douglas Gregore8f5a172010-04-07 00:21:17 +00004325}
Douglas Gregor1f5537a2010-07-08 23:20:03 +00004326
4327void Sema::CodeCompleteObjCMethodDeclSelector(Scope *S,
4328 bool IsInstanceMethod,
Douglas Gregor40ed9a12010-07-08 23:37:41 +00004329 bool AtParameterName,
Douglas Gregor1f5537a2010-07-08 23:20:03 +00004330 TypeTy *ReturnTy,
4331 IdentifierInfo **SelIdents,
4332 unsigned NumSelIdents) {
Douglas Gregor1f5537a2010-07-08 23:20:03 +00004333 // If we have an external source, load the entire class method
Sebastian Redl3c7f4132010-08-18 23:57:06 +00004334 // pool from the AST file.
Douglas Gregor1f5537a2010-07-08 23:20:03 +00004335 if (ExternalSource) {
4336 for (uint32_t I = 0, N = ExternalSource->GetNumExternalSelectors();
4337 I != N; ++I) {
4338 Selector Sel = ExternalSource->GetExternalSelector(I);
Sebastian Redldb9d2142010-08-02 23:18:59 +00004339 if (Sel.isNull() || MethodPool.count(Sel))
Douglas Gregor1f5537a2010-07-08 23:20:03 +00004340 continue;
Sebastian Redldb9d2142010-08-02 23:18:59 +00004341
4342 ReadMethodPool(Sel);
Douglas Gregor1f5537a2010-07-08 23:20:03 +00004343 }
4344 }
4345
4346 // Build the set of methods we can see.
4347 typedef CodeCompleteConsumer::Result Result;
4348 ResultBuilder Results(*this);
4349
4350 if (ReturnTy)
4351 Results.setPreferredType(GetTypeFromParser(ReturnTy).getNonReferenceType());
Sebastian Redldb9d2142010-08-02 23:18:59 +00004352
Douglas Gregor1f5537a2010-07-08 23:20:03 +00004353 Results.EnterNewScope();
Sebastian Redldb9d2142010-08-02 23:18:59 +00004354 for (GlobalMethodPool::iterator M = MethodPool.begin(),
4355 MEnd = MethodPool.end();
4356 M != MEnd; ++M) {
4357 for (ObjCMethodList *MethList = IsInstanceMethod ? &M->second.first :
4358 &M->second.second;
4359 MethList && MethList->Method;
Douglas Gregor1f5537a2010-07-08 23:20:03 +00004360 MethList = MethList->Next) {
4361 if (!isAcceptableObjCMethod(MethList->Method, MK_Any, SelIdents,
4362 NumSelIdents))
4363 continue;
4364
Douglas Gregor40ed9a12010-07-08 23:37:41 +00004365 if (AtParameterName) {
4366 // Suggest parameter names we've seen before.
4367 if (NumSelIdents && NumSelIdents <= MethList->Method->param_size()) {
4368 ParmVarDecl *Param = MethList->Method->param_begin()[NumSelIdents-1];
4369 if (Param->getIdentifier()) {
4370 CodeCompletionString *Pattern = new CodeCompletionString;
4371 Pattern->AddTypedTextChunk(Param->getIdentifier()->getName());
4372 Results.AddResult(Pattern);
4373 }
4374 }
4375
4376 continue;
4377 }
4378
Douglas Gregor1f5537a2010-07-08 23:20:03 +00004379 Result R(MethList->Method, 0);
4380 R.StartParameter = NumSelIdents;
4381 R.AllParametersAreInformative = false;
4382 R.DeclaringEntity = true;
4383 Results.MaybeAddResult(R, CurContext);
4384 }
4385 }
4386
4387 Results.ExitScope();
Douglas Gregore6b1bb62010-08-11 21:23:17 +00004388 HandleCodeCompleteResults(this, CodeCompleter,
4389 CodeCompletionContext::CCC_Other,
4390 Results.data(),Results.size());
Douglas Gregor1f5537a2010-07-08 23:20:03 +00004391}
Douglas Gregor87c08a52010-08-13 22:48:40 +00004392
4393void Sema::GatherGlobalCodeCompletions(
4394 llvm::SmallVectorImpl<CodeCompleteConsumer::Result> &Results) {
4395 ResultBuilder Builder(*this);
4396
Douglas Gregor8071e422010-08-15 06:18:01 +00004397 if (!CodeCompleter || CodeCompleter->includeGlobals()) {
4398 CodeCompletionDeclConsumer Consumer(Builder,
4399 Context.getTranslationUnitDecl());
4400 LookupVisibleDecls(Context.getTranslationUnitDecl(), LookupAnyName,
4401 Consumer);
4402 }
Douglas Gregor87c08a52010-08-13 22:48:40 +00004403
4404 if (!CodeCompleter || CodeCompleter->includeMacros())
4405 AddMacroResults(PP, Builder);
4406
4407 Results.clear();
4408 Results.insert(Results.end(),
4409 Builder.data(), Builder.data() + Builder.size());
4410}