blob: 649f70b7b4e98e4e1392e60d0f62353a9030cd41 [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 {
Douglas Gregord32b0222010-08-24 01:06:58 +0000898 if (UsingShadowDecl *Using = dyn_cast<UsingShadowDecl>(ND))
899 ND = Using->getTargetDecl();
900
901 return isa<TypeDecl>(ND) || isa<ObjCInterfaceDecl>(ND);
Douglas Gregor86d9a522009-09-21 16:56:56 +0000902}
903
Douglas Gregor76282942009-12-11 17:31:05 +0000904/// \brief Determines which members of a class should be visible via
905/// "." or "->". Only value declarations, nested name specifiers, and
906/// using declarations thereof should show up.
Douglas Gregoreb5758b2009-09-23 22:26:46 +0000907bool ResultBuilder::IsMember(NamedDecl *ND) const {
Douglas Gregor76282942009-12-11 17:31:05 +0000908 if (UsingShadowDecl *Using = dyn_cast<UsingShadowDecl>(ND))
909 ND = Using->getTargetDecl();
910
Douglas Gregorce821962009-12-11 18:14:22 +0000911 return isa<ValueDecl>(ND) || isa<FunctionTemplateDecl>(ND) ||
912 isa<ObjCPropertyDecl>(ND);
Douglas Gregoreb5758b2009-09-23 22:26:46 +0000913}
914
Douglas Gregor8e254cf2010-05-27 23:06:34 +0000915static bool isObjCReceiverType(ASTContext &C, QualType T) {
916 T = C.getCanonicalType(T);
917 switch (T->getTypeClass()) {
918 case Type::ObjCObject:
919 case Type::ObjCInterface:
920 case Type::ObjCObjectPointer:
921 return true;
922
923 case Type::Builtin:
924 switch (cast<BuiltinType>(T)->getKind()) {
925 case BuiltinType::ObjCId:
926 case BuiltinType::ObjCClass:
927 case BuiltinType::ObjCSel:
928 return true;
929
930 default:
931 break;
932 }
933 return false;
934
935 default:
936 break;
937 }
938
939 if (!C.getLangOptions().CPlusPlus)
940 return false;
941
942 // FIXME: We could perform more analysis here to determine whether a
943 // particular class type has any conversions to Objective-C types. For now,
944 // just accept all class types.
945 return T->isDependentType() || T->isRecordType();
946}
947
948bool ResultBuilder::IsObjCMessageReceiver(NamedDecl *ND) const {
949 QualType T = getDeclUsageType(SemaRef.Context, ND);
950 if (T.isNull())
951 return false;
952
953 T = SemaRef.Context.getBaseElementType(T);
954 return isObjCReceiverType(SemaRef.Context, T);
955}
956
Douglas Gregorfb629412010-08-23 21:17:50 +0000957bool ResultBuilder::IsObjCCollection(NamedDecl *ND) const {
958 if ((SemaRef.getLangOptions().CPlusPlus && !IsOrdinaryName(ND)) ||
959 (!SemaRef.getLangOptions().CPlusPlus && !IsOrdinaryNonTypeName(ND)))
960 return false;
961
962 QualType T = getDeclUsageType(SemaRef.Context, ND);
963 if (T.isNull())
964 return false;
965
966 T = SemaRef.Context.getBaseElementType(T);
967 return T->isObjCObjectType() || T->isObjCObjectPointerType() ||
968 T->isObjCIdType() ||
969 (SemaRef.getLangOptions().CPlusPlus && T->isRecordType());
970}
Douglas Gregor8e254cf2010-05-27 23:06:34 +0000971
Douglas Gregor80f4f4c2010-01-14 16:08:12 +0000972/// \rief Determines whether the given declaration is an Objective-C
973/// instance variable.
974bool ResultBuilder::IsObjCIvar(NamedDecl *ND) const {
975 return isa<ObjCIvarDecl>(ND);
976}
977
Douglas Gregor1ca6ae82010-01-14 01:09:38 +0000978namespace {
979 /// \brief Visible declaration consumer that adds a code-completion result
980 /// for each visible declaration.
981 class CodeCompletionDeclConsumer : public VisibleDeclConsumer {
982 ResultBuilder &Results;
983 DeclContext *CurContext;
984
985 public:
986 CodeCompletionDeclConsumer(ResultBuilder &Results, DeclContext *CurContext)
987 : Results(Results), CurContext(CurContext) { }
988
Douglas Gregor0cc84042010-01-14 15:47:35 +0000989 virtual void FoundDecl(NamedDecl *ND, NamedDecl *Hiding, bool InBaseClass) {
990 Results.AddResult(ND, CurContext, Hiding, InBaseClass);
Douglas Gregor1ca6ae82010-01-14 01:09:38 +0000991 }
992 };
993}
994
Douglas Gregor86d9a522009-09-21 16:56:56 +0000995/// \brief Add type specifiers for the current language as keyword results.
Douglas Gregorbca403c2010-01-13 23:51:12 +0000996static void AddTypeSpecifierResults(const LangOptions &LangOpts,
Douglas Gregor86d9a522009-09-21 16:56:56 +0000997 ResultBuilder &Results) {
998 typedef CodeCompleteConsumer::Result Result;
Douglas Gregor12e13132010-05-26 22:00:08 +0000999 Results.AddResult(Result("short", CCP_Type));
1000 Results.AddResult(Result("long", CCP_Type));
1001 Results.AddResult(Result("signed", CCP_Type));
1002 Results.AddResult(Result("unsigned", CCP_Type));
1003 Results.AddResult(Result("void", CCP_Type));
1004 Results.AddResult(Result("char", CCP_Type));
1005 Results.AddResult(Result("int", CCP_Type));
1006 Results.AddResult(Result("float", CCP_Type));
1007 Results.AddResult(Result("double", CCP_Type));
1008 Results.AddResult(Result("enum", CCP_Type));
1009 Results.AddResult(Result("struct", CCP_Type));
1010 Results.AddResult(Result("union", CCP_Type));
1011 Results.AddResult(Result("const", CCP_Type));
1012 Results.AddResult(Result("volatile", CCP_Type));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001013
Douglas Gregor86d9a522009-09-21 16:56:56 +00001014 if (LangOpts.C99) {
1015 // C99-specific
Douglas Gregor12e13132010-05-26 22:00:08 +00001016 Results.AddResult(Result("_Complex", CCP_Type));
1017 Results.AddResult(Result("_Imaginary", CCP_Type));
1018 Results.AddResult(Result("_Bool", CCP_Type));
1019 Results.AddResult(Result("restrict", CCP_Type));
Douglas Gregor86d9a522009-09-21 16:56:56 +00001020 }
1021
1022 if (LangOpts.CPlusPlus) {
1023 // C++-specific
Douglas Gregor12e13132010-05-26 22:00:08 +00001024 Results.AddResult(Result("bool", CCP_Type));
1025 Results.AddResult(Result("class", CCP_Type));
1026 Results.AddResult(Result("wchar_t", CCP_Type));
Douglas Gregor86d9a522009-09-21 16:56:56 +00001027
Douglas Gregorc8bddde2010-05-28 00:22:41 +00001028 // typename qualified-id
1029 CodeCompletionString *Pattern = new CodeCompletionString;
1030 Pattern->AddTypedTextChunk("typename");
1031 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
1032 Pattern->AddPlaceholderChunk("qualifier");
1033 Pattern->AddTextChunk("::");
1034 Pattern->AddPlaceholderChunk("name");
1035 Results.AddResult(Result(Pattern));
Douglas Gregord8e8a582010-05-25 21:41:55 +00001036
Douglas Gregor86d9a522009-09-21 16:56:56 +00001037 if (LangOpts.CPlusPlus0x) {
Douglas Gregor12e13132010-05-26 22:00:08 +00001038 Results.AddResult(Result("auto", CCP_Type));
1039 Results.AddResult(Result("char16_t", CCP_Type));
1040 Results.AddResult(Result("char32_t", CCP_Type));
Douglas Gregorc8bddde2010-05-28 00:22:41 +00001041
1042 CodeCompletionString *Pattern = new CodeCompletionString;
1043 Pattern->AddTypedTextChunk("decltype");
1044 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
1045 Pattern->AddPlaceholderChunk("expression");
1046 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
1047 Results.AddResult(Result(Pattern));
Douglas Gregor86d9a522009-09-21 16:56:56 +00001048 }
1049 }
1050
1051 // GNU extensions
1052 if (LangOpts.GNUMode) {
1053 // FIXME: Enable when we actually support decimal floating point.
Douglas Gregora4477812010-01-14 16:01:26 +00001054 // Results.AddResult(Result("_Decimal32"));
1055 // Results.AddResult(Result("_Decimal64"));
1056 // Results.AddResult(Result("_Decimal128"));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001057
Douglas Gregorc8bddde2010-05-28 00:22:41 +00001058 CodeCompletionString *Pattern = new CodeCompletionString;
1059 Pattern->AddTypedTextChunk("typeof");
1060 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
1061 Pattern->AddPlaceholderChunk("expression");
1062 Results.AddResult(Result(Pattern));
1063
1064 Pattern = new CodeCompletionString;
1065 Pattern->AddTypedTextChunk("typeof");
1066 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
1067 Pattern->AddPlaceholderChunk("type");
1068 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
1069 Results.AddResult(Result(Pattern));
Douglas Gregor86d9a522009-09-21 16:56:56 +00001070 }
1071}
1072
Douglas Gregore6b1bb62010-08-11 21:23:17 +00001073static void AddStorageSpecifiers(Action::ParserCompletionContext CCC,
Douglas Gregor01dfea02010-01-10 23:08:15 +00001074 const LangOptions &LangOpts,
Douglas Gregor01dfea02010-01-10 23:08:15 +00001075 ResultBuilder &Results) {
1076 typedef CodeCompleteConsumer::Result Result;
1077 // Note: we don't suggest either "auto" or "register", because both
1078 // are pointless as storage specifiers. Elsewhere, we suggest "auto"
1079 // in C++0x as a type specifier.
Douglas Gregora4477812010-01-14 16:01:26 +00001080 Results.AddResult(Result("extern"));
1081 Results.AddResult(Result("static"));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001082}
1083
Douglas Gregore6b1bb62010-08-11 21:23:17 +00001084static void AddFunctionSpecifiers(Action::ParserCompletionContext CCC,
Douglas Gregor01dfea02010-01-10 23:08:15 +00001085 const LangOptions &LangOpts,
Douglas Gregor01dfea02010-01-10 23:08:15 +00001086 ResultBuilder &Results) {
1087 typedef CodeCompleteConsumer::Result Result;
1088 switch (CCC) {
Douglas Gregore6b1bb62010-08-11 21:23:17 +00001089 case Action::PCC_Class:
1090 case Action::PCC_MemberTemplate:
Douglas Gregor01dfea02010-01-10 23:08:15 +00001091 if (LangOpts.CPlusPlus) {
Douglas Gregora4477812010-01-14 16:01:26 +00001092 Results.AddResult(Result("explicit"));
1093 Results.AddResult(Result("friend"));
1094 Results.AddResult(Result("mutable"));
1095 Results.AddResult(Result("virtual"));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001096 }
1097 // Fall through
1098
Douglas Gregore6b1bb62010-08-11 21:23:17 +00001099 case Action::PCC_ObjCInterface:
1100 case Action::PCC_ObjCImplementation:
1101 case Action::PCC_Namespace:
1102 case Action::PCC_Template:
Douglas Gregor01dfea02010-01-10 23:08:15 +00001103 if (LangOpts.CPlusPlus || LangOpts.C99)
Douglas Gregora4477812010-01-14 16:01:26 +00001104 Results.AddResult(Result("inline"));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001105 break;
1106
Douglas Gregore6b1bb62010-08-11 21:23:17 +00001107 case Action::PCC_ObjCInstanceVariableList:
1108 case Action::PCC_Expression:
1109 case Action::PCC_Statement:
1110 case Action::PCC_ForInit:
1111 case Action::PCC_Condition:
1112 case Action::PCC_RecoveryInFunction:
Douglas Gregord32b0222010-08-24 01:06:58 +00001113 case Action::PCC_Type:
Douglas Gregor01dfea02010-01-10 23:08:15 +00001114 break;
1115 }
1116}
1117
Douglas Gregorbca403c2010-01-13 23:51:12 +00001118static void AddObjCExpressionResults(ResultBuilder &Results, bool NeedAt);
1119static void AddObjCStatementResults(ResultBuilder &Results, bool NeedAt);
1120static void AddObjCVisibilityResults(const LangOptions &LangOpts,
Douglas Gregorc38c3e12010-01-13 21:54:15 +00001121 ResultBuilder &Results,
1122 bool NeedAt);
Douglas Gregorbca403c2010-01-13 23:51:12 +00001123static void AddObjCImplementationResults(const LangOptions &LangOpts,
Douglas Gregorb6ac2452010-01-13 21:24:21 +00001124 ResultBuilder &Results,
1125 bool NeedAt);
Douglas Gregorbca403c2010-01-13 23:51:12 +00001126static void AddObjCInterfaceResults(const LangOptions &LangOpts,
Douglas Gregorb6ac2452010-01-13 21:24:21 +00001127 ResultBuilder &Results,
1128 bool NeedAt);
Douglas Gregorbca403c2010-01-13 23:51:12 +00001129static void AddObjCTopLevelResults(ResultBuilder &Results, bool NeedAt);
Douglas Gregorb6ac2452010-01-13 21:24:21 +00001130
Douglas Gregorc8bddde2010-05-28 00:22:41 +00001131static void AddTypedefResult(ResultBuilder &Results) {
1132 CodeCompletionString *Pattern = new CodeCompletionString;
1133 Pattern->AddTypedTextChunk("typedef");
1134 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
1135 Pattern->AddPlaceholderChunk("type");
1136 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
1137 Pattern->AddPlaceholderChunk("name");
1138 Results.AddResult(CodeCompleteConsumer::Result(Pattern));
1139}
1140
Douglas Gregore6b1bb62010-08-11 21:23:17 +00001141static bool WantTypesInContext(Action::ParserCompletionContext CCC,
Douglas Gregor4710e5b2010-05-28 00:49:12 +00001142 const LangOptions &LangOpts) {
1143 if (LangOpts.CPlusPlus)
1144 return true;
1145
1146 switch (CCC) {
Douglas Gregore6b1bb62010-08-11 21:23:17 +00001147 case Action::PCC_Namespace:
1148 case Action::PCC_Class:
1149 case Action::PCC_ObjCInstanceVariableList:
1150 case Action::PCC_Template:
1151 case Action::PCC_MemberTemplate:
1152 case Action::PCC_Statement:
1153 case Action::PCC_RecoveryInFunction:
Douglas Gregord32b0222010-08-24 01:06:58 +00001154 case Action::PCC_Type:
Douglas Gregor4710e5b2010-05-28 00:49:12 +00001155 return true;
1156
Douglas Gregore6b1bb62010-08-11 21:23:17 +00001157 case Action::PCC_ObjCInterface:
1158 case Action::PCC_ObjCImplementation:
1159 case Action::PCC_Expression:
1160 case Action::PCC_Condition:
Douglas Gregor4710e5b2010-05-28 00:49:12 +00001161 return false;
1162
Douglas Gregore6b1bb62010-08-11 21:23:17 +00001163 case Action::PCC_ForInit:
Douglas Gregor4710e5b2010-05-28 00:49:12 +00001164 return LangOpts.ObjC1 || LangOpts.C99;
1165 }
1166
1167 return false;
1168}
1169
Douglas Gregor01dfea02010-01-10 23:08:15 +00001170/// \brief Add language constructs that show up for "ordinary" names.
Douglas Gregore6b1bb62010-08-11 21:23:17 +00001171static void AddOrdinaryNameResults(Action::ParserCompletionContext CCC,
Douglas Gregor01dfea02010-01-10 23:08:15 +00001172 Scope *S,
1173 Sema &SemaRef,
Douglas Gregor01dfea02010-01-10 23:08:15 +00001174 ResultBuilder &Results) {
1175 typedef CodeCompleteConsumer::Result Result;
1176 switch (CCC) {
Douglas Gregore6b1bb62010-08-11 21:23:17 +00001177 case Action::PCC_Namespace:
Douglas Gregorc8bddde2010-05-28 00:22:41 +00001178 if (SemaRef.getLangOptions().CPlusPlus) {
1179 CodeCompletionString *Pattern = 0;
1180
1181 if (Results.includeCodePatterns()) {
1182 // namespace <identifier> { declarations }
1183 CodeCompletionString *Pattern = new CodeCompletionString;
1184 Pattern->AddTypedTextChunk("namespace");
1185 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
1186 Pattern->AddPlaceholderChunk("identifier");
1187 Pattern->AddChunk(CodeCompletionString::CK_LeftBrace);
1188 Pattern->AddPlaceholderChunk("declarations");
1189 Pattern->AddChunk(CodeCompletionString::CK_VerticalSpace);
1190 Pattern->AddChunk(CodeCompletionString::CK_RightBrace);
1191 Results.AddResult(Result(Pattern));
1192 }
1193
Douglas Gregor01dfea02010-01-10 23:08:15 +00001194 // namespace identifier = identifier ;
1195 Pattern = new CodeCompletionString;
1196 Pattern->AddTypedTextChunk("namespace");
1197 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
Douglas Gregorc8bddde2010-05-28 00:22:41 +00001198 Pattern->AddPlaceholderChunk("name");
Douglas Gregor01dfea02010-01-10 23:08:15 +00001199 Pattern->AddChunk(CodeCompletionString::CK_Equal);
Douglas Gregorc8bddde2010-05-28 00:22:41 +00001200 Pattern->AddPlaceholderChunk("namespace");
Douglas Gregora4477812010-01-14 16:01:26 +00001201 Results.AddResult(Result(Pattern));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001202
1203 // Using directives
1204 Pattern = new CodeCompletionString;
1205 Pattern->AddTypedTextChunk("using");
1206 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
1207 Pattern->AddTextChunk("namespace");
1208 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
1209 Pattern->AddPlaceholderChunk("identifier");
Douglas Gregora4477812010-01-14 16:01:26 +00001210 Results.AddResult(Result(Pattern));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001211
1212 // asm(string-literal)
1213 Pattern = new CodeCompletionString;
1214 Pattern->AddTypedTextChunk("asm");
1215 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
1216 Pattern->AddPlaceholderChunk("string-literal");
1217 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
Douglas Gregora4477812010-01-14 16:01:26 +00001218 Results.AddResult(Result(Pattern));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001219
Douglas Gregorc8bddde2010-05-28 00:22:41 +00001220 if (Results.includeCodePatterns()) {
1221 // Explicit template instantiation
1222 Pattern = new CodeCompletionString;
1223 Pattern->AddTypedTextChunk("template");
1224 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
1225 Pattern->AddPlaceholderChunk("declaration");
1226 Results.AddResult(Result(Pattern));
1227 }
Douglas Gregor01dfea02010-01-10 23:08:15 +00001228 }
Douglas Gregorb6ac2452010-01-13 21:24:21 +00001229
1230 if (SemaRef.getLangOptions().ObjC1)
Douglas Gregorbca403c2010-01-13 23:51:12 +00001231 AddObjCTopLevelResults(Results, true);
Douglas Gregorb6ac2452010-01-13 21:24:21 +00001232
Douglas Gregorc8bddde2010-05-28 00:22:41 +00001233 AddTypedefResult(Results);
Douglas Gregor01dfea02010-01-10 23:08:15 +00001234 // Fall through
1235
Douglas Gregore6b1bb62010-08-11 21:23:17 +00001236 case Action::PCC_Class:
Douglas Gregorc8bddde2010-05-28 00:22:41 +00001237 if (SemaRef.getLangOptions().CPlusPlus) {
Douglas Gregor01dfea02010-01-10 23:08:15 +00001238 // Using declaration
1239 CodeCompletionString *Pattern = new CodeCompletionString;
1240 Pattern->AddTypedTextChunk("using");
1241 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
Douglas Gregorc8bddde2010-05-28 00:22:41 +00001242 Pattern->AddPlaceholderChunk("qualifier");
1243 Pattern->AddTextChunk("::");
1244 Pattern->AddPlaceholderChunk("name");
Douglas Gregora4477812010-01-14 16:01:26 +00001245 Results.AddResult(Result(Pattern));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001246
Douglas Gregorc8bddde2010-05-28 00:22:41 +00001247 // using typename qualifier::name (only in a dependent context)
Douglas Gregor01dfea02010-01-10 23:08:15 +00001248 if (SemaRef.CurContext->isDependentContext()) {
1249 Pattern = new CodeCompletionString;
1250 Pattern->AddTypedTextChunk("using");
1251 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
1252 Pattern->AddTextChunk("typename");
1253 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
Douglas Gregorc8bddde2010-05-28 00:22:41 +00001254 Pattern->AddPlaceholderChunk("qualifier");
1255 Pattern->AddTextChunk("::");
1256 Pattern->AddPlaceholderChunk("name");
Douglas Gregora4477812010-01-14 16:01:26 +00001257 Results.AddResult(Result(Pattern));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001258 }
1259
Douglas Gregore6b1bb62010-08-11 21:23:17 +00001260 if (CCC == Action::PCC_Class) {
Douglas Gregorc8bddde2010-05-28 00:22:41 +00001261 AddTypedefResult(Results);
1262
Douglas Gregor01dfea02010-01-10 23:08:15 +00001263 // public:
1264 Pattern = new CodeCompletionString;
1265 Pattern->AddTypedTextChunk("public");
1266 Pattern->AddChunk(CodeCompletionString::CK_Colon);
Douglas Gregora4477812010-01-14 16:01:26 +00001267 Results.AddResult(Result(Pattern));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001268
1269 // protected:
1270 Pattern = new CodeCompletionString;
1271 Pattern->AddTypedTextChunk("protected");
1272 Pattern->AddChunk(CodeCompletionString::CK_Colon);
Douglas Gregora4477812010-01-14 16:01:26 +00001273 Results.AddResult(Result(Pattern));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001274
1275 // private:
1276 Pattern = new CodeCompletionString;
1277 Pattern->AddTypedTextChunk("private");
1278 Pattern->AddChunk(CodeCompletionString::CK_Colon);
Douglas Gregora4477812010-01-14 16:01:26 +00001279 Results.AddResult(Result(Pattern));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001280 }
1281 }
1282 // Fall through
1283
Douglas Gregore6b1bb62010-08-11 21:23:17 +00001284 case Action::PCC_Template:
1285 case Action::PCC_MemberTemplate:
Douglas Gregord8e8a582010-05-25 21:41:55 +00001286 if (SemaRef.getLangOptions().CPlusPlus && Results.includeCodePatterns()) {
Douglas Gregor01dfea02010-01-10 23:08:15 +00001287 // template < parameters >
1288 CodeCompletionString *Pattern = new CodeCompletionString;
1289 Pattern->AddTypedTextChunk("template");
1290 Pattern->AddChunk(CodeCompletionString::CK_LeftAngle);
1291 Pattern->AddPlaceholderChunk("parameters");
1292 Pattern->AddChunk(CodeCompletionString::CK_RightAngle);
Douglas Gregora4477812010-01-14 16:01:26 +00001293 Results.AddResult(Result(Pattern));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001294 }
1295
Douglas Gregorbca403c2010-01-13 23:51:12 +00001296 AddStorageSpecifiers(CCC, SemaRef.getLangOptions(), Results);
1297 AddFunctionSpecifiers(CCC, SemaRef.getLangOptions(), Results);
Douglas Gregor01dfea02010-01-10 23:08:15 +00001298 break;
1299
Douglas Gregore6b1bb62010-08-11 21:23:17 +00001300 case Action::PCC_ObjCInterface:
Douglas Gregorbca403c2010-01-13 23:51:12 +00001301 AddObjCInterfaceResults(SemaRef.getLangOptions(), Results, true);
1302 AddStorageSpecifiers(CCC, SemaRef.getLangOptions(), Results);
1303 AddFunctionSpecifiers(CCC, SemaRef.getLangOptions(), Results);
Douglas Gregorb6ac2452010-01-13 21:24:21 +00001304 break;
1305
Douglas Gregore6b1bb62010-08-11 21:23:17 +00001306 case Action::PCC_ObjCImplementation:
Douglas Gregorbca403c2010-01-13 23:51:12 +00001307 AddObjCImplementationResults(SemaRef.getLangOptions(), Results, true);
1308 AddStorageSpecifiers(CCC, SemaRef.getLangOptions(), Results);
1309 AddFunctionSpecifiers(CCC, SemaRef.getLangOptions(), Results);
Douglas Gregorb6ac2452010-01-13 21:24:21 +00001310 break;
1311
Douglas Gregore6b1bb62010-08-11 21:23:17 +00001312 case Action::PCC_ObjCInstanceVariableList:
Douglas Gregorbca403c2010-01-13 23:51:12 +00001313 AddObjCVisibilityResults(SemaRef.getLangOptions(), Results, true);
Douglas Gregorc38c3e12010-01-13 21:54:15 +00001314 break;
1315
Douglas Gregore6b1bb62010-08-11 21:23:17 +00001316 case Action::PCC_RecoveryInFunction:
1317 case Action::PCC_Statement: {
Douglas Gregorc8bddde2010-05-28 00:22:41 +00001318 AddTypedefResult(Results);
Douglas Gregor01dfea02010-01-10 23:08:15 +00001319
1320 CodeCompletionString *Pattern = 0;
Douglas Gregord8e8a582010-05-25 21:41:55 +00001321 if (SemaRef.getLangOptions().CPlusPlus && Results.includeCodePatterns()) {
Douglas Gregor01dfea02010-01-10 23:08:15 +00001322 Pattern = new CodeCompletionString;
1323 Pattern->AddTypedTextChunk("try");
1324 Pattern->AddChunk(CodeCompletionString::CK_LeftBrace);
1325 Pattern->AddPlaceholderChunk("statements");
1326 Pattern->AddChunk(CodeCompletionString::CK_VerticalSpace);
1327 Pattern->AddChunk(CodeCompletionString::CK_RightBrace);
1328 Pattern->AddTextChunk("catch");
1329 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
1330 Pattern->AddPlaceholderChunk("declaration");
1331 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
1332 Pattern->AddChunk(CodeCompletionString::CK_LeftBrace);
1333 Pattern->AddPlaceholderChunk("statements");
1334 Pattern->AddChunk(CodeCompletionString::CK_VerticalSpace);
1335 Pattern->AddChunk(CodeCompletionString::CK_RightBrace);
Douglas Gregora4477812010-01-14 16:01:26 +00001336 Results.AddResult(Result(Pattern));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001337 }
Douglas Gregorb6ac2452010-01-13 21:24:21 +00001338 if (SemaRef.getLangOptions().ObjC1)
Douglas Gregorbca403c2010-01-13 23:51:12 +00001339 AddObjCStatementResults(Results, true);
Douglas Gregorb6ac2452010-01-13 21:24:21 +00001340
Douglas Gregord8e8a582010-05-25 21:41:55 +00001341 if (Results.includeCodePatterns()) {
1342 // if (condition) { statements }
1343 Pattern = new CodeCompletionString;
1344 Pattern->AddTypedTextChunk("if");
1345 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
1346 if (SemaRef.getLangOptions().CPlusPlus)
1347 Pattern->AddPlaceholderChunk("condition");
1348 else
1349 Pattern->AddPlaceholderChunk("expression");
1350 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
1351 Pattern->AddChunk(CodeCompletionString::CK_LeftBrace);
1352 Pattern->AddPlaceholderChunk("statements");
1353 Pattern->AddChunk(CodeCompletionString::CK_VerticalSpace);
1354 Pattern->AddChunk(CodeCompletionString::CK_RightBrace);
1355 Results.AddResult(Result(Pattern));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001356
Douglas Gregord8e8a582010-05-25 21:41:55 +00001357 // switch (condition) { }
1358 Pattern = new CodeCompletionString;
1359 Pattern->AddTypedTextChunk("switch");
1360 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
1361 if (SemaRef.getLangOptions().CPlusPlus)
1362 Pattern->AddPlaceholderChunk("condition");
1363 else
1364 Pattern->AddPlaceholderChunk("expression");
1365 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
1366 Pattern->AddChunk(CodeCompletionString::CK_LeftBrace);
1367 Pattern->AddChunk(CodeCompletionString::CK_VerticalSpace);
1368 Pattern->AddChunk(CodeCompletionString::CK_RightBrace);
1369 Results.AddResult(Result(Pattern));
1370 }
1371
Douglas Gregor01dfea02010-01-10 23:08:15 +00001372 // Switch-specific statements.
Douglas Gregorc8bddde2010-05-28 00:22:41 +00001373 if (!SemaRef.getSwitchStack().empty()) {
Douglas Gregor01dfea02010-01-10 23:08:15 +00001374 // case expression:
1375 Pattern = new CodeCompletionString;
1376 Pattern->AddTypedTextChunk("case");
Douglas Gregorc8bddde2010-05-28 00:22:41 +00001377 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
Douglas Gregor01dfea02010-01-10 23:08:15 +00001378 Pattern->AddPlaceholderChunk("expression");
1379 Pattern->AddChunk(CodeCompletionString::CK_Colon);
Douglas Gregora4477812010-01-14 16:01:26 +00001380 Results.AddResult(Result(Pattern));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001381
1382 // default:
1383 Pattern = new CodeCompletionString;
1384 Pattern->AddTypedTextChunk("default");
1385 Pattern->AddChunk(CodeCompletionString::CK_Colon);
Douglas Gregora4477812010-01-14 16:01:26 +00001386 Results.AddResult(Result(Pattern));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001387 }
1388
Douglas Gregord8e8a582010-05-25 21:41:55 +00001389 if (Results.includeCodePatterns()) {
1390 /// while (condition) { statements }
1391 Pattern = new CodeCompletionString;
1392 Pattern->AddTypedTextChunk("while");
1393 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
1394 if (SemaRef.getLangOptions().CPlusPlus)
1395 Pattern->AddPlaceholderChunk("condition");
1396 else
1397 Pattern->AddPlaceholderChunk("expression");
1398 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
1399 Pattern->AddChunk(CodeCompletionString::CK_LeftBrace);
1400 Pattern->AddPlaceholderChunk("statements");
1401 Pattern->AddChunk(CodeCompletionString::CK_VerticalSpace);
1402 Pattern->AddChunk(CodeCompletionString::CK_RightBrace);
1403 Results.AddResult(Result(Pattern));
1404
1405 // do { statements } while ( expression );
1406 Pattern = new CodeCompletionString;
1407 Pattern->AddTypedTextChunk("do");
1408 Pattern->AddChunk(CodeCompletionString::CK_LeftBrace);
1409 Pattern->AddPlaceholderChunk("statements");
1410 Pattern->AddChunk(CodeCompletionString::CK_VerticalSpace);
1411 Pattern->AddChunk(CodeCompletionString::CK_RightBrace);
1412 Pattern->AddTextChunk("while");
1413 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
Douglas Gregor01dfea02010-01-10 23:08:15 +00001414 Pattern->AddPlaceholderChunk("expression");
Douglas Gregord8e8a582010-05-25 21:41:55 +00001415 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
1416 Results.AddResult(Result(Pattern));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001417
Douglas Gregord8e8a582010-05-25 21:41:55 +00001418 // for ( for-init-statement ; condition ; expression ) { statements }
1419 Pattern = new CodeCompletionString;
1420 Pattern->AddTypedTextChunk("for");
1421 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
1422 if (SemaRef.getLangOptions().CPlusPlus || SemaRef.getLangOptions().C99)
1423 Pattern->AddPlaceholderChunk("init-statement");
1424 else
1425 Pattern->AddPlaceholderChunk("init-expression");
1426 Pattern->AddChunk(CodeCompletionString::CK_SemiColon);
1427 Pattern->AddPlaceholderChunk("condition");
1428 Pattern->AddChunk(CodeCompletionString::CK_SemiColon);
1429 Pattern->AddPlaceholderChunk("inc-expression");
1430 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
1431 Pattern->AddChunk(CodeCompletionString::CK_LeftBrace);
1432 Pattern->AddPlaceholderChunk("statements");
1433 Pattern->AddChunk(CodeCompletionString::CK_VerticalSpace);
1434 Pattern->AddChunk(CodeCompletionString::CK_RightBrace);
1435 Results.AddResult(Result(Pattern));
1436 }
Douglas Gregor01dfea02010-01-10 23:08:15 +00001437
1438 if (S->getContinueParent()) {
1439 // continue ;
1440 Pattern = new CodeCompletionString;
1441 Pattern->AddTypedTextChunk("continue");
Douglas Gregora4477812010-01-14 16:01:26 +00001442 Results.AddResult(Result(Pattern));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001443 }
1444
1445 if (S->getBreakParent()) {
1446 // break ;
1447 Pattern = new CodeCompletionString;
1448 Pattern->AddTypedTextChunk("break");
Douglas Gregora4477812010-01-14 16:01:26 +00001449 Results.AddResult(Result(Pattern));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001450 }
1451
1452 // "return expression ;" or "return ;", depending on whether we
1453 // know the function is void or not.
1454 bool isVoid = false;
1455 if (FunctionDecl *Function = dyn_cast<FunctionDecl>(SemaRef.CurContext))
1456 isVoid = Function->getResultType()->isVoidType();
1457 else if (ObjCMethodDecl *Method
1458 = dyn_cast<ObjCMethodDecl>(SemaRef.CurContext))
1459 isVoid = Method->getResultType()->isVoidType();
Douglas Gregor9ea9bdb2010-03-01 23:15:13 +00001460 else if (SemaRef.getCurBlock() &&
1461 !SemaRef.getCurBlock()->ReturnType.isNull())
1462 isVoid = SemaRef.getCurBlock()->ReturnType->isVoidType();
Douglas Gregor01dfea02010-01-10 23:08:15 +00001463 Pattern = new CodeCompletionString;
1464 Pattern->AddTypedTextChunk("return");
Douglas Gregor93298002010-02-18 04:06:48 +00001465 if (!isVoid) {
1466 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
Douglas Gregor01dfea02010-01-10 23:08:15 +00001467 Pattern->AddPlaceholderChunk("expression");
Douglas Gregor93298002010-02-18 04:06:48 +00001468 }
Douglas Gregora4477812010-01-14 16:01:26 +00001469 Results.AddResult(Result(Pattern));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001470
Douglas Gregorc8bddde2010-05-28 00:22:41 +00001471 // goto identifier ;
1472 Pattern = new CodeCompletionString;
1473 Pattern->AddTypedTextChunk("goto");
1474 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
1475 Pattern->AddPlaceholderChunk("label");
1476 Results.AddResult(Result(Pattern));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001477
Douglas Gregorc8bddde2010-05-28 00:22:41 +00001478 // Using directives
1479 Pattern = new CodeCompletionString;
1480 Pattern->AddTypedTextChunk("using");
1481 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
1482 Pattern->AddTextChunk("namespace");
1483 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
1484 Pattern->AddPlaceholderChunk("identifier");
1485 Results.AddResult(Result(Pattern));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001486 }
1487
1488 // Fall through (for statement expressions).
Douglas Gregore6b1bb62010-08-11 21:23:17 +00001489 case Action::PCC_ForInit:
1490 case Action::PCC_Condition:
Douglas Gregorbca403c2010-01-13 23:51:12 +00001491 AddStorageSpecifiers(CCC, SemaRef.getLangOptions(), Results);
Douglas Gregor01dfea02010-01-10 23:08:15 +00001492 // Fall through: conditions and statements can have expressions.
1493
Douglas Gregore6b1bb62010-08-11 21:23:17 +00001494 case Action::PCC_Expression: {
Douglas Gregor01dfea02010-01-10 23:08:15 +00001495 CodeCompletionString *Pattern = 0;
1496 if (SemaRef.getLangOptions().CPlusPlus) {
1497 // 'this', if we're in a non-static member function.
1498 if (CXXMethodDecl *Method = dyn_cast<CXXMethodDecl>(SemaRef.CurContext))
1499 if (!Method->isStatic())
Douglas Gregora4477812010-01-14 16:01:26 +00001500 Results.AddResult(Result("this"));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001501
1502 // true, false
Douglas Gregora4477812010-01-14 16:01:26 +00001503 Results.AddResult(Result("true"));
1504 Results.AddResult(Result("false"));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001505
Douglas Gregorc8bddde2010-05-28 00:22:41 +00001506 // dynamic_cast < type-id > ( expression )
1507 Pattern = new CodeCompletionString;
1508 Pattern->AddTypedTextChunk("dynamic_cast");
1509 Pattern->AddChunk(CodeCompletionString::CK_LeftAngle);
1510 Pattern->AddPlaceholderChunk("type");
1511 Pattern->AddChunk(CodeCompletionString::CK_RightAngle);
1512 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
1513 Pattern->AddPlaceholderChunk("expression");
1514 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
1515 Results.AddResult(Result(Pattern));
1516
1517 // static_cast < type-id > ( expression )
1518 Pattern = new CodeCompletionString;
1519 Pattern->AddTypedTextChunk("static_cast");
1520 Pattern->AddChunk(CodeCompletionString::CK_LeftAngle);
1521 Pattern->AddPlaceholderChunk("type");
1522 Pattern->AddChunk(CodeCompletionString::CK_RightAngle);
1523 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
1524 Pattern->AddPlaceholderChunk("expression");
1525 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
1526 Results.AddResult(Result(Pattern));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001527
Douglas Gregorc8bddde2010-05-28 00:22:41 +00001528 // reinterpret_cast < type-id > ( expression )
1529 Pattern = new CodeCompletionString;
1530 Pattern->AddTypedTextChunk("reinterpret_cast");
1531 Pattern->AddChunk(CodeCompletionString::CK_LeftAngle);
1532 Pattern->AddPlaceholderChunk("type");
1533 Pattern->AddChunk(CodeCompletionString::CK_RightAngle);
1534 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
1535 Pattern->AddPlaceholderChunk("expression");
1536 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
1537 Results.AddResult(Result(Pattern));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001538
Douglas Gregorc8bddde2010-05-28 00:22:41 +00001539 // const_cast < type-id > ( expression )
1540 Pattern = new CodeCompletionString;
1541 Pattern->AddTypedTextChunk("const_cast");
1542 Pattern->AddChunk(CodeCompletionString::CK_LeftAngle);
1543 Pattern->AddPlaceholderChunk("type");
1544 Pattern->AddChunk(CodeCompletionString::CK_RightAngle);
1545 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
1546 Pattern->AddPlaceholderChunk("expression");
1547 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
1548 Results.AddResult(Result(Pattern));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001549
Douglas Gregorc8bddde2010-05-28 00:22:41 +00001550 // typeid ( expression-or-type )
1551 Pattern = new CodeCompletionString;
1552 Pattern->AddTypedTextChunk("typeid");
1553 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
1554 Pattern->AddPlaceholderChunk("expression-or-type");
1555 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
1556 Results.AddResult(Result(Pattern));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001557
Douglas Gregorc8bddde2010-05-28 00:22:41 +00001558 // new T ( ... )
1559 Pattern = new CodeCompletionString;
1560 Pattern->AddTypedTextChunk("new");
1561 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
1562 Pattern->AddPlaceholderChunk("type");
1563 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
1564 Pattern->AddPlaceholderChunk("expressions");
1565 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
1566 Results.AddResult(Result(Pattern));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001567
Douglas Gregorc8bddde2010-05-28 00:22:41 +00001568 // new T [ ] ( ... )
1569 Pattern = new CodeCompletionString;
1570 Pattern->AddTypedTextChunk("new");
1571 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
1572 Pattern->AddPlaceholderChunk("type");
1573 Pattern->AddChunk(CodeCompletionString::CK_LeftBracket);
1574 Pattern->AddPlaceholderChunk("size");
1575 Pattern->AddChunk(CodeCompletionString::CK_RightBracket);
1576 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
1577 Pattern->AddPlaceholderChunk("expressions");
1578 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
1579 Results.AddResult(Result(Pattern));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001580
Douglas Gregorc8bddde2010-05-28 00:22:41 +00001581 // delete expression
1582 Pattern = new CodeCompletionString;
1583 Pattern->AddTypedTextChunk("delete");
1584 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
1585 Pattern->AddPlaceholderChunk("expression");
1586 Results.AddResult(Result(Pattern));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001587
Douglas Gregorc8bddde2010-05-28 00:22:41 +00001588 // delete [] expression
1589 Pattern = new CodeCompletionString;
1590 Pattern->AddTypedTextChunk("delete");
1591 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
1592 Pattern->AddChunk(CodeCompletionString::CK_LeftBracket);
1593 Pattern->AddChunk(CodeCompletionString::CK_RightBracket);
1594 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
1595 Pattern->AddPlaceholderChunk("expression");
1596 Results.AddResult(Result(Pattern));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001597
Douglas Gregorc8bddde2010-05-28 00:22:41 +00001598 // throw expression
1599 Pattern = new CodeCompletionString;
1600 Pattern->AddTypedTextChunk("throw");
1601 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
1602 Pattern->AddPlaceholderChunk("expression");
1603 Results.AddResult(Result(Pattern));
Douglas Gregor12e13132010-05-26 22:00:08 +00001604
1605 // FIXME: Rethrow?
Douglas Gregor01dfea02010-01-10 23:08:15 +00001606 }
1607
1608 if (SemaRef.getLangOptions().ObjC1) {
1609 // Add "super", if we're in an Objective-C class with a superclass.
Ted Kremenek681e2562010-05-31 21:43:10 +00001610 if (ObjCMethodDecl *Method = SemaRef.getCurMethodDecl()) {
1611 // The interface can be NULL.
1612 if (ObjCInterfaceDecl *ID = Method->getClassInterface())
1613 if (ID->getSuperClass())
1614 Results.AddResult(Result("super"));
1615 }
1616
Douglas Gregorbca403c2010-01-13 23:51:12 +00001617 AddObjCExpressionResults(Results, true);
Douglas Gregor01dfea02010-01-10 23:08:15 +00001618 }
1619
Douglas Gregorc8bddde2010-05-28 00:22:41 +00001620 // sizeof expression
1621 Pattern = new CodeCompletionString;
1622 Pattern->AddTypedTextChunk("sizeof");
1623 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
1624 Pattern->AddPlaceholderChunk("expression-or-type");
1625 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
1626 Results.AddResult(Result(Pattern));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001627 break;
1628 }
Douglas Gregord32b0222010-08-24 01:06:58 +00001629
1630 case Action::PCC_Type:
1631 break;
Douglas Gregor01dfea02010-01-10 23:08:15 +00001632 }
1633
Douglas Gregor4710e5b2010-05-28 00:49:12 +00001634 if (WantTypesInContext(CCC, SemaRef.getLangOptions()))
1635 AddTypeSpecifierResults(SemaRef.getLangOptions(), Results);
Douglas Gregor01dfea02010-01-10 23:08:15 +00001636
Douglas Gregord32b0222010-08-24 01:06:58 +00001637 if (SemaRef.getLangOptions().CPlusPlus && CCC != Action::PCC_Type)
Douglas Gregora4477812010-01-14 16:01:26 +00001638 Results.AddResult(Result("operator"));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001639}
1640
Douglas Gregorff5ce6e2009-12-18 18:53:37 +00001641/// \brief If the given declaration has an associated type, add it as a result
1642/// type chunk.
1643static void AddResultTypeChunk(ASTContext &Context,
1644 NamedDecl *ND,
1645 CodeCompletionString *Result) {
1646 if (!ND)
1647 return;
1648
1649 // Determine the type of the declaration (if it has a type).
1650 QualType T;
1651 if (FunctionDecl *Function = dyn_cast<FunctionDecl>(ND))
1652 T = Function->getResultType();
1653 else if (ObjCMethodDecl *Method = dyn_cast<ObjCMethodDecl>(ND))
1654 T = Method->getResultType();
1655 else if (FunctionTemplateDecl *FunTmpl = dyn_cast<FunctionTemplateDecl>(ND))
1656 T = FunTmpl->getTemplatedDecl()->getResultType();
1657 else if (EnumConstantDecl *Enumerator = dyn_cast<EnumConstantDecl>(ND))
1658 T = Context.getTypeDeclType(cast<TypeDecl>(Enumerator->getDeclContext()));
1659 else if (isa<UnresolvedUsingValueDecl>(ND)) {
1660 /* Do nothing: ignore unresolved using declarations*/
1661 } else if (ValueDecl *Value = dyn_cast<ValueDecl>(ND))
1662 T = Value->getType();
1663 else if (ObjCPropertyDecl *Property = dyn_cast<ObjCPropertyDecl>(ND))
1664 T = Property->getType();
1665
1666 if (T.isNull() || Context.hasSameType(T, Context.DependentTy))
1667 return;
1668
Douglas Gregor84139d62010-04-05 21:25:31 +00001669 PrintingPolicy Policy(Context.PrintingPolicy);
1670 Policy.AnonymousTagLocations = false;
1671
Douglas Gregorff5ce6e2009-12-18 18:53:37 +00001672 std::string TypeStr;
Douglas Gregor84139d62010-04-05 21:25:31 +00001673 T.getAsStringInternal(TypeStr, Policy);
Douglas Gregorff5ce6e2009-12-18 18:53:37 +00001674 Result->AddResultTypeChunk(TypeStr);
1675}
1676
Douglas Gregoraaa107a2010-08-23 23:51:41 +00001677static void MaybeAddSentinel(ASTContext &Context, NamedDecl *FunctionOrMethod,
1678 CodeCompletionString *Result) {
1679 if (SentinelAttr *Sentinel = FunctionOrMethod->getAttr<SentinelAttr>())
1680 if (Sentinel->getSentinel() == 0) {
1681 if (Context.getLangOptions().ObjC1 &&
1682 Context.Idents.get("nil").hasMacroDefinition())
1683 Result->AddTextChunk(", nil");
1684 else if (Context.Idents.get("NULL").hasMacroDefinition())
1685 Result->AddTextChunk(", NULL");
1686 else
1687 Result->AddTextChunk(", (void*)0");
1688 }
1689}
1690
Douglas Gregor86d9a522009-09-21 16:56:56 +00001691/// \brief Add function parameter chunks to the given code completion string.
1692static void AddFunctionParameterChunks(ASTContext &Context,
1693 FunctionDecl *Function,
1694 CodeCompletionString *Result) {
Douglas Gregor0c8296d2009-11-07 00:00:49 +00001695 typedef CodeCompletionString::Chunk Chunk;
1696
Douglas Gregor86d9a522009-09-21 16:56:56 +00001697 CodeCompletionString *CCStr = Result;
1698
1699 for (unsigned P = 0, N = Function->getNumParams(); P != N; ++P) {
1700 ParmVarDecl *Param = Function->getParamDecl(P);
1701
1702 if (Param->hasDefaultArg()) {
1703 // When we see an optional default argument, put that argument and
1704 // the remaining default arguments into a new, optional string.
1705 CodeCompletionString *Opt = new CodeCompletionString;
1706 CCStr->AddOptionalChunk(std::auto_ptr<CodeCompletionString>(Opt));
1707 CCStr = Opt;
1708 }
1709
1710 if (P != 0)
Douglas Gregor0c8296d2009-11-07 00:00:49 +00001711 CCStr->AddChunk(Chunk(CodeCompletionString::CK_Comma));
Douglas Gregor86d9a522009-09-21 16:56:56 +00001712
1713 // Format the placeholder string.
1714 std::string PlaceholderStr;
1715 if (Param->getIdentifier())
1716 PlaceholderStr = Param->getIdentifier()->getName();
1717
1718 Param->getType().getAsStringInternal(PlaceholderStr,
1719 Context.PrintingPolicy);
1720
1721 // Add the placeholder string.
Benjamin Kramer660cc182009-11-29 20:18:50 +00001722 CCStr->AddPlaceholderChunk(PlaceholderStr);
Douglas Gregor86d9a522009-09-21 16:56:56 +00001723 }
Douglas Gregorb3d45252009-09-22 21:42:17 +00001724
1725 if (const FunctionProtoType *Proto
1726 = Function->getType()->getAs<FunctionProtoType>())
Douglas Gregoraaa107a2010-08-23 23:51:41 +00001727 if (Proto->isVariadic()) {
Douglas Gregorb3d45252009-09-22 21:42:17 +00001728 CCStr->AddPlaceholderChunk(", ...");
Douglas Gregoraaa107a2010-08-23 23:51:41 +00001729
1730 MaybeAddSentinel(Context, Function, CCStr);
1731 }
Douglas Gregor86d9a522009-09-21 16:56:56 +00001732}
1733
1734/// \brief Add template parameter chunks to the given code completion string.
1735static void AddTemplateParameterChunks(ASTContext &Context,
1736 TemplateDecl *Template,
1737 CodeCompletionString *Result,
1738 unsigned MaxParameters = 0) {
Douglas Gregor0c8296d2009-11-07 00:00:49 +00001739 typedef CodeCompletionString::Chunk Chunk;
1740
Douglas Gregor86d9a522009-09-21 16:56:56 +00001741 CodeCompletionString *CCStr = Result;
1742 bool FirstParameter = true;
1743
1744 TemplateParameterList *Params = Template->getTemplateParameters();
1745 TemplateParameterList::iterator PEnd = Params->end();
1746 if (MaxParameters)
1747 PEnd = Params->begin() + MaxParameters;
1748 for (TemplateParameterList::iterator P = Params->begin(); P != PEnd; ++P) {
1749 bool HasDefaultArg = false;
1750 std::string PlaceholderStr;
1751 if (TemplateTypeParmDecl *TTP = dyn_cast<TemplateTypeParmDecl>(*P)) {
1752 if (TTP->wasDeclaredWithTypename())
1753 PlaceholderStr = "typename";
1754 else
1755 PlaceholderStr = "class";
1756
1757 if (TTP->getIdentifier()) {
1758 PlaceholderStr += ' ';
1759 PlaceholderStr += TTP->getIdentifier()->getName();
1760 }
1761
1762 HasDefaultArg = TTP->hasDefaultArgument();
1763 } else if (NonTypeTemplateParmDecl *NTTP
1764 = dyn_cast<NonTypeTemplateParmDecl>(*P)) {
1765 if (NTTP->getIdentifier())
1766 PlaceholderStr = NTTP->getIdentifier()->getName();
1767 NTTP->getType().getAsStringInternal(PlaceholderStr,
1768 Context.PrintingPolicy);
1769 HasDefaultArg = NTTP->hasDefaultArgument();
1770 } else {
1771 assert(isa<TemplateTemplateParmDecl>(*P));
1772 TemplateTemplateParmDecl *TTP = cast<TemplateTemplateParmDecl>(*P);
1773
1774 // Since putting the template argument list into the placeholder would
1775 // be very, very long, we just use an abbreviation.
1776 PlaceholderStr = "template<...> class";
1777 if (TTP->getIdentifier()) {
1778 PlaceholderStr += ' ';
1779 PlaceholderStr += TTP->getIdentifier()->getName();
1780 }
1781
1782 HasDefaultArg = TTP->hasDefaultArgument();
1783 }
1784
1785 if (HasDefaultArg) {
1786 // When we see an optional default argument, put that argument and
1787 // the remaining default arguments into a new, optional string.
1788 CodeCompletionString *Opt = new CodeCompletionString;
1789 CCStr->AddOptionalChunk(std::auto_ptr<CodeCompletionString>(Opt));
1790 CCStr = Opt;
1791 }
1792
1793 if (FirstParameter)
1794 FirstParameter = false;
1795 else
Douglas Gregor0c8296d2009-11-07 00:00:49 +00001796 CCStr->AddChunk(Chunk(CodeCompletionString::CK_Comma));
Douglas Gregor86d9a522009-09-21 16:56:56 +00001797
1798 // Add the placeholder string.
Benjamin Kramer660cc182009-11-29 20:18:50 +00001799 CCStr->AddPlaceholderChunk(PlaceholderStr);
Douglas Gregor86d9a522009-09-21 16:56:56 +00001800 }
1801}
1802
Douglas Gregorb9d0ef72009-09-21 19:57:38 +00001803/// \brief Add a qualifier to the given code-completion string, if the
1804/// provided nested-name-specifier is non-NULL.
Douglas Gregora61a8792009-12-11 18:44:16 +00001805static void
1806AddQualifierToCompletionString(CodeCompletionString *Result,
1807 NestedNameSpecifier *Qualifier,
1808 bool QualifierIsInformative,
1809 ASTContext &Context) {
Douglas Gregorb9d0ef72009-09-21 19:57:38 +00001810 if (!Qualifier)
1811 return;
1812
1813 std::string PrintedNNS;
1814 {
1815 llvm::raw_string_ostream OS(PrintedNNS);
1816 Qualifier->print(OS, Context.PrintingPolicy);
1817 }
Douglas Gregor0563c262009-09-22 23:15:58 +00001818 if (QualifierIsInformative)
Benjamin Kramer660cc182009-11-29 20:18:50 +00001819 Result->AddInformativeChunk(PrintedNNS);
Douglas Gregor0563c262009-09-22 23:15:58 +00001820 else
Benjamin Kramer660cc182009-11-29 20:18:50 +00001821 Result->AddTextChunk(PrintedNNS);
Douglas Gregorb9d0ef72009-09-21 19:57:38 +00001822}
1823
Douglas Gregora61a8792009-12-11 18:44:16 +00001824static void AddFunctionTypeQualsToCompletionString(CodeCompletionString *Result,
1825 FunctionDecl *Function) {
1826 const FunctionProtoType *Proto
1827 = Function->getType()->getAs<FunctionProtoType>();
1828 if (!Proto || !Proto->getTypeQuals())
1829 return;
1830
1831 std::string QualsStr;
1832 if (Proto->getTypeQuals() & Qualifiers::Const)
1833 QualsStr += " const";
1834 if (Proto->getTypeQuals() & Qualifiers::Volatile)
1835 QualsStr += " volatile";
1836 if (Proto->getTypeQuals() & Qualifiers::Restrict)
1837 QualsStr += " restrict";
1838 Result->AddInformativeChunk(QualsStr);
1839}
1840
Douglas Gregor86d9a522009-09-21 16:56:56 +00001841/// \brief If possible, create a new code completion string for the given
1842/// result.
1843///
1844/// \returns Either a new, heap-allocated code completion string describing
1845/// how to use this result, or NULL to indicate that the string or name of the
1846/// result is all that is needed.
1847CodeCompletionString *
Douglas Gregor1abc6bc2010-08-04 16:47:14 +00001848CodeCompleteConsumer::Result::CreateCodeCompletionString(Sema &S,
1849 CodeCompletionString *Result) {
Douglas Gregor0c8296d2009-11-07 00:00:49 +00001850 typedef CodeCompletionString::Chunk Chunk;
1851
Douglas Gregor2b4074f2009-12-01 05:55:20 +00001852 if (Kind == RK_Pattern)
Douglas Gregor1abc6bc2010-08-04 16:47:14 +00001853 return Pattern->Clone(Result);
Douglas Gregor2b4074f2009-12-01 05:55:20 +00001854
Douglas Gregor1abc6bc2010-08-04 16:47:14 +00001855 if (!Result)
1856 Result = new CodeCompletionString;
Douglas Gregor2b4074f2009-12-01 05:55:20 +00001857
1858 if (Kind == RK_Keyword) {
1859 Result->AddTypedTextChunk(Keyword);
1860 return Result;
1861 }
Douglas Gregor86d9a522009-09-21 16:56:56 +00001862
Douglas Gregor3f7c7f42009-10-30 16:50:04 +00001863 if (Kind == RK_Macro) {
1864 MacroInfo *MI = S.PP.getMacroInfo(Macro);
Douglas Gregor2b4074f2009-12-01 05:55:20 +00001865 assert(MI && "Not a macro?");
1866
1867 Result->AddTypedTextChunk(Macro->getName());
1868
1869 if (!MI->isFunctionLike())
1870 return Result;
Douglas Gregor3f7c7f42009-10-30 16:50:04 +00001871
1872 // Format a function-like macro with placeholders for the arguments.
Douglas Gregor0c8296d2009-11-07 00:00:49 +00001873 Result->AddChunk(Chunk(CodeCompletionString::CK_LeftParen));
Douglas Gregor3f7c7f42009-10-30 16:50:04 +00001874 for (MacroInfo::arg_iterator A = MI->arg_begin(), AEnd = MI->arg_end();
1875 A != AEnd; ++A) {
1876 if (A != MI->arg_begin())
Douglas Gregor0c8296d2009-11-07 00:00:49 +00001877 Result->AddChunk(Chunk(CodeCompletionString::CK_Comma));
Douglas Gregor3f7c7f42009-10-30 16:50:04 +00001878
1879 if (!MI->isVariadic() || A != AEnd - 1) {
1880 // Non-variadic argument.
Benjamin Kramer660cc182009-11-29 20:18:50 +00001881 Result->AddPlaceholderChunk((*A)->getName());
Douglas Gregor3f7c7f42009-10-30 16:50:04 +00001882 continue;
1883 }
1884
1885 // Variadic argument; cope with the different between GNU and C99
1886 // variadic macros, providing a single placeholder for the rest of the
1887 // arguments.
1888 if ((*A)->isStr("__VA_ARGS__"))
1889 Result->AddPlaceholderChunk("...");
1890 else {
1891 std::string Arg = (*A)->getName();
1892 Arg += "...";
Benjamin Kramer660cc182009-11-29 20:18:50 +00001893 Result->AddPlaceholderChunk(Arg);
Douglas Gregor3f7c7f42009-10-30 16:50:04 +00001894 }
1895 }
Douglas Gregor0c8296d2009-11-07 00:00:49 +00001896 Result->AddChunk(Chunk(CodeCompletionString::CK_RightParen));
Douglas Gregor3f7c7f42009-10-30 16:50:04 +00001897 return Result;
1898 }
1899
Douglas Gregord8e8a582010-05-25 21:41:55 +00001900 assert(Kind == RK_Declaration && "Missed a result kind?");
Douglas Gregor86d9a522009-09-21 16:56:56 +00001901 NamedDecl *ND = Declaration;
1902
Douglas Gregor0c8296d2009-11-07 00:00:49 +00001903 if (StartsNestedNameSpecifier) {
Benjamin Kramer660cc182009-11-29 20:18:50 +00001904 Result->AddTypedTextChunk(ND->getNameAsString());
Douglas Gregor0c8296d2009-11-07 00:00:49 +00001905 Result->AddTextChunk("::");
1906 return Result;
1907 }
1908
Douglas Gregorff5ce6e2009-12-18 18:53:37 +00001909 AddResultTypeChunk(S.Context, ND, Result);
1910
Douglas Gregor86d9a522009-09-21 16:56:56 +00001911 if (FunctionDecl *Function = dyn_cast<FunctionDecl>(ND)) {
Douglas Gregor0563c262009-09-22 23:15:58 +00001912 AddQualifierToCompletionString(Result, Qualifier, QualifierIsInformative,
1913 S.Context);
Benjamin Kramer660cc182009-11-29 20:18:50 +00001914 Result->AddTypedTextChunk(Function->getNameAsString());
Douglas Gregor0c8296d2009-11-07 00:00:49 +00001915 Result->AddChunk(Chunk(CodeCompletionString::CK_LeftParen));
Douglas Gregor86d9a522009-09-21 16:56:56 +00001916 AddFunctionParameterChunks(S.Context, Function, Result);
Douglas Gregor0c8296d2009-11-07 00:00:49 +00001917 Result->AddChunk(Chunk(CodeCompletionString::CK_RightParen));
Douglas Gregora61a8792009-12-11 18:44:16 +00001918 AddFunctionTypeQualsToCompletionString(Result, Function);
Douglas Gregor86d9a522009-09-21 16:56:56 +00001919 return Result;
1920 }
1921
1922 if (FunctionTemplateDecl *FunTmpl = dyn_cast<FunctionTemplateDecl>(ND)) {
Douglas Gregor0563c262009-09-22 23:15:58 +00001923 AddQualifierToCompletionString(Result, Qualifier, QualifierIsInformative,
1924 S.Context);
Douglas Gregor86d9a522009-09-21 16:56:56 +00001925 FunctionDecl *Function = FunTmpl->getTemplatedDecl();
Benjamin Kramer660cc182009-11-29 20:18:50 +00001926 Result->AddTypedTextChunk(Function->getNameAsString());
Douglas Gregor86d9a522009-09-21 16:56:56 +00001927
1928 // Figure out which template parameters are deduced (or have default
1929 // arguments).
1930 llvm::SmallVector<bool, 16> Deduced;
1931 S.MarkDeducedTemplateParameters(FunTmpl, Deduced);
1932 unsigned LastDeducibleArgument;
1933 for (LastDeducibleArgument = Deduced.size(); LastDeducibleArgument > 0;
1934 --LastDeducibleArgument) {
1935 if (!Deduced[LastDeducibleArgument - 1]) {
1936 // C++0x: Figure out if the template argument has a default. If so,
1937 // the user doesn't need to type this argument.
1938 // FIXME: We need to abstract template parameters better!
1939 bool HasDefaultArg = false;
1940 NamedDecl *Param = FunTmpl->getTemplateParameters()->getParam(
1941 LastDeducibleArgument - 1);
1942 if (TemplateTypeParmDecl *TTP = dyn_cast<TemplateTypeParmDecl>(Param))
1943 HasDefaultArg = TTP->hasDefaultArgument();
1944 else if (NonTypeTemplateParmDecl *NTTP
1945 = dyn_cast<NonTypeTemplateParmDecl>(Param))
1946 HasDefaultArg = NTTP->hasDefaultArgument();
1947 else {
1948 assert(isa<TemplateTemplateParmDecl>(Param));
1949 HasDefaultArg
Douglas Gregor0c8296d2009-11-07 00:00:49 +00001950 = cast<TemplateTemplateParmDecl>(Param)->hasDefaultArgument();
Douglas Gregor86d9a522009-09-21 16:56:56 +00001951 }
1952
1953 if (!HasDefaultArg)
1954 break;
1955 }
1956 }
1957
1958 if (LastDeducibleArgument) {
1959 // Some of the function template arguments cannot be deduced from a
1960 // function call, so we introduce an explicit template argument list
1961 // containing all of the arguments up to the first deducible argument.
Douglas Gregor0c8296d2009-11-07 00:00:49 +00001962 Result->AddChunk(Chunk(CodeCompletionString::CK_LeftAngle));
Douglas Gregor86d9a522009-09-21 16:56:56 +00001963 AddTemplateParameterChunks(S.Context, FunTmpl, Result,
1964 LastDeducibleArgument);
Douglas Gregor0c8296d2009-11-07 00:00:49 +00001965 Result->AddChunk(Chunk(CodeCompletionString::CK_RightAngle));
Douglas Gregor86d9a522009-09-21 16:56:56 +00001966 }
1967
1968 // Add the function parameters
Douglas Gregor0c8296d2009-11-07 00:00:49 +00001969 Result->AddChunk(Chunk(CodeCompletionString::CK_LeftParen));
Douglas Gregor86d9a522009-09-21 16:56:56 +00001970 AddFunctionParameterChunks(S.Context, Function, Result);
Douglas Gregor0c8296d2009-11-07 00:00:49 +00001971 Result->AddChunk(Chunk(CodeCompletionString::CK_RightParen));
Douglas Gregora61a8792009-12-11 18:44:16 +00001972 AddFunctionTypeQualsToCompletionString(Result, Function);
Douglas Gregor86d9a522009-09-21 16:56:56 +00001973 return Result;
1974 }
1975
1976 if (TemplateDecl *Template = dyn_cast<TemplateDecl>(ND)) {
Douglas Gregor0563c262009-09-22 23:15:58 +00001977 AddQualifierToCompletionString(Result, Qualifier, QualifierIsInformative,
1978 S.Context);
Benjamin Kramer660cc182009-11-29 20:18:50 +00001979 Result->AddTypedTextChunk(Template->getNameAsString());
Douglas Gregor0c8296d2009-11-07 00:00:49 +00001980 Result->AddChunk(Chunk(CodeCompletionString::CK_LeftAngle));
Douglas Gregor86d9a522009-09-21 16:56:56 +00001981 AddTemplateParameterChunks(S.Context, Template, Result);
Douglas Gregor0c8296d2009-11-07 00:00:49 +00001982 Result->AddChunk(Chunk(CodeCompletionString::CK_RightAngle));
Douglas Gregor86d9a522009-09-21 16:56:56 +00001983 return Result;
1984 }
1985
Douglas Gregor9630eb62009-11-17 16:44:22 +00001986 if (ObjCMethodDecl *Method = dyn_cast<ObjCMethodDecl>(ND)) {
Douglas Gregor9630eb62009-11-17 16:44:22 +00001987 Selector Sel = Method->getSelector();
1988 if (Sel.isUnarySelector()) {
1989 Result->AddTypedTextChunk(Sel.getIdentifierInfoForSlot(0)->getName());
1990 return Result;
1991 }
1992
Douglas Gregord3c68542009-11-19 01:08:35 +00001993 std::string SelName = Sel.getIdentifierInfoForSlot(0)->getName().str();
1994 SelName += ':';
1995 if (StartParameter == 0)
1996 Result->AddTypedTextChunk(SelName);
1997 else {
1998 Result->AddInformativeChunk(SelName);
1999
2000 // If there is only one parameter, and we're past it, add an empty
2001 // typed-text chunk since there is nothing to type.
2002 if (Method->param_size() == 1)
2003 Result->AddTypedTextChunk("");
2004 }
Douglas Gregor9630eb62009-11-17 16:44:22 +00002005 unsigned Idx = 0;
2006 for (ObjCMethodDecl::param_iterator P = Method->param_begin(),
2007 PEnd = Method->param_end();
2008 P != PEnd; (void)++P, ++Idx) {
2009 if (Idx > 0) {
Douglas Gregord3c68542009-11-19 01:08:35 +00002010 std::string Keyword;
2011 if (Idx > StartParameter)
Douglas Gregor834389b2010-01-12 06:38:28 +00002012 Result->AddChunk(CodeCompletionString::CK_HorizontalSpace);
Douglas Gregor9630eb62009-11-17 16:44:22 +00002013 if (IdentifierInfo *II = Sel.getIdentifierInfoForSlot(Idx))
2014 Keyword += II->getName().str();
2015 Keyword += ":";
Douglas Gregor1f5537a2010-07-08 23:20:03 +00002016 if (Idx < StartParameter || AllParametersAreInformative)
Douglas Gregord3c68542009-11-19 01:08:35 +00002017 Result->AddInformativeChunk(Keyword);
Douglas Gregor1f5537a2010-07-08 23:20:03 +00002018 else if (Idx == StartParameter)
Douglas Gregord3c68542009-11-19 01:08:35 +00002019 Result->AddTypedTextChunk(Keyword);
2020 else
2021 Result->AddTextChunk(Keyword);
Douglas Gregor9630eb62009-11-17 16:44:22 +00002022 }
Douglas Gregord3c68542009-11-19 01:08:35 +00002023
2024 // If we're before the starting parameter, skip the placeholder.
2025 if (Idx < StartParameter)
2026 continue;
Douglas Gregor9630eb62009-11-17 16:44:22 +00002027
2028 std::string Arg;
2029 (*P)->getType().getAsStringInternal(Arg, S.Context.PrintingPolicy);
2030 Arg = "(" + Arg + ")";
2031 if (IdentifierInfo *II = (*P)->getIdentifier())
2032 Arg += II->getName().str();
Douglas Gregor1f5537a2010-07-08 23:20:03 +00002033 if (DeclaringEntity)
2034 Result->AddTextChunk(Arg);
2035 else if (AllParametersAreInformative)
Douglas Gregor4ad96852009-11-19 07:41:15 +00002036 Result->AddInformativeChunk(Arg);
2037 else
2038 Result->AddPlaceholderChunk(Arg);
Douglas Gregor9630eb62009-11-17 16:44:22 +00002039 }
2040
Douglas Gregor2a17af02009-12-23 00:21:46 +00002041 if (Method->isVariadic()) {
Douglas Gregor1f5537a2010-07-08 23:20:03 +00002042 if (DeclaringEntity)
2043 Result->AddTextChunk(", ...");
2044 else if (AllParametersAreInformative)
Douglas Gregor2a17af02009-12-23 00:21:46 +00002045 Result->AddInformativeChunk(", ...");
2046 else
2047 Result->AddPlaceholderChunk(", ...");
Douglas Gregoraaa107a2010-08-23 23:51:41 +00002048
2049 MaybeAddSentinel(S.Context, Method, Result);
Douglas Gregor2a17af02009-12-23 00:21:46 +00002050 }
2051
Douglas Gregor9630eb62009-11-17 16:44:22 +00002052 return Result;
2053 }
2054
Douglas Gregor2b4074f2009-12-01 05:55:20 +00002055 if (Qualifier)
Douglas Gregor0563c262009-09-22 23:15:58 +00002056 AddQualifierToCompletionString(Result, Qualifier, QualifierIsInformative,
2057 S.Context);
Douglas Gregor2b4074f2009-12-01 05:55:20 +00002058
2059 Result->AddTypedTextChunk(ND->getNameAsString());
2060 return Result;
Douglas Gregor86d9a522009-09-21 16:56:56 +00002061}
2062
Douglas Gregor86d802e2009-09-23 00:34:09 +00002063CodeCompletionString *
2064CodeCompleteConsumer::OverloadCandidate::CreateSignatureString(
2065 unsigned CurrentArg,
2066 Sema &S) const {
Douglas Gregor0c8296d2009-11-07 00:00:49 +00002067 typedef CodeCompletionString::Chunk Chunk;
2068
Douglas Gregor86d802e2009-09-23 00:34:09 +00002069 CodeCompletionString *Result = new CodeCompletionString;
2070 FunctionDecl *FDecl = getFunction();
Douglas Gregorff5ce6e2009-12-18 18:53:37 +00002071 AddResultTypeChunk(S.Context, FDecl, Result);
Douglas Gregor86d802e2009-09-23 00:34:09 +00002072 const FunctionProtoType *Proto
2073 = dyn_cast<FunctionProtoType>(getFunctionType());
2074 if (!FDecl && !Proto) {
2075 // Function without a prototype. Just give the return type and a
2076 // highlighted ellipsis.
2077 const FunctionType *FT = getFunctionType();
2078 Result->AddTextChunk(
Benjamin Kramer660cc182009-11-29 20:18:50 +00002079 FT->getResultType().getAsString(S.Context.PrintingPolicy));
Douglas Gregor0c8296d2009-11-07 00:00:49 +00002080 Result->AddChunk(Chunk(CodeCompletionString::CK_LeftParen));
2081 Result->AddChunk(Chunk(CodeCompletionString::CK_CurrentParameter, "..."));
2082 Result->AddChunk(Chunk(CodeCompletionString::CK_RightParen));
Douglas Gregor86d802e2009-09-23 00:34:09 +00002083 return Result;
2084 }
2085
2086 if (FDecl)
Benjamin Kramer660cc182009-11-29 20:18:50 +00002087 Result->AddTextChunk(FDecl->getNameAsString());
Douglas Gregor86d802e2009-09-23 00:34:09 +00002088 else
2089 Result->AddTextChunk(
Benjamin Kramer660cc182009-11-29 20:18:50 +00002090 Proto->getResultType().getAsString(S.Context.PrintingPolicy));
Douglas Gregor86d802e2009-09-23 00:34:09 +00002091
Douglas Gregor0c8296d2009-11-07 00:00:49 +00002092 Result->AddChunk(Chunk(CodeCompletionString::CK_LeftParen));
Douglas Gregor86d802e2009-09-23 00:34:09 +00002093 unsigned NumParams = FDecl? FDecl->getNumParams() : Proto->getNumArgs();
2094 for (unsigned I = 0; I != NumParams; ++I) {
2095 if (I)
Douglas Gregor0c8296d2009-11-07 00:00:49 +00002096 Result->AddChunk(Chunk(CodeCompletionString::CK_Comma));
Douglas Gregor86d802e2009-09-23 00:34:09 +00002097
2098 std::string ArgString;
2099 QualType ArgType;
2100
2101 if (FDecl) {
2102 ArgString = FDecl->getParamDecl(I)->getNameAsString();
2103 ArgType = FDecl->getParamDecl(I)->getOriginalType();
2104 } else {
2105 ArgType = Proto->getArgType(I);
2106 }
2107
2108 ArgType.getAsStringInternal(ArgString, S.Context.PrintingPolicy);
2109
2110 if (I == CurrentArg)
Douglas Gregor0c8296d2009-11-07 00:00:49 +00002111 Result->AddChunk(Chunk(CodeCompletionString::CK_CurrentParameter,
Benjamin Kramer660cc182009-11-29 20:18:50 +00002112 ArgString));
Douglas Gregor86d802e2009-09-23 00:34:09 +00002113 else
Benjamin Kramer660cc182009-11-29 20:18:50 +00002114 Result->AddTextChunk(ArgString);
Douglas Gregor86d802e2009-09-23 00:34:09 +00002115 }
2116
2117 if (Proto && Proto->isVariadic()) {
Douglas Gregor0c8296d2009-11-07 00:00:49 +00002118 Result->AddChunk(Chunk(CodeCompletionString::CK_Comma));
Douglas Gregor86d802e2009-09-23 00:34:09 +00002119 if (CurrentArg < NumParams)
2120 Result->AddTextChunk("...");
2121 else
Douglas Gregor0c8296d2009-11-07 00:00:49 +00002122 Result->AddChunk(Chunk(CodeCompletionString::CK_CurrentParameter, "..."));
Douglas Gregor86d802e2009-09-23 00:34:09 +00002123 }
Douglas Gregor0c8296d2009-11-07 00:00:49 +00002124 Result->AddChunk(Chunk(CodeCompletionString::CK_RightParen));
Douglas Gregor86d802e2009-09-23 00:34:09 +00002125
2126 return Result;
2127}
2128
Douglas Gregor86d9a522009-09-21 16:56:56 +00002129namespace {
2130 struct SortCodeCompleteResult {
2131 typedef CodeCompleteConsumer::Result Result;
2132
Douglas Gregorab0b4f12010-01-13 23:24:38 +00002133 /// \brief Retrieve the name that should be used to order a result.
2134 ///
2135 /// If the name needs to be constructed as a string, that string will be
2136 /// saved into Saved and the returned StringRef will refer to it.
2137 static llvm::StringRef getOrderedName(const Result &R,
2138 std::string &Saved) {
2139 switch (R.Kind) {
2140 case Result::RK_Keyword:
2141 return R.Keyword;
2142
2143 case Result::RK_Pattern:
2144 return R.Pattern->getTypedText();
2145
2146 case Result::RK_Macro:
2147 return R.Macro->getName();
2148
2149 case Result::RK_Declaration:
2150 // Handle declarations below.
2151 break;
Douglas Gregor54f01612009-11-19 00:01:57 +00002152 }
Douglas Gregorab0b4f12010-01-13 23:24:38 +00002153
2154 DeclarationName Name = R.Declaration->getDeclName();
Douglas Gregor54f01612009-11-19 00:01:57 +00002155
Douglas Gregorab0b4f12010-01-13 23:24:38 +00002156 // If the name is a simple identifier (by far the common case), or a
2157 // zero-argument selector, just return a reference to that identifier.
2158 if (IdentifierInfo *Id = Name.getAsIdentifierInfo())
2159 return Id->getName();
2160 if (Name.isObjCZeroArgSelector())
2161 if (IdentifierInfo *Id
2162 = Name.getObjCSelector().getIdentifierInfoForSlot(0))
2163 return Id->getName();
2164
2165 Saved = Name.getAsString();
2166 return Saved;
2167 }
2168
2169 bool operator()(const Result &X, const Result &Y) const {
2170 std::string XSaved, YSaved;
2171 llvm::StringRef XStr = getOrderedName(X, XSaved);
2172 llvm::StringRef YStr = getOrderedName(Y, YSaved);
2173 int cmp = XStr.compare_lower(YStr);
2174 if (cmp)
2175 return cmp < 0;
Douglas Gregor86d9a522009-09-21 16:56:56 +00002176
2177 // Non-hidden names precede hidden names.
2178 if (X.Hidden != Y.Hidden)
2179 return !X.Hidden;
2180
Douglas Gregoreb5758b2009-09-23 22:26:46 +00002181 // Non-nested-name-specifiers precede nested-name-specifiers.
2182 if (X.StartsNestedNameSpecifier != Y.StartsNestedNameSpecifier)
2183 return !X.StartsNestedNameSpecifier;
2184
Douglas Gregor86d9a522009-09-21 16:56:56 +00002185 return false;
2186 }
2187 };
2188}
2189
Douglas Gregor1827e102010-08-16 16:18:59 +00002190unsigned clang::getMacroUsagePriority(llvm::StringRef MacroName,
2191 bool PreferredTypeIsPointer) {
2192 unsigned Priority = CCP_Macro;
2193
2194 // Treat the "nil" and "NULL" macros as null pointer constants.
2195 if (MacroName.equals("nil") || MacroName.equals("NULL")) {
2196 Priority = CCP_Constant;
2197 if (PreferredTypeIsPointer)
2198 Priority = Priority / CCF_SimilarTypeMatch;
2199 }
2200
2201 return Priority;
2202}
2203
Douglas Gregor590c7d52010-07-08 20:55:51 +00002204static void AddMacroResults(Preprocessor &PP, ResultBuilder &Results,
2205 bool TargetTypeIsPointer = false) {
2206 typedef CodeCompleteConsumer::Result Result;
2207
Douglas Gregor3f7c7f42009-10-30 16:50:04 +00002208 Results.EnterNewScope();
Douglas Gregor0c8296d2009-11-07 00:00:49 +00002209 for (Preprocessor::macro_iterator M = PP.macro_begin(),
2210 MEnd = PP.macro_end();
Douglas Gregor590c7d52010-07-08 20:55:51 +00002211 M != MEnd; ++M) {
Douglas Gregor1827e102010-08-16 16:18:59 +00002212 Results.AddResult(Result(M->first,
2213 getMacroUsagePriority(M->first->getName(),
2214 TargetTypeIsPointer)));
Douglas Gregor590c7d52010-07-08 20:55:51 +00002215 }
Douglas Gregor3f7c7f42009-10-30 16:50:04 +00002216 Results.ExitScope();
2217}
2218
Douglas Gregoraa5f77b2010-08-23 21:54:33 +00002219static void AddPrettyFunctionResults(const LangOptions &LangOpts,
2220 ResultBuilder &Results) {
2221 typedef CodeCompleteConsumer::Result Result;
2222
2223 Results.EnterNewScope();
2224 Results.AddResult(Result("__PRETTY_FUNCTION__", CCP_Constant));
2225 Results.AddResult(Result("__FUNCTION__", CCP_Constant));
2226 if (LangOpts.C99 || LangOpts.CPlusPlus0x)
2227 Results.AddResult(Result("__func__", CCP_Constant));
2228 Results.ExitScope();
2229}
2230
Daniel Dunbar3a2838d2009-11-13 08:58:20 +00002231static void HandleCodeCompleteResults(Sema *S,
2232 CodeCompleteConsumer *CodeCompleter,
Douglas Gregore6b1bb62010-08-11 21:23:17 +00002233 CodeCompletionContext Context,
2234 CodeCompleteConsumer::Result *Results,
2235 unsigned NumResults) {
Douglas Gregor86d9a522009-09-21 16:56:56 +00002236 std::stable_sort(Results, Results + NumResults, SortCodeCompleteResult());
2237
2238 if (CodeCompleter)
Douglas Gregore6b1bb62010-08-11 21:23:17 +00002239 CodeCompleter->ProcessCodeCompleteResults(*S, Context, Results, NumResults);
Douglas Gregor54f01612009-11-19 00:01:57 +00002240
2241 for (unsigned I = 0; I != NumResults; ++I)
2242 Results[I].Destroy();
Douglas Gregor86d9a522009-09-21 16:56:56 +00002243}
2244
Douglas Gregore6b1bb62010-08-11 21:23:17 +00002245static enum CodeCompletionContext::Kind mapCodeCompletionContext(Sema &S,
2246 Sema::ParserCompletionContext PCC) {
2247 switch (PCC) {
2248 case Action::PCC_Namespace:
2249 return CodeCompletionContext::CCC_TopLevel;
2250
2251 case Action::PCC_Class:
2252 return CodeCompletionContext::CCC_ClassStructUnion;
2253
2254 case Action::PCC_ObjCInterface:
2255 return CodeCompletionContext::CCC_ObjCInterface;
2256
2257 case Action::PCC_ObjCImplementation:
2258 return CodeCompletionContext::CCC_ObjCImplementation;
2259
2260 case Action::PCC_ObjCInstanceVariableList:
2261 return CodeCompletionContext::CCC_ObjCIvarList;
2262
2263 case Action::PCC_Template:
2264 case Action::PCC_MemberTemplate:
2265 case Action::PCC_RecoveryInFunction:
2266 return CodeCompletionContext::CCC_Other;
2267
2268 case Action::PCC_Expression:
2269 case Action::PCC_ForInit:
2270 case Action::PCC_Condition:
2271 return CodeCompletionContext::CCC_Expression;
2272
2273 case Action::PCC_Statement:
2274 return CodeCompletionContext::CCC_Statement;
Douglas Gregor72db1082010-08-24 01:11:00 +00002275
2276 case Action::PCC_Type:
2277 return CodeCompletionContext::CCC_Type;
Douglas Gregore6b1bb62010-08-11 21:23:17 +00002278 }
2279
2280 return CodeCompletionContext::CCC_Other;
2281}
2282
Douglas Gregor01dfea02010-01-10 23:08:15 +00002283void Sema::CodeCompleteOrdinaryName(Scope *S,
Douglas Gregore6b1bb62010-08-11 21:23:17 +00002284 ParserCompletionContext CompletionContext) {
Douglas Gregor2a7925c2009-12-07 09:54:55 +00002285 typedef CodeCompleteConsumer::Result Result;
Douglas Gregor2ccccb32010-08-23 18:23:48 +00002286 ResultBuilder Results(*this);
Douglas Gregor01dfea02010-01-10 23:08:15 +00002287
2288 // Determine how to filter results, e.g., so that the names of
2289 // values (functions, enumerators, function templates, etc.) are
2290 // only allowed where we can have an expression.
2291 switch (CompletionContext) {
Douglas Gregore6b1bb62010-08-11 21:23:17 +00002292 case PCC_Namespace:
2293 case PCC_Class:
2294 case PCC_ObjCInterface:
2295 case PCC_ObjCImplementation:
2296 case PCC_ObjCInstanceVariableList:
2297 case PCC_Template:
2298 case PCC_MemberTemplate:
Douglas Gregor72db1082010-08-24 01:11:00 +00002299 case PCC_Type:
Douglas Gregor01dfea02010-01-10 23:08:15 +00002300 Results.setFilter(&ResultBuilder::IsOrdinaryNonValueName);
2301 break;
2302
Douglas Gregore6b1bb62010-08-11 21:23:17 +00002303 case PCC_Expression:
2304 case PCC_Statement:
2305 case PCC_ForInit:
2306 case PCC_Condition:
Douglas Gregor4710e5b2010-05-28 00:49:12 +00002307 if (WantTypesInContext(CompletionContext, getLangOptions()))
2308 Results.setFilter(&ResultBuilder::IsOrdinaryName);
2309 else
2310 Results.setFilter(&ResultBuilder::IsOrdinaryNonTypeName);
Douglas Gregor01dfea02010-01-10 23:08:15 +00002311 break;
Douglas Gregordc845342010-05-25 05:58:43 +00002312
Douglas Gregore6b1bb62010-08-11 21:23:17 +00002313 case PCC_RecoveryInFunction:
Douglas Gregordc845342010-05-25 05:58:43 +00002314 // Unfiltered
2315 break;
Douglas Gregor01dfea02010-01-10 23:08:15 +00002316 }
2317
Douglas Gregor1ca6ae82010-01-14 01:09:38 +00002318 CodeCompletionDeclConsumer Consumer(Results, CurContext);
Douglas Gregor8071e422010-08-15 06:18:01 +00002319 LookupVisibleDecls(S, LookupOrdinaryName, Consumer,
2320 CodeCompleter->includeGlobals());
Douglas Gregor2a7925c2009-12-07 09:54:55 +00002321
2322 Results.EnterNewScope();
Douglas Gregorbca403c2010-01-13 23:51:12 +00002323 AddOrdinaryNameResults(CompletionContext, S, *this, Results);
Douglas Gregor2a7925c2009-12-07 09:54:55 +00002324 Results.ExitScope();
2325
Douglas Gregoraa5f77b2010-08-23 21:54:33 +00002326 switch (CompletionContext) {
Douglas Gregor72db1082010-08-24 01:11:00 +00002327 case PCC_Expression:
2328 case PCC_Statement:
2329 case PCC_RecoveryInFunction:
2330 if (S->getFnParent())
2331 AddPrettyFunctionResults(PP.getLangOptions(), Results);
2332 break;
2333
2334 case PCC_Namespace:
2335 case PCC_Class:
2336 case PCC_ObjCInterface:
2337 case PCC_ObjCImplementation:
2338 case PCC_ObjCInstanceVariableList:
2339 case PCC_Template:
2340 case PCC_MemberTemplate:
2341 case PCC_ForInit:
2342 case PCC_Condition:
2343 case PCC_Type:
2344 break;
Douglas Gregoraa5f77b2010-08-23 21:54:33 +00002345 }
2346
Douglas Gregor0c8296d2009-11-07 00:00:49 +00002347 if (CodeCompleter->includeMacros())
Douglas Gregorbca403c2010-01-13 23:51:12 +00002348 AddMacroResults(PP, Results);
Douglas Gregoraa5f77b2010-08-23 21:54:33 +00002349
Douglas Gregore6b1bb62010-08-11 21:23:17 +00002350 HandleCodeCompleteResults(this, CodeCompleter,
2351 mapCodeCompletionContext(*this, CompletionContext),
2352 Results.data(),Results.size());
Douglas Gregor791215b2009-09-21 20:51:25 +00002353}
2354
Douglas Gregor2ccccb32010-08-23 18:23:48 +00002355void Sema::CodeCompleteDeclarator(Scope *S,
2356 bool AllowNonIdentifiers,
2357 bool AllowNestedNameSpecifiers) {
2358 typedef CodeCompleteConsumer::Result Result;
2359 ResultBuilder Results(*this);
2360 Results.EnterNewScope();
2361
2362 // Type qualifiers can come after names.
2363 Results.AddResult(Result("const"));
2364 Results.AddResult(Result("volatile"));
2365 if (getLangOptions().C99)
2366 Results.AddResult(Result("restrict"));
2367
2368 if (getLangOptions().CPlusPlus) {
2369 if (AllowNonIdentifiers) {
2370 Results.AddResult(Result("operator"));
2371 }
2372
2373 // Add nested-name-specifiers.
2374 if (AllowNestedNameSpecifiers) {
2375 Results.allowNestedNameSpecifiers();
2376 CodeCompletionDeclConsumer Consumer(Results, CurContext);
2377 LookupVisibleDecls(S, LookupNestedNameSpecifierName, Consumer,
2378 CodeCompleter->includeGlobals());
2379 }
2380 }
2381 Results.ExitScope();
2382
Douglas Gregor4497dd42010-08-24 04:59:56 +00002383 // Note that we intentionally suppress macro results here, since we do not
2384 // encourage using macros to produce the names of entities.
2385
Douglas Gregor2ccccb32010-08-23 18:23:48 +00002386 HandleCodeCompleteResults(this, CodeCompleter,
2387 AllowNestedNameSpecifiers
2388 ? CodeCompletionContext::CCC_PotentiallyQualifiedName
2389 : CodeCompletionContext::CCC_Name,
2390 Results.data(), Results.size());
2391}
2392
Douglas Gregorfb629412010-08-23 21:17:50 +00002393struct Sema::CodeCompleteExpressionData {
2394 CodeCompleteExpressionData(QualType PreferredType = QualType())
2395 : PreferredType(PreferredType), IntegralConstantExpression(false),
2396 ObjCCollection(false) { }
2397
2398 QualType PreferredType;
2399 bool IntegralConstantExpression;
2400 bool ObjCCollection;
2401 llvm::SmallVector<Decl *, 4> IgnoreDecls;
2402};
2403
Douglas Gregor5ac3bdb2010-05-30 01:49:25 +00002404/// \brief Perform code-completion in an expression context when we know what
2405/// type we're looking for.
Douglas Gregorf9578432010-07-28 21:50:18 +00002406///
2407/// \param IntegralConstantExpression Only permit integral constant
2408/// expressions.
Douglas Gregorfb629412010-08-23 21:17:50 +00002409void Sema::CodeCompleteExpression(Scope *S,
2410 const CodeCompleteExpressionData &Data) {
Douglas Gregor5ac3bdb2010-05-30 01:49:25 +00002411 typedef CodeCompleteConsumer::Result Result;
2412 ResultBuilder Results(*this);
2413
Douglas Gregorfb629412010-08-23 21:17:50 +00002414 if (Data.ObjCCollection)
2415 Results.setFilter(&ResultBuilder::IsObjCCollection);
2416 else if (Data.IntegralConstantExpression)
Douglas Gregorf9578432010-07-28 21:50:18 +00002417 Results.setFilter(&ResultBuilder::IsIntegralConstantValue);
Douglas Gregore6b1bb62010-08-11 21:23:17 +00002418 else if (WantTypesInContext(PCC_Expression, getLangOptions()))
Douglas Gregor5ac3bdb2010-05-30 01:49:25 +00002419 Results.setFilter(&ResultBuilder::IsOrdinaryName);
2420 else
2421 Results.setFilter(&ResultBuilder::IsOrdinaryNonTypeName);
Douglas Gregorfb629412010-08-23 21:17:50 +00002422
2423 if (!Data.PreferredType.isNull())
2424 Results.setPreferredType(Data.PreferredType.getNonReferenceType());
2425
2426 // Ignore any declarations that we were told that we don't care about.
2427 for (unsigned I = 0, N = Data.IgnoreDecls.size(); I != N; ++I)
2428 Results.Ignore(Data.IgnoreDecls[I]);
Douglas Gregor5ac3bdb2010-05-30 01:49:25 +00002429
2430 CodeCompletionDeclConsumer Consumer(Results, CurContext);
Douglas Gregor8071e422010-08-15 06:18:01 +00002431 LookupVisibleDecls(S, LookupOrdinaryName, Consumer,
2432 CodeCompleter->includeGlobals());
Douglas Gregor5ac3bdb2010-05-30 01:49:25 +00002433
2434 Results.EnterNewScope();
Douglas Gregore6b1bb62010-08-11 21:23:17 +00002435 AddOrdinaryNameResults(PCC_Expression, S, *this, Results);
Douglas Gregor5ac3bdb2010-05-30 01:49:25 +00002436 Results.ExitScope();
2437
Douglas Gregor590c7d52010-07-08 20:55:51 +00002438 bool PreferredTypeIsPointer = false;
Douglas Gregorfb629412010-08-23 21:17:50 +00002439 if (!Data.PreferredType.isNull())
2440 PreferredTypeIsPointer = Data.PreferredType->isAnyPointerType()
2441 || Data.PreferredType->isMemberPointerType()
2442 || Data.PreferredType->isBlockPointerType();
Douglas Gregor590c7d52010-07-08 20:55:51 +00002443
Douglas Gregoraa5f77b2010-08-23 21:54:33 +00002444 if (S->getFnParent() &&
2445 !Data.ObjCCollection &&
2446 !Data.IntegralConstantExpression)
2447 AddPrettyFunctionResults(PP.getLangOptions(), Results);
2448
Douglas Gregor5ac3bdb2010-05-30 01:49:25 +00002449 if (CodeCompleter->includeMacros())
Douglas Gregor590c7d52010-07-08 20:55:51 +00002450 AddMacroResults(PP, Results, PreferredTypeIsPointer);
Douglas Gregore6b1bb62010-08-11 21:23:17 +00002451 HandleCodeCompleteResults(this, CodeCompleter,
Douglas Gregorfb629412010-08-23 21:17:50 +00002452 CodeCompletionContext(CodeCompletionContext::CCC_Expression,
2453 Data.PreferredType),
Douglas Gregore6b1bb62010-08-11 21:23:17 +00002454 Results.data(),Results.size());
Douglas Gregor5ac3bdb2010-05-30 01:49:25 +00002455}
2456
2457
Douglas Gregor95ac6552009-11-18 01:29:26 +00002458static void AddObjCProperties(ObjCContainerDecl *Container,
Douglas Gregor322328b2009-11-18 22:32:06 +00002459 bool AllowCategories,
Douglas Gregor95ac6552009-11-18 01:29:26 +00002460 DeclContext *CurContext,
2461 ResultBuilder &Results) {
2462 typedef CodeCompleteConsumer::Result Result;
2463
2464 // Add properties in this container.
2465 for (ObjCContainerDecl::prop_iterator P = Container->prop_begin(),
2466 PEnd = Container->prop_end();
2467 P != PEnd;
2468 ++P)
2469 Results.MaybeAddResult(Result(*P, 0), CurContext);
2470
2471 // Add properties in referenced protocols.
2472 if (ObjCProtocolDecl *Protocol = dyn_cast<ObjCProtocolDecl>(Container)) {
2473 for (ObjCProtocolDecl::protocol_iterator P = Protocol->protocol_begin(),
2474 PEnd = Protocol->protocol_end();
2475 P != PEnd; ++P)
Douglas Gregor322328b2009-11-18 22:32:06 +00002476 AddObjCProperties(*P, AllowCategories, CurContext, Results);
Douglas Gregor95ac6552009-11-18 01:29:26 +00002477 } else if (ObjCInterfaceDecl *IFace = dyn_cast<ObjCInterfaceDecl>(Container)){
Douglas Gregor322328b2009-11-18 22:32:06 +00002478 if (AllowCategories) {
2479 // Look through categories.
2480 for (ObjCCategoryDecl *Category = IFace->getCategoryList();
2481 Category; Category = Category->getNextClassCategory())
2482 AddObjCProperties(Category, AllowCategories, CurContext, Results);
2483 }
Douglas Gregor95ac6552009-11-18 01:29:26 +00002484
2485 // Look through protocols.
2486 for (ObjCInterfaceDecl::protocol_iterator I = IFace->protocol_begin(),
2487 E = IFace->protocol_end();
2488 I != E; ++I)
Douglas Gregor322328b2009-11-18 22:32:06 +00002489 AddObjCProperties(*I, AllowCategories, CurContext, Results);
Douglas Gregor95ac6552009-11-18 01:29:26 +00002490
2491 // Look in the superclass.
2492 if (IFace->getSuperClass())
Douglas Gregor322328b2009-11-18 22:32:06 +00002493 AddObjCProperties(IFace->getSuperClass(), AllowCategories, CurContext,
2494 Results);
Douglas Gregor95ac6552009-11-18 01:29:26 +00002495 } else if (const ObjCCategoryDecl *Category
2496 = dyn_cast<ObjCCategoryDecl>(Container)) {
2497 // Look through protocols.
2498 for (ObjCInterfaceDecl::protocol_iterator P = Category->protocol_begin(),
2499 PEnd = Category->protocol_end();
2500 P != PEnd; ++P)
Douglas Gregor322328b2009-11-18 22:32:06 +00002501 AddObjCProperties(*P, AllowCategories, CurContext, Results);
Douglas Gregor95ac6552009-11-18 01:29:26 +00002502 }
2503}
2504
Douglas Gregor81b747b2009-09-17 21:32:03 +00002505void Sema::CodeCompleteMemberReferenceExpr(Scope *S, ExprTy *BaseE,
2506 SourceLocation OpLoc,
2507 bool IsArrow) {
2508 if (!BaseE || !CodeCompleter)
2509 return;
2510
Douglas Gregor86d9a522009-09-21 16:56:56 +00002511 typedef CodeCompleteConsumer::Result Result;
2512
Douglas Gregor81b747b2009-09-17 21:32:03 +00002513 Expr *Base = static_cast<Expr *>(BaseE);
2514 QualType BaseType = Base->getType();
Douglas Gregor86d9a522009-09-21 16:56:56 +00002515
2516 if (IsArrow) {
2517 if (const PointerType *Ptr = BaseType->getAs<PointerType>())
2518 BaseType = Ptr->getPointeeType();
2519 else if (BaseType->isObjCObjectPointerType())
2520 /*Do nothing*/ ;
2521 else
2522 return;
2523 }
2524
Douglas Gregoreb5758b2009-09-23 22:26:46 +00002525 ResultBuilder Results(*this, &ResultBuilder::IsMember);
Douglas Gregor95ac6552009-11-18 01:29:26 +00002526 Results.EnterNewScope();
2527 if (const RecordType *Record = BaseType->getAs<RecordType>()) {
2528 // Access to a C/C++ class, struct, or union.
Douglas Gregor45bcd432010-01-14 03:21:49 +00002529 Results.allowNestedNameSpecifiers();
Douglas Gregor0cc84042010-01-14 15:47:35 +00002530 CodeCompletionDeclConsumer Consumer(Results, CurContext);
Douglas Gregor8071e422010-08-15 06:18:01 +00002531 LookupVisibleDecls(Record->getDecl(), LookupMemberName, Consumer,
2532 CodeCompleter->includeGlobals());
Daniel Dunbar3a2838d2009-11-13 08:58:20 +00002533
Douglas Gregor95ac6552009-11-18 01:29:26 +00002534 if (getLangOptions().CPlusPlus) {
2535 if (!Results.empty()) {
2536 // The "template" keyword can follow "->" or "." in the grammar.
2537 // However, we only want to suggest the template keyword if something
2538 // is dependent.
2539 bool IsDependent = BaseType->isDependentType();
2540 if (!IsDependent) {
2541 for (Scope *DepScope = S; DepScope; DepScope = DepScope->getParent())
2542 if (DeclContext *Ctx = (DeclContext *)DepScope->getEntity()) {
2543 IsDependent = Ctx->isDependentContext();
2544 break;
2545 }
2546 }
Daniel Dunbar3a2838d2009-11-13 08:58:20 +00002547
Douglas Gregor95ac6552009-11-18 01:29:26 +00002548 if (IsDependent)
Douglas Gregora4477812010-01-14 16:01:26 +00002549 Results.AddResult(Result("template"));
Daniel Dunbar3a2838d2009-11-13 08:58:20 +00002550 }
Daniel Dunbar3a2838d2009-11-13 08:58:20 +00002551 }
Douglas Gregor95ac6552009-11-18 01:29:26 +00002552 } else if (!IsArrow && BaseType->getAsObjCInterfacePointerType()) {
2553 // Objective-C property reference.
2554
2555 // Add property results based on our interface.
2556 const ObjCObjectPointerType *ObjCPtr
2557 = BaseType->getAsObjCInterfacePointerType();
2558 assert(ObjCPtr && "Non-NULL pointer guaranteed above!");
Douglas Gregor322328b2009-11-18 22:32:06 +00002559 AddObjCProperties(ObjCPtr->getInterfaceDecl(), true, CurContext, Results);
Douglas Gregor95ac6552009-11-18 01:29:26 +00002560
2561 // Add properties from the protocols in a qualified interface.
2562 for (ObjCObjectPointerType::qual_iterator I = ObjCPtr->qual_begin(),
2563 E = ObjCPtr->qual_end();
2564 I != E; ++I)
Douglas Gregor322328b2009-11-18 22:32:06 +00002565 AddObjCProperties(*I, true, CurContext, Results);
Douglas Gregor95ac6552009-11-18 01:29:26 +00002566 } else if ((IsArrow && BaseType->isObjCObjectPointerType()) ||
John McCallc12c5bb2010-05-15 11:32:37 +00002567 (!IsArrow && BaseType->isObjCObjectType())) {
Douglas Gregor95ac6552009-11-18 01:29:26 +00002568 // Objective-C instance variable access.
2569 ObjCInterfaceDecl *Class = 0;
2570 if (const ObjCObjectPointerType *ObjCPtr
2571 = BaseType->getAs<ObjCObjectPointerType>())
2572 Class = ObjCPtr->getInterfaceDecl();
2573 else
John McCallc12c5bb2010-05-15 11:32:37 +00002574 Class = BaseType->getAs<ObjCObjectType>()->getInterface();
Douglas Gregor95ac6552009-11-18 01:29:26 +00002575
2576 // Add all ivars from this class and its superclasses.
Douglas Gregor80f4f4c2010-01-14 16:08:12 +00002577 if (Class) {
2578 CodeCompletionDeclConsumer Consumer(Results, CurContext);
2579 Results.setFilter(&ResultBuilder::IsObjCIvar);
Douglas Gregor8071e422010-08-15 06:18:01 +00002580 LookupVisibleDecls(Class, LookupMemberName, Consumer,
2581 CodeCompleter->includeGlobals());
Douglas Gregor95ac6552009-11-18 01:29:26 +00002582 }
Douglas Gregor86d9a522009-09-21 16:56:56 +00002583 }
Douglas Gregor95ac6552009-11-18 01:29:26 +00002584
2585 // FIXME: How do we cope with isa?
2586
2587 Results.ExitScope();
Daniel Dunbar3a2838d2009-11-13 08:58:20 +00002588
Daniel Dunbar3a2838d2009-11-13 08:58:20 +00002589 // Hand off the results found for code completion.
Douglas Gregore6b1bb62010-08-11 21:23:17 +00002590 HandleCodeCompleteResults(this, CodeCompleter,
2591 CodeCompletionContext(CodeCompletionContext::CCC_MemberAccess,
2592 BaseType),
2593 Results.data(),Results.size());
Douglas Gregor81b747b2009-09-17 21:32:03 +00002594}
2595
Douglas Gregor374929f2009-09-18 15:37:17 +00002596void Sema::CodeCompleteTag(Scope *S, unsigned TagSpec) {
2597 if (!CodeCompleter)
2598 return;
2599
Douglas Gregor86d9a522009-09-21 16:56:56 +00002600 typedef CodeCompleteConsumer::Result Result;
2601 ResultBuilder::LookupFilter Filter = 0;
Douglas Gregore6b1bb62010-08-11 21:23:17 +00002602 enum CodeCompletionContext::Kind ContextKind
2603 = CodeCompletionContext::CCC_Other;
Douglas Gregor374929f2009-09-18 15:37:17 +00002604 switch ((DeclSpec::TST)TagSpec) {
2605 case DeclSpec::TST_enum:
Douglas Gregor86d9a522009-09-21 16:56:56 +00002606 Filter = &ResultBuilder::IsEnum;
Douglas Gregore6b1bb62010-08-11 21:23:17 +00002607 ContextKind = CodeCompletionContext::CCC_EnumTag;
Douglas Gregor374929f2009-09-18 15:37:17 +00002608 break;
2609
2610 case DeclSpec::TST_union:
Douglas Gregor86d9a522009-09-21 16:56:56 +00002611 Filter = &ResultBuilder::IsUnion;
Douglas Gregore6b1bb62010-08-11 21:23:17 +00002612 ContextKind = CodeCompletionContext::CCC_UnionTag;
Douglas Gregor374929f2009-09-18 15:37:17 +00002613 break;
2614
2615 case DeclSpec::TST_struct:
Douglas Gregor374929f2009-09-18 15:37:17 +00002616 case DeclSpec::TST_class:
Douglas Gregor86d9a522009-09-21 16:56:56 +00002617 Filter = &ResultBuilder::IsClassOrStruct;
Douglas Gregore6b1bb62010-08-11 21:23:17 +00002618 ContextKind = CodeCompletionContext::CCC_ClassOrStructTag;
Douglas Gregor374929f2009-09-18 15:37:17 +00002619 break;
2620
2621 default:
2622 assert(false && "Unknown type specifier kind in CodeCompleteTag");
2623 return;
2624 }
Douglas Gregor86d9a522009-09-21 16:56:56 +00002625
John McCall0d6b1642010-04-23 18:46:30 +00002626 ResultBuilder Results(*this);
Douglas Gregor5d2fc402010-01-14 03:27:13 +00002627 CodeCompletionDeclConsumer Consumer(Results, CurContext);
John McCall0d6b1642010-04-23 18:46:30 +00002628
2629 // First pass: look for tags.
2630 Results.setFilter(Filter);
Douglas Gregor8071e422010-08-15 06:18:01 +00002631 LookupVisibleDecls(S, LookupTagName, Consumer,
2632 CodeCompleter->includeGlobals());
John McCall0d6b1642010-04-23 18:46:30 +00002633
Douglas Gregor8071e422010-08-15 06:18:01 +00002634 if (CodeCompleter->includeGlobals()) {
2635 // Second pass: look for nested name specifiers.
2636 Results.setFilter(&ResultBuilder::IsNestedNameSpecifier);
2637 LookupVisibleDecls(S, LookupNestedNameSpecifierName, Consumer);
2638 }
Douglas Gregor86d9a522009-09-21 16:56:56 +00002639
Douglas Gregore6b1bb62010-08-11 21:23:17 +00002640 HandleCodeCompleteResults(this, CodeCompleter, ContextKind,
2641 Results.data(),Results.size());
Douglas Gregor374929f2009-09-18 15:37:17 +00002642}
2643
Douglas Gregor3e1005f2009-09-21 18:10:23 +00002644void Sema::CodeCompleteCase(Scope *S) {
2645 if (getSwitchStack().empty() || !CodeCompleter)
2646 return;
2647
2648 SwitchStmt *Switch = getSwitchStack().back();
Douglas Gregorf9578432010-07-28 21:50:18 +00002649 if (!Switch->getCond()->getType()->isEnumeralType()) {
Douglas Gregorfb629412010-08-23 21:17:50 +00002650 CodeCompleteExpressionData Data(Switch->getCond()->getType());
2651 Data.IntegralConstantExpression = true;
2652 CodeCompleteExpression(S, Data);
Douglas Gregor3e1005f2009-09-21 18:10:23 +00002653 return;
Douglas Gregorf9578432010-07-28 21:50:18 +00002654 }
Douglas Gregor3e1005f2009-09-21 18:10:23 +00002655
2656 // Code-complete the cases of a switch statement over an enumeration type
2657 // by providing the list of
2658 EnumDecl *Enum = Switch->getCond()->getType()->getAs<EnumType>()->getDecl();
2659
2660 // Determine which enumerators we have already seen in the switch statement.
2661 // FIXME: Ideally, we would also be able to look *past* the code-completion
2662 // token, in case we are code-completing in the middle of the switch and not
2663 // at the end. However, we aren't able to do so at the moment.
2664 llvm::SmallPtrSet<EnumConstantDecl *, 8> EnumeratorsSeen;
Douglas Gregorb9d0ef72009-09-21 19:57:38 +00002665 NestedNameSpecifier *Qualifier = 0;
Douglas Gregor3e1005f2009-09-21 18:10:23 +00002666 for (SwitchCase *SC = Switch->getSwitchCaseList(); SC;
2667 SC = SC->getNextSwitchCase()) {
2668 CaseStmt *Case = dyn_cast<CaseStmt>(SC);
2669 if (!Case)
2670 continue;
2671
2672 Expr *CaseVal = Case->getLHS()->IgnoreParenCasts();
2673 if (DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(CaseVal))
2674 if (EnumConstantDecl *Enumerator
2675 = dyn_cast<EnumConstantDecl>(DRE->getDecl())) {
2676 // We look into the AST of the case statement to determine which
2677 // enumerator was named. Alternatively, we could compute the value of
2678 // the integral constant expression, then compare it against the
2679 // values of each enumerator. However, value-based approach would not
2680 // work as well with C++ templates where enumerators declared within a
2681 // template are type- and value-dependent.
2682 EnumeratorsSeen.insert(Enumerator);
2683
Douglas Gregorb9d0ef72009-09-21 19:57:38 +00002684 // If this is a qualified-id, keep track of the nested-name-specifier
2685 // so that we can reproduce it as part of code completion, e.g.,
Douglas Gregor3e1005f2009-09-21 18:10:23 +00002686 //
2687 // switch (TagD.getKind()) {
2688 // case TagDecl::TK_enum:
2689 // break;
2690 // case XXX
2691 //
Douglas Gregorb9d0ef72009-09-21 19:57:38 +00002692 // At the XXX, our completions are TagDecl::TK_union,
Douglas Gregor3e1005f2009-09-21 18:10:23 +00002693 // TagDecl::TK_struct, and TagDecl::TK_class, rather than TK_union,
2694 // TK_struct, and TK_class.
Douglas Gregora2813ce2009-10-23 18:54:35 +00002695 Qualifier = DRE->getQualifier();
Douglas Gregor3e1005f2009-09-21 18:10:23 +00002696 }
2697 }
2698
Douglas Gregorb9d0ef72009-09-21 19:57:38 +00002699 if (getLangOptions().CPlusPlus && !Qualifier && EnumeratorsSeen.empty()) {
2700 // If there are no prior enumerators in C++, check whether we have to
2701 // qualify the names of the enumerators that we suggest, because they
2702 // may not be visible in this scope.
2703 Qualifier = getRequiredQualification(Context, CurContext,
2704 Enum->getDeclContext());
2705
2706 // FIXME: Scoped enums need to start with "EnumDecl" as the context!
2707 }
2708
Douglas Gregor3e1005f2009-09-21 18:10:23 +00002709 // Add any enumerators that have not yet been mentioned.
2710 ResultBuilder Results(*this);
2711 Results.EnterNewScope();
2712 for (EnumDecl::enumerator_iterator E = Enum->enumerator_begin(),
2713 EEnd = Enum->enumerator_end();
2714 E != EEnd; ++E) {
2715 if (EnumeratorsSeen.count(*E))
2716 continue;
2717
Douglas Gregor608300b2010-01-14 16:14:35 +00002718 Results.AddResult(CodeCompleteConsumer::Result(*E, Qualifier),
2719 CurContext, 0, false);
Douglas Gregor3e1005f2009-09-21 18:10:23 +00002720 }
2721 Results.ExitScope();
Douglas Gregor2f880e42010-04-06 20:02:15 +00002722
Douglas Gregor0c8296d2009-11-07 00:00:49 +00002723 if (CodeCompleter->includeMacros())
Douglas Gregorbca403c2010-01-13 23:51:12 +00002724 AddMacroResults(PP, Results);
Douglas Gregore6b1bb62010-08-11 21:23:17 +00002725 HandleCodeCompleteResults(this, CodeCompleter,
2726 CodeCompletionContext::CCC_Expression,
2727 Results.data(),Results.size());
Douglas Gregor3e1005f2009-09-21 18:10:23 +00002728}
2729
Douglas Gregor9c6a0e92009-09-22 15:41:20 +00002730namespace {
2731 struct IsBetterOverloadCandidate {
2732 Sema &S;
John McCall5769d612010-02-08 23:07:23 +00002733 SourceLocation Loc;
Douglas Gregor9c6a0e92009-09-22 15:41:20 +00002734
2735 public:
John McCall5769d612010-02-08 23:07:23 +00002736 explicit IsBetterOverloadCandidate(Sema &S, SourceLocation Loc)
2737 : S(S), Loc(Loc) { }
Douglas Gregor9c6a0e92009-09-22 15:41:20 +00002738
2739 bool
2740 operator()(const OverloadCandidate &X, const OverloadCandidate &Y) const {
John McCall5769d612010-02-08 23:07:23 +00002741 return S.isBetterOverloadCandidate(X, Y, Loc);
Douglas Gregor9c6a0e92009-09-22 15:41:20 +00002742 }
2743 };
2744}
2745
Douglas Gregord28dcd72010-05-30 06:10:08 +00002746static bool anyNullArguments(Expr **Args, unsigned NumArgs) {
2747 if (NumArgs && !Args)
2748 return true;
2749
2750 for (unsigned I = 0; I != NumArgs; ++I)
2751 if (!Args[I])
2752 return true;
2753
2754 return false;
2755}
2756
Douglas Gregor9c6a0e92009-09-22 15:41:20 +00002757void Sema::CodeCompleteCall(Scope *S, ExprTy *FnIn,
2758 ExprTy **ArgsIn, unsigned NumArgs) {
2759 if (!CodeCompleter)
2760 return;
Douglas Gregoref96eac2009-12-11 19:06:04 +00002761
2762 // When we're code-completing for a call, we fall back to ordinary
2763 // name code-completion whenever we can't produce specific
2764 // results. We may want to revisit this strategy in the future,
2765 // e.g., by merging the two kinds of results.
2766
Douglas Gregor9c6a0e92009-09-22 15:41:20 +00002767 Expr *Fn = (Expr *)FnIn;
2768 Expr **Args = (Expr **)ArgsIn;
Douglas Gregoref96eac2009-12-11 19:06:04 +00002769
Douglas Gregor9c6a0e92009-09-22 15:41:20 +00002770 // Ignore type-dependent call expressions entirely.
Douglas Gregord28dcd72010-05-30 06:10:08 +00002771 if (!Fn || Fn->isTypeDependent() || anyNullArguments(Args, NumArgs) ||
Douglas Gregoref96eac2009-12-11 19:06:04 +00002772 Expr::hasAnyTypeDependentArguments(Args, NumArgs)) {
Douglas Gregore6b1bb62010-08-11 21:23:17 +00002773 CodeCompleteOrdinaryName(S, PCC_Expression);
Douglas Gregor9c6a0e92009-09-22 15:41:20 +00002774 return;
Douglas Gregoref96eac2009-12-11 19:06:04 +00002775 }
Douglas Gregor9c6a0e92009-09-22 15:41:20 +00002776
John McCall3b4294e2009-12-16 12:17:52 +00002777 // Build an overload candidate set based on the functions we find.
John McCall5769d612010-02-08 23:07:23 +00002778 SourceLocation Loc = Fn->getExprLoc();
2779 OverloadCandidateSet CandidateSet(Loc);
John McCall3b4294e2009-12-16 12:17:52 +00002780
Douglas Gregor9c6a0e92009-09-22 15:41:20 +00002781 // FIXME: What if we're calling something that isn't a function declaration?
2782 // FIXME: What if we're calling a pseudo-destructor?
2783 // FIXME: What if we're calling a member function?
2784
Douglas Gregorc0265402010-01-21 15:46:19 +00002785 typedef CodeCompleteConsumer::OverloadCandidate ResultCandidate;
2786 llvm::SmallVector<ResultCandidate, 8> Results;
2787
John McCall3b4294e2009-12-16 12:17:52 +00002788 Expr *NakedFn = Fn->IgnoreParenCasts();
2789 if (UnresolvedLookupExpr *ULE = dyn_cast<UnresolvedLookupExpr>(NakedFn))
2790 AddOverloadedCallCandidates(ULE, Args, NumArgs, CandidateSet,
2791 /*PartialOverloading=*/ true);
2792 else if (DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(NakedFn)) {
2793 FunctionDecl *FDecl = dyn_cast<FunctionDecl>(DRE->getDecl());
Douglas Gregorc0265402010-01-21 15:46:19 +00002794 if (FDecl) {
Douglas Gregord28dcd72010-05-30 06:10:08 +00002795 if (!getLangOptions().CPlusPlus ||
2796 !FDecl->getType()->getAs<FunctionProtoType>())
Douglas Gregorc0265402010-01-21 15:46:19 +00002797 Results.push_back(ResultCandidate(FDecl));
2798 else
John McCall86820f52010-01-26 01:37:31 +00002799 // FIXME: access?
John McCall9aa472c2010-03-19 07:35:19 +00002800 AddOverloadCandidate(FDecl, DeclAccessPair::make(FDecl, AS_none),
2801 Args, NumArgs, CandidateSet,
Douglas Gregorc27d6c52010-04-16 17:41:49 +00002802 false, /*PartialOverloading*/true);
Douglas Gregorc0265402010-01-21 15:46:19 +00002803 }
John McCall3b4294e2009-12-16 12:17:52 +00002804 }
Douglas Gregor9c6a0e92009-09-22 15:41:20 +00002805
Douglas Gregor5ac3bdb2010-05-30 01:49:25 +00002806 QualType ParamType;
2807
Douglas Gregorc0265402010-01-21 15:46:19 +00002808 if (!CandidateSet.empty()) {
2809 // Sort the overload candidate set by placing the best overloads first.
2810 std::stable_sort(CandidateSet.begin(), CandidateSet.end(),
John McCall5769d612010-02-08 23:07:23 +00002811 IsBetterOverloadCandidate(*this, Loc));
Douglas Gregor9c6a0e92009-09-22 15:41:20 +00002812
Douglas Gregorc0265402010-01-21 15:46:19 +00002813 // Add the remaining viable overload candidates as code-completion reslults.
2814 for (OverloadCandidateSet::iterator Cand = CandidateSet.begin(),
2815 CandEnd = CandidateSet.end();
2816 Cand != CandEnd; ++Cand) {
2817 if (Cand->Viable)
2818 Results.push_back(ResultCandidate(Cand->Function));
2819 }
Douglas Gregor5ac3bdb2010-05-30 01:49:25 +00002820
2821 // From the viable candidates, try to determine the type of this parameter.
2822 for (unsigned I = 0, N = Results.size(); I != N; ++I) {
2823 if (const FunctionType *FType = Results[I].getFunctionType())
2824 if (const FunctionProtoType *Proto = dyn_cast<FunctionProtoType>(FType))
2825 if (NumArgs < Proto->getNumArgs()) {
2826 if (ParamType.isNull())
2827 ParamType = Proto->getArgType(NumArgs);
2828 else if (!Context.hasSameUnqualifiedType(
2829 ParamType.getNonReferenceType(),
2830 Proto->getArgType(NumArgs).getNonReferenceType())) {
2831 ParamType = QualType();
2832 break;
2833 }
2834 }
2835 }
2836 } else {
2837 // Try to determine the parameter type from the type of the expression
2838 // being called.
2839 QualType FunctionType = Fn->getType();
2840 if (const PointerType *Ptr = FunctionType->getAs<PointerType>())
2841 FunctionType = Ptr->getPointeeType();
2842 else if (const BlockPointerType *BlockPtr
2843 = FunctionType->getAs<BlockPointerType>())
2844 FunctionType = BlockPtr->getPointeeType();
2845 else if (const MemberPointerType *MemPtr
2846 = FunctionType->getAs<MemberPointerType>())
2847 FunctionType = MemPtr->getPointeeType();
2848
2849 if (const FunctionProtoType *Proto
2850 = FunctionType->getAs<FunctionProtoType>()) {
2851 if (NumArgs < Proto->getNumArgs())
2852 ParamType = Proto->getArgType(NumArgs);
2853 }
Douglas Gregor9c6a0e92009-09-22 15:41:20 +00002854 }
Douglas Gregoref96eac2009-12-11 19:06:04 +00002855
Douglas Gregor5ac3bdb2010-05-30 01:49:25 +00002856 if (ParamType.isNull())
Douglas Gregore6b1bb62010-08-11 21:23:17 +00002857 CodeCompleteOrdinaryName(S, PCC_Expression);
Douglas Gregor5ac3bdb2010-05-30 01:49:25 +00002858 else
2859 CodeCompleteExpression(S, ParamType);
2860
Douglas Gregor2e4c7a52010-04-06 20:19:47 +00002861 if (!Results.empty())
Douglas Gregoref96eac2009-12-11 19:06:04 +00002862 CodeCompleter->ProcessOverloadCandidates(*this, NumArgs, Results.data(),
2863 Results.size());
Douglas Gregor9c6a0e92009-09-22 15:41:20 +00002864}
2865
John McCalld226f652010-08-21 09:40:31 +00002866void Sema::CodeCompleteInitializer(Scope *S, Decl *D) {
2867 ValueDecl *VD = dyn_cast_or_null<ValueDecl>(D);
Douglas Gregor5ac3bdb2010-05-30 01:49:25 +00002868 if (!VD) {
Douglas Gregore6b1bb62010-08-11 21:23:17 +00002869 CodeCompleteOrdinaryName(S, PCC_Expression);
Douglas Gregor5ac3bdb2010-05-30 01:49:25 +00002870 return;
2871 }
2872
2873 CodeCompleteExpression(S, VD->getType());
2874}
2875
2876void Sema::CodeCompleteReturn(Scope *S) {
2877 QualType ResultType;
2878 if (isa<BlockDecl>(CurContext)) {
2879 if (BlockScopeInfo *BSI = getCurBlock())
2880 ResultType = BSI->ReturnType;
2881 } else if (FunctionDecl *Function = dyn_cast<FunctionDecl>(CurContext))
2882 ResultType = Function->getResultType();
2883 else if (ObjCMethodDecl *Method = dyn_cast<ObjCMethodDecl>(CurContext))
2884 ResultType = Method->getResultType();
2885
2886 if (ResultType.isNull())
Douglas Gregore6b1bb62010-08-11 21:23:17 +00002887 CodeCompleteOrdinaryName(S, PCC_Expression);
Douglas Gregor5ac3bdb2010-05-30 01:49:25 +00002888 else
2889 CodeCompleteExpression(S, ResultType);
2890}
2891
2892void Sema::CodeCompleteAssignmentRHS(Scope *S, ExprTy *LHS) {
2893 if (LHS)
2894 CodeCompleteExpression(S, static_cast<Expr *>(LHS)->getType());
2895 else
Douglas Gregore6b1bb62010-08-11 21:23:17 +00002896 CodeCompleteOrdinaryName(S, PCC_Expression);
Douglas Gregor5ac3bdb2010-05-30 01:49:25 +00002897}
2898
Jeffrey Yasskin9ab14542010-04-08 16:38:48 +00002899void Sema::CodeCompleteQualifiedId(Scope *S, CXXScopeSpec &SS,
Douglas Gregor81b747b2009-09-17 21:32:03 +00002900 bool EnteringContext) {
2901 if (!SS.getScopeRep() || !CodeCompleter)
2902 return;
2903
Douglas Gregor86d9a522009-09-21 16:56:56 +00002904 DeclContext *Ctx = computeDeclContext(SS, EnteringContext);
2905 if (!Ctx)
2906 return;
Douglas Gregord1cd31a2009-12-11 18:28:39 +00002907
2908 // Try to instantiate any non-dependent declaration contexts before
2909 // we look in them.
John McCall77bb1aa2010-05-01 00:40:08 +00002910 if (!isDependentScopeSpecifier(SS) && RequireCompleteDeclContext(SS, Ctx))
Douglas Gregord1cd31a2009-12-11 18:28:39 +00002911 return;
2912
Douglas Gregor86d9a522009-09-21 16:56:56 +00002913 ResultBuilder Results(*this);
Douglas Gregordef91072010-01-14 03:35:48 +00002914 CodeCompletionDeclConsumer Consumer(Results, CurContext);
2915 LookupVisibleDecls(Ctx, LookupOrdinaryName, Consumer);
Douglas Gregor86d9a522009-09-21 16:56:56 +00002916
2917 // The "template" keyword can follow "::" in the grammar, but only
2918 // put it into the grammar if the nested-name-specifier is dependent.
2919 NestedNameSpecifier *NNS = (NestedNameSpecifier *)SS.getScopeRep();
2920 if (!Results.empty() && NNS->isDependent())
Douglas Gregora4477812010-01-14 16:01:26 +00002921 Results.AddResult("template");
Douglas Gregor86d9a522009-09-21 16:56:56 +00002922
Douglas Gregore6b1bb62010-08-11 21:23:17 +00002923 HandleCodeCompleteResults(this, CodeCompleter,
2924 CodeCompletionContext::CCC_Other,
2925 Results.data(),Results.size());
Douglas Gregor81b747b2009-09-17 21:32:03 +00002926}
Douglas Gregor49f40bd2009-09-18 19:03:04 +00002927
2928void Sema::CodeCompleteUsing(Scope *S) {
2929 if (!CodeCompleter)
2930 return;
2931
Douglas Gregor86d9a522009-09-21 16:56:56 +00002932 ResultBuilder Results(*this, &ResultBuilder::IsNestedNameSpecifier);
Douglas Gregor8e0a0e42009-09-22 23:31:26 +00002933 Results.EnterNewScope();
Douglas Gregor86d9a522009-09-21 16:56:56 +00002934
2935 // If we aren't in class scope, we could see the "namespace" keyword.
2936 if (!S->isClassScope())
Douglas Gregora4477812010-01-14 16:01:26 +00002937 Results.AddResult(CodeCompleteConsumer::Result("namespace"));
Douglas Gregor86d9a522009-09-21 16:56:56 +00002938
2939 // After "using", we can see anything that would start a
2940 // nested-name-specifier.
Douglas Gregor5d2fc402010-01-14 03:27:13 +00002941 CodeCompletionDeclConsumer Consumer(Results, CurContext);
Douglas Gregor8071e422010-08-15 06:18:01 +00002942 LookupVisibleDecls(S, LookupOrdinaryName, Consumer,
2943 CodeCompleter->includeGlobals());
Douglas Gregor8e0a0e42009-09-22 23:31:26 +00002944 Results.ExitScope();
Douglas Gregor86d9a522009-09-21 16:56:56 +00002945
Douglas Gregore6b1bb62010-08-11 21:23:17 +00002946 HandleCodeCompleteResults(this, CodeCompleter,
2947 CodeCompletionContext::CCC_Other,
2948 Results.data(),Results.size());
Douglas Gregor49f40bd2009-09-18 19:03:04 +00002949}
2950
2951void Sema::CodeCompleteUsingDirective(Scope *S) {
2952 if (!CodeCompleter)
2953 return;
2954
Douglas Gregor86d9a522009-09-21 16:56:56 +00002955 // After "using namespace", we expect to see a namespace name or namespace
2956 // alias.
2957 ResultBuilder Results(*this, &ResultBuilder::IsNamespaceOrAlias);
Douglas Gregor8e0a0e42009-09-22 23:31:26 +00002958 Results.EnterNewScope();
Douglas Gregor5d2fc402010-01-14 03:27:13 +00002959 CodeCompletionDeclConsumer Consumer(Results, CurContext);
Douglas Gregor8071e422010-08-15 06:18:01 +00002960 LookupVisibleDecls(S, LookupOrdinaryName, Consumer,
2961 CodeCompleter->includeGlobals());
Douglas Gregor8e0a0e42009-09-22 23:31:26 +00002962 Results.ExitScope();
Douglas Gregore6b1bb62010-08-11 21:23:17 +00002963 HandleCodeCompleteResults(this, CodeCompleter,
Douglas Gregor8071e422010-08-15 06:18:01 +00002964 CodeCompletionContext::CCC_Namespace,
Douglas Gregore6b1bb62010-08-11 21:23:17 +00002965 Results.data(),Results.size());
Douglas Gregor49f40bd2009-09-18 19:03:04 +00002966}
2967
2968void Sema::CodeCompleteNamespaceDecl(Scope *S) {
2969 if (!CodeCompleter)
2970 return;
2971
Douglas Gregor86d9a522009-09-21 16:56:56 +00002972 ResultBuilder Results(*this, &ResultBuilder::IsNamespace);
2973 DeclContext *Ctx = (DeclContext *)S->getEntity();
2974 if (!S->getParent())
2975 Ctx = Context.getTranslationUnitDecl();
2976
2977 if (Ctx && Ctx->isFileContext()) {
2978 // We only want to see those namespaces that have already been defined
2979 // within this scope, because its likely that the user is creating an
2980 // extended namespace declaration. Keep track of the most recent
2981 // definition of each namespace.
2982 std::map<NamespaceDecl *, NamespaceDecl *> OrigToLatest;
2983 for (DeclContext::specific_decl_iterator<NamespaceDecl>
2984 NS(Ctx->decls_begin()), NSEnd(Ctx->decls_end());
2985 NS != NSEnd; ++NS)
2986 OrigToLatest[NS->getOriginalNamespace()] = *NS;
2987
2988 // Add the most recent definition (or extended definition) of each
2989 // namespace to the list of results.
Douglas Gregor8e0a0e42009-09-22 23:31:26 +00002990 Results.EnterNewScope();
Douglas Gregor86d9a522009-09-21 16:56:56 +00002991 for (std::map<NamespaceDecl *, NamespaceDecl *>::iterator
2992 NS = OrigToLatest.begin(), NSEnd = OrigToLatest.end();
2993 NS != NSEnd; ++NS)
Douglas Gregor608300b2010-01-14 16:14:35 +00002994 Results.AddResult(CodeCompleteConsumer::Result(NS->second, 0),
2995 CurContext, 0, false);
Douglas Gregor8e0a0e42009-09-22 23:31:26 +00002996 Results.ExitScope();
Douglas Gregor86d9a522009-09-21 16:56:56 +00002997 }
2998
Douglas Gregore6b1bb62010-08-11 21:23:17 +00002999 HandleCodeCompleteResults(this, CodeCompleter,
3000 CodeCompletionContext::CCC_Other,
3001 Results.data(),Results.size());
Douglas Gregor49f40bd2009-09-18 19:03:04 +00003002}
3003
3004void Sema::CodeCompleteNamespaceAliasDecl(Scope *S) {
3005 if (!CodeCompleter)
3006 return;
3007
Douglas Gregor86d9a522009-09-21 16:56:56 +00003008 // After "namespace", we expect to see a namespace or alias.
3009 ResultBuilder Results(*this, &ResultBuilder::IsNamespaceOrAlias);
Douglas Gregor5d2fc402010-01-14 03:27:13 +00003010 CodeCompletionDeclConsumer Consumer(Results, CurContext);
Douglas Gregor8071e422010-08-15 06:18:01 +00003011 LookupVisibleDecls(S, LookupOrdinaryName, Consumer,
3012 CodeCompleter->includeGlobals());
Douglas Gregore6b1bb62010-08-11 21:23:17 +00003013 HandleCodeCompleteResults(this, CodeCompleter,
Douglas Gregor8071e422010-08-15 06:18:01 +00003014 CodeCompletionContext::CCC_Namespace,
Douglas Gregore6b1bb62010-08-11 21:23:17 +00003015 Results.data(),Results.size());
Douglas Gregor49f40bd2009-09-18 19:03:04 +00003016}
3017
Douglas Gregored8d3222009-09-18 20:05:18 +00003018void Sema::CodeCompleteOperatorName(Scope *S) {
3019 if (!CodeCompleter)
3020 return;
Douglas Gregor86d9a522009-09-21 16:56:56 +00003021
3022 typedef CodeCompleteConsumer::Result Result;
3023 ResultBuilder Results(*this, &ResultBuilder::IsType);
Douglas Gregor8e0a0e42009-09-22 23:31:26 +00003024 Results.EnterNewScope();
Douglas Gregored8d3222009-09-18 20:05:18 +00003025
Douglas Gregor86d9a522009-09-21 16:56:56 +00003026 // Add the names of overloadable operators.
3027#define OVERLOADED_OPERATOR(Name,Spelling,Token,Unary,Binary,MemberOnly) \
3028 if (std::strcmp(Spelling, "?")) \
Douglas Gregora4477812010-01-14 16:01:26 +00003029 Results.AddResult(Result(Spelling));
Douglas Gregor86d9a522009-09-21 16:56:56 +00003030#include "clang/Basic/OperatorKinds.def"
3031
3032 // Add any type names visible from the current scope
Douglas Gregor45bcd432010-01-14 03:21:49 +00003033 Results.allowNestedNameSpecifiers();
Douglas Gregor5d2fc402010-01-14 03:27:13 +00003034 CodeCompletionDeclConsumer Consumer(Results, CurContext);
Douglas Gregor8071e422010-08-15 06:18:01 +00003035 LookupVisibleDecls(S, LookupOrdinaryName, Consumer,
3036 CodeCompleter->includeGlobals());
Douglas Gregor86d9a522009-09-21 16:56:56 +00003037
3038 // Add any type specifiers
Douglas Gregorbca403c2010-01-13 23:51:12 +00003039 AddTypeSpecifierResults(getLangOptions(), Results);
Douglas Gregor8e0a0e42009-09-22 23:31:26 +00003040 Results.ExitScope();
Douglas Gregor86d9a522009-09-21 16:56:56 +00003041
Douglas Gregore6b1bb62010-08-11 21:23:17 +00003042 HandleCodeCompleteResults(this, CodeCompleter,
Douglas Gregor8071e422010-08-15 06:18:01 +00003043 CodeCompletionContext::CCC_Type,
Douglas Gregore6b1bb62010-08-11 21:23:17 +00003044 Results.data(),Results.size());
Douglas Gregored8d3222009-09-18 20:05:18 +00003045}
Douglas Gregor49f40bd2009-09-18 19:03:04 +00003046
Douglas Gregorb6ac2452010-01-13 21:24:21 +00003047// Macro that expands to @Keyword or Keyword, depending on whether NeedAt is
3048// true or false.
3049#define OBJC_AT_KEYWORD_NAME(NeedAt,Keyword) NeedAt? "@" #Keyword : #Keyword
Douglas Gregorbca403c2010-01-13 23:51:12 +00003050static void AddObjCImplementationResults(const LangOptions &LangOpts,
Douglas Gregorb6ac2452010-01-13 21:24:21 +00003051 ResultBuilder &Results,
3052 bool NeedAt) {
3053 typedef CodeCompleteConsumer::Result Result;
3054 // Since we have an implementation, we can end it.
Douglas Gregora4477812010-01-14 16:01:26 +00003055 Results.AddResult(Result(OBJC_AT_KEYWORD_NAME(NeedAt,end)));
Douglas Gregorb6ac2452010-01-13 21:24:21 +00003056
3057 CodeCompletionString *Pattern = 0;
3058 if (LangOpts.ObjC2) {
3059 // @dynamic
3060 Pattern = new CodeCompletionString;
3061 Pattern->AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt,dynamic));
3062 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
3063 Pattern->AddPlaceholderChunk("property");
Douglas Gregora4477812010-01-14 16:01:26 +00003064 Results.AddResult(Result(Pattern));
Douglas Gregorb6ac2452010-01-13 21:24:21 +00003065
3066 // @synthesize
3067 Pattern = new CodeCompletionString;
3068 Pattern->AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt,synthesize));
3069 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
3070 Pattern->AddPlaceholderChunk("property");
Douglas Gregora4477812010-01-14 16:01:26 +00003071 Results.AddResult(Result(Pattern));
Douglas Gregorb6ac2452010-01-13 21:24:21 +00003072 }
3073}
3074
Douglas Gregorbca403c2010-01-13 23:51:12 +00003075static void AddObjCInterfaceResults(const LangOptions &LangOpts,
Douglas Gregorb6ac2452010-01-13 21:24:21 +00003076 ResultBuilder &Results,
3077 bool NeedAt) {
3078 typedef CodeCompleteConsumer::Result Result;
3079
3080 // Since we have an interface or protocol, we can end it.
Douglas Gregora4477812010-01-14 16:01:26 +00003081 Results.AddResult(Result(OBJC_AT_KEYWORD_NAME(NeedAt,end)));
Douglas Gregorb6ac2452010-01-13 21:24:21 +00003082
3083 if (LangOpts.ObjC2) {
3084 // @property
Douglas Gregora4477812010-01-14 16:01:26 +00003085 Results.AddResult(Result(OBJC_AT_KEYWORD_NAME(NeedAt,property)));
Douglas Gregorb6ac2452010-01-13 21:24:21 +00003086
3087 // @required
Douglas Gregora4477812010-01-14 16:01:26 +00003088 Results.AddResult(Result(OBJC_AT_KEYWORD_NAME(NeedAt,required)));
Douglas Gregorb6ac2452010-01-13 21:24:21 +00003089
3090 // @optional
Douglas Gregora4477812010-01-14 16:01:26 +00003091 Results.AddResult(Result(OBJC_AT_KEYWORD_NAME(NeedAt,optional)));
Douglas Gregorb6ac2452010-01-13 21:24:21 +00003092 }
3093}
3094
Douglas Gregorbca403c2010-01-13 23:51:12 +00003095static void AddObjCTopLevelResults(ResultBuilder &Results, bool NeedAt) {
Douglas Gregorb6ac2452010-01-13 21:24:21 +00003096 typedef CodeCompleteConsumer::Result Result;
3097 CodeCompletionString *Pattern = 0;
3098
3099 // @class name ;
3100 Pattern = new CodeCompletionString;
3101 Pattern->AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt,class));
3102 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
Douglas Gregorc8bddde2010-05-28 00:22:41 +00003103 Pattern->AddPlaceholderChunk("name");
Douglas Gregora4477812010-01-14 16:01:26 +00003104 Results.AddResult(Result(Pattern));
Douglas Gregorb6ac2452010-01-13 21:24:21 +00003105
Douglas Gregorc8bddde2010-05-28 00:22:41 +00003106 if (Results.includeCodePatterns()) {
3107 // @interface name
3108 // FIXME: Could introduce the whole pattern, including superclasses and
3109 // such.
3110 Pattern = new CodeCompletionString;
3111 Pattern->AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt,interface));
3112 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
3113 Pattern->AddPlaceholderChunk("class");
3114 Results.AddResult(Result(Pattern));
Douglas Gregorb6ac2452010-01-13 21:24:21 +00003115
Douglas Gregorc8bddde2010-05-28 00:22:41 +00003116 // @protocol name
3117 Pattern = new CodeCompletionString;
3118 Pattern->AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt,protocol));
3119 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
3120 Pattern->AddPlaceholderChunk("protocol");
3121 Results.AddResult(Result(Pattern));
3122
3123 // @implementation name
3124 Pattern = new CodeCompletionString;
3125 Pattern->AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt,implementation));
3126 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
3127 Pattern->AddPlaceholderChunk("class");
3128 Results.AddResult(Result(Pattern));
3129 }
Douglas Gregorb6ac2452010-01-13 21:24:21 +00003130
3131 // @compatibility_alias name
3132 Pattern = new CodeCompletionString;
3133 Pattern->AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt,compatibility_alias));
3134 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
3135 Pattern->AddPlaceholderChunk("alias");
3136 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
3137 Pattern->AddPlaceholderChunk("class");
Douglas Gregora4477812010-01-14 16:01:26 +00003138 Results.AddResult(Result(Pattern));
Douglas Gregorb6ac2452010-01-13 21:24:21 +00003139}
3140
John McCalld226f652010-08-21 09:40:31 +00003141void Sema::CodeCompleteObjCAtDirective(Scope *S, Decl *ObjCImpDecl,
Douglas Gregorc464ae82009-12-07 09:27:33 +00003142 bool InInterface) {
3143 typedef CodeCompleteConsumer::Result Result;
3144 ResultBuilder Results(*this);
3145 Results.EnterNewScope();
Douglas Gregorb6ac2452010-01-13 21:24:21 +00003146 if (ObjCImpDecl)
Douglas Gregorbca403c2010-01-13 23:51:12 +00003147 AddObjCImplementationResults(getLangOptions(), Results, false);
Douglas Gregorb6ac2452010-01-13 21:24:21 +00003148 else if (InInterface)
Douglas Gregorbca403c2010-01-13 23:51:12 +00003149 AddObjCInterfaceResults(getLangOptions(), Results, false);
Douglas Gregorb6ac2452010-01-13 21:24:21 +00003150 else
Douglas Gregorbca403c2010-01-13 23:51:12 +00003151 AddObjCTopLevelResults(Results, false);
Douglas Gregorc464ae82009-12-07 09:27:33 +00003152 Results.ExitScope();
Douglas Gregore6b1bb62010-08-11 21:23:17 +00003153 HandleCodeCompleteResults(this, CodeCompleter,
3154 CodeCompletionContext::CCC_Other,
3155 Results.data(),Results.size());
Douglas Gregorc464ae82009-12-07 09:27:33 +00003156}
3157
Douglas Gregorbca403c2010-01-13 23:51:12 +00003158static void AddObjCExpressionResults(ResultBuilder &Results, bool NeedAt) {
Douglas Gregor9a0c85e2009-12-07 09:51:25 +00003159 typedef CodeCompleteConsumer::Result Result;
3160 CodeCompletionString *Pattern = 0;
3161
3162 // @encode ( type-name )
3163 Pattern = new CodeCompletionString;
Douglas Gregorb6ac2452010-01-13 21:24:21 +00003164 Pattern->AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt,encode));
Douglas Gregor9a0c85e2009-12-07 09:51:25 +00003165 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
3166 Pattern->AddPlaceholderChunk("type-name");
3167 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
Douglas Gregora4477812010-01-14 16:01:26 +00003168 Results.AddResult(Result(Pattern));
Douglas Gregor9a0c85e2009-12-07 09:51:25 +00003169
3170 // @protocol ( protocol-name )
3171 Pattern = new CodeCompletionString;
Douglas Gregorb6ac2452010-01-13 21:24:21 +00003172 Pattern->AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt,protocol));
Douglas Gregor9a0c85e2009-12-07 09:51:25 +00003173 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
3174 Pattern->AddPlaceholderChunk("protocol-name");
3175 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
Douglas Gregora4477812010-01-14 16:01:26 +00003176 Results.AddResult(Result(Pattern));
Douglas Gregor9a0c85e2009-12-07 09:51:25 +00003177
3178 // @selector ( selector )
3179 Pattern = new CodeCompletionString;
Douglas Gregorb6ac2452010-01-13 21:24:21 +00003180 Pattern->AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt,selector));
Douglas Gregor9a0c85e2009-12-07 09:51:25 +00003181 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
3182 Pattern->AddPlaceholderChunk("selector");
3183 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
Douglas Gregora4477812010-01-14 16:01:26 +00003184 Results.AddResult(Result(Pattern));
Douglas Gregor9a0c85e2009-12-07 09:51:25 +00003185}
3186
Douglas Gregorbca403c2010-01-13 23:51:12 +00003187static void AddObjCStatementResults(ResultBuilder &Results, bool NeedAt) {
Douglas Gregor9a0c85e2009-12-07 09:51:25 +00003188 typedef CodeCompleteConsumer::Result Result;
Douglas Gregor9a0c85e2009-12-07 09:51:25 +00003189 CodeCompletionString *Pattern = 0;
Douglas Gregorb6ac2452010-01-13 21:24:21 +00003190
Douglas Gregorc8bddde2010-05-28 00:22:41 +00003191 if (Results.includeCodePatterns()) {
3192 // @try { statements } @catch ( declaration ) { statements } @finally
3193 // { statements }
3194 Pattern = new CodeCompletionString;
3195 Pattern->AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt,try));
3196 Pattern->AddChunk(CodeCompletionString::CK_LeftBrace);
3197 Pattern->AddPlaceholderChunk("statements");
3198 Pattern->AddChunk(CodeCompletionString::CK_RightBrace);
3199 Pattern->AddTextChunk("@catch");
3200 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
3201 Pattern->AddPlaceholderChunk("parameter");
3202 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
3203 Pattern->AddChunk(CodeCompletionString::CK_LeftBrace);
3204 Pattern->AddPlaceholderChunk("statements");
3205 Pattern->AddChunk(CodeCompletionString::CK_RightBrace);
3206 Pattern->AddTextChunk("@finally");
3207 Pattern->AddChunk(CodeCompletionString::CK_LeftBrace);
3208 Pattern->AddPlaceholderChunk("statements");
3209 Pattern->AddChunk(CodeCompletionString::CK_RightBrace);
3210 Results.AddResult(Result(Pattern));
3211 }
Douglas Gregorb6ac2452010-01-13 21:24:21 +00003212
Douglas Gregor9a0c85e2009-12-07 09:51:25 +00003213 // @throw
3214 Pattern = new CodeCompletionString;
Douglas Gregorb6ac2452010-01-13 21:24:21 +00003215 Pattern->AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt,throw));
Douglas Gregor834389b2010-01-12 06:38:28 +00003216 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
Douglas Gregor9a0c85e2009-12-07 09:51:25 +00003217 Pattern->AddPlaceholderChunk("expression");
Douglas Gregora4477812010-01-14 16:01:26 +00003218 Results.AddResult(Result(Pattern));
Douglas Gregorb6ac2452010-01-13 21:24:21 +00003219
Douglas Gregorc8bddde2010-05-28 00:22:41 +00003220 if (Results.includeCodePatterns()) {
3221 // @synchronized ( expression ) { statements }
3222 Pattern = new CodeCompletionString;
3223 Pattern->AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt,synchronized));
3224 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
3225 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
3226 Pattern->AddPlaceholderChunk("expression");
3227 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
3228 Pattern->AddChunk(CodeCompletionString::CK_LeftBrace);
3229 Pattern->AddPlaceholderChunk("statements");
3230 Pattern->AddChunk(CodeCompletionString::CK_RightBrace);
3231 Results.AddResult(Result(Pattern));
3232 }
Douglas Gregorb6ac2452010-01-13 21:24:21 +00003233}
Douglas Gregor9a0c85e2009-12-07 09:51:25 +00003234
Douglas Gregorbca403c2010-01-13 23:51:12 +00003235static void AddObjCVisibilityResults(const LangOptions &LangOpts,
Douglas Gregorc38c3e12010-01-13 21:54:15 +00003236 ResultBuilder &Results,
3237 bool NeedAt) {
Douglas Gregorb6ac2452010-01-13 21:24:21 +00003238 typedef CodeCompleteConsumer::Result Result;
Douglas Gregora4477812010-01-14 16:01:26 +00003239 Results.AddResult(Result(OBJC_AT_KEYWORD_NAME(NeedAt,private)));
3240 Results.AddResult(Result(OBJC_AT_KEYWORD_NAME(NeedAt,protected)));
3241 Results.AddResult(Result(OBJC_AT_KEYWORD_NAME(NeedAt,public)));
Douglas Gregorc38c3e12010-01-13 21:54:15 +00003242 if (LangOpts.ObjC2)
Douglas Gregora4477812010-01-14 16:01:26 +00003243 Results.AddResult(Result(OBJC_AT_KEYWORD_NAME(NeedAt,package)));
Douglas Gregorc38c3e12010-01-13 21:54:15 +00003244}
3245
3246void Sema::CodeCompleteObjCAtVisibility(Scope *S) {
3247 ResultBuilder Results(*this);
3248 Results.EnterNewScope();
Douglas Gregorbca403c2010-01-13 23:51:12 +00003249 AddObjCVisibilityResults(getLangOptions(), Results, false);
Douglas Gregorc38c3e12010-01-13 21:54:15 +00003250 Results.ExitScope();
Douglas Gregore6b1bb62010-08-11 21:23:17 +00003251 HandleCodeCompleteResults(this, CodeCompleter,
3252 CodeCompletionContext::CCC_Other,
3253 Results.data(),Results.size());
Douglas Gregorc38c3e12010-01-13 21:54:15 +00003254}
3255
3256void Sema::CodeCompleteObjCAtStatement(Scope *S) {
Douglas Gregorb6ac2452010-01-13 21:24:21 +00003257 ResultBuilder Results(*this);
3258 Results.EnterNewScope();
Douglas Gregorbca403c2010-01-13 23:51:12 +00003259 AddObjCStatementResults(Results, false);
3260 AddObjCExpressionResults(Results, false);
Douglas Gregor9a0c85e2009-12-07 09:51:25 +00003261 Results.ExitScope();
Douglas Gregore6b1bb62010-08-11 21:23:17 +00003262 HandleCodeCompleteResults(this, CodeCompleter,
3263 CodeCompletionContext::CCC_Other,
3264 Results.data(),Results.size());
Douglas Gregor9a0c85e2009-12-07 09:51:25 +00003265}
3266
3267void Sema::CodeCompleteObjCAtExpression(Scope *S) {
3268 ResultBuilder Results(*this);
3269 Results.EnterNewScope();
Douglas Gregorbca403c2010-01-13 23:51:12 +00003270 AddObjCExpressionResults(Results, false);
Douglas Gregor9a0c85e2009-12-07 09:51:25 +00003271 Results.ExitScope();
Douglas Gregore6b1bb62010-08-11 21:23:17 +00003272 HandleCodeCompleteResults(this, CodeCompleter,
3273 CodeCompletionContext::CCC_Other,
3274 Results.data(),Results.size());
Douglas Gregor9a0c85e2009-12-07 09:51:25 +00003275}
3276
Douglas Gregor988358f2009-11-19 00:14:45 +00003277/// \brief Determine whether the addition of the given flag to an Objective-C
3278/// property's attributes will cause a conflict.
3279static bool ObjCPropertyFlagConflicts(unsigned Attributes, unsigned NewFlag) {
3280 // Check if we've already added this flag.
3281 if (Attributes & NewFlag)
3282 return true;
3283
3284 Attributes |= NewFlag;
3285
3286 // Check for collisions with "readonly".
3287 if ((Attributes & ObjCDeclSpec::DQ_PR_readonly) &&
3288 (Attributes & (ObjCDeclSpec::DQ_PR_readwrite |
3289 ObjCDeclSpec::DQ_PR_assign |
3290 ObjCDeclSpec::DQ_PR_copy |
3291 ObjCDeclSpec::DQ_PR_retain)))
3292 return true;
3293
3294 // Check for more than one of { assign, copy, retain }.
3295 unsigned AssignCopyRetMask = Attributes & (ObjCDeclSpec::DQ_PR_assign |
3296 ObjCDeclSpec::DQ_PR_copy |
3297 ObjCDeclSpec::DQ_PR_retain);
3298 if (AssignCopyRetMask &&
3299 AssignCopyRetMask != ObjCDeclSpec::DQ_PR_assign &&
3300 AssignCopyRetMask != ObjCDeclSpec::DQ_PR_copy &&
3301 AssignCopyRetMask != ObjCDeclSpec::DQ_PR_retain)
3302 return true;
3303
3304 return false;
3305}
3306
Douglas Gregora93b1082009-11-18 23:08:07 +00003307void Sema::CodeCompleteObjCPropertyFlags(Scope *S, ObjCDeclSpec &ODS) {
Steve Naroffece8e712009-10-08 21:55:05 +00003308 if (!CodeCompleter)
3309 return;
Douglas Gregord3c68542009-11-19 01:08:35 +00003310
Steve Naroffece8e712009-10-08 21:55:05 +00003311 unsigned Attributes = ODS.getPropertyAttributes();
3312
3313 typedef CodeCompleteConsumer::Result Result;
3314 ResultBuilder Results(*this);
3315 Results.EnterNewScope();
Douglas Gregor988358f2009-11-19 00:14:45 +00003316 if (!ObjCPropertyFlagConflicts(Attributes, ObjCDeclSpec::DQ_PR_readonly))
Douglas Gregora4477812010-01-14 16:01:26 +00003317 Results.AddResult(CodeCompleteConsumer::Result("readonly"));
Douglas Gregor988358f2009-11-19 00:14:45 +00003318 if (!ObjCPropertyFlagConflicts(Attributes, ObjCDeclSpec::DQ_PR_assign))
Douglas Gregora4477812010-01-14 16:01:26 +00003319 Results.AddResult(CodeCompleteConsumer::Result("assign"));
Douglas Gregor988358f2009-11-19 00:14:45 +00003320 if (!ObjCPropertyFlagConflicts(Attributes, ObjCDeclSpec::DQ_PR_readwrite))
Douglas Gregora4477812010-01-14 16:01:26 +00003321 Results.AddResult(CodeCompleteConsumer::Result("readwrite"));
Douglas Gregor988358f2009-11-19 00:14:45 +00003322 if (!ObjCPropertyFlagConflicts(Attributes, ObjCDeclSpec::DQ_PR_retain))
Douglas Gregora4477812010-01-14 16:01:26 +00003323 Results.AddResult(CodeCompleteConsumer::Result("retain"));
Douglas Gregor988358f2009-11-19 00:14:45 +00003324 if (!ObjCPropertyFlagConflicts(Attributes, ObjCDeclSpec::DQ_PR_copy))
Douglas Gregora4477812010-01-14 16:01:26 +00003325 Results.AddResult(CodeCompleteConsumer::Result("copy"));
Douglas Gregor988358f2009-11-19 00:14:45 +00003326 if (!ObjCPropertyFlagConflicts(Attributes, ObjCDeclSpec::DQ_PR_nonatomic))
Douglas Gregora4477812010-01-14 16:01:26 +00003327 Results.AddResult(CodeCompleteConsumer::Result("nonatomic"));
Douglas Gregor988358f2009-11-19 00:14:45 +00003328 if (!ObjCPropertyFlagConflicts(Attributes, ObjCDeclSpec::DQ_PR_setter)) {
Douglas Gregor54f01612009-11-19 00:01:57 +00003329 CodeCompletionString *Setter = new CodeCompletionString;
3330 Setter->AddTypedTextChunk("setter");
3331 Setter->AddTextChunk(" = ");
3332 Setter->AddPlaceholderChunk("method");
Douglas Gregora4477812010-01-14 16:01:26 +00003333 Results.AddResult(CodeCompleteConsumer::Result(Setter));
Douglas Gregor54f01612009-11-19 00:01:57 +00003334 }
Douglas Gregor988358f2009-11-19 00:14:45 +00003335 if (!ObjCPropertyFlagConflicts(Attributes, ObjCDeclSpec::DQ_PR_getter)) {
Douglas Gregor54f01612009-11-19 00:01:57 +00003336 CodeCompletionString *Getter = new CodeCompletionString;
3337 Getter->AddTypedTextChunk("getter");
3338 Getter->AddTextChunk(" = ");
3339 Getter->AddPlaceholderChunk("method");
Douglas Gregora4477812010-01-14 16:01:26 +00003340 Results.AddResult(CodeCompleteConsumer::Result(Getter));
Douglas Gregor54f01612009-11-19 00:01:57 +00003341 }
Steve Naroffece8e712009-10-08 21:55:05 +00003342 Results.ExitScope();
Douglas Gregore6b1bb62010-08-11 21:23:17 +00003343 HandleCodeCompleteResults(this, CodeCompleter,
3344 CodeCompletionContext::CCC_Other,
3345 Results.data(),Results.size());
Steve Naroffece8e712009-10-08 21:55:05 +00003346}
Steve Naroffc4df6d22009-11-07 02:08:14 +00003347
Douglas Gregor4ad96852009-11-19 07:41:15 +00003348/// \brief Descripts the kind of Objective-C method that we want to find
3349/// via code completion.
3350enum ObjCMethodKind {
3351 MK_Any, //< Any kind of method, provided it means other specified criteria.
3352 MK_ZeroArgSelector, //< Zero-argument (unary) selector.
3353 MK_OneArgSelector //< One-argument selector.
3354};
3355
3356static bool isAcceptableObjCMethod(ObjCMethodDecl *Method,
3357 ObjCMethodKind WantKind,
3358 IdentifierInfo **SelIdents,
3359 unsigned NumSelIdents) {
3360 Selector Sel = Method->getSelector();
3361 if (NumSelIdents > Sel.getNumArgs())
3362 return false;
3363
3364 switch (WantKind) {
3365 case MK_Any: break;
3366 case MK_ZeroArgSelector: return Sel.isUnarySelector();
3367 case MK_OneArgSelector: return Sel.getNumArgs() == 1;
3368 }
3369
3370 for (unsigned I = 0; I != NumSelIdents; ++I)
3371 if (SelIdents[I] != Sel.getIdentifierInfoForSlot(I))
3372 return false;
3373
3374 return true;
3375}
3376
Douglas Gregor36ecb042009-11-17 23:22:23 +00003377/// \brief Add all of the Objective-C methods in the given Objective-C
3378/// container to the set of results.
3379///
3380/// The container will be a class, protocol, category, or implementation of
3381/// any of the above. This mether will recurse to include methods from
3382/// the superclasses of classes along with their categories, protocols, and
3383/// implementations.
3384///
3385/// \param Container the container in which we'll look to find methods.
3386///
3387/// \param WantInstance whether to add instance methods (only); if false, this
3388/// routine will add factory methods (only).
3389///
3390/// \param CurContext the context in which we're performing the lookup that
3391/// finds methods.
3392///
3393/// \param Results the structure into which we'll add results.
3394static void AddObjCMethods(ObjCContainerDecl *Container,
3395 bool WantInstanceMethods,
Douglas Gregor4ad96852009-11-19 07:41:15 +00003396 ObjCMethodKind WantKind,
Douglas Gregord3c68542009-11-19 01:08:35 +00003397 IdentifierInfo **SelIdents,
3398 unsigned NumSelIdents,
Douglas Gregor36ecb042009-11-17 23:22:23 +00003399 DeclContext *CurContext,
3400 ResultBuilder &Results) {
3401 typedef CodeCompleteConsumer::Result Result;
3402 for (ObjCContainerDecl::method_iterator M = Container->meth_begin(),
3403 MEnd = Container->meth_end();
3404 M != MEnd; ++M) {
Douglas Gregord3c68542009-11-19 01:08:35 +00003405 if ((*M)->isInstanceMethod() == WantInstanceMethods) {
3406 // Check whether the selector identifiers we've been given are a
3407 // subset of the identifiers for this particular method.
Douglas Gregor4ad96852009-11-19 07:41:15 +00003408 if (!isAcceptableObjCMethod(*M, WantKind, SelIdents, NumSelIdents))
Douglas Gregord3c68542009-11-19 01:08:35 +00003409 continue;
Douglas Gregor4ad96852009-11-19 07:41:15 +00003410
Douglas Gregord3c68542009-11-19 01:08:35 +00003411 Result R = Result(*M, 0);
3412 R.StartParameter = NumSelIdents;
Douglas Gregor4ad96852009-11-19 07:41:15 +00003413 R.AllParametersAreInformative = (WantKind != MK_Any);
Douglas Gregord3c68542009-11-19 01:08:35 +00003414 Results.MaybeAddResult(R, CurContext);
3415 }
Douglas Gregor36ecb042009-11-17 23:22:23 +00003416 }
3417
3418 ObjCInterfaceDecl *IFace = dyn_cast<ObjCInterfaceDecl>(Container);
3419 if (!IFace)
3420 return;
3421
3422 // Add methods in protocols.
3423 const ObjCList<ObjCProtocolDecl> &Protocols= IFace->getReferencedProtocols();
3424 for (ObjCList<ObjCProtocolDecl>::iterator I = Protocols.begin(),
3425 E = Protocols.end();
3426 I != E; ++I)
Douglas Gregor4ad96852009-11-19 07:41:15 +00003427 AddObjCMethods(*I, WantInstanceMethods, WantKind, SelIdents, NumSelIdents,
Douglas Gregord3c68542009-11-19 01:08:35 +00003428 CurContext, Results);
Douglas Gregor36ecb042009-11-17 23:22:23 +00003429
3430 // Add methods in categories.
3431 for (ObjCCategoryDecl *CatDecl = IFace->getCategoryList(); CatDecl;
3432 CatDecl = CatDecl->getNextClassCategory()) {
Douglas Gregor4ad96852009-11-19 07:41:15 +00003433 AddObjCMethods(CatDecl, WantInstanceMethods, WantKind, SelIdents,
3434 NumSelIdents, CurContext, Results);
Douglas Gregor36ecb042009-11-17 23:22:23 +00003435
3436 // Add a categories protocol methods.
3437 const ObjCList<ObjCProtocolDecl> &Protocols
3438 = CatDecl->getReferencedProtocols();
3439 for (ObjCList<ObjCProtocolDecl>::iterator I = Protocols.begin(),
3440 E = Protocols.end();
3441 I != E; ++I)
Douglas Gregor4ad96852009-11-19 07:41:15 +00003442 AddObjCMethods(*I, WantInstanceMethods, WantKind, SelIdents,
3443 NumSelIdents, CurContext, Results);
Douglas Gregor36ecb042009-11-17 23:22:23 +00003444
3445 // Add methods in category implementations.
3446 if (ObjCCategoryImplDecl *Impl = CatDecl->getImplementation())
Douglas Gregor4ad96852009-11-19 07:41:15 +00003447 AddObjCMethods(Impl, WantInstanceMethods, WantKind, SelIdents,
3448 NumSelIdents, CurContext, Results);
Douglas Gregor36ecb042009-11-17 23:22:23 +00003449 }
3450
3451 // Add methods in superclass.
3452 if (IFace->getSuperClass())
Douglas Gregor4ad96852009-11-19 07:41:15 +00003453 AddObjCMethods(IFace->getSuperClass(), WantInstanceMethods, WantKind,
3454 SelIdents, NumSelIdents, CurContext, Results);
Douglas Gregor36ecb042009-11-17 23:22:23 +00003455
3456 // Add methods in our implementation, if any.
3457 if (ObjCImplementationDecl *Impl = IFace->getImplementation())
Douglas Gregor4ad96852009-11-19 07:41:15 +00003458 AddObjCMethods(Impl, WantInstanceMethods, WantKind, SelIdents,
3459 NumSelIdents, CurContext, Results);
3460}
3461
3462
John McCalld226f652010-08-21 09:40:31 +00003463void Sema::CodeCompleteObjCPropertyGetter(Scope *S, Decl *ClassDecl,
3464 Decl **Methods,
Douglas Gregor4ad96852009-11-19 07:41:15 +00003465 unsigned NumMethods) {
3466 typedef CodeCompleteConsumer::Result Result;
3467
3468 // Try to find the interface where getters might live.
John McCalld226f652010-08-21 09:40:31 +00003469 ObjCInterfaceDecl *Class = dyn_cast_or_null<ObjCInterfaceDecl>(ClassDecl);
Douglas Gregor4ad96852009-11-19 07:41:15 +00003470 if (!Class) {
3471 if (ObjCCategoryDecl *Category
John McCalld226f652010-08-21 09:40:31 +00003472 = dyn_cast_or_null<ObjCCategoryDecl>(ClassDecl))
Douglas Gregor4ad96852009-11-19 07:41:15 +00003473 Class = Category->getClassInterface();
3474
3475 if (!Class)
3476 return;
3477 }
3478
3479 // Find all of the potential getters.
3480 ResultBuilder Results(*this);
3481 Results.EnterNewScope();
3482
3483 // FIXME: We need to do this because Objective-C methods don't get
3484 // pushed into DeclContexts early enough. Argh!
3485 for (unsigned I = 0; I != NumMethods; ++I) {
3486 if (ObjCMethodDecl *Method
John McCalld226f652010-08-21 09:40:31 +00003487 = dyn_cast_or_null<ObjCMethodDecl>(Methods[I]))
Douglas Gregor4ad96852009-11-19 07:41:15 +00003488 if (Method->isInstanceMethod() &&
3489 isAcceptableObjCMethod(Method, MK_ZeroArgSelector, 0, 0)) {
3490 Result R = Result(Method, 0);
3491 R.AllParametersAreInformative = true;
3492 Results.MaybeAddResult(R, CurContext);
3493 }
3494 }
3495
3496 AddObjCMethods(Class, true, MK_ZeroArgSelector, 0, 0, CurContext, Results);
3497 Results.ExitScope();
Douglas Gregore6b1bb62010-08-11 21:23:17 +00003498 HandleCodeCompleteResults(this, CodeCompleter,
3499 CodeCompletionContext::CCC_Other,
3500 Results.data(),Results.size());
Douglas Gregor4ad96852009-11-19 07:41:15 +00003501}
3502
John McCalld226f652010-08-21 09:40:31 +00003503void Sema::CodeCompleteObjCPropertySetter(Scope *S, Decl *ObjCImplDecl,
3504 Decl **Methods,
Douglas Gregor4ad96852009-11-19 07:41:15 +00003505 unsigned NumMethods) {
3506 typedef CodeCompleteConsumer::Result Result;
3507
3508 // Try to find the interface where setters might live.
3509 ObjCInterfaceDecl *Class
John McCalld226f652010-08-21 09:40:31 +00003510 = dyn_cast_or_null<ObjCInterfaceDecl>(ObjCImplDecl);
Douglas Gregor4ad96852009-11-19 07:41:15 +00003511 if (!Class) {
3512 if (ObjCCategoryDecl *Category
John McCalld226f652010-08-21 09:40:31 +00003513 = dyn_cast_or_null<ObjCCategoryDecl>(ObjCImplDecl))
Douglas Gregor4ad96852009-11-19 07:41:15 +00003514 Class = Category->getClassInterface();
3515
3516 if (!Class)
3517 return;
3518 }
3519
3520 // Find all of the potential getters.
3521 ResultBuilder Results(*this);
3522 Results.EnterNewScope();
3523
3524 // FIXME: We need to do this because Objective-C methods don't get
3525 // pushed into DeclContexts early enough. Argh!
3526 for (unsigned I = 0; I != NumMethods; ++I) {
3527 if (ObjCMethodDecl *Method
John McCalld226f652010-08-21 09:40:31 +00003528 = dyn_cast_or_null<ObjCMethodDecl>(Methods[I]))
Douglas Gregor4ad96852009-11-19 07:41:15 +00003529 if (Method->isInstanceMethod() &&
3530 isAcceptableObjCMethod(Method, MK_OneArgSelector, 0, 0)) {
3531 Result R = Result(Method, 0);
3532 R.AllParametersAreInformative = true;
3533 Results.MaybeAddResult(R, CurContext);
3534 }
3535 }
3536
3537 AddObjCMethods(Class, true, MK_OneArgSelector, 0, 0, CurContext, Results);
3538
3539 Results.ExitScope();
Douglas Gregore6b1bb62010-08-11 21:23:17 +00003540 HandleCodeCompleteResults(this, CodeCompleter,
3541 CodeCompletionContext::CCC_Other,
3542 Results.data(),Results.size());
Douglas Gregor36ecb042009-11-17 23:22:23 +00003543}
3544
Douglas Gregord32b0222010-08-24 01:06:58 +00003545void Sema::CodeCompleteObjCPassingType(Scope *S, ObjCDeclSpec &DS) {
3546 typedef CodeCompleteConsumer::Result Result;
3547 ResultBuilder Results(*this);
3548 Results.EnterNewScope();
3549
3550 // Add context-sensitive, Objective-C parameter-passing keywords.
3551 bool AddedInOut = false;
3552 if ((DS.getObjCDeclQualifier() &
3553 (ObjCDeclSpec::DQ_In | ObjCDeclSpec::DQ_Inout)) == 0) {
3554 Results.AddResult("in");
3555 Results.AddResult("inout");
3556 AddedInOut = true;
3557 }
3558 if ((DS.getObjCDeclQualifier() &
3559 (ObjCDeclSpec::DQ_Out | ObjCDeclSpec::DQ_Inout)) == 0) {
3560 Results.AddResult("out");
3561 if (!AddedInOut)
3562 Results.AddResult("inout");
3563 }
3564 if ((DS.getObjCDeclQualifier() &
3565 (ObjCDeclSpec::DQ_Bycopy | ObjCDeclSpec::DQ_Byref |
3566 ObjCDeclSpec::DQ_Oneway)) == 0) {
3567 Results.AddResult("bycopy");
3568 Results.AddResult("byref");
3569 Results.AddResult("oneway");
3570 }
3571
3572 // Add various builtin type names and specifiers.
3573 AddOrdinaryNameResults(PCC_Type, S, *this, Results);
3574 Results.ExitScope();
3575
3576 // Add the various type names
3577 Results.setFilter(&ResultBuilder::IsOrdinaryNonValueName);
3578 CodeCompletionDeclConsumer Consumer(Results, CurContext);
3579 LookupVisibleDecls(S, LookupOrdinaryName, Consumer,
3580 CodeCompleter->includeGlobals());
3581
3582 if (CodeCompleter->includeMacros())
3583 AddMacroResults(PP, Results);
3584
3585 HandleCodeCompleteResults(this, CodeCompleter,
3586 CodeCompletionContext::CCC_Type,
3587 Results.data(), Results.size());
3588}
3589
Douglas Gregor22f56992010-04-06 19:22:33 +00003590/// \brief When we have an expression with type "id", we may assume
3591/// that it has some more-specific class type based on knowledge of
3592/// common uses of Objective-C. This routine returns that class type,
3593/// or NULL if no better result could be determined.
3594static ObjCInterfaceDecl *GetAssumedMessageSendExprType(Expr *E) {
3595 ObjCMessageExpr *Msg = dyn_cast<ObjCMessageExpr>(E);
3596 if (!Msg)
3597 return 0;
3598
3599 Selector Sel = Msg->getSelector();
3600 if (Sel.isNull())
3601 return 0;
3602
3603 IdentifierInfo *Id = Sel.getIdentifierInfoForSlot(0);
3604 if (!Id)
3605 return 0;
3606
3607 ObjCMethodDecl *Method = Msg->getMethodDecl();
3608 if (!Method)
3609 return 0;
3610
3611 // Determine the class that we're sending the message to.
Douglas Gregor04badcf2010-04-21 00:45:42 +00003612 ObjCInterfaceDecl *IFace = 0;
3613 switch (Msg->getReceiverKind()) {
3614 case ObjCMessageExpr::Class:
John McCallc12c5bb2010-05-15 11:32:37 +00003615 if (const ObjCObjectType *ObjType
3616 = Msg->getClassReceiver()->getAs<ObjCObjectType>())
3617 IFace = ObjType->getInterface();
Douglas Gregor04badcf2010-04-21 00:45:42 +00003618 break;
3619
3620 case ObjCMessageExpr::Instance: {
3621 QualType T = Msg->getInstanceReceiver()->getType();
3622 if (const ObjCObjectPointerType *Ptr = T->getAs<ObjCObjectPointerType>())
3623 IFace = Ptr->getInterfaceDecl();
3624 break;
3625 }
3626
3627 case ObjCMessageExpr::SuperInstance:
3628 case ObjCMessageExpr::SuperClass:
3629 break;
Douglas Gregor22f56992010-04-06 19:22:33 +00003630 }
3631
3632 if (!IFace)
3633 return 0;
3634
3635 ObjCInterfaceDecl *Super = IFace->getSuperClass();
3636 if (Method->isInstanceMethod())
3637 return llvm::StringSwitch<ObjCInterfaceDecl *>(Id->getName())
3638 .Case("retain", IFace)
3639 .Case("autorelease", IFace)
3640 .Case("copy", IFace)
3641 .Case("copyWithZone", IFace)
3642 .Case("mutableCopy", IFace)
3643 .Case("mutableCopyWithZone", IFace)
3644 .Case("awakeFromCoder", IFace)
3645 .Case("replacementObjectFromCoder", IFace)
3646 .Case("class", IFace)
3647 .Case("classForCoder", IFace)
3648 .Case("superclass", Super)
3649 .Default(0);
3650
3651 return llvm::StringSwitch<ObjCInterfaceDecl *>(Id->getName())
3652 .Case("new", IFace)
3653 .Case("alloc", IFace)
3654 .Case("allocWithZone", IFace)
3655 .Case("class", IFace)
3656 .Case("superclass", Super)
3657 .Default(0);
3658}
3659
Douglas Gregor8e254cf2010-05-27 23:06:34 +00003660void Sema::CodeCompleteObjCMessageReceiver(Scope *S) {
3661 typedef CodeCompleteConsumer::Result Result;
3662 ResultBuilder Results(*this);
3663
3664 // Find anything that looks like it could be a message receiver.
3665 Results.setFilter(&ResultBuilder::IsObjCMessageReceiver);
3666 CodeCompletionDeclConsumer Consumer(Results, CurContext);
3667 Results.EnterNewScope();
Douglas Gregor8071e422010-08-15 06:18:01 +00003668 LookupVisibleDecls(S, LookupOrdinaryName, Consumer,
3669 CodeCompleter->includeGlobals());
Douglas Gregor8e254cf2010-05-27 23:06:34 +00003670
3671 // If we are in an Objective-C method inside a class that has a superclass,
3672 // add "super" as an option.
3673 if (ObjCMethodDecl *Method = getCurMethodDecl())
3674 if (ObjCInterfaceDecl *Iface = Method->getClassInterface())
3675 if (Iface->getSuperClass())
3676 Results.AddResult(Result("super"));
3677
3678 Results.ExitScope();
3679
3680 if (CodeCompleter->includeMacros())
3681 AddMacroResults(PP, Results);
Douglas Gregore6b1bb62010-08-11 21:23:17 +00003682 HandleCodeCompleteResults(this, CodeCompleter,
3683 CodeCompletionContext::CCC_ObjCMessageReceiver,
3684 Results.data(), Results.size());
Douglas Gregor8e254cf2010-05-27 23:06:34 +00003685
3686}
3687
Douglas Gregor2725ca82010-04-21 19:57:20 +00003688void Sema::CodeCompleteObjCSuperMessage(Scope *S, SourceLocation SuperLoc,
3689 IdentifierInfo **SelIdents,
3690 unsigned NumSelIdents) {
3691 ObjCInterfaceDecl *CDecl = 0;
3692 if (ObjCMethodDecl *CurMethod = getCurMethodDecl()) {
3693 // Figure out which interface we're in.
3694 CDecl = CurMethod->getClassInterface();
3695 if (!CDecl)
3696 return;
3697
3698 // Find the superclass of this class.
3699 CDecl = CDecl->getSuperClass();
3700 if (!CDecl)
3701 return;
3702
3703 if (CurMethod->isInstanceMethod()) {
3704 // We are inside an instance method, which means that the message
3705 // send [super ...] is actually calling an instance method on the
3706 // current object. Build the super expression and handle this like
3707 // an instance method.
3708 QualType SuperTy = Context.getObjCInterfaceType(CDecl);
3709 SuperTy = Context.getObjCObjectPointerType(SuperTy);
John McCall60d7b3a2010-08-24 06:29:42 +00003710 ExprResult Super
Douglas Gregor2725ca82010-04-21 19:57:20 +00003711 = Owned(new (Context) ObjCSuperExpr(SuperLoc, SuperTy));
3712 return CodeCompleteObjCInstanceMessage(S, (Expr *)Super.get(),
3713 SelIdents, NumSelIdents);
3714 }
3715
3716 // Fall through to send to the superclass in CDecl.
3717 } else {
3718 // "super" may be the name of a type or variable. Figure out which
3719 // it is.
3720 IdentifierInfo *Super = &Context.Idents.get("super");
3721 NamedDecl *ND = LookupSingleName(S, Super, SuperLoc,
3722 LookupOrdinaryName);
3723 if ((CDecl = dyn_cast_or_null<ObjCInterfaceDecl>(ND))) {
3724 // "super" names an interface. Use it.
3725 } else if (TypeDecl *TD = dyn_cast_or_null<TypeDecl>(ND)) {
John McCallc12c5bb2010-05-15 11:32:37 +00003726 if (const ObjCObjectType *Iface
3727 = Context.getTypeDeclType(TD)->getAs<ObjCObjectType>())
3728 CDecl = Iface->getInterface();
Douglas Gregor2725ca82010-04-21 19:57:20 +00003729 } else if (ND && isa<UnresolvedUsingTypenameDecl>(ND)) {
3730 // "super" names an unresolved type; we can't be more specific.
3731 } else {
3732 // Assume that "super" names some kind of value and parse that way.
3733 CXXScopeSpec SS;
3734 UnqualifiedId id;
3735 id.setIdentifier(Super, SuperLoc);
John McCall60d7b3a2010-08-24 06:29:42 +00003736 ExprResult SuperExpr = ActOnIdExpression(S, SS, id, false, false);
Douglas Gregor2725ca82010-04-21 19:57:20 +00003737 return CodeCompleteObjCInstanceMessage(S, (Expr *)SuperExpr.get(),
3738 SelIdents, NumSelIdents);
3739 }
3740
3741 // Fall through
3742 }
3743
John McCallb3d87482010-08-24 05:47:05 +00003744 ParsedType Receiver;
Douglas Gregor2725ca82010-04-21 19:57:20 +00003745 if (CDecl)
John McCallb3d87482010-08-24 05:47:05 +00003746 Receiver = ParsedType::make(Context.getObjCInterfaceType(CDecl));
Douglas Gregor2725ca82010-04-21 19:57:20 +00003747 return CodeCompleteObjCClassMessage(S, Receiver, SelIdents,
3748 NumSelIdents);
3749}
3750
John McCallb3d87482010-08-24 05:47:05 +00003751void Sema::CodeCompleteObjCClassMessage(Scope *S, ParsedType Receiver,
Douglas Gregord3c68542009-11-19 01:08:35 +00003752 IdentifierInfo **SelIdents,
3753 unsigned NumSelIdents) {
Steve Naroffc4df6d22009-11-07 02:08:14 +00003754 typedef CodeCompleteConsumer::Result Result;
Douglas Gregor24a069f2009-11-17 17:59:40 +00003755 ObjCInterfaceDecl *CDecl = 0;
3756
Douglas Gregor24a069f2009-11-17 17:59:40 +00003757 // If the given name refers to an interface type, retrieve the
3758 // corresponding declaration.
Douglas Gregor2725ca82010-04-21 19:57:20 +00003759 if (Receiver) {
3760 QualType T = GetTypeFromParser(Receiver, 0);
3761 if (!T.isNull())
John McCallc12c5bb2010-05-15 11:32:37 +00003762 if (const ObjCObjectType *Interface = T->getAs<ObjCObjectType>())
3763 CDecl = Interface->getInterface();
Douglas Gregor24a069f2009-11-17 17:59:40 +00003764 }
3765
Douglas Gregor36ecb042009-11-17 23:22:23 +00003766 // Add all of the factory methods in this Objective-C class, its protocols,
3767 // superclasses, categories, implementation, etc.
Steve Naroffc4df6d22009-11-07 02:08:14 +00003768 ResultBuilder Results(*this);
3769 Results.EnterNewScope();
Douglas Gregor13438f92010-04-06 16:40:00 +00003770
3771 if (CDecl)
3772 AddObjCMethods(CDecl, false, MK_Any, SelIdents, NumSelIdents, CurContext,
3773 Results);
Douglas Gregor2725ca82010-04-21 19:57:20 +00003774 else {
Douglas Gregor13438f92010-04-06 16:40:00 +00003775 // We're messaging "id" as a type; provide all class/factory methods.
3776
Douglas Gregor719770d2010-04-06 17:30:22 +00003777 // If we have an external source, load the entire class method
Sebastian Redl3c7f4132010-08-18 23:57:06 +00003778 // pool from the AST file.
Douglas Gregor719770d2010-04-06 17:30:22 +00003779 if (ExternalSource) {
John McCall76bd1f32010-06-01 09:23:16 +00003780 for (uint32_t I = 0, N = ExternalSource->GetNumExternalSelectors();
3781 I != N; ++I) {
3782 Selector Sel = ExternalSource->GetExternalSelector(I);
Sebastian Redldb9d2142010-08-02 23:18:59 +00003783 if (Sel.isNull() || MethodPool.count(Sel))
Douglas Gregor719770d2010-04-06 17:30:22 +00003784 continue;
3785
Sebastian Redldb9d2142010-08-02 23:18:59 +00003786 ReadMethodPool(Sel);
Douglas Gregor719770d2010-04-06 17:30:22 +00003787 }
3788 }
3789
Sebastian Redldb9d2142010-08-02 23:18:59 +00003790 for (GlobalMethodPool::iterator M = MethodPool.begin(),
3791 MEnd = MethodPool.end();
3792 M != MEnd; ++M) {
3793 for (ObjCMethodList *MethList = &M->second.second;
3794 MethList && MethList->Method;
Douglas Gregor13438f92010-04-06 16:40:00 +00003795 MethList = MethList->Next) {
3796 if (!isAcceptableObjCMethod(MethList->Method, MK_Any, SelIdents,
3797 NumSelIdents))
3798 continue;
3799
3800 Result R(MethList->Method, 0);
3801 R.StartParameter = NumSelIdents;
3802 R.AllParametersAreInformative = false;
3803 Results.MaybeAddResult(R, CurContext);
3804 }
3805 }
3806 }
3807
Steve Naroffc4df6d22009-11-07 02:08:14 +00003808 Results.ExitScope();
Douglas Gregore6b1bb62010-08-11 21:23:17 +00003809 HandleCodeCompleteResults(this, CodeCompleter,
3810 CodeCompletionContext::CCC_Other,
3811 Results.data(),Results.size());
Steve Naroffc4df6d22009-11-07 02:08:14 +00003812}
3813
Douglas Gregord3c68542009-11-19 01:08:35 +00003814void Sema::CodeCompleteObjCInstanceMessage(Scope *S, ExprTy *Receiver,
3815 IdentifierInfo **SelIdents,
3816 unsigned NumSelIdents) {
Steve Naroffc4df6d22009-11-07 02:08:14 +00003817 typedef CodeCompleteConsumer::Result Result;
Steve Naroffc4df6d22009-11-07 02:08:14 +00003818
3819 Expr *RecExpr = static_cast<Expr *>(Receiver);
Steve Naroffc4df6d22009-11-07 02:08:14 +00003820
Douglas Gregor36ecb042009-11-17 23:22:23 +00003821 // If necessary, apply function/array conversion to the receiver.
3822 // C99 6.7.5.3p[7,8].
Douglas Gregora873dfc2010-02-03 00:27:59 +00003823 DefaultFunctionArrayLvalueConversion(RecExpr);
Douglas Gregor36ecb042009-11-17 23:22:23 +00003824 QualType ReceiverType = RecExpr->getType();
Steve Naroffc4df6d22009-11-07 02:08:14 +00003825
Douglas Gregor36ecb042009-11-17 23:22:23 +00003826 // Build the set of methods we can see.
3827 ResultBuilder Results(*this);
3828 Results.EnterNewScope();
Douglas Gregor22f56992010-04-06 19:22:33 +00003829
3830 // If we're messaging an expression with type "id" or "Class", check
3831 // whether we know something special about the receiver that allows
3832 // us to assume a more-specific receiver type.
3833 if (ReceiverType->isObjCIdType() || ReceiverType->isObjCClassType())
3834 if (ObjCInterfaceDecl *IFace = GetAssumedMessageSendExprType(RecExpr))
3835 ReceiverType = Context.getObjCObjectPointerType(
3836 Context.getObjCInterfaceType(IFace));
Douglas Gregor36ecb042009-11-17 23:22:23 +00003837
Douglas Gregorf74a4192009-11-18 00:06:18 +00003838 // Handle messages to Class. This really isn't a message to an instance
3839 // method, so we treat it the same way we would treat a message send to a
3840 // class method.
3841 if (ReceiverType->isObjCClassType() ||
3842 ReceiverType->isObjCQualifiedClassType()) {
3843 if (ObjCMethodDecl *CurMethod = getCurMethodDecl()) {
3844 if (ObjCInterfaceDecl *ClassDecl = CurMethod->getClassInterface())
Douglas Gregor4ad96852009-11-19 07:41:15 +00003845 AddObjCMethods(ClassDecl, false, MK_Any, SelIdents, NumSelIdents,
3846 CurContext, Results);
Douglas Gregorf74a4192009-11-18 00:06:18 +00003847 }
3848 }
3849 // Handle messages to a qualified ID ("id<foo>").
3850 else if (const ObjCObjectPointerType *QualID
3851 = ReceiverType->getAsObjCQualifiedIdType()) {
3852 // Search protocols for instance methods.
3853 for (ObjCObjectPointerType::qual_iterator I = QualID->qual_begin(),
3854 E = QualID->qual_end();
3855 I != E; ++I)
Douglas Gregor4ad96852009-11-19 07:41:15 +00003856 AddObjCMethods(*I, true, MK_Any, SelIdents, NumSelIdents, CurContext,
3857 Results);
Douglas Gregorf74a4192009-11-18 00:06:18 +00003858 }
3859 // Handle messages to a pointer to interface type.
3860 else if (const ObjCObjectPointerType *IFacePtr
3861 = ReceiverType->getAsObjCInterfacePointerType()) {
3862 // Search the class, its superclasses, etc., for instance methods.
Douglas Gregor4ad96852009-11-19 07:41:15 +00003863 AddObjCMethods(IFacePtr->getInterfaceDecl(), true, MK_Any, SelIdents,
3864 NumSelIdents, CurContext, Results);
Douglas Gregorf74a4192009-11-18 00:06:18 +00003865
3866 // Search protocols for instance methods.
3867 for (ObjCObjectPointerType::qual_iterator I = IFacePtr->qual_begin(),
3868 E = IFacePtr->qual_end();
3869 I != E; ++I)
Douglas Gregor4ad96852009-11-19 07:41:15 +00003870 AddObjCMethods(*I, true, MK_Any, SelIdents, NumSelIdents, CurContext,
3871 Results);
Douglas Gregorf74a4192009-11-18 00:06:18 +00003872 }
Douglas Gregor13438f92010-04-06 16:40:00 +00003873 // Handle messages to "id".
3874 else if (ReceiverType->isObjCIdType()) {
Douglas Gregor719770d2010-04-06 17:30:22 +00003875 // We're messaging "id", so provide all instance methods we know
3876 // about as code-completion results.
3877
3878 // If we have an external source, load the entire class method
Sebastian Redl3c7f4132010-08-18 23:57:06 +00003879 // pool from the AST file.
Douglas Gregor719770d2010-04-06 17:30:22 +00003880 if (ExternalSource) {
John McCall76bd1f32010-06-01 09:23:16 +00003881 for (uint32_t I = 0, N = ExternalSource->GetNumExternalSelectors();
3882 I != N; ++I) {
3883 Selector Sel = ExternalSource->GetExternalSelector(I);
Sebastian Redldb9d2142010-08-02 23:18:59 +00003884 if (Sel.isNull() || MethodPool.count(Sel))
Douglas Gregor719770d2010-04-06 17:30:22 +00003885 continue;
3886
Sebastian Redldb9d2142010-08-02 23:18:59 +00003887 ReadMethodPool(Sel);
Douglas Gregor719770d2010-04-06 17:30:22 +00003888 }
3889 }
3890
Sebastian Redldb9d2142010-08-02 23:18:59 +00003891 for (GlobalMethodPool::iterator M = MethodPool.begin(),
3892 MEnd = MethodPool.end();
3893 M != MEnd; ++M) {
3894 for (ObjCMethodList *MethList = &M->second.first;
3895 MethList && MethList->Method;
Douglas Gregor13438f92010-04-06 16:40:00 +00003896 MethList = MethList->Next) {
3897 if (!isAcceptableObjCMethod(MethList->Method, MK_Any, SelIdents,
3898 NumSelIdents))
3899 continue;
3900
3901 Result R(MethList->Method, 0);
3902 R.StartParameter = NumSelIdents;
3903 R.AllParametersAreInformative = false;
3904 Results.MaybeAddResult(R, CurContext);
3905 }
3906 }
3907 }
3908
Steve Naroffc4df6d22009-11-07 02:08:14 +00003909 Results.ExitScope();
Douglas Gregore6b1bb62010-08-11 21:23:17 +00003910 HandleCodeCompleteResults(this, CodeCompleter,
3911 CodeCompletionContext::CCC_Other,
3912 Results.data(),Results.size());
Steve Naroffc4df6d22009-11-07 02:08:14 +00003913}
Douglas Gregor55385fe2009-11-18 04:19:12 +00003914
Douglas Gregorfb629412010-08-23 21:17:50 +00003915void Sema::CodeCompleteObjCForCollection(Scope *S,
3916 DeclGroupPtrTy IterationVar) {
3917 CodeCompleteExpressionData Data;
3918 Data.ObjCCollection = true;
3919
3920 if (IterationVar.getAsOpaquePtr()) {
3921 DeclGroupRef DG = IterationVar.getAsVal<DeclGroupRef>();
3922 for (DeclGroupRef::iterator I = DG.begin(), End = DG.end(); I != End; ++I) {
3923 if (*I)
3924 Data.IgnoreDecls.push_back(*I);
3925 }
3926 }
3927
3928 CodeCompleteExpression(S, Data);
3929}
3930
Douglas Gregor55385fe2009-11-18 04:19:12 +00003931/// \brief Add all of the protocol declarations that we find in the given
3932/// (translation unit) context.
3933static void AddProtocolResults(DeclContext *Ctx, DeclContext *CurContext,
Douglas Gregor083128f2009-11-18 04:49:41 +00003934 bool OnlyForwardDeclarations,
Douglas Gregor55385fe2009-11-18 04:19:12 +00003935 ResultBuilder &Results) {
3936 typedef CodeCompleteConsumer::Result Result;
3937
3938 for (DeclContext::decl_iterator D = Ctx->decls_begin(),
3939 DEnd = Ctx->decls_end();
3940 D != DEnd; ++D) {
3941 // Record any protocols we find.
3942 if (ObjCProtocolDecl *Proto = dyn_cast<ObjCProtocolDecl>(*D))
Douglas Gregor083128f2009-11-18 04:49:41 +00003943 if (!OnlyForwardDeclarations || Proto->isForwardDecl())
Douglas Gregor608300b2010-01-14 16:14:35 +00003944 Results.AddResult(Result(Proto, 0), CurContext, 0, false);
Douglas Gregor55385fe2009-11-18 04:19:12 +00003945
3946 // Record any forward-declared protocols we find.
3947 if (ObjCForwardProtocolDecl *Forward
3948 = dyn_cast<ObjCForwardProtocolDecl>(*D)) {
3949 for (ObjCForwardProtocolDecl::protocol_iterator
3950 P = Forward->protocol_begin(),
3951 PEnd = Forward->protocol_end();
3952 P != PEnd; ++P)
Douglas Gregor083128f2009-11-18 04:49:41 +00003953 if (!OnlyForwardDeclarations || (*P)->isForwardDecl())
Douglas Gregor608300b2010-01-14 16:14:35 +00003954 Results.AddResult(Result(*P, 0), CurContext, 0, false);
Douglas Gregor55385fe2009-11-18 04:19:12 +00003955 }
3956 }
3957}
3958
3959void Sema::CodeCompleteObjCProtocolReferences(IdentifierLocPair *Protocols,
3960 unsigned NumProtocols) {
3961 ResultBuilder Results(*this);
3962 Results.EnterNewScope();
3963
3964 // Tell the result set to ignore all of the protocols we have
3965 // already seen.
3966 for (unsigned I = 0; I != NumProtocols; ++I)
Douglas Gregorc83c6872010-04-15 22:33:43 +00003967 if (ObjCProtocolDecl *Protocol = LookupProtocol(Protocols[I].first,
3968 Protocols[I].second))
Douglas Gregor55385fe2009-11-18 04:19:12 +00003969 Results.Ignore(Protocol);
3970
3971 // Add all protocols.
Douglas Gregor083128f2009-11-18 04:49:41 +00003972 AddProtocolResults(Context.getTranslationUnitDecl(), CurContext, false,
3973 Results);
3974
3975 Results.ExitScope();
Douglas Gregore6b1bb62010-08-11 21:23:17 +00003976 HandleCodeCompleteResults(this, CodeCompleter,
3977 CodeCompletionContext::CCC_ObjCProtocolName,
3978 Results.data(),Results.size());
Douglas Gregor083128f2009-11-18 04:49:41 +00003979}
3980
3981void Sema::CodeCompleteObjCProtocolDecl(Scope *) {
3982 ResultBuilder Results(*this);
3983 Results.EnterNewScope();
3984
3985 // Add all protocols.
3986 AddProtocolResults(Context.getTranslationUnitDecl(), CurContext, true,
3987 Results);
Douglas Gregor55385fe2009-11-18 04:19:12 +00003988
3989 Results.ExitScope();
Douglas Gregore6b1bb62010-08-11 21:23:17 +00003990 HandleCodeCompleteResults(this, CodeCompleter,
3991 CodeCompletionContext::CCC_ObjCProtocolName,
3992 Results.data(),Results.size());
Douglas Gregor55385fe2009-11-18 04:19:12 +00003993}
Douglas Gregor3b49aca2009-11-18 16:26:39 +00003994
3995/// \brief Add all of the Objective-C interface declarations that we find in
3996/// the given (translation unit) context.
3997static void AddInterfaceResults(DeclContext *Ctx, DeclContext *CurContext,
3998 bool OnlyForwardDeclarations,
3999 bool OnlyUnimplemented,
4000 ResultBuilder &Results) {
4001 typedef CodeCompleteConsumer::Result Result;
4002
4003 for (DeclContext::decl_iterator D = Ctx->decls_begin(),
4004 DEnd = Ctx->decls_end();
4005 D != DEnd; ++D) {
Douglas Gregordeacbdc2010-08-11 12:19:30 +00004006 // Record any interfaces we find.
4007 if (ObjCInterfaceDecl *Class = dyn_cast<ObjCInterfaceDecl>(*D))
4008 if ((!OnlyForwardDeclarations || Class->isForwardDecl()) &&
4009 (!OnlyUnimplemented || !Class->getImplementation()))
4010 Results.AddResult(Result(Class, 0), CurContext, 0, false);
Douglas Gregor3b49aca2009-11-18 16:26:39 +00004011
4012 // Record any forward-declared interfaces we find.
4013 if (ObjCClassDecl *Forward = dyn_cast<ObjCClassDecl>(*D)) {
4014 for (ObjCClassDecl::iterator C = Forward->begin(), CEnd = Forward->end();
Douglas Gregordeacbdc2010-08-11 12:19:30 +00004015 C != CEnd; ++C)
4016 if ((!OnlyForwardDeclarations || C->getInterface()->isForwardDecl()) &&
4017 (!OnlyUnimplemented || !C->getInterface()->getImplementation()))
4018 Results.AddResult(Result(C->getInterface(), 0), CurContext,
Douglas Gregor608300b2010-01-14 16:14:35 +00004019 0, false);
Douglas Gregor3b49aca2009-11-18 16:26:39 +00004020 }
4021 }
4022}
4023
4024void Sema::CodeCompleteObjCInterfaceDecl(Scope *S) {
4025 ResultBuilder Results(*this);
4026 Results.EnterNewScope();
4027
4028 // Add all classes.
4029 AddInterfaceResults(Context.getTranslationUnitDecl(), CurContext, true,
4030 false, Results);
4031
4032 Results.ExitScope();
Douglas Gregore6b1bb62010-08-11 21:23:17 +00004033 HandleCodeCompleteResults(this, CodeCompleter,
4034 CodeCompletionContext::CCC_Other,
4035 Results.data(),Results.size());
Douglas Gregor3b49aca2009-11-18 16:26:39 +00004036}
4037
Douglas Gregorc83c6872010-04-15 22:33:43 +00004038void Sema::CodeCompleteObjCSuperclass(Scope *S, IdentifierInfo *ClassName,
4039 SourceLocation ClassNameLoc) {
Douglas Gregor3b49aca2009-11-18 16:26:39 +00004040 ResultBuilder Results(*this);
4041 Results.EnterNewScope();
4042
4043 // Make sure that we ignore the class we're currently defining.
4044 NamedDecl *CurClass
Douglas Gregorc83c6872010-04-15 22:33:43 +00004045 = LookupSingleName(TUScope, ClassName, ClassNameLoc, LookupOrdinaryName);
Douglas Gregor33ced0b2009-11-18 19:08:43 +00004046 if (CurClass && isa<ObjCInterfaceDecl>(CurClass))
Douglas Gregor3b49aca2009-11-18 16:26:39 +00004047 Results.Ignore(CurClass);
4048
4049 // Add all classes.
4050 AddInterfaceResults(Context.getTranslationUnitDecl(), CurContext, false,
4051 false, Results);
4052
4053 Results.ExitScope();
Douglas Gregore6b1bb62010-08-11 21:23:17 +00004054 HandleCodeCompleteResults(this, CodeCompleter,
4055 CodeCompletionContext::CCC_Other,
4056 Results.data(),Results.size());
Douglas Gregor3b49aca2009-11-18 16:26:39 +00004057}
4058
4059void Sema::CodeCompleteObjCImplementationDecl(Scope *S) {
4060 ResultBuilder Results(*this);
4061 Results.EnterNewScope();
4062
4063 // Add all unimplemented classes.
4064 AddInterfaceResults(Context.getTranslationUnitDecl(), CurContext, false,
4065 true, Results);
4066
4067 Results.ExitScope();
Douglas Gregore6b1bb62010-08-11 21:23:17 +00004068 HandleCodeCompleteResults(this, CodeCompleter,
4069 CodeCompletionContext::CCC_Other,
4070 Results.data(),Results.size());
Douglas Gregor3b49aca2009-11-18 16:26:39 +00004071}
Douglas Gregor33ced0b2009-11-18 19:08:43 +00004072
4073void Sema::CodeCompleteObjCInterfaceCategory(Scope *S,
Douglas Gregorc83c6872010-04-15 22:33:43 +00004074 IdentifierInfo *ClassName,
4075 SourceLocation ClassNameLoc) {
Douglas Gregor33ced0b2009-11-18 19:08:43 +00004076 typedef CodeCompleteConsumer::Result Result;
4077
4078 ResultBuilder Results(*this);
4079
4080 // Ignore any categories we find that have already been implemented by this
4081 // interface.
4082 llvm::SmallPtrSet<IdentifierInfo *, 16> CategoryNames;
4083 NamedDecl *CurClass
Douglas Gregorc83c6872010-04-15 22:33:43 +00004084 = LookupSingleName(TUScope, ClassName, ClassNameLoc, LookupOrdinaryName);
Douglas Gregor33ced0b2009-11-18 19:08:43 +00004085 if (ObjCInterfaceDecl *Class = dyn_cast_or_null<ObjCInterfaceDecl>(CurClass))
4086 for (ObjCCategoryDecl *Category = Class->getCategoryList(); Category;
4087 Category = Category->getNextClassCategory())
4088 CategoryNames.insert(Category->getIdentifier());
4089
4090 // Add all of the categories we know about.
4091 Results.EnterNewScope();
4092 TranslationUnitDecl *TU = Context.getTranslationUnitDecl();
4093 for (DeclContext::decl_iterator D = TU->decls_begin(),
4094 DEnd = TU->decls_end();
4095 D != DEnd; ++D)
4096 if (ObjCCategoryDecl *Category = dyn_cast<ObjCCategoryDecl>(*D))
4097 if (CategoryNames.insert(Category->getIdentifier()))
Douglas Gregor608300b2010-01-14 16:14:35 +00004098 Results.AddResult(Result(Category, 0), CurContext, 0, false);
Douglas Gregor33ced0b2009-11-18 19:08:43 +00004099 Results.ExitScope();
4100
Douglas Gregore6b1bb62010-08-11 21:23:17 +00004101 HandleCodeCompleteResults(this, CodeCompleter,
4102 CodeCompletionContext::CCC_Other,
4103 Results.data(),Results.size());
Douglas Gregor33ced0b2009-11-18 19:08:43 +00004104}
4105
4106void Sema::CodeCompleteObjCImplementationCategory(Scope *S,
Douglas Gregorc83c6872010-04-15 22:33:43 +00004107 IdentifierInfo *ClassName,
4108 SourceLocation ClassNameLoc) {
Douglas Gregor33ced0b2009-11-18 19:08:43 +00004109 typedef CodeCompleteConsumer::Result Result;
4110
4111 // Find the corresponding interface. If we couldn't find the interface, the
4112 // program itself is ill-formed. However, we'll try to be helpful still by
4113 // providing the list of all of the categories we know about.
4114 NamedDecl *CurClass
Douglas Gregorc83c6872010-04-15 22:33:43 +00004115 = LookupSingleName(TUScope, ClassName, ClassNameLoc, LookupOrdinaryName);
Douglas Gregor33ced0b2009-11-18 19:08:43 +00004116 ObjCInterfaceDecl *Class = dyn_cast_or_null<ObjCInterfaceDecl>(CurClass);
4117 if (!Class)
Douglas Gregorc83c6872010-04-15 22:33:43 +00004118 return CodeCompleteObjCInterfaceCategory(S, ClassName, ClassNameLoc);
Douglas Gregor33ced0b2009-11-18 19:08:43 +00004119
4120 ResultBuilder Results(*this);
4121
4122 // Add all of the categories that have have corresponding interface
4123 // declarations in this class and any of its superclasses, except for
4124 // already-implemented categories in the class itself.
4125 llvm::SmallPtrSet<IdentifierInfo *, 16> CategoryNames;
4126 Results.EnterNewScope();
4127 bool IgnoreImplemented = true;
4128 while (Class) {
4129 for (ObjCCategoryDecl *Category = Class->getCategoryList(); Category;
4130 Category = Category->getNextClassCategory())
4131 if ((!IgnoreImplemented || !Category->getImplementation()) &&
4132 CategoryNames.insert(Category->getIdentifier()))
Douglas Gregor608300b2010-01-14 16:14:35 +00004133 Results.AddResult(Result(Category, 0), CurContext, 0, false);
Douglas Gregor33ced0b2009-11-18 19:08:43 +00004134
4135 Class = Class->getSuperClass();
4136 IgnoreImplemented = false;
4137 }
4138 Results.ExitScope();
4139
Douglas Gregore6b1bb62010-08-11 21:23:17 +00004140 HandleCodeCompleteResults(this, CodeCompleter,
4141 CodeCompletionContext::CCC_Other,
4142 Results.data(),Results.size());
Douglas Gregor33ced0b2009-11-18 19:08:43 +00004143}
Douglas Gregor322328b2009-11-18 22:32:06 +00004144
John McCalld226f652010-08-21 09:40:31 +00004145void Sema::CodeCompleteObjCPropertyDefinition(Scope *S, Decl *ObjCImpDecl) {
Douglas Gregor322328b2009-11-18 22:32:06 +00004146 typedef CodeCompleteConsumer::Result Result;
4147 ResultBuilder Results(*this);
4148
4149 // Figure out where this @synthesize lives.
4150 ObjCContainerDecl *Container
John McCalld226f652010-08-21 09:40:31 +00004151 = dyn_cast_or_null<ObjCContainerDecl>(ObjCImpDecl);
Douglas Gregor322328b2009-11-18 22:32:06 +00004152 if (!Container ||
4153 (!isa<ObjCImplementationDecl>(Container) &&
4154 !isa<ObjCCategoryImplDecl>(Container)))
4155 return;
4156
4157 // Ignore any properties that have already been implemented.
4158 for (DeclContext::decl_iterator D = Container->decls_begin(),
4159 DEnd = Container->decls_end();
4160 D != DEnd; ++D)
4161 if (ObjCPropertyImplDecl *PropertyImpl = dyn_cast<ObjCPropertyImplDecl>(*D))
4162 Results.Ignore(PropertyImpl->getPropertyDecl());
4163
4164 // Add any properties that we find.
4165 Results.EnterNewScope();
4166 if (ObjCImplementationDecl *ClassImpl
4167 = dyn_cast<ObjCImplementationDecl>(Container))
4168 AddObjCProperties(ClassImpl->getClassInterface(), false, CurContext,
4169 Results);
4170 else
4171 AddObjCProperties(cast<ObjCCategoryImplDecl>(Container)->getCategoryDecl(),
4172 false, CurContext, Results);
4173 Results.ExitScope();
4174
Douglas Gregore6b1bb62010-08-11 21:23:17 +00004175 HandleCodeCompleteResults(this, CodeCompleter,
4176 CodeCompletionContext::CCC_Other,
4177 Results.data(),Results.size());
Douglas Gregor322328b2009-11-18 22:32:06 +00004178}
4179
4180void Sema::CodeCompleteObjCPropertySynthesizeIvar(Scope *S,
4181 IdentifierInfo *PropertyName,
John McCalld226f652010-08-21 09:40:31 +00004182 Decl *ObjCImpDecl) {
Douglas Gregor322328b2009-11-18 22:32:06 +00004183 typedef CodeCompleteConsumer::Result Result;
4184 ResultBuilder Results(*this);
4185
4186 // Figure out where this @synthesize lives.
4187 ObjCContainerDecl *Container
John McCalld226f652010-08-21 09:40:31 +00004188 = dyn_cast_or_null<ObjCContainerDecl>(ObjCImpDecl);
Douglas Gregor322328b2009-11-18 22:32:06 +00004189 if (!Container ||
4190 (!isa<ObjCImplementationDecl>(Container) &&
4191 !isa<ObjCCategoryImplDecl>(Container)))
4192 return;
4193
4194 // Figure out which interface we're looking into.
4195 ObjCInterfaceDecl *Class = 0;
4196 if (ObjCImplementationDecl *ClassImpl
4197 = dyn_cast<ObjCImplementationDecl>(Container))
4198 Class = ClassImpl->getClassInterface();
4199 else
4200 Class = cast<ObjCCategoryImplDecl>(Container)->getCategoryDecl()
4201 ->getClassInterface();
4202
4203 // Add all of the instance variables in this class and its superclasses.
4204 Results.EnterNewScope();
4205 for(; Class; Class = Class->getSuperClass()) {
4206 // FIXME: We could screen the type of each ivar for compatibility with
4207 // the property, but is that being too paternal?
4208 for (ObjCInterfaceDecl::ivar_iterator IVar = Class->ivar_begin(),
4209 IVarEnd = Class->ivar_end();
4210 IVar != IVarEnd; ++IVar)
Douglas Gregor608300b2010-01-14 16:14:35 +00004211 Results.AddResult(Result(*IVar, 0), CurContext, 0, false);
Douglas Gregor322328b2009-11-18 22:32:06 +00004212 }
4213 Results.ExitScope();
4214
Douglas Gregore6b1bb62010-08-11 21:23:17 +00004215 HandleCodeCompleteResults(this, CodeCompleter,
4216 CodeCompletionContext::CCC_Other,
4217 Results.data(),Results.size());
Douglas Gregor322328b2009-11-18 22:32:06 +00004218}
Douglas Gregore8f5a172010-04-07 00:21:17 +00004219
4220typedef llvm::DenseMap<Selector, ObjCMethodDecl *> KnownMethodsMap;
4221
4222/// \brief Find all of the methods that reside in the given container
4223/// (and its superclasses, protocols, etc.) that meet the given
4224/// criteria. Insert those methods into the map of known methods,
4225/// indexed by selector so they can be easily found.
4226static void FindImplementableMethods(ASTContext &Context,
4227 ObjCContainerDecl *Container,
4228 bool WantInstanceMethods,
4229 QualType ReturnType,
4230 bool IsInImplementation,
4231 KnownMethodsMap &KnownMethods) {
4232 if (ObjCInterfaceDecl *IFace = dyn_cast<ObjCInterfaceDecl>(Container)) {
4233 // Recurse into protocols.
4234 const ObjCList<ObjCProtocolDecl> &Protocols
4235 = IFace->getReferencedProtocols();
4236 for (ObjCList<ObjCProtocolDecl>::iterator I = Protocols.begin(),
4237 E = Protocols.end();
4238 I != E; ++I)
4239 FindImplementableMethods(Context, *I, WantInstanceMethods, ReturnType,
4240 IsInImplementation, KnownMethods);
4241
4242 // If we're not in the implementation of a class, also visit the
4243 // superclass.
4244 if (!IsInImplementation && IFace->getSuperClass())
4245 FindImplementableMethods(Context, IFace->getSuperClass(),
4246 WantInstanceMethods, ReturnType,
4247 IsInImplementation, KnownMethods);
4248
4249 // Add methods from any class extensions (but not from categories;
4250 // those should go into category implementations).
Fariborz Jahanian80aa1cd2010-06-22 23:20:40 +00004251 for (const ObjCCategoryDecl *Cat = IFace->getFirstClassExtension(); Cat;
4252 Cat = Cat->getNextClassExtension())
4253 FindImplementableMethods(Context, const_cast<ObjCCategoryDecl*>(Cat),
4254 WantInstanceMethods, ReturnType,
Douglas Gregore8f5a172010-04-07 00:21:17 +00004255 IsInImplementation, KnownMethods);
Douglas Gregore8f5a172010-04-07 00:21:17 +00004256 }
4257
4258 if (ObjCCategoryDecl *Category = dyn_cast<ObjCCategoryDecl>(Container)) {
4259 // Recurse into protocols.
4260 const ObjCList<ObjCProtocolDecl> &Protocols
4261 = Category->getReferencedProtocols();
4262 for (ObjCList<ObjCProtocolDecl>::iterator I = Protocols.begin(),
4263 E = Protocols.end();
4264 I != E; ++I)
4265 FindImplementableMethods(Context, *I, WantInstanceMethods, ReturnType,
4266 IsInImplementation, KnownMethods);
4267 }
4268
4269 if (ObjCProtocolDecl *Protocol = dyn_cast<ObjCProtocolDecl>(Container)) {
4270 // Recurse into protocols.
4271 const ObjCList<ObjCProtocolDecl> &Protocols
4272 = Protocol->getReferencedProtocols();
4273 for (ObjCList<ObjCProtocolDecl>::iterator I = Protocols.begin(),
4274 E = Protocols.end();
4275 I != E; ++I)
4276 FindImplementableMethods(Context, *I, WantInstanceMethods, ReturnType,
4277 IsInImplementation, KnownMethods);
4278 }
4279
4280 // Add methods in this container. This operation occurs last because
4281 // we want the methods from this container to override any methods
4282 // we've previously seen with the same selector.
4283 for (ObjCContainerDecl::method_iterator M = Container->meth_begin(),
4284 MEnd = Container->meth_end();
4285 M != MEnd; ++M) {
4286 if ((*M)->isInstanceMethod() == WantInstanceMethods) {
4287 if (!ReturnType.isNull() &&
4288 !Context.hasSameUnqualifiedType(ReturnType, (*M)->getResultType()))
4289 continue;
4290
4291 KnownMethods[(*M)->getSelector()] = *M;
4292 }
4293 }
4294}
4295
4296void Sema::CodeCompleteObjCMethodDecl(Scope *S,
4297 bool IsInstanceMethod,
John McCallb3d87482010-08-24 05:47:05 +00004298 ParsedType ReturnTy,
John McCalld226f652010-08-21 09:40:31 +00004299 Decl *IDecl) {
Douglas Gregore8f5a172010-04-07 00:21:17 +00004300 // Determine the return type of the method we're declaring, if
4301 // provided.
4302 QualType ReturnType = GetTypeFromParser(ReturnTy);
4303
4304 // Determine where we should start searching for methods, and where we
4305 ObjCContainerDecl *SearchDecl = 0, *CurrentDecl = 0;
4306 bool IsInImplementation = false;
John McCalld226f652010-08-21 09:40:31 +00004307 if (Decl *D = IDecl) {
Douglas Gregore8f5a172010-04-07 00:21:17 +00004308 if (ObjCImplementationDecl *Impl = dyn_cast<ObjCImplementationDecl>(D)) {
4309 SearchDecl = Impl->getClassInterface();
4310 CurrentDecl = Impl;
4311 IsInImplementation = true;
4312 } else if (ObjCCategoryImplDecl *CatImpl
4313 = dyn_cast<ObjCCategoryImplDecl>(D)) {
4314 SearchDecl = CatImpl->getCategoryDecl();
4315 CurrentDecl = CatImpl;
4316 IsInImplementation = true;
4317 } else {
4318 SearchDecl = dyn_cast<ObjCContainerDecl>(D);
4319 CurrentDecl = SearchDecl;
4320 }
4321 }
4322
4323 if (!SearchDecl && S) {
4324 if (DeclContext *DC = static_cast<DeclContext *>(S->getEntity())) {
4325 SearchDecl = dyn_cast<ObjCContainerDecl>(DC);
4326 CurrentDecl = SearchDecl;
4327 }
4328 }
4329
4330 if (!SearchDecl || !CurrentDecl) {
Douglas Gregore6b1bb62010-08-11 21:23:17 +00004331 HandleCodeCompleteResults(this, CodeCompleter,
4332 CodeCompletionContext::CCC_Other,
4333 0, 0);
Douglas Gregore8f5a172010-04-07 00:21:17 +00004334 return;
4335 }
4336
4337 // Find all of the methods that we could declare/implement here.
4338 KnownMethodsMap KnownMethods;
4339 FindImplementableMethods(Context, SearchDecl, IsInstanceMethod,
4340 ReturnType, IsInImplementation, KnownMethods);
4341
4342 // Erase any methods that have already been declared or
4343 // implemented here.
4344 for (ObjCContainerDecl::method_iterator M = CurrentDecl->meth_begin(),
4345 MEnd = CurrentDecl->meth_end();
4346 M != MEnd; ++M) {
4347 if ((*M)->isInstanceMethod() != IsInstanceMethod)
4348 continue;
4349
4350 KnownMethodsMap::iterator Pos = KnownMethods.find((*M)->getSelector());
4351 if (Pos != KnownMethods.end())
4352 KnownMethods.erase(Pos);
4353 }
4354
4355 // Add declarations or definitions for each of the known methods.
4356 typedef CodeCompleteConsumer::Result Result;
4357 ResultBuilder Results(*this);
4358 Results.EnterNewScope();
4359 PrintingPolicy Policy(Context.PrintingPolicy);
4360 Policy.AnonymousTagLocations = false;
4361 for (KnownMethodsMap::iterator M = KnownMethods.begin(),
4362 MEnd = KnownMethods.end();
4363 M != MEnd; ++M) {
4364 ObjCMethodDecl *Method = M->second;
4365 CodeCompletionString *Pattern = new CodeCompletionString;
4366
4367 // If the result type was not already provided, add it to the
4368 // pattern as (type).
4369 if (ReturnType.isNull()) {
4370 std::string TypeStr;
4371 Method->getResultType().getAsStringInternal(TypeStr, Policy);
4372 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
4373 Pattern->AddTextChunk(TypeStr);
4374 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
4375 }
4376
4377 Selector Sel = Method->getSelector();
4378
4379 // Add the first part of the selector to the pattern.
4380 Pattern->AddTypedTextChunk(Sel.getIdentifierInfoForSlot(0)->getName());
4381
4382 // Add parameters to the pattern.
4383 unsigned I = 0;
4384 for (ObjCMethodDecl::param_iterator P = Method->param_begin(),
4385 PEnd = Method->param_end();
4386 P != PEnd; (void)++P, ++I) {
4387 // Add the part of the selector name.
4388 if (I == 0)
4389 Pattern->AddChunk(CodeCompletionString::CK_Colon);
4390 else if (I < Sel.getNumArgs()) {
4391 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
Douglas Gregor47c03a72010-08-17 15:53:35 +00004392 Pattern->AddTextChunk(Sel.getIdentifierInfoForSlot(I)->getName());
Douglas Gregore8f5a172010-04-07 00:21:17 +00004393 Pattern->AddChunk(CodeCompletionString::CK_Colon);
4394 } else
4395 break;
4396
4397 // Add the parameter type.
4398 std::string TypeStr;
4399 (*P)->getOriginalType().getAsStringInternal(TypeStr, Policy);
4400 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
4401 Pattern->AddTextChunk(TypeStr);
4402 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
4403
4404 if (IdentifierInfo *Id = (*P)->getIdentifier())
4405 Pattern->AddTextChunk(Id->getName());
4406 }
4407
4408 if (Method->isVariadic()) {
4409 if (Method->param_size() > 0)
4410 Pattern->AddChunk(CodeCompletionString::CK_Comma);
4411 Pattern->AddTextChunk("...");
4412 }
4413
Douglas Gregor447107d2010-05-28 00:57:46 +00004414 if (IsInImplementation && Results.includeCodePatterns()) {
Douglas Gregore8f5a172010-04-07 00:21:17 +00004415 // We will be defining the method here, so add a compound statement.
4416 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
4417 Pattern->AddChunk(CodeCompletionString::CK_LeftBrace);
4418 Pattern->AddChunk(CodeCompletionString::CK_VerticalSpace);
4419 if (!Method->getResultType()->isVoidType()) {
4420 // If the result type is not void, add a return clause.
4421 Pattern->AddTextChunk("return");
4422 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
4423 Pattern->AddPlaceholderChunk("expression");
4424 Pattern->AddChunk(CodeCompletionString::CK_SemiColon);
4425 } else
4426 Pattern->AddPlaceholderChunk("statements");
4427
4428 Pattern->AddChunk(CodeCompletionString::CK_VerticalSpace);
4429 Pattern->AddChunk(CodeCompletionString::CK_RightBrace);
4430 }
4431
Douglas Gregor16ed9ad2010-08-17 16:06:07 +00004432 Results.AddResult(Result(Pattern, CCP_CodePattern,
4433 Method->isInstanceMethod()
4434 ? CXCursor_ObjCInstanceMethodDecl
4435 : CXCursor_ObjCClassMethodDecl));
Douglas Gregore8f5a172010-04-07 00:21:17 +00004436 }
4437
4438 Results.ExitScope();
4439
Douglas Gregore6b1bb62010-08-11 21:23:17 +00004440 HandleCodeCompleteResults(this, CodeCompleter,
4441 CodeCompletionContext::CCC_Other,
4442 Results.data(),Results.size());
Douglas Gregore8f5a172010-04-07 00:21:17 +00004443}
Douglas Gregor1f5537a2010-07-08 23:20:03 +00004444
4445void Sema::CodeCompleteObjCMethodDeclSelector(Scope *S,
4446 bool IsInstanceMethod,
Douglas Gregor40ed9a12010-07-08 23:37:41 +00004447 bool AtParameterName,
John McCallb3d87482010-08-24 05:47:05 +00004448 ParsedType ReturnTy,
Douglas Gregor1f5537a2010-07-08 23:20:03 +00004449 IdentifierInfo **SelIdents,
4450 unsigned NumSelIdents) {
Douglas Gregor1f5537a2010-07-08 23:20:03 +00004451 // If we have an external source, load the entire class method
Sebastian Redl3c7f4132010-08-18 23:57:06 +00004452 // pool from the AST file.
Douglas Gregor1f5537a2010-07-08 23:20:03 +00004453 if (ExternalSource) {
4454 for (uint32_t I = 0, N = ExternalSource->GetNumExternalSelectors();
4455 I != N; ++I) {
4456 Selector Sel = ExternalSource->GetExternalSelector(I);
Sebastian Redldb9d2142010-08-02 23:18:59 +00004457 if (Sel.isNull() || MethodPool.count(Sel))
Douglas Gregor1f5537a2010-07-08 23:20:03 +00004458 continue;
Sebastian Redldb9d2142010-08-02 23:18:59 +00004459
4460 ReadMethodPool(Sel);
Douglas Gregor1f5537a2010-07-08 23:20:03 +00004461 }
4462 }
4463
4464 // Build the set of methods we can see.
4465 typedef CodeCompleteConsumer::Result Result;
4466 ResultBuilder Results(*this);
4467
4468 if (ReturnTy)
4469 Results.setPreferredType(GetTypeFromParser(ReturnTy).getNonReferenceType());
Sebastian Redldb9d2142010-08-02 23:18:59 +00004470
Douglas Gregor1f5537a2010-07-08 23:20:03 +00004471 Results.EnterNewScope();
Sebastian Redldb9d2142010-08-02 23:18:59 +00004472 for (GlobalMethodPool::iterator M = MethodPool.begin(),
4473 MEnd = MethodPool.end();
4474 M != MEnd; ++M) {
4475 for (ObjCMethodList *MethList = IsInstanceMethod ? &M->second.first :
4476 &M->second.second;
4477 MethList && MethList->Method;
Douglas Gregor1f5537a2010-07-08 23:20:03 +00004478 MethList = MethList->Next) {
4479 if (!isAcceptableObjCMethod(MethList->Method, MK_Any, SelIdents,
4480 NumSelIdents))
4481 continue;
4482
Douglas Gregor40ed9a12010-07-08 23:37:41 +00004483 if (AtParameterName) {
4484 // Suggest parameter names we've seen before.
4485 if (NumSelIdents && NumSelIdents <= MethList->Method->param_size()) {
4486 ParmVarDecl *Param = MethList->Method->param_begin()[NumSelIdents-1];
4487 if (Param->getIdentifier()) {
4488 CodeCompletionString *Pattern = new CodeCompletionString;
4489 Pattern->AddTypedTextChunk(Param->getIdentifier()->getName());
4490 Results.AddResult(Pattern);
4491 }
4492 }
4493
4494 continue;
4495 }
4496
Douglas Gregor1f5537a2010-07-08 23:20:03 +00004497 Result R(MethList->Method, 0);
4498 R.StartParameter = NumSelIdents;
4499 R.AllParametersAreInformative = false;
4500 R.DeclaringEntity = true;
4501 Results.MaybeAddResult(R, CurContext);
4502 }
4503 }
4504
4505 Results.ExitScope();
Douglas Gregore6b1bb62010-08-11 21:23:17 +00004506 HandleCodeCompleteResults(this, CodeCompleter,
4507 CodeCompletionContext::CCC_Other,
4508 Results.data(),Results.size());
Douglas Gregor1f5537a2010-07-08 23:20:03 +00004509}
Douglas Gregor87c08a52010-08-13 22:48:40 +00004510
4511void Sema::GatherGlobalCodeCompletions(
4512 llvm::SmallVectorImpl<CodeCompleteConsumer::Result> &Results) {
4513 ResultBuilder Builder(*this);
4514
Douglas Gregor8071e422010-08-15 06:18:01 +00004515 if (!CodeCompleter || CodeCompleter->includeGlobals()) {
4516 CodeCompletionDeclConsumer Consumer(Builder,
4517 Context.getTranslationUnitDecl());
4518 LookupVisibleDecls(Context.getTranslationUnitDecl(), LookupAnyName,
4519 Consumer);
4520 }
Douglas Gregor87c08a52010-08-13 22:48:40 +00004521
4522 if (!CodeCompleter || CodeCompleter->includeMacros())
4523 AddMacroResults(PP, Builder);
4524
4525 Results.clear();
4526 Results.insert(Results.end(),
4527 Builder.data(), Builder.data() + Builder.size());
4528}