blob: 9d5bc0be0f20dc3a5f2bcce3a4086958fa1d2c26 [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"
John McCall7cd088e2010-08-24 07:21:54 +000017#include "clang/AST/DeclObjC.h"
Douglas Gregorb9d0ef72009-09-21 19:57:38 +000018#include "clang/AST/ExprCXX.h"
Douglas Gregor24a069f2009-11-17 17:59:40 +000019#include "clang/AST/ExprObjC.h"
Douglas Gregor3f7c7f42009-10-30 16:50:04 +000020#include "clang/Lex/MacroInfo.h"
21#include "clang/Lex/Preprocessor.h"
Douglas Gregor86d9a522009-09-21 16:56:56 +000022#include "llvm/ADT/SmallPtrSet.h"
Douglas Gregor6a684032009-09-28 03:51:44 +000023#include "llvm/ADT/StringExtras.h"
Douglas Gregor22f56992010-04-06 19:22:33 +000024#include "llvm/ADT/StringSwitch.h"
Douglas Gregor86d9a522009-09-21 16:56:56 +000025#include <list>
26#include <map>
27#include <vector>
Douglas Gregor81b747b2009-09-17 21:32:03 +000028
29using namespace clang;
30
Douglas Gregor86d9a522009-09-21 16:56:56 +000031namespace {
32 /// \brief A container of code-completion results.
33 class ResultBuilder {
34 public:
35 /// \brief The type of a name-lookup filter, which can be provided to the
36 /// name-lookup routines to specify which declarations should be included in
37 /// the result set (when it returns true) and which declarations should be
38 /// filtered out (returns false).
39 typedef bool (ResultBuilder::*LookupFilter)(NamedDecl *) const;
40
41 typedef CodeCompleteConsumer::Result Result;
42
43 private:
44 /// \brief The actual results we have found.
45 std::vector<Result> Results;
46
47 /// \brief A record of all of the declarations we have found and placed
48 /// into the result set, used to ensure that no declaration ever gets into
49 /// the result set twice.
50 llvm::SmallPtrSet<Decl*, 16> AllDeclsFound;
51
Douglas Gregorfbcb5d62009-12-06 20:23:50 +000052 typedef std::pair<NamedDecl *, unsigned> DeclIndexPair;
53
54 /// \brief An entry in the shadow map, which is optimized to store
55 /// a single (declaration, index) mapping (the common case) but
56 /// can also store a list of (declaration, index) mappings.
57 class ShadowMapEntry {
58 typedef llvm::SmallVector<DeclIndexPair, 4> DeclIndexPairVector;
59
60 /// \brief Contains either the solitary NamedDecl * or a vector
61 /// of (declaration, index) pairs.
62 llvm::PointerUnion<NamedDecl *, DeclIndexPairVector*> DeclOrVector;
63
64 /// \brief When the entry contains a single declaration, this is
65 /// the index associated with that entry.
66 unsigned SingleDeclIndex;
67
68 public:
69 ShadowMapEntry() : DeclOrVector(), SingleDeclIndex(0) { }
70
71 void Add(NamedDecl *ND, unsigned Index) {
72 if (DeclOrVector.isNull()) {
73 // 0 - > 1 elements: just set the single element information.
74 DeclOrVector = ND;
75 SingleDeclIndex = Index;
76 return;
77 }
78
79 if (NamedDecl *PrevND = DeclOrVector.dyn_cast<NamedDecl *>()) {
80 // 1 -> 2 elements: create the vector of results and push in the
81 // existing declaration.
82 DeclIndexPairVector *Vec = new DeclIndexPairVector;
83 Vec->push_back(DeclIndexPair(PrevND, SingleDeclIndex));
84 DeclOrVector = Vec;
85 }
86
87 // Add the new element to the end of the vector.
88 DeclOrVector.get<DeclIndexPairVector*>()->push_back(
89 DeclIndexPair(ND, Index));
90 }
91
92 void Destroy() {
93 if (DeclIndexPairVector *Vec
94 = DeclOrVector.dyn_cast<DeclIndexPairVector *>()) {
95 delete Vec;
96 DeclOrVector = ((NamedDecl *)0);
97 }
98 }
99
100 // Iteration.
101 class iterator;
102 iterator begin() const;
103 iterator end() const;
104 };
105
Douglas Gregor86d9a522009-09-21 16:56:56 +0000106 /// \brief A mapping from declaration names to the declarations that have
107 /// this name within a particular scope and their index within the list of
108 /// results.
Douglas Gregorfbcb5d62009-12-06 20:23:50 +0000109 typedef llvm::DenseMap<DeclarationName, ShadowMapEntry> ShadowMap;
Douglas Gregor86d9a522009-09-21 16:56:56 +0000110
111 /// \brief The semantic analysis object for which results are being
112 /// produced.
113 Sema &SemaRef;
114
115 /// \brief If non-NULL, a filter function used to remove any code-completion
116 /// results that are not desirable.
117 LookupFilter Filter;
Douglas Gregor45bcd432010-01-14 03:21:49 +0000118
119 /// \brief Whether we should allow declarations as
120 /// nested-name-specifiers that would otherwise be filtered out.
121 bool AllowNestedNameSpecifiers;
122
Douglas Gregor5ac3bdb2010-05-30 01:49:25 +0000123 /// \brief If set, the type that we would prefer our resulting value
124 /// declarations to have.
125 ///
126 /// Closely matching the preferred type gives a boost to a result's
127 /// priority.
128 CanQualType PreferredType;
129
Douglas Gregor86d9a522009-09-21 16:56:56 +0000130 /// \brief A list of shadow maps, which is used to model name hiding at
131 /// different levels of, e.g., the inheritance hierarchy.
132 std::list<ShadowMap> ShadowMaps;
133
Douglas Gregor1f5537a2010-07-08 23:20:03 +0000134 void AdjustResultPriorityForPreferredType(Result &R);
135
Douglas Gregor86d9a522009-09-21 16:56:56 +0000136 public:
137 explicit ResultBuilder(Sema &SemaRef, LookupFilter Filter = 0)
Douglas Gregor45bcd432010-01-14 03:21:49 +0000138 : SemaRef(SemaRef), Filter(Filter), AllowNestedNameSpecifiers(false) { }
Douglas Gregor86d9a522009-09-21 16:56:56 +0000139
Douglas Gregord8e8a582010-05-25 21:41:55 +0000140 /// \brief Whether we should include code patterns in the completion
141 /// results.
142 bool includeCodePatterns() const {
143 return SemaRef.CodeCompleter &&
144 SemaRef.CodeCompleter->includeCodePatterns();
145 }
146
Douglas Gregor86d9a522009-09-21 16:56:56 +0000147 /// \brief Set the filter used for code-completion results.
148 void setFilter(LookupFilter Filter) {
149 this->Filter = Filter;
150 }
151
152 typedef std::vector<Result>::iterator iterator;
153 iterator begin() { return Results.begin(); }
154 iterator end() { return Results.end(); }
155
156 Result *data() { return Results.empty()? 0 : &Results.front(); }
157 unsigned size() const { return Results.size(); }
158 bool empty() const { return Results.empty(); }
159
Douglas Gregor5ac3bdb2010-05-30 01:49:25 +0000160 /// \brief Specify the preferred type.
161 void setPreferredType(QualType T) {
162 PreferredType = SemaRef.Context.getCanonicalType(T);
163 }
164
Douglas Gregor45bcd432010-01-14 03:21:49 +0000165 /// \brief Specify whether nested-name-specifiers are allowed.
166 void allowNestedNameSpecifiers(bool Allow = true) {
167 AllowNestedNameSpecifiers = Allow;
168 }
169
Douglas Gregore495b7f2010-01-14 00:20:49 +0000170 /// \brief Determine whether the given declaration is at all interesting
171 /// as a code-completion result.
Douglas Gregor45bcd432010-01-14 03:21:49 +0000172 ///
173 /// \param ND the declaration that we are inspecting.
174 ///
175 /// \param AsNestedNameSpecifier will be set true if this declaration is
176 /// only interesting when it is a nested-name-specifier.
177 bool isInterestingDecl(NamedDecl *ND, bool &AsNestedNameSpecifier) const;
Douglas Gregor6660d842010-01-14 00:41:07 +0000178
179 /// \brief Check whether the result is hidden by the Hiding declaration.
180 ///
181 /// \returns true if the result is hidden and cannot be found, false if
182 /// the hidden result could still be found. When false, \p R may be
183 /// modified to describe how the result can be found (e.g., via extra
184 /// qualification).
185 bool CheckHiddenResult(Result &R, DeclContext *CurContext,
186 NamedDecl *Hiding);
187
Douglas Gregor86d9a522009-09-21 16:56:56 +0000188 /// \brief Add a new result to this result set (if it isn't already in one
189 /// of the shadow maps), or replace an existing result (for, e.g., a
190 /// redeclaration).
Douglas Gregor456c4a12009-09-21 20:12:40 +0000191 ///
Douglas Gregor1ca6ae82010-01-14 01:09:38 +0000192 /// \param CurContext the result to add (if it is unique).
Douglas Gregor456c4a12009-09-21 20:12:40 +0000193 ///
194 /// \param R the context in which this result will be named.
195 void MaybeAddResult(Result R, DeclContext *CurContext = 0);
Douglas Gregor86d9a522009-09-21 16:56:56 +0000196
Douglas Gregor1ca6ae82010-01-14 01:09:38 +0000197 /// \brief Add a new result to this result set, where we already know
198 /// the hiding declation (if any).
199 ///
200 /// \param R the result to add (if it is unique).
201 ///
202 /// \param CurContext the context in which this result will be named.
203 ///
204 /// \param Hiding the declaration that hides the result.
Douglas Gregor0cc84042010-01-14 15:47:35 +0000205 ///
206 /// \param InBaseClass whether the result was found in a base
207 /// class of the searched context.
208 void AddResult(Result R, DeclContext *CurContext, NamedDecl *Hiding,
209 bool InBaseClass);
Douglas Gregor1ca6ae82010-01-14 01:09:38 +0000210
Douglas Gregora4477812010-01-14 16:01:26 +0000211 /// \brief Add a new non-declaration result to this result set.
212 void AddResult(Result R);
213
Douglas Gregor86d9a522009-09-21 16:56:56 +0000214 /// \brief Enter into a new scope.
215 void EnterNewScope();
216
217 /// \brief Exit from the current scope.
218 void ExitScope();
219
Douglas Gregor55385fe2009-11-18 04:19:12 +0000220 /// \brief Ignore this declaration, if it is seen again.
221 void Ignore(Decl *D) { AllDeclsFound.insert(D->getCanonicalDecl()); }
222
Douglas Gregor86d9a522009-09-21 16:56:56 +0000223 /// \name Name lookup predicates
224 ///
225 /// These predicates can be passed to the name lookup functions to filter the
226 /// results of name lookup. All of the predicates have the same type, so that
227 ///
228 //@{
Douglas Gregor791215b2009-09-21 20:51:25 +0000229 bool IsOrdinaryName(NamedDecl *ND) const;
Douglas Gregor4710e5b2010-05-28 00:49:12 +0000230 bool IsOrdinaryNonTypeName(NamedDecl *ND) const;
Douglas Gregorf9578432010-07-28 21:50:18 +0000231 bool IsIntegralConstantValue(NamedDecl *ND) const;
Douglas Gregor01dfea02010-01-10 23:08:15 +0000232 bool IsOrdinaryNonValueName(NamedDecl *ND) const;
Douglas Gregor86d9a522009-09-21 16:56:56 +0000233 bool IsNestedNameSpecifier(NamedDecl *ND) const;
234 bool IsEnum(NamedDecl *ND) const;
235 bool IsClassOrStruct(NamedDecl *ND) const;
236 bool IsUnion(NamedDecl *ND) const;
237 bool IsNamespace(NamedDecl *ND) const;
238 bool IsNamespaceOrAlias(NamedDecl *ND) const;
239 bool IsType(NamedDecl *ND) const;
Douglas Gregoreb5758b2009-09-23 22:26:46 +0000240 bool IsMember(NamedDecl *ND) const;
Douglas Gregor80f4f4c2010-01-14 16:08:12 +0000241 bool IsObjCIvar(NamedDecl *ND) const;
Douglas Gregor8e254cf2010-05-27 23:06:34 +0000242 bool IsObjCMessageReceiver(NamedDecl *ND) const;
Douglas Gregorfb629412010-08-23 21:17:50 +0000243 bool IsObjCCollection(NamedDecl *ND) const;
Douglas Gregor86d9a522009-09-21 16:56:56 +0000244 //@}
245 };
246}
247
Douglas Gregorfbcb5d62009-12-06 20:23:50 +0000248class ResultBuilder::ShadowMapEntry::iterator {
249 llvm::PointerUnion<NamedDecl*, const DeclIndexPair*> DeclOrIterator;
250 unsigned SingleDeclIndex;
251
252public:
253 typedef DeclIndexPair value_type;
254 typedef value_type reference;
255 typedef std::ptrdiff_t difference_type;
256 typedef std::input_iterator_tag iterator_category;
257
258 class pointer {
259 DeclIndexPair Value;
260
261 public:
262 pointer(const DeclIndexPair &Value) : Value(Value) { }
263
264 const DeclIndexPair *operator->() const {
265 return &Value;
266 }
267 };
268
269 iterator() : DeclOrIterator((NamedDecl *)0), SingleDeclIndex(0) { }
270
271 iterator(NamedDecl *SingleDecl, unsigned Index)
272 : DeclOrIterator(SingleDecl), SingleDeclIndex(Index) { }
273
274 iterator(const DeclIndexPair *Iterator)
275 : DeclOrIterator(Iterator), SingleDeclIndex(0) { }
276
277 iterator &operator++() {
278 if (DeclOrIterator.is<NamedDecl *>()) {
279 DeclOrIterator = (NamedDecl *)0;
280 SingleDeclIndex = 0;
281 return *this;
282 }
283
284 const DeclIndexPair *I = DeclOrIterator.get<const DeclIndexPair*>();
285 ++I;
286 DeclOrIterator = I;
287 return *this;
288 }
289
290 iterator operator++(int) {
291 iterator tmp(*this);
292 ++(*this);
293 return tmp;
294 }
295
296 reference operator*() const {
297 if (NamedDecl *ND = DeclOrIterator.dyn_cast<NamedDecl *>())
298 return reference(ND, SingleDeclIndex);
299
Douglas Gregord490f952009-12-06 21:27:58 +0000300 return *DeclOrIterator.get<const DeclIndexPair*>();
Douglas Gregorfbcb5d62009-12-06 20:23:50 +0000301 }
302
303 pointer operator->() const {
304 return pointer(**this);
305 }
306
307 friend bool operator==(const iterator &X, const iterator &Y) {
Douglas Gregord490f952009-12-06 21:27:58 +0000308 return X.DeclOrIterator.getOpaqueValue()
309 == Y.DeclOrIterator.getOpaqueValue() &&
Douglas Gregorfbcb5d62009-12-06 20:23:50 +0000310 X.SingleDeclIndex == Y.SingleDeclIndex;
311 }
312
313 friend bool operator!=(const iterator &X, const iterator &Y) {
Douglas Gregord490f952009-12-06 21:27:58 +0000314 return !(X == Y);
Douglas Gregorfbcb5d62009-12-06 20:23:50 +0000315 }
316};
317
Douglas Gregorfbcb5d62009-12-06 20:23:50 +0000318ResultBuilder::ShadowMapEntry::iterator
319ResultBuilder::ShadowMapEntry::begin() const {
320 if (DeclOrVector.isNull())
321 return iterator();
322
323 if (NamedDecl *ND = DeclOrVector.dyn_cast<NamedDecl *>())
324 return iterator(ND, SingleDeclIndex);
325
326 return iterator(DeclOrVector.get<DeclIndexPairVector *>()->begin());
327}
328
329ResultBuilder::ShadowMapEntry::iterator
330ResultBuilder::ShadowMapEntry::end() const {
331 if (DeclOrVector.is<NamedDecl *>() || DeclOrVector.isNull())
332 return iterator();
333
334 return iterator(DeclOrVector.get<DeclIndexPairVector *>()->end());
335}
336
Douglas Gregor456c4a12009-09-21 20:12:40 +0000337/// \brief Compute the qualification required to get from the current context
338/// (\p CurContext) to the target context (\p TargetContext).
339///
340/// \param Context the AST context in which the qualification will be used.
341///
342/// \param CurContext the context where an entity is being named, which is
343/// typically based on the current scope.
344///
345/// \param TargetContext the context in which the named entity actually
346/// resides.
347///
348/// \returns a nested name specifier that refers into the target context, or
349/// NULL if no qualification is needed.
350static NestedNameSpecifier *
351getRequiredQualification(ASTContext &Context,
352 DeclContext *CurContext,
353 DeclContext *TargetContext) {
354 llvm::SmallVector<DeclContext *, 4> TargetParents;
355
356 for (DeclContext *CommonAncestor = TargetContext;
357 CommonAncestor && !CommonAncestor->Encloses(CurContext);
358 CommonAncestor = CommonAncestor->getLookupParent()) {
359 if (CommonAncestor->isTransparentContext() ||
360 CommonAncestor->isFunctionOrMethod())
361 continue;
362
363 TargetParents.push_back(CommonAncestor);
364 }
365
366 NestedNameSpecifier *Result = 0;
367 while (!TargetParents.empty()) {
368 DeclContext *Parent = TargetParents.back();
369 TargetParents.pop_back();
370
Douglas Gregorfb629412010-08-23 21:17:50 +0000371 if (NamespaceDecl *Namespace = dyn_cast<NamespaceDecl>(Parent)) {
372 if (!Namespace->getIdentifier())
373 continue;
374
Douglas Gregor456c4a12009-09-21 20:12:40 +0000375 Result = NestedNameSpecifier::Create(Context, Result, Namespace);
Douglas Gregorfb629412010-08-23 21:17:50 +0000376 }
Douglas Gregor456c4a12009-09-21 20:12:40 +0000377 else if (TagDecl *TD = dyn_cast<TagDecl>(Parent))
378 Result = NestedNameSpecifier::Create(Context, Result,
379 false,
380 Context.getTypeDeclType(TD).getTypePtr());
Douglas Gregor0c8296d2009-11-07 00:00:49 +0000381 }
Douglas Gregor456c4a12009-09-21 20:12:40 +0000382 return Result;
383}
384
Douglas Gregor45bcd432010-01-14 03:21:49 +0000385bool ResultBuilder::isInterestingDecl(NamedDecl *ND,
386 bool &AsNestedNameSpecifier) const {
387 AsNestedNameSpecifier = false;
388
Douglas Gregore495b7f2010-01-14 00:20:49 +0000389 ND = ND->getUnderlyingDecl();
390 unsigned IDNS = ND->getIdentifierNamespace();
Douglas Gregorf52cede2009-10-09 22:16:47 +0000391
392 // Skip unnamed entities.
Douglas Gregore495b7f2010-01-14 00:20:49 +0000393 if (!ND->getDeclName())
394 return false;
Douglas Gregor86d9a522009-09-21 16:56:56 +0000395
396 // Friend declarations and declarations introduced due to friends are never
397 // added as results.
John McCall92b7f702010-03-11 07:50:04 +0000398 if (IDNS & (Decl::IDNS_OrdinaryFriend | Decl::IDNS_TagFriend))
Douglas Gregore495b7f2010-01-14 00:20:49 +0000399 return false;
400
Douglas Gregor76282942009-12-11 17:31:05 +0000401 // Class template (partial) specializations are never added as results.
Douglas Gregore495b7f2010-01-14 00:20:49 +0000402 if (isa<ClassTemplateSpecializationDecl>(ND) ||
403 isa<ClassTemplatePartialSpecializationDecl>(ND))
404 return false;
Douglas Gregor86d9a522009-09-21 16:56:56 +0000405
Douglas Gregor76282942009-12-11 17:31:05 +0000406 // Using declarations themselves are never added as results.
Douglas Gregore495b7f2010-01-14 00:20:49 +0000407 if (isa<UsingDecl>(ND))
408 return false;
409
410 // Some declarations have reserved names that we don't want to ever show.
411 if (const IdentifierInfo *Id = ND->getIdentifier()) {
Douglas Gregor86d9a522009-09-21 16:56:56 +0000412 // __va_list_tag is a freak of nature. Find it and skip it.
413 if (Id->isStr("__va_list_tag") || Id->isStr("__builtin_va_list"))
Douglas Gregore495b7f2010-01-14 00:20:49 +0000414 return false;
Douglas Gregor86d9a522009-09-21 16:56:56 +0000415
Douglas Gregorf52cede2009-10-09 22:16:47 +0000416 // Filter out names reserved for the implementation (C99 7.1.3,
Douglas Gregor797efb52010-07-14 17:44:04 +0000417 // C++ [lib.global.names]) if they come from a system header.
Daniel Dunbare013d682009-10-18 20:26:12 +0000418 //
419 // FIXME: Add predicate for this.
Douglas Gregorf52cede2009-10-09 22:16:47 +0000420 if (Id->getLength() >= 2) {
Daniel Dunbare013d682009-10-18 20:26:12 +0000421 const char *Name = Id->getNameStart();
Douglas Gregorf52cede2009-10-09 22:16:47 +0000422 if (Name[0] == '_' &&
Douglas Gregor797efb52010-07-14 17:44:04 +0000423 (Name[1] == '_' || (Name[1] >= 'A' && Name[1] <= 'Z')) &&
424 (ND->getLocation().isInvalid() ||
425 SemaRef.SourceMgr.isInSystemHeader(
426 SemaRef.SourceMgr.getSpellingLoc(ND->getLocation()))))
Douglas Gregore495b7f2010-01-14 00:20:49 +0000427 return false;
Douglas Gregorf52cede2009-10-09 22:16:47 +0000428 }
Douglas Gregor86d9a522009-09-21 16:56:56 +0000429 }
Douglas Gregore495b7f2010-01-14 00:20:49 +0000430
Douglas Gregor86d9a522009-09-21 16:56:56 +0000431 // C++ constructors are never found by name lookup.
Douglas Gregore495b7f2010-01-14 00:20:49 +0000432 if (isa<CXXConstructorDecl>(ND))
433 return false;
Douglas Gregor86d9a522009-09-21 16:56:56 +0000434
Douglas Gregora5fb7c32010-08-16 23:05:20 +0000435 if (Filter == &ResultBuilder::IsNestedNameSpecifier ||
436 ((isa<NamespaceDecl>(ND) || isa<NamespaceAliasDecl>(ND)) &&
437 Filter != &ResultBuilder::IsNamespace &&
438 Filter != &ResultBuilder::IsNamespaceOrAlias))
439 AsNestedNameSpecifier = true;
440
Douglas Gregor86d9a522009-09-21 16:56:56 +0000441 // Filter out any unwanted results.
Douglas Gregor45bcd432010-01-14 03:21:49 +0000442 if (Filter && !(this->*Filter)(ND)) {
443 // Check whether it is interesting as a nested-name-specifier.
444 if (AllowNestedNameSpecifiers && SemaRef.getLangOptions().CPlusPlus &&
445 IsNestedNameSpecifier(ND) &&
446 (Filter != &ResultBuilder::IsMember ||
447 (isa<CXXRecordDecl>(ND) &&
448 cast<CXXRecordDecl>(ND)->isInjectedClassName()))) {
449 AsNestedNameSpecifier = true;
450 return true;
451 }
452
Douglas Gregore495b7f2010-01-14 00:20:49 +0000453 return false;
Douglas Gregora5fb7c32010-08-16 23:05:20 +0000454 }
Douglas Gregore495b7f2010-01-14 00:20:49 +0000455 // ... then it must be interesting!
456 return true;
457}
458
Douglas Gregor6660d842010-01-14 00:41:07 +0000459bool ResultBuilder::CheckHiddenResult(Result &R, DeclContext *CurContext,
460 NamedDecl *Hiding) {
461 // In C, there is no way to refer to a hidden name.
462 // FIXME: This isn't true; we can find a tag name hidden by an ordinary
463 // name if we introduce the tag type.
464 if (!SemaRef.getLangOptions().CPlusPlus)
465 return true;
466
467 DeclContext *HiddenCtx = R.Declaration->getDeclContext()->getLookupContext();
468
469 // There is no way to qualify a name declared in a function or method.
470 if (HiddenCtx->isFunctionOrMethod())
471 return true;
472
473 if (HiddenCtx == Hiding->getDeclContext()->getLookupContext())
474 return true;
475
476 // We can refer to the result with the appropriate qualification. Do it.
477 R.Hidden = true;
478 R.QualifierIsInformative = false;
479
480 if (!R.Qualifier)
481 R.Qualifier = getRequiredQualification(SemaRef.Context,
482 CurContext,
483 R.Declaration->getDeclContext());
484 return false;
485}
486
Douglas Gregor1f5537a2010-07-08 23:20:03 +0000487/// \brief A simplified classification of types used to determine whether two
488/// types are "similar enough" when adjusting priorities.
Douglas Gregor1827e102010-08-16 16:18:59 +0000489SimplifiedTypeClass clang::getSimplifiedTypeClass(CanQualType T) {
Douglas Gregor1f5537a2010-07-08 23:20:03 +0000490 switch (T->getTypeClass()) {
491 case Type::Builtin:
492 switch (cast<BuiltinType>(T)->getKind()) {
493 case BuiltinType::Void:
494 return STC_Void;
495
496 case BuiltinType::NullPtr:
497 return STC_Pointer;
498
499 case BuiltinType::Overload:
500 case BuiltinType::Dependent:
501 case BuiltinType::UndeducedAuto:
502 return STC_Other;
503
504 case BuiltinType::ObjCId:
505 case BuiltinType::ObjCClass:
506 case BuiltinType::ObjCSel:
507 return STC_ObjectiveC;
508
509 default:
510 return STC_Arithmetic;
511 }
512 return STC_Other;
513
514 case Type::Complex:
515 return STC_Arithmetic;
516
517 case Type::Pointer:
518 return STC_Pointer;
519
520 case Type::BlockPointer:
521 return STC_Block;
522
523 case Type::LValueReference:
524 case Type::RValueReference:
525 return getSimplifiedTypeClass(T->getAs<ReferenceType>()->getPointeeType());
526
527 case Type::ConstantArray:
528 case Type::IncompleteArray:
529 case Type::VariableArray:
530 case Type::DependentSizedArray:
531 return STC_Array;
532
533 case Type::DependentSizedExtVector:
534 case Type::Vector:
535 case Type::ExtVector:
536 return STC_Arithmetic;
537
538 case Type::FunctionProto:
539 case Type::FunctionNoProto:
540 return STC_Function;
541
542 case Type::Record:
543 return STC_Record;
544
545 case Type::Enum:
546 return STC_Arithmetic;
547
548 case Type::ObjCObject:
549 case Type::ObjCInterface:
550 case Type::ObjCObjectPointer:
551 return STC_ObjectiveC;
552
553 default:
554 return STC_Other;
555 }
556}
557
558/// \brief Get the type that a given expression will have if this declaration
559/// is used as an expression in its "typical" code-completion form.
Douglas Gregor1827e102010-08-16 16:18:59 +0000560QualType clang::getDeclUsageType(ASTContext &C, NamedDecl *ND) {
Douglas Gregor1f5537a2010-07-08 23:20:03 +0000561 ND = cast<NamedDecl>(ND->getUnderlyingDecl());
562
563 if (TypeDecl *Type = dyn_cast<TypeDecl>(ND))
564 return C.getTypeDeclType(Type);
565 if (ObjCInterfaceDecl *Iface = dyn_cast<ObjCInterfaceDecl>(ND))
566 return C.getObjCInterfaceType(Iface);
567
568 QualType T;
569 if (FunctionDecl *Function = dyn_cast<FunctionDecl>(ND))
Douglas Gregor5291c3c2010-07-13 08:18:22 +0000570 T = Function->getCallResultType();
Douglas Gregor1f5537a2010-07-08 23:20:03 +0000571 else if (ObjCMethodDecl *Method = dyn_cast<ObjCMethodDecl>(ND))
Douglas Gregor5291c3c2010-07-13 08:18:22 +0000572 T = Method->getSendResultType();
Douglas Gregor1f5537a2010-07-08 23:20:03 +0000573 else if (FunctionTemplateDecl *FunTmpl = dyn_cast<FunctionTemplateDecl>(ND))
Douglas Gregor5291c3c2010-07-13 08:18:22 +0000574 T = FunTmpl->getTemplatedDecl()->getCallResultType();
Douglas Gregor1f5537a2010-07-08 23:20:03 +0000575 else if (EnumConstantDecl *Enumerator = dyn_cast<EnumConstantDecl>(ND))
576 T = C.getTypeDeclType(cast<EnumDecl>(Enumerator->getDeclContext()));
577 else if (ObjCPropertyDecl *Property = dyn_cast<ObjCPropertyDecl>(ND))
578 T = Property->getType();
579 else if (ValueDecl *Value = dyn_cast<ValueDecl>(ND))
580 T = Value->getType();
581 else
582 return QualType();
583
584 return T.getNonReferenceType();
585}
586
587void ResultBuilder::AdjustResultPriorityForPreferredType(Result &R) {
588 QualType T = getDeclUsageType(SemaRef.Context, R.Declaration);
589 if (T.isNull())
590 return;
591
592 CanQualType TC = SemaRef.Context.getCanonicalType(T);
593 // Check for exactly-matching types (modulo qualifiers).
594 if (SemaRef.Context.hasSameUnqualifiedType(PreferredType, TC))
595 R.Priority /= CCF_ExactTypeMatch;
596 // Check for nearly-matching types, based on classification of each.
597 else if ((getSimplifiedTypeClass(PreferredType)
598 == getSimplifiedTypeClass(TC)) &&
599 !(PreferredType->isEnumeralType() && TC->isEnumeralType()))
600 R.Priority /= CCF_SimilarTypeMatch;
601}
602
Douglas Gregore495b7f2010-01-14 00:20:49 +0000603void ResultBuilder::MaybeAddResult(Result R, DeclContext *CurContext) {
604 assert(!ShadowMaps.empty() && "Must enter into a results scope");
605
606 if (R.Kind != Result::RK_Declaration) {
607 // For non-declaration results, just add the result.
608 Results.push_back(R);
609 return;
610 }
611
612 // Look through using declarations.
613 if (UsingShadowDecl *Using = dyn_cast<UsingShadowDecl>(R.Declaration)) {
614 MaybeAddResult(Result(Using->getTargetDecl(), R.Qualifier), CurContext);
615 return;
616 }
617
618 Decl *CanonDecl = R.Declaration->getCanonicalDecl();
619 unsigned IDNS = CanonDecl->getIdentifierNamespace();
620
Douglas Gregor45bcd432010-01-14 03:21:49 +0000621 bool AsNestedNameSpecifier = false;
622 if (!isInterestingDecl(R.Declaration, AsNestedNameSpecifier))
Douglas Gregore495b7f2010-01-14 00:20:49 +0000623 return;
624
Douglas Gregor86d9a522009-09-21 16:56:56 +0000625 ShadowMap &SMap = ShadowMaps.back();
Douglas Gregorfbcb5d62009-12-06 20:23:50 +0000626 ShadowMapEntry::iterator I, IEnd;
627 ShadowMap::iterator NamePos = SMap.find(R.Declaration->getDeclName());
628 if (NamePos != SMap.end()) {
629 I = NamePos->second.begin();
630 IEnd = NamePos->second.end();
631 }
632
633 for (; I != IEnd; ++I) {
634 NamedDecl *ND = I->first;
635 unsigned Index = I->second;
Douglas Gregor86d9a522009-09-21 16:56:56 +0000636 if (ND->getCanonicalDecl() == CanonDecl) {
637 // This is a redeclaration. Always pick the newer declaration.
Douglas Gregor86d9a522009-09-21 16:56:56 +0000638 Results[Index].Declaration = R.Declaration;
639
Douglas Gregor86d9a522009-09-21 16:56:56 +0000640 // We're done.
641 return;
642 }
643 }
644
645 // This is a new declaration in this scope. However, check whether this
646 // declaration name is hidden by a similarly-named declaration in an outer
647 // scope.
648 std::list<ShadowMap>::iterator SM, SMEnd = ShadowMaps.end();
649 --SMEnd;
650 for (SM = ShadowMaps.begin(); SM != SMEnd; ++SM) {
Douglas Gregorfbcb5d62009-12-06 20:23:50 +0000651 ShadowMapEntry::iterator I, IEnd;
652 ShadowMap::iterator NamePos = SM->find(R.Declaration->getDeclName());
653 if (NamePos != SM->end()) {
654 I = NamePos->second.begin();
655 IEnd = NamePos->second.end();
656 }
657 for (; I != IEnd; ++I) {
Douglas Gregor86d9a522009-09-21 16:56:56 +0000658 // A tag declaration does not hide a non-tag declaration.
John McCall0d6b1642010-04-23 18:46:30 +0000659 if (I->first->hasTagIdentifierNamespace() &&
Douglas Gregor86d9a522009-09-21 16:56:56 +0000660 (IDNS & (Decl::IDNS_Member | Decl::IDNS_Ordinary |
661 Decl::IDNS_ObjCProtocol)))
662 continue;
663
664 // Protocols are in distinct namespaces from everything else.
Douglas Gregorfbcb5d62009-12-06 20:23:50 +0000665 if (((I->first->getIdentifierNamespace() & Decl::IDNS_ObjCProtocol)
Douglas Gregor86d9a522009-09-21 16:56:56 +0000666 || (IDNS & Decl::IDNS_ObjCProtocol)) &&
Douglas Gregorfbcb5d62009-12-06 20:23:50 +0000667 I->first->getIdentifierNamespace() != IDNS)
Douglas Gregor86d9a522009-09-21 16:56:56 +0000668 continue;
669
670 // The newly-added result is hidden by an entry in the shadow map.
Douglas Gregor6660d842010-01-14 00:41:07 +0000671 if (CheckHiddenResult(R, CurContext, I->first))
Douglas Gregor86d9a522009-09-21 16:56:56 +0000672 return;
Douglas Gregor86d9a522009-09-21 16:56:56 +0000673
674 break;
675 }
676 }
677
678 // Make sure that any given declaration only shows up in the result set once.
679 if (!AllDeclsFound.insert(CanonDecl))
680 return;
681
Douglas Gregoreb5758b2009-09-23 22:26:46 +0000682 // If the filter is for nested-name-specifiers, then this result starts a
683 // nested-name-specifier.
Douglas Gregor12e13132010-05-26 22:00:08 +0000684 if (AsNestedNameSpecifier) {
Douglas Gregoreb5758b2009-09-23 22:26:46 +0000685 R.StartsNestedNameSpecifier = true;
Douglas Gregor12e13132010-05-26 22:00:08 +0000686 R.Priority = CCP_NestedNameSpecifier;
Douglas Gregor1f5537a2010-07-08 23:20:03 +0000687 } else if (!PreferredType.isNull())
688 AdjustResultPriorityForPreferredType(R);
689
Douglas Gregor0563c262009-09-22 23:15:58 +0000690 // If this result is supposed to have an informative qualifier, add one.
Douglas Gregoreb5758b2009-09-23 22:26:46 +0000691 if (R.QualifierIsInformative && !R.Qualifier &&
692 !R.StartsNestedNameSpecifier) {
Douglas Gregor0563c262009-09-22 23:15:58 +0000693 DeclContext *Ctx = R.Declaration->getDeclContext();
694 if (NamespaceDecl *Namespace = dyn_cast<NamespaceDecl>(Ctx))
695 R.Qualifier = NestedNameSpecifier::Create(SemaRef.Context, 0, Namespace);
696 else if (TagDecl *Tag = dyn_cast<TagDecl>(Ctx))
697 R.Qualifier = NestedNameSpecifier::Create(SemaRef.Context, 0, false,
698 SemaRef.Context.getTypeDeclType(Tag).getTypePtr());
699 else
700 R.QualifierIsInformative = false;
701 }
Douglas Gregoreb5758b2009-09-23 22:26:46 +0000702
Douglas Gregor86d9a522009-09-21 16:56:56 +0000703 // Insert this result into the set of results and into the current shadow
704 // map.
Douglas Gregorfbcb5d62009-12-06 20:23:50 +0000705 SMap[R.Declaration->getDeclName()].Add(R.Declaration, Results.size());
Douglas Gregor86d9a522009-09-21 16:56:56 +0000706 Results.push_back(R);
707}
708
Douglas Gregor1ca6ae82010-01-14 01:09:38 +0000709void ResultBuilder::AddResult(Result R, DeclContext *CurContext,
Douglas Gregor0cc84042010-01-14 15:47:35 +0000710 NamedDecl *Hiding, bool InBaseClass = false) {
Douglas Gregora4477812010-01-14 16:01:26 +0000711 if (R.Kind != Result::RK_Declaration) {
712 // For non-declaration results, just add the result.
713 Results.push_back(R);
714 return;
715 }
716
Douglas Gregor1ca6ae82010-01-14 01:09:38 +0000717 // Look through using declarations.
718 if (UsingShadowDecl *Using = dyn_cast<UsingShadowDecl>(R.Declaration)) {
719 AddResult(Result(Using->getTargetDecl(), R.Qualifier), CurContext, Hiding);
720 return;
721 }
722
Douglas Gregor45bcd432010-01-14 03:21:49 +0000723 bool AsNestedNameSpecifier = false;
724 if (!isInterestingDecl(R.Declaration, AsNestedNameSpecifier))
Douglas Gregor1ca6ae82010-01-14 01:09:38 +0000725 return;
726
727 if (Hiding && CheckHiddenResult(R, CurContext, Hiding))
728 return;
729
730 // Make sure that any given declaration only shows up in the result set once.
731 if (!AllDeclsFound.insert(R.Declaration->getCanonicalDecl()))
732 return;
733
734 // If the filter is for nested-name-specifiers, then this result starts a
735 // nested-name-specifier.
Douglas Gregor12e13132010-05-26 22:00:08 +0000736 if (AsNestedNameSpecifier) {
Douglas Gregor1ca6ae82010-01-14 01:09:38 +0000737 R.StartsNestedNameSpecifier = true;
Douglas Gregor12e13132010-05-26 22:00:08 +0000738 R.Priority = CCP_NestedNameSpecifier;
739 }
Douglas Gregor0cc84042010-01-14 15:47:35 +0000740 else if (Filter == &ResultBuilder::IsMember && !R.Qualifier && InBaseClass &&
741 isa<CXXRecordDecl>(R.Declaration->getDeclContext()
742 ->getLookupContext()))
743 R.QualifierIsInformative = true;
744
Douglas Gregor1ca6ae82010-01-14 01:09:38 +0000745 // If this result is supposed to have an informative qualifier, add one.
746 if (R.QualifierIsInformative && !R.Qualifier &&
747 !R.StartsNestedNameSpecifier) {
748 DeclContext *Ctx = R.Declaration->getDeclContext();
749 if (NamespaceDecl *Namespace = dyn_cast<NamespaceDecl>(Ctx))
750 R.Qualifier = NestedNameSpecifier::Create(SemaRef.Context, 0, Namespace);
751 else if (TagDecl *Tag = dyn_cast<TagDecl>(Ctx))
752 R.Qualifier = NestedNameSpecifier::Create(SemaRef.Context, 0, false,
Douglas Gregor45bcd432010-01-14 03:21:49 +0000753 SemaRef.Context.getTypeDeclType(Tag).getTypePtr());
Douglas Gregor1ca6ae82010-01-14 01:09:38 +0000754 else
755 R.QualifierIsInformative = false;
756 }
757
Douglas Gregor12e13132010-05-26 22:00:08 +0000758 // Adjust the priority if this result comes from a base class.
759 if (InBaseClass)
760 R.Priority += CCD_InBaseClass;
761
Douglas Gregor1f5537a2010-07-08 23:20:03 +0000762 if (!PreferredType.isNull())
763 AdjustResultPriorityForPreferredType(R);
Douglas Gregor5ac3bdb2010-05-30 01:49:25 +0000764
Douglas Gregor1ca6ae82010-01-14 01:09:38 +0000765 // Insert this result into the set of results.
766 Results.push_back(R);
767}
768
Douglas Gregora4477812010-01-14 16:01:26 +0000769void ResultBuilder::AddResult(Result R) {
770 assert(R.Kind != Result::RK_Declaration &&
771 "Declaration results need more context");
772 Results.push_back(R);
773}
774
Douglas Gregor86d9a522009-09-21 16:56:56 +0000775/// \brief Enter into a new scope.
776void ResultBuilder::EnterNewScope() {
777 ShadowMaps.push_back(ShadowMap());
778}
779
780/// \brief Exit from the current scope.
781void ResultBuilder::ExitScope() {
Douglas Gregorfbcb5d62009-12-06 20:23:50 +0000782 for (ShadowMap::iterator E = ShadowMaps.back().begin(),
783 EEnd = ShadowMaps.back().end();
784 E != EEnd;
785 ++E)
786 E->second.Destroy();
787
Douglas Gregor86d9a522009-09-21 16:56:56 +0000788 ShadowMaps.pop_back();
789}
790
Douglas Gregor791215b2009-09-21 20:51:25 +0000791/// \brief Determines whether this given declaration will be found by
792/// ordinary name lookup.
793bool ResultBuilder::IsOrdinaryName(NamedDecl *ND) const {
Douglas Gregor4710e5b2010-05-28 00:49:12 +0000794 ND = cast<NamedDecl>(ND->getUnderlyingDecl());
795
Douglas Gregor791215b2009-09-21 20:51:25 +0000796 unsigned IDNS = Decl::IDNS_Ordinary;
797 if (SemaRef.getLangOptions().CPlusPlus)
Douglas Gregor9b30b262010-06-15 20:26:51 +0000798 IDNS |= Decl::IDNS_Tag | Decl::IDNS_Namespace | Decl::IDNS_Member;
Douglas Gregor1ca6ae82010-01-14 01:09:38 +0000799 else if (SemaRef.getLangOptions().ObjC1 && isa<ObjCIvarDecl>(ND))
800 return true;
801
Douglas Gregor791215b2009-09-21 20:51:25 +0000802 return ND->getIdentifierNamespace() & IDNS;
803}
804
Douglas Gregor01dfea02010-01-10 23:08:15 +0000805/// \brief Determines whether this given declaration will be found by
Douglas Gregor4710e5b2010-05-28 00:49:12 +0000806/// ordinary name lookup but is not a type name.
807bool ResultBuilder::IsOrdinaryNonTypeName(NamedDecl *ND) const {
808 ND = cast<NamedDecl>(ND->getUnderlyingDecl());
809 if (isa<TypeDecl>(ND) || isa<ObjCInterfaceDecl>(ND))
810 return false;
811
812 unsigned IDNS = Decl::IDNS_Ordinary;
813 if (SemaRef.getLangOptions().CPlusPlus)
Douglas Gregor9b30b262010-06-15 20:26:51 +0000814 IDNS |= Decl::IDNS_Tag | Decl::IDNS_Namespace | Decl::IDNS_Member;
Douglas Gregor4710e5b2010-05-28 00:49:12 +0000815 else if (SemaRef.getLangOptions().ObjC1 && isa<ObjCIvarDecl>(ND))
816 return true;
817
818 return ND->getIdentifierNamespace() & IDNS;
819}
820
Douglas Gregorf9578432010-07-28 21:50:18 +0000821bool ResultBuilder::IsIntegralConstantValue(NamedDecl *ND) const {
822 if (!IsOrdinaryNonTypeName(ND))
823 return 0;
824
825 if (ValueDecl *VD = dyn_cast<ValueDecl>(ND->getUnderlyingDecl()))
826 if (VD->getType()->isIntegralOrEnumerationType())
827 return true;
828
829 return false;
830}
831
Douglas Gregor4710e5b2010-05-28 00:49:12 +0000832/// \brief Determines whether this given declaration will be found by
Douglas Gregor01dfea02010-01-10 23:08:15 +0000833/// ordinary name lookup.
834bool ResultBuilder::IsOrdinaryNonValueName(NamedDecl *ND) const {
Douglas Gregor4710e5b2010-05-28 00:49:12 +0000835 ND = cast<NamedDecl>(ND->getUnderlyingDecl());
836
Douglas Gregor01dfea02010-01-10 23:08:15 +0000837 unsigned IDNS = Decl::IDNS_Ordinary;
838 if (SemaRef.getLangOptions().CPlusPlus)
John McCall0d6b1642010-04-23 18:46:30 +0000839 IDNS |= Decl::IDNS_Tag | Decl::IDNS_Namespace;
Douglas Gregor01dfea02010-01-10 23:08:15 +0000840
841 return (ND->getIdentifierNamespace() & IDNS) &&
Douglas Gregor4710e5b2010-05-28 00:49:12 +0000842 !isa<ValueDecl>(ND) && !isa<FunctionTemplateDecl>(ND) &&
843 !isa<ObjCPropertyDecl>(ND);
Douglas Gregor01dfea02010-01-10 23:08:15 +0000844}
845
Douglas Gregor86d9a522009-09-21 16:56:56 +0000846/// \brief Determines whether the given declaration is suitable as the
847/// start of a C++ nested-name-specifier, e.g., a class or namespace.
848bool ResultBuilder::IsNestedNameSpecifier(NamedDecl *ND) const {
849 // Allow us to find class templates, too.
850 if (ClassTemplateDecl *ClassTemplate = dyn_cast<ClassTemplateDecl>(ND))
851 ND = ClassTemplate->getTemplatedDecl();
852
853 return SemaRef.isAcceptableNestedNameSpecifier(ND);
854}
855
856/// \brief Determines whether the given declaration is an enumeration.
857bool ResultBuilder::IsEnum(NamedDecl *ND) const {
858 return isa<EnumDecl>(ND);
859}
860
861/// \brief Determines whether the given declaration is a class or struct.
862bool ResultBuilder::IsClassOrStruct(NamedDecl *ND) const {
863 // Allow us to find class templates, too.
864 if (ClassTemplateDecl *ClassTemplate = dyn_cast<ClassTemplateDecl>(ND))
865 ND = ClassTemplate->getTemplatedDecl();
866
867 if (RecordDecl *RD = dyn_cast<RecordDecl>(ND))
Abramo Bagnara465d41b2010-05-11 21:36:43 +0000868 return RD->getTagKind() == TTK_Class ||
869 RD->getTagKind() == TTK_Struct;
Douglas Gregor86d9a522009-09-21 16:56:56 +0000870
871 return false;
872}
873
874/// \brief Determines whether the given declaration is a union.
875bool ResultBuilder::IsUnion(NamedDecl *ND) const {
876 // Allow us to find class templates, too.
877 if (ClassTemplateDecl *ClassTemplate = dyn_cast<ClassTemplateDecl>(ND))
878 ND = ClassTemplate->getTemplatedDecl();
879
880 if (RecordDecl *RD = dyn_cast<RecordDecl>(ND))
Abramo Bagnara465d41b2010-05-11 21:36:43 +0000881 return RD->getTagKind() == TTK_Union;
Douglas Gregor86d9a522009-09-21 16:56:56 +0000882
883 return false;
884}
885
886/// \brief Determines whether the given declaration is a namespace.
887bool ResultBuilder::IsNamespace(NamedDecl *ND) const {
888 return isa<NamespaceDecl>(ND);
889}
890
891/// \brief Determines whether the given declaration is a namespace or
892/// namespace alias.
893bool ResultBuilder::IsNamespaceOrAlias(NamedDecl *ND) const {
894 return isa<NamespaceDecl>(ND) || isa<NamespaceAliasDecl>(ND);
895}
896
Douglas Gregor76282942009-12-11 17:31:05 +0000897/// \brief Determines whether the given declaration is a type.
Douglas Gregor86d9a522009-09-21 16:56:56 +0000898bool ResultBuilder::IsType(NamedDecl *ND) const {
Douglas Gregord32b0222010-08-24 01:06:58 +0000899 if (UsingShadowDecl *Using = dyn_cast<UsingShadowDecl>(ND))
900 ND = Using->getTargetDecl();
901
902 return isa<TypeDecl>(ND) || isa<ObjCInterfaceDecl>(ND);
Douglas Gregor86d9a522009-09-21 16:56:56 +0000903}
904
Douglas Gregor76282942009-12-11 17:31:05 +0000905/// \brief Determines which members of a class should be visible via
906/// "." or "->". Only value declarations, nested name specifiers, and
907/// using declarations thereof should show up.
Douglas Gregoreb5758b2009-09-23 22:26:46 +0000908bool ResultBuilder::IsMember(NamedDecl *ND) const {
Douglas Gregor76282942009-12-11 17:31:05 +0000909 if (UsingShadowDecl *Using = dyn_cast<UsingShadowDecl>(ND))
910 ND = Using->getTargetDecl();
911
Douglas Gregorce821962009-12-11 18:14:22 +0000912 return isa<ValueDecl>(ND) || isa<FunctionTemplateDecl>(ND) ||
913 isa<ObjCPropertyDecl>(ND);
Douglas Gregoreb5758b2009-09-23 22:26:46 +0000914}
915
Douglas Gregor8e254cf2010-05-27 23:06:34 +0000916static bool isObjCReceiverType(ASTContext &C, QualType T) {
917 T = C.getCanonicalType(T);
918 switch (T->getTypeClass()) {
919 case Type::ObjCObject:
920 case Type::ObjCInterface:
921 case Type::ObjCObjectPointer:
922 return true;
923
924 case Type::Builtin:
925 switch (cast<BuiltinType>(T)->getKind()) {
926 case BuiltinType::ObjCId:
927 case BuiltinType::ObjCClass:
928 case BuiltinType::ObjCSel:
929 return true;
930
931 default:
932 break;
933 }
934 return false;
935
936 default:
937 break;
938 }
939
940 if (!C.getLangOptions().CPlusPlus)
941 return false;
942
943 // FIXME: We could perform more analysis here to determine whether a
944 // particular class type has any conversions to Objective-C types. For now,
945 // just accept all class types.
946 return T->isDependentType() || T->isRecordType();
947}
948
949bool ResultBuilder::IsObjCMessageReceiver(NamedDecl *ND) const {
950 QualType T = getDeclUsageType(SemaRef.Context, ND);
951 if (T.isNull())
952 return false;
953
954 T = SemaRef.Context.getBaseElementType(T);
955 return isObjCReceiverType(SemaRef.Context, T);
956}
957
Douglas Gregorfb629412010-08-23 21:17:50 +0000958bool ResultBuilder::IsObjCCollection(NamedDecl *ND) const {
959 if ((SemaRef.getLangOptions().CPlusPlus && !IsOrdinaryName(ND)) ||
960 (!SemaRef.getLangOptions().CPlusPlus && !IsOrdinaryNonTypeName(ND)))
961 return false;
962
963 QualType T = getDeclUsageType(SemaRef.Context, ND);
964 if (T.isNull())
965 return false;
966
967 T = SemaRef.Context.getBaseElementType(T);
968 return T->isObjCObjectType() || T->isObjCObjectPointerType() ||
969 T->isObjCIdType() ||
970 (SemaRef.getLangOptions().CPlusPlus && T->isRecordType());
971}
Douglas Gregor8e254cf2010-05-27 23:06:34 +0000972
Douglas Gregor80f4f4c2010-01-14 16:08:12 +0000973/// \rief Determines whether the given declaration is an Objective-C
974/// instance variable.
975bool ResultBuilder::IsObjCIvar(NamedDecl *ND) const {
976 return isa<ObjCIvarDecl>(ND);
977}
978
Douglas Gregor1ca6ae82010-01-14 01:09:38 +0000979namespace {
980 /// \brief Visible declaration consumer that adds a code-completion result
981 /// for each visible declaration.
982 class CodeCompletionDeclConsumer : public VisibleDeclConsumer {
983 ResultBuilder &Results;
984 DeclContext *CurContext;
985
986 public:
987 CodeCompletionDeclConsumer(ResultBuilder &Results, DeclContext *CurContext)
988 : Results(Results), CurContext(CurContext) { }
989
Douglas Gregor0cc84042010-01-14 15:47:35 +0000990 virtual void FoundDecl(NamedDecl *ND, NamedDecl *Hiding, bool InBaseClass) {
991 Results.AddResult(ND, CurContext, Hiding, InBaseClass);
Douglas Gregor1ca6ae82010-01-14 01:09:38 +0000992 }
993 };
994}
995
Douglas Gregor86d9a522009-09-21 16:56:56 +0000996/// \brief Add type specifiers for the current language as keyword results.
Douglas Gregorbca403c2010-01-13 23:51:12 +0000997static void AddTypeSpecifierResults(const LangOptions &LangOpts,
Douglas Gregor86d9a522009-09-21 16:56:56 +0000998 ResultBuilder &Results) {
999 typedef CodeCompleteConsumer::Result Result;
Douglas Gregor12e13132010-05-26 22:00:08 +00001000 Results.AddResult(Result("short", CCP_Type));
1001 Results.AddResult(Result("long", CCP_Type));
1002 Results.AddResult(Result("signed", CCP_Type));
1003 Results.AddResult(Result("unsigned", CCP_Type));
1004 Results.AddResult(Result("void", CCP_Type));
1005 Results.AddResult(Result("char", CCP_Type));
1006 Results.AddResult(Result("int", CCP_Type));
1007 Results.AddResult(Result("float", CCP_Type));
1008 Results.AddResult(Result("double", CCP_Type));
1009 Results.AddResult(Result("enum", CCP_Type));
1010 Results.AddResult(Result("struct", CCP_Type));
1011 Results.AddResult(Result("union", CCP_Type));
1012 Results.AddResult(Result("const", CCP_Type));
1013 Results.AddResult(Result("volatile", CCP_Type));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001014
Douglas Gregor86d9a522009-09-21 16:56:56 +00001015 if (LangOpts.C99) {
1016 // C99-specific
Douglas Gregor12e13132010-05-26 22:00:08 +00001017 Results.AddResult(Result("_Complex", CCP_Type));
1018 Results.AddResult(Result("_Imaginary", CCP_Type));
1019 Results.AddResult(Result("_Bool", CCP_Type));
1020 Results.AddResult(Result("restrict", CCP_Type));
Douglas Gregor86d9a522009-09-21 16:56:56 +00001021 }
1022
1023 if (LangOpts.CPlusPlus) {
1024 // C++-specific
Douglas Gregor12e13132010-05-26 22:00:08 +00001025 Results.AddResult(Result("bool", CCP_Type));
1026 Results.AddResult(Result("class", CCP_Type));
1027 Results.AddResult(Result("wchar_t", CCP_Type));
Douglas Gregor86d9a522009-09-21 16:56:56 +00001028
Douglas Gregorc8bddde2010-05-28 00:22:41 +00001029 // typename qualified-id
1030 CodeCompletionString *Pattern = new CodeCompletionString;
1031 Pattern->AddTypedTextChunk("typename");
1032 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
1033 Pattern->AddPlaceholderChunk("qualifier");
1034 Pattern->AddTextChunk("::");
1035 Pattern->AddPlaceholderChunk("name");
1036 Results.AddResult(Result(Pattern));
Douglas Gregord8e8a582010-05-25 21:41:55 +00001037
Douglas Gregor86d9a522009-09-21 16:56:56 +00001038 if (LangOpts.CPlusPlus0x) {
Douglas Gregor12e13132010-05-26 22:00:08 +00001039 Results.AddResult(Result("auto", CCP_Type));
1040 Results.AddResult(Result("char16_t", CCP_Type));
1041 Results.AddResult(Result("char32_t", CCP_Type));
Douglas Gregorc8bddde2010-05-28 00:22:41 +00001042
1043 CodeCompletionString *Pattern = new CodeCompletionString;
1044 Pattern->AddTypedTextChunk("decltype");
1045 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
1046 Pattern->AddPlaceholderChunk("expression");
1047 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
1048 Results.AddResult(Result(Pattern));
Douglas Gregor86d9a522009-09-21 16:56:56 +00001049 }
1050 }
1051
1052 // GNU extensions
1053 if (LangOpts.GNUMode) {
1054 // FIXME: Enable when we actually support decimal floating point.
Douglas Gregora4477812010-01-14 16:01:26 +00001055 // Results.AddResult(Result("_Decimal32"));
1056 // Results.AddResult(Result("_Decimal64"));
1057 // Results.AddResult(Result("_Decimal128"));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001058
Douglas Gregorc8bddde2010-05-28 00:22:41 +00001059 CodeCompletionString *Pattern = new CodeCompletionString;
1060 Pattern->AddTypedTextChunk("typeof");
1061 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
1062 Pattern->AddPlaceholderChunk("expression");
1063 Results.AddResult(Result(Pattern));
1064
1065 Pattern = new CodeCompletionString;
1066 Pattern->AddTypedTextChunk("typeof");
1067 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
1068 Pattern->AddPlaceholderChunk("type");
1069 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
1070 Results.AddResult(Result(Pattern));
Douglas Gregor86d9a522009-09-21 16:56:56 +00001071 }
1072}
1073
Douglas Gregore6b1bb62010-08-11 21:23:17 +00001074static void AddStorageSpecifiers(Action::ParserCompletionContext CCC,
Douglas Gregor01dfea02010-01-10 23:08:15 +00001075 const LangOptions &LangOpts,
Douglas Gregor01dfea02010-01-10 23:08:15 +00001076 ResultBuilder &Results) {
1077 typedef CodeCompleteConsumer::Result Result;
1078 // Note: we don't suggest either "auto" or "register", because both
1079 // are pointless as storage specifiers. Elsewhere, we suggest "auto"
1080 // in C++0x as a type specifier.
Douglas Gregora4477812010-01-14 16:01:26 +00001081 Results.AddResult(Result("extern"));
1082 Results.AddResult(Result("static"));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001083}
1084
Douglas Gregore6b1bb62010-08-11 21:23:17 +00001085static void AddFunctionSpecifiers(Action::ParserCompletionContext CCC,
Douglas Gregor01dfea02010-01-10 23:08:15 +00001086 const LangOptions &LangOpts,
Douglas Gregor01dfea02010-01-10 23:08:15 +00001087 ResultBuilder &Results) {
1088 typedef CodeCompleteConsumer::Result Result;
1089 switch (CCC) {
Douglas Gregore6b1bb62010-08-11 21:23:17 +00001090 case Action::PCC_Class:
1091 case Action::PCC_MemberTemplate:
Douglas Gregor01dfea02010-01-10 23:08:15 +00001092 if (LangOpts.CPlusPlus) {
Douglas Gregora4477812010-01-14 16:01:26 +00001093 Results.AddResult(Result("explicit"));
1094 Results.AddResult(Result("friend"));
1095 Results.AddResult(Result("mutable"));
1096 Results.AddResult(Result("virtual"));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001097 }
1098 // Fall through
1099
Douglas Gregore6b1bb62010-08-11 21:23:17 +00001100 case Action::PCC_ObjCInterface:
1101 case Action::PCC_ObjCImplementation:
1102 case Action::PCC_Namespace:
1103 case Action::PCC_Template:
Douglas Gregor01dfea02010-01-10 23:08:15 +00001104 if (LangOpts.CPlusPlus || LangOpts.C99)
Douglas Gregora4477812010-01-14 16:01:26 +00001105 Results.AddResult(Result("inline"));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001106 break;
1107
Douglas Gregore6b1bb62010-08-11 21:23:17 +00001108 case Action::PCC_ObjCInstanceVariableList:
1109 case Action::PCC_Expression:
1110 case Action::PCC_Statement:
1111 case Action::PCC_ForInit:
1112 case Action::PCC_Condition:
1113 case Action::PCC_RecoveryInFunction:
Douglas Gregord32b0222010-08-24 01:06:58 +00001114 case Action::PCC_Type:
Douglas Gregor01dfea02010-01-10 23:08:15 +00001115 break;
1116 }
1117}
1118
Douglas Gregorbca403c2010-01-13 23:51:12 +00001119static void AddObjCExpressionResults(ResultBuilder &Results, bool NeedAt);
1120static void AddObjCStatementResults(ResultBuilder &Results, bool NeedAt);
1121static void AddObjCVisibilityResults(const LangOptions &LangOpts,
Douglas Gregorc38c3e12010-01-13 21:54:15 +00001122 ResultBuilder &Results,
1123 bool NeedAt);
Douglas Gregorbca403c2010-01-13 23:51:12 +00001124static void AddObjCImplementationResults(const LangOptions &LangOpts,
Douglas Gregorb6ac2452010-01-13 21:24:21 +00001125 ResultBuilder &Results,
1126 bool NeedAt);
Douglas Gregorbca403c2010-01-13 23:51:12 +00001127static void AddObjCInterfaceResults(const LangOptions &LangOpts,
Douglas Gregorb6ac2452010-01-13 21:24:21 +00001128 ResultBuilder &Results,
1129 bool NeedAt);
Douglas Gregorbca403c2010-01-13 23:51:12 +00001130static void AddObjCTopLevelResults(ResultBuilder &Results, bool NeedAt);
Douglas Gregorb6ac2452010-01-13 21:24:21 +00001131
Douglas Gregorc8bddde2010-05-28 00:22:41 +00001132static void AddTypedefResult(ResultBuilder &Results) {
1133 CodeCompletionString *Pattern = new CodeCompletionString;
1134 Pattern->AddTypedTextChunk("typedef");
1135 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
1136 Pattern->AddPlaceholderChunk("type");
1137 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
1138 Pattern->AddPlaceholderChunk("name");
1139 Results.AddResult(CodeCompleteConsumer::Result(Pattern));
1140}
1141
Douglas Gregore6b1bb62010-08-11 21:23:17 +00001142static bool WantTypesInContext(Action::ParserCompletionContext CCC,
Douglas Gregor4710e5b2010-05-28 00:49:12 +00001143 const LangOptions &LangOpts) {
1144 if (LangOpts.CPlusPlus)
1145 return true;
1146
1147 switch (CCC) {
Douglas Gregore6b1bb62010-08-11 21:23:17 +00001148 case Action::PCC_Namespace:
1149 case Action::PCC_Class:
1150 case Action::PCC_ObjCInstanceVariableList:
1151 case Action::PCC_Template:
1152 case Action::PCC_MemberTemplate:
1153 case Action::PCC_Statement:
1154 case Action::PCC_RecoveryInFunction:
Douglas Gregord32b0222010-08-24 01:06:58 +00001155 case Action::PCC_Type:
Douglas Gregor4710e5b2010-05-28 00:49:12 +00001156 return true;
1157
Douglas Gregore6b1bb62010-08-11 21:23:17 +00001158 case Action::PCC_ObjCInterface:
1159 case Action::PCC_ObjCImplementation:
1160 case Action::PCC_Expression:
1161 case Action::PCC_Condition:
Douglas Gregor4710e5b2010-05-28 00:49:12 +00001162 return false;
1163
Douglas Gregore6b1bb62010-08-11 21:23:17 +00001164 case Action::PCC_ForInit:
Douglas Gregor4710e5b2010-05-28 00:49:12 +00001165 return LangOpts.ObjC1 || LangOpts.C99;
1166 }
1167
1168 return false;
1169}
1170
Douglas Gregor01dfea02010-01-10 23:08:15 +00001171/// \brief Add language constructs that show up for "ordinary" names.
Douglas Gregore6b1bb62010-08-11 21:23:17 +00001172static void AddOrdinaryNameResults(Action::ParserCompletionContext CCC,
Douglas Gregor01dfea02010-01-10 23:08:15 +00001173 Scope *S,
1174 Sema &SemaRef,
Douglas Gregor01dfea02010-01-10 23:08:15 +00001175 ResultBuilder &Results) {
1176 typedef CodeCompleteConsumer::Result Result;
1177 switch (CCC) {
Douglas Gregore6b1bb62010-08-11 21:23:17 +00001178 case Action::PCC_Namespace:
Douglas Gregorc8bddde2010-05-28 00:22:41 +00001179 if (SemaRef.getLangOptions().CPlusPlus) {
1180 CodeCompletionString *Pattern = 0;
1181
1182 if (Results.includeCodePatterns()) {
1183 // namespace <identifier> { declarations }
1184 CodeCompletionString *Pattern = new CodeCompletionString;
1185 Pattern->AddTypedTextChunk("namespace");
1186 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
1187 Pattern->AddPlaceholderChunk("identifier");
1188 Pattern->AddChunk(CodeCompletionString::CK_LeftBrace);
1189 Pattern->AddPlaceholderChunk("declarations");
1190 Pattern->AddChunk(CodeCompletionString::CK_VerticalSpace);
1191 Pattern->AddChunk(CodeCompletionString::CK_RightBrace);
1192 Results.AddResult(Result(Pattern));
1193 }
1194
Douglas Gregor01dfea02010-01-10 23:08:15 +00001195 // namespace identifier = identifier ;
1196 Pattern = new CodeCompletionString;
1197 Pattern->AddTypedTextChunk("namespace");
1198 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
Douglas Gregorc8bddde2010-05-28 00:22:41 +00001199 Pattern->AddPlaceholderChunk("name");
Douglas Gregor01dfea02010-01-10 23:08:15 +00001200 Pattern->AddChunk(CodeCompletionString::CK_Equal);
Douglas Gregorc8bddde2010-05-28 00:22:41 +00001201 Pattern->AddPlaceholderChunk("namespace");
Douglas Gregora4477812010-01-14 16:01:26 +00001202 Results.AddResult(Result(Pattern));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001203
1204 // Using directives
1205 Pattern = new CodeCompletionString;
1206 Pattern->AddTypedTextChunk("using");
1207 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
1208 Pattern->AddTextChunk("namespace");
1209 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
1210 Pattern->AddPlaceholderChunk("identifier");
Douglas Gregora4477812010-01-14 16:01:26 +00001211 Results.AddResult(Result(Pattern));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001212
1213 // asm(string-literal)
1214 Pattern = new CodeCompletionString;
1215 Pattern->AddTypedTextChunk("asm");
1216 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
1217 Pattern->AddPlaceholderChunk("string-literal");
1218 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
Douglas Gregora4477812010-01-14 16:01:26 +00001219 Results.AddResult(Result(Pattern));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001220
Douglas Gregorc8bddde2010-05-28 00:22:41 +00001221 if (Results.includeCodePatterns()) {
1222 // Explicit template instantiation
1223 Pattern = new CodeCompletionString;
1224 Pattern->AddTypedTextChunk("template");
1225 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
1226 Pattern->AddPlaceholderChunk("declaration");
1227 Results.AddResult(Result(Pattern));
1228 }
Douglas Gregor01dfea02010-01-10 23:08:15 +00001229 }
Douglas Gregorb6ac2452010-01-13 21:24:21 +00001230
1231 if (SemaRef.getLangOptions().ObjC1)
Douglas Gregorbca403c2010-01-13 23:51:12 +00001232 AddObjCTopLevelResults(Results, true);
Douglas Gregorb6ac2452010-01-13 21:24:21 +00001233
Douglas Gregorc8bddde2010-05-28 00:22:41 +00001234 AddTypedefResult(Results);
Douglas Gregor01dfea02010-01-10 23:08:15 +00001235 // Fall through
1236
Douglas Gregore6b1bb62010-08-11 21:23:17 +00001237 case Action::PCC_Class:
Douglas Gregorc8bddde2010-05-28 00:22:41 +00001238 if (SemaRef.getLangOptions().CPlusPlus) {
Douglas Gregor01dfea02010-01-10 23:08:15 +00001239 // Using declaration
1240 CodeCompletionString *Pattern = new CodeCompletionString;
1241 Pattern->AddTypedTextChunk("using");
1242 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
Douglas Gregorc8bddde2010-05-28 00:22:41 +00001243 Pattern->AddPlaceholderChunk("qualifier");
1244 Pattern->AddTextChunk("::");
1245 Pattern->AddPlaceholderChunk("name");
Douglas Gregora4477812010-01-14 16:01:26 +00001246 Results.AddResult(Result(Pattern));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001247
Douglas Gregorc8bddde2010-05-28 00:22:41 +00001248 // using typename qualifier::name (only in a dependent context)
Douglas Gregor01dfea02010-01-10 23:08:15 +00001249 if (SemaRef.CurContext->isDependentContext()) {
1250 Pattern = new CodeCompletionString;
1251 Pattern->AddTypedTextChunk("using");
1252 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
1253 Pattern->AddTextChunk("typename");
1254 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
Douglas Gregorc8bddde2010-05-28 00:22:41 +00001255 Pattern->AddPlaceholderChunk("qualifier");
1256 Pattern->AddTextChunk("::");
1257 Pattern->AddPlaceholderChunk("name");
Douglas Gregora4477812010-01-14 16:01:26 +00001258 Results.AddResult(Result(Pattern));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001259 }
1260
Douglas Gregore6b1bb62010-08-11 21:23:17 +00001261 if (CCC == Action::PCC_Class) {
Douglas Gregorc8bddde2010-05-28 00:22:41 +00001262 AddTypedefResult(Results);
1263
Douglas Gregor01dfea02010-01-10 23:08:15 +00001264 // public:
1265 Pattern = new CodeCompletionString;
1266 Pattern->AddTypedTextChunk("public");
1267 Pattern->AddChunk(CodeCompletionString::CK_Colon);
Douglas Gregora4477812010-01-14 16:01:26 +00001268 Results.AddResult(Result(Pattern));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001269
1270 // protected:
1271 Pattern = new CodeCompletionString;
1272 Pattern->AddTypedTextChunk("protected");
1273 Pattern->AddChunk(CodeCompletionString::CK_Colon);
Douglas Gregora4477812010-01-14 16:01:26 +00001274 Results.AddResult(Result(Pattern));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001275
1276 // private:
1277 Pattern = new CodeCompletionString;
1278 Pattern->AddTypedTextChunk("private");
1279 Pattern->AddChunk(CodeCompletionString::CK_Colon);
Douglas Gregora4477812010-01-14 16:01:26 +00001280 Results.AddResult(Result(Pattern));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001281 }
1282 }
1283 // Fall through
1284
Douglas Gregore6b1bb62010-08-11 21:23:17 +00001285 case Action::PCC_Template:
1286 case Action::PCC_MemberTemplate:
Douglas Gregord8e8a582010-05-25 21:41:55 +00001287 if (SemaRef.getLangOptions().CPlusPlus && Results.includeCodePatterns()) {
Douglas Gregor01dfea02010-01-10 23:08:15 +00001288 // template < parameters >
1289 CodeCompletionString *Pattern = new CodeCompletionString;
1290 Pattern->AddTypedTextChunk("template");
1291 Pattern->AddChunk(CodeCompletionString::CK_LeftAngle);
1292 Pattern->AddPlaceholderChunk("parameters");
1293 Pattern->AddChunk(CodeCompletionString::CK_RightAngle);
Douglas Gregora4477812010-01-14 16:01:26 +00001294 Results.AddResult(Result(Pattern));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001295 }
1296
Douglas Gregorbca403c2010-01-13 23:51:12 +00001297 AddStorageSpecifiers(CCC, SemaRef.getLangOptions(), Results);
1298 AddFunctionSpecifiers(CCC, SemaRef.getLangOptions(), Results);
Douglas Gregor01dfea02010-01-10 23:08:15 +00001299 break;
1300
Douglas Gregore6b1bb62010-08-11 21:23:17 +00001301 case Action::PCC_ObjCInterface:
Douglas Gregorbca403c2010-01-13 23:51:12 +00001302 AddObjCInterfaceResults(SemaRef.getLangOptions(), Results, true);
1303 AddStorageSpecifiers(CCC, SemaRef.getLangOptions(), Results);
1304 AddFunctionSpecifiers(CCC, SemaRef.getLangOptions(), Results);
Douglas Gregorb6ac2452010-01-13 21:24:21 +00001305 break;
1306
Douglas Gregore6b1bb62010-08-11 21:23:17 +00001307 case Action::PCC_ObjCImplementation:
Douglas Gregorbca403c2010-01-13 23:51:12 +00001308 AddObjCImplementationResults(SemaRef.getLangOptions(), Results, true);
1309 AddStorageSpecifiers(CCC, SemaRef.getLangOptions(), Results);
1310 AddFunctionSpecifiers(CCC, SemaRef.getLangOptions(), Results);
Douglas Gregorb6ac2452010-01-13 21:24:21 +00001311 break;
1312
Douglas Gregore6b1bb62010-08-11 21:23:17 +00001313 case Action::PCC_ObjCInstanceVariableList:
Douglas Gregorbca403c2010-01-13 23:51:12 +00001314 AddObjCVisibilityResults(SemaRef.getLangOptions(), Results, true);
Douglas Gregorc38c3e12010-01-13 21:54:15 +00001315 break;
1316
Douglas Gregore6b1bb62010-08-11 21:23:17 +00001317 case Action::PCC_RecoveryInFunction:
1318 case Action::PCC_Statement: {
Douglas Gregorc8bddde2010-05-28 00:22:41 +00001319 AddTypedefResult(Results);
Douglas Gregor01dfea02010-01-10 23:08:15 +00001320
1321 CodeCompletionString *Pattern = 0;
Douglas Gregord8e8a582010-05-25 21:41:55 +00001322 if (SemaRef.getLangOptions().CPlusPlus && Results.includeCodePatterns()) {
Douglas Gregor01dfea02010-01-10 23:08:15 +00001323 Pattern = new CodeCompletionString;
1324 Pattern->AddTypedTextChunk("try");
1325 Pattern->AddChunk(CodeCompletionString::CK_LeftBrace);
1326 Pattern->AddPlaceholderChunk("statements");
1327 Pattern->AddChunk(CodeCompletionString::CK_VerticalSpace);
1328 Pattern->AddChunk(CodeCompletionString::CK_RightBrace);
1329 Pattern->AddTextChunk("catch");
1330 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
1331 Pattern->AddPlaceholderChunk("declaration");
1332 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
1333 Pattern->AddChunk(CodeCompletionString::CK_LeftBrace);
1334 Pattern->AddPlaceholderChunk("statements");
1335 Pattern->AddChunk(CodeCompletionString::CK_VerticalSpace);
1336 Pattern->AddChunk(CodeCompletionString::CK_RightBrace);
Douglas Gregora4477812010-01-14 16:01:26 +00001337 Results.AddResult(Result(Pattern));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001338 }
Douglas Gregorb6ac2452010-01-13 21:24:21 +00001339 if (SemaRef.getLangOptions().ObjC1)
Douglas Gregorbca403c2010-01-13 23:51:12 +00001340 AddObjCStatementResults(Results, true);
Douglas Gregorb6ac2452010-01-13 21:24:21 +00001341
Douglas Gregord8e8a582010-05-25 21:41:55 +00001342 if (Results.includeCodePatterns()) {
1343 // if (condition) { statements }
1344 Pattern = new CodeCompletionString;
1345 Pattern->AddTypedTextChunk("if");
1346 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
1347 if (SemaRef.getLangOptions().CPlusPlus)
1348 Pattern->AddPlaceholderChunk("condition");
1349 else
1350 Pattern->AddPlaceholderChunk("expression");
1351 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
1352 Pattern->AddChunk(CodeCompletionString::CK_LeftBrace);
1353 Pattern->AddPlaceholderChunk("statements");
1354 Pattern->AddChunk(CodeCompletionString::CK_VerticalSpace);
1355 Pattern->AddChunk(CodeCompletionString::CK_RightBrace);
1356 Results.AddResult(Result(Pattern));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001357
Douglas Gregord8e8a582010-05-25 21:41:55 +00001358 // switch (condition) { }
1359 Pattern = new CodeCompletionString;
1360 Pattern->AddTypedTextChunk("switch");
1361 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
1362 if (SemaRef.getLangOptions().CPlusPlus)
1363 Pattern->AddPlaceholderChunk("condition");
1364 else
1365 Pattern->AddPlaceholderChunk("expression");
1366 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
1367 Pattern->AddChunk(CodeCompletionString::CK_LeftBrace);
1368 Pattern->AddChunk(CodeCompletionString::CK_VerticalSpace);
1369 Pattern->AddChunk(CodeCompletionString::CK_RightBrace);
1370 Results.AddResult(Result(Pattern));
1371 }
1372
Douglas Gregor01dfea02010-01-10 23:08:15 +00001373 // Switch-specific statements.
Douglas Gregorc8bddde2010-05-28 00:22:41 +00001374 if (!SemaRef.getSwitchStack().empty()) {
Douglas Gregor01dfea02010-01-10 23:08:15 +00001375 // case expression:
1376 Pattern = new CodeCompletionString;
1377 Pattern->AddTypedTextChunk("case");
Douglas Gregorc8bddde2010-05-28 00:22:41 +00001378 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
Douglas Gregor01dfea02010-01-10 23:08:15 +00001379 Pattern->AddPlaceholderChunk("expression");
1380 Pattern->AddChunk(CodeCompletionString::CK_Colon);
Douglas Gregora4477812010-01-14 16:01:26 +00001381 Results.AddResult(Result(Pattern));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001382
1383 // default:
1384 Pattern = new CodeCompletionString;
1385 Pattern->AddTypedTextChunk("default");
1386 Pattern->AddChunk(CodeCompletionString::CK_Colon);
Douglas Gregora4477812010-01-14 16:01:26 +00001387 Results.AddResult(Result(Pattern));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001388 }
1389
Douglas Gregord8e8a582010-05-25 21:41:55 +00001390 if (Results.includeCodePatterns()) {
1391 /// while (condition) { statements }
1392 Pattern = new CodeCompletionString;
1393 Pattern->AddTypedTextChunk("while");
1394 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
1395 if (SemaRef.getLangOptions().CPlusPlus)
1396 Pattern->AddPlaceholderChunk("condition");
1397 else
1398 Pattern->AddPlaceholderChunk("expression");
1399 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
1400 Pattern->AddChunk(CodeCompletionString::CK_LeftBrace);
1401 Pattern->AddPlaceholderChunk("statements");
1402 Pattern->AddChunk(CodeCompletionString::CK_VerticalSpace);
1403 Pattern->AddChunk(CodeCompletionString::CK_RightBrace);
1404 Results.AddResult(Result(Pattern));
1405
1406 // do { statements } while ( expression );
1407 Pattern = new CodeCompletionString;
1408 Pattern->AddTypedTextChunk("do");
1409 Pattern->AddChunk(CodeCompletionString::CK_LeftBrace);
1410 Pattern->AddPlaceholderChunk("statements");
1411 Pattern->AddChunk(CodeCompletionString::CK_VerticalSpace);
1412 Pattern->AddChunk(CodeCompletionString::CK_RightBrace);
1413 Pattern->AddTextChunk("while");
1414 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
Douglas Gregor01dfea02010-01-10 23:08:15 +00001415 Pattern->AddPlaceholderChunk("expression");
Douglas Gregord8e8a582010-05-25 21:41:55 +00001416 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
1417 Results.AddResult(Result(Pattern));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001418
Douglas Gregord8e8a582010-05-25 21:41:55 +00001419 // for ( for-init-statement ; condition ; expression ) { statements }
1420 Pattern = new CodeCompletionString;
1421 Pattern->AddTypedTextChunk("for");
1422 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
1423 if (SemaRef.getLangOptions().CPlusPlus || SemaRef.getLangOptions().C99)
1424 Pattern->AddPlaceholderChunk("init-statement");
1425 else
1426 Pattern->AddPlaceholderChunk("init-expression");
1427 Pattern->AddChunk(CodeCompletionString::CK_SemiColon);
1428 Pattern->AddPlaceholderChunk("condition");
1429 Pattern->AddChunk(CodeCompletionString::CK_SemiColon);
1430 Pattern->AddPlaceholderChunk("inc-expression");
1431 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
1432 Pattern->AddChunk(CodeCompletionString::CK_LeftBrace);
1433 Pattern->AddPlaceholderChunk("statements");
1434 Pattern->AddChunk(CodeCompletionString::CK_VerticalSpace);
1435 Pattern->AddChunk(CodeCompletionString::CK_RightBrace);
1436 Results.AddResult(Result(Pattern));
1437 }
Douglas Gregor01dfea02010-01-10 23:08:15 +00001438
1439 if (S->getContinueParent()) {
1440 // continue ;
1441 Pattern = new CodeCompletionString;
1442 Pattern->AddTypedTextChunk("continue");
Douglas Gregora4477812010-01-14 16:01:26 +00001443 Results.AddResult(Result(Pattern));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001444 }
1445
1446 if (S->getBreakParent()) {
1447 // break ;
1448 Pattern = new CodeCompletionString;
1449 Pattern->AddTypedTextChunk("break");
Douglas Gregora4477812010-01-14 16:01:26 +00001450 Results.AddResult(Result(Pattern));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001451 }
1452
1453 // "return expression ;" or "return ;", depending on whether we
1454 // know the function is void or not.
1455 bool isVoid = false;
1456 if (FunctionDecl *Function = dyn_cast<FunctionDecl>(SemaRef.CurContext))
1457 isVoid = Function->getResultType()->isVoidType();
1458 else if (ObjCMethodDecl *Method
1459 = dyn_cast<ObjCMethodDecl>(SemaRef.CurContext))
1460 isVoid = Method->getResultType()->isVoidType();
Douglas Gregor9ea9bdb2010-03-01 23:15:13 +00001461 else if (SemaRef.getCurBlock() &&
1462 !SemaRef.getCurBlock()->ReturnType.isNull())
1463 isVoid = SemaRef.getCurBlock()->ReturnType->isVoidType();
Douglas Gregor01dfea02010-01-10 23:08:15 +00001464 Pattern = new CodeCompletionString;
1465 Pattern->AddTypedTextChunk("return");
Douglas Gregor93298002010-02-18 04:06:48 +00001466 if (!isVoid) {
1467 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
Douglas Gregor01dfea02010-01-10 23:08:15 +00001468 Pattern->AddPlaceholderChunk("expression");
Douglas Gregor93298002010-02-18 04:06:48 +00001469 }
Douglas Gregora4477812010-01-14 16:01:26 +00001470 Results.AddResult(Result(Pattern));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001471
Douglas Gregorc8bddde2010-05-28 00:22:41 +00001472 // goto identifier ;
1473 Pattern = new CodeCompletionString;
1474 Pattern->AddTypedTextChunk("goto");
1475 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
1476 Pattern->AddPlaceholderChunk("label");
1477 Results.AddResult(Result(Pattern));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001478
Douglas Gregorc8bddde2010-05-28 00:22:41 +00001479 // Using directives
1480 Pattern = new CodeCompletionString;
1481 Pattern->AddTypedTextChunk("using");
1482 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
1483 Pattern->AddTextChunk("namespace");
1484 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
1485 Pattern->AddPlaceholderChunk("identifier");
1486 Results.AddResult(Result(Pattern));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001487 }
1488
1489 // Fall through (for statement expressions).
Douglas Gregore6b1bb62010-08-11 21:23:17 +00001490 case Action::PCC_ForInit:
1491 case Action::PCC_Condition:
Douglas Gregorbca403c2010-01-13 23:51:12 +00001492 AddStorageSpecifiers(CCC, SemaRef.getLangOptions(), Results);
Douglas Gregor01dfea02010-01-10 23:08:15 +00001493 // Fall through: conditions and statements can have expressions.
1494
Douglas Gregore6b1bb62010-08-11 21:23:17 +00001495 case Action::PCC_Expression: {
Douglas Gregor01dfea02010-01-10 23:08:15 +00001496 CodeCompletionString *Pattern = 0;
1497 if (SemaRef.getLangOptions().CPlusPlus) {
1498 // 'this', if we're in a non-static member function.
1499 if (CXXMethodDecl *Method = dyn_cast<CXXMethodDecl>(SemaRef.CurContext))
1500 if (!Method->isStatic())
Douglas Gregora4477812010-01-14 16:01:26 +00001501 Results.AddResult(Result("this"));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001502
1503 // true, false
Douglas Gregora4477812010-01-14 16:01:26 +00001504 Results.AddResult(Result("true"));
1505 Results.AddResult(Result("false"));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001506
Douglas Gregorc8bddde2010-05-28 00:22:41 +00001507 // dynamic_cast < type-id > ( expression )
1508 Pattern = new CodeCompletionString;
1509 Pattern->AddTypedTextChunk("dynamic_cast");
1510 Pattern->AddChunk(CodeCompletionString::CK_LeftAngle);
1511 Pattern->AddPlaceholderChunk("type");
1512 Pattern->AddChunk(CodeCompletionString::CK_RightAngle);
1513 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
1514 Pattern->AddPlaceholderChunk("expression");
1515 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
1516 Results.AddResult(Result(Pattern));
1517
1518 // static_cast < type-id > ( expression )
1519 Pattern = new CodeCompletionString;
1520 Pattern->AddTypedTextChunk("static_cast");
1521 Pattern->AddChunk(CodeCompletionString::CK_LeftAngle);
1522 Pattern->AddPlaceholderChunk("type");
1523 Pattern->AddChunk(CodeCompletionString::CK_RightAngle);
1524 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
1525 Pattern->AddPlaceholderChunk("expression");
1526 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
1527 Results.AddResult(Result(Pattern));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001528
Douglas Gregorc8bddde2010-05-28 00:22:41 +00001529 // reinterpret_cast < type-id > ( expression )
1530 Pattern = new CodeCompletionString;
1531 Pattern->AddTypedTextChunk("reinterpret_cast");
1532 Pattern->AddChunk(CodeCompletionString::CK_LeftAngle);
1533 Pattern->AddPlaceholderChunk("type");
1534 Pattern->AddChunk(CodeCompletionString::CK_RightAngle);
1535 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
1536 Pattern->AddPlaceholderChunk("expression");
1537 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
1538 Results.AddResult(Result(Pattern));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001539
Douglas Gregorc8bddde2010-05-28 00:22:41 +00001540 // const_cast < type-id > ( expression )
1541 Pattern = new CodeCompletionString;
1542 Pattern->AddTypedTextChunk("const_cast");
1543 Pattern->AddChunk(CodeCompletionString::CK_LeftAngle);
1544 Pattern->AddPlaceholderChunk("type");
1545 Pattern->AddChunk(CodeCompletionString::CK_RightAngle);
1546 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
1547 Pattern->AddPlaceholderChunk("expression");
1548 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
1549 Results.AddResult(Result(Pattern));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001550
Douglas Gregorc8bddde2010-05-28 00:22:41 +00001551 // typeid ( expression-or-type )
1552 Pattern = new CodeCompletionString;
1553 Pattern->AddTypedTextChunk("typeid");
1554 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
1555 Pattern->AddPlaceholderChunk("expression-or-type");
1556 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
1557 Results.AddResult(Result(Pattern));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001558
Douglas Gregorc8bddde2010-05-28 00:22:41 +00001559 // new T ( ... )
1560 Pattern = new CodeCompletionString;
1561 Pattern->AddTypedTextChunk("new");
1562 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
1563 Pattern->AddPlaceholderChunk("type");
1564 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
1565 Pattern->AddPlaceholderChunk("expressions");
1566 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
1567 Results.AddResult(Result(Pattern));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001568
Douglas Gregorc8bddde2010-05-28 00:22:41 +00001569 // new T [ ] ( ... )
1570 Pattern = new CodeCompletionString;
1571 Pattern->AddTypedTextChunk("new");
1572 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
1573 Pattern->AddPlaceholderChunk("type");
1574 Pattern->AddChunk(CodeCompletionString::CK_LeftBracket);
1575 Pattern->AddPlaceholderChunk("size");
1576 Pattern->AddChunk(CodeCompletionString::CK_RightBracket);
1577 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
1578 Pattern->AddPlaceholderChunk("expressions");
1579 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
1580 Results.AddResult(Result(Pattern));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001581
Douglas Gregorc8bddde2010-05-28 00:22:41 +00001582 // delete expression
1583 Pattern = new CodeCompletionString;
1584 Pattern->AddTypedTextChunk("delete");
1585 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
1586 Pattern->AddPlaceholderChunk("expression");
1587 Results.AddResult(Result(Pattern));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001588
Douglas Gregorc8bddde2010-05-28 00:22:41 +00001589 // delete [] expression
1590 Pattern = new CodeCompletionString;
1591 Pattern->AddTypedTextChunk("delete");
1592 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
1593 Pattern->AddChunk(CodeCompletionString::CK_LeftBracket);
1594 Pattern->AddChunk(CodeCompletionString::CK_RightBracket);
1595 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
1596 Pattern->AddPlaceholderChunk("expression");
1597 Results.AddResult(Result(Pattern));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001598
Douglas Gregorc8bddde2010-05-28 00:22:41 +00001599 // throw expression
1600 Pattern = new CodeCompletionString;
1601 Pattern->AddTypedTextChunk("throw");
1602 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
1603 Pattern->AddPlaceholderChunk("expression");
1604 Results.AddResult(Result(Pattern));
Douglas Gregor12e13132010-05-26 22:00:08 +00001605
1606 // FIXME: Rethrow?
Douglas Gregor01dfea02010-01-10 23:08:15 +00001607 }
1608
1609 if (SemaRef.getLangOptions().ObjC1) {
1610 // Add "super", if we're in an Objective-C class with a superclass.
Ted Kremenek681e2562010-05-31 21:43:10 +00001611 if (ObjCMethodDecl *Method = SemaRef.getCurMethodDecl()) {
1612 // The interface can be NULL.
1613 if (ObjCInterfaceDecl *ID = Method->getClassInterface())
1614 if (ID->getSuperClass())
1615 Results.AddResult(Result("super"));
1616 }
1617
Douglas Gregorbca403c2010-01-13 23:51:12 +00001618 AddObjCExpressionResults(Results, true);
Douglas Gregor01dfea02010-01-10 23:08:15 +00001619 }
1620
Douglas Gregorc8bddde2010-05-28 00:22:41 +00001621 // sizeof expression
1622 Pattern = new CodeCompletionString;
1623 Pattern->AddTypedTextChunk("sizeof");
1624 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
1625 Pattern->AddPlaceholderChunk("expression-or-type");
1626 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
1627 Results.AddResult(Result(Pattern));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001628 break;
1629 }
Douglas Gregord32b0222010-08-24 01:06:58 +00001630
1631 case Action::PCC_Type:
1632 break;
Douglas Gregor01dfea02010-01-10 23:08:15 +00001633 }
1634
Douglas Gregor4710e5b2010-05-28 00:49:12 +00001635 if (WantTypesInContext(CCC, SemaRef.getLangOptions()))
1636 AddTypeSpecifierResults(SemaRef.getLangOptions(), Results);
Douglas Gregor01dfea02010-01-10 23:08:15 +00001637
Douglas Gregord32b0222010-08-24 01:06:58 +00001638 if (SemaRef.getLangOptions().CPlusPlus && CCC != Action::PCC_Type)
Douglas Gregora4477812010-01-14 16:01:26 +00001639 Results.AddResult(Result("operator"));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001640}
1641
Douglas Gregorff5ce6e2009-12-18 18:53:37 +00001642/// \brief If the given declaration has an associated type, add it as a result
1643/// type chunk.
1644static void AddResultTypeChunk(ASTContext &Context,
1645 NamedDecl *ND,
1646 CodeCompletionString *Result) {
1647 if (!ND)
1648 return;
1649
1650 // Determine the type of the declaration (if it has a type).
1651 QualType T;
1652 if (FunctionDecl *Function = dyn_cast<FunctionDecl>(ND))
1653 T = Function->getResultType();
1654 else if (ObjCMethodDecl *Method = dyn_cast<ObjCMethodDecl>(ND))
1655 T = Method->getResultType();
1656 else if (FunctionTemplateDecl *FunTmpl = dyn_cast<FunctionTemplateDecl>(ND))
1657 T = FunTmpl->getTemplatedDecl()->getResultType();
1658 else if (EnumConstantDecl *Enumerator = dyn_cast<EnumConstantDecl>(ND))
1659 T = Context.getTypeDeclType(cast<TypeDecl>(Enumerator->getDeclContext()));
1660 else if (isa<UnresolvedUsingValueDecl>(ND)) {
1661 /* Do nothing: ignore unresolved using declarations*/
1662 } else if (ValueDecl *Value = dyn_cast<ValueDecl>(ND))
1663 T = Value->getType();
1664 else if (ObjCPropertyDecl *Property = dyn_cast<ObjCPropertyDecl>(ND))
1665 T = Property->getType();
1666
1667 if (T.isNull() || Context.hasSameType(T, Context.DependentTy))
1668 return;
1669
Douglas Gregor84139d62010-04-05 21:25:31 +00001670 PrintingPolicy Policy(Context.PrintingPolicy);
1671 Policy.AnonymousTagLocations = false;
1672
Douglas Gregorff5ce6e2009-12-18 18:53:37 +00001673 std::string TypeStr;
Douglas Gregor84139d62010-04-05 21:25:31 +00001674 T.getAsStringInternal(TypeStr, Policy);
Douglas Gregorff5ce6e2009-12-18 18:53:37 +00001675 Result->AddResultTypeChunk(TypeStr);
1676}
1677
Douglas Gregoraaa107a2010-08-23 23:51:41 +00001678static void MaybeAddSentinel(ASTContext &Context, NamedDecl *FunctionOrMethod,
1679 CodeCompletionString *Result) {
1680 if (SentinelAttr *Sentinel = FunctionOrMethod->getAttr<SentinelAttr>())
1681 if (Sentinel->getSentinel() == 0) {
1682 if (Context.getLangOptions().ObjC1 &&
1683 Context.Idents.get("nil").hasMacroDefinition())
1684 Result->AddTextChunk(", nil");
1685 else if (Context.Idents.get("NULL").hasMacroDefinition())
1686 Result->AddTextChunk(", NULL");
1687 else
1688 Result->AddTextChunk(", (void*)0");
1689 }
1690}
1691
Douglas Gregor86d9a522009-09-21 16:56:56 +00001692/// \brief Add function parameter chunks to the given code completion string.
1693static void AddFunctionParameterChunks(ASTContext &Context,
1694 FunctionDecl *Function,
1695 CodeCompletionString *Result) {
Douglas Gregor0c8296d2009-11-07 00:00:49 +00001696 typedef CodeCompletionString::Chunk Chunk;
1697
Douglas Gregor86d9a522009-09-21 16:56:56 +00001698 CodeCompletionString *CCStr = Result;
1699
1700 for (unsigned P = 0, N = Function->getNumParams(); P != N; ++P) {
1701 ParmVarDecl *Param = Function->getParamDecl(P);
1702
1703 if (Param->hasDefaultArg()) {
1704 // When we see an optional default argument, put that argument and
1705 // the remaining default arguments into a new, optional string.
1706 CodeCompletionString *Opt = new CodeCompletionString;
1707 CCStr->AddOptionalChunk(std::auto_ptr<CodeCompletionString>(Opt));
1708 CCStr = Opt;
1709 }
1710
1711 if (P != 0)
Douglas Gregor0c8296d2009-11-07 00:00:49 +00001712 CCStr->AddChunk(Chunk(CodeCompletionString::CK_Comma));
Douglas Gregor86d9a522009-09-21 16:56:56 +00001713
1714 // Format the placeholder string.
1715 std::string PlaceholderStr;
1716 if (Param->getIdentifier())
1717 PlaceholderStr = Param->getIdentifier()->getName();
1718
1719 Param->getType().getAsStringInternal(PlaceholderStr,
1720 Context.PrintingPolicy);
1721
1722 // Add the placeholder string.
Benjamin Kramer660cc182009-11-29 20:18:50 +00001723 CCStr->AddPlaceholderChunk(PlaceholderStr);
Douglas Gregor86d9a522009-09-21 16:56:56 +00001724 }
Douglas Gregorb3d45252009-09-22 21:42:17 +00001725
1726 if (const FunctionProtoType *Proto
1727 = Function->getType()->getAs<FunctionProtoType>())
Douglas Gregoraaa107a2010-08-23 23:51:41 +00001728 if (Proto->isVariadic()) {
Douglas Gregorb3d45252009-09-22 21:42:17 +00001729 CCStr->AddPlaceholderChunk(", ...");
Douglas Gregoraaa107a2010-08-23 23:51:41 +00001730
1731 MaybeAddSentinel(Context, Function, CCStr);
1732 }
Douglas Gregor86d9a522009-09-21 16:56:56 +00001733}
1734
1735/// \brief Add template parameter chunks to the given code completion string.
1736static void AddTemplateParameterChunks(ASTContext &Context,
1737 TemplateDecl *Template,
1738 CodeCompletionString *Result,
1739 unsigned MaxParameters = 0) {
Douglas Gregor0c8296d2009-11-07 00:00:49 +00001740 typedef CodeCompletionString::Chunk Chunk;
1741
Douglas Gregor86d9a522009-09-21 16:56:56 +00001742 CodeCompletionString *CCStr = Result;
1743 bool FirstParameter = true;
1744
1745 TemplateParameterList *Params = Template->getTemplateParameters();
1746 TemplateParameterList::iterator PEnd = Params->end();
1747 if (MaxParameters)
1748 PEnd = Params->begin() + MaxParameters;
1749 for (TemplateParameterList::iterator P = Params->begin(); P != PEnd; ++P) {
1750 bool HasDefaultArg = false;
1751 std::string PlaceholderStr;
1752 if (TemplateTypeParmDecl *TTP = dyn_cast<TemplateTypeParmDecl>(*P)) {
1753 if (TTP->wasDeclaredWithTypename())
1754 PlaceholderStr = "typename";
1755 else
1756 PlaceholderStr = "class";
1757
1758 if (TTP->getIdentifier()) {
1759 PlaceholderStr += ' ';
1760 PlaceholderStr += TTP->getIdentifier()->getName();
1761 }
1762
1763 HasDefaultArg = TTP->hasDefaultArgument();
1764 } else if (NonTypeTemplateParmDecl *NTTP
1765 = dyn_cast<NonTypeTemplateParmDecl>(*P)) {
1766 if (NTTP->getIdentifier())
1767 PlaceholderStr = NTTP->getIdentifier()->getName();
1768 NTTP->getType().getAsStringInternal(PlaceholderStr,
1769 Context.PrintingPolicy);
1770 HasDefaultArg = NTTP->hasDefaultArgument();
1771 } else {
1772 assert(isa<TemplateTemplateParmDecl>(*P));
1773 TemplateTemplateParmDecl *TTP = cast<TemplateTemplateParmDecl>(*P);
1774
1775 // Since putting the template argument list into the placeholder would
1776 // be very, very long, we just use an abbreviation.
1777 PlaceholderStr = "template<...> class";
1778 if (TTP->getIdentifier()) {
1779 PlaceholderStr += ' ';
1780 PlaceholderStr += TTP->getIdentifier()->getName();
1781 }
1782
1783 HasDefaultArg = TTP->hasDefaultArgument();
1784 }
1785
1786 if (HasDefaultArg) {
1787 // When we see an optional default argument, put that argument and
1788 // the remaining default arguments into a new, optional string.
1789 CodeCompletionString *Opt = new CodeCompletionString;
1790 CCStr->AddOptionalChunk(std::auto_ptr<CodeCompletionString>(Opt));
1791 CCStr = Opt;
1792 }
1793
1794 if (FirstParameter)
1795 FirstParameter = false;
1796 else
Douglas Gregor0c8296d2009-11-07 00:00:49 +00001797 CCStr->AddChunk(Chunk(CodeCompletionString::CK_Comma));
Douglas Gregor86d9a522009-09-21 16:56:56 +00001798
1799 // Add the placeholder string.
Benjamin Kramer660cc182009-11-29 20:18:50 +00001800 CCStr->AddPlaceholderChunk(PlaceholderStr);
Douglas Gregor86d9a522009-09-21 16:56:56 +00001801 }
1802}
1803
Douglas Gregorb9d0ef72009-09-21 19:57:38 +00001804/// \brief Add a qualifier to the given code-completion string, if the
1805/// provided nested-name-specifier is non-NULL.
Douglas Gregora61a8792009-12-11 18:44:16 +00001806static void
1807AddQualifierToCompletionString(CodeCompletionString *Result,
1808 NestedNameSpecifier *Qualifier,
1809 bool QualifierIsInformative,
1810 ASTContext &Context) {
Douglas Gregorb9d0ef72009-09-21 19:57:38 +00001811 if (!Qualifier)
1812 return;
1813
1814 std::string PrintedNNS;
1815 {
1816 llvm::raw_string_ostream OS(PrintedNNS);
1817 Qualifier->print(OS, Context.PrintingPolicy);
1818 }
Douglas Gregor0563c262009-09-22 23:15:58 +00001819 if (QualifierIsInformative)
Benjamin Kramer660cc182009-11-29 20:18:50 +00001820 Result->AddInformativeChunk(PrintedNNS);
Douglas Gregor0563c262009-09-22 23:15:58 +00001821 else
Benjamin Kramer660cc182009-11-29 20:18:50 +00001822 Result->AddTextChunk(PrintedNNS);
Douglas Gregorb9d0ef72009-09-21 19:57:38 +00001823}
1824
Douglas Gregora61a8792009-12-11 18:44:16 +00001825static void AddFunctionTypeQualsToCompletionString(CodeCompletionString *Result,
1826 FunctionDecl *Function) {
1827 const FunctionProtoType *Proto
1828 = Function->getType()->getAs<FunctionProtoType>();
1829 if (!Proto || !Proto->getTypeQuals())
1830 return;
1831
1832 std::string QualsStr;
1833 if (Proto->getTypeQuals() & Qualifiers::Const)
1834 QualsStr += " const";
1835 if (Proto->getTypeQuals() & Qualifiers::Volatile)
1836 QualsStr += " volatile";
1837 if (Proto->getTypeQuals() & Qualifiers::Restrict)
1838 QualsStr += " restrict";
1839 Result->AddInformativeChunk(QualsStr);
1840}
1841
Douglas Gregor86d9a522009-09-21 16:56:56 +00001842/// \brief If possible, create a new code completion string for the given
1843/// result.
1844///
1845/// \returns Either a new, heap-allocated code completion string describing
1846/// how to use this result, or NULL to indicate that the string or name of the
1847/// result is all that is needed.
1848CodeCompletionString *
Douglas Gregor1abc6bc2010-08-04 16:47:14 +00001849CodeCompleteConsumer::Result::CreateCodeCompletionString(Sema &S,
1850 CodeCompletionString *Result) {
Douglas Gregor0c8296d2009-11-07 00:00:49 +00001851 typedef CodeCompletionString::Chunk Chunk;
1852
Douglas Gregor2b4074f2009-12-01 05:55:20 +00001853 if (Kind == RK_Pattern)
Douglas Gregor1abc6bc2010-08-04 16:47:14 +00001854 return Pattern->Clone(Result);
Douglas Gregor2b4074f2009-12-01 05:55:20 +00001855
Douglas Gregor1abc6bc2010-08-04 16:47:14 +00001856 if (!Result)
1857 Result = new CodeCompletionString;
Douglas Gregor2b4074f2009-12-01 05:55:20 +00001858
1859 if (Kind == RK_Keyword) {
1860 Result->AddTypedTextChunk(Keyword);
1861 return Result;
1862 }
Douglas Gregor86d9a522009-09-21 16:56:56 +00001863
Douglas Gregor3f7c7f42009-10-30 16:50:04 +00001864 if (Kind == RK_Macro) {
1865 MacroInfo *MI = S.PP.getMacroInfo(Macro);
Douglas Gregor2b4074f2009-12-01 05:55:20 +00001866 assert(MI && "Not a macro?");
1867
1868 Result->AddTypedTextChunk(Macro->getName());
1869
1870 if (!MI->isFunctionLike())
1871 return Result;
Douglas Gregor3f7c7f42009-10-30 16:50:04 +00001872
1873 // Format a function-like macro with placeholders for the arguments.
Douglas Gregor0c8296d2009-11-07 00:00:49 +00001874 Result->AddChunk(Chunk(CodeCompletionString::CK_LeftParen));
Douglas Gregor3f7c7f42009-10-30 16:50:04 +00001875 for (MacroInfo::arg_iterator A = MI->arg_begin(), AEnd = MI->arg_end();
1876 A != AEnd; ++A) {
1877 if (A != MI->arg_begin())
Douglas Gregor0c8296d2009-11-07 00:00:49 +00001878 Result->AddChunk(Chunk(CodeCompletionString::CK_Comma));
Douglas Gregor3f7c7f42009-10-30 16:50:04 +00001879
1880 if (!MI->isVariadic() || A != AEnd - 1) {
1881 // Non-variadic argument.
Benjamin Kramer660cc182009-11-29 20:18:50 +00001882 Result->AddPlaceholderChunk((*A)->getName());
Douglas Gregor3f7c7f42009-10-30 16:50:04 +00001883 continue;
1884 }
1885
1886 // Variadic argument; cope with the different between GNU and C99
1887 // variadic macros, providing a single placeholder for the rest of the
1888 // arguments.
1889 if ((*A)->isStr("__VA_ARGS__"))
1890 Result->AddPlaceholderChunk("...");
1891 else {
1892 std::string Arg = (*A)->getName();
1893 Arg += "...";
Benjamin Kramer660cc182009-11-29 20:18:50 +00001894 Result->AddPlaceholderChunk(Arg);
Douglas Gregor3f7c7f42009-10-30 16:50:04 +00001895 }
1896 }
Douglas Gregor0c8296d2009-11-07 00:00:49 +00001897 Result->AddChunk(Chunk(CodeCompletionString::CK_RightParen));
Douglas Gregor3f7c7f42009-10-30 16:50:04 +00001898 return Result;
1899 }
1900
Douglas Gregord8e8a582010-05-25 21:41:55 +00001901 assert(Kind == RK_Declaration && "Missed a result kind?");
Douglas Gregor86d9a522009-09-21 16:56:56 +00001902 NamedDecl *ND = Declaration;
1903
Douglas Gregor0c8296d2009-11-07 00:00:49 +00001904 if (StartsNestedNameSpecifier) {
Benjamin Kramer660cc182009-11-29 20:18:50 +00001905 Result->AddTypedTextChunk(ND->getNameAsString());
Douglas Gregor0c8296d2009-11-07 00:00:49 +00001906 Result->AddTextChunk("::");
1907 return Result;
1908 }
1909
Douglas Gregorff5ce6e2009-12-18 18:53:37 +00001910 AddResultTypeChunk(S.Context, ND, Result);
1911
Douglas Gregor86d9a522009-09-21 16:56:56 +00001912 if (FunctionDecl *Function = dyn_cast<FunctionDecl>(ND)) {
Douglas Gregor0563c262009-09-22 23:15:58 +00001913 AddQualifierToCompletionString(Result, Qualifier, QualifierIsInformative,
1914 S.Context);
Benjamin Kramer660cc182009-11-29 20:18:50 +00001915 Result->AddTypedTextChunk(Function->getNameAsString());
Douglas Gregor0c8296d2009-11-07 00:00:49 +00001916 Result->AddChunk(Chunk(CodeCompletionString::CK_LeftParen));
Douglas Gregor86d9a522009-09-21 16:56:56 +00001917 AddFunctionParameterChunks(S.Context, Function, Result);
Douglas Gregor0c8296d2009-11-07 00:00:49 +00001918 Result->AddChunk(Chunk(CodeCompletionString::CK_RightParen));
Douglas Gregora61a8792009-12-11 18:44:16 +00001919 AddFunctionTypeQualsToCompletionString(Result, Function);
Douglas Gregor86d9a522009-09-21 16:56:56 +00001920 return Result;
1921 }
1922
1923 if (FunctionTemplateDecl *FunTmpl = dyn_cast<FunctionTemplateDecl>(ND)) {
Douglas Gregor0563c262009-09-22 23:15:58 +00001924 AddQualifierToCompletionString(Result, Qualifier, QualifierIsInformative,
1925 S.Context);
Douglas Gregor86d9a522009-09-21 16:56:56 +00001926 FunctionDecl *Function = FunTmpl->getTemplatedDecl();
Benjamin Kramer660cc182009-11-29 20:18:50 +00001927 Result->AddTypedTextChunk(Function->getNameAsString());
Douglas Gregor86d9a522009-09-21 16:56:56 +00001928
1929 // Figure out which template parameters are deduced (or have default
1930 // arguments).
1931 llvm::SmallVector<bool, 16> Deduced;
1932 S.MarkDeducedTemplateParameters(FunTmpl, Deduced);
1933 unsigned LastDeducibleArgument;
1934 for (LastDeducibleArgument = Deduced.size(); LastDeducibleArgument > 0;
1935 --LastDeducibleArgument) {
1936 if (!Deduced[LastDeducibleArgument - 1]) {
1937 // C++0x: Figure out if the template argument has a default. If so,
1938 // the user doesn't need to type this argument.
1939 // FIXME: We need to abstract template parameters better!
1940 bool HasDefaultArg = false;
1941 NamedDecl *Param = FunTmpl->getTemplateParameters()->getParam(
1942 LastDeducibleArgument - 1);
1943 if (TemplateTypeParmDecl *TTP = dyn_cast<TemplateTypeParmDecl>(Param))
1944 HasDefaultArg = TTP->hasDefaultArgument();
1945 else if (NonTypeTemplateParmDecl *NTTP
1946 = dyn_cast<NonTypeTemplateParmDecl>(Param))
1947 HasDefaultArg = NTTP->hasDefaultArgument();
1948 else {
1949 assert(isa<TemplateTemplateParmDecl>(Param));
1950 HasDefaultArg
Douglas Gregor0c8296d2009-11-07 00:00:49 +00001951 = cast<TemplateTemplateParmDecl>(Param)->hasDefaultArgument();
Douglas Gregor86d9a522009-09-21 16:56:56 +00001952 }
1953
1954 if (!HasDefaultArg)
1955 break;
1956 }
1957 }
1958
1959 if (LastDeducibleArgument) {
1960 // Some of the function template arguments cannot be deduced from a
1961 // function call, so we introduce an explicit template argument list
1962 // containing all of the arguments up to the first deducible argument.
Douglas Gregor0c8296d2009-11-07 00:00:49 +00001963 Result->AddChunk(Chunk(CodeCompletionString::CK_LeftAngle));
Douglas Gregor86d9a522009-09-21 16:56:56 +00001964 AddTemplateParameterChunks(S.Context, FunTmpl, Result,
1965 LastDeducibleArgument);
Douglas Gregor0c8296d2009-11-07 00:00:49 +00001966 Result->AddChunk(Chunk(CodeCompletionString::CK_RightAngle));
Douglas Gregor86d9a522009-09-21 16:56:56 +00001967 }
1968
1969 // Add the function parameters
Douglas Gregor0c8296d2009-11-07 00:00:49 +00001970 Result->AddChunk(Chunk(CodeCompletionString::CK_LeftParen));
Douglas Gregor86d9a522009-09-21 16:56:56 +00001971 AddFunctionParameterChunks(S.Context, Function, Result);
Douglas Gregor0c8296d2009-11-07 00:00:49 +00001972 Result->AddChunk(Chunk(CodeCompletionString::CK_RightParen));
Douglas Gregora61a8792009-12-11 18:44:16 +00001973 AddFunctionTypeQualsToCompletionString(Result, Function);
Douglas Gregor86d9a522009-09-21 16:56:56 +00001974 return Result;
1975 }
1976
1977 if (TemplateDecl *Template = dyn_cast<TemplateDecl>(ND)) {
Douglas Gregor0563c262009-09-22 23:15:58 +00001978 AddQualifierToCompletionString(Result, Qualifier, QualifierIsInformative,
1979 S.Context);
Benjamin Kramer660cc182009-11-29 20:18:50 +00001980 Result->AddTypedTextChunk(Template->getNameAsString());
Douglas Gregor0c8296d2009-11-07 00:00:49 +00001981 Result->AddChunk(Chunk(CodeCompletionString::CK_LeftAngle));
Douglas Gregor86d9a522009-09-21 16:56:56 +00001982 AddTemplateParameterChunks(S.Context, Template, Result);
Douglas Gregor0c8296d2009-11-07 00:00:49 +00001983 Result->AddChunk(Chunk(CodeCompletionString::CK_RightAngle));
Douglas Gregor86d9a522009-09-21 16:56:56 +00001984 return Result;
1985 }
1986
Douglas Gregor9630eb62009-11-17 16:44:22 +00001987 if (ObjCMethodDecl *Method = dyn_cast<ObjCMethodDecl>(ND)) {
Douglas Gregor9630eb62009-11-17 16:44:22 +00001988 Selector Sel = Method->getSelector();
1989 if (Sel.isUnarySelector()) {
1990 Result->AddTypedTextChunk(Sel.getIdentifierInfoForSlot(0)->getName());
1991 return Result;
1992 }
1993
Douglas Gregord3c68542009-11-19 01:08:35 +00001994 std::string SelName = Sel.getIdentifierInfoForSlot(0)->getName().str();
1995 SelName += ':';
1996 if (StartParameter == 0)
1997 Result->AddTypedTextChunk(SelName);
1998 else {
1999 Result->AddInformativeChunk(SelName);
2000
2001 // If there is only one parameter, and we're past it, add an empty
2002 // typed-text chunk since there is nothing to type.
2003 if (Method->param_size() == 1)
2004 Result->AddTypedTextChunk("");
2005 }
Douglas Gregor9630eb62009-11-17 16:44:22 +00002006 unsigned Idx = 0;
2007 for (ObjCMethodDecl::param_iterator P = Method->param_begin(),
2008 PEnd = Method->param_end();
2009 P != PEnd; (void)++P, ++Idx) {
2010 if (Idx > 0) {
Douglas Gregord3c68542009-11-19 01:08:35 +00002011 std::string Keyword;
2012 if (Idx > StartParameter)
Douglas Gregor834389b2010-01-12 06:38:28 +00002013 Result->AddChunk(CodeCompletionString::CK_HorizontalSpace);
Douglas Gregor9630eb62009-11-17 16:44:22 +00002014 if (IdentifierInfo *II = Sel.getIdentifierInfoForSlot(Idx))
2015 Keyword += II->getName().str();
2016 Keyword += ":";
Douglas Gregor1f5537a2010-07-08 23:20:03 +00002017 if (Idx < StartParameter || AllParametersAreInformative)
Douglas Gregord3c68542009-11-19 01:08:35 +00002018 Result->AddInformativeChunk(Keyword);
Douglas Gregor1f5537a2010-07-08 23:20:03 +00002019 else if (Idx == StartParameter)
Douglas Gregord3c68542009-11-19 01:08:35 +00002020 Result->AddTypedTextChunk(Keyword);
2021 else
2022 Result->AddTextChunk(Keyword);
Douglas Gregor9630eb62009-11-17 16:44:22 +00002023 }
Douglas Gregord3c68542009-11-19 01:08:35 +00002024
2025 // If we're before the starting parameter, skip the placeholder.
2026 if (Idx < StartParameter)
2027 continue;
Douglas Gregor9630eb62009-11-17 16:44:22 +00002028
2029 std::string Arg;
2030 (*P)->getType().getAsStringInternal(Arg, S.Context.PrintingPolicy);
2031 Arg = "(" + Arg + ")";
2032 if (IdentifierInfo *II = (*P)->getIdentifier())
2033 Arg += II->getName().str();
Douglas Gregor1f5537a2010-07-08 23:20:03 +00002034 if (DeclaringEntity)
2035 Result->AddTextChunk(Arg);
2036 else if (AllParametersAreInformative)
Douglas Gregor4ad96852009-11-19 07:41:15 +00002037 Result->AddInformativeChunk(Arg);
2038 else
2039 Result->AddPlaceholderChunk(Arg);
Douglas Gregor9630eb62009-11-17 16:44:22 +00002040 }
2041
Douglas Gregor2a17af02009-12-23 00:21:46 +00002042 if (Method->isVariadic()) {
Douglas Gregor1f5537a2010-07-08 23:20:03 +00002043 if (DeclaringEntity)
2044 Result->AddTextChunk(", ...");
2045 else if (AllParametersAreInformative)
Douglas Gregor2a17af02009-12-23 00:21:46 +00002046 Result->AddInformativeChunk(", ...");
2047 else
2048 Result->AddPlaceholderChunk(", ...");
Douglas Gregoraaa107a2010-08-23 23:51:41 +00002049
2050 MaybeAddSentinel(S.Context, Method, Result);
Douglas Gregor2a17af02009-12-23 00:21:46 +00002051 }
2052
Douglas Gregor9630eb62009-11-17 16:44:22 +00002053 return Result;
2054 }
2055
Douglas Gregor2b4074f2009-12-01 05:55:20 +00002056 if (Qualifier)
Douglas Gregor0563c262009-09-22 23:15:58 +00002057 AddQualifierToCompletionString(Result, Qualifier, QualifierIsInformative,
2058 S.Context);
Douglas Gregor2b4074f2009-12-01 05:55:20 +00002059
2060 Result->AddTypedTextChunk(ND->getNameAsString());
2061 return Result;
Douglas Gregor86d9a522009-09-21 16:56:56 +00002062}
2063
Douglas Gregor86d802e2009-09-23 00:34:09 +00002064CodeCompletionString *
2065CodeCompleteConsumer::OverloadCandidate::CreateSignatureString(
2066 unsigned CurrentArg,
2067 Sema &S) const {
Douglas Gregor0c8296d2009-11-07 00:00:49 +00002068 typedef CodeCompletionString::Chunk Chunk;
2069
Douglas Gregor86d802e2009-09-23 00:34:09 +00002070 CodeCompletionString *Result = new CodeCompletionString;
2071 FunctionDecl *FDecl = getFunction();
Douglas Gregorff5ce6e2009-12-18 18:53:37 +00002072 AddResultTypeChunk(S.Context, FDecl, Result);
Douglas Gregor86d802e2009-09-23 00:34:09 +00002073 const FunctionProtoType *Proto
2074 = dyn_cast<FunctionProtoType>(getFunctionType());
2075 if (!FDecl && !Proto) {
2076 // Function without a prototype. Just give the return type and a
2077 // highlighted ellipsis.
2078 const FunctionType *FT = getFunctionType();
2079 Result->AddTextChunk(
Benjamin Kramer660cc182009-11-29 20:18:50 +00002080 FT->getResultType().getAsString(S.Context.PrintingPolicy));
Douglas Gregor0c8296d2009-11-07 00:00:49 +00002081 Result->AddChunk(Chunk(CodeCompletionString::CK_LeftParen));
2082 Result->AddChunk(Chunk(CodeCompletionString::CK_CurrentParameter, "..."));
2083 Result->AddChunk(Chunk(CodeCompletionString::CK_RightParen));
Douglas Gregor86d802e2009-09-23 00:34:09 +00002084 return Result;
2085 }
2086
2087 if (FDecl)
Benjamin Kramer660cc182009-11-29 20:18:50 +00002088 Result->AddTextChunk(FDecl->getNameAsString());
Douglas Gregor86d802e2009-09-23 00:34:09 +00002089 else
2090 Result->AddTextChunk(
Benjamin Kramer660cc182009-11-29 20:18:50 +00002091 Proto->getResultType().getAsString(S.Context.PrintingPolicy));
Douglas Gregor86d802e2009-09-23 00:34:09 +00002092
Douglas Gregor0c8296d2009-11-07 00:00:49 +00002093 Result->AddChunk(Chunk(CodeCompletionString::CK_LeftParen));
Douglas Gregor86d802e2009-09-23 00:34:09 +00002094 unsigned NumParams = FDecl? FDecl->getNumParams() : Proto->getNumArgs();
2095 for (unsigned I = 0; I != NumParams; ++I) {
2096 if (I)
Douglas Gregor0c8296d2009-11-07 00:00:49 +00002097 Result->AddChunk(Chunk(CodeCompletionString::CK_Comma));
Douglas Gregor86d802e2009-09-23 00:34:09 +00002098
2099 std::string ArgString;
2100 QualType ArgType;
2101
2102 if (FDecl) {
2103 ArgString = FDecl->getParamDecl(I)->getNameAsString();
2104 ArgType = FDecl->getParamDecl(I)->getOriginalType();
2105 } else {
2106 ArgType = Proto->getArgType(I);
2107 }
2108
2109 ArgType.getAsStringInternal(ArgString, S.Context.PrintingPolicy);
2110
2111 if (I == CurrentArg)
Douglas Gregor0c8296d2009-11-07 00:00:49 +00002112 Result->AddChunk(Chunk(CodeCompletionString::CK_CurrentParameter,
Benjamin Kramer660cc182009-11-29 20:18:50 +00002113 ArgString));
Douglas Gregor86d802e2009-09-23 00:34:09 +00002114 else
Benjamin Kramer660cc182009-11-29 20:18:50 +00002115 Result->AddTextChunk(ArgString);
Douglas Gregor86d802e2009-09-23 00:34:09 +00002116 }
2117
2118 if (Proto && Proto->isVariadic()) {
Douglas Gregor0c8296d2009-11-07 00:00:49 +00002119 Result->AddChunk(Chunk(CodeCompletionString::CK_Comma));
Douglas Gregor86d802e2009-09-23 00:34:09 +00002120 if (CurrentArg < NumParams)
2121 Result->AddTextChunk("...");
2122 else
Douglas Gregor0c8296d2009-11-07 00:00:49 +00002123 Result->AddChunk(Chunk(CodeCompletionString::CK_CurrentParameter, "..."));
Douglas Gregor86d802e2009-09-23 00:34:09 +00002124 }
Douglas Gregor0c8296d2009-11-07 00:00:49 +00002125 Result->AddChunk(Chunk(CodeCompletionString::CK_RightParen));
Douglas Gregor86d802e2009-09-23 00:34:09 +00002126
2127 return Result;
2128}
2129
Douglas Gregor86d9a522009-09-21 16:56:56 +00002130namespace {
2131 struct SortCodeCompleteResult {
2132 typedef CodeCompleteConsumer::Result Result;
2133
Douglas Gregorab0b4f12010-01-13 23:24:38 +00002134 /// \brief Retrieve the name that should be used to order a result.
2135 ///
2136 /// If the name needs to be constructed as a string, that string will be
2137 /// saved into Saved and the returned StringRef will refer to it.
2138 static llvm::StringRef getOrderedName(const Result &R,
2139 std::string &Saved) {
2140 switch (R.Kind) {
2141 case Result::RK_Keyword:
2142 return R.Keyword;
2143
2144 case Result::RK_Pattern:
2145 return R.Pattern->getTypedText();
2146
2147 case Result::RK_Macro:
2148 return R.Macro->getName();
2149
2150 case Result::RK_Declaration:
2151 // Handle declarations below.
2152 break;
Douglas Gregor54f01612009-11-19 00:01:57 +00002153 }
Douglas Gregorab0b4f12010-01-13 23:24:38 +00002154
2155 DeclarationName Name = R.Declaration->getDeclName();
Douglas Gregor54f01612009-11-19 00:01:57 +00002156
Douglas Gregorab0b4f12010-01-13 23:24:38 +00002157 // If the name is a simple identifier (by far the common case), or a
2158 // zero-argument selector, just return a reference to that identifier.
2159 if (IdentifierInfo *Id = Name.getAsIdentifierInfo())
2160 return Id->getName();
2161 if (Name.isObjCZeroArgSelector())
2162 if (IdentifierInfo *Id
2163 = Name.getObjCSelector().getIdentifierInfoForSlot(0))
2164 return Id->getName();
2165
2166 Saved = Name.getAsString();
2167 return Saved;
2168 }
2169
2170 bool operator()(const Result &X, const Result &Y) const {
2171 std::string XSaved, YSaved;
2172 llvm::StringRef XStr = getOrderedName(X, XSaved);
2173 llvm::StringRef YStr = getOrderedName(Y, YSaved);
2174 int cmp = XStr.compare_lower(YStr);
2175 if (cmp)
2176 return cmp < 0;
Douglas Gregor86d9a522009-09-21 16:56:56 +00002177
2178 // Non-hidden names precede hidden names.
2179 if (X.Hidden != Y.Hidden)
2180 return !X.Hidden;
2181
Douglas Gregoreb5758b2009-09-23 22:26:46 +00002182 // Non-nested-name-specifiers precede nested-name-specifiers.
2183 if (X.StartsNestedNameSpecifier != Y.StartsNestedNameSpecifier)
2184 return !X.StartsNestedNameSpecifier;
2185
Douglas Gregor86d9a522009-09-21 16:56:56 +00002186 return false;
2187 }
2188 };
2189}
2190
Douglas Gregor1827e102010-08-16 16:18:59 +00002191unsigned clang::getMacroUsagePriority(llvm::StringRef MacroName,
2192 bool PreferredTypeIsPointer) {
2193 unsigned Priority = CCP_Macro;
2194
2195 // Treat the "nil" and "NULL" macros as null pointer constants.
2196 if (MacroName.equals("nil") || MacroName.equals("NULL")) {
2197 Priority = CCP_Constant;
2198 if (PreferredTypeIsPointer)
2199 Priority = Priority / CCF_SimilarTypeMatch;
2200 }
2201
2202 return Priority;
2203}
2204
Douglas Gregor590c7d52010-07-08 20:55:51 +00002205static void AddMacroResults(Preprocessor &PP, ResultBuilder &Results,
2206 bool TargetTypeIsPointer = false) {
2207 typedef CodeCompleteConsumer::Result Result;
2208
Douglas Gregor3f7c7f42009-10-30 16:50:04 +00002209 Results.EnterNewScope();
Douglas Gregor0c8296d2009-11-07 00:00:49 +00002210 for (Preprocessor::macro_iterator M = PP.macro_begin(),
2211 MEnd = PP.macro_end();
Douglas Gregor590c7d52010-07-08 20:55:51 +00002212 M != MEnd; ++M) {
Douglas Gregor1827e102010-08-16 16:18:59 +00002213 Results.AddResult(Result(M->first,
2214 getMacroUsagePriority(M->first->getName(),
2215 TargetTypeIsPointer)));
Douglas Gregor590c7d52010-07-08 20:55:51 +00002216 }
Douglas Gregor3f7c7f42009-10-30 16:50:04 +00002217 Results.ExitScope();
2218}
2219
Douglas Gregoraa5f77b2010-08-23 21:54:33 +00002220static void AddPrettyFunctionResults(const LangOptions &LangOpts,
2221 ResultBuilder &Results) {
2222 typedef CodeCompleteConsumer::Result Result;
2223
2224 Results.EnterNewScope();
2225 Results.AddResult(Result("__PRETTY_FUNCTION__", CCP_Constant));
2226 Results.AddResult(Result("__FUNCTION__", CCP_Constant));
2227 if (LangOpts.C99 || LangOpts.CPlusPlus0x)
2228 Results.AddResult(Result("__func__", CCP_Constant));
2229 Results.ExitScope();
2230}
2231
Daniel Dunbar3a2838d2009-11-13 08:58:20 +00002232static void HandleCodeCompleteResults(Sema *S,
2233 CodeCompleteConsumer *CodeCompleter,
Douglas Gregore6b1bb62010-08-11 21:23:17 +00002234 CodeCompletionContext Context,
2235 CodeCompleteConsumer::Result *Results,
2236 unsigned NumResults) {
Douglas Gregor86d9a522009-09-21 16:56:56 +00002237 std::stable_sort(Results, Results + NumResults, SortCodeCompleteResult());
2238
2239 if (CodeCompleter)
Douglas Gregore6b1bb62010-08-11 21:23:17 +00002240 CodeCompleter->ProcessCodeCompleteResults(*S, Context, Results, NumResults);
Douglas Gregor54f01612009-11-19 00:01:57 +00002241
2242 for (unsigned I = 0; I != NumResults; ++I)
2243 Results[I].Destroy();
Douglas Gregor86d9a522009-09-21 16:56:56 +00002244}
2245
Douglas Gregore6b1bb62010-08-11 21:23:17 +00002246static enum CodeCompletionContext::Kind mapCodeCompletionContext(Sema &S,
2247 Sema::ParserCompletionContext PCC) {
2248 switch (PCC) {
2249 case Action::PCC_Namespace:
2250 return CodeCompletionContext::CCC_TopLevel;
2251
2252 case Action::PCC_Class:
2253 return CodeCompletionContext::CCC_ClassStructUnion;
2254
2255 case Action::PCC_ObjCInterface:
2256 return CodeCompletionContext::CCC_ObjCInterface;
2257
2258 case Action::PCC_ObjCImplementation:
2259 return CodeCompletionContext::CCC_ObjCImplementation;
2260
2261 case Action::PCC_ObjCInstanceVariableList:
2262 return CodeCompletionContext::CCC_ObjCIvarList;
2263
2264 case Action::PCC_Template:
2265 case Action::PCC_MemberTemplate:
2266 case Action::PCC_RecoveryInFunction:
2267 return CodeCompletionContext::CCC_Other;
2268
2269 case Action::PCC_Expression:
2270 case Action::PCC_ForInit:
2271 case Action::PCC_Condition:
2272 return CodeCompletionContext::CCC_Expression;
2273
2274 case Action::PCC_Statement:
2275 return CodeCompletionContext::CCC_Statement;
Douglas Gregor72db1082010-08-24 01:11:00 +00002276
2277 case Action::PCC_Type:
2278 return CodeCompletionContext::CCC_Type;
Douglas Gregore6b1bb62010-08-11 21:23:17 +00002279 }
2280
2281 return CodeCompletionContext::CCC_Other;
2282}
2283
Douglas Gregor01dfea02010-01-10 23:08:15 +00002284void Sema::CodeCompleteOrdinaryName(Scope *S,
Douglas Gregore6b1bb62010-08-11 21:23:17 +00002285 ParserCompletionContext CompletionContext) {
Douglas Gregor2a7925c2009-12-07 09:54:55 +00002286 typedef CodeCompleteConsumer::Result Result;
Douglas Gregor2ccccb32010-08-23 18:23:48 +00002287 ResultBuilder Results(*this);
Douglas Gregor01dfea02010-01-10 23:08:15 +00002288
2289 // Determine how to filter results, e.g., so that the names of
2290 // values (functions, enumerators, function templates, etc.) are
2291 // only allowed where we can have an expression.
2292 switch (CompletionContext) {
Douglas Gregore6b1bb62010-08-11 21:23:17 +00002293 case PCC_Namespace:
2294 case PCC_Class:
2295 case PCC_ObjCInterface:
2296 case PCC_ObjCImplementation:
2297 case PCC_ObjCInstanceVariableList:
2298 case PCC_Template:
2299 case PCC_MemberTemplate:
Douglas Gregor72db1082010-08-24 01:11:00 +00002300 case PCC_Type:
Douglas Gregor01dfea02010-01-10 23:08:15 +00002301 Results.setFilter(&ResultBuilder::IsOrdinaryNonValueName);
2302 break;
2303
Douglas Gregore6b1bb62010-08-11 21:23:17 +00002304 case PCC_Expression:
2305 case PCC_Statement:
2306 case PCC_ForInit:
2307 case PCC_Condition:
Douglas Gregor4710e5b2010-05-28 00:49:12 +00002308 if (WantTypesInContext(CompletionContext, getLangOptions()))
2309 Results.setFilter(&ResultBuilder::IsOrdinaryName);
2310 else
2311 Results.setFilter(&ResultBuilder::IsOrdinaryNonTypeName);
Douglas Gregor01dfea02010-01-10 23:08:15 +00002312 break;
Douglas Gregordc845342010-05-25 05:58:43 +00002313
Douglas Gregore6b1bb62010-08-11 21:23:17 +00002314 case PCC_RecoveryInFunction:
Douglas Gregordc845342010-05-25 05:58:43 +00002315 // Unfiltered
2316 break;
Douglas Gregor01dfea02010-01-10 23:08:15 +00002317 }
2318
Douglas Gregor1ca6ae82010-01-14 01:09:38 +00002319 CodeCompletionDeclConsumer Consumer(Results, CurContext);
Douglas Gregor8071e422010-08-15 06:18:01 +00002320 LookupVisibleDecls(S, LookupOrdinaryName, Consumer,
2321 CodeCompleter->includeGlobals());
Douglas Gregor2a7925c2009-12-07 09:54:55 +00002322
2323 Results.EnterNewScope();
Douglas Gregorbca403c2010-01-13 23:51:12 +00002324 AddOrdinaryNameResults(CompletionContext, S, *this, Results);
Douglas Gregor2a7925c2009-12-07 09:54:55 +00002325 Results.ExitScope();
2326
Douglas Gregoraa5f77b2010-08-23 21:54:33 +00002327 switch (CompletionContext) {
Douglas Gregor72db1082010-08-24 01:11:00 +00002328 case PCC_Expression:
2329 case PCC_Statement:
2330 case PCC_RecoveryInFunction:
2331 if (S->getFnParent())
2332 AddPrettyFunctionResults(PP.getLangOptions(), Results);
2333 break;
2334
2335 case PCC_Namespace:
2336 case PCC_Class:
2337 case PCC_ObjCInterface:
2338 case PCC_ObjCImplementation:
2339 case PCC_ObjCInstanceVariableList:
2340 case PCC_Template:
2341 case PCC_MemberTemplate:
2342 case PCC_ForInit:
2343 case PCC_Condition:
2344 case PCC_Type:
2345 break;
Douglas Gregoraa5f77b2010-08-23 21:54:33 +00002346 }
2347
Douglas Gregor0c8296d2009-11-07 00:00:49 +00002348 if (CodeCompleter->includeMacros())
Douglas Gregorbca403c2010-01-13 23:51:12 +00002349 AddMacroResults(PP, Results);
Douglas Gregoraa5f77b2010-08-23 21:54:33 +00002350
Douglas Gregore6b1bb62010-08-11 21:23:17 +00002351 HandleCodeCompleteResults(this, CodeCompleter,
2352 mapCodeCompletionContext(*this, CompletionContext),
2353 Results.data(),Results.size());
Douglas Gregor791215b2009-09-21 20:51:25 +00002354}
2355
Douglas Gregor2ccccb32010-08-23 18:23:48 +00002356void Sema::CodeCompleteDeclarator(Scope *S,
2357 bool AllowNonIdentifiers,
2358 bool AllowNestedNameSpecifiers) {
2359 typedef CodeCompleteConsumer::Result Result;
2360 ResultBuilder Results(*this);
2361 Results.EnterNewScope();
2362
2363 // Type qualifiers can come after names.
2364 Results.AddResult(Result("const"));
2365 Results.AddResult(Result("volatile"));
2366 if (getLangOptions().C99)
2367 Results.AddResult(Result("restrict"));
2368
2369 if (getLangOptions().CPlusPlus) {
2370 if (AllowNonIdentifiers) {
2371 Results.AddResult(Result("operator"));
2372 }
2373
2374 // Add nested-name-specifiers.
2375 if (AllowNestedNameSpecifiers) {
2376 Results.allowNestedNameSpecifiers();
2377 CodeCompletionDeclConsumer Consumer(Results, CurContext);
2378 LookupVisibleDecls(S, LookupNestedNameSpecifierName, Consumer,
2379 CodeCompleter->includeGlobals());
2380 }
2381 }
2382 Results.ExitScope();
2383
Douglas Gregor4497dd42010-08-24 04:59:56 +00002384 // Note that we intentionally suppress macro results here, since we do not
2385 // encourage using macros to produce the names of entities.
2386
Douglas Gregor2ccccb32010-08-23 18:23:48 +00002387 HandleCodeCompleteResults(this, CodeCompleter,
2388 AllowNestedNameSpecifiers
2389 ? CodeCompletionContext::CCC_PotentiallyQualifiedName
2390 : CodeCompletionContext::CCC_Name,
2391 Results.data(), Results.size());
2392}
2393
Douglas Gregorfb629412010-08-23 21:17:50 +00002394struct Sema::CodeCompleteExpressionData {
2395 CodeCompleteExpressionData(QualType PreferredType = QualType())
2396 : PreferredType(PreferredType), IntegralConstantExpression(false),
2397 ObjCCollection(false) { }
2398
2399 QualType PreferredType;
2400 bool IntegralConstantExpression;
2401 bool ObjCCollection;
2402 llvm::SmallVector<Decl *, 4> IgnoreDecls;
2403};
2404
Douglas Gregor5ac3bdb2010-05-30 01:49:25 +00002405/// \brief Perform code-completion in an expression context when we know what
2406/// type we're looking for.
Douglas Gregorf9578432010-07-28 21:50:18 +00002407///
2408/// \param IntegralConstantExpression Only permit integral constant
2409/// expressions.
Douglas Gregorfb629412010-08-23 21:17:50 +00002410void Sema::CodeCompleteExpression(Scope *S,
2411 const CodeCompleteExpressionData &Data) {
Douglas Gregor5ac3bdb2010-05-30 01:49:25 +00002412 typedef CodeCompleteConsumer::Result Result;
2413 ResultBuilder Results(*this);
2414
Douglas Gregorfb629412010-08-23 21:17:50 +00002415 if (Data.ObjCCollection)
2416 Results.setFilter(&ResultBuilder::IsObjCCollection);
2417 else if (Data.IntegralConstantExpression)
Douglas Gregorf9578432010-07-28 21:50:18 +00002418 Results.setFilter(&ResultBuilder::IsIntegralConstantValue);
Douglas Gregore6b1bb62010-08-11 21:23:17 +00002419 else if (WantTypesInContext(PCC_Expression, getLangOptions()))
Douglas Gregor5ac3bdb2010-05-30 01:49:25 +00002420 Results.setFilter(&ResultBuilder::IsOrdinaryName);
2421 else
2422 Results.setFilter(&ResultBuilder::IsOrdinaryNonTypeName);
Douglas Gregorfb629412010-08-23 21:17:50 +00002423
2424 if (!Data.PreferredType.isNull())
2425 Results.setPreferredType(Data.PreferredType.getNonReferenceType());
2426
2427 // Ignore any declarations that we were told that we don't care about.
2428 for (unsigned I = 0, N = Data.IgnoreDecls.size(); I != N; ++I)
2429 Results.Ignore(Data.IgnoreDecls[I]);
Douglas Gregor5ac3bdb2010-05-30 01:49:25 +00002430
2431 CodeCompletionDeclConsumer Consumer(Results, CurContext);
Douglas Gregor8071e422010-08-15 06:18:01 +00002432 LookupVisibleDecls(S, LookupOrdinaryName, Consumer,
2433 CodeCompleter->includeGlobals());
Douglas Gregor5ac3bdb2010-05-30 01:49:25 +00002434
2435 Results.EnterNewScope();
Douglas Gregore6b1bb62010-08-11 21:23:17 +00002436 AddOrdinaryNameResults(PCC_Expression, S, *this, Results);
Douglas Gregor5ac3bdb2010-05-30 01:49:25 +00002437 Results.ExitScope();
2438
Douglas Gregor590c7d52010-07-08 20:55:51 +00002439 bool PreferredTypeIsPointer = false;
Douglas Gregorfb629412010-08-23 21:17:50 +00002440 if (!Data.PreferredType.isNull())
2441 PreferredTypeIsPointer = Data.PreferredType->isAnyPointerType()
2442 || Data.PreferredType->isMemberPointerType()
2443 || Data.PreferredType->isBlockPointerType();
Douglas Gregor590c7d52010-07-08 20:55:51 +00002444
Douglas Gregoraa5f77b2010-08-23 21:54:33 +00002445 if (S->getFnParent() &&
2446 !Data.ObjCCollection &&
2447 !Data.IntegralConstantExpression)
2448 AddPrettyFunctionResults(PP.getLangOptions(), Results);
2449
Douglas Gregor5ac3bdb2010-05-30 01:49:25 +00002450 if (CodeCompleter->includeMacros())
Douglas Gregor590c7d52010-07-08 20:55:51 +00002451 AddMacroResults(PP, Results, PreferredTypeIsPointer);
Douglas Gregore6b1bb62010-08-11 21:23:17 +00002452 HandleCodeCompleteResults(this, CodeCompleter,
Douglas Gregorfb629412010-08-23 21:17:50 +00002453 CodeCompletionContext(CodeCompletionContext::CCC_Expression,
2454 Data.PreferredType),
Douglas Gregore6b1bb62010-08-11 21:23:17 +00002455 Results.data(),Results.size());
Douglas Gregor5ac3bdb2010-05-30 01:49:25 +00002456}
2457
2458
Douglas Gregor95ac6552009-11-18 01:29:26 +00002459static void AddObjCProperties(ObjCContainerDecl *Container,
Douglas Gregor322328b2009-11-18 22:32:06 +00002460 bool AllowCategories,
Douglas Gregor95ac6552009-11-18 01:29:26 +00002461 DeclContext *CurContext,
2462 ResultBuilder &Results) {
2463 typedef CodeCompleteConsumer::Result Result;
2464
2465 // Add properties in this container.
2466 for (ObjCContainerDecl::prop_iterator P = Container->prop_begin(),
2467 PEnd = Container->prop_end();
2468 P != PEnd;
2469 ++P)
2470 Results.MaybeAddResult(Result(*P, 0), CurContext);
2471
2472 // Add properties in referenced protocols.
2473 if (ObjCProtocolDecl *Protocol = dyn_cast<ObjCProtocolDecl>(Container)) {
2474 for (ObjCProtocolDecl::protocol_iterator P = Protocol->protocol_begin(),
2475 PEnd = Protocol->protocol_end();
2476 P != PEnd; ++P)
Douglas Gregor322328b2009-11-18 22:32:06 +00002477 AddObjCProperties(*P, AllowCategories, CurContext, Results);
Douglas Gregor95ac6552009-11-18 01:29:26 +00002478 } else if (ObjCInterfaceDecl *IFace = dyn_cast<ObjCInterfaceDecl>(Container)){
Douglas Gregor322328b2009-11-18 22:32:06 +00002479 if (AllowCategories) {
2480 // Look through categories.
2481 for (ObjCCategoryDecl *Category = IFace->getCategoryList();
2482 Category; Category = Category->getNextClassCategory())
2483 AddObjCProperties(Category, AllowCategories, CurContext, Results);
2484 }
Douglas Gregor95ac6552009-11-18 01:29:26 +00002485
2486 // Look through protocols.
2487 for (ObjCInterfaceDecl::protocol_iterator I = IFace->protocol_begin(),
2488 E = IFace->protocol_end();
2489 I != E; ++I)
Douglas Gregor322328b2009-11-18 22:32:06 +00002490 AddObjCProperties(*I, AllowCategories, CurContext, Results);
Douglas Gregor95ac6552009-11-18 01:29:26 +00002491
2492 // Look in the superclass.
2493 if (IFace->getSuperClass())
Douglas Gregor322328b2009-11-18 22:32:06 +00002494 AddObjCProperties(IFace->getSuperClass(), AllowCategories, CurContext,
2495 Results);
Douglas Gregor95ac6552009-11-18 01:29:26 +00002496 } else if (const ObjCCategoryDecl *Category
2497 = dyn_cast<ObjCCategoryDecl>(Container)) {
2498 // Look through protocols.
2499 for (ObjCInterfaceDecl::protocol_iterator P = Category->protocol_begin(),
2500 PEnd = Category->protocol_end();
2501 P != PEnd; ++P)
Douglas Gregor322328b2009-11-18 22:32:06 +00002502 AddObjCProperties(*P, AllowCategories, CurContext, Results);
Douglas Gregor95ac6552009-11-18 01:29:26 +00002503 }
2504}
2505
Douglas Gregor81b747b2009-09-17 21:32:03 +00002506void Sema::CodeCompleteMemberReferenceExpr(Scope *S, ExprTy *BaseE,
2507 SourceLocation OpLoc,
2508 bool IsArrow) {
2509 if (!BaseE || !CodeCompleter)
2510 return;
2511
Douglas Gregor86d9a522009-09-21 16:56:56 +00002512 typedef CodeCompleteConsumer::Result Result;
2513
Douglas Gregor81b747b2009-09-17 21:32:03 +00002514 Expr *Base = static_cast<Expr *>(BaseE);
2515 QualType BaseType = Base->getType();
Douglas Gregor86d9a522009-09-21 16:56:56 +00002516
2517 if (IsArrow) {
2518 if (const PointerType *Ptr = BaseType->getAs<PointerType>())
2519 BaseType = Ptr->getPointeeType();
2520 else if (BaseType->isObjCObjectPointerType())
2521 /*Do nothing*/ ;
2522 else
2523 return;
2524 }
2525
Douglas Gregoreb5758b2009-09-23 22:26:46 +00002526 ResultBuilder Results(*this, &ResultBuilder::IsMember);
Douglas Gregor95ac6552009-11-18 01:29:26 +00002527 Results.EnterNewScope();
2528 if (const RecordType *Record = BaseType->getAs<RecordType>()) {
2529 // Access to a C/C++ class, struct, or union.
Douglas Gregor45bcd432010-01-14 03:21:49 +00002530 Results.allowNestedNameSpecifiers();
Douglas Gregor0cc84042010-01-14 15:47:35 +00002531 CodeCompletionDeclConsumer Consumer(Results, CurContext);
Douglas Gregor8071e422010-08-15 06:18:01 +00002532 LookupVisibleDecls(Record->getDecl(), LookupMemberName, Consumer,
2533 CodeCompleter->includeGlobals());
Daniel Dunbar3a2838d2009-11-13 08:58:20 +00002534
Douglas Gregor95ac6552009-11-18 01:29:26 +00002535 if (getLangOptions().CPlusPlus) {
2536 if (!Results.empty()) {
2537 // The "template" keyword can follow "->" or "." in the grammar.
2538 // However, we only want to suggest the template keyword if something
2539 // is dependent.
2540 bool IsDependent = BaseType->isDependentType();
2541 if (!IsDependent) {
2542 for (Scope *DepScope = S; DepScope; DepScope = DepScope->getParent())
2543 if (DeclContext *Ctx = (DeclContext *)DepScope->getEntity()) {
2544 IsDependent = Ctx->isDependentContext();
2545 break;
2546 }
2547 }
Daniel Dunbar3a2838d2009-11-13 08:58:20 +00002548
Douglas Gregor95ac6552009-11-18 01:29:26 +00002549 if (IsDependent)
Douglas Gregora4477812010-01-14 16:01:26 +00002550 Results.AddResult(Result("template"));
Daniel Dunbar3a2838d2009-11-13 08:58:20 +00002551 }
Daniel Dunbar3a2838d2009-11-13 08:58:20 +00002552 }
Douglas Gregor95ac6552009-11-18 01:29:26 +00002553 } else if (!IsArrow && BaseType->getAsObjCInterfacePointerType()) {
2554 // Objective-C property reference.
2555
2556 // Add property results based on our interface.
2557 const ObjCObjectPointerType *ObjCPtr
2558 = BaseType->getAsObjCInterfacePointerType();
2559 assert(ObjCPtr && "Non-NULL pointer guaranteed above!");
Douglas Gregor322328b2009-11-18 22:32:06 +00002560 AddObjCProperties(ObjCPtr->getInterfaceDecl(), true, CurContext, Results);
Douglas Gregor95ac6552009-11-18 01:29:26 +00002561
2562 // Add properties from the protocols in a qualified interface.
2563 for (ObjCObjectPointerType::qual_iterator I = ObjCPtr->qual_begin(),
2564 E = ObjCPtr->qual_end();
2565 I != E; ++I)
Douglas Gregor322328b2009-11-18 22:32:06 +00002566 AddObjCProperties(*I, true, CurContext, Results);
Douglas Gregor95ac6552009-11-18 01:29:26 +00002567 } else if ((IsArrow && BaseType->isObjCObjectPointerType()) ||
John McCallc12c5bb2010-05-15 11:32:37 +00002568 (!IsArrow && BaseType->isObjCObjectType())) {
Douglas Gregor95ac6552009-11-18 01:29:26 +00002569 // Objective-C instance variable access.
2570 ObjCInterfaceDecl *Class = 0;
2571 if (const ObjCObjectPointerType *ObjCPtr
2572 = BaseType->getAs<ObjCObjectPointerType>())
2573 Class = ObjCPtr->getInterfaceDecl();
2574 else
John McCallc12c5bb2010-05-15 11:32:37 +00002575 Class = BaseType->getAs<ObjCObjectType>()->getInterface();
Douglas Gregor95ac6552009-11-18 01:29:26 +00002576
2577 // Add all ivars from this class and its superclasses.
Douglas Gregor80f4f4c2010-01-14 16:08:12 +00002578 if (Class) {
2579 CodeCompletionDeclConsumer Consumer(Results, CurContext);
2580 Results.setFilter(&ResultBuilder::IsObjCIvar);
Douglas Gregor8071e422010-08-15 06:18:01 +00002581 LookupVisibleDecls(Class, LookupMemberName, Consumer,
2582 CodeCompleter->includeGlobals());
Douglas Gregor95ac6552009-11-18 01:29:26 +00002583 }
Douglas Gregor86d9a522009-09-21 16:56:56 +00002584 }
Douglas Gregor95ac6552009-11-18 01:29:26 +00002585
2586 // FIXME: How do we cope with isa?
2587
2588 Results.ExitScope();
Daniel Dunbar3a2838d2009-11-13 08:58:20 +00002589
Daniel Dunbar3a2838d2009-11-13 08:58:20 +00002590 // Hand off the results found for code completion.
Douglas Gregore6b1bb62010-08-11 21:23:17 +00002591 HandleCodeCompleteResults(this, CodeCompleter,
2592 CodeCompletionContext(CodeCompletionContext::CCC_MemberAccess,
2593 BaseType),
2594 Results.data(),Results.size());
Douglas Gregor81b747b2009-09-17 21:32:03 +00002595}
2596
Douglas Gregor374929f2009-09-18 15:37:17 +00002597void Sema::CodeCompleteTag(Scope *S, unsigned TagSpec) {
2598 if (!CodeCompleter)
2599 return;
2600
Douglas Gregor86d9a522009-09-21 16:56:56 +00002601 typedef CodeCompleteConsumer::Result Result;
2602 ResultBuilder::LookupFilter Filter = 0;
Douglas Gregore6b1bb62010-08-11 21:23:17 +00002603 enum CodeCompletionContext::Kind ContextKind
2604 = CodeCompletionContext::CCC_Other;
Douglas Gregor374929f2009-09-18 15:37:17 +00002605 switch ((DeclSpec::TST)TagSpec) {
2606 case DeclSpec::TST_enum:
Douglas Gregor86d9a522009-09-21 16:56:56 +00002607 Filter = &ResultBuilder::IsEnum;
Douglas Gregore6b1bb62010-08-11 21:23:17 +00002608 ContextKind = CodeCompletionContext::CCC_EnumTag;
Douglas Gregor374929f2009-09-18 15:37:17 +00002609 break;
2610
2611 case DeclSpec::TST_union:
Douglas Gregor86d9a522009-09-21 16:56:56 +00002612 Filter = &ResultBuilder::IsUnion;
Douglas Gregore6b1bb62010-08-11 21:23:17 +00002613 ContextKind = CodeCompletionContext::CCC_UnionTag;
Douglas Gregor374929f2009-09-18 15:37:17 +00002614 break;
2615
2616 case DeclSpec::TST_struct:
Douglas Gregor374929f2009-09-18 15:37:17 +00002617 case DeclSpec::TST_class:
Douglas Gregor86d9a522009-09-21 16:56:56 +00002618 Filter = &ResultBuilder::IsClassOrStruct;
Douglas Gregore6b1bb62010-08-11 21:23:17 +00002619 ContextKind = CodeCompletionContext::CCC_ClassOrStructTag;
Douglas Gregor374929f2009-09-18 15:37:17 +00002620 break;
2621
2622 default:
2623 assert(false && "Unknown type specifier kind in CodeCompleteTag");
2624 return;
2625 }
Douglas Gregor86d9a522009-09-21 16:56:56 +00002626
John McCall0d6b1642010-04-23 18:46:30 +00002627 ResultBuilder Results(*this);
Douglas Gregor5d2fc402010-01-14 03:27:13 +00002628 CodeCompletionDeclConsumer Consumer(Results, CurContext);
John McCall0d6b1642010-04-23 18:46:30 +00002629
2630 // First pass: look for tags.
2631 Results.setFilter(Filter);
Douglas Gregor8071e422010-08-15 06:18:01 +00002632 LookupVisibleDecls(S, LookupTagName, Consumer,
2633 CodeCompleter->includeGlobals());
John McCall0d6b1642010-04-23 18:46:30 +00002634
Douglas Gregor8071e422010-08-15 06:18:01 +00002635 if (CodeCompleter->includeGlobals()) {
2636 // Second pass: look for nested name specifiers.
2637 Results.setFilter(&ResultBuilder::IsNestedNameSpecifier);
2638 LookupVisibleDecls(S, LookupNestedNameSpecifierName, Consumer);
2639 }
Douglas Gregor86d9a522009-09-21 16:56:56 +00002640
Douglas Gregore6b1bb62010-08-11 21:23:17 +00002641 HandleCodeCompleteResults(this, CodeCompleter, ContextKind,
2642 Results.data(),Results.size());
Douglas Gregor374929f2009-09-18 15:37:17 +00002643}
2644
Douglas Gregor3e1005f2009-09-21 18:10:23 +00002645void Sema::CodeCompleteCase(Scope *S) {
2646 if (getSwitchStack().empty() || !CodeCompleter)
2647 return;
2648
2649 SwitchStmt *Switch = getSwitchStack().back();
Douglas Gregorf9578432010-07-28 21:50:18 +00002650 if (!Switch->getCond()->getType()->isEnumeralType()) {
Douglas Gregorfb629412010-08-23 21:17:50 +00002651 CodeCompleteExpressionData Data(Switch->getCond()->getType());
2652 Data.IntegralConstantExpression = true;
2653 CodeCompleteExpression(S, Data);
Douglas Gregor3e1005f2009-09-21 18:10:23 +00002654 return;
Douglas Gregorf9578432010-07-28 21:50:18 +00002655 }
Douglas Gregor3e1005f2009-09-21 18:10:23 +00002656
2657 // Code-complete the cases of a switch statement over an enumeration type
2658 // by providing the list of
2659 EnumDecl *Enum = Switch->getCond()->getType()->getAs<EnumType>()->getDecl();
2660
2661 // Determine which enumerators we have already seen in the switch statement.
2662 // FIXME: Ideally, we would also be able to look *past* the code-completion
2663 // token, in case we are code-completing in the middle of the switch and not
2664 // at the end. However, we aren't able to do so at the moment.
2665 llvm::SmallPtrSet<EnumConstantDecl *, 8> EnumeratorsSeen;
Douglas Gregorb9d0ef72009-09-21 19:57:38 +00002666 NestedNameSpecifier *Qualifier = 0;
Douglas Gregor3e1005f2009-09-21 18:10:23 +00002667 for (SwitchCase *SC = Switch->getSwitchCaseList(); SC;
2668 SC = SC->getNextSwitchCase()) {
2669 CaseStmt *Case = dyn_cast<CaseStmt>(SC);
2670 if (!Case)
2671 continue;
2672
2673 Expr *CaseVal = Case->getLHS()->IgnoreParenCasts();
2674 if (DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(CaseVal))
2675 if (EnumConstantDecl *Enumerator
2676 = dyn_cast<EnumConstantDecl>(DRE->getDecl())) {
2677 // We look into the AST of the case statement to determine which
2678 // enumerator was named. Alternatively, we could compute the value of
2679 // the integral constant expression, then compare it against the
2680 // values of each enumerator. However, value-based approach would not
2681 // work as well with C++ templates where enumerators declared within a
2682 // template are type- and value-dependent.
2683 EnumeratorsSeen.insert(Enumerator);
2684
Douglas Gregorb9d0ef72009-09-21 19:57:38 +00002685 // If this is a qualified-id, keep track of the nested-name-specifier
2686 // so that we can reproduce it as part of code completion, e.g.,
Douglas Gregor3e1005f2009-09-21 18:10:23 +00002687 //
2688 // switch (TagD.getKind()) {
2689 // case TagDecl::TK_enum:
2690 // break;
2691 // case XXX
2692 //
Douglas Gregorb9d0ef72009-09-21 19:57:38 +00002693 // At the XXX, our completions are TagDecl::TK_union,
Douglas Gregor3e1005f2009-09-21 18:10:23 +00002694 // TagDecl::TK_struct, and TagDecl::TK_class, rather than TK_union,
2695 // TK_struct, and TK_class.
Douglas Gregora2813ce2009-10-23 18:54:35 +00002696 Qualifier = DRE->getQualifier();
Douglas Gregor3e1005f2009-09-21 18:10:23 +00002697 }
2698 }
2699
Douglas Gregorb9d0ef72009-09-21 19:57:38 +00002700 if (getLangOptions().CPlusPlus && !Qualifier && EnumeratorsSeen.empty()) {
2701 // If there are no prior enumerators in C++, check whether we have to
2702 // qualify the names of the enumerators that we suggest, because they
2703 // may not be visible in this scope.
2704 Qualifier = getRequiredQualification(Context, CurContext,
2705 Enum->getDeclContext());
2706
2707 // FIXME: Scoped enums need to start with "EnumDecl" as the context!
2708 }
2709
Douglas Gregor3e1005f2009-09-21 18:10:23 +00002710 // Add any enumerators that have not yet been mentioned.
2711 ResultBuilder Results(*this);
2712 Results.EnterNewScope();
2713 for (EnumDecl::enumerator_iterator E = Enum->enumerator_begin(),
2714 EEnd = Enum->enumerator_end();
2715 E != EEnd; ++E) {
2716 if (EnumeratorsSeen.count(*E))
2717 continue;
2718
Douglas Gregor608300b2010-01-14 16:14:35 +00002719 Results.AddResult(CodeCompleteConsumer::Result(*E, Qualifier),
2720 CurContext, 0, false);
Douglas Gregor3e1005f2009-09-21 18:10:23 +00002721 }
2722 Results.ExitScope();
Douglas Gregor2f880e42010-04-06 20:02:15 +00002723
Douglas Gregor0c8296d2009-11-07 00:00:49 +00002724 if (CodeCompleter->includeMacros())
Douglas Gregorbca403c2010-01-13 23:51:12 +00002725 AddMacroResults(PP, Results);
Douglas Gregore6b1bb62010-08-11 21:23:17 +00002726 HandleCodeCompleteResults(this, CodeCompleter,
2727 CodeCompletionContext::CCC_Expression,
2728 Results.data(),Results.size());
Douglas Gregor3e1005f2009-09-21 18:10:23 +00002729}
2730
Douglas Gregor9c6a0e92009-09-22 15:41:20 +00002731namespace {
2732 struct IsBetterOverloadCandidate {
2733 Sema &S;
John McCall5769d612010-02-08 23:07:23 +00002734 SourceLocation Loc;
Douglas Gregor9c6a0e92009-09-22 15:41:20 +00002735
2736 public:
John McCall5769d612010-02-08 23:07:23 +00002737 explicit IsBetterOverloadCandidate(Sema &S, SourceLocation Loc)
2738 : S(S), Loc(Loc) { }
Douglas Gregor9c6a0e92009-09-22 15:41:20 +00002739
2740 bool
2741 operator()(const OverloadCandidate &X, const OverloadCandidate &Y) const {
John McCall5769d612010-02-08 23:07:23 +00002742 return S.isBetterOverloadCandidate(X, Y, Loc);
Douglas Gregor9c6a0e92009-09-22 15:41:20 +00002743 }
2744 };
2745}
2746
Douglas Gregord28dcd72010-05-30 06:10:08 +00002747static bool anyNullArguments(Expr **Args, unsigned NumArgs) {
2748 if (NumArgs && !Args)
2749 return true;
2750
2751 for (unsigned I = 0; I != NumArgs; ++I)
2752 if (!Args[I])
2753 return true;
2754
2755 return false;
2756}
2757
Douglas Gregor9c6a0e92009-09-22 15:41:20 +00002758void Sema::CodeCompleteCall(Scope *S, ExprTy *FnIn,
2759 ExprTy **ArgsIn, unsigned NumArgs) {
2760 if (!CodeCompleter)
2761 return;
Douglas Gregoref96eac2009-12-11 19:06:04 +00002762
2763 // When we're code-completing for a call, we fall back to ordinary
2764 // name code-completion whenever we can't produce specific
2765 // results. We may want to revisit this strategy in the future,
2766 // e.g., by merging the two kinds of results.
2767
Douglas Gregor9c6a0e92009-09-22 15:41:20 +00002768 Expr *Fn = (Expr *)FnIn;
2769 Expr **Args = (Expr **)ArgsIn;
Douglas Gregoref96eac2009-12-11 19:06:04 +00002770
Douglas Gregor9c6a0e92009-09-22 15:41:20 +00002771 // Ignore type-dependent call expressions entirely.
Douglas Gregord28dcd72010-05-30 06:10:08 +00002772 if (!Fn || Fn->isTypeDependent() || anyNullArguments(Args, NumArgs) ||
Douglas Gregoref96eac2009-12-11 19:06:04 +00002773 Expr::hasAnyTypeDependentArguments(Args, NumArgs)) {
Douglas Gregore6b1bb62010-08-11 21:23:17 +00002774 CodeCompleteOrdinaryName(S, PCC_Expression);
Douglas Gregor9c6a0e92009-09-22 15:41:20 +00002775 return;
Douglas Gregoref96eac2009-12-11 19:06:04 +00002776 }
Douglas Gregor9c6a0e92009-09-22 15:41:20 +00002777
John McCall3b4294e2009-12-16 12:17:52 +00002778 // Build an overload candidate set based on the functions we find.
John McCall5769d612010-02-08 23:07:23 +00002779 SourceLocation Loc = Fn->getExprLoc();
2780 OverloadCandidateSet CandidateSet(Loc);
John McCall3b4294e2009-12-16 12:17:52 +00002781
Douglas Gregor9c6a0e92009-09-22 15:41:20 +00002782 // FIXME: What if we're calling something that isn't a function declaration?
2783 // FIXME: What if we're calling a pseudo-destructor?
2784 // FIXME: What if we're calling a member function?
2785
Douglas Gregorc0265402010-01-21 15:46:19 +00002786 typedef CodeCompleteConsumer::OverloadCandidate ResultCandidate;
2787 llvm::SmallVector<ResultCandidate, 8> Results;
2788
John McCall3b4294e2009-12-16 12:17:52 +00002789 Expr *NakedFn = Fn->IgnoreParenCasts();
2790 if (UnresolvedLookupExpr *ULE = dyn_cast<UnresolvedLookupExpr>(NakedFn))
2791 AddOverloadedCallCandidates(ULE, Args, NumArgs, CandidateSet,
2792 /*PartialOverloading=*/ true);
2793 else if (DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(NakedFn)) {
2794 FunctionDecl *FDecl = dyn_cast<FunctionDecl>(DRE->getDecl());
Douglas Gregorc0265402010-01-21 15:46:19 +00002795 if (FDecl) {
Douglas Gregord28dcd72010-05-30 06:10:08 +00002796 if (!getLangOptions().CPlusPlus ||
2797 !FDecl->getType()->getAs<FunctionProtoType>())
Douglas Gregorc0265402010-01-21 15:46:19 +00002798 Results.push_back(ResultCandidate(FDecl));
2799 else
John McCall86820f52010-01-26 01:37:31 +00002800 // FIXME: access?
John McCall9aa472c2010-03-19 07:35:19 +00002801 AddOverloadCandidate(FDecl, DeclAccessPair::make(FDecl, AS_none),
2802 Args, NumArgs, CandidateSet,
Douglas Gregorc27d6c52010-04-16 17:41:49 +00002803 false, /*PartialOverloading*/true);
Douglas Gregorc0265402010-01-21 15:46:19 +00002804 }
John McCall3b4294e2009-12-16 12:17:52 +00002805 }
Douglas Gregor9c6a0e92009-09-22 15:41:20 +00002806
Douglas Gregor5ac3bdb2010-05-30 01:49:25 +00002807 QualType ParamType;
2808
Douglas Gregorc0265402010-01-21 15:46:19 +00002809 if (!CandidateSet.empty()) {
2810 // Sort the overload candidate set by placing the best overloads first.
2811 std::stable_sort(CandidateSet.begin(), CandidateSet.end(),
John McCall5769d612010-02-08 23:07:23 +00002812 IsBetterOverloadCandidate(*this, Loc));
Douglas Gregor9c6a0e92009-09-22 15:41:20 +00002813
Douglas Gregorc0265402010-01-21 15:46:19 +00002814 // Add the remaining viable overload candidates as code-completion reslults.
2815 for (OverloadCandidateSet::iterator Cand = CandidateSet.begin(),
2816 CandEnd = CandidateSet.end();
2817 Cand != CandEnd; ++Cand) {
2818 if (Cand->Viable)
2819 Results.push_back(ResultCandidate(Cand->Function));
2820 }
Douglas Gregor5ac3bdb2010-05-30 01:49:25 +00002821
2822 // From the viable candidates, try to determine the type of this parameter.
2823 for (unsigned I = 0, N = Results.size(); I != N; ++I) {
2824 if (const FunctionType *FType = Results[I].getFunctionType())
2825 if (const FunctionProtoType *Proto = dyn_cast<FunctionProtoType>(FType))
2826 if (NumArgs < Proto->getNumArgs()) {
2827 if (ParamType.isNull())
2828 ParamType = Proto->getArgType(NumArgs);
2829 else if (!Context.hasSameUnqualifiedType(
2830 ParamType.getNonReferenceType(),
2831 Proto->getArgType(NumArgs).getNonReferenceType())) {
2832 ParamType = QualType();
2833 break;
2834 }
2835 }
2836 }
2837 } else {
2838 // Try to determine the parameter type from the type of the expression
2839 // being called.
2840 QualType FunctionType = Fn->getType();
2841 if (const PointerType *Ptr = FunctionType->getAs<PointerType>())
2842 FunctionType = Ptr->getPointeeType();
2843 else if (const BlockPointerType *BlockPtr
2844 = FunctionType->getAs<BlockPointerType>())
2845 FunctionType = BlockPtr->getPointeeType();
2846 else if (const MemberPointerType *MemPtr
2847 = FunctionType->getAs<MemberPointerType>())
2848 FunctionType = MemPtr->getPointeeType();
2849
2850 if (const FunctionProtoType *Proto
2851 = FunctionType->getAs<FunctionProtoType>()) {
2852 if (NumArgs < Proto->getNumArgs())
2853 ParamType = Proto->getArgType(NumArgs);
2854 }
Douglas Gregor9c6a0e92009-09-22 15:41:20 +00002855 }
Douglas Gregoref96eac2009-12-11 19:06:04 +00002856
Douglas Gregor5ac3bdb2010-05-30 01:49:25 +00002857 if (ParamType.isNull())
Douglas Gregore6b1bb62010-08-11 21:23:17 +00002858 CodeCompleteOrdinaryName(S, PCC_Expression);
Douglas Gregor5ac3bdb2010-05-30 01:49:25 +00002859 else
2860 CodeCompleteExpression(S, ParamType);
2861
Douglas Gregor2e4c7a52010-04-06 20:19:47 +00002862 if (!Results.empty())
Douglas Gregoref96eac2009-12-11 19:06:04 +00002863 CodeCompleter->ProcessOverloadCandidates(*this, NumArgs, Results.data(),
2864 Results.size());
Douglas Gregor9c6a0e92009-09-22 15:41:20 +00002865}
2866
John McCalld226f652010-08-21 09:40:31 +00002867void Sema::CodeCompleteInitializer(Scope *S, Decl *D) {
2868 ValueDecl *VD = dyn_cast_or_null<ValueDecl>(D);
Douglas Gregor5ac3bdb2010-05-30 01:49:25 +00002869 if (!VD) {
Douglas Gregore6b1bb62010-08-11 21:23:17 +00002870 CodeCompleteOrdinaryName(S, PCC_Expression);
Douglas Gregor5ac3bdb2010-05-30 01:49:25 +00002871 return;
2872 }
2873
2874 CodeCompleteExpression(S, VD->getType());
2875}
2876
2877void Sema::CodeCompleteReturn(Scope *S) {
2878 QualType ResultType;
2879 if (isa<BlockDecl>(CurContext)) {
2880 if (BlockScopeInfo *BSI = getCurBlock())
2881 ResultType = BSI->ReturnType;
2882 } else if (FunctionDecl *Function = dyn_cast<FunctionDecl>(CurContext))
2883 ResultType = Function->getResultType();
2884 else if (ObjCMethodDecl *Method = dyn_cast<ObjCMethodDecl>(CurContext))
2885 ResultType = Method->getResultType();
2886
2887 if (ResultType.isNull())
Douglas Gregore6b1bb62010-08-11 21:23:17 +00002888 CodeCompleteOrdinaryName(S, PCC_Expression);
Douglas Gregor5ac3bdb2010-05-30 01:49:25 +00002889 else
2890 CodeCompleteExpression(S, ResultType);
2891}
2892
2893void Sema::CodeCompleteAssignmentRHS(Scope *S, ExprTy *LHS) {
2894 if (LHS)
2895 CodeCompleteExpression(S, static_cast<Expr *>(LHS)->getType());
2896 else
Douglas Gregore6b1bb62010-08-11 21:23:17 +00002897 CodeCompleteOrdinaryName(S, PCC_Expression);
Douglas Gregor5ac3bdb2010-05-30 01:49:25 +00002898}
2899
Jeffrey Yasskin9ab14542010-04-08 16:38:48 +00002900void Sema::CodeCompleteQualifiedId(Scope *S, CXXScopeSpec &SS,
Douglas Gregor81b747b2009-09-17 21:32:03 +00002901 bool EnteringContext) {
2902 if (!SS.getScopeRep() || !CodeCompleter)
2903 return;
2904
Douglas Gregor86d9a522009-09-21 16:56:56 +00002905 DeclContext *Ctx = computeDeclContext(SS, EnteringContext);
2906 if (!Ctx)
2907 return;
Douglas Gregord1cd31a2009-12-11 18:28:39 +00002908
2909 // Try to instantiate any non-dependent declaration contexts before
2910 // we look in them.
John McCall77bb1aa2010-05-01 00:40:08 +00002911 if (!isDependentScopeSpecifier(SS) && RequireCompleteDeclContext(SS, Ctx))
Douglas Gregord1cd31a2009-12-11 18:28:39 +00002912 return;
2913
Douglas Gregor86d9a522009-09-21 16:56:56 +00002914 ResultBuilder Results(*this);
Douglas Gregordef91072010-01-14 03:35:48 +00002915 CodeCompletionDeclConsumer Consumer(Results, CurContext);
2916 LookupVisibleDecls(Ctx, LookupOrdinaryName, Consumer);
Douglas Gregor86d9a522009-09-21 16:56:56 +00002917
2918 // The "template" keyword can follow "::" in the grammar, but only
2919 // put it into the grammar if the nested-name-specifier is dependent.
2920 NestedNameSpecifier *NNS = (NestedNameSpecifier *)SS.getScopeRep();
2921 if (!Results.empty() && NNS->isDependent())
Douglas Gregora4477812010-01-14 16:01:26 +00002922 Results.AddResult("template");
Douglas Gregor86d9a522009-09-21 16:56:56 +00002923
Douglas Gregore6b1bb62010-08-11 21:23:17 +00002924 HandleCodeCompleteResults(this, CodeCompleter,
2925 CodeCompletionContext::CCC_Other,
2926 Results.data(),Results.size());
Douglas Gregor81b747b2009-09-17 21:32:03 +00002927}
Douglas Gregor49f40bd2009-09-18 19:03:04 +00002928
2929void Sema::CodeCompleteUsing(Scope *S) {
2930 if (!CodeCompleter)
2931 return;
2932
Douglas Gregor86d9a522009-09-21 16:56:56 +00002933 ResultBuilder Results(*this, &ResultBuilder::IsNestedNameSpecifier);
Douglas Gregor8e0a0e42009-09-22 23:31:26 +00002934 Results.EnterNewScope();
Douglas Gregor86d9a522009-09-21 16:56:56 +00002935
2936 // If we aren't in class scope, we could see the "namespace" keyword.
2937 if (!S->isClassScope())
Douglas Gregora4477812010-01-14 16:01:26 +00002938 Results.AddResult(CodeCompleteConsumer::Result("namespace"));
Douglas Gregor86d9a522009-09-21 16:56:56 +00002939
2940 // After "using", we can see anything that would start a
2941 // nested-name-specifier.
Douglas Gregor5d2fc402010-01-14 03:27:13 +00002942 CodeCompletionDeclConsumer Consumer(Results, CurContext);
Douglas Gregor8071e422010-08-15 06:18:01 +00002943 LookupVisibleDecls(S, LookupOrdinaryName, Consumer,
2944 CodeCompleter->includeGlobals());
Douglas Gregor8e0a0e42009-09-22 23:31:26 +00002945 Results.ExitScope();
Douglas Gregor86d9a522009-09-21 16:56:56 +00002946
Douglas Gregore6b1bb62010-08-11 21:23:17 +00002947 HandleCodeCompleteResults(this, CodeCompleter,
2948 CodeCompletionContext::CCC_Other,
2949 Results.data(),Results.size());
Douglas Gregor49f40bd2009-09-18 19:03:04 +00002950}
2951
2952void Sema::CodeCompleteUsingDirective(Scope *S) {
2953 if (!CodeCompleter)
2954 return;
2955
Douglas Gregor86d9a522009-09-21 16:56:56 +00002956 // After "using namespace", we expect to see a namespace name or namespace
2957 // alias.
2958 ResultBuilder Results(*this, &ResultBuilder::IsNamespaceOrAlias);
Douglas Gregor8e0a0e42009-09-22 23:31:26 +00002959 Results.EnterNewScope();
Douglas Gregor5d2fc402010-01-14 03:27:13 +00002960 CodeCompletionDeclConsumer Consumer(Results, CurContext);
Douglas Gregor8071e422010-08-15 06:18:01 +00002961 LookupVisibleDecls(S, LookupOrdinaryName, Consumer,
2962 CodeCompleter->includeGlobals());
Douglas Gregor8e0a0e42009-09-22 23:31:26 +00002963 Results.ExitScope();
Douglas Gregore6b1bb62010-08-11 21:23:17 +00002964 HandleCodeCompleteResults(this, CodeCompleter,
Douglas Gregor8071e422010-08-15 06:18:01 +00002965 CodeCompletionContext::CCC_Namespace,
Douglas Gregore6b1bb62010-08-11 21:23:17 +00002966 Results.data(),Results.size());
Douglas Gregor49f40bd2009-09-18 19:03:04 +00002967}
2968
2969void Sema::CodeCompleteNamespaceDecl(Scope *S) {
2970 if (!CodeCompleter)
2971 return;
2972
Douglas Gregor86d9a522009-09-21 16:56:56 +00002973 ResultBuilder Results(*this, &ResultBuilder::IsNamespace);
2974 DeclContext *Ctx = (DeclContext *)S->getEntity();
2975 if (!S->getParent())
2976 Ctx = Context.getTranslationUnitDecl();
2977
2978 if (Ctx && Ctx->isFileContext()) {
2979 // We only want to see those namespaces that have already been defined
2980 // within this scope, because its likely that the user is creating an
2981 // extended namespace declaration. Keep track of the most recent
2982 // definition of each namespace.
2983 std::map<NamespaceDecl *, NamespaceDecl *> OrigToLatest;
2984 for (DeclContext::specific_decl_iterator<NamespaceDecl>
2985 NS(Ctx->decls_begin()), NSEnd(Ctx->decls_end());
2986 NS != NSEnd; ++NS)
2987 OrigToLatest[NS->getOriginalNamespace()] = *NS;
2988
2989 // Add the most recent definition (or extended definition) of each
2990 // namespace to the list of results.
Douglas Gregor8e0a0e42009-09-22 23:31:26 +00002991 Results.EnterNewScope();
Douglas Gregor86d9a522009-09-21 16:56:56 +00002992 for (std::map<NamespaceDecl *, NamespaceDecl *>::iterator
2993 NS = OrigToLatest.begin(), NSEnd = OrigToLatest.end();
2994 NS != NSEnd; ++NS)
Douglas Gregor608300b2010-01-14 16:14:35 +00002995 Results.AddResult(CodeCompleteConsumer::Result(NS->second, 0),
2996 CurContext, 0, false);
Douglas Gregor8e0a0e42009-09-22 23:31:26 +00002997 Results.ExitScope();
Douglas Gregor86d9a522009-09-21 16:56:56 +00002998 }
2999
Douglas Gregore6b1bb62010-08-11 21:23:17 +00003000 HandleCodeCompleteResults(this, CodeCompleter,
3001 CodeCompletionContext::CCC_Other,
3002 Results.data(),Results.size());
Douglas Gregor49f40bd2009-09-18 19:03:04 +00003003}
3004
3005void Sema::CodeCompleteNamespaceAliasDecl(Scope *S) {
3006 if (!CodeCompleter)
3007 return;
3008
Douglas Gregor86d9a522009-09-21 16:56:56 +00003009 // After "namespace", we expect to see a namespace or alias.
3010 ResultBuilder Results(*this, &ResultBuilder::IsNamespaceOrAlias);
Douglas Gregor5d2fc402010-01-14 03:27:13 +00003011 CodeCompletionDeclConsumer Consumer(Results, CurContext);
Douglas Gregor8071e422010-08-15 06:18:01 +00003012 LookupVisibleDecls(S, LookupOrdinaryName, Consumer,
3013 CodeCompleter->includeGlobals());
Douglas Gregore6b1bb62010-08-11 21:23:17 +00003014 HandleCodeCompleteResults(this, CodeCompleter,
Douglas Gregor8071e422010-08-15 06:18:01 +00003015 CodeCompletionContext::CCC_Namespace,
Douglas Gregore6b1bb62010-08-11 21:23:17 +00003016 Results.data(),Results.size());
Douglas Gregor49f40bd2009-09-18 19:03:04 +00003017}
3018
Douglas Gregored8d3222009-09-18 20:05:18 +00003019void Sema::CodeCompleteOperatorName(Scope *S) {
3020 if (!CodeCompleter)
3021 return;
Douglas Gregor86d9a522009-09-21 16:56:56 +00003022
3023 typedef CodeCompleteConsumer::Result Result;
3024 ResultBuilder Results(*this, &ResultBuilder::IsType);
Douglas Gregor8e0a0e42009-09-22 23:31:26 +00003025 Results.EnterNewScope();
Douglas Gregored8d3222009-09-18 20:05:18 +00003026
Douglas Gregor86d9a522009-09-21 16:56:56 +00003027 // Add the names of overloadable operators.
3028#define OVERLOADED_OPERATOR(Name,Spelling,Token,Unary,Binary,MemberOnly) \
3029 if (std::strcmp(Spelling, "?")) \
Douglas Gregora4477812010-01-14 16:01:26 +00003030 Results.AddResult(Result(Spelling));
Douglas Gregor86d9a522009-09-21 16:56:56 +00003031#include "clang/Basic/OperatorKinds.def"
3032
3033 // Add any type names visible from the current scope
Douglas Gregor45bcd432010-01-14 03:21:49 +00003034 Results.allowNestedNameSpecifiers();
Douglas Gregor5d2fc402010-01-14 03:27:13 +00003035 CodeCompletionDeclConsumer Consumer(Results, CurContext);
Douglas Gregor8071e422010-08-15 06:18:01 +00003036 LookupVisibleDecls(S, LookupOrdinaryName, Consumer,
3037 CodeCompleter->includeGlobals());
Douglas Gregor86d9a522009-09-21 16:56:56 +00003038
3039 // Add any type specifiers
Douglas Gregorbca403c2010-01-13 23:51:12 +00003040 AddTypeSpecifierResults(getLangOptions(), Results);
Douglas Gregor8e0a0e42009-09-22 23:31:26 +00003041 Results.ExitScope();
Douglas Gregor86d9a522009-09-21 16:56:56 +00003042
Douglas Gregore6b1bb62010-08-11 21:23:17 +00003043 HandleCodeCompleteResults(this, CodeCompleter,
Douglas Gregor8071e422010-08-15 06:18:01 +00003044 CodeCompletionContext::CCC_Type,
Douglas Gregore6b1bb62010-08-11 21:23:17 +00003045 Results.data(),Results.size());
Douglas Gregored8d3222009-09-18 20:05:18 +00003046}
Douglas Gregor49f40bd2009-09-18 19:03:04 +00003047
Douglas Gregorb6ac2452010-01-13 21:24:21 +00003048// Macro that expands to @Keyword or Keyword, depending on whether NeedAt is
3049// true or false.
3050#define OBJC_AT_KEYWORD_NAME(NeedAt,Keyword) NeedAt? "@" #Keyword : #Keyword
Douglas Gregorbca403c2010-01-13 23:51:12 +00003051static void AddObjCImplementationResults(const LangOptions &LangOpts,
Douglas Gregorb6ac2452010-01-13 21:24:21 +00003052 ResultBuilder &Results,
3053 bool NeedAt) {
3054 typedef CodeCompleteConsumer::Result Result;
3055 // Since we have an implementation, we can end it.
Douglas Gregora4477812010-01-14 16:01:26 +00003056 Results.AddResult(Result(OBJC_AT_KEYWORD_NAME(NeedAt,end)));
Douglas Gregorb6ac2452010-01-13 21:24:21 +00003057
3058 CodeCompletionString *Pattern = 0;
3059 if (LangOpts.ObjC2) {
3060 // @dynamic
3061 Pattern = new CodeCompletionString;
3062 Pattern->AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt,dynamic));
3063 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
3064 Pattern->AddPlaceholderChunk("property");
Douglas Gregora4477812010-01-14 16:01:26 +00003065 Results.AddResult(Result(Pattern));
Douglas Gregorb6ac2452010-01-13 21:24:21 +00003066
3067 // @synthesize
3068 Pattern = new CodeCompletionString;
3069 Pattern->AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt,synthesize));
3070 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
3071 Pattern->AddPlaceholderChunk("property");
Douglas Gregora4477812010-01-14 16:01:26 +00003072 Results.AddResult(Result(Pattern));
Douglas Gregorb6ac2452010-01-13 21:24:21 +00003073 }
3074}
3075
Douglas Gregorbca403c2010-01-13 23:51:12 +00003076static void AddObjCInterfaceResults(const LangOptions &LangOpts,
Douglas Gregorb6ac2452010-01-13 21:24:21 +00003077 ResultBuilder &Results,
3078 bool NeedAt) {
3079 typedef CodeCompleteConsumer::Result Result;
3080
3081 // Since we have an interface or protocol, we can end it.
Douglas Gregora4477812010-01-14 16:01:26 +00003082 Results.AddResult(Result(OBJC_AT_KEYWORD_NAME(NeedAt,end)));
Douglas Gregorb6ac2452010-01-13 21:24:21 +00003083
3084 if (LangOpts.ObjC2) {
3085 // @property
Douglas Gregora4477812010-01-14 16:01:26 +00003086 Results.AddResult(Result(OBJC_AT_KEYWORD_NAME(NeedAt,property)));
Douglas Gregorb6ac2452010-01-13 21:24:21 +00003087
3088 // @required
Douglas Gregora4477812010-01-14 16:01:26 +00003089 Results.AddResult(Result(OBJC_AT_KEYWORD_NAME(NeedAt,required)));
Douglas Gregorb6ac2452010-01-13 21:24:21 +00003090
3091 // @optional
Douglas Gregora4477812010-01-14 16:01:26 +00003092 Results.AddResult(Result(OBJC_AT_KEYWORD_NAME(NeedAt,optional)));
Douglas Gregorb6ac2452010-01-13 21:24:21 +00003093 }
3094}
3095
Douglas Gregorbca403c2010-01-13 23:51:12 +00003096static void AddObjCTopLevelResults(ResultBuilder &Results, bool NeedAt) {
Douglas Gregorb6ac2452010-01-13 21:24:21 +00003097 typedef CodeCompleteConsumer::Result Result;
3098 CodeCompletionString *Pattern = 0;
3099
3100 // @class name ;
3101 Pattern = new CodeCompletionString;
3102 Pattern->AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt,class));
3103 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
Douglas Gregorc8bddde2010-05-28 00:22:41 +00003104 Pattern->AddPlaceholderChunk("name");
Douglas Gregora4477812010-01-14 16:01:26 +00003105 Results.AddResult(Result(Pattern));
Douglas Gregorb6ac2452010-01-13 21:24:21 +00003106
Douglas Gregorc8bddde2010-05-28 00:22:41 +00003107 if (Results.includeCodePatterns()) {
3108 // @interface name
3109 // FIXME: Could introduce the whole pattern, including superclasses and
3110 // such.
3111 Pattern = new CodeCompletionString;
3112 Pattern->AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt,interface));
3113 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
3114 Pattern->AddPlaceholderChunk("class");
3115 Results.AddResult(Result(Pattern));
Douglas Gregorb6ac2452010-01-13 21:24:21 +00003116
Douglas Gregorc8bddde2010-05-28 00:22:41 +00003117 // @protocol name
3118 Pattern = new CodeCompletionString;
3119 Pattern->AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt,protocol));
3120 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
3121 Pattern->AddPlaceholderChunk("protocol");
3122 Results.AddResult(Result(Pattern));
3123
3124 // @implementation name
3125 Pattern = new CodeCompletionString;
3126 Pattern->AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt,implementation));
3127 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
3128 Pattern->AddPlaceholderChunk("class");
3129 Results.AddResult(Result(Pattern));
3130 }
Douglas Gregorb6ac2452010-01-13 21:24:21 +00003131
3132 // @compatibility_alias name
3133 Pattern = new CodeCompletionString;
3134 Pattern->AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt,compatibility_alias));
3135 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
3136 Pattern->AddPlaceholderChunk("alias");
3137 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
3138 Pattern->AddPlaceholderChunk("class");
Douglas Gregora4477812010-01-14 16:01:26 +00003139 Results.AddResult(Result(Pattern));
Douglas Gregorb6ac2452010-01-13 21:24:21 +00003140}
3141
John McCalld226f652010-08-21 09:40:31 +00003142void Sema::CodeCompleteObjCAtDirective(Scope *S, Decl *ObjCImpDecl,
Douglas Gregorc464ae82009-12-07 09:27:33 +00003143 bool InInterface) {
3144 typedef CodeCompleteConsumer::Result Result;
3145 ResultBuilder Results(*this);
3146 Results.EnterNewScope();
Douglas Gregorb6ac2452010-01-13 21:24:21 +00003147 if (ObjCImpDecl)
Douglas Gregorbca403c2010-01-13 23:51:12 +00003148 AddObjCImplementationResults(getLangOptions(), Results, false);
Douglas Gregorb6ac2452010-01-13 21:24:21 +00003149 else if (InInterface)
Douglas Gregorbca403c2010-01-13 23:51:12 +00003150 AddObjCInterfaceResults(getLangOptions(), Results, false);
Douglas Gregorb6ac2452010-01-13 21:24:21 +00003151 else
Douglas Gregorbca403c2010-01-13 23:51:12 +00003152 AddObjCTopLevelResults(Results, false);
Douglas Gregorc464ae82009-12-07 09:27:33 +00003153 Results.ExitScope();
Douglas Gregore6b1bb62010-08-11 21:23:17 +00003154 HandleCodeCompleteResults(this, CodeCompleter,
3155 CodeCompletionContext::CCC_Other,
3156 Results.data(),Results.size());
Douglas Gregorc464ae82009-12-07 09:27:33 +00003157}
3158
Douglas Gregorbca403c2010-01-13 23:51:12 +00003159static void AddObjCExpressionResults(ResultBuilder &Results, bool NeedAt) {
Douglas Gregor9a0c85e2009-12-07 09:51:25 +00003160 typedef CodeCompleteConsumer::Result Result;
3161 CodeCompletionString *Pattern = 0;
3162
3163 // @encode ( type-name )
3164 Pattern = new CodeCompletionString;
Douglas Gregorb6ac2452010-01-13 21:24:21 +00003165 Pattern->AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt,encode));
Douglas Gregor9a0c85e2009-12-07 09:51:25 +00003166 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
3167 Pattern->AddPlaceholderChunk("type-name");
3168 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
Douglas Gregora4477812010-01-14 16:01:26 +00003169 Results.AddResult(Result(Pattern));
Douglas Gregor9a0c85e2009-12-07 09:51:25 +00003170
3171 // @protocol ( protocol-name )
3172 Pattern = new CodeCompletionString;
Douglas Gregorb6ac2452010-01-13 21:24:21 +00003173 Pattern->AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt,protocol));
Douglas Gregor9a0c85e2009-12-07 09:51:25 +00003174 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
3175 Pattern->AddPlaceholderChunk("protocol-name");
3176 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
Douglas Gregora4477812010-01-14 16:01:26 +00003177 Results.AddResult(Result(Pattern));
Douglas Gregor9a0c85e2009-12-07 09:51:25 +00003178
3179 // @selector ( selector )
3180 Pattern = new CodeCompletionString;
Douglas Gregorb6ac2452010-01-13 21:24:21 +00003181 Pattern->AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt,selector));
Douglas Gregor9a0c85e2009-12-07 09:51:25 +00003182 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
3183 Pattern->AddPlaceholderChunk("selector");
3184 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
Douglas Gregora4477812010-01-14 16:01:26 +00003185 Results.AddResult(Result(Pattern));
Douglas Gregor9a0c85e2009-12-07 09:51:25 +00003186}
3187
Douglas Gregorbca403c2010-01-13 23:51:12 +00003188static void AddObjCStatementResults(ResultBuilder &Results, bool NeedAt) {
Douglas Gregor9a0c85e2009-12-07 09:51:25 +00003189 typedef CodeCompleteConsumer::Result Result;
Douglas Gregor9a0c85e2009-12-07 09:51:25 +00003190 CodeCompletionString *Pattern = 0;
Douglas Gregorb6ac2452010-01-13 21:24:21 +00003191
Douglas Gregorc8bddde2010-05-28 00:22:41 +00003192 if (Results.includeCodePatterns()) {
3193 // @try { statements } @catch ( declaration ) { statements } @finally
3194 // { statements }
3195 Pattern = new CodeCompletionString;
3196 Pattern->AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt,try));
3197 Pattern->AddChunk(CodeCompletionString::CK_LeftBrace);
3198 Pattern->AddPlaceholderChunk("statements");
3199 Pattern->AddChunk(CodeCompletionString::CK_RightBrace);
3200 Pattern->AddTextChunk("@catch");
3201 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
3202 Pattern->AddPlaceholderChunk("parameter");
3203 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
3204 Pattern->AddChunk(CodeCompletionString::CK_LeftBrace);
3205 Pattern->AddPlaceholderChunk("statements");
3206 Pattern->AddChunk(CodeCompletionString::CK_RightBrace);
3207 Pattern->AddTextChunk("@finally");
3208 Pattern->AddChunk(CodeCompletionString::CK_LeftBrace);
3209 Pattern->AddPlaceholderChunk("statements");
3210 Pattern->AddChunk(CodeCompletionString::CK_RightBrace);
3211 Results.AddResult(Result(Pattern));
3212 }
Douglas Gregorb6ac2452010-01-13 21:24:21 +00003213
Douglas Gregor9a0c85e2009-12-07 09:51:25 +00003214 // @throw
3215 Pattern = new CodeCompletionString;
Douglas Gregorb6ac2452010-01-13 21:24:21 +00003216 Pattern->AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt,throw));
Douglas Gregor834389b2010-01-12 06:38:28 +00003217 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
Douglas Gregor9a0c85e2009-12-07 09:51:25 +00003218 Pattern->AddPlaceholderChunk("expression");
Douglas Gregora4477812010-01-14 16:01:26 +00003219 Results.AddResult(Result(Pattern));
Douglas Gregorb6ac2452010-01-13 21:24:21 +00003220
Douglas Gregorc8bddde2010-05-28 00:22:41 +00003221 if (Results.includeCodePatterns()) {
3222 // @synchronized ( expression ) { statements }
3223 Pattern = new CodeCompletionString;
3224 Pattern->AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt,synchronized));
3225 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
3226 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
3227 Pattern->AddPlaceholderChunk("expression");
3228 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
3229 Pattern->AddChunk(CodeCompletionString::CK_LeftBrace);
3230 Pattern->AddPlaceholderChunk("statements");
3231 Pattern->AddChunk(CodeCompletionString::CK_RightBrace);
3232 Results.AddResult(Result(Pattern));
3233 }
Douglas Gregorb6ac2452010-01-13 21:24:21 +00003234}
Douglas Gregor9a0c85e2009-12-07 09:51:25 +00003235
Douglas Gregorbca403c2010-01-13 23:51:12 +00003236static void AddObjCVisibilityResults(const LangOptions &LangOpts,
Douglas Gregorc38c3e12010-01-13 21:54:15 +00003237 ResultBuilder &Results,
3238 bool NeedAt) {
Douglas Gregorb6ac2452010-01-13 21:24:21 +00003239 typedef CodeCompleteConsumer::Result Result;
Douglas Gregora4477812010-01-14 16:01:26 +00003240 Results.AddResult(Result(OBJC_AT_KEYWORD_NAME(NeedAt,private)));
3241 Results.AddResult(Result(OBJC_AT_KEYWORD_NAME(NeedAt,protected)));
3242 Results.AddResult(Result(OBJC_AT_KEYWORD_NAME(NeedAt,public)));
Douglas Gregorc38c3e12010-01-13 21:54:15 +00003243 if (LangOpts.ObjC2)
Douglas Gregora4477812010-01-14 16:01:26 +00003244 Results.AddResult(Result(OBJC_AT_KEYWORD_NAME(NeedAt,package)));
Douglas Gregorc38c3e12010-01-13 21:54:15 +00003245}
3246
3247void Sema::CodeCompleteObjCAtVisibility(Scope *S) {
3248 ResultBuilder Results(*this);
3249 Results.EnterNewScope();
Douglas Gregorbca403c2010-01-13 23:51:12 +00003250 AddObjCVisibilityResults(getLangOptions(), Results, false);
Douglas Gregorc38c3e12010-01-13 21:54:15 +00003251 Results.ExitScope();
Douglas Gregore6b1bb62010-08-11 21:23:17 +00003252 HandleCodeCompleteResults(this, CodeCompleter,
3253 CodeCompletionContext::CCC_Other,
3254 Results.data(),Results.size());
Douglas Gregorc38c3e12010-01-13 21:54:15 +00003255}
3256
3257void Sema::CodeCompleteObjCAtStatement(Scope *S) {
Douglas Gregorb6ac2452010-01-13 21:24:21 +00003258 ResultBuilder Results(*this);
3259 Results.EnterNewScope();
Douglas Gregorbca403c2010-01-13 23:51:12 +00003260 AddObjCStatementResults(Results, false);
3261 AddObjCExpressionResults(Results, false);
Douglas Gregor9a0c85e2009-12-07 09:51:25 +00003262 Results.ExitScope();
Douglas Gregore6b1bb62010-08-11 21:23:17 +00003263 HandleCodeCompleteResults(this, CodeCompleter,
3264 CodeCompletionContext::CCC_Other,
3265 Results.data(),Results.size());
Douglas Gregor9a0c85e2009-12-07 09:51:25 +00003266}
3267
3268void Sema::CodeCompleteObjCAtExpression(Scope *S) {
3269 ResultBuilder Results(*this);
3270 Results.EnterNewScope();
Douglas Gregorbca403c2010-01-13 23:51:12 +00003271 AddObjCExpressionResults(Results, false);
Douglas Gregor9a0c85e2009-12-07 09:51:25 +00003272 Results.ExitScope();
Douglas Gregore6b1bb62010-08-11 21:23:17 +00003273 HandleCodeCompleteResults(this, CodeCompleter,
3274 CodeCompletionContext::CCC_Other,
3275 Results.data(),Results.size());
Douglas Gregor9a0c85e2009-12-07 09:51:25 +00003276}
3277
Douglas Gregor988358f2009-11-19 00:14:45 +00003278/// \brief Determine whether the addition of the given flag to an Objective-C
3279/// property's attributes will cause a conflict.
3280static bool ObjCPropertyFlagConflicts(unsigned Attributes, unsigned NewFlag) {
3281 // Check if we've already added this flag.
3282 if (Attributes & NewFlag)
3283 return true;
3284
3285 Attributes |= NewFlag;
3286
3287 // Check for collisions with "readonly".
3288 if ((Attributes & ObjCDeclSpec::DQ_PR_readonly) &&
3289 (Attributes & (ObjCDeclSpec::DQ_PR_readwrite |
3290 ObjCDeclSpec::DQ_PR_assign |
3291 ObjCDeclSpec::DQ_PR_copy |
3292 ObjCDeclSpec::DQ_PR_retain)))
3293 return true;
3294
3295 // Check for more than one of { assign, copy, retain }.
3296 unsigned AssignCopyRetMask = Attributes & (ObjCDeclSpec::DQ_PR_assign |
3297 ObjCDeclSpec::DQ_PR_copy |
3298 ObjCDeclSpec::DQ_PR_retain);
3299 if (AssignCopyRetMask &&
3300 AssignCopyRetMask != ObjCDeclSpec::DQ_PR_assign &&
3301 AssignCopyRetMask != ObjCDeclSpec::DQ_PR_copy &&
3302 AssignCopyRetMask != ObjCDeclSpec::DQ_PR_retain)
3303 return true;
3304
3305 return false;
3306}
3307
Douglas Gregora93b1082009-11-18 23:08:07 +00003308void Sema::CodeCompleteObjCPropertyFlags(Scope *S, ObjCDeclSpec &ODS) {
Steve Naroffece8e712009-10-08 21:55:05 +00003309 if (!CodeCompleter)
3310 return;
Douglas Gregord3c68542009-11-19 01:08:35 +00003311
Steve Naroffece8e712009-10-08 21:55:05 +00003312 unsigned Attributes = ODS.getPropertyAttributes();
3313
3314 typedef CodeCompleteConsumer::Result Result;
3315 ResultBuilder Results(*this);
3316 Results.EnterNewScope();
Douglas Gregor988358f2009-11-19 00:14:45 +00003317 if (!ObjCPropertyFlagConflicts(Attributes, ObjCDeclSpec::DQ_PR_readonly))
Douglas Gregora4477812010-01-14 16:01:26 +00003318 Results.AddResult(CodeCompleteConsumer::Result("readonly"));
Douglas Gregor988358f2009-11-19 00:14:45 +00003319 if (!ObjCPropertyFlagConflicts(Attributes, ObjCDeclSpec::DQ_PR_assign))
Douglas Gregora4477812010-01-14 16:01:26 +00003320 Results.AddResult(CodeCompleteConsumer::Result("assign"));
Douglas Gregor988358f2009-11-19 00:14:45 +00003321 if (!ObjCPropertyFlagConflicts(Attributes, ObjCDeclSpec::DQ_PR_readwrite))
Douglas Gregora4477812010-01-14 16:01:26 +00003322 Results.AddResult(CodeCompleteConsumer::Result("readwrite"));
Douglas Gregor988358f2009-11-19 00:14:45 +00003323 if (!ObjCPropertyFlagConflicts(Attributes, ObjCDeclSpec::DQ_PR_retain))
Douglas Gregora4477812010-01-14 16:01:26 +00003324 Results.AddResult(CodeCompleteConsumer::Result("retain"));
Douglas Gregor988358f2009-11-19 00:14:45 +00003325 if (!ObjCPropertyFlagConflicts(Attributes, ObjCDeclSpec::DQ_PR_copy))
Douglas Gregora4477812010-01-14 16:01:26 +00003326 Results.AddResult(CodeCompleteConsumer::Result("copy"));
Douglas Gregor988358f2009-11-19 00:14:45 +00003327 if (!ObjCPropertyFlagConflicts(Attributes, ObjCDeclSpec::DQ_PR_nonatomic))
Douglas Gregora4477812010-01-14 16:01:26 +00003328 Results.AddResult(CodeCompleteConsumer::Result("nonatomic"));
Douglas Gregor988358f2009-11-19 00:14:45 +00003329 if (!ObjCPropertyFlagConflicts(Attributes, ObjCDeclSpec::DQ_PR_setter)) {
Douglas Gregor54f01612009-11-19 00:01:57 +00003330 CodeCompletionString *Setter = new CodeCompletionString;
3331 Setter->AddTypedTextChunk("setter");
3332 Setter->AddTextChunk(" = ");
3333 Setter->AddPlaceholderChunk("method");
Douglas Gregora4477812010-01-14 16:01:26 +00003334 Results.AddResult(CodeCompleteConsumer::Result(Setter));
Douglas Gregor54f01612009-11-19 00:01:57 +00003335 }
Douglas Gregor988358f2009-11-19 00:14:45 +00003336 if (!ObjCPropertyFlagConflicts(Attributes, ObjCDeclSpec::DQ_PR_getter)) {
Douglas Gregor54f01612009-11-19 00:01:57 +00003337 CodeCompletionString *Getter = new CodeCompletionString;
3338 Getter->AddTypedTextChunk("getter");
3339 Getter->AddTextChunk(" = ");
3340 Getter->AddPlaceholderChunk("method");
Douglas Gregora4477812010-01-14 16:01:26 +00003341 Results.AddResult(CodeCompleteConsumer::Result(Getter));
Douglas Gregor54f01612009-11-19 00:01:57 +00003342 }
Steve Naroffece8e712009-10-08 21:55:05 +00003343 Results.ExitScope();
Douglas Gregore6b1bb62010-08-11 21:23:17 +00003344 HandleCodeCompleteResults(this, CodeCompleter,
3345 CodeCompletionContext::CCC_Other,
3346 Results.data(),Results.size());
Steve Naroffece8e712009-10-08 21:55:05 +00003347}
Steve Naroffc4df6d22009-11-07 02:08:14 +00003348
Douglas Gregor4ad96852009-11-19 07:41:15 +00003349/// \brief Descripts the kind of Objective-C method that we want to find
3350/// via code completion.
3351enum ObjCMethodKind {
3352 MK_Any, //< Any kind of method, provided it means other specified criteria.
3353 MK_ZeroArgSelector, //< Zero-argument (unary) selector.
3354 MK_OneArgSelector //< One-argument selector.
3355};
3356
3357static bool isAcceptableObjCMethod(ObjCMethodDecl *Method,
3358 ObjCMethodKind WantKind,
3359 IdentifierInfo **SelIdents,
3360 unsigned NumSelIdents) {
3361 Selector Sel = Method->getSelector();
3362 if (NumSelIdents > Sel.getNumArgs())
3363 return false;
3364
3365 switch (WantKind) {
3366 case MK_Any: break;
3367 case MK_ZeroArgSelector: return Sel.isUnarySelector();
3368 case MK_OneArgSelector: return Sel.getNumArgs() == 1;
3369 }
3370
3371 for (unsigned I = 0; I != NumSelIdents; ++I)
3372 if (SelIdents[I] != Sel.getIdentifierInfoForSlot(I))
3373 return false;
3374
3375 return true;
3376}
3377
Douglas Gregor36ecb042009-11-17 23:22:23 +00003378/// \brief Add all of the Objective-C methods in the given Objective-C
3379/// container to the set of results.
3380///
3381/// The container will be a class, protocol, category, or implementation of
3382/// any of the above. This mether will recurse to include methods from
3383/// the superclasses of classes along with their categories, protocols, and
3384/// implementations.
3385///
3386/// \param Container the container in which we'll look to find methods.
3387///
3388/// \param WantInstance whether to add instance methods (only); if false, this
3389/// routine will add factory methods (only).
3390///
3391/// \param CurContext the context in which we're performing the lookup that
3392/// finds methods.
3393///
3394/// \param Results the structure into which we'll add results.
3395static void AddObjCMethods(ObjCContainerDecl *Container,
3396 bool WantInstanceMethods,
Douglas Gregor4ad96852009-11-19 07:41:15 +00003397 ObjCMethodKind WantKind,
Douglas Gregord3c68542009-11-19 01:08:35 +00003398 IdentifierInfo **SelIdents,
3399 unsigned NumSelIdents,
Douglas Gregor36ecb042009-11-17 23:22:23 +00003400 DeclContext *CurContext,
3401 ResultBuilder &Results) {
3402 typedef CodeCompleteConsumer::Result Result;
3403 for (ObjCContainerDecl::method_iterator M = Container->meth_begin(),
3404 MEnd = Container->meth_end();
3405 M != MEnd; ++M) {
Douglas Gregord3c68542009-11-19 01:08:35 +00003406 if ((*M)->isInstanceMethod() == WantInstanceMethods) {
3407 // Check whether the selector identifiers we've been given are a
3408 // subset of the identifiers for this particular method.
Douglas Gregor4ad96852009-11-19 07:41:15 +00003409 if (!isAcceptableObjCMethod(*M, WantKind, SelIdents, NumSelIdents))
Douglas Gregord3c68542009-11-19 01:08:35 +00003410 continue;
Douglas Gregor4ad96852009-11-19 07:41:15 +00003411
Douglas Gregord3c68542009-11-19 01:08:35 +00003412 Result R = Result(*M, 0);
3413 R.StartParameter = NumSelIdents;
Douglas Gregor4ad96852009-11-19 07:41:15 +00003414 R.AllParametersAreInformative = (WantKind != MK_Any);
Douglas Gregord3c68542009-11-19 01:08:35 +00003415 Results.MaybeAddResult(R, CurContext);
3416 }
Douglas Gregor36ecb042009-11-17 23:22:23 +00003417 }
3418
3419 ObjCInterfaceDecl *IFace = dyn_cast<ObjCInterfaceDecl>(Container);
3420 if (!IFace)
3421 return;
3422
3423 // Add methods in protocols.
3424 const ObjCList<ObjCProtocolDecl> &Protocols= IFace->getReferencedProtocols();
3425 for (ObjCList<ObjCProtocolDecl>::iterator I = Protocols.begin(),
3426 E = Protocols.end();
3427 I != E; ++I)
Douglas Gregor4ad96852009-11-19 07:41:15 +00003428 AddObjCMethods(*I, WantInstanceMethods, WantKind, SelIdents, NumSelIdents,
Douglas Gregord3c68542009-11-19 01:08:35 +00003429 CurContext, Results);
Douglas Gregor36ecb042009-11-17 23:22:23 +00003430
3431 // Add methods in categories.
3432 for (ObjCCategoryDecl *CatDecl = IFace->getCategoryList(); CatDecl;
3433 CatDecl = CatDecl->getNextClassCategory()) {
Douglas Gregor4ad96852009-11-19 07:41:15 +00003434 AddObjCMethods(CatDecl, WantInstanceMethods, WantKind, SelIdents,
3435 NumSelIdents, CurContext, Results);
Douglas Gregor36ecb042009-11-17 23:22:23 +00003436
3437 // Add a categories protocol methods.
3438 const ObjCList<ObjCProtocolDecl> &Protocols
3439 = CatDecl->getReferencedProtocols();
3440 for (ObjCList<ObjCProtocolDecl>::iterator I = Protocols.begin(),
3441 E = Protocols.end();
3442 I != E; ++I)
Douglas Gregor4ad96852009-11-19 07:41:15 +00003443 AddObjCMethods(*I, WantInstanceMethods, WantKind, SelIdents,
3444 NumSelIdents, CurContext, Results);
Douglas Gregor36ecb042009-11-17 23:22:23 +00003445
3446 // Add methods in category implementations.
3447 if (ObjCCategoryImplDecl *Impl = CatDecl->getImplementation())
Douglas Gregor4ad96852009-11-19 07:41:15 +00003448 AddObjCMethods(Impl, WantInstanceMethods, WantKind, SelIdents,
3449 NumSelIdents, CurContext, Results);
Douglas Gregor36ecb042009-11-17 23:22:23 +00003450 }
3451
3452 // Add methods in superclass.
3453 if (IFace->getSuperClass())
Douglas Gregor4ad96852009-11-19 07:41:15 +00003454 AddObjCMethods(IFace->getSuperClass(), WantInstanceMethods, WantKind,
3455 SelIdents, NumSelIdents, CurContext, Results);
Douglas Gregor36ecb042009-11-17 23:22:23 +00003456
3457 // Add methods in our implementation, if any.
3458 if (ObjCImplementationDecl *Impl = IFace->getImplementation())
Douglas Gregor4ad96852009-11-19 07:41:15 +00003459 AddObjCMethods(Impl, WantInstanceMethods, WantKind, SelIdents,
3460 NumSelIdents, CurContext, Results);
3461}
3462
3463
John McCalld226f652010-08-21 09:40:31 +00003464void Sema::CodeCompleteObjCPropertyGetter(Scope *S, Decl *ClassDecl,
3465 Decl **Methods,
Douglas Gregor4ad96852009-11-19 07:41:15 +00003466 unsigned NumMethods) {
3467 typedef CodeCompleteConsumer::Result Result;
3468
3469 // Try to find the interface where getters might live.
John McCalld226f652010-08-21 09:40:31 +00003470 ObjCInterfaceDecl *Class = dyn_cast_or_null<ObjCInterfaceDecl>(ClassDecl);
Douglas Gregor4ad96852009-11-19 07:41:15 +00003471 if (!Class) {
3472 if (ObjCCategoryDecl *Category
John McCalld226f652010-08-21 09:40:31 +00003473 = dyn_cast_or_null<ObjCCategoryDecl>(ClassDecl))
Douglas Gregor4ad96852009-11-19 07:41:15 +00003474 Class = Category->getClassInterface();
3475
3476 if (!Class)
3477 return;
3478 }
3479
3480 // Find all of the potential getters.
3481 ResultBuilder Results(*this);
3482 Results.EnterNewScope();
3483
3484 // FIXME: We need to do this because Objective-C methods don't get
3485 // pushed into DeclContexts early enough. Argh!
3486 for (unsigned I = 0; I != NumMethods; ++I) {
3487 if (ObjCMethodDecl *Method
John McCalld226f652010-08-21 09:40:31 +00003488 = dyn_cast_or_null<ObjCMethodDecl>(Methods[I]))
Douglas Gregor4ad96852009-11-19 07:41:15 +00003489 if (Method->isInstanceMethod() &&
3490 isAcceptableObjCMethod(Method, MK_ZeroArgSelector, 0, 0)) {
3491 Result R = Result(Method, 0);
3492 R.AllParametersAreInformative = true;
3493 Results.MaybeAddResult(R, CurContext);
3494 }
3495 }
3496
3497 AddObjCMethods(Class, true, MK_ZeroArgSelector, 0, 0, CurContext, Results);
3498 Results.ExitScope();
Douglas Gregore6b1bb62010-08-11 21:23:17 +00003499 HandleCodeCompleteResults(this, CodeCompleter,
3500 CodeCompletionContext::CCC_Other,
3501 Results.data(),Results.size());
Douglas Gregor4ad96852009-11-19 07:41:15 +00003502}
3503
John McCalld226f652010-08-21 09:40:31 +00003504void Sema::CodeCompleteObjCPropertySetter(Scope *S, Decl *ObjCImplDecl,
3505 Decl **Methods,
Douglas Gregor4ad96852009-11-19 07:41:15 +00003506 unsigned NumMethods) {
3507 typedef CodeCompleteConsumer::Result Result;
3508
3509 // Try to find the interface where setters might live.
3510 ObjCInterfaceDecl *Class
John McCalld226f652010-08-21 09:40:31 +00003511 = dyn_cast_or_null<ObjCInterfaceDecl>(ObjCImplDecl);
Douglas Gregor4ad96852009-11-19 07:41:15 +00003512 if (!Class) {
3513 if (ObjCCategoryDecl *Category
John McCalld226f652010-08-21 09:40:31 +00003514 = dyn_cast_or_null<ObjCCategoryDecl>(ObjCImplDecl))
Douglas Gregor4ad96852009-11-19 07:41:15 +00003515 Class = Category->getClassInterface();
3516
3517 if (!Class)
3518 return;
3519 }
3520
3521 // Find all of the potential getters.
3522 ResultBuilder Results(*this);
3523 Results.EnterNewScope();
3524
3525 // FIXME: We need to do this because Objective-C methods don't get
3526 // pushed into DeclContexts early enough. Argh!
3527 for (unsigned I = 0; I != NumMethods; ++I) {
3528 if (ObjCMethodDecl *Method
John McCalld226f652010-08-21 09:40:31 +00003529 = dyn_cast_or_null<ObjCMethodDecl>(Methods[I]))
Douglas Gregor4ad96852009-11-19 07:41:15 +00003530 if (Method->isInstanceMethod() &&
3531 isAcceptableObjCMethod(Method, MK_OneArgSelector, 0, 0)) {
3532 Result R = Result(Method, 0);
3533 R.AllParametersAreInformative = true;
3534 Results.MaybeAddResult(R, CurContext);
3535 }
3536 }
3537
3538 AddObjCMethods(Class, true, MK_OneArgSelector, 0, 0, CurContext, Results);
3539
3540 Results.ExitScope();
Douglas Gregore6b1bb62010-08-11 21:23:17 +00003541 HandleCodeCompleteResults(this, CodeCompleter,
3542 CodeCompletionContext::CCC_Other,
3543 Results.data(),Results.size());
Douglas Gregor36ecb042009-11-17 23:22:23 +00003544}
3545
Douglas Gregord32b0222010-08-24 01:06:58 +00003546void Sema::CodeCompleteObjCPassingType(Scope *S, ObjCDeclSpec &DS) {
3547 typedef CodeCompleteConsumer::Result Result;
3548 ResultBuilder Results(*this);
3549 Results.EnterNewScope();
3550
3551 // Add context-sensitive, Objective-C parameter-passing keywords.
3552 bool AddedInOut = false;
3553 if ((DS.getObjCDeclQualifier() &
3554 (ObjCDeclSpec::DQ_In | ObjCDeclSpec::DQ_Inout)) == 0) {
3555 Results.AddResult("in");
3556 Results.AddResult("inout");
3557 AddedInOut = true;
3558 }
3559 if ((DS.getObjCDeclQualifier() &
3560 (ObjCDeclSpec::DQ_Out | ObjCDeclSpec::DQ_Inout)) == 0) {
3561 Results.AddResult("out");
3562 if (!AddedInOut)
3563 Results.AddResult("inout");
3564 }
3565 if ((DS.getObjCDeclQualifier() &
3566 (ObjCDeclSpec::DQ_Bycopy | ObjCDeclSpec::DQ_Byref |
3567 ObjCDeclSpec::DQ_Oneway)) == 0) {
3568 Results.AddResult("bycopy");
3569 Results.AddResult("byref");
3570 Results.AddResult("oneway");
3571 }
3572
3573 // Add various builtin type names and specifiers.
3574 AddOrdinaryNameResults(PCC_Type, S, *this, Results);
3575 Results.ExitScope();
3576
3577 // Add the various type names
3578 Results.setFilter(&ResultBuilder::IsOrdinaryNonValueName);
3579 CodeCompletionDeclConsumer Consumer(Results, CurContext);
3580 LookupVisibleDecls(S, LookupOrdinaryName, Consumer,
3581 CodeCompleter->includeGlobals());
3582
3583 if (CodeCompleter->includeMacros())
3584 AddMacroResults(PP, Results);
3585
3586 HandleCodeCompleteResults(this, CodeCompleter,
3587 CodeCompletionContext::CCC_Type,
3588 Results.data(), Results.size());
3589}
3590
Douglas Gregor22f56992010-04-06 19:22:33 +00003591/// \brief When we have an expression with type "id", we may assume
3592/// that it has some more-specific class type based on knowledge of
3593/// common uses of Objective-C. This routine returns that class type,
3594/// or NULL if no better result could be determined.
3595static ObjCInterfaceDecl *GetAssumedMessageSendExprType(Expr *E) {
3596 ObjCMessageExpr *Msg = dyn_cast<ObjCMessageExpr>(E);
3597 if (!Msg)
3598 return 0;
3599
3600 Selector Sel = Msg->getSelector();
3601 if (Sel.isNull())
3602 return 0;
3603
3604 IdentifierInfo *Id = Sel.getIdentifierInfoForSlot(0);
3605 if (!Id)
3606 return 0;
3607
3608 ObjCMethodDecl *Method = Msg->getMethodDecl();
3609 if (!Method)
3610 return 0;
3611
3612 // Determine the class that we're sending the message to.
Douglas Gregor04badcf2010-04-21 00:45:42 +00003613 ObjCInterfaceDecl *IFace = 0;
3614 switch (Msg->getReceiverKind()) {
3615 case ObjCMessageExpr::Class:
John McCallc12c5bb2010-05-15 11:32:37 +00003616 if (const ObjCObjectType *ObjType
3617 = Msg->getClassReceiver()->getAs<ObjCObjectType>())
3618 IFace = ObjType->getInterface();
Douglas Gregor04badcf2010-04-21 00:45:42 +00003619 break;
3620
3621 case ObjCMessageExpr::Instance: {
3622 QualType T = Msg->getInstanceReceiver()->getType();
3623 if (const ObjCObjectPointerType *Ptr = T->getAs<ObjCObjectPointerType>())
3624 IFace = Ptr->getInterfaceDecl();
3625 break;
3626 }
3627
3628 case ObjCMessageExpr::SuperInstance:
3629 case ObjCMessageExpr::SuperClass:
3630 break;
Douglas Gregor22f56992010-04-06 19:22:33 +00003631 }
3632
3633 if (!IFace)
3634 return 0;
3635
3636 ObjCInterfaceDecl *Super = IFace->getSuperClass();
3637 if (Method->isInstanceMethod())
3638 return llvm::StringSwitch<ObjCInterfaceDecl *>(Id->getName())
3639 .Case("retain", IFace)
3640 .Case("autorelease", IFace)
3641 .Case("copy", IFace)
3642 .Case("copyWithZone", IFace)
3643 .Case("mutableCopy", IFace)
3644 .Case("mutableCopyWithZone", IFace)
3645 .Case("awakeFromCoder", IFace)
3646 .Case("replacementObjectFromCoder", IFace)
3647 .Case("class", IFace)
3648 .Case("classForCoder", IFace)
3649 .Case("superclass", Super)
3650 .Default(0);
3651
3652 return llvm::StringSwitch<ObjCInterfaceDecl *>(Id->getName())
3653 .Case("new", IFace)
3654 .Case("alloc", IFace)
3655 .Case("allocWithZone", IFace)
3656 .Case("class", IFace)
3657 .Case("superclass", Super)
3658 .Default(0);
3659}
3660
Douglas Gregor8e254cf2010-05-27 23:06:34 +00003661void Sema::CodeCompleteObjCMessageReceiver(Scope *S) {
3662 typedef CodeCompleteConsumer::Result Result;
3663 ResultBuilder Results(*this);
3664
3665 // Find anything that looks like it could be a message receiver.
3666 Results.setFilter(&ResultBuilder::IsObjCMessageReceiver);
3667 CodeCompletionDeclConsumer Consumer(Results, CurContext);
3668 Results.EnterNewScope();
Douglas Gregor8071e422010-08-15 06:18:01 +00003669 LookupVisibleDecls(S, LookupOrdinaryName, Consumer,
3670 CodeCompleter->includeGlobals());
Douglas Gregor8e254cf2010-05-27 23:06:34 +00003671
3672 // If we are in an Objective-C method inside a class that has a superclass,
3673 // add "super" as an option.
3674 if (ObjCMethodDecl *Method = getCurMethodDecl())
3675 if (ObjCInterfaceDecl *Iface = Method->getClassInterface())
3676 if (Iface->getSuperClass())
3677 Results.AddResult(Result("super"));
3678
3679 Results.ExitScope();
3680
3681 if (CodeCompleter->includeMacros())
3682 AddMacroResults(PP, Results);
Douglas Gregore6b1bb62010-08-11 21:23:17 +00003683 HandleCodeCompleteResults(this, CodeCompleter,
3684 CodeCompletionContext::CCC_ObjCMessageReceiver,
3685 Results.data(), Results.size());
Douglas Gregor8e254cf2010-05-27 23:06:34 +00003686
3687}
3688
Douglas Gregor2725ca82010-04-21 19:57:20 +00003689void Sema::CodeCompleteObjCSuperMessage(Scope *S, SourceLocation SuperLoc,
3690 IdentifierInfo **SelIdents,
3691 unsigned NumSelIdents) {
3692 ObjCInterfaceDecl *CDecl = 0;
3693 if (ObjCMethodDecl *CurMethod = getCurMethodDecl()) {
3694 // Figure out which interface we're in.
3695 CDecl = CurMethod->getClassInterface();
3696 if (!CDecl)
3697 return;
3698
3699 // Find the superclass of this class.
3700 CDecl = CDecl->getSuperClass();
3701 if (!CDecl)
3702 return;
3703
3704 if (CurMethod->isInstanceMethod()) {
3705 // We are inside an instance method, which means that the message
3706 // send [super ...] is actually calling an instance method on the
3707 // current object. Build the super expression and handle this like
3708 // an instance method.
3709 QualType SuperTy = Context.getObjCInterfaceType(CDecl);
3710 SuperTy = Context.getObjCObjectPointerType(SuperTy);
John McCall60d7b3a2010-08-24 06:29:42 +00003711 ExprResult Super
Douglas Gregor2725ca82010-04-21 19:57:20 +00003712 = Owned(new (Context) ObjCSuperExpr(SuperLoc, SuperTy));
3713 return CodeCompleteObjCInstanceMessage(S, (Expr *)Super.get(),
3714 SelIdents, NumSelIdents);
3715 }
3716
3717 // Fall through to send to the superclass in CDecl.
3718 } else {
3719 // "super" may be the name of a type or variable. Figure out which
3720 // it is.
3721 IdentifierInfo *Super = &Context.Idents.get("super");
3722 NamedDecl *ND = LookupSingleName(S, Super, SuperLoc,
3723 LookupOrdinaryName);
3724 if ((CDecl = dyn_cast_or_null<ObjCInterfaceDecl>(ND))) {
3725 // "super" names an interface. Use it.
3726 } else if (TypeDecl *TD = dyn_cast_or_null<TypeDecl>(ND)) {
John McCallc12c5bb2010-05-15 11:32:37 +00003727 if (const ObjCObjectType *Iface
3728 = Context.getTypeDeclType(TD)->getAs<ObjCObjectType>())
3729 CDecl = Iface->getInterface();
Douglas Gregor2725ca82010-04-21 19:57:20 +00003730 } else if (ND && isa<UnresolvedUsingTypenameDecl>(ND)) {
3731 // "super" names an unresolved type; we can't be more specific.
3732 } else {
3733 // Assume that "super" names some kind of value and parse that way.
3734 CXXScopeSpec SS;
3735 UnqualifiedId id;
3736 id.setIdentifier(Super, SuperLoc);
John McCall60d7b3a2010-08-24 06:29:42 +00003737 ExprResult SuperExpr = ActOnIdExpression(S, SS, id, false, false);
Douglas Gregor2725ca82010-04-21 19:57:20 +00003738 return CodeCompleteObjCInstanceMessage(S, (Expr *)SuperExpr.get(),
3739 SelIdents, NumSelIdents);
3740 }
3741
3742 // Fall through
3743 }
3744
John McCallb3d87482010-08-24 05:47:05 +00003745 ParsedType Receiver;
Douglas Gregor2725ca82010-04-21 19:57:20 +00003746 if (CDecl)
John McCallb3d87482010-08-24 05:47:05 +00003747 Receiver = ParsedType::make(Context.getObjCInterfaceType(CDecl));
Douglas Gregor2725ca82010-04-21 19:57:20 +00003748 return CodeCompleteObjCClassMessage(S, Receiver, SelIdents,
3749 NumSelIdents);
3750}
3751
John McCallb3d87482010-08-24 05:47:05 +00003752void Sema::CodeCompleteObjCClassMessage(Scope *S, ParsedType Receiver,
Douglas Gregord3c68542009-11-19 01:08:35 +00003753 IdentifierInfo **SelIdents,
3754 unsigned NumSelIdents) {
Steve Naroffc4df6d22009-11-07 02:08:14 +00003755 typedef CodeCompleteConsumer::Result Result;
Douglas Gregor24a069f2009-11-17 17:59:40 +00003756 ObjCInterfaceDecl *CDecl = 0;
3757
Douglas Gregor24a069f2009-11-17 17:59:40 +00003758 // If the given name refers to an interface type, retrieve the
3759 // corresponding declaration.
Douglas Gregor2725ca82010-04-21 19:57:20 +00003760 if (Receiver) {
3761 QualType T = GetTypeFromParser(Receiver, 0);
3762 if (!T.isNull())
John McCallc12c5bb2010-05-15 11:32:37 +00003763 if (const ObjCObjectType *Interface = T->getAs<ObjCObjectType>())
3764 CDecl = Interface->getInterface();
Douglas Gregor24a069f2009-11-17 17:59:40 +00003765 }
3766
Douglas Gregor36ecb042009-11-17 23:22:23 +00003767 // Add all of the factory methods in this Objective-C class, its protocols,
3768 // superclasses, categories, implementation, etc.
Steve Naroffc4df6d22009-11-07 02:08:14 +00003769 ResultBuilder Results(*this);
3770 Results.EnterNewScope();
Douglas Gregor13438f92010-04-06 16:40:00 +00003771
3772 if (CDecl)
3773 AddObjCMethods(CDecl, false, MK_Any, SelIdents, NumSelIdents, CurContext,
3774 Results);
Douglas Gregor2725ca82010-04-21 19:57:20 +00003775 else {
Douglas Gregor13438f92010-04-06 16:40:00 +00003776 // We're messaging "id" as a type; provide all class/factory methods.
3777
Douglas Gregor719770d2010-04-06 17:30:22 +00003778 // If we have an external source, load the entire class method
Sebastian Redl3c7f4132010-08-18 23:57:06 +00003779 // pool from the AST file.
Douglas Gregor719770d2010-04-06 17:30:22 +00003780 if (ExternalSource) {
John McCall76bd1f32010-06-01 09:23:16 +00003781 for (uint32_t I = 0, N = ExternalSource->GetNumExternalSelectors();
3782 I != N; ++I) {
3783 Selector Sel = ExternalSource->GetExternalSelector(I);
Sebastian Redldb9d2142010-08-02 23:18:59 +00003784 if (Sel.isNull() || MethodPool.count(Sel))
Douglas Gregor719770d2010-04-06 17:30:22 +00003785 continue;
3786
Sebastian Redldb9d2142010-08-02 23:18:59 +00003787 ReadMethodPool(Sel);
Douglas Gregor719770d2010-04-06 17:30:22 +00003788 }
3789 }
3790
Sebastian Redldb9d2142010-08-02 23:18:59 +00003791 for (GlobalMethodPool::iterator M = MethodPool.begin(),
3792 MEnd = MethodPool.end();
3793 M != MEnd; ++M) {
3794 for (ObjCMethodList *MethList = &M->second.second;
3795 MethList && MethList->Method;
Douglas Gregor13438f92010-04-06 16:40:00 +00003796 MethList = MethList->Next) {
3797 if (!isAcceptableObjCMethod(MethList->Method, MK_Any, SelIdents,
3798 NumSelIdents))
3799 continue;
3800
3801 Result R(MethList->Method, 0);
3802 R.StartParameter = NumSelIdents;
3803 R.AllParametersAreInformative = false;
3804 Results.MaybeAddResult(R, CurContext);
3805 }
3806 }
3807 }
3808
Steve Naroffc4df6d22009-11-07 02:08:14 +00003809 Results.ExitScope();
Douglas Gregore6b1bb62010-08-11 21:23:17 +00003810 HandleCodeCompleteResults(this, CodeCompleter,
3811 CodeCompletionContext::CCC_Other,
3812 Results.data(),Results.size());
Steve Naroffc4df6d22009-11-07 02:08:14 +00003813}
3814
Douglas Gregord3c68542009-11-19 01:08:35 +00003815void Sema::CodeCompleteObjCInstanceMessage(Scope *S, ExprTy *Receiver,
3816 IdentifierInfo **SelIdents,
3817 unsigned NumSelIdents) {
Steve Naroffc4df6d22009-11-07 02:08:14 +00003818 typedef CodeCompleteConsumer::Result Result;
Steve Naroffc4df6d22009-11-07 02:08:14 +00003819
3820 Expr *RecExpr = static_cast<Expr *>(Receiver);
Steve Naroffc4df6d22009-11-07 02:08:14 +00003821
Douglas Gregor36ecb042009-11-17 23:22:23 +00003822 // If necessary, apply function/array conversion to the receiver.
3823 // C99 6.7.5.3p[7,8].
Douglas Gregora873dfc2010-02-03 00:27:59 +00003824 DefaultFunctionArrayLvalueConversion(RecExpr);
Douglas Gregor36ecb042009-11-17 23:22:23 +00003825 QualType ReceiverType = RecExpr->getType();
Steve Naroffc4df6d22009-11-07 02:08:14 +00003826
Douglas Gregor36ecb042009-11-17 23:22:23 +00003827 // Build the set of methods we can see.
3828 ResultBuilder Results(*this);
3829 Results.EnterNewScope();
Douglas Gregor22f56992010-04-06 19:22:33 +00003830
3831 // If we're messaging an expression with type "id" or "Class", check
3832 // whether we know something special about the receiver that allows
3833 // us to assume a more-specific receiver type.
3834 if (ReceiverType->isObjCIdType() || ReceiverType->isObjCClassType())
3835 if (ObjCInterfaceDecl *IFace = GetAssumedMessageSendExprType(RecExpr))
3836 ReceiverType = Context.getObjCObjectPointerType(
3837 Context.getObjCInterfaceType(IFace));
Douglas Gregor36ecb042009-11-17 23:22:23 +00003838
Douglas Gregorf74a4192009-11-18 00:06:18 +00003839 // Handle messages to Class. This really isn't a message to an instance
3840 // method, so we treat it the same way we would treat a message send to a
3841 // class method.
3842 if (ReceiverType->isObjCClassType() ||
3843 ReceiverType->isObjCQualifiedClassType()) {
3844 if (ObjCMethodDecl *CurMethod = getCurMethodDecl()) {
3845 if (ObjCInterfaceDecl *ClassDecl = CurMethod->getClassInterface())
Douglas Gregor4ad96852009-11-19 07:41:15 +00003846 AddObjCMethods(ClassDecl, false, MK_Any, SelIdents, NumSelIdents,
3847 CurContext, Results);
Douglas Gregorf74a4192009-11-18 00:06:18 +00003848 }
3849 }
3850 // Handle messages to a qualified ID ("id<foo>").
3851 else if (const ObjCObjectPointerType *QualID
3852 = ReceiverType->getAsObjCQualifiedIdType()) {
3853 // Search protocols for instance methods.
3854 for (ObjCObjectPointerType::qual_iterator I = QualID->qual_begin(),
3855 E = QualID->qual_end();
3856 I != E; ++I)
Douglas Gregor4ad96852009-11-19 07:41:15 +00003857 AddObjCMethods(*I, true, MK_Any, SelIdents, NumSelIdents, CurContext,
3858 Results);
Douglas Gregorf74a4192009-11-18 00:06:18 +00003859 }
3860 // Handle messages to a pointer to interface type.
3861 else if (const ObjCObjectPointerType *IFacePtr
3862 = ReceiverType->getAsObjCInterfacePointerType()) {
3863 // Search the class, its superclasses, etc., for instance methods.
Douglas Gregor4ad96852009-11-19 07:41:15 +00003864 AddObjCMethods(IFacePtr->getInterfaceDecl(), true, MK_Any, SelIdents,
3865 NumSelIdents, CurContext, Results);
Douglas Gregorf74a4192009-11-18 00:06:18 +00003866
3867 // Search protocols for instance methods.
3868 for (ObjCObjectPointerType::qual_iterator I = IFacePtr->qual_begin(),
3869 E = IFacePtr->qual_end();
3870 I != E; ++I)
Douglas Gregor4ad96852009-11-19 07:41:15 +00003871 AddObjCMethods(*I, true, MK_Any, SelIdents, NumSelIdents, CurContext,
3872 Results);
Douglas Gregorf74a4192009-11-18 00:06:18 +00003873 }
Douglas Gregor13438f92010-04-06 16:40:00 +00003874 // Handle messages to "id".
3875 else if (ReceiverType->isObjCIdType()) {
Douglas Gregor719770d2010-04-06 17:30:22 +00003876 // We're messaging "id", so provide all instance methods we know
3877 // about as code-completion results.
3878
3879 // If we have an external source, load the entire class method
Sebastian Redl3c7f4132010-08-18 23:57:06 +00003880 // pool from the AST file.
Douglas Gregor719770d2010-04-06 17:30:22 +00003881 if (ExternalSource) {
John McCall76bd1f32010-06-01 09:23:16 +00003882 for (uint32_t I = 0, N = ExternalSource->GetNumExternalSelectors();
3883 I != N; ++I) {
3884 Selector Sel = ExternalSource->GetExternalSelector(I);
Sebastian Redldb9d2142010-08-02 23:18:59 +00003885 if (Sel.isNull() || MethodPool.count(Sel))
Douglas Gregor719770d2010-04-06 17:30:22 +00003886 continue;
3887
Sebastian Redldb9d2142010-08-02 23:18:59 +00003888 ReadMethodPool(Sel);
Douglas Gregor719770d2010-04-06 17:30:22 +00003889 }
3890 }
3891
Sebastian Redldb9d2142010-08-02 23:18:59 +00003892 for (GlobalMethodPool::iterator M = MethodPool.begin(),
3893 MEnd = MethodPool.end();
3894 M != MEnd; ++M) {
3895 for (ObjCMethodList *MethList = &M->second.first;
3896 MethList && MethList->Method;
Douglas Gregor13438f92010-04-06 16:40:00 +00003897 MethList = MethList->Next) {
3898 if (!isAcceptableObjCMethod(MethList->Method, MK_Any, SelIdents,
3899 NumSelIdents))
3900 continue;
3901
3902 Result R(MethList->Method, 0);
3903 R.StartParameter = NumSelIdents;
3904 R.AllParametersAreInformative = false;
3905 Results.MaybeAddResult(R, CurContext);
3906 }
3907 }
3908 }
3909
Steve Naroffc4df6d22009-11-07 02:08:14 +00003910 Results.ExitScope();
Douglas Gregore6b1bb62010-08-11 21:23:17 +00003911 HandleCodeCompleteResults(this, CodeCompleter,
3912 CodeCompletionContext::CCC_Other,
3913 Results.data(),Results.size());
Steve Naroffc4df6d22009-11-07 02:08:14 +00003914}
Douglas Gregor55385fe2009-11-18 04:19:12 +00003915
Douglas Gregorfb629412010-08-23 21:17:50 +00003916void Sema::CodeCompleteObjCForCollection(Scope *S,
3917 DeclGroupPtrTy IterationVar) {
3918 CodeCompleteExpressionData Data;
3919 Data.ObjCCollection = true;
3920
3921 if (IterationVar.getAsOpaquePtr()) {
3922 DeclGroupRef DG = IterationVar.getAsVal<DeclGroupRef>();
3923 for (DeclGroupRef::iterator I = DG.begin(), End = DG.end(); I != End; ++I) {
3924 if (*I)
3925 Data.IgnoreDecls.push_back(*I);
3926 }
3927 }
3928
3929 CodeCompleteExpression(S, Data);
3930}
3931
Douglas Gregor55385fe2009-11-18 04:19:12 +00003932/// \brief Add all of the protocol declarations that we find in the given
3933/// (translation unit) context.
3934static void AddProtocolResults(DeclContext *Ctx, DeclContext *CurContext,
Douglas Gregor083128f2009-11-18 04:49:41 +00003935 bool OnlyForwardDeclarations,
Douglas Gregor55385fe2009-11-18 04:19:12 +00003936 ResultBuilder &Results) {
3937 typedef CodeCompleteConsumer::Result Result;
3938
3939 for (DeclContext::decl_iterator D = Ctx->decls_begin(),
3940 DEnd = Ctx->decls_end();
3941 D != DEnd; ++D) {
3942 // Record any protocols we find.
3943 if (ObjCProtocolDecl *Proto = dyn_cast<ObjCProtocolDecl>(*D))
Douglas Gregor083128f2009-11-18 04:49:41 +00003944 if (!OnlyForwardDeclarations || Proto->isForwardDecl())
Douglas Gregor608300b2010-01-14 16:14:35 +00003945 Results.AddResult(Result(Proto, 0), CurContext, 0, false);
Douglas Gregor55385fe2009-11-18 04:19:12 +00003946
3947 // Record any forward-declared protocols we find.
3948 if (ObjCForwardProtocolDecl *Forward
3949 = dyn_cast<ObjCForwardProtocolDecl>(*D)) {
3950 for (ObjCForwardProtocolDecl::protocol_iterator
3951 P = Forward->protocol_begin(),
3952 PEnd = Forward->protocol_end();
3953 P != PEnd; ++P)
Douglas Gregor083128f2009-11-18 04:49:41 +00003954 if (!OnlyForwardDeclarations || (*P)->isForwardDecl())
Douglas Gregor608300b2010-01-14 16:14:35 +00003955 Results.AddResult(Result(*P, 0), CurContext, 0, false);
Douglas Gregor55385fe2009-11-18 04:19:12 +00003956 }
3957 }
3958}
3959
3960void Sema::CodeCompleteObjCProtocolReferences(IdentifierLocPair *Protocols,
3961 unsigned NumProtocols) {
3962 ResultBuilder Results(*this);
3963 Results.EnterNewScope();
3964
3965 // Tell the result set to ignore all of the protocols we have
3966 // already seen.
3967 for (unsigned I = 0; I != NumProtocols; ++I)
Douglas Gregorc83c6872010-04-15 22:33:43 +00003968 if (ObjCProtocolDecl *Protocol = LookupProtocol(Protocols[I].first,
3969 Protocols[I].second))
Douglas Gregor55385fe2009-11-18 04:19:12 +00003970 Results.Ignore(Protocol);
3971
3972 // Add all protocols.
Douglas Gregor083128f2009-11-18 04:49:41 +00003973 AddProtocolResults(Context.getTranslationUnitDecl(), CurContext, false,
3974 Results);
3975
3976 Results.ExitScope();
Douglas Gregore6b1bb62010-08-11 21:23:17 +00003977 HandleCodeCompleteResults(this, CodeCompleter,
3978 CodeCompletionContext::CCC_ObjCProtocolName,
3979 Results.data(),Results.size());
Douglas Gregor083128f2009-11-18 04:49:41 +00003980}
3981
3982void Sema::CodeCompleteObjCProtocolDecl(Scope *) {
3983 ResultBuilder Results(*this);
3984 Results.EnterNewScope();
3985
3986 // Add all protocols.
3987 AddProtocolResults(Context.getTranslationUnitDecl(), CurContext, true,
3988 Results);
Douglas Gregor55385fe2009-11-18 04:19:12 +00003989
3990 Results.ExitScope();
Douglas Gregore6b1bb62010-08-11 21:23:17 +00003991 HandleCodeCompleteResults(this, CodeCompleter,
3992 CodeCompletionContext::CCC_ObjCProtocolName,
3993 Results.data(),Results.size());
Douglas Gregor55385fe2009-11-18 04:19:12 +00003994}
Douglas Gregor3b49aca2009-11-18 16:26:39 +00003995
3996/// \brief Add all of the Objective-C interface declarations that we find in
3997/// the given (translation unit) context.
3998static void AddInterfaceResults(DeclContext *Ctx, DeclContext *CurContext,
3999 bool OnlyForwardDeclarations,
4000 bool OnlyUnimplemented,
4001 ResultBuilder &Results) {
4002 typedef CodeCompleteConsumer::Result Result;
4003
4004 for (DeclContext::decl_iterator D = Ctx->decls_begin(),
4005 DEnd = Ctx->decls_end();
4006 D != DEnd; ++D) {
Douglas Gregordeacbdc2010-08-11 12:19:30 +00004007 // Record any interfaces we find.
4008 if (ObjCInterfaceDecl *Class = dyn_cast<ObjCInterfaceDecl>(*D))
4009 if ((!OnlyForwardDeclarations || Class->isForwardDecl()) &&
4010 (!OnlyUnimplemented || !Class->getImplementation()))
4011 Results.AddResult(Result(Class, 0), CurContext, 0, false);
Douglas Gregor3b49aca2009-11-18 16:26:39 +00004012
4013 // Record any forward-declared interfaces we find.
4014 if (ObjCClassDecl *Forward = dyn_cast<ObjCClassDecl>(*D)) {
4015 for (ObjCClassDecl::iterator C = Forward->begin(), CEnd = Forward->end();
Douglas Gregordeacbdc2010-08-11 12:19:30 +00004016 C != CEnd; ++C)
4017 if ((!OnlyForwardDeclarations || C->getInterface()->isForwardDecl()) &&
4018 (!OnlyUnimplemented || !C->getInterface()->getImplementation()))
4019 Results.AddResult(Result(C->getInterface(), 0), CurContext,
Douglas Gregor608300b2010-01-14 16:14:35 +00004020 0, false);
Douglas Gregor3b49aca2009-11-18 16:26:39 +00004021 }
4022 }
4023}
4024
4025void Sema::CodeCompleteObjCInterfaceDecl(Scope *S) {
4026 ResultBuilder Results(*this);
4027 Results.EnterNewScope();
4028
4029 // Add all classes.
4030 AddInterfaceResults(Context.getTranslationUnitDecl(), CurContext, true,
4031 false, Results);
4032
4033 Results.ExitScope();
Douglas Gregore6b1bb62010-08-11 21:23:17 +00004034 HandleCodeCompleteResults(this, CodeCompleter,
4035 CodeCompletionContext::CCC_Other,
4036 Results.data(),Results.size());
Douglas Gregor3b49aca2009-11-18 16:26:39 +00004037}
4038
Douglas Gregorc83c6872010-04-15 22:33:43 +00004039void Sema::CodeCompleteObjCSuperclass(Scope *S, IdentifierInfo *ClassName,
4040 SourceLocation ClassNameLoc) {
Douglas Gregor3b49aca2009-11-18 16:26:39 +00004041 ResultBuilder Results(*this);
4042 Results.EnterNewScope();
4043
4044 // Make sure that we ignore the class we're currently defining.
4045 NamedDecl *CurClass
Douglas Gregorc83c6872010-04-15 22:33:43 +00004046 = LookupSingleName(TUScope, ClassName, ClassNameLoc, LookupOrdinaryName);
Douglas Gregor33ced0b2009-11-18 19:08:43 +00004047 if (CurClass && isa<ObjCInterfaceDecl>(CurClass))
Douglas Gregor3b49aca2009-11-18 16:26:39 +00004048 Results.Ignore(CurClass);
4049
4050 // Add all classes.
4051 AddInterfaceResults(Context.getTranslationUnitDecl(), CurContext, false,
4052 false, Results);
4053
4054 Results.ExitScope();
Douglas Gregore6b1bb62010-08-11 21:23:17 +00004055 HandleCodeCompleteResults(this, CodeCompleter,
4056 CodeCompletionContext::CCC_Other,
4057 Results.data(),Results.size());
Douglas Gregor3b49aca2009-11-18 16:26:39 +00004058}
4059
4060void Sema::CodeCompleteObjCImplementationDecl(Scope *S) {
4061 ResultBuilder Results(*this);
4062 Results.EnterNewScope();
4063
4064 // Add all unimplemented classes.
4065 AddInterfaceResults(Context.getTranslationUnitDecl(), CurContext, false,
4066 true, Results);
4067
4068 Results.ExitScope();
Douglas Gregore6b1bb62010-08-11 21:23:17 +00004069 HandleCodeCompleteResults(this, CodeCompleter,
4070 CodeCompletionContext::CCC_Other,
4071 Results.data(),Results.size());
Douglas Gregor3b49aca2009-11-18 16:26:39 +00004072}
Douglas Gregor33ced0b2009-11-18 19:08:43 +00004073
4074void Sema::CodeCompleteObjCInterfaceCategory(Scope *S,
Douglas Gregorc83c6872010-04-15 22:33:43 +00004075 IdentifierInfo *ClassName,
4076 SourceLocation ClassNameLoc) {
Douglas Gregor33ced0b2009-11-18 19:08:43 +00004077 typedef CodeCompleteConsumer::Result Result;
4078
4079 ResultBuilder Results(*this);
4080
4081 // Ignore any categories we find that have already been implemented by this
4082 // interface.
4083 llvm::SmallPtrSet<IdentifierInfo *, 16> CategoryNames;
4084 NamedDecl *CurClass
Douglas Gregorc83c6872010-04-15 22:33:43 +00004085 = LookupSingleName(TUScope, ClassName, ClassNameLoc, LookupOrdinaryName);
Douglas Gregor33ced0b2009-11-18 19:08:43 +00004086 if (ObjCInterfaceDecl *Class = dyn_cast_or_null<ObjCInterfaceDecl>(CurClass))
4087 for (ObjCCategoryDecl *Category = Class->getCategoryList(); Category;
4088 Category = Category->getNextClassCategory())
4089 CategoryNames.insert(Category->getIdentifier());
4090
4091 // Add all of the categories we know about.
4092 Results.EnterNewScope();
4093 TranslationUnitDecl *TU = Context.getTranslationUnitDecl();
4094 for (DeclContext::decl_iterator D = TU->decls_begin(),
4095 DEnd = TU->decls_end();
4096 D != DEnd; ++D)
4097 if (ObjCCategoryDecl *Category = dyn_cast<ObjCCategoryDecl>(*D))
4098 if (CategoryNames.insert(Category->getIdentifier()))
Douglas Gregor608300b2010-01-14 16:14:35 +00004099 Results.AddResult(Result(Category, 0), CurContext, 0, false);
Douglas Gregor33ced0b2009-11-18 19:08:43 +00004100 Results.ExitScope();
4101
Douglas Gregore6b1bb62010-08-11 21:23:17 +00004102 HandleCodeCompleteResults(this, CodeCompleter,
4103 CodeCompletionContext::CCC_Other,
4104 Results.data(),Results.size());
Douglas Gregor33ced0b2009-11-18 19:08:43 +00004105}
4106
4107void Sema::CodeCompleteObjCImplementationCategory(Scope *S,
Douglas Gregorc83c6872010-04-15 22:33:43 +00004108 IdentifierInfo *ClassName,
4109 SourceLocation ClassNameLoc) {
Douglas Gregor33ced0b2009-11-18 19:08:43 +00004110 typedef CodeCompleteConsumer::Result Result;
4111
4112 // Find the corresponding interface. If we couldn't find the interface, the
4113 // program itself is ill-formed. However, we'll try to be helpful still by
4114 // providing the list of all of the categories we know about.
4115 NamedDecl *CurClass
Douglas Gregorc83c6872010-04-15 22:33:43 +00004116 = LookupSingleName(TUScope, ClassName, ClassNameLoc, LookupOrdinaryName);
Douglas Gregor33ced0b2009-11-18 19:08:43 +00004117 ObjCInterfaceDecl *Class = dyn_cast_or_null<ObjCInterfaceDecl>(CurClass);
4118 if (!Class)
Douglas Gregorc83c6872010-04-15 22:33:43 +00004119 return CodeCompleteObjCInterfaceCategory(S, ClassName, ClassNameLoc);
Douglas Gregor33ced0b2009-11-18 19:08:43 +00004120
4121 ResultBuilder Results(*this);
4122
4123 // Add all of the categories that have have corresponding interface
4124 // declarations in this class and any of its superclasses, except for
4125 // already-implemented categories in the class itself.
4126 llvm::SmallPtrSet<IdentifierInfo *, 16> CategoryNames;
4127 Results.EnterNewScope();
4128 bool IgnoreImplemented = true;
4129 while (Class) {
4130 for (ObjCCategoryDecl *Category = Class->getCategoryList(); Category;
4131 Category = Category->getNextClassCategory())
4132 if ((!IgnoreImplemented || !Category->getImplementation()) &&
4133 CategoryNames.insert(Category->getIdentifier()))
Douglas Gregor608300b2010-01-14 16:14:35 +00004134 Results.AddResult(Result(Category, 0), CurContext, 0, false);
Douglas Gregor33ced0b2009-11-18 19:08:43 +00004135
4136 Class = Class->getSuperClass();
4137 IgnoreImplemented = false;
4138 }
4139 Results.ExitScope();
4140
Douglas Gregore6b1bb62010-08-11 21:23:17 +00004141 HandleCodeCompleteResults(this, CodeCompleter,
4142 CodeCompletionContext::CCC_Other,
4143 Results.data(),Results.size());
Douglas Gregor33ced0b2009-11-18 19:08:43 +00004144}
Douglas Gregor322328b2009-11-18 22:32:06 +00004145
John McCalld226f652010-08-21 09:40:31 +00004146void Sema::CodeCompleteObjCPropertyDefinition(Scope *S, Decl *ObjCImpDecl) {
Douglas Gregor322328b2009-11-18 22:32:06 +00004147 typedef CodeCompleteConsumer::Result Result;
4148 ResultBuilder Results(*this);
4149
4150 // Figure out where this @synthesize lives.
4151 ObjCContainerDecl *Container
John McCalld226f652010-08-21 09:40:31 +00004152 = dyn_cast_or_null<ObjCContainerDecl>(ObjCImpDecl);
Douglas Gregor322328b2009-11-18 22:32:06 +00004153 if (!Container ||
4154 (!isa<ObjCImplementationDecl>(Container) &&
4155 !isa<ObjCCategoryImplDecl>(Container)))
4156 return;
4157
4158 // Ignore any properties that have already been implemented.
4159 for (DeclContext::decl_iterator D = Container->decls_begin(),
4160 DEnd = Container->decls_end();
4161 D != DEnd; ++D)
4162 if (ObjCPropertyImplDecl *PropertyImpl = dyn_cast<ObjCPropertyImplDecl>(*D))
4163 Results.Ignore(PropertyImpl->getPropertyDecl());
4164
4165 // Add any properties that we find.
4166 Results.EnterNewScope();
4167 if (ObjCImplementationDecl *ClassImpl
4168 = dyn_cast<ObjCImplementationDecl>(Container))
4169 AddObjCProperties(ClassImpl->getClassInterface(), false, CurContext,
4170 Results);
4171 else
4172 AddObjCProperties(cast<ObjCCategoryImplDecl>(Container)->getCategoryDecl(),
4173 false, CurContext, Results);
4174 Results.ExitScope();
4175
Douglas Gregore6b1bb62010-08-11 21:23:17 +00004176 HandleCodeCompleteResults(this, CodeCompleter,
4177 CodeCompletionContext::CCC_Other,
4178 Results.data(),Results.size());
Douglas Gregor322328b2009-11-18 22:32:06 +00004179}
4180
4181void Sema::CodeCompleteObjCPropertySynthesizeIvar(Scope *S,
4182 IdentifierInfo *PropertyName,
John McCalld226f652010-08-21 09:40:31 +00004183 Decl *ObjCImpDecl) {
Douglas Gregor322328b2009-11-18 22:32:06 +00004184 typedef CodeCompleteConsumer::Result Result;
4185 ResultBuilder Results(*this);
4186
4187 // Figure out where this @synthesize lives.
4188 ObjCContainerDecl *Container
John McCalld226f652010-08-21 09:40:31 +00004189 = dyn_cast_or_null<ObjCContainerDecl>(ObjCImpDecl);
Douglas Gregor322328b2009-11-18 22:32:06 +00004190 if (!Container ||
4191 (!isa<ObjCImplementationDecl>(Container) &&
4192 !isa<ObjCCategoryImplDecl>(Container)))
4193 return;
4194
4195 // Figure out which interface we're looking into.
4196 ObjCInterfaceDecl *Class = 0;
4197 if (ObjCImplementationDecl *ClassImpl
4198 = dyn_cast<ObjCImplementationDecl>(Container))
4199 Class = ClassImpl->getClassInterface();
4200 else
4201 Class = cast<ObjCCategoryImplDecl>(Container)->getCategoryDecl()
4202 ->getClassInterface();
4203
4204 // Add all of the instance variables in this class and its superclasses.
4205 Results.EnterNewScope();
4206 for(; Class; Class = Class->getSuperClass()) {
4207 // FIXME: We could screen the type of each ivar for compatibility with
4208 // the property, but is that being too paternal?
4209 for (ObjCInterfaceDecl::ivar_iterator IVar = Class->ivar_begin(),
4210 IVarEnd = Class->ivar_end();
4211 IVar != IVarEnd; ++IVar)
Douglas Gregor608300b2010-01-14 16:14:35 +00004212 Results.AddResult(Result(*IVar, 0), CurContext, 0, false);
Douglas Gregor322328b2009-11-18 22:32:06 +00004213 }
4214 Results.ExitScope();
4215
Douglas Gregore6b1bb62010-08-11 21:23:17 +00004216 HandleCodeCompleteResults(this, CodeCompleter,
4217 CodeCompletionContext::CCC_Other,
4218 Results.data(),Results.size());
Douglas Gregor322328b2009-11-18 22:32:06 +00004219}
Douglas Gregore8f5a172010-04-07 00:21:17 +00004220
4221typedef llvm::DenseMap<Selector, ObjCMethodDecl *> KnownMethodsMap;
4222
4223/// \brief Find all of the methods that reside in the given container
4224/// (and its superclasses, protocols, etc.) that meet the given
4225/// criteria. Insert those methods into the map of known methods,
4226/// indexed by selector so they can be easily found.
4227static void FindImplementableMethods(ASTContext &Context,
4228 ObjCContainerDecl *Container,
4229 bool WantInstanceMethods,
4230 QualType ReturnType,
4231 bool IsInImplementation,
4232 KnownMethodsMap &KnownMethods) {
4233 if (ObjCInterfaceDecl *IFace = dyn_cast<ObjCInterfaceDecl>(Container)) {
4234 // Recurse into protocols.
4235 const ObjCList<ObjCProtocolDecl> &Protocols
4236 = IFace->getReferencedProtocols();
4237 for (ObjCList<ObjCProtocolDecl>::iterator I = Protocols.begin(),
4238 E = Protocols.end();
4239 I != E; ++I)
4240 FindImplementableMethods(Context, *I, WantInstanceMethods, ReturnType,
4241 IsInImplementation, KnownMethods);
4242
4243 // If we're not in the implementation of a class, also visit the
4244 // superclass.
4245 if (!IsInImplementation && IFace->getSuperClass())
4246 FindImplementableMethods(Context, IFace->getSuperClass(),
4247 WantInstanceMethods, ReturnType,
4248 IsInImplementation, KnownMethods);
4249
4250 // Add methods from any class extensions (but not from categories;
4251 // those should go into category implementations).
Fariborz Jahanian80aa1cd2010-06-22 23:20:40 +00004252 for (const ObjCCategoryDecl *Cat = IFace->getFirstClassExtension(); Cat;
4253 Cat = Cat->getNextClassExtension())
4254 FindImplementableMethods(Context, const_cast<ObjCCategoryDecl*>(Cat),
4255 WantInstanceMethods, ReturnType,
Douglas Gregore8f5a172010-04-07 00:21:17 +00004256 IsInImplementation, KnownMethods);
Douglas Gregore8f5a172010-04-07 00:21:17 +00004257 }
4258
4259 if (ObjCCategoryDecl *Category = dyn_cast<ObjCCategoryDecl>(Container)) {
4260 // Recurse into protocols.
4261 const ObjCList<ObjCProtocolDecl> &Protocols
4262 = Category->getReferencedProtocols();
4263 for (ObjCList<ObjCProtocolDecl>::iterator I = Protocols.begin(),
4264 E = Protocols.end();
4265 I != E; ++I)
4266 FindImplementableMethods(Context, *I, WantInstanceMethods, ReturnType,
4267 IsInImplementation, KnownMethods);
4268 }
4269
4270 if (ObjCProtocolDecl *Protocol = dyn_cast<ObjCProtocolDecl>(Container)) {
4271 // Recurse into protocols.
4272 const ObjCList<ObjCProtocolDecl> &Protocols
4273 = Protocol->getReferencedProtocols();
4274 for (ObjCList<ObjCProtocolDecl>::iterator I = Protocols.begin(),
4275 E = Protocols.end();
4276 I != E; ++I)
4277 FindImplementableMethods(Context, *I, WantInstanceMethods, ReturnType,
4278 IsInImplementation, KnownMethods);
4279 }
4280
4281 // Add methods in this container. This operation occurs last because
4282 // we want the methods from this container to override any methods
4283 // we've previously seen with the same selector.
4284 for (ObjCContainerDecl::method_iterator M = Container->meth_begin(),
4285 MEnd = Container->meth_end();
4286 M != MEnd; ++M) {
4287 if ((*M)->isInstanceMethod() == WantInstanceMethods) {
4288 if (!ReturnType.isNull() &&
4289 !Context.hasSameUnqualifiedType(ReturnType, (*M)->getResultType()))
4290 continue;
4291
4292 KnownMethods[(*M)->getSelector()] = *M;
4293 }
4294 }
4295}
4296
4297void Sema::CodeCompleteObjCMethodDecl(Scope *S,
4298 bool IsInstanceMethod,
John McCallb3d87482010-08-24 05:47:05 +00004299 ParsedType ReturnTy,
John McCalld226f652010-08-21 09:40:31 +00004300 Decl *IDecl) {
Douglas Gregore8f5a172010-04-07 00:21:17 +00004301 // Determine the return type of the method we're declaring, if
4302 // provided.
4303 QualType ReturnType = GetTypeFromParser(ReturnTy);
4304
4305 // Determine where we should start searching for methods, and where we
4306 ObjCContainerDecl *SearchDecl = 0, *CurrentDecl = 0;
4307 bool IsInImplementation = false;
John McCalld226f652010-08-21 09:40:31 +00004308 if (Decl *D = IDecl) {
Douglas Gregore8f5a172010-04-07 00:21:17 +00004309 if (ObjCImplementationDecl *Impl = dyn_cast<ObjCImplementationDecl>(D)) {
4310 SearchDecl = Impl->getClassInterface();
4311 CurrentDecl = Impl;
4312 IsInImplementation = true;
4313 } else if (ObjCCategoryImplDecl *CatImpl
4314 = dyn_cast<ObjCCategoryImplDecl>(D)) {
4315 SearchDecl = CatImpl->getCategoryDecl();
4316 CurrentDecl = CatImpl;
4317 IsInImplementation = true;
4318 } else {
4319 SearchDecl = dyn_cast<ObjCContainerDecl>(D);
4320 CurrentDecl = SearchDecl;
4321 }
4322 }
4323
4324 if (!SearchDecl && S) {
4325 if (DeclContext *DC = static_cast<DeclContext *>(S->getEntity())) {
4326 SearchDecl = dyn_cast<ObjCContainerDecl>(DC);
4327 CurrentDecl = SearchDecl;
4328 }
4329 }
4330
4331 if (!SearchDecl || !CurrentDecl) {
Douglas Gregore6b1bb62010-08-11 21:23:17 +00004332 HandleCodeCompleteResults(this, CodeCompleter,
4333 CodeCompletionContext::CCC_Other,
4334 0, 0);
Douglas Gregore8f5a172010-04-07 00:21:17 +00004335 return;
4336 }
4337
4338 // Find all of the methods that we could declare/implement here.
4339 KnownMethodsMap KnownMethods;
4340 FindImplementableMethods(Context, SearchDecl, IsInstanceMethod,
4341 ReturnType, IsInImplementation, KnownMethods);
4342
4343 // Erase any methods that have already been declared or
4344 // implemented here.
4345 for (ObjCContainerDecl::method_iterator M = CurrentDecl->meth_begin(),
4346 MEnd = CurrentDecl->meth_end();
4347 M != MEnd; ++M) {
4348 if ((*M)->isInstanceMethod() != IsInstanceMethod)
4349 continue;
4350
4351 KnownMethodsMap::iterator Pos = KnownMethods.find((*M)->getSelector());
4352 if (Pos != KnownMethods.end())
4353 KnownMethods.erase(Pos);
4354 }
4355
4356 // Add declarations or definitions for each of the known methods.
4357 typedef CodeCompleteConsumer::Result Result;
4358 ResultBuilder Results(*this);
4359 Results.EnterNewScope();
4360 PrintingPolicy Policy(Context.PrintingPolicy);
4361 Policy.AnonymousTagLocations = false;
4362 for (KnownMethodsMap::iterator M = KnownMethods.begin(),
4363 MEnd = KnownMethods.end();
4364 M != MEnd; ++M) {
4365 ObjCMethodDecl *Method = M->second;
4366 CodeCompletionString *Pattern = new CodeCompletionString;
4367
4368 // If the result type was not already provided, add it to the
4369 // pattern as (type).
4370 if (ReturnType.isNull()) {
4371 std::string TypeStr;
4372 Method->getResultType().getAsStringInternal(TypeStr, Policy);
4373 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
4374 Pattern->AddTextChunk(TypeStr);
4375 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
4376 }
4377
4378 Selector Sel = Method->getSelector();
4379
4380 // Add the first part of the selector to the pattern.
4381 Pattern->AddTypedTextChunk(Sel.getIdentifierInfoForSlot(0)->getName());
4382
4383 // Add parameters to the pattern.
4384 unsigned I = 0;
4385 for (ObjCMethodDecl::param_iterator P = Method->param_begin(),
4386 PEnd = Method->param_end();
4387 P != PEnd; (void)++P, ++I) {
4388 // Add the part of the selector name.
4389 if (I == 0)
4390 Pattern->AddChunk(CodeCompletionString::CK_Colon);
4391 else if (I < Sel.getNumArgs()) {
4392 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
Douglas Gregor47c03a72010-08-17 15:53:35 +00004393 Pattern->AddTextChunk(Sel.getIdentifierInfoForSlot(I)->getName());
Douglas Gregore8f5a172010-04-07 00:21:17 +00004394 Pattern->AddChunk(CodeCompletionString::CK_Colon);
4395 } else
4396 break;
4397
4398 // Add the parameter type.
4399 std::string TypeStr;
4400 (*P)->getOriginalType().getAsStringInternal(TypeStr, Policy);
4401 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
4402 Pattern->AddTextChunk(TypeStr);
4403 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
4404
4405 if (IdentifierInfo *Id = (*P)->getIdentifier())
4406 Pattern->AddTextChunk(Id->getName());
4407 }
4408
4409 if (Method->isVariadic()) {
4410 if (Method->param_size() > 0)
4411 Pattern->AddChunk(CodeCompletionString::CK_Comma);
4412 Pattern->AddTextChunk("...");
4413 }
4414
Douglas Gregor447107d2010-05-28 00:57:46 +00004415 if (IsInImplementation && Results.includeCodePatterns()) {
Douglas Gregore8f5a172010-04-07 00:21:17 +00004416 // We will be defining the method here, so add a compound statement.
4417 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
4418 Pattern->AddChunk(CodeCompletionString::CK_LeftBrace);
4419 Pattern->AddChunk(CodeCompletionString::CK_VerticalSpace);
4420 if (!Method->getResultType()->isVoidType()) {
4421 // If the result type is not void, add a return clause.
4422 Pattern->AddTextChunk("return");
4423 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
4424 Pattern->AddPlaceholderChunk("expression");
4425 Pattern->AddChunk(CodeCompletionString::CK_SemiColon);
4426 } else
4427 Pattern->AddPlaceholderChunk("statements");
4428
4429 Pattern->AddChunk(CodeCompletionString::CK_VerticalSpace);
4430 Pattern->AddChunk(CodeCompletionString::CK_RightBrace);
4431 }
4432
Douglas Gregor16ed9ad2010-08-17 16:06:07 +00004433 Results.AddResult(Result(Pattern, CCP_CodePattern,
4434 Method->isInstanceMethod()
4435 ? CXCursor_ObjCInstanceMethodDecl
4436 : CXCursor_ObjCClassMethodDecl));
Douglas Gregore8f5a172010-04-07 00:21:17 +00004437 }
4438
4439 Results.ExitScope();
4440
Douglas Gregore6b1bb62010-08-11 21:23:17 +00004441 HandleCodeCompleteResults(this, CodeCompleter,
4442 CodeCompletionContext::CCC_Other,
4443 Results.data(),Results.size());
Douglas Gregore8f5a172010-04-07 00:21:17 +00004444}
Douglas Gregor1f5537a2010-07-08 23:20:03 +00004445
4446void Sema::CodeCompleteObjCMethodDeclSelector(Scope *S,
4447 bool IsInstanceMethod,
Douglas Gregor40ed9a12010-07-08 23:37:41 +00004448 bool AtParameterName,
John McCallb3d87482010-08-24 05:47:05 +00004449 ParsedType ReturnTy,
Douglas Gregor1f5537a2010-07-08 23:20:03 +00004450 IdentifierInfo **SelIdents,
4451 unsigned NumSelIdents) {
Douglas Gregor1f5537a2010-07-08 23:20:03 +00004452 // If we have an external source, load the entire class method
Sebastian Redl3c7f4132010-08-18 23:57:06 +00004453 // pool from the AST file.
Douglas Gregor1f5537a2010-07-08 23:20:03 +00004454 if (ExternalSource) {
4455 for (uint32_t I = 0, N = ExternalSource->GetNumExternalSelectors();
4456 I != N; ++I) {
4457 Selector Sel = ExternalSource->GetExternalSelector(I);
Sebastian Redldb9d2142010-08-02 23:18:59 +00004458 if (Sel.isNull() || MethodPool.count(Sel))
Douglas Gregor1f5537a2010-07-08 23:20:03 +00004459 continue;
Sebastian Redldb9d2142010-08-02 23:18:59 +00004460
4461 ReadMethodPool(Sel);
Douglas Gregor1f5537a2010-07-08 23:20:03 +00004462 }
4463 }
4464
4465 // Build the set of methods we can see.
4466 typedef CodeCompleteConsumer::Result Result;
4467 ResultBuilder Results(*this);
4468
4469 if (ReturnTy)
4470 Results.setPreferredType(GetTypeFromParser(ReturnTy).getNonReferenceType());
Sebastian Redldb9d2142010-08-02 23:18:59 +00004471
Douglas Gregor1f5537a2010-07-08 23:20:03 +00004472 Results.EnterNewScope();
Sebastian Redldb9d2142010-08-02 23:18:59 +00004473 for (GlobalMethodPool::iterator M = MethodPool.begin(),
4474 MEnd = MethodPool.end();
4475 M != MEnd; ++M) {
4476 for (ObjCMethodList *MethList = IsInstanceMethod ? &M->second.first :
4477 &M->second.second;
4478 MethList && MethList->Method;
Douglas Gregor1f5537a2010-07-08 23:20:03 +00004479 MethList = MethList->Next) {
4480 if (!isAcceptableObjCMethod(MethList->Method, MK_Any, SelIdents,
4481 NumSelIdents))
4482 continue;
4483
Douglas Gregor40ed9a12010-07-08 23:37:41 +00004484 if (AtParameterName) {
4485 // Suggest parameter names we've seen before.
4486 if (NumSelIdents && NumSelIdents <= MethList->Method->param_size()) {
4487 ParmVarDecl *Param = MethList->Method->param_begin()[NumSelIdents-1];
4488 if (Param->getIdentifier()) {
4489 CodeCompletionString *Pattern = new CodeCompletionString;
4490 Pattern->AddTypedTextChunk(Param->getIdentifier()->getName());
4491 Results.AddResult(Pattern);
4492 }
4493 }
4494
4495 continue;
4496 }
4497
Douglas Gregor1f5537a2010-07-08 23:20:03 +00004498 Result R(MethList->Method, 0);
4499 R.StartParameter = NumSelIdents;
4500 R.AllParametersAreInformative = false;
4501 R.DeclaringEntity = true;
4502 Results.MaybeAddResult(R, CurContext);
4503 }
4504 }
4505
4506 Results.ExitScope();
Douglas Gregore6b1bb62010-08-11 21:23:17 +00004507 HandleCodeCompleteResults(this, CodeCompleter,
4508 CodeCompletionContext::CCC_Other,
4509 Results.data(),Results.size());
Douglas Gregor1f5537a2010-07-08 23:20:03 +00004510}
Douglas Gregor87c08a52010-08-13 22:48:40 +00004511
4512void Sema::GatherGlobalCodeCompletions(
4513 llvm::SmallVectorImpl<CodeCompleteConsumer::Result> &Results) {
4514 ResultBuilder Builder(*this);
4515
Douglas Gregor8071e422010-08-15 06:18:01 +00004516 if (!CodeCompleter || CodeCompleter->includeGlobals()) {
4517 CodeCompletionDeclConsumer Consumer(Builder,
4518 Context.getTranslationUnitDecl());
4519 LookupVisibleDecls(Context.getTranslationUnitDecl(), LookupAnyName,
4520 Consumer);
4521 }
Douglas Gregor87c08a52010-08-13 22:48:40 +00004522
4523 if (!CodeCompleter || CodeCompleter->includeMacros())
4524 AddMacroResults(PP, Builder);
4525
4526 Results.clear();
4527 Results.insert(Results.end(),
4528 Builder.data(), Builder.data() + Builder.size());
4529}