blob: 14043e8b62c354e466b7ed7149b23106ae06eeb0 [file] [log] [blame]
Douglas Gregor2436e712009-09-17 21:32:03 +00001//===---------------- SemaCodeComplete.cpp - Code Completion ----*- C++ -*-===//
2//
3// The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9//
10// This file defines the code-completion semantic actions.
11//
12//===----------------------------------------------------------------------===//
Douglas Gregorc3a6ade2010-08-12 20:07:10 +000013#include "clang/Sema/Sema.h"
14#include "clang/Sema/Lookup.h"
Douglas Gregor2436e712009-09-17 21:32:03 +000015#include "clang/Sema/CodeCompleteConsumer.h"
Douglas Gregord720daf2010-04-06 17:30:22 +000016#include "clang/Sema/ExternalSemaSource.h"
John McCallcc14d1f2010-08-24 08:50:51 +000017#include "clang/Sema/Scope.h"
John McCallde6836a2010-08-24 07:21:54 +000018#include "clang/AST/DeclObjC.h"
Douglas Gregorf2510672009-09-21 19:57:38 +000019#include "clang/AST/ExprCXX.h"
Douglas Gregor8ce33212009-11-17 17:59:40 +000020#include "clang/AST/ExprObjC.h"
Douglas Gregorf329c7c2009-10-30 16:50:04 +000021#include "clang/Lex/MacroInfo.h"
22#include "clang/Lex/Preprocessor.h"
Douglas Gregor3545ff42009-09-21 16:56:56 +000023#include "llvm/ADT/SmallPtrSet.h"
Douglas Gregore6688e62009-09-28 03:51:44 +000024#include "llvm/ADT/StringExtras.h"
Douglas Gregor9d2ddb22010-04-06 19:22:33 +000025#include "llvm/ADT/StringSwitch.h"
Douglas Gregor3545ff42009-09-21 16:56:56 +000026#include <list>
27#include <map>
28#include <vector>
Douglas Gregor2436e712009-09-17 21:32:03 +000029
30using namespace clang;
31
Douglas Gregor3545ff42009-09-21 16:56:56 +000032namespace {
33 /// \brief A container of code-completion results.
34 class ResultBuilder {
35 public:
36 /// \brief The type of a name-lookup filter, which can be provided to the
37 /// name-lookup routines to specify which declarations should be included in
38 /// the result set (when it returns true) and which declarations should be
39 /// filtered out (returns false).
40 typedef bool (ResultBuilder::*LookupFilter)(NamedDecl *) const;
41
42 typedef CodeCompleteConsumer::Result Result;
43
44 private:
45 /// \brief The actual results we have found.
46 std::vector<Result> Results;
47
48 /// \brief A record of all of the declarations we have found and placed
49 /// into the result set, used to ensure that no declaration ever gets into
50 /// the result set twice.
51 llvm::SmallPtrSet<Decl*, 16> AllDeclsFound;
52
Douglas Gregor05e7ca32009-12-06 20:23:50 +000053 typedef std::pair<NamedDecl *, unsigned> DeclIndexPair;
54
55 /// \brief An entry in the shadow map, which is optimized to store
56 /// a single (declaration, index) mapping (the common case) but
57 /// can also store a list of (declaration, index) mappings.
58 class ShadowMapEntry {
59 typedef llvm::SmallVector<DeclIndexPair, 4> DeclIndexPairVector;
60
61 /// \brief Contains either the solitary NamedDecl * or a vector
62 /// of (declaration, index) pairs.
63 llvm::PointerUnion<NamedDecl *, DeclIndexPairVector*> DeclOrVector;
64
65 /// \brief When the entry contains a single declaration, this is
66 /// the index associated with that entry.
67 unsigned SingleDeclIndex;
68
69 public:
70 ShadowMapEntry() : DeclOrVector(), SingleDeclIndex(0) { }
71
72 void Add(NamedDecl *ND, unsigned Index) {
73 if (DeclOrVector.isNull()) {
74 // 0 - > 1 elements: just set the single element information.
75 DeclOrVector = ND;
76 SingleDeclIndex = Index;
77 return;
78 }
79
80 if (NamedDecl *PrevND = DeclOrVector.dyn_cast<NamedDecl *>()) {
81 // 1 -> 2 elements: create the vector of results and push in the
82 // existing declaration.
83 DeclIndexPairVector *Vec = new DeclIndexPairVector;
84 Vec->push_back(DeclIndexPair(PrevND, SingleDeclIndex));
85 DeclOrVector = Vec;
86 }
87
88 // Add the new element to the end of the vector.
89 DeclOrVector.get<DeclIndexPairVector*>()->push_back(
90 DeclIndexPair(ND, Index));
91 }
92
93 void Destroy() {
94 if (DeclIndexPairVector *Vec
95 = DeclOrVector.dyn_cast<DeclIndexPairVector *>()) {
96 delete Vec;
97 DeclOrVector = ((NamedDecl *)0);
98 }
99 }
100
101 // Iteration.
102 class iterator;
103 iterator begin() const;
104 iterator end() const;
105 };
106
Douglas Gregor3545ff42009-09-21 16:56:56 +0000107 /// \brief A mapping from declaration names to the declarations that have
108 /// this name within a particular scope and their index within the list of
109 /// results.
Douglas Gregor05e7ca32009-12-06 20:23:50 +0000110 typedef llvm::DenseMap<DeclarationName, ShadowMapEntry> ShadowMap;
Douglas Gregor3545ff42009-09-21 16:56:56 +0000111
112 /// \brief The semantic analysis object for which results are being
113 /// produced.
114 Sema &SemaRef;
115
116 /// \brief If non-NULL, a filter function used to remove any code-completion
117 /// results that are not desirable.
118 LookupFilter Filter;
Douglas Gregor6ae4c522010-01-14 03:21:49 +0000119
120 /// \brief Whether we should allow declarations as
121 /// nested-name-specifiers that would otherwise be filtered out.
122 bool AllowNestedNameSpecifiers;
123
Douglas Gregor7aa6b222010-05-30 01:49:25 +0000124 /// \brief If set, the type that we would prefer our resulting value
125 /// declarations to have.
126 ///
127 /// Closely matching the preferred type gives a boost to a result's
128 /// priority.
129 CanQualType PreferredType;
130
Douglas Gregor3545ff42009-09-21 16:56:56 +0000131 /// \brief A list of shadow maps, which is used to model name hiding at
132 /// different levels of, e.g., the inheritance hierarchy.
133 std::list<ShadowMap> ShadowMaps;
134
Douglas Gregor95887f92010-07-08 23:20:03 +0000135 void AdjustResultPriorityForPreferredType(Result &R);
136
Douglas Gregor3545ff42009-09-21 16:56:56 +0000137 public:
138 explicit ResultBuilder(Sema &SemaRef, LookupFilter Filter = 0)
Douglas Gregor6ae4c522010-01-14 03:21:49 +0000139 : SemaRef(SemaRef), Filter(Filter), AllowNestedNameSpecifiers(false) { }
Douglas Gregor3545ff42009-09-21 16:56:56 +0000140
Douglas Gregorf64acca2010-05-25 21:41:55 +0000141 /// \brief Whether we should include code patterns in the completion
142 /// results.
143 bool includeCodePatterns() const {
144 return SemaRef.CodeCompleter &&
145 SemaRef.CodeCompleter->includeCodePatterns();
146 }
147
Douglas Gregor3545ff42009-09-21 16:56:56 +0000148 /// \brief Set the filter used for code-completion results.
149 void setFilter(LookupFilter Filter) {
150 this->Filter = Filter;
151 }
152
153 typedef std::vector<Result>::iterator iterator;
154 iterator begin() { return Results.begin(); }
155 iterator end() { return Results.end(); }
156
157 Result *data() { return Results.empty()? 0 : &Results.front(); }
158 unsigned size() const { return Results.size(); }
159 bool empty() const { return Results.empty(); }
160
Douglas Gregor7aa6b222010-05-30 01:49:25 +0000161 /// \brief Specify the preferred type.
162 void setPreferredType(QualType T) {
163 PreferredType = SemaRef.Context.getCanonicalType(T);
164 }
165
Douglas Gregor6ae4c522010-01-14 03:21:49 +0000166 /// \brief Specify whether nested-name-specifiers are allowed.
167 void allowNestedNameSpecifiers(bool Allow = true) {
168 AllowNestedNameSpecifiers = Allow;
169 }
170
Douglas Gregor7c208612010-01-14 00:20:49 +0000171 /// \brief Determine whether the given declaration is at all interesting
172 /// as a code-completion result.
Douglas Gregor6ae4c522010-01-14 03:21:49 +0000173 ///
174 /// \param ND the declaration that we are inspecting.
175 ///
176 /// \param AsNestedNameSpecifier will be set true if this declaration is
177 /// only interesting when it is a nested-name-specifier.
178 bool isInterestingDecl(NamedDecl *ND, bool &AsNestedNameSpecifier) const;
Douglas Gregore0717ab2010-01-14 00:41:07 +0000179
180 /// \brief Check whether the result is hidden by the Hiding declaration.
181 ///
182 /// \returns true if the result is hidden and cannot be found, false if
183 /// the hidden result could still be found. When false, \p R may be
184 /// modified to describe how the result can be found (e.g., via extra
185 /// qualification).
186 bool CheckHiddenResult(Result &R, DeclContext *CurContext,
187 NamedDecl *Hiding);
188
Douglas Gregor3545ff42009-09-21 16:56:56 +0000189 /// \brief Add a new result to this result set (if it isn't already in one
190 /// of the shadow maps), or replace an existing result (for, e.g., a
191 /// redeclaration).
Douglas Gregor2af2f672009-09-21 20:12:40 +0000192 ///
Douglas Gregorc580c522010-01-14 01:09:38 +0000193 /// \param CurContext the result to add (if it is unique).
Douglas Gregor2af2f672009-09-21 20:12:40 +0000194 ///
195 /// \param R the context in which this result will be named.
196 void MaybeAddResult(Result R, DeclContext *CurContext = 0);
Douglas Gregor3545ff42009-09-21 16:56:56 +0000197
Douglas Gregorc580c522010-01-14 01:09:38 +0000198 /// \brief Add a new result to this result set, where we already know
199 /// the hiding declation (if any).
200 ///
201 /// \param R the result to add (if it is unique).
202 ///
203 /// \param CurContext the context in which this result will be named.
204 ///
205 /// \param Hiding the declaration that hides the result.
Douglas Gregor09bbc652010-01-14 15:47:35 +0000206 ///
207 /// \param InBaseClass whether the result was found in a base
208 /// class of the searched context.
209 void AddResult(Result R, DeclContext *CurContext, NamedDecl *Hiding,
210 bool InBaseClass);
Douglas Gregorc580c522010-01-14 01:09:38 +0000211
Douglas Gregor78a21012010-01-14 16:01:26 +0000212 /// \brief Add a new non-declaration result to this result set.
213 void AddResult(Result R);
214
Douglas Gregor3545ff42009-09-21 16:56:56 +0000215 /// \brief Enter into a new scope.
216 void EnterNewScope();
217
218 /// \brief Exit from the current scope.
219 void ExitScope();
220
Douglas Gregorbaf69612009-11-18 04:19:12 +0000221 /// \brief Ignore this declaration, if it is seen again.
222 void Ignore(Decl *D) { AllDeclsFound.insert(D->getCanonicalDecl()); }
223
Douglas Gregor3545ff42009-09-21 16:56:56 +0000224 /// \name Name lookup predicates
225 ///
226 /// These predicates can be passed to the name lookup functions to filter the
227 /// results of name lookup. All of the predicates have the same type, so that
228 ///
229 //@{
Douglas Gregor9d64c5e2009-09-21 20:51:25 +0000230 bool IsOrdinaryName(NamedDecl *ND) const;
Douglas Gregor70febae2010-05-28 00:49:12 +0000231 bool IsOrdinaryNonTypeName(NamedDecl *ND) const;
Douglas Gregor85b50632010-07-28 21:50:18 +0000232 bool IsIntegralConstantValue(NamedDecl *ND) const;
Douglas Gregor504a6ae2010-01-10 23:08:15 +0000233 bool IsOrdinaryNonValueName(NamedDecl *ND) const;
Douglas Gregor3545ff42009-09-21 16:56:56 +0000234 bool IsNestedNameSpecifier(NamedDecl *ND) const;
235 bool IsEnum(NamedDecl *ND) const;
236 bool IsClassOrStruct(NamedDecl *ND) const;
237 bool IsUnion(NamedDecl *ND) const;
238 bool IsNamespace(NamedDecl *ND) const;
239 bool IsNamespaceOrAlias(NamedDecl *ND) const;
240 bool IsType(NamedDecl *ND) const;
Douglas Gregore412a5a2009-09-23 22:26:46 +0000241 bool IsMember(NamedDecl *ND) const;
Douglas Gregor2b8162b2010-01-14 16:08:12 +0000242 bool IsObjCIvar(NamedDecl *ND) const;
Douglas Gregora817a192010-05-27 23:06:34 +0000243 bool IsObjCMessageReceiver(NamedDecl *ND) const;
Douglas Gregor68762e72010-08-23 21:17:50 +0000244 bool IsObjCCollection(NamedDecl *ND) const;
Douglas Gregor3545ff42009-09-21 16:56:56 +0000245 //@}
246 };
247}
248
Douglas Gregor05e7ca32009-12-06 20:23:50 +0000249class ResultBuilder::ShadowMapEntry::iterator {
250 llvm::PointerUnion<NamedDecl*, const DeclIndexPair*> DeclOrIterator;
251 unsigned SingleDeclIndex;
252
253public:
254 typedef DeclIndexPair value_type;
255 typedef value_type reference;
256 typedef std::ptrdiff_t difference_type;
257 typedef std::input_iterator_tag iterator_category;
258
259 class pointer {
260 DeclIndexPair Value;
261
262 public:
263 pointer(const DeclIndexPair &Value) : Value(Value) { }
264
265 const DeclIndexPair *operator->() const {
266 return &Value;
267 }
268 };
269
270 iterator() : DeclOrIterator((NamedDecl *)0), SingleDeclIndex(0) { }
271
272 iterator(NamedDecl *SingleDecl, unsigned Index)
273 : DeclOrIterator(SingleDecl), SingleDeclIndex(Index) { }
274
275 iterator(const DeclIndexPair *Iterator)
276 : DeclOrIterator(Iterator), SingleDeclIndex(0) { }
277
278 iterator &operator++() {
279 if (DeclOrIterator.is<NamedDecl *>()) {
280 DeclOrIterator = (NamedDecl *)0;
281 SingleDeclIndex = 0;
282 return *this;
283 }
284
285 const DeclIndexPair *I = DeclOrIterator.get<const DeclIndexPair*>();
286 ++I;
287 DeclOrIterator = I;
288 return *this;
289 }
290
291 iterator operator++(int) {
292 iterator tmp(*this);
293 ++(*this);
294 return tmp;
295 }
296
297 reference operator*() const {
298 if (NamedDecl *ND = DeclOrIterator.dyn_cast<NamedDecl *>())
299 return reference(ND, SingleDeclIndex);
300
Douglas Gregor94bb5e82009-12-06 21:27:58 +0000301 return *DeclOrIterator.get<const DeclIndexPair*>();
Douglas Gregor05e7ca32009-12-06 20:23:50 +0000302 }
303
304 pointer operator->() const {
305 return pointer(**this);
306 }
307
308 friend bool operator==(const iterator &X, const iterator &Y) {
Douglas Gregor94bb5e82009-12-06 21:27:58 +0000309 return X.DeclOrIterator.getOpaqueValue()
310 == Y.DeclOrIterator.getOpaqueValue() &&
Douglas Gregor05e7ca32009-12-06 20:23:50 +0000311 X.SingleDeclIndex == Y.SingleDeclIndex;
312 }
313
314 friend bool operator!=(const iterator &X, const iterator &Y) {
Douglas Gregor94bb5e82009-12-06 21:27:58 +0000315 return !(X == Y);
Douglas Gregor05e7ca32009-12-06 20:23:50 +0000316 }
317};
318
Douglas Gregor05e7ca32009-12-06 20:23:50 +0000319ResultBuilder::ShadowMapEntry::iterator
320ResultBuilder::ShadowMapEntry::begin() const {
321 if (DeclOrVector.isNull())
322 return iterator();
323
324 if (NamedDecl *ND = DeclOrVector.dyn_cast<NamedDecl *>())
325 return iterator(ND, SingleDeclIndex);
326
327 return iterator(DeclOrVector.get<DeclIndexPairVector *>()->begin());
328}
329
330ResultBuilder::ShadowMapEntry::iterator
331ResultBuilder::ShadowMapEntry::end() const {
332 if (DeclOrVector.is<NamedDecl *>() || DeclOrVector.isNull())
333 return iterator();
334
335 return iterator(DeclOrVector.get<DeclIndexPairVector *>()->end());
336}
337
Douglas Gregor2af2f672009-09-21 20:12:40 +0000338/// \brief Compute the qualification required to get from the current context
339/// (\p CurContext) to the target context (\p TargetContext).
340///
341/// \param Context the AST context in which the qualification will be used.
342///
343/// \param CurContext the context where an entity is being named, which is
344/// typically based on the current scope.
345///
346/// \param TargetContext the context in which the named entity actually
347/// resides.
348///
349/// \returns a nested name specifier that refers into the target context, or
350/// NULL if no qualification is needed.
351static NestedNameSpecifier *
352getRequiredQualification(ASTContext &Context,
353 DeclContext *CurContext,
354 DeclContext *TargetContext) {
355 llvm::SmallVector<DeclContext *, 4> TargetParents;
356
357 for (DeclContext *CommonAncestor = TargetContext;
358 CommonAncestor && !CommonAncestor->Encloses(CurContext);
359 CommonAncestor = CommonAncestor->getLookupParent()) {
360 if (CommonAncestor->isTransparentContext() ||
361 CommonAncestor->isFunctionOrMethod())
362 continue;
363
364 TargetParents.push_back(CommonAncestor);
365 }
366
367 NestedNameSpecifier *Result = 0;
368 while (!TargetParents.empty()) {
369 DeclContext *Parent = TargetParents.back();
370 TargetParents.pop_back();
371
Douglas Gregor68762e72010-08-23 21:17:50 +0000372 if (NamespaceDecl *Namespace = dyn_cast<NamespaceDecl>(Parent)) {
373 if (!Namespace->getIdentifier())
374 continue;
375
Douglas Gregor2af2f672009-09-21 20:12:40 +0000376 Result = NestedNameSpecifier::Create(Context, Result, Namespace);
Douglas Gregor68762e72010-08-23 21:17:50 +0000377 }
Douglas Gregor2af2f672009-09-21 20:12:40 +0000378 else if (TagDecl *TD = dyn_cast<TagDecl>(Parent))
379 Result = NestedNameSpecifier::Create(Context, Result,
380 false,
381 Context.getTypeDeclType(TD).getTypePtr());
Douglas Gregor9eb77012009-11-07 00:00:49 +0000382 }
Douglas Gregor2af2f672009-09-21 20:12:40 +0000383 return Result;
384}
385
Douglas Gregor6ae4c522010-01-14 03:21:49 +0000386bool ResultBuilder::isInterestingDecl(NamedDecl *ND,
387 bool &AsNestedNameSpecifier) const {
388 AsNestedNameSpecifier = false;
389
Douglas Gregor7c208612010-01-14 00:20:49 +0000390 ND = ND->getUnderlyingDecl();
391 unsigned IDNS = ND->getIdentifierNamespace();
Douglas Gregor58acf322009-10-09 22:16:47 +0000392
393 // Skip unnamed entities.
Douglas Gregor7c208612010-01-14 00:20:49 +0000394 if (!ND->getDeclName())
395 return false;
Douglas Gregor3545ff42009-09-21 16:56:56 +0000396
397 // Friend declarations and declarations introduced due to friends are never
398 // added as results.
John McCallbbbbe4e2010-03-11 07:50:04 +0000399 if (IDNS & (Decl::IDNS_OrdinaryFriend | Decl::IDNS_TagFriend))
Douglas Gregor7c208612010-01-14 00:20:49 +0000400 return false;
401
Douglas Gregor99fe2ad2009-12-11 17:31:05 +0000402 // Class template (partial) specializations are never added as results.
Douglas Gregor7c208612010-01-14 00:20:49 +0000403 if (isa<ClassTemplateSpecializationDecl>(ND) ||
404 isa<ClassTemplatePartialSpecializationDecl>(ND))
405 return false;
Douglas Gregor3545ff42009-09-21 16:56:56 +0000406
Douglas Gregor99fe2ad2009-12-11 17:31:05 +0000407 // Using declarations themselves are never added as results.
Douglas Gregor7c208612010-01-14 00:20:49 +0000408 if (isa<UsingDecl>(ND))
409 return false;
410
411 // Some declarations have reserved names that we don't want to ever show.
412 if (const IdentifierInfo *Id = ND->getIdentifier()) {
Douglas Gregor3545ff42009-09-21 16:56:56 +0000413 // __va_list_tag is a freak of nature. Find it and skip it.
414 if (Id->isStr("__va_list_tag") || Id->isStr("__builtin_va_list"))
Douglas Gregor7c208612010-01-14 00:20:49 +0000415 return false;
Douglas Gregor3545ff42009-09-21 16:56:56 +0000416
Douglas Gregor58acf322009-10-09 22:16:47 +0000417 // Filter out names reserved for the implementation (C99 7.1.3,
Douglas Gregor9f1570d2010-07-14 17:44:04 +0000418 // C++ [lib.global.names]) if they come from a system header.
Daniel Dunbar2c422dc92009-10-18 20:26:12 +0000419 //
420 // FIXME: Add predicate for this.
Douglas Gregor58acf322009-10-09 22:16:47 +0000421 if (Id->getLength() >= 2) {
Daniel Dunbar2c422dc92009-10-18 20:26:12 +0000422 const char *Name = Id->getNameStart();
Douglas Gregor58acf322009-10-09 22:16:47 +0000423 if (Name[0] == '_' &&
Douglas Gregor9f1570d2010-07-14 17:44:04 +0000424 (Name[1] == '_' || (Name[1] >= 'A' && Name[1] <= 'Z')) &&
425 (ND->getLocation().isInvalid() ||
426 SemaRef.SourceMgr.isInSystemHeader(
427 SemaRef.SourceMgr.getSpellingLoc(ND->getLocation()))))
Douglas Gregor7c208612010-01-14 00:20:49 +0000428 return false;
Douglas Gregor58acf322009-10-09 22:16:47 +0000429 }
Douglas Gregor3545ff42009-09-21 16:56:56 +0000430 }
Douglas Gregor7c208612010-01-14 00:20:49 +0000431
Douglas Gregor3545ff42009-09-21 16:56:56 +0000432 // C++ constructors are never found by name lookup.
Douglas Gregor7c208612010-01-14 00:20:49 +0000433 if (isa<CXXConstructorDecl>(ND))
434 return false;
Douglas Gregor3545ff42009-09-21 16:56:56 +0000435
Douglas Gregor59cab552010-08-16 23:05:20 +0000436 if (Filter == &ResultBuilder::IsNestedNameSpecifier ||
437 ((isa<NamespaceDecl>(ND) || isa<NamespaceAliasDecl>(ND)) &&
438 Filter != &ResultBuilder::IsNamespace &&
439 Filter != &ResultBuilder::IsNamespaceOrAlias))
440 AsNestedNameSpecifier = true;
441
Douglas Gregor3545ff42009-09-21 16:56:56 +0000442 // Filter out any unwanted results.
Douglas Gregor6ae4c522010-01-14 03:21:49 +0000443 if (Filter && !(this->*Filter)(ND)) {
444 // Check whether it is interesting as a nested-name-specifier.
445 if (AllowNestedNameSpecifiers && SemaRef.getLangOptions().CPlusPlus &&
446 IsNestedNameSpecifier(ND) &&
447 (Filter != &ResultBuilder::IsMember ||
448 (isa<CXXRecordDecl>(ND) &&
449 cast<CXXRecordDecl>(ND)->isInjectedClassName()))) {
450 AsNestedNameSpecifier = true;
451 return true;
452 }
453
Douglas Gregor7c208612010-01-14 00:20:49 +0000454 return false;
Douglas Gregor59cab552010-08-16 23:05:20 +0000455 }
Douglas Gregor7c208612010-01-14 00:20:49 +0000456 // ... then it must be interesting!
457 return true;
458}
459
Douglas Gregore0717ab2010-01-14 00:41:07 +0000460bool ResultBuilder::CheckHiddenResult(Result &R, DeclContext *CurContext,
461 NamedDecl *Hiding) {
462 // In C, there is no way to refer to a hidden name.
463 // FIXME: This isn't true; we can find a tag name hidden by an ordinary
464 // name if we introduce the tag type.
465 if (!SemaRef.getLangOptions().CPlusPlus)
466 return true;
467
468 DeclContext *HiddenCtx = R.Declaration->getDeclContext()->getLookupContext();
469
470 // There is no way to qualify a name declared in a function or method.
471 if (HiddenCtx->isFunctionOrMethod())
472 return true;
473
474 if (HiddenCtx == Hiding->getDeclContext()->getLookupContext())
475 return true;
476
477 // We can refer to the result with the appropriate qualification. Do it.
478 R.Hidden = true;
479 R.QualifierIsInformative = false;
480
481 if (!R.Qualifier)
482 R.Qualifier = getRequiredQualification(SemaRef.Context,
483 CurContext,
484 R.Declaration->getDeclContext());
485 return false;
486}
487
Douglas Gregor95887f92010-07-08 23:20:03 +0000488/// \brief A simplified classification of types used to determine whether two
489/// types are "similar enough" when adjusting priorities.
Douglas Gregor6e240332010-08-16 16:18:59 +0000490SimplifiedTypeClass clang::getSimplifiedTypeClass(CanQualType T) {
Douglas Gregor95887f92010-07-08 23:20:03 +0000491 switch (T->getTypeClass()) {
492 case Type::Builtin:
493 switch (cast<BuiltinType>(T)->getKind()) {
494 case BuiltinType::Void:
495 return STC_Void;
496
497 case BuiltinType::NullPtr:
498 return STC_Pointer;
499
500 case BuiltinType::Overload:
501 case BuiltinType::Dependent:
502 case BuiltinType::UndeducedAuto:
503 return STC_Other;
504
505 case BuiltinType::ObjCId:
506 case BuiltinType::ObjCClass:
507 case BuiltinType::ObjCSel:
508 return STC_ObjectiveC;
509
510 default:
511 return STC_Arithmetic;
512 }
513 return STC_Other;
514
515 case Type::Complex:
516 return STC_Arithmetic;
517
518 case Type::Pointer:
519 return STC_Pointer;
520
521 case Type::BlockPointer:
522 return STC_Block;
523
524 case Type::LValueReference:
525 case Type::RValueReference:
526 return getSimplifiedTypeClass(T->getAs<ReferenceType>()->getPointeeType());
527
528 case Type::ConstantArray:
529 case Type::IncompleteArray:
530 case Type::VariableArray:
531 case Type::DependentSizedArray:
532 return STC_Array;
533
534 case Type::DependentSizedExtVector:
535 case Type::Vector:
536 case Type::ExtVector:
537 return STC_Arithmetic;
538
539 case Type::FunctionProto:
540 case Type::FunctionNoProto:
541 return STC_Function;
542
543 case Type::Record:
544 return STC_Record;
545
546 case Type::Enum:
547 return STC_Arithmetic;
548
549 case Type::ObjCObject:
550 case Type::ObjCInterface:
551 case Type::ObjCObjectPointer:
552 return STC_ObjectiveC;
553
554 default:
555 return STC_Other;
556 }
557}
558
559/// \brief Get the type that a given expression will have if this declaration
560/// is used as an expression in its "typical" code-completion form.
Douglas Gregor6e240332010-08-16 16:18:59 +0000561QualType clang::getDeclUsageType(ASTContext &C, NamedDecl *ND) {
Douglas Gregor95887f92010-07-08 23:20:03 +0000562 ND = cast<NamedDecl>(ND->getUnderlyingDecl());
563
564 if (TypeDecl *Type = dyn_cast<TypeDecl>(ND))
565 return C.getTypeDeclType(Type);
566 if (ObjCInterfaceDecl *Iface = dyn_cast<ObjCInterfaceDecl>(ND))
567 return C.getObjCInterfaceType(Iface);
568
569 QualType T;
570 if (FunctionDecl *Function = dyn_cast<FunctionDecl>(ND))
Douglas Gregor603d81b2010-07-13 08:18:22 +0000571 T = Function->getCallResultType();
Douglas Gregor95887f92010-07-08 23:20:03 +0000572 else if (ObjCMethodDecl *Method = dyn_cast<ObjCMethodDecl>(ND))
Douglas Gregor603d81b2010-07-13 08:18:22 +0000573 T = Method->getSendResultType();
Douglas Gregor95887f92010-07-08 23:20:03 +0000574 else if (FunctionTemplateDecl *FunTmpl = dyn_cast<FunctionTemplateDecl>(ND))
Douglas Gregor603d81b2010-07-13 08:18:22 +0000575 T = FunTmpl->getTemplatedDecl()->getCallResultType();
Douglas Gregor95887f92010-07-08 23:20:03 +0000576 else if (EnumConstantDecl *Enumerator = dyn_cast<EnumConstantDecl>(ND))
577 T = C.getTypeDeclType(cast<EnumDecl>(Enumerator->getDeclContext()));
578 else if (ObjCPropertyDecl *Property = dyn_cast<ObjCPropertyDecl>(ND))
579 T = Property->getType();
580 else if (ValueDecl *Value = dyn_cast<ValueDecl>(ND))
581 T = Value->getType();
582 else
583 return QualType();
584
585 return T.getNonReferenceType();
586}
587
588void ResultBuilder::AdjustResultPriorityForPreferredType(Result &R) {
589 QualType T = getDeclUsageType(SemaRef.Context, R.Declaration);
590 if (T.isNull())
591 return;
592
593 CanQualType TC = SemaRef.Context.getCanonicalType(T);
594 // Check for exactly-matching types (modulo qualifiers).
595 if (SemaRef.Context.hasSameUnqualifiedType(PreferredType, TC))
596 R.Priority /= CCF_ExactTypeMatch;
597 // Check for nearly-matching types, based on classification of each.
598 else if ((getSimplifiedTypeClass(PreferredType)
599 == getSimplifiedTypeClass(TC)) &&
600 !(PreferredType->isEnumeralType() && TC->isEnumeralType()))
601 R.Priority /= CCF_SimilarTypeMatch;
602}
603
Douglas Gregor7c208612010-01-14 00:20:49 +0000604void ResultBuilder::MaybeAddResult(Result R, DeclContext *CurContext) {
605 assert(!ShadowMaps.empty() && "Must enter into a results scope");
606
607 if (R.Kind != Result::RK_Declaration) {
608 // For non-declaration results, just add the result.
609 Results.push_back(R);
610 return;
611 }
612
613 // Look through using declarations.
614 if (UsingShadowDecl *Using = dyn_cast<UsingShadowDecl>(R.Declaration)) {
615 MaybeAddResult(Result(Using->getTargetDecl(), R.Qualifier), CurContext);
616 return;
617 }
618
619 Decl *CanonDecl = R.Declaration->getCanonicalDecl();
620 unsigned IDNS = CanonDecl->getIdentifierNamespace();
621
Douglas Gregor6ae4c522010-01-14 03:21:49 +0000622 bool AsNestedNameSpecifier = false;
623 if (!isInterestingDecl(R.Declaration, AsNestedNameSpecifier))
Douglas Gregor7c208612010-01-14 00:20:49 +0000624 return;
625
Douglas Gregor3545ff42009-09-21 16:56:56 +0000626 ShadowMap &SMap = ShadowMaps.back();
Douglas Gregor05e7ca32009-12-06 20:23:50 +0000627 ShadowMapEntry::iterator I, IEnd;
628 ShadowMap::iterator NamePos = SMap.find(R.Declaration->getDeclName());
629 if (NamePos != SMap.end()) {
630 I = NamePos->second.begin();
631 IEnd = NamePos->second.end();
632 }
633
634 for (; I != IEnd; ++I) {
635 NamedDecl *ND = I->first;
636 unsigned Index = I->second;
Douglas Gregor3545ff42009-09-21 16:56:56 +0000637 if (ND->getCanonicalDecl() == CanonDecl) {
638 // This is a redeclaration. Always pick the newer declaration.
Douglas Gregor3545ff42009-09-21 16:56:56 +0000639 Results[Index].Declaration = R.Declaration;
640
Douglas Gregor3545ff42009-09-21 16:56:56 +0000641 // We're done.
642 return;
643 }
644 }
645
646 // This is a new declaration in this scope. However, check whether this
647 // declaration name is hidden by a similarly-named declaration in an outer
648 // scope.
649 std::list<ShadowMap>::iterator SM, SMEnd = ShadowMaps.end();
650 --SMEnd;
651 for (SM = ShadowMaps.begin(); SM != SMEnd; ++SM) {
Douglas Gregor05e7ca32009-12-06 20:23:50 +0000652 ShadowMapEntry::iterator I, IEnd;
653 ShadowMap::iterator NamePos = SM->find(R.Declaration->getDeclName());
654 if (NamePos != SM->end()) {
655 I = NamePos->second.begin();
656 IEnd = NamePos->second.end();
657 }
658 for (; I != IEnd; ++I) {
Douglas Gregor3545ff42009-09-21 16:56:56 +0000659 // A tag declaration does not hide a non-tag declaration.
John McCalle87beb22010-04-23 18:46:30 +0000660 if (I->first->hasTagIdentifierNamespace() &&
Douglas Gregor3545ff42009-09-21 16:56:56 +0000661 (IDNS & (Decl::IDNS_Member | Decl::IDNS_Ordinary |
662 Decl::IDNS_ObjCProtocol)))
663 continue;
664
665 // Protocols are in distinct namespaces from everything else.
Douglas Gregor05e7ca32009-12-06 20:23:50 +0000666 if (((I->first->getIdentifierNamespace() & Decl::IDNS_ObjCProtocol)
Douglas Gregor3545ff42009-09-21 16:56:56 +0000667 || (IDNS & Decl::IDNS_ObjCProtocol)) &&
Douglas Gregor05e7ca32009-12-06 20:23:50 +0000668 I->first->getIdentifierNamespace() != IDNS)
Douglas Gregor3545ff42009-09-21 16:56:56 +0000669 continue;
670
671 // The newly-added result is hidden by an entry in the shadow map.
Douglas Gregore0717ab2010-01-14 00:41:07 +0000672 if (CheckHiddenResult(R, CurContext, I->first))
Douglas Gregor3545ff42009-09-21 16:56:56 +0000673 return;
Douglas Gregor3545ff42009-09-21 16:56:56 +0000674
675 break;
676 }
677 }
678
679 // Make sure that any given declaration only shows up in the result set once.
680 if (!AllDeclsFound.insert(CanonDecl))
681 return;
682
Douglas Gregore412a5a2009-09-23 22:26:46 +0000683 // If the filter is for nested-name-specifiers, then this result starts a
684 // nested-name-specifier.
Douglas Gregora2db7932010-05-26 22:00:08 +0000685 if (AsNestedNameSpecifier) {
Douglas Gregore412a5a2009-09-23 22:26:46 +0000686 R.StartsNestedNameSpecifier = true;
Douglas Gregora2db7932010-05-26 22:00:08 +0000687 R.Priority = CCP_NestedNameSpecifier;
Douglas Gregor95887f92010-07-08 23:20:03 +0000688 } else if (!PreferredType.isNull())
689 AdjustResultPriorityForPreferredType(R);
690
Douglas Gregor5bf52692009-09-22 23:15:58 +0000691 // If this result is supposed to have an informative qualifier, add one.
Douglas Gregore412a5a2009-09-23 22:26:46 +0000692 if (R.QualifierIsInformative && !R.Qualifier &&
693 !R.StartsNestedNameSpecifier) {
Douglas Gregor5bf52692009-09-22 23:15:58 +0000694 DeclContext *Ctx = R.Declaration->getDeclContext();
695 if (NamespaceDecl *Namespace = dyn_cast<NamespaceDecl>(Ctx))
696 R.Qualifier = NestedNameSpecifier::Create(SemaRef.Context, 0, Namespace);
697 else if (TagDecl *Tag = dyn_cast<TagDecl>(Ctx))
698 R.Qualifier = NestedNameSpecifier::Create(SemaRef.Context, 0, false,
699 SemaRef.Context.getTypeDeclType(Tag).getTypePtr());
700 else
701 R.QualifierIsInformative = false;
702 }
Douglas Gregore412a5a2009-09-23 22:26:46 +0000703
Douglas Gregor3545ff42009-09-21 16:56:56 +0000704 // Insert this result into the set of results and into the current shadow
705 // map.
Douglas Gregor05e7ca32009-12-06 20:23:50 +0000706 SMap[R.Declaration->getDeclName()].Add(R.Declaration, Results.size());
Douglas Gregor3545ff42009-09-21 16:56:56 +0000707 Results.push_back(R);
708}
709
Douglas Gregorc580c522010-01-14 01:09:38 +0000710void ResultBuilder::AddResult(Result R, DeclContext *CurContext,
Douglas Gregor09bbc652010-01-14 15:47:35 +0000711 NamedDecl *Hiding, bool InBaseClass = false) {
Douglas Gregor78a21012010-01-14 16:01:26 +0000712 if (R.Kind != Result::RK_Declaration) {
713 // For non-declaration results, just add the result.
714 Results.push_back(R);
715 return;
716 }
717
Douglas Gregorc580c522010-01-14 01:09:38 +0000718 // Look through using declarations.
719 if (UsingShadowDecl *Using = dyn_cast<UsingShadowDecl>(R.Declaration)) {
720 AddResult(Result(Using->getTargetDecl(), R.Qualifier), CurContext, Hiding);
721 return;
722 }
723
Douglas Gregor6ae4c522010-01-14 03:21:49 +0000724 bool AsNestedNameSpecifier = false;
725 if (!isInterestingDecl(R.Declaration, AsNestedNameSpecifier))
Douglas Gregorc580c522010-01-14 01:09:38 +0000726 return;
727
728 if (Hiding && CheckHiddenResult(R, CurContext, Hiding))
729 return;
730
731 // Make sure that any given declaration only shows up in the result set once.
732 if (!AllDeclsFound.insert(R.Declaration->getCanonicalDecl()))
733 return;
734
735 // If the filter is for nested-name-specifiers, then this result starts a
736 // nested-name-specifier.
Douglas Gregora2db7932010-05-26 22:00:08 +0000737 if (AsNestedNameSpecifier) {
Douglas Gregorc580c522010-01-14 01:09:38 +0000738 R.StartsNestedNameSpecifier = true;
Douglas Gregora2db7932010-05-26 22:00:08 +0000739 R.Priority = CCP_NestedNameSpecifier;
740 }
Douglas Gregor09bbc652010-01-14 15:47:35 +0000741 else if (Filter == &ResultBuilder::IsMember && !R.Qualifier && InBaseClass &&
742 isa<CXXRecordDecl>(R.Declaration->getDeclContext()
743 ->getLookupContext()))
744 R.QualifierIsInformative = true;
745
Douglas Gregorc580c522010-01-14 01:09:38 +0000746 // If this result is supposed to have an informative qualifier, add one.
747 if (R.QualifierIsInformative && !R.Qualifier &&
748 !R.StartsNestedNameSpecifier) {
749 DeclContext *Ctx = R.Declaration->getDeclContext();
750 if (NamespaceDecl *Namespace = dyn_cast<NamespaceDecl>(Ctx))
751 R.Qualifier = NestedNameSpecifier::Create(SemaRef.Context, 0, Namespace);
752 else if (TagDecl *Tag = dyn_cast<TagDecl>(Ctx))
753 R.Qualifier = NestedNameSpecifier::Create(SemaRef.Context, 0, false,
Douglas Gregor6ae4c522010-01-14 03:21:49 +0000754 SemaRef.Context.getTypeDeclType(Tag).getTypePtr());
Douglas Gregorc580c522010-01-14 01:09:38 +0000755 else
756 R.QualifierIsInformative = false;
757 }
758
Douglas Gregora2db7932010-05-26 22:00:08 +0000759 // Adjust the priority if this result comes from a base class.
760 if (InBaseClass)
761 R.Priority += CCD_InBaseClass;
762
Douglas Gregor95887f92010-07-08 23:20:03 +0000763 if (!PreferredType.isNull())
764 AdjustResultPriorityForPreferredType(R);
Douglas Gregor7aa6b222010-05-30 01:49:25 +0000765
Douglas Gregorc580c522010-01-14 01:09:38 +0000766 // Insert this result into the set of results.
767 Results.push_back(R);
768}
769
Douglas Gregor78a21012010-01-14 16:01:26 +0000770void ResultBuilder::AddResult(Result R) {
771 assert(R.Kind != Result::RK_Declaration &&
772 "Declaration results need more context");
773 Results.push_back(R);
774}
775
Douglas Gregor3545ff42009-09-21 16:56:56 +0000776/// \brief Enter into a new scope.
777void ResultBuilder::EnterNewScope() {
778 ShadowMaps.push_back(ShadowMap());
779}
780
781/// \brief Exit from the current scope.
782void ResultBuilder::ExitScope() {
Douglas Gregor05e7ca32009-12-06 20:23:50 +0000783 for (ShadowMap::iterator E = ShadowMaps.back().begin(),
784 EEnd = ShadowMaps.back().end();
785 E != EEnd;
786 ++E)
787 E->second.Destroy();
788
Douglas Gregor3545ff42009-09-21 16:56:56 +0000789 ShadowMaps.pop_back();
790}
791
Douglas Gregor9d64c5e2009-09-21 20:51:25 +0000792/// \brief Determines whether this given declaration will be found by
793/// ordinary name lookup.
794bool ResultBuilder::IsOrdinaryName(NamedDecl *ND) const {
Douglas Gregor70febae2010-05-28 00:49:12 +0000795 ND = cast<NamedDecl>(ND->getUnderlyingDecl());
796
Douglas Gregor9d64c5e2009-09-21 20:51:25 +0000797 unsigned IDNS = Decl::IDNS_Ordinary;
798 if (SemaRef.getLangOptions().CPlusPlus)
Douglas Gregor9858ed52010-06-15 20:26:51 +0000799 IDNS |= Decl::IDNS_Tag | Decl::IDNS_Namespace | Decl::IDNS_Member;
Douglas Gregorc580c522010-01-14 01:09:38 +0000800 else if (SemaRef.getLangOptions().ObjC1 && isa<ObjCIvarDecl>(ND))
801 return true;
802
Douglas Gregor9d64c5e2009-09-21 20:51:25 +0000803 return ND->getIdentifierNamespace() & IDNS;
804}
805
Douglas Gregor504a6ae2010-01-10 23:08:15 +0000806/// \brief Determines whether this given declaration will be found by
Douglas Gregor70febae2010-05-28 00:49:12 +0000807/// ordinary name lookup but is not a type name.
808bool ResultBuilder::IsOrdinaryNonTypeName(NamedDecl *ND) const {
809 ND = cast<NamedDecl>(ND->getUnderlyingDecl());
810 if (isa<TypeDecl>(ND) || isa<ObjCInterfaceDecl>(ND))
811 return false;
812
813 unsigned IDNS = Decl::IDNS_Ordinary;
814 if (SemaRef.getLangOptions().CPlusPlus)
Douglas Gregor9858ed52010-06-15 20:26:51 +0000815 IDNS |= Decl::IDNS_Tag | Decl::IDNS_Namespace | Decl::IDNS_Member;
Douglas Gregor70febae2010-05-28 00:49:12 +0000816 else if (SemaRef.getLangOptions().ObjC1 && isa<ObjCIvarDecl>(ND))
817 return true;
818
819 return ND->getIdentifierNamespace() & IDNS;
820}
821
Douglas Gregor85b50632010-07-28 21:50:18 +0000822bool ResultBuilder::IsIntegralConstantValue(NamedDecl *ND) const {
823 if (!IsOrdinaryNonTypeName(ND))
824 return 0;
825
826 if (ValueDecl *VD = dyn_cast<ValueDecl>(ND->getUnderlyingDecl()))
827 if (VD->getType()->isIntegralOrEnumerationType())
828 return true;
829
830 return false;
831}
832
Douglas Gregor70febae2010-05-28 00:49:12 +0000833/// \brief Determines whether this given declaration will be found by
Douglas Gregor504a6ae2010-01-10 23:08:15 +0000834/// ordinary name lookup.
835bool ResultBuilder::IsOrdinaryNonValueName(NamedDecl *ND) const {
Douglas Gregor70febae2010-05-28 00:49:12 +0000836 ND = cast<NamedDecl>(ND->getUnderlyingDecl());
837
Douglas Gregor504a6ae2010-01-10 23:08:15 +0000838 unsigned IDNS = Decl::IDNS_Ordinary;
839 if (SemaRef.getLangOptions().CPlusPlus)
John McCalle87beb22010-04-23 18:46:30 +0000840 IDNS |= Decl::IDNS_Tag | Decl::IDNS_Namespace;
Douglas Gregor504a6ae2010-01-10 23:08:15 +0000841
842 return (ND->getIdentifierNamespace() & IDNS) &&
Douglas Gregor70febae2010-05-28 00:49:12 +0000843 !isa<ValueDecl>(ND) && !isa<FunctionTemplateDecl>(ND) &&
844 !isa<ObjCPropertyDecl>(ND);
Douglas Gregor504a6ae2010-01-10 23:08:15 +0000845}
846
Douglas Gregor3545ff42009-09-21 16:56:56 +0000847/// \brief Determines whether the given declaration is suitable as the
848/// start of a C++ nested-name-specifier, e.g., a class or namespace.
849bool ResultBuilder::IsNestedNameSpecifier(NamedDecl *ND) const {
850 // Allow us to find class templates, too.
851 if (ClassTemplateDecl *ClassTemplate = dyn_cast<ClassTemplateDecl>(ND))
852 ND = ClassTemplate->getTemplatedDecl();
853
854 return SemaRef.isAcceptableNestedNameSpecifier(ND);
855}
856
857/// \brief Determines whether the given declaration is an enumeration.
858bool ResultBuilder::IsEnum(NamedDecl *ND) const {
859 return isa<EnumDecl>(ND);
860}
861
862/// \brief Determines whether the given declaration is a class or struct.
863bool ResultBuilder::IsClassOrStruct(NamedDecl *ND) const {
864 // Allow us to find class templates, too.
865 if (ClassTemplateDecl *ClassTemplate = dyn_cast<ClassTemplateDecl>(ND))
866 ND = ClassTemplate->getTemplatedDecl();
867
868 if (RecordDecl *RD = dyn_cast<RecordDecl>(ND))
Abramo Bagnara6150c882010-05-11 21:36:43 +0000869 return RD->getTagKind() == TTK_Class ||
870 RD->getTagKind() == TTK_Struct;
Douglas Gregor3545ff42009-09-21 16:56:56 +0000871
872 return false;
873}
874
875/// \brief Determines whether the given declaration is a union.
876bool ResultBuilder::IsUnion(NamedDecl *ND) const {
877 // Allow us to find class templates, too.
878 if (ClassTemplateDecl *ClassTemplate = dyn_cast<ClassTemplateDecl>(ND))
879 ND = ClassTemplate->getTemplatedDecl();
880
881 if (RecordDecl *RD = dyn_cast<RecordDecl>(ND))
Abramo Bagnara6150c882010-05-11 21:36:43 +0000882 return RD->getTagKind() == TTK_Union;
Douglas Gregor3545ff42009-09-21 16:56:56 +0000883
884 return false;
885}
886
887/// \brief Determines whether the given declaration is a namespace.
888bool ResultBuilder::IsNamespace(NamedDecl *ND) const {
889 return isa<NamespaceDecl>(ND);
890}
891
892/// \brief Determines whether the given declaration is a namespace or
893/// namespace alias.
894bool ResultBuilder::IsNamespaceOrAlias(NamedDecl *ND) const {
895 return isa<NamespaceDecl>(ND) || isa<NamespaceAliasDecl>(ND);
896}
897
Douglas Gregor99fe2ad2009-12-11 17:31:05 +0000898/// \brief Determines whether the given declaration is a type.
Douglas Gregor3545ff42009-09-21 16:56:56 +0000899bool ResultBuilder::IsType(NamedDecl *ND) const {
Douglas Gregor99fa2642010-08-24 01:06:58 +0000900 if (UsingShadowDecl *Using = dyn_cast<UsingShadowDecl>(ND))
901 ND = Using->getTargetDecl();
902
903 return isa<TypeDecl>(ND) || isa<ObjCInterfaceDecl>(ND);
Douglas Gregor3545ff42009-09-21 16:56:56 +0000904}
905
Douglas Gregor99fe2ad2009-12-11 17:31:05 +0000906/// \brief Determines which members of a class should be visible via
907/// "." or "->". Only value declarations, nested name specifiers, and
908/// using declarations thereof should show up.
Douglas Gregore412a5a2009-09-23 22:26:46 +0000909bool ResultBuilder::IsMember(NamedDecl *ND) const {
Douglas Gregor99fe2ad2009-12-11 17:31:05 +0000910 if (UsingShadowDecl *Using = dyn_cast<UsingShadowDecl>(ND))
911 ND = Using->getTargetDecl();
912
Douglas Gregor70788392009-12-11 18:14:22 +0000913 return isa<ValueDecl>(ND) || isa<FunctionTemplateDecl>(ND) ||
914 isa<ObjCPropertyDecl>(ND);
Douglas Gregore412a5a2009-09-23 22:26:46 +0000915}
916
Douglas Gregora817a192010-05-27 23:06:34 +0000917static bool isObjCReceiverType(ASTContext &C, QualType T) {
918 T = C.getCanonicalType(T);
919 switch (T->getTypeClass()) {
920 case Type::ObjCObject:
921 case Type::ObjCInterface:
922 case Type::ObjCObjectPointer:
923 return true;
924
925 case Type::Builtin:
926 switch (cast<BuiltinType>(T)->getKind()) {
927 case BuiltinType::ObjCId:
928 case BuiltinType::ObjCClass:
929 case BuiltinType::ObjCSel:
930 return true;
931
932 default:
933 break;
934 }
935 return false;
936
937 default:
938 break;
939 }
940
941 if (!C.getLangOptions().CPlusPlus)
942 return false;
943
944 // FIXME: We could perform more analysis here to determine whether a
945 // particular class type has any conversions to Objective-C types. For now,
946 // just accept all class types.
947 return T->isDependentType() || T->isRecordType();
948}
949
950bool ResultBuilder::IsObjCMessageReceiver(NamedDecl *ND) const {
951 QualType T = getDeclUsageType(SemaRef.Context, ND);
952 if (T.isNull())
953 return false;
954
955 T = SemaRef.Context.getBaseElementType(T);
956 return isObjCReceiverType(SemaRef.Context, T);
957}
958
Douglas Gregor68762e72010-08-23 21:17:50 +0000959bool ResultBuilder::IsObjCCollection(NamedDecl *ND) const {
960 if ((SemaRef.getLangOptions().CPlusPlus && !IsOrdinaryName(ND)) ||
961 (!SemaRef.getLangOptions().CPlusPlus && !IsOrdinaryNonTypeName(ND)))
962 return false;
963
964 QualType T = getDeclUsageType(SemaRef.Context, ND);
965 if (T.isNull())
966 return false;
967
968 T = SemaRef.Context.getBaseElementType(T);
969 return T->isObjCObjectType() || T->isObjCObjectPointerType() ||
970 T->isObjCIdType() ||
971 (SemaRef.getLangOptions().CPlusPlus && T->isRecordType());
972}
Douglas Gregora817a192010-05-27 23:06:34 +0000973
Douglas Gregor2b8162b2010-01-14 16:08:12 +0000974/// \rief Determines whether the given declaration is an Objective-C
975/// instance variable.
976bool ResultBuilder::IsObjCIvar(NamedDecl *ND) const {
977 return isa<ObjCIvarDecl>(ND);
978}
979
Douglas Gregorc580c522010-01-14 01:09:38 +0000980namespace {
981 /// \brief Visible declaration consumer that adds a code-completion result
982 /// for each visible declaration.
983 class CodeCompletionDeclConsumer : public VisibleDeclConsumer {
984 ResultBuilder &Results;
985 DeclContext *CurContext;
986
987 public:
988 CodeCompletionDeclConsumer(ResultBuilder &Results, DeclContext *CurContext)
989 : Results(Results), CurContext(CurContext) { }
990
Douglas Gregor09bbc652010-01-14 15:47:35 +0000991 virtual void FoundDecl(NamedDecl *ND, NamedDecl *Hiding, bool InBaseClass) {
992 Results.AddResult(ND, CurContext, Hiding, InBaseClass);
Douglas Gregorc580c522010-01-14 01:09:38 +0000993 }
994 };
995}
996
Douglas Gregor3545ff42009-09-21 16:56:56 +0000997/// \brief Add type specifiers for the current language as keyword results.
Douglas Gregorf98e6a22010-01-13 23:51:12 +0000998static void AddTypeSpecifierResults(const LangOptions &LangOpts,
Douglas Gregor3545ff42009-09-21 16:56:56 +0000999 ResultBuilder &Results) {
1000 typedef CodeCompleteConsumer::Result Result;
Douglas Gregora2db7932010-05-26 22:00:08 +00001001 Results.AddResult(Result("short", CCP_Type));
1002 Results.AddResult(Result("long", CCP_Type));
1003 Results.AddResult(Result("signed", CCP_Type));
1004 Results.AddResult(Result("unsigned", CCP_Type));
1005 Results.AddResult(Result("void", CCP_Type));
1006 Results.AddResult(Result("char", CCP_Type));
1007 Results.AddResult(Result("int", CCP_Type));
1008 Results.AddResult(Result("float", CCP_Type));
1009 Results.AddResult(Result("double", CCP_Type));
1010 Results.AddResult(Result("enum", CCP_Type));
1011 Results.AddResult(Result("struct", CCP_Type));
1012 Results.AddResult(Result("union", CCP_Type));
1013 Results.AddResult(Result("const", CCP_Type));
1014 Results.AddResult(Result("volatile", CCP_Type));
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001015
Douglas Gregor3545ff42009-09-21 16:56:56 +00001016 if (LangOpts.C99) {
1017 // C99-specific
Douglas Gregora2db7932010-05-26 22:00:08 +00001018 Results.AddResult(Result("_Complex", CCP_Type));
1019 Results.AddResult(Result("_Imaginary", CCP_Type));
1020 Results.AddResult(Result("_Bool", CCP_Type));
1021 Results.AddResult(Result("restrict", CCP_Type));
Douglas Gregor3545ff42009-09-21 16:56:56 +00001022 }
1023
1024 if (LangOpts.CPlusPlus) {
1025 // C++-specific
Douglas Gregora2db7932010-05-26 22:00:08 +00001026 Results.AddResult(Result("bool", CCP_Type));
1027 Results.AddResult(Result("class", CCP_Type));
1028 Results.AddResult(Result("wchar_t", CCP_Type));
Douglas Gregor3545ff42009-09-21 16:56:56 +00001029
Douglas Gregorf4c33342010-05-28 00:22:41 +00001030 // typename qualified-id
1031 CodeCompletionString *Pattern = new CodeCompletionString;
1032 Pattern->AddTypedTextChunk("typename");
1033 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
1034 Pattern->AddPlaceholderChunk("qualifier");
1035 Pattern->AddTextChunk("::");
1036 Pattern->AddPlaceholderChunk("name");
1037 Results.AddResult(Result(Pattern));
Douglas Gregorf64acca2010-05-25 21:41:55 +00001038
Douglas Gregor3545ff42009-09-21 16:56:56 +00001039 if (LangOpts.CPlusPlus0x) {
Douglas Gregora2db7932010-05-26 22:00:08 +00001040 Results.AddResult(Result("auto", CCP_Type));
1041 Results.AddResult(Result("char16_t", CCP_Type));
1042 Results.AddResult(Result("char32_t", CCP_Type));
Douglas Gregorf4c33342010-05-28 00:22:41 +00001043
1044 CodeCompletionString *Pattern = new CodeCompletionString;
1045 Pattern->AddTypedTextChunk("decltype");
1046 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
1047 Pattern->AddPlaceholderChunk("expression");
1048 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
1049 Results.AddResult(Result(Pattern));
Douglas Gregor3545ff42009-09-21 16:56:56 +00001050 }
1051 }
1052
1053 // GNU extensions
1054 if (LangOpts.GNUMode) {
1055 // FIXME: Enable when we actually support decimal floating point.
Douglas Gregor78a21012010-01-14 16:01:26 +00001056 // Results.AddResult(Result("_Decimal32"));
1057 // Results.AddResult(Result("_Decimal64"));
1058 // Results.AddResult(Result("_Decimal128"));
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001059
Douglas Gregorf4c33342010-05-28 00:22:41 +00001060 CodeCompletionString *Pattern = new CodeCompletionString;
1061 Pattern->AddTypedTextChunk("typeof");
1062 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
1063 Pattern->AddPlaceholderChunk("expression");
1064 Results.AddResult(Result(Pattern));
1065
1066 Pattern = new CodeCompletionString;
1067 Pattern->AddTypedTextChunk("typeof");
1068 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
1069 Pattern->AddPlaceholderChunk("type");
1070 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
1071 Results.AddResult(Result(Pattern));
Douglas Gregor3545ff42009-09-21 16:56:56 +00001072 }
1073}
1074
Douglas Gregor00c37ef2010-08-11 21:23:17 +00001075static void AddStorageSpecifiers(Action::ParserCompletionContext CCC,
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001076 const LangOptions &LangOpts,
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001077 ResultBuilder &Results) {
1078 typedef CodeCompleteConsumer::Result Result;
1079 // Note: we don't suggest either "auto" or "register", because both
1080 // are pointless as storage specifiers. Elsewhere, we suggest "auto"
1081 // in C++0x as a type specifier.
Douglas Gregor78a21012010-01-14 16:01:26 +00001082 Results.AddResult(Result("extern"));
1083 Results.AddResult(Result("static"));
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001084}
1085
Douglas Gregor00c37ef2010-08-11 21:23:17 +00001086static void AddFunctionSpecifiers(Action::ParserCompletionContext CCC,
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001087 const LangOptions &LangOpts,
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001088 ResultBuilder &Results) {
1089 typedef CodeCompleteConsumer::Result Result;
1090 switch (CCC) {
Douglas Gregor00c37ef2010-08-11 21:23:17 +00001091 case Action::PCC_Class:
1092 case Action::PCC_MemberTemplate:
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001093 if (LangOpts.CPlusPlus) {
Douglas Gregor78a21012010-01-14 16:01:26 +00001094 Results.AddResult(Result("explicit"));
1095 Results.AddResult(Result("friend"));
1096 Results.AddResult(Result("mutable"));
1097 Results.AddResult(Result("virtual"));
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001098 }
1099 // Fall through
1100
Douglas Gregor00c37ef2010-08-11 21:23:17 +00001101 case Action::PCC_ObjCInterface:
1102 case Action::PCC_ObjCImplementation:
1103 case Action::PCC_Namespace:
1104 case Action::PCC_Template:
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001105 if (LangOpts.CPlusPlus || LangOpts.C99)
Douglas Gregor78a21012010-01-14 16:01:26 +00001106 Results.AddResult(Result("inline"));
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001107 break;
1108
Douglas Gregor00c37ef2010-08-11 21:23:17 +00001109 case Action::PCC_ObjCInstanceVariableList:
1110 case Action::PCC_Expression:
1111 case Action::PCC_Statement:
1112 case Action::PCC_ForInit:
1113 case Action::PCC_Condition:
1114 case Action::PCC_RecoveryInFunction:
Douglas Gregor99fa2642010-08-24 01:06:58 +00001115 case Action::PCC_Type:
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001116 break;
1117 }
1118}
1119
Douglas Gregorf98e6a22010-01-13 23:51:12 +00001120static void AddObjCExpressionResults(ResultBuilder &Results, bool NeedAt);
1121static void AddObjCStatementResults(ResultBuilder &Results, bool NeedAt);
1122static void AddObjCVisibilityResults(const LangOptions &LangOpts,
Douglas Gregor48d46252010-01-13 21:54:15 +00001123 ResultBuilder &Results,
1124 bool NeedAt);
Douglas Gregorf98e6a22010-01-13 23:51:12 +00001125static void AddObjCImplementationResults(const LangOptions &LangOpts,
Douglas Gregorf1934162010-01-13 21:24:21 +00001126 ResultBuilder &Results,
1127 bool NeedAt);
Douglas Gregorf98e6a22010-01-13 23:51:12 +00001128static void AddObjCInterfaceResults(const LangOptions &LangOpts,
Douglas Gregorf1934162010-01-13 21:24:21 +00001129 ResultBuilder &Results,
1130 bool NeedAt);
Douglas Gregorf98e6a22010-01-13 23:51:12 +00001131static void AddObjCTopLevelResults(ResultBuilder &Results, bool NeedAt);
Douglas Gregorf1934162010-01-13 21:24:21 +00001132
Douglas Gregorf4c33342010-05-28 00:22:41 +00001133static void AddTypedefResult(ResultBuilder &Results) {
1134 CodeCompletionString *Pattern = new CodeCompletionString;
1135 Pattern->AddTypedTextChunk("typedef");
1136 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
1137 Pattern->AddPlaceholderChunk("type");
1138 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
1139 Pattern->AddPlaceholderChunk("name");
1140 Results.AddResult(CodeCompleteConsumer::Result(Pattern));
1141}
1142
Douglas Gregor00c37ef2010-08-11 21:23:17 +00001143static bool WantTypesInContext(Action::ParserCompletionContext CCC,
Douglas Gregor70febae2010-05-28 00:49:12 +00001144 const LangOptions &LangOpts) {
1145 if (LangOpts.CPlusPlus)
1146 return true;
1147
1148 switch (CCC) {
Douglas Gregor00c37ef2010-08-11 21:23:17 +00001149 case Action::PCC_Namespace:
1150 case Action::PCC_Class:
1151 case Action::PCC_ObjCInstanceVariableList:
1152 case Action::PCC_Template:
1153 case Action::PCC_MemberTemplate:
1154 case Action::PCC_Statement:
1155 case Action::PCC_RecoveryInFunction:
Douglas Gregor99fa2642010-08-24 01:06:58 +00001156 case Action::PCC_Type:
Douglas Gregor70febae2010-05-28 00:49:12 +00001157 return true;
1158
Douglas Gregor00c37ef2010-08-11 21:23:17 +00001159 case Action::PCC_ObjCInterface:
1160 case Action::PCC_ObjCImplementation:
1161 case Action::PCC_Expression:
1162 case Action::PCC_Condition:
Douglas Gregor70febae2010-05-28 00:49:12 +00001163 return false;
1164
Douglas Gregor00c37ef2010-08-11 21:23:17 +00001165 case Action::PCC_ForInit:
Douglas Gregor70febae2010-05-28 00:49:12 +00001166 return LangOpts.ObjC1 || LangOpts.C99;
1167 }
1168
1169 return false;
1170}
1171
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001172/// \brief Add language constructs that show up for "ordinary" names.
Douglas Gregor00c37ef2010-08-11 21:23:17 +00001173static void AddOrdinaryNameResults(Action::ParserCompletionContext CCC,
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001174 Scope *S,
1175 Sema &SemaRef,
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001176 ResultBuilder &Results) {
1177 typedef CodeCompleteConsumer::Result Result;
1178 switch (CCC) {
Douglas Gregor00c37ef2010-08-11 21:23:17 +00001179 case Action::PCC_Namespace:
Douglas Gregorf4c33342010-05-28 00:22:41 +00001180 if (SemaRef.getLangOptions().CPlusPlus) {
1181 CodeCompletionString *Pattern = 0;
1182
1183 if (Results.includeCodePatterns()) {
1184 // namespace <identifier> { declarations }
1185 CodeCompletionString *Pattern = new CodeCompletionString;
1186 Pattern->AddTypedTextChunk("namespace");
1187 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
1188 Pattern->AddPlaceholderChunk("identifier");
1189 Pattern->AddChunk(CodeCompletionString::CK_LeftBrace);
1190 Pattern->AddPlaceholderChunk("declarations");
1191 Pattern->AddChunk(CodeCompletionString::CK_VerticalSpace);
1192 Pattern->AddChunk(CodeCompletionString::CK_RightBrace);
1193 Results.AddResult(Result(Pattern));
1194 }
1195
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001196 // namespace identifier = identifier ;
1197 Pattern = new CodeCompletionString;
1198 Pattern->AddTypedTextChunk("namespace");
1199 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
Douglas Gregorf4c33342010-05-28 00:22:41 +00001200 Pattern->AddPlaceholderChunk("name");
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001201 Pattern->AddChunk(CodeCompletionString::CK_Equal);
Douglas Gregorf4c33342010-05-28 00:22:41 +00001202 Pattern->AddPlaceholderChunk("namespace");
Douglas Gregor78a21012010-01-14 16:01:26 +00001203 Results.AddResult(Result(Pattern));
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001204
1205 // Using directives
1206 Pattern = new CodeCompletionString;
1207 Pattern->AddTypedTextChunk("using");
1208 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
1209 Pattern->AddTextChunk("namespace");
1210 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
1211 Pattern->AddPlaceholderChunk("identifier");
Douglas Gregor78a21012010-01-14 16:01:26 +00001212 Results.AddResult(Result(Pattern));
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001213
1214 // asm(string-literal)
1215 Pattern = new CodeCompletionString;
1216 Pattern->AddTypedTextChunk("asm");
1217 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
1218 Pattern->AddPlaceholderChunk("string-literal");
1219 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
Douglas Gregor78a21012010-01-14 16:01:26 +00001220 Results.AddResult(Result(Pattern));
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001221
Douglas Gregorf4c33342010-05-28 00:22:41 +00001222 if (Results.includeCodePatterns()) {
1223 // Explicit template instantiation
1224 Pattern = new CodeCompletionString;
1225 Pattern->AddTypedTextChunk("template");
1226 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
1227 Pattern->AddPlaceholderChunk("declaration");
1228 Results.AddResult(Result(Pattern));
1229 }
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001230 }
Douglas Gregorf1934162010-01-13 21:24:21 +00001231
1232 if (SemaRef.getLangOptions().ObjC1)
Douglas Gregorf98e6a22010-01-13 23:51:12 +00001233 AddObjCTopLevelResults(Results, true);
Douglas Gregorf1934162010-01-13 21:24:21 +00001234
Douglas Gregorf4c33342010-05-28 00:22:41 +00001235 AddTypedefResult(Results);
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001236 // Fall through
1237
Douglas Gregor00c37ef2010-08-11 21:23:17 +00001238 case Action::PCC_Class:
Douglas Gregorf4c33342010-05-28 00:22:41 +00001239 if (SemaRef.getLangOptions().CPlusPlus) {
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001240 // Using declaration
1241 CodeCompletionString *Pattern = new CodeCompletionString;
1242 Pattern->AddTypedTextChunk("using");
1243 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
Douglas Gregorf4c33342010-05-28 00:22:41 +00001244 Pattern->AddPlaceholderChunk("qualifier");
1245 Pattern->AddTextChunk("::");
1246 Pattern->AddPlaceholderChunk("name");
Douglas Gregor78a21012010-01-14 16:01:26 +00001247 Results.AddResult(Result(Pattern));
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001248
Douglas Gregorf4c33342010-05-28 00:22:41 +00001249 // using typename qualifier::name (only in a dependent context)
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001250 if (SemaRef.CurContext->isDependentContext()) {
1251 Pattern = new CodeCompletionString;
1252 Pattern->AddTypedTextChunk("using");
1253 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
1254 Pattern->AddTextChunk("typename");
1255 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
Douglas Gregorf4c33342010-05-28 00:22:41 +00001256 Pattern->AddPlaceholderChunk("qualifier");
1257 Pattern->AddTextChunk("::");
1258 Pattern->AddPlaceholderChunk("name");
Douglas Gregor78a21012010-01-14 16:01:26 +00001259 Results.AddResult(Result(Pattern));
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001260 }
1261
Douglas Gregor00c37ef2010-08-11 21:23:17 +00001262 if (CCC == Action::PCC_Class) {
Douglas Gregorf4c33342010-05-28 00:22:41 +00001263 AddTypedefResult(Results);
1264
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001265 // public:
1266 Pattern = new CodeCompletionString;
1267 Pattern->AddTypedTextChunk("public");
1268 Pattern->AddChunk(CodeCompletionString::CK_Colon);
Douglas Gregor78a21012010-01-14 16:01:26 +00001269 Results.AddResult(Result(Pattern));
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001270
1271 // protected:
1272 Pattern = new CodeCompletionString;
1273 Pattern->AddTypedTextChunk("protected");
1274 Pattern->AddChunk(CodeCompletionString::CK_Colon);
Douglas Gregor78a21012010-01-14 16:01:26 +00001275 Results.AddResult(Result(Pattern));
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001276
1277 // private:
1278 Pattern = new CodeCompletionString;
1279 Pattern->AddTypedTextChunk("private");
1280 Pattern->AddChunk(CodeCompletionString::CK_Colon);
Douglas Gregor78a21012010-01-14 16:01:26 +00001281 Results.AddResult(Result(Pattern));
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001282 }
1283 }
1284 // Fall through
1285
Douglas Gregor00c37ef2010-08-11 21:23:17 +00001286 case Action::PCC_Template:
1287 case Action::PCC_MemberTemplate:
Douglas Gregorf64acca2010-05-25 21:41:55 +00001288 if (SemaRef.getLangOptions().CPlusPlus && Results.includeCodePatterns()) {
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001289 // template < parameters >
1290 CodeCompletionString *Pattern = new CodeCompletionString;
1291 Pattern->AddTypedTextChunk("template");
1292 Pattern->AddChunk(CodeCompletionString::CK_LeftAngle);
1293 Pattern->AddPlaceholderChunk("parameters");
1294 Pattern->AddChunk(CodeCompletionString::CK_RightAngle);
Douglas Gregor78a21012010-01-14 16:01:26 +00001295 Results.AddResult(Result(Pattern));
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001296 }
1297
Douglas Gregorf98e6a22010-01-13 23:51:12 +00001298 AddStorageSpecifiers(CCC, SemaRef.getLangOptions(), Results);
1299 AddFunctionSpecifiers(CCC, SemaRef.getLangOptions(), Results);
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001300 break;
1301
Douglas Gregor00c37ef2010-08-11 21:23:17 +00001302 case Action::PCC_ObjCInterface:
Douglas Gregorf98e6a22010-01-13 23:51:12 +00001303 AddObjCInterfaceResults(SemaRef.getLangOptions(), Results, true);
1304 AddStorageSpecifiers(CCC, SemaRef.getLangOptions(), Results);
1305 AddFunctionSpecifiers(CCC, SemaRef.getLangOptions(), Results);
Douglas Gregorf1934162010-01-13 21:24:21 +00001306 break;
1307
Douglas Gregor00c37ef2010-08-11 21:23:17 +00001308 case Action::PCC_ObjCImplementation:
Douglas Gregorf98e6a22010-01-13 23:51:12 +00001309 AddObjCImplementationResults(SemaRef.getLangOptions(), Results, true);
1310 AddStorageSpecifiers(CCC, SemaRef.getLangOptions(), Results);
1311 AddFunctionSpecifiers(CCC, SemaRef.getLangOptions(), Results);
Douglas Gregorf1934162010-01-13 21:24:21 +00001312 break;
1313
Douglas Gregor00c37ef2010-08-11 21:23:17 +00001314 case Action::PCC_ObjCInstanceVariableList:
Douglas Gregorf98e6a22010-01-13 23:51:12 +00001315 AddObjCVisibilityResults(SemaRef.getLangOptions(), Results, true);
Douglas Gregor48d46252010-01-13 21:54:15 +00001316 break;
1317
Douglas Gregor00c37ef2010-08-11 21:23:17 +00001318 case Action::PCC_RecoveryInFunction:
1319 case Action::PCC_Statement: {
Douglas Gregorf4c33342010-05-28 00:22:41 +00001320 AddTypedefResult(Results);
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001321
1322 CodeCompletionString *Pattern = 0;
Douglas Gregorf64acca2010-05-25 21:41:55 +00001323 if (SemaRef.getLangOptions().CPlusPlus && Results.includeCodePatterns()) {
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001324 Pattern = new CodeCompletionString;
1325 Pattern->AddTypedTextChunk("try");
1326 Pattern->AddChunk(CodeCompletionString::CK_LeftBrace);
1327 Pattern->AddPlaceholderChunk("statements");
1328 Pattern->AddChunk(CodeCompletionString::CK_VerticalSpace);
1329 Pattern->AddChunk(CodeCompletionString::CK_RightBrace);
1330 Pattern->AddTextChunk("catch");
1331 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
1332 Pattern->AddPlaceholderChunk("declaration");
1333 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
1334 Pattern->AddChunk(CodeCompletionString::CK_LeftBrace);
1335 Pattern->AddPlaceholderChunk("statements");
1336 Pattern->AddChunk(CodeCompletionString::CK_VerticalSpace);
1337 Pattern->AddChunk(CodeCompletionString::CK_RightBrace);
Douglas Gregor78a21012010-01-14 16:01:26 +00001338 Results.AddResult(Result(Pattern));
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001339 }
Douglas Gregorf1934162010-01-13 21:24:21 +00001340 if (SemaRef.getLangOptions().ObjC1)
Douglas Gregorf98e6a22010-01-13 23:51:12 +00001341 AddObjCStatementResults(Results, true);
Douglas Gregorf1934162010-01-13 21:24:21 +00001342
Douglas Gregorf64acca2010-05-25 21:41:55 +00001343 if (Results.includeCodePatterns()) {
1344 // if (condition) { statements }
1345 Pattern = new CodeCompletionString;
1346 Pattern->AddTypedTextChunk("if");
1347 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
1348 if (SemaRef.getLangOptions().CPlusPlus)
1349 Pattern->AddPlaceholderChunk("condition");
1350 else
1351 Pattern->AddPlaceholderChunk("expression");
1352 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
1353 Pattern->AddChunk(CodeCompletionString::CK_LeftBrace);
1354 Pattern->AddPlaceholderChunk("statements");
1355 Pattern->AddChunk(CodeCompletionString::CK_VerticalSpace);
1356 Pattern->AddChunk(CodeCompletionString::CK_RightBrace);
1357 Results.AddResult(Result(Pattern));
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001358
Douglas Gregorf64acca2010-05-25 21:41:55 +00001359 // switch (condition) { }
1360 Pattern = new CodeCompletionString;
1361 Pattern->AddTypedTextChunk("switch");
1362 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
1363 if (SemaRef.getLangOptions().CPlusPlus)
1364 Pattern->AddPlaceholderChunk("condition");
1365 else
1366 Pattern->AddPlaceholderChunk("expression");
1367 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
1368 Pattern->AddChunk(CodeCompletionString::CK_LeftBrace);
1369 Pattern->AddChunk(CodeCompletionString::CK_VerticalSpace);
1370 Pattern->AddChunk(CodeCompletionString::CK_RightBrace);
1371 Results.AddResult(Result(Pattern));
1372 }
1373
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001374 // Switch-specific statements.
Douglas Gregorf4c33342010-05-28 00:22:41 +00001375 if (!SemaRef.getSwitchStack().empty()) {
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001376 // case expression:
1377 Pattern = new CodeCompletionString;
1378 Pattern->AddTypedTextChunk("case");
Douglas Gregorf4c33342010-05-28 00:22:41 +00001379 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001380 Pattern->AddPlaceholderChunk("expression");
1381 Pattern->AddChunk(CodeCompletionString::CK_Colon);
Douglas Gregor78a21012010-01-14 16:01:26 +00001382 Results.AddResult(Result(Pattern));
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001383
1384 // default:
1385 Pattern = new CodeCompletionString;
1386 Pattern->AddTypedTextChunk("default");
1387 Pattern->AddChunk(CodeCompletionString::CK_Colon);
Douglas Gregor78a21012010-01-14 16:01:26 +00001388 Results.AddResult(Result(Pattern));
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001389 }
1390
Douglas Gregorf64acca2010-05-25 21:41:55 +00001391 if (Results.includeCodePatterns()) {
1392 /// while (condition) { statements }
1393 Pattern = new CodeCompletionString;
1394 Pattern->AddTypedTextChunk("while");
1395 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
1396 if (SemaRef.getLangOptions().CPlusPlus)
1397 Pattern->AddPlaceholderChunk("condition");
1398 else
1399 Pattern->AddPlaceholderChunk("expression");
1400 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
1401 Pattern->AddChunk(CodeCompletionString::CK_LeftBrace);
1402 Pattern->AddPlaceholderChunk("statements");
1403 Pattern->AddChunk(CodeCompletionString::CK_VerticalSpace);
1404 Pattern->AddChunk(CodeCompletionString::CK_RightBrace);
1405 Results.AddResult(Result(Pattern));
1406
1407 // do { statements } while ( expression );
1408 Pattern = new CodeCompletionString;
1409 Pattern->AddTypedTextChunk("do");
1410 Pattern->AddChunk(CodeCompletionString::CK_LeftBrace);
1411 Pattern->AddPlaceholderChunk("statements");
1412 Pattern->AddChunk(CodeCompletionString::CK_VerticalSpace);
1413 Pattern->AddChunk(CodeCompletionString::CK_RightBrace);
1414 Pattern->AddTextChunk("while");
1415 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001416 Pattern->AddPlaceholderChunk("expression");
Douglas Gregorf64acca2010-05-25 21:41:55 +00001417 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
1418 Results.AddResult(Result(Pattern));
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001419
Douglas Gregorf64acca2010-05-25 21:41:55 +00001420 // for ( for-init-statement ; condition ; expression ) { statements }
1421 Pattern = new CodeCompletionString;
1422 Pattern->AddTypedTextChunk("for");
1423 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
1424 if (SemaRef.getLangOptions().CPlusPlus || SemaRef.getLangOptions().C99)
1425 Pattern->AddPlaceholderChunk("init-statement");
1426 else
1427 Pattern->AddPlaceholderChunk("init-expression");
1428 Pattern->AddChunk(CodeCompletionString::CK_SemiColon);
1429 Pattern->AddPlaceholderChunk("condition");
1430 Pattern->AddChunk(CodeCompletionString::CK_SemiColon);
1431 Pattern->AddPlaceholderChunk("inc-expression");
1432 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
1433 Pattern->AddChunk(CodeCompletionString::CK_LeftBrace);
1434 Pattern->AddPlaceholderChunk("statements");
1435 Pattern->AddChunk(CodeCompletionString::CK_VerticalSpace);
1436 Pattern->AddChunk(CodeCompletionString::CK_RightBrace);
1437 Results.AddResult(Result(Pattern));
1438 }
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001439
1440 if (S->getContinueParent()) {
1441 // continue ;
1442 Pattern = new CodeCompletionString;
1443 Pattern->AddTypedTextChunk("continue");
Douglas Gregor78a21012010-01-14 16:01:26 +00001444 Results.AddResult(Result(Pattern));
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001445 }
1446
1447 if (S->getBreakParent()) {
1448 // break ;
1449 Pattern = new CodeCompletionString;
1450 Pattern->AddTypedTextChunk("break");
Douglas Gregor78a21012010-01-14 16:01:26 +00001451 Results.AddResult(Result(Pattern));
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001452 }
1453
1454 // "return expression ;" or "return ;", depending on whether we
1455 // know the function is void or not.
1456 bool isVoid = false;
1457 if (FunctionDecl *Function = dyn_cast<FunctionDecl>(SemaRef.CurContext))
1458 isVoid = Function->getResultType()->isVoidType();
1459 else if (ObjCMethodDecl *Method
1460 = dyn_cast<ObjCMethodDecl>(SemaRef.CurContext))
1461 isVoid = Method->getResultType()->isVoidType();
Douglas Gregor9a28e842010-03-01 23:15:13 +00001462 else if (SemaRef.getCurBlock() &&
1463 !SemaRef.getCurBlock()->ReturnType.isNull())
1464 isVoid = SemaRef.getCurBlock()->ReturnType->isVoidType();
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001465 Pattern = new CodeCompletionString;
1466 Pattern->AddTypedTextChunk("return");
Douglas Gregor44272ca2010-02-18 04:06:48 +00001467 if (!isVoid) {
1468 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001469 Pattern->AddPlaceholderChunk("expression");
Douglas Gregor44272ca2010-02-18 04:06:48 +00001470 }
Douglas Gregor78a21012010-01-14 16:01:26 +00001471 Results.AddResult(Result(Pattern));
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001472
Douglas Gregorf4c33342010-05-28 00:22:41 +00001473 // goto identifier ;
1474 Pattern = new CodeCompletionString;
1475 Pattern->AddTypedTextChunk("goto");
1476 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
1477 Pattern->AddPlaceholderChunk("label");
1478 Results.AddResult(Result(Pattern));
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001479
Douglas Gregorf4c33342010-05-28 00:22:41 +00001480 // Using directives
1481 Pattern = new CodeCompletionString;
1482 Pattern->AddTypedTextChunk("using");
1483 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
1484 Pattern->AddTextChunk("namespace");
1485 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
1486 Pattern->AddPlaceholderChunk("identifier");
1487 Results.AddResult(Result(Pattern));
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001488 }
1489
1490 // Fall through (for statement expressions).
Douglas Gregor00c37ef2010-08-11 21:23:17 +00001491 case Action::PCC_ForInit:
1492 case Action::PCC_Condition:
Douglas Gregorf98e6a22010-01-13 23:51:12 +00001493 AddStorageSpecifiers(CCC, SemaRef.getLangOptions(), Results);
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001494 // Fall through: conditions and statements can have expressions.
1495
Douglas Gregor00c37ef2010-08-11 21:23:17 +00001496 case Action::PCC_Expression: {
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001497 CodeCompletionString *Pattern = 0;
1498 if (SemaRef.getLangOptions().CPlusPlus) {
1499 // 'this', if we're in a non-static member function.
1500 if (CXXMethodDecl *Method = dyn_cast<CXXMethodDecl>(SemaRef.CurContext))
1501 if (!Method->isStatic())
Douglas Gregor78a21012010-01-14 16:01:26 +00001502 Results.AddResult(Result("this"));
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001503
1504 // true, false
Douglas Gregor78a21012010-01-14 16:01:26 +00001505 Results.AddResult(Result("true"));
1506 Results.AddResult(Result("false"));
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001507
Douglas Gregorf4c33342010-05-28 00:22:41 +00001508 // dynamic_cast < type-id > ( expression )
1509 Pattern = new CodeCompletionString;
1510 Pattern->AddTypedTextChunk("dynamic_cast");
1511 Pattern->AddChunk(CodeCompletionString::CK_LeftAngle);
1512 Pattern->AddPlaceholderChunk("type");
1513 Pattern->AddChunk(CodeCompletionString::CK_RightAngle);
1514 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
1515 Pattern->AddPlaceholderChunk("expression");
1516 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
1517 Results.AddResult(Result(Pattern));
1518
1519 // static_cast < type-id > ( expression )
1520 Pattern = new CodeCompletionString;
1521 Pattern->AddTypedTextChunk("static_cast");
1522 Pattern->AddChunk(CodeCompletionString::CK_LeftAngle);
1523 Pattern->AddPlaceholderChunk("type");
1524 Pattern->AddChunk(CodeCompletionString::CK_RightAngle);
1525 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
1526 Pattern->AddPlaceholderChunk("expression");
1527 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
1528 Results.AddResult(Result(Pattern));
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001529
Douglas Gregorf4c33342010-05-28 00:22:41 +00001530 // reinterpret_cast < type-id > ( expression )
1531 Pattern = new CodeCompletionString;
1532 Pattern->AddTypedTextChunk("reinterpret_cast");
1533 Pattern->AddChunk(CodeCompletionString::CK_LeftAngle);
1534 Pattern->AddPlaceholderChunk("type");
1535 Pattern->AddChunk(CodeCompletionString::CK_RightAngle);
1536 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
1537 Pattern->AddPlaceholderChunk("expression");
1538 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
1539 Results.AddResult(Result(Pattern));
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001540
Douglas Gregorf4c33342010-05-28 00:22:41 +00001541 // const_cast < type-id > ( expression )
1542 Pattern = new CodeCompletionString;
1543 Pattern->AddTypedTextChunk("const_cast");
1544 Pattern->AddChunk(CodeCompletionString::CK_LeftAngle);
1545 Pattern->AddPlaceholderChunk("type");
1546 Pattern->AddChunk(CodeCompletionString::CK_RightAngle);
1547 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
1548 Pattern->AddPlaceholderChunk("expression");
1549 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
1550 Results.AddResult(Result(Pattern));
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001551
Douglas Gregorf4c33342010-05-28 00:22:41 +00001552 // typeid ( expression-or-type )
1553 Pattern = new CodeCompletionString;
1554 Pattern->AddTypedTextChunk("typeid");
1555 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
1556 Pattern->AddPlaceholderChunk("expression-or-type");
1557 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
1558 Results.AddResult(Result(Pattern));
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001559
Douglas Gregorf4c33342010-05-28 00:22:41 +00001560 // new T ( ... )
1561 Pattern = new CodeCompletionString;
1562 Pattern->AddTypedTextChunk("new");
1563 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
1564 Pattern->AddPlaceholderChunk("type");
1565 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
1566 Pattern->AddPlaceholderChunk("expressions");
1567 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
1568 Results.AddResult(Result(Pattern));
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001569
Douglas Gregorf4c33342010-05-28 00:22:41 +00001570 // new T [ ] ( ... )
1571 Pattern = new CodeCompletionString;
1572 Pattern->AddTypedTextChunk("new");
1573 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
1574 Pattern->AddPlaceholderChunk("type");
1575 Pattern->AddChunk(CodeCompletionString::CK_LeftBracket);
1576 Pattern->AddPlaceholderChunk("size");
1577 Pattern->AddChunk(CodeCompletionString::CK_RightBracket);
1578 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
1579 Pattern->AddPlaceholderChunk("expressions");
1580 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
1581 Results.AddResult(Result(Pattern));
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001582
Douglas Gregorf4c33342010-05-28 00:22:41 +00001583 // delete expression
1584 Pattern = new CodeCompletionString;
1585 Pattern->AddTypedTextChunk("delete");
1586 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
1587 Pattern->AddPlaceholderChunk("expression");
1588 Results.AddResult(Result(Pattern));
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001589
Douglas Gregorf4c33342010-05-28 00:22:41 +00001590 // delete [] expression
1591 Pattern = new CodeCompletionString;
1592 Pattern->AddTypedTextChunk("delete");
1593 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
1594 Pattern->AddChunk(CodeCompletionString::CK_LeftBracket);
1595 Pattern->AddChunk(CodeCompletionString::CK_RightBracket);
1596 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
1597 Pattern->AddPlaceholderChunk("expression");
1598 Results.AddResult(Result(Pattern));
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001599
Douglas Gregorf4c33342010-05-28 00:22:41 +00001600 // throw expression
1601 Pattern = new CodeCompletionString;
1602 Pattern->AddTypedTextChunk("throw");
1603 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
1604 Pattern->AddPlaceholderChunk("expression");
1605 Results.AddResult(Result(Pattern));
Douglas Gregora2db7932010-05-26 22:00:08 +00001606
1607 // FIXME: Rethrow?
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001608 }
1609
1610 if (SemaRef.getLangOptions().ObjC1) {
1611 // Add "super", if we're in an Objective-C class with a superclass.
Ted Kremenek305a0a72010-05-31 21:43:10 +00001612 if (ObjCMethodDecl *Method = SemaRef.getCurMethodDecl()) {
1613 // The interface can be NULL.
1614 if (ObjCInterfaceDecl *ID = Method->getClassInterface())
1615 if (ID->getSuperClass())
1616 Results.AddResult(Result("super"));
1617 }
1618
Douglas Gregorf98e6a22010-01-13 23:51:12 +00001619 AddObjCExpressionResults(Results, true);
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001620 }
1621
Douglas Gregorf4c33342010-05-28 00:22:41 +00001622 // sizeof expression
1623 Pattern = new CodeCompletionString;
1624 Pattern->AddTypedTextChunk("sizeof");
1625 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
1626 Pattern->AddPlaceholderChunk("expression-or-type");
1627 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
1628 Results.AddResult(Result(Pattern));
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001629 break;
1630 }
Douglas Gregor99fa2642010-08-24 01:06:58 +00001631
1632 case Action::PCC_Type:
1633 break;
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001634 }
1635
Douglas Gregor70febae2010-05-28 00:49:12 +00001636 if (WantTypesInContext(CCC, SemaRef.getLangOptions()))
1637 AddTypeSpecifierResults(SemaRef.getLangOptions(), Results);
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001638
Douglas Gregor99fa2642010-08-24 01:06:58 +00001639 if (SemaRef.getLangOptions().CPlusPlus && CCC != Action::PCC_Type)
Douglas Gregor78a21012010-01-14 16:01:26 +00001640 Results.AddResult(Result("operator"));
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001641}
1642
Douglas Gregorb3fa9192009-12-18 18:53:37 +00001643/// \brief If the given declaration has an associated type, add it as a result
1644/// type chunk.
1645static void AddResultTypeChunk(ASTContext &Context,
1646 NamedDecl *ND,
1647 CodeCompletionString *Result) {
1648 if (!ND)
1649 return;
1650
1651 // Determine the type of the declaration (if it has a type).
1652 QualType T;
1653 if (FunctionDecl *Function = dyn_cast<FunctionDecl>(ND))
1654 T = Function->getResultType();
1655 else if (ObjCMethodDecl *Method = dyn_cast<ObjCMethodDecl>(ND))
1656 T = Method->getResultType();
1657 else if (FunctionTemplateDecl *FunTmpl = dyn_cast<FunctionTemplateDecl>(ND))
1658 T = FunTmpl->getTemplatedDecl()->getResultType();
1659 else if (EnumConstantDecl *Enumerator = dyn_cast<EnumConstantDecl>(ND))
1660 T = Context.getTypeDeclType(cast<TypeDecl>(Enumerator->getDeclContext()));
1661 else if (isa<UnresolvedUsingValueDecl>(ND)) {
1662 /* Do nothing: ignore unresolved using declarations*/
1663 } else if (ValueDecl *Value = dyn_cast<ValueDecl>(ND))
1664 T = Value->getType();
1665 else if (ObjCPropertyDecl *Property = dyn_cast<ObjCPropertyDecl>(ND))
1666 T = Property->getType();
1667
1668 if (T.isNull() || Context.hasSameType(T, Context.DependentTy))
1669 return;
1670
Douglas Gregorcf04b022010-04-05 21:25:31 +00001671 PrintingPolicy Policy(Context.PrintingPolicy);
1672 Policy.AnonymousTagLocations = false;
1673
Douglas Gregorb3fa9192009-12-18 18:53:37 +00001674 std::string TypeStr;
Douglas Gregorcf04b022010-04-05 21:25:31 +00001675 T.getAsStringInternal(TypeStr, Policy);
Douglas Gregorb3fa9192009-12-18 18:53:37 +00001676 Result->AddResultTypeChunk(TypeStr);
1677}
1678
Douglas Gregordbb71db2010-08-23 23:51:41 +00001679static void MaybeAddSentinel(ASTContext &Context, NamedDecl *FunctionOrMethod,
1680 CodeCompletionString *Result) {
1681 if (SentinelAttr *Sentinel = FunctionOrMethod->getAttr<SentinelAttr>())
1682 if (Sentinel->getSentinel() == 0) {
1683 if (Context.getLangOptions().ObjC1 &&
1684 Context.Idents.get("nil").hasMacroDefinition())
1685 Result->AddTextChunk(", nil");
1686 else if (Context.Idents.get("NULL").hasMacroDefinition())
1687 Result->AddTextChunk(", NULL");
1688 else
1689 Result->AddTextChunk(", (void*)0");
1690 }
1691}
1692
Douglas Gregore90dd002010-08-24 16:15:59 +00001693static std::string FormatFunctionParameter(ASTContext &Context,
1694 ParmVarDecl *Param) {
1695 bool ObjCMethodParam = isa<ObjCMethodDecl>(Param->getDeclContext());
1696 if (Param->getType()->isDependentType() ||
1697 !Param->getType()->isBlockPointerType()) {
1698 // The argument for a dependent or non-block parameter is a placeholder
1699 // containing that parameter's type.
1700 std::string Result;
1701
1702 if (Param->getIdentifier() && !ObjCMethodParam)
1703 Result = Param->getIdentifier()->getName();
1704
1705 Param->getType().getAsStringInternal(Result,
1706 Context.PrintingPolicy);
1707
1708 if (ObjCMethodParam) {
1709 Result = "(" + Result;
1710 Result += ")";
1711 if (Param->getIdentifier())
1712 Result += Param->getIdentifier()->getName();
1713 }
1714 return Result;
1715 }
1716
1717 // The argument for a block pointer parameter is a block literal with
1718 // the appropriate type.
1719 FunctionProtoTypeLoc *Block = 0;
1720 TypeLoc TL;
1721 if (TypeSourceInfo *TSInfo = Param->getTypeSourceInfo()) {
1722 TL = TSInfo->getTypeLoc().getUnqualifiedLoc();
1723 while (true) {
1724 // Look through typedefs.
1725 if (TypedefTypeLoc *TypedefTL = dyn_cast<TypedefTypeLoc>(&TL)) {
1726 if (TypeSourceInfo *InnerTSInfo
1727 = TypedefTL->getTypedefDecl()->getTypeSourceInfo()) {
1728 TL = InnerTSInfo->getTypeLoc().getUnqualifiedLoc();
1729 continue;
1730 }
1731 }
1732
1733 // Look through qualified types
1734 if (QualifiedTypeLoc *QualifiedTL = dyn_cast<QualifiedTypeLoc>(&TL)) {
1735 TL = QualifiedTL->getUnqualifiedLoc();
1736 continue;
1737 }
1738
1739 // Try to get the function prototype behind the block pointer type,
1740 // then we're done.
1741 if (BlockPointerTypeLoc *BlockPtr
1742 = dyn_cast<BlockPointerTypeLoc>(&TL)) {
1743 TL = BlockPtr->getPointeeLoc();
1744 Block = dyn_cast<FunctionProtoTypeLoc>(&TL);
1745 }
1746 break;
1747 }
1748 }
1749
1750 if (!Block) {
1751 // We were unable to find a FunctionProtoTypeLoc with parameter names
1752 // for the block; just use the parameter type as a placeholder.
1753 std::string Result;
1754 Param->getType().getUnqualifiedType().
1755 getAsStringInternal(Result, Context.PrintingPolicy);
1756
1757 if (ObjCMethodParam) {
1758 Result = "(" + Result;
1759 Result += ")";
1760 if (Param->getIdentifier())
1761 Result += Param->getIdentifier()->getName();
1762 }
1763
1764 return Result;
1765 }
1766
1767 // We have the function prototype behind the block pointer type, as it was
1768 // written in the source.
1769 std::string Result = "(^)(";
1770 for (unsigned I = 0, N = Block->getNumArgs(); I != N; ++I) {
1771 if (I)
1772 Result += ", ";
1773 Result += FormatFunctionParameter(Context, Block->getArg(I));
1774 }
1775 if (Block->getTypePtr()->isVariadic()) {
1776 if (Block->getNumArgs() > 0)
1777 Result += ", ...";
1778 else
1779 Result += "...";
1780 } else if (Block->getNumArgs() == 0 && !Context.getLangOptions().CPlusPlus)
1781 Result += "void";
1782
1783 Result += ")";
1784 Block->getTypePtr()->getResultType().getAsStringInternal(Result,
1785 Context.PrintingPolicy);
1786 return Result;
1787}
1788
Douglas Gregor3545ff42009-09-21 16:56:56 +00001789/// \brief Add function parameter chunks to the given code completion string.
1790static void AddFunctionParameterChunks(ASTContext &Context,
1791 FunctionDecl *Function,
1792 CodeCompletionString *Result) {
Douglas Gregor9eb77012009-11-07 00:00:49 +00001793 typedef CodeCompletionString::Chunk Chunk;
1794
Douglas Gregor3545ff42009-09-21 16:56:56 +00001795 CodeCompletionString *CCStr = Result;
1796
1797 for (unsigned P = 0, N = Function->getNumParams(); P != N; ++P) {
1798 ParmVarDecl *Param = Function->getParamDecl(P);
1799
1800 if (Param->hasDefaultArg()) {
1801 // When we see an optional default argument, put that argument and
1802 // the remaining default arguments into a new, optional string.
1803 CodeCompletionString *Opt = new CodeCompletionString;
1804 CCStr->AddOptionalChunk(std::auto_ptr<CodeCompletionString>(Opt));
1805 CCStr = Opt;
1806 }
1807
1808 if (P != 0)
Douglas Gregor9eb77012009-11-07 00:00:49 +00001809 CCStr->AddChunk(Chunk(CodeCompletionString::CK_Comma));
Douglas Gregor3545ff42009-09-21 16:56:56 +00001810
1811 // Format the placeholder string.
Douglas Gregore90dd002010-08-24 16:15:59 +00001812 std::string PlaceholderStr = FormatFunctionParameter(Context, Param);
1813
Douglas Gregor3545ff42009-09-21 16:56:56 +00001814 // Add the placeholder string.
Benjamin Kramerb33a97c2009-11-29 20:18:50 +00001815 CCStr->AddPlaceholderChunk(PlaceholderStr);
Douglas Gregor3545ff42009-09-21 16:56:56 +00001816 }
Douglas Gregorba449032009-09-22 21:42:17 +00001817
1818 if (const FunctionProtoType *Proto
1819 = Function->getType()->getAs<FunctionProtoType>())
Douglas Gregordbb71db2010-08-23 23:51:41 +00001820 if (Proto->isVariadic()) {
Douglas Gregorba449032009-09-22 21:42:17 +00001821 CCStr->AddPlaceholderChunk(", ...");
Douglas Gregordbb71db2010-08-23 23:51:41 +00001822
1823 MaybeAddSentinel(Context, Function, CCStr);
1824 }
Douglas Gregor3545ff42009-09-21 16:56:56 +00001825}
1826
1827/// \brief Add template parameter chunks to the given code completion string.
1828static void AddTemplateParameterChunks(ASTContext &Context,
1829 TemplateDecl *Template,
1830 CodeCompletionString *Result,
1831 unsigned MaxParameters = 0) {
Douglas Gregor9eb77012009-11-07 00:00:49 +00001832 typedef CodeCompletionString::Chunk Chunk;
1833
Douglas Gregor3545ff42009-09-21 16:56:56 +00001834 CodeCompletionString *CCStr = Result;
1835 bool FirstParameter = true;
1836
1837 TemplateParameterList *Params = Template->getTemplateParameters();
1838 TemplateParameterList::iterator PEnd = Params->end();
1839 if (MaxParameters)
1840 PEnd = Params->begin() + MaxParameters;
1841 for (TemplateParameterList::iterator P = Params->begin(); P != PEnd; ++P) {
1842 bool HasDefaultArg = false;
1843 std::string PlaceholderStr;
1844 if (TemplateTypeParmDecl *TTP = dyn_cast<TemplateTypeParmDecl>(*P)) {
1845 if (TTP->wasDeclaredWithTypename())
1846 PlaceholderStr = "typename";
1847 else
1848 PlaceholderStr = "class";
1849
1850 if (TTP->getIdentifier()) {
1851 PlaceholderStr += ' ';
1852 PlaceholderStr += TTP->getIdentifier()->getName();
1853 }
1854
1855 HasDefaultArg = TTP->hasDefaultArgument();
1856 } else if (NonTypeTemplateParmDecl *NTTP
1857 = dyn_cast<NonTypeTemplateParmDecl>(*P)) {
1858 if (NTTP->getIdentifier())
1859 PlaceholderStr = NTTP->getIdentifier()->getName();
1860 NTTP->getType().getAsStringInternal(PlaceholderStr,
1861 Context.PrintingPolicy);
1862 HasDefaultArg = NTTP->hasDefaultArgument();
1863 } else {
1864 assert(isa<TemplateTemplateParmDecl>(*P));
1865 TemplateTemplateParmDecl *TTP = cast<TemplateTemplateParmDecl>(*P);
1866
1867 // Since putting the template argument list into the placeholder would
1868 // be very, very long, we just use an abbreviation.
1869 PlaceholderStr = "template<...> class";
1870 if (TTP->getIdentifier()) {
1871 PlaceholderStr += ' ';
1872 PlaceholderStr += TTP->getIdentifier()->getName();
1873 }
1874
1875 HasDefaultArg = TTP->hasDefaultArgument();
1876 }
1877
1878 if (HasDefaultArg) {
1879 // When we see an optional default argument, put that argument and
1880 // the remaining default arguments into a new, optional string.
1881 CodeCompletionString *Opt = new CodeCompletionString;
1882 CCStr->AddOptionalChunk(std::auto_ptr<CodeCompletionString>(Opt));
1883 CCStr = Opt;
1884 }
1885
1886 if (FirstParameter)
1887 FirstParameter = false;
1888 else
Douglas Gregor9eb77012009-11-07 00:00:49 +00001889 CCStr->AddChunk(Chunk(CodeCompletionString::CK_Comma));
Douglas Gregor3545ff42009-09-21 16:56:56 +00001890
1891 // Add the placeholder string.
Benjamin Kramerb33a97c2009-11-29 20:18:50 +00001892 CCStr->AddPlaceholderChunk(PlaceholderStr);
Douglas Gregor3545ff42009-09-21 16:56:56 +00001893 }
1894}
1895
Douglas Gregorf2510672009-09-21 19:57:38 +00001896/// \brief Add a qualifier to the given code-completion string, if the
1897/// provided nested-name-specifier is non-NULL.
Douglas Gregor0f622362009-12-11 18:44:16 +00001898static void
1899AddQualifierToCompletionString(CodeCompletionString *Result,
1900 NestedNameSpecifier *Qualifier,
1901 bool QualifierIsInformative,
1902 ASTContext &Context) {
Douglas Gregorf2510672009-09-21 19:57:38 +00001903 if (!Qualifier)
1904 return;
1905
1906 std::string PrintedNNS;
1907 {
1908 llvm::raw_string_ostream OS(PrintedNNS);
1909 Qualifier->print(OS, Context.PrintingPolicy);
1910 }
Douglas Gregor5bf52692009-09-22 23:15:58 +00001911 if (QualifierIsInformative)
Benjamin Kramerb33a97c2009-11-29 20:18:50 +00001912 Result->AddInformativeChunk(PrintedNNS);
Douglas Gregor5bf52692009-09-22 23:15:58 +00001913 else
Benjamin Kramerb33a97c2009-11-29 20:18:50 +00001914 Result->AddTextChunk(PrintedNNS);
Douglas Gregorf2510672009-09-21 19:57:38 +00001915}
1916
Douglas Gregor0f622362009-12-11 18:44:16 +00001917static void AddFunctionTypeQualsToCompletionString(CodeCompletionString *Result,
1918 FunctionDecl *Function) {
1919 const FunctionProtoType *Proto
1920 = Function->getType()->getAs<FunctionProtoType>();
1921 if (!Proto || !Proto->getTypeQuals())
1922 return;
1923
1924 std::string QualsStr;
1925 if (Proto->getTypeQuals() & Qualifiers::Const)
1926 QualsStr += " const";
1927 if (Proto->getTypeQuals() & Qualifiers::Volatile)
1928 QualsStr += " volatile";
1929 if (Proto->getTypeQuals() & Qualifiers::Restrict)
1930 QualsStr += " restrict";
1931 Result->AddInformativeChunk(QualsStr);
1932}
1933
Douglas Gregor3545ff42009-09-21 16:56:56 +00001934/// \brief If possible, create a new code completion string for the given
1935/// result.
1936///
1937/// \returns Either a new, heap-allocated code completion string describing
1938/// how to use this result, or NULL to indicate that the string or name of the
1939/// result is all that is needed.
1940CodeCompletionString *
Douglas Gregor8e984da2010-08-04 16:47:14 +00001941CodeCompleteConsumer::Result::CreateCodeCompletionString(Sema &S,
1942 CodeCompletionString *Result) {
Douglas Gregor9eb77012009-11-07 00:00:49 +00001943 typedef CodeCompletionString::Chunk Chunk;
1944
Douglas Gregorf09935f2009-12-01 05:55:20 +00001945 if (Kind == RK_Pattern)
Douglas Gregor8e984da2010-08-04 16:47:14 +00001946 return Pattern->Clone(Result);
Douglas Gregorf09935f2009-12-01 05:55:20 +00001947
Douglas Gregor8e984da2010-08-04 16:47:14 +00001948 if (!Result)
1949 Result = new CodeCompletionString;
Douglas Gregorf09935f2009-12-01 05:55:20 +00001950
1951 if (Kind == RK_Keyword) {
1952 Result->AddTypedTextChunk(Keyword);
1953 return Result;
1954 }
Douglas Gregor3545ff42009-09-21 16:56:56 +00001955
Douglas Gregorf329c7c2009-10-30 16:50:04 +00001956 if (Kind == RK_Macro) {
1957 MacroInfo *MI = S.PP.getMacroInfo(Macro);
Douglas Gregorf09935f2009-12-01 05:55:20 +00001958 assert(MI && "Not a macro?");
1959
1960 Result->AddTypedTextChunk(Macro->getName());
1961
1962 if (!MI->isFunctionLike())
1963 return Result;
Douglas Gregorf329c7c2009-10-30 16:50:04 +00001964
1965 // Format a function-like macro with placeholders for the arguments.
Douglas Gregor9eb77012009-11-07 00:00:49 +00001966 Result->AddChunk(Chunk(CodeCompletionString::CK_LeftParen));
Douglas Gregorf329c7c2009-10-30 16:50:04 +00001967 for (MacroInfo::arg_iterator A = MI->arg_begin(), AEnd = MI->arg_end();
1968 A != AEnd; ++A) {
1969 if (A != MI->arg_begin())
Douglas Gregor9eb77012009-11-07 00:00:49 +00001970 Result->AddChunk(Chunk(CodeCompletionString::CK_Comma));
Douglas Gregorf329c7c2009-10-30 16:50:04 +00001971
1972 if (!MI->isVariadic() || A != AEnd - 1) {
1973 // Non-variadic argument.
Benjamin Kramerb33a97c2009-11-29 20:18:50 +00001974 Result->AddPlaceholderChunk((*A)->getName());
Douglas Gregorf329c7c2009-10-30 16:50:04 +00001975 continue;
1976 }
1977
1978 // Variadic argument; cope with the different between GNU and C99
1979 // variadic macros, providing a single placeholder for the rest of the
1980 // arguments.
1981 if ((*A)->isStr("__VA_ARGS__"))
1982 Result->AddPlaceholderChunk("...");
1983 else {
1984 std::string Arg = (*A)->getName();
1985 Arg += "...";
Benjamin Kramerb33a97c2009-11-29 20:18:50 +00001986 Result->AddPlaceholderChunk(Arg);
Douglas Gregorf329c7c2009-10-30 16:50:04 +00001987 }
1988 }
Douglas Gregor9eb77012009-11-07 00:00:49 +00001989 Result->AddChunk(Chunk(CodeCompletionString::CK_RightParen));
Douglas Gregorf329c7c2009-10-30 16:50:04 +00001990 return Result;
1991 }
1992
Douglas Gregorf64acca2010-05-25 21:41:55 +00001993 assert(Kind == RK_Declaration && "Missed a result kind?");
Douglas Gregor3545ff42009-09-21 16:56:56 +00001994 NamedDecl *ND = Declaration;
1995
Douglas Gregor9eb77012009-11-07 00:00:49 +00001996 if (StartsNestedNameSpecifier) {
Benjamin Kramerb33a97c2009-11-29 20:18:50 +00001997 Result->AddTypedTextChunk(ND->getNameAsString());
Douglas Gregor9eb77012009-11-07 00:00:49 +00001998 Result->AddTextChunk("::");
1999 return Result;
2000 }
2001
Douglas Gregorb3fa9192009-12-18 18:53:37 +00002002 AddResultTypeChunk(S.Context, ND, Result);
2003
Douglas Gregor3545ff42009-09-21 16:56:56 +00002004 if (FunctionDecl *Function = dyn_cast<FunctionDecl>(ND)) {
Douglas Gregor5bf52692009-09-22 23:15:58 +00002005 AddQualifierToCompletionString(Result, Qualifier, QualifierIsInformative,
2006 S.Context);
Benjamin Kramerb33a97c2009-11-29 20:18:50 +00002007 Result->AddTypedTextChunk(Function->getNameAsString());
Douglas Gregor9eb77012009-11-07 00:00:49 +00002008 Result->AddChunk(Chunk(CodeCompletionString::CK_LeftParen));
Douglas Gregor3545ff42009-09-21 16:56:56 +00002009 AddFunctionParameterChunks(S.Context, Function, Result);
Douglas Gregor9eb77012009-11-07 00:00:49 +00002010 Result->AddChunk(Chunk(CodeCompletionString::CK_RightParen));
Douglas Gregor0f622362009-12-11 18:44:16 +00002011 AddFunctionTypeQualsToCompletionString(Result, Function);
Douglas Gregor3545ff42009-09-21 16:56:56 +00002012 return Result;
2013 }
2014
2015 if (FunctionTemplateDecl *FunTmpl = dyn_cast<FunctionTemplateDecl>(ND)) {
Douglas Gregor5bf52692009-09-22 23:15:58 +00002016 AddQualifierToCompletionString(Result, Qualifier, QualifierIsInformative,
2017 S.Context);
Douglas Gregor3545ff42009-09-21 16:56:56 +00002018 FunctionDecl *Function = FunTmpl->getTemplatedDecl();
Benjamin Kramerb33a97c2009-11-29 20:18:50 +00002019 Result->AddTypedTextChunk(Function->getNameAsString());
Douglas Gregor3545ff42009-09-21 16:56:56 +00002020
2021 // Figure out which template parameters are deduced (or have default
2022 // arguments).
2023 llvm::SmallVector<bool, 16> Deduced;
2024 S.MarkDeducedTemplateParameters(FunTmpl, Deduced);
2025 unsigned LastDeducibleArgument;
2026 for (LastDeducibleArgument = Deduced.size(); LastDeducibleArgument > 0;
2027 --LastDeducibleArgument) {
2028 if (!Deduced[LastDeducibleArgument - 1]) {
2029 // C++0x: Figure out if the template argument has a default. If so,
2030 // the user doesn't need to type this argument.
2031 // FIXME: We need to abstract template parameters better!
2032 bool HasDefaultArg = false;
2033 NamedDecl *Param = FunTmpl->getTemplateParameters()->getParam(
2034 LastDeducibleArgument - 1);
2035 if (TemplateTypeParmDecl *TTP = dyn_cast<TemplateTypeParmDecl>(Param))
2036 HasDefaultArg = TTP->hasDefaultArgument();
2037 else if (NonTypeTemplateParmDecl *NTTP
2038 = dyn_cast<NonTypeTemplateParmDecl>(Param))
2039 HasDefaultArg = NTTP->hasDefaultArgument();
2040 else {
2041 assert(isa<TemplateTemplateParmDecl>(Param));
2042 HasDefaultArg
Douglas Gregor9eb77012009-11-07 00:00:49 +00002043 = cast<TemplateTemplateParmDecl>(Param)->hasDefaultArgument();
Douglas Gregor3545ff42009-09-21 16:56:56 +00002044 }
2045
2046 if (!HasDefaultArg)
2047 break;
2048 }
2049 }
2050
2051 if (LastDeducibleArgument) {
2052 // Some of the function template arguments cannot be deduced from a
2053 // function call, so we introduce an explicit template argument list
2054 // containing all of the arguments up to the first deducible argument.
Douglas Gregor9eb77012009-11-07 00:00:49 +00002055 Result->AddChunk(Chunk(CodeCompletionString::CK_LeftAngle));
Douglas Gregor3545ff42009-09-21 16:56:56 +00002056 AddTemplateParameterChunks(S.Context, FunTmpl, Result,
2057 LastDeducibleArgument);
Douglas Gregor9eb77012009-11-07 00:00:49 +00002058 Result->AddChunk(Chunk(CodeCompletionString::CK_RightAngle));
Douglas Gregor3545ff42009-09-21 16:56:56 +00002059 }
2060
2061 // Add the function parameters
Douglas Gregor9eb77012009-11-07 00:00:49 +00002062 Result->AddChunk(Chunk(CodeCompletionString::CK_LeftParen));
Douglas Gregor3545ff42009-09-21 16:56:56 +00002063 AddFunctionParameterChunks(S.Context, Function, Result);
Douglas Gregor9eb77012009-11-07 00:00:49 +00002064 Result->AddChunk(Chunk(CodeCompletionString::CK_RightParen));
Douglas Gregor0f622362009-12-11 18:44:16 +00002065 AddFunctionTypeQualsToCompletionString(Result, Function);
Douglas Gregor3545ff42009-09-21 16:56:56 +00002066 return Result;
2067 }
2068
2069 if (TemplateDecl *Template = dyn_cast<TemplateDecl>(ND)) {
Douglas Gregor5bf52692009-09-22 23:15:58 +00002070 AddQualifierToCompletionString(Result, Qualifier, QualifierIsInformative,
2071 S.Context);
Benjamin Kramerb33a97c2009-11-29 20:18:50 +00002072 Result->AddTypedTextChunk(Template->getNameAsString());
Douglas Gregor9eb77012009-11-07 00:00:49 +00002073 Result->AddChunk(Chunk(CodeCompletionString::CK_LeftAngle));
Douglas Gregor3545ff42009-09-21 16:56:56 +00002074 AddTemplateParameterChunks(S.Context, Template, Result);
Douglas Gregor9eb77012009-11-07 00:00:49 +00002075 Result->AddChunk(Chunk(CodeCompletionString::CK_RightAngle));
Douglas Gregor3545ff42009-09-21 16:56:56 +00002076 return Result;
2077 }
2078
Douglas Gregord3c5d792009-11-17 16:44:22 +00002079 if (ObjCMethodDecl *Method = dyn_cast<ObjCMethodDecl>(ND)) {
Douglas Gregord3c5d792009-11-17 16:44:22 +00002080 Selector Sel = Method->getSelector();
2081 if (Sel.isUnarySelector()) {
2082 Result->AddTypedTextChunk(Sel.getIdentifierInfoForSlot(0)->getName());
2083 return Result;
2084 }
2085
Douglas Gregor1b605f72009-11-19 01:08:35 +00002086 std::string SelName = Sel.getIdentifierInfoForSlot(0)->getName().str();
2087 SelName += ':';
2088 if (StartParameter == 0)
2089 Result->AddTypedTextChunk(SelName);
2090 else {
2091 Result->AddInformativeChunk(SelName);
2092
2093 // If there is only one parameter, and we're past it, add an empty
2094 // typed-text chunk since there is nothing to type.
2095 if (Method->param_size() == 1)
2096 Result->AddTypedTextChunk("");
2097 }
Douglas Gregord3c5d792009-11-17 16:44:22 +00002098 unsigned Idx = 0;
2099 for (ObjCMethodDecl::param_iterator P = Method->param_begin(),
2100 PEnd = Method->param_end();
2101 P != PEnd; (void)++P, ++Idx) {
2102 if (Idx > 0) {
Douglas Gregor1b605f72009-11-19 01:08:35 +00002103 std::string Keyword;
2104 if (Idx > StartParameter)
Douglas Gregor6a803932010-01-12 06:38:28 +00002105 Result->AddChunk(CodeCompletionString::CK_HorizontalSpace);
Douglas Gregord3c5d792009-11-17 16:44:22 +00002106 if (IdentifierInfo *II = Sel.getIdentifierInfoForSlot(Idx))
2107 Keyword += II->getName().str();
2108 Keyword += ":";
Douglas Gregor95887f92010-07-08 23:20:03 +00002109 if (Idx < StartParameter || AllParametersAreInformative)
Douglas Gregor1b605f72009-11-19 01:08:35 +00002110 Result->AddInformativeChunk(Keyword);
Douglas Gregor95887f92010-07-08 23:20:03 +00002111 else if (Idx == StartParameter)
Douglas Gregor1b605f72009-11-19 01:08:35 +00002112 Result->AddTypedTextChunk(Keyword);
2113 else
2114 Result->AddTextChunk(Keyword);
Douglas Gregord3c5d792009-11-17 16:44:22 +00002115 }
Douglas Gregor1b605f72009-11-19 01:08:35 +00002116
2117 // If we're before the starting parameter, skip the placeholder.
2118 if (Idx < StartParameter)
2119 continue;
Douglas Gregord3c5d792009-11-17 16:44:22 +00002120
2121 std::string Arg;
Douglas Gregore90dd002010-08-24 16:15:59 +00002122
2123 if ((*P)->getType()->isBlockPointerType() && !DeclaringEntity)
2124 Arg = FormatFunctionParameter(S.Context, *P);
2125 else {
2126 (*P)->getType().getAsStringInternal(Arg, S.Context.PrintingPolicy);
2127 Arg = "(" + Arg + ")";
2128 if (IdentifierInfo *II = (*P)->getIdentifier())
2129 Arg += II->getName().str();
2130 }
2131
Douglas Gregor95887f92010-07-08 23:20:03 +00002132 if (DeclaringEntity)
2133 Result->AddTextChunk(Arg);
2134 else if (AllParametersAreInformative)
Douglas Gregorc8537c52009-11-19 07:41:15 +00002135 Result->AddInformativeChunk(Arg);
2136 else
2137 Result->AddPlaceholderChunk(Arg);
Douglas Gregord3c5d792009-11-17 16:44:22 +00002138 }
2139
Douglas Gregor04c5f972009-12-23 00:21:46 +00002140 if (Method->isVariadic()) {
Douglas Gregor95887f92010-07-08 23:20:03 +00002141 if (DeclaringEntity)
2142 Result->AddTextChunk(", ...");
2143 else if (AllParametersAreInformative)
Douglas Gregor04c5f972009-12-23 00:21:46 +00002144 Result->AddInformativeChunk(", ...");
2145 else
2146 Result->AddPlaceholderChunk(", ...");
Douglas Gregordbb71db2010-08-23 23:51:41 +00002147
2148 MaybeAddSentinel(S.Context, Method, Result);
Douglas Gregor04c5f972009-12-23 00:21:46 +00002149 }
2150
Douglas Gregord3c5d792009-11-17 16:44:22 +00002151 return Result;
2152 }
2153
Douglas Gregorf09935f2009-12-01 05:55:20 +00002154 if (Qualifier)
Douglas Gregor5bf52692009-09-22 23:15:58 +00002155 AddQualifierToCompletionString(Result, Qualifier, QualifierIsInformative,
2156 S.Context);
Douglas Gregorf09935f2009-12-01 05:55:20 +00002157
2158 Result->AddTypedTextChunk(ND->getNameAsString());
2159 return Result;
Douglas Gregor3545ff42009-09-21 16:56:56 +00002160}
2161
Douglas Gregorf0f51982009-09-23 00:34:09 +00002162CodeCompletionString *
2163CodeCompleteConsumer::OverloadCandidate::CreateSignatureString(
2164 unsigned CurrentArg,
2165 Sema &S) const {
Douglas Gregor9eb77012009-11-07 00:00:49 +00002166 typedef CodeCompletionString::Chunk Chunk;
2167
Douglas Gregorf0f51982009-09-23 00:34:09 +00002168 CodeCompletionString *Result = new CodeCompletionString;
2169 FunctionDecl *FDecl = getFunction();
Douglas Gregorb3fa9192009-12-18 18:53:37 +00002170 AddResultTypeChunk(S.Context, FDecl, Result);
Douglas Gregorf0f51982009-09-23 00:34:09 +00002171 const FunctionProtoType *Proto
2172 = dyn_cast<FunctionProtoType>(getFunctionType());
2173 if (!FDecl && !Proto) {
2174 // Function without a prototype. Just give the return type and a
2175 // highlighted ellipsis.
2176 const FunctionType *FT = getFunctionType();
2177 Result->AddTextChunk(
Benjamin Kramerb33a97c2009-11-29 20:18:50 +00002178 FT->getResultType().getAsString(S.Context.PrintingPolicy));
Douglas Gregor9eb77012009-11-07 00:00:49 +00002179 Result->AddChunk(Chunk(CodeCompletionString::CK_LeftParen));
2180 Result->AddChunk(Chunk(CodeCompletionString::CK_CurrentParameter, "..."));
2181 Result->AddChunk(Chunk(CodeCompletionString::CK_RightParen));
Douglas Gregorf0f51982009-09-23 00:34:09 +00002182 return Result;
2183 }
2184
2185 if (FDecl)
Benjamin Kramerb33a97c2009-11-29 20:18:50 +00002186 Result->AddTextChunk(FDecl->getNameAsString());
Douglas Gregorf0f51982009-09-23 00:34:09 +00002187 else
2188 Result->AddTextChunk(
Benjamin Kramerb33a97c2009-11-29 20:18:50 +00002189 Proto->getResultType().getAsString(S.Context.PrintingPolicy));
Douglas Gregorf0f51982009-09-23 00:34:09 +00002190
Douglas Gregor9eb77012009-11-07 00:00:49 +00002191 Result->AddChunk(Chunk(CodeCompletionString::CK_LeftParen));
Douglas Gregorf0f51982009-09-23 00:34:09 +00002192 unsigned NumParams = FDecl? FDecl->getNumParams() : Proto->getNumArgs();
2193 for (unsigned I = 0; I != NumParams; ++I) {
2194 if (I)
Douglas Gregor9eb77012009-11-07 00:00:49 +00002195 Result->AddChunk(Chunk(CodeCompletionString::CK_Comma));
Douglas Gregorf0f51982009-09-23 00:34:09 +00002196
2197 std::string ArgString;
2198 QualType ArgType;
2199
2200 if (FDecl) {
2201 ArgString = FDecl->getParamDecl(I)->getNameAsString();
2202 ArgType = FDecl->getParamDecl(I)->getOriginalType();
2203 } else {
2204 ArgType = Proto->getArgType(I);
2205 }
2206
2207 ArgType.getAsStringInternal(ArgString, S.Context.PrintingPolicy);
2208
2209 if (I == CurrentArg)
Douglas Gregor9eb77012009-11-07 00:00:49 +00002210 Result->AddChunk(Chunk(CodeCompletionString::CK_CurrentParameter,
Benjamin Kramerb33a97c2009-11-29 20:18:50 +00002211 ArgString));
Douglas Gregorf0f51982009-09-23 00:34:09 +00002212 else
Benjamin Kramerb33a97c2009-11-29 20:18:50 +00002213 Result->AddTextChunk(ArgString);
Douglas Gregorf0f51982009-09-23 00:34:09 +00002214 }
2215
2216 if (Proto && Proto->isVariadic()) {
Douglas Gregor9eb77012009-11-07 00:00:49 +00002217 Result->AddChunk(Chunk(CodeCompletionString::CK_Comma));
Douglas Gregorf0f51982009-09-23 00:34:09 +00002218 if (CurrentArg < NumParams)
2219 Result->AddTextChunk("...");
2220 else
Douglas Gregor9eb77012009-11-07 00:00:49 +00002221 Result->AddChunk(Chunk(CodeCompletionString::CK_CurrentParameter, "..."));
Douglas Gregorf0f51982009-09-23 00:34:09 +00002222 }
Douglas Gregor9eb77012009-11-07 00:00:49 +00002223 Result->AddChunk(Chunk(CodeCompletionString::CK_RightParen));
Douglas Gregorf0f51982009-09-23 00:34:09 +00002224
2225 return Result;
2226}
2227
Douglas Gregor3545ff42009-09-21 16:56:56 +00002228namespace {
2229 struct SortCodeCompleteResult {
2230 typedef CodeCompleteConsumer::Result Result;
2231
Douglas Gregor52ce62f2010-01-13 23:24:38 +00002232 /// \brief Retrieve the name that should be used to order a result.
2233 ///
2234 /// If the name needs to be constructed as a string, that string will be
2235 /// saved into Saved and the returned StringRef will refer to it.
2236 static llvm::StringRef getOrderedName(const Result &R,
2237 std::string &Saved) {
2238 switch (R.Kind) {
2239 case Result::RK_Keyword:
2240 return R.Keyword;
2241
2242 case Result::RK_Pattern:
2243 return R.Pattern->getTypedText();
2244
2245 case Result::RK_Macro:
2246 return R.Macro->getName();
2247
2248 case Result::RK_Declaration:
2249 // Handle declarations below.
2250 break;
Douglas Gregor45f83ee2009-11-19 00:01:57 +00002251 }
Douglas Gregor52ce62f2010-01-13 23:24:38 +00002252
2253 DeclarationName Name = R.Declaration->getDeclName();
Douglas Gregor45f83ee2009-11-19 00:01:57 +00002254
Douglas Gregor52ce62f2010-01-13 23:24:38 +00002255 // If the name is a simple identifier (by far the common case), or a
2256 // zero-argument selector, just return a reference to that identifier.
2257 if (IdentifierInfo *Id = Name.getAsIdentifierInfo())
2258 return Id->getName();
2259 if (Name.isObjCZeroArgSelector())
2260 if (IdentifierInfo *Id
2261 = Name.getObjCSelector().getIdentifierInfoForSlot(0))
2262 return Id->getName();
2263
2264 Saved = Name.getAsString();
2265 return Saved;
2266 }
2267
2268 bool operator()(const Result &X, const Result &Y) const {
2269 std::string XSaved, YSaved;
2270 llvm::StringRef XStr = getOrderedName(X, XSaved);
2271 llvm::StringRef YStr = getOrderedName(Y, YSaved);
2272 int cmp = XStr.compare_lower(YStr);
2273 if (cmp)
2274 return cmp < 0;
Douglas Gregor3545ff42009-09-21 16:56:56 +00002275
2276 // Non-hidden names precede hidden names.
2277 if (X.Hidden != Y.Hidden)
2278 return !X.Hidden;
2279
Douglas Gregore412a5a2009-09-23 22:26:46 +00002280 // Non-nested-name-specifiers precede nested-name-specifiers.
2281 if (X.StartsNestedNameSpecifier != Y.StartsNestedNameSpecifier)
2282 return !X.StartsNestedNameSpecifier;
2283
Douglas Gregor3545ff42009-09-21 16:56:56 +00002284 return false;
2285 }
2286 };
2287}
2288
Douglas Gregor6e240332010-08-16 16:18:59 +00002289unsigned clang::getMacroUsagePriority(llvm::StringRef MacroName,
2290 bool PreferredTypeIsPointer) {
2291 unsigned Priority = CCP_Macro;
2292
2293 // Treat the "nil" and "NULL" macros as null pointer constants.
2294 if (MacroName.equals("nil") || MacroName.equals("NULL")) {
2295 Priority = CCP_Constant;
2296 if (PreferredTypeIsPointer)
2297 Priority = Priority / CCF_SimilarTypeMatch;
2298 }
2299
2300 return Priority;
2301}
2302
Douglas Gregor55b037b2010-07-08 20:55:51 +00002303static void AddMacroResults(Preprocessor &PP, ResultBuilder &Results,
2304 bool TargetTypeIsPointer = false) {
2305 typedef CodeCompleteConsumer::Result Result;
2306
Douglas Gregorf329c7c2009-10-30 16:50:04 +00002307 Results.EnterNewScope();
Douglas Gregor9eb77012009-11-07 00:00:49 +00002308 for (Preprocessor::macro_iterator M = PP.macro_begin(),
2309 MEnd = PP.macro_end();
Douglas Gregor55b037b2010-07-08 20:55:51 +00002310 M != MEnd; ++M) {
Douglas Gregor6e240332010-08-16 16:18:59 +00002311 Results.AddResult(Result(M->first,
2312 getMacroUsagePriority(M->first->getName(),
2313 TargetTypeIsPointer)));
Douglas Gregor55b037b2010-07-08 20:55:51 +00002314 }
Douglas Gregorf329c7c2009-10-30 16:50:04 +00002315 Results.ExitScope();
2316}
2317
Douglas Gregorce0e8562010-08-23 21:54:33 +00002318static void AddPrettyFunctionResults(const LangOptions &LangOpts,
2319 ResultBuilder &Results) {
2320 typedef CodeCompleteConsumer::Result Result;
2321
2322 Results.EnterNewScope();
2323 Results.AddResult(Result("__PRETTY_FUNCTION__", CCP_Constant));
2324 Results.AddResult(Result("__FUNCTION__", CCP_Constant));
2325 if (LangOpts.C99 || LangOpts.CPlusPlus0x)
2326 Results.AddResult(Result("__func__", CCP_Constant));
2327 Results.ExitScope();
2328}
2329
Daniel Dunbar242ea9a2009-11-13 08:58:20 +00002330static void HandleCodeCompleteResults(Sema *S,
2331 CodeCompleteConsumer *CodeCompleter,
Douglas Gregor00c37ef2010-08-11 21:23:17 +00002332 CodeCompletionContext Context,
2333 CodeCompleteConsumer::Result *Results,
2334 unsigned NumResults) {
Douglas Gregor3545ff42009-09-21 16:56:56 +00002335 std::stable_sort(Results, Results + NumResults, SortCodeCompleteResult());
2336
2337 if (CodeCompleter)
Douglas Gregor00c37ef2010-08-11 21:23:17 +00002338 CodeCompleter->ProcessCodeCompleteResults(*S, Context, Results, NumResults);
Douglas Gregor45f83ee2009-11-19 00:01:57 +00002339
2340 for (unsigned I = 0; I != NumResults; ++I)
2341 Results[I].Destroy();
Douglas Gregor3545ff42009-09-21 16:56:56 +00002342}
2343
Douglas Gregor00c37ef2010-08-11 21:23:17 +00002344static enum CodeCompletionContext::Kind mapCodeCompletionContext(Sema &S,
2345 Sema::ParserCompletionContext PCC) {
2346 switch (PCC) {
2347 case Action::PCC_Namespace:
2348 return CodeCompletionContext::CCC_TopLevel;
2349
2350 case Action::PCC_Class:
2351 return CodeCompletionContext::CCC_ClassStructUnion;
2352
2353 case Action::PCC_ObjCInterface:
2354 return CodeCompletionContext::CCC_ObjCInterface;
2355
2356 case Action::PCC_ObjCImplementation:
2357 return CodeCompletionContext::CCC_ObjCImplementation;
2358
2359 case Action::PCC_ObjCInstanceVariableList:
2360 return CodeCompletionContext::CCC_ObjCIvarList;
2361
2362 case Action::PCC_Template:
2363 case Action::PCC_MemberTemplate:
2364 case Action::PCC_RecoveryInFunction:
2365 return CodeCompletionContext::CCC_Other;
2366
2367 case Action::PCC_Expression:
2368 case Action::PCC_ForInit:
2369 case Action::PCC_Condition:
2370 return CodeCompletionContext::CCC_Expression;
2371
2372 case Action::PCC_Statement:
2373 return CodeCompletionContext::CCC_Statement;
Douglas Gregorf02e5f32010-08-24 01:11:00 +00002374
2375 case Action::PCC_Type:
2376 return CodeCompletionContext::CCC_Type;
Douglas Gregor00c37ef2010-08-11 21:23:17 +00002377 }
2378
2379 return CodeCompletionContext::CCC_Other;
2380}
2381
Douglas Gregor504a6ae2010-01-10 23:08:15 +00002382void Sema::CodeCompleteOrdinaryName(Scope *S,
Douglas Gregor00c37ef2010-08-11 21:23:17 +00002383 ParserCompletionContext CompletionContext) {
Douglas Gregor92253692009-12-07 09:54:55 +00002384 typedef CodeCompleteConsumer::Result Result;
Douglas Gregorc49f5b22010-08-23 18:23:48 +00002385 ResultBuilder Results(*this);
Douglas Gregor504a6ae2010-01-10 23:08:15 +00002386
2387 // Determine how to filter results, e.g., so that the names of
2388 // values (functions, enumerators, function templates, etc.) are
2389 // only allowed where we can have an expression.
2390 switch (CompletionContext) {
Douglas Gregor00c37ef2010-08-11 21:23:17 +00002391 case PCC_Namespace:
2392 case PCC_Class:
2393 case PCC_ObjCInterface:
2394 case PCC_ObjCImplementation:
2395 case PCC_ObjCInstanceVariableList:
2396 case PCC_Template:
2397 case PCC_MemberTemplate:
Douglas Gregorf02e5f32010-08-24 01:11:00 +00002398 case PCC_Type:
Douglas Gregor504a6ae2010-01-10 23:08:15 +00002399 Results.setFilter(&ResultBuilder::IsOrdinaryNonValueName);
2400 break;
2401
Douglas Gregor00c37ef2010-08-11 21:23:17 +00002402 case PCC_Expression:
2403 case PCC_Statement:
2404 case PCC_ForInit:
2405 case PCC_Condition:
Douglas Gregor70febae2010-05-28 00:49:12 +00002406 if (WantTypesInContext(CompletionContext, getLangOptions()))
2407 Results.setFilter(&ResultBuilder::IsOrdinaryName);
2408 else
2409 Results.setFilter(&ResultBuilder::IsOrdinaryNonTypeName);
Douglas Gregor504a6ae2010-01-10 23:08:15 +00002410 break;
Douglas Gregor6da3db42010-05-25 05:58:43 +00002411
Douglas Gregor00c37ef2010-08-11 21:23:17 +00002412 case PCC_RecoveryInFunction:
Douglas Gregor6da3db42010-05-25 05:58:43 +00002413 // Unfiltered
2414 break;
Douglas Gregor504a6ae2010-01-10 23:08:15 +00002415 }
2416
Douglas Gregorc580c522010-01-14 01:09:38 +00002417 CodeCompletionDeclConsumer Consumer(Results, CurContext);
Douglas Gregor39982192010-08-15 06:18:01 +00002418 LookupVisibleDecls(S, LookupOrdinaryName, Consumer,
2419 CodeCompleter->includeGlobals());
Douglas Gregor92253692009-12-07 09:54:55 +00002420
2421 Results.EnterNewScope();
Douglas Gregorf98e6a22010-01-13 23:51:12 +00002422 AddOrdinaryNameResults(CompletionContext, S, *this, Results);
Douglas Gregor92253692009-12-07 09:54:55 +00002423 Results.ExitScope();
2424
Douglas Gregorce0e8562010-08-23 21:54:33 +00002425 switch (CompletionContext) {
Douglas Gregorf02e5f32010-08-24 01:11:00 +00002426 case PCC_Expression:
2427 case PCC_Statement:
2428 case PCC_RecoveryInFunction:
2429 if (S->getFnParent())
2430 AddPrettyFunctionResults(PP.getLangOptions(), Results);
2431 break;
2432
2433 case PCC_Namespace:
2434 case PCC_Class:
2435 case PCC_ObjCInterface:
2436 case PCC_ObjCImplementation:
2437 case PCC_ObjCInstanceVariableList:
2438 case PCC_Template:
2439 case PCC_MemberTemplate:
2440 case PCC_ForInit:
2441 case PCC_Condition:
2442 case PCC_Type:
2443 break;
Douglas Gregorce0e8562010-08-23 21:54:33 +00002444 }
2445
Douglas Gregor9eb77012009-11-07 00:00:49 +00002446 if (CodeCompleter->includeMacros())
Douglas Gregorf98e6a22010-01-13 23:51:12 +00002447 AddMacroResults(PP, Results);
Douglas Gregorce0e8562010-08-23 21:54:33 +00002448
Douglas Gregor00c37ef2010-08-11 21:23:17 +00002449 HandleCodeCompleteResults(this, CodeCompleter,
2450 mapCodeCompletionContext(*this, CompletionContext),
2451 Results.data(),Results.size());
Douglas Gregor9d64c5e2009-09-21 20:51:25 +00002452}
2453
Douglas Gregorc49f5b22010-08-23 18:23:48 +00002454void Sema::CodeCompleteDeclarator(Scope *S,
2455 bool AllowNonIdentifiers,
2456 bool AllowNestedNameSpecifiers) {
2457 typedef CodeCompleteConsumer::Result Result;
2458 ResultBuilder Results(*this);
2459 Results.EnterNewScope();
2460
2461 // Type qualifiers can come after names.
2462 Results.AddResult(Result("const"));
2463 Results.AddResult(Result("volatile"));
2464 if (getLangOptions().C99)
2465 Results.AddResult(Result("restrict"));
2466
2467 if (getLangOptions().CPlusPlus) {
2468 if (AllowNonIdentifiers) {
2469 Results.AddResult(Result("operator"));
2470 }
2471
2472 // Add nested-name-specifiers.
2473 if (AllowNestedNameSpecifiers) {
2474 Results.allowNestedNameSpecifiers();
2475 CodeCompletionDeclConsumer Consumer(Results, CurContext);
2476 LookupVisibleDecls(S, LookupNestedNameSpecifierName, Consumer,
2477 CodeCompleter->includeGlobals());
2478 }
2479 }
2480 Results.ExitScope();
2481
Douglas Gregor56ccce02010-08-24 04:59:56 +00002482 // Note that we intentionally suppress macro results here, since we do not
2483 // encourage using macros to produce the names of entities.
2484
Douglas Gregorc49f5b22010-08-23 18:23:48 +00002485 HandleCodeCompleteResults(this, CodeCompleter,
2486 AllowNestedNameSpecifiers
2487 ? CodeCompletionContext::CCC_PotentiallyQualifiedName
2488 : CodeCompletionContext::CCC_Name,
2489 Results.data(), Results.size());
2490}
2491
Douglas Gregor68762e72010-08-23 21:17:50 +00002492struct Sema::CodeCompleteExpressionData {
2493 CodeCompleteExpressionData(QualType PreferredType = QualType())
2494 : PreferredType(PreferredType), IntegralConstantExpression(false),
2495 ObjCCollection(false) { }
2496
2497 QualType PreferredType;
2498 bool IntegralConstantExpression;
2499 bool ObjCCollection;
2500 llvm::SmallVector<Decl *, 4> IgnoreDecls;
2501};
2502
Douglas Gregor7aa6b222010-05-30 01:49:25 +00002503/// \brief Perform code-completion in an expression context when we know what
2504/// type we're looking for.
Douglas Gregor85b50632010-07-28 21:50:18 +00002505///
2506/// \param IntegralConstantExpression Only permit integral constant
2507/// expressions.
Douglas Gregor68762e72010-08-23 21:17:50 +00002508void Sema::CodeCompleteExpression(Scope *S,
2509 const CodeCompleteExpressionData &Data) {
Douglas Gregor7aa6b222010-05-30 01:49:25 +00002510 typedef CodeCompleteConsumer::Result Result;
2511 ResultBuilder Results(*this);
2512
Douglas Gregor68762e72010-08-23 21:17:50 +00002513 if (Data.ObjCCollection)
2514 Results.setFilter(&ResultBuilder::IsObjCCollection);
2515 else if (Data.IntegralConstantExpression)
Douglas Gregor85b50632010-07-28 21:50:18 +00002516 Results.setFilter(&ResultBuilder::IsIntegralConstantValue);
Douglas Gregor00c37ef2010-08-11 21:23:17 +00002517 else if (WantTypesInContext(PCC_Expression, getLangOptions()))
Douglas Gregor7aa6b222010-05-30 01:49:25 +00002518 Results.setFilter(&ResultBuilder::IsOrdinaryName);
2519 else
2520 Results.setFilter(&ResultBuilder::IsOrdinaryNonTypeName);
Douglas Gregor68762e72010-08-23 21:17:50 +00002521
2522 if (!Data.PreferredType.isNull())
2523 Results.setPreferredType(Data.PreferredType.getNonReferenceType());
2524
2525 // Ignore any declarations that we were told that we don't care about.
2526 for (unsigned I = 0, N = Data.IgnoreDecls.size(); I != N; ++I)
2527 Results.Ignore(Data.IgnoreDecls[I]);
Douglas Gregor7aa6b222010-05-30 01:49:25 +00002528
2529 CodeCompletionDeclConsumer Consumer(Results, CurContext);
Douglas Gregor39982192010-08-15 06:18:01 +00002530 LookupVisibleDecls(S, LookupOrdinaryName, Consumer,
2531 CodeCompleter->includeGlobals());
Douglas Gregor7aa6b222010-05-30 01:49:25 +00002532
2533 Results.EnterNewScope();
Douglas Gregor00c37ef2010-08-11 21:23:17 +00002534 AddOrdinaryNameResults(PCC_Expression, S, *this, Results);
Douglas Gregor7aa6b222010-05-30 01:49:25 +00002535 Results.ExitScope();
2536
Douglas Gregor55b037b2010-07-08 20:55:51 +00002537 bool PreferredTypeIsPointer = false;
Douglas Gregor68762e72010-08-23 21:17:50 +00002538 if (!Data.PreferredType.isNull())
2539 PreferredTypeIsPointer = Data.PreferredType->isAnyPointerType()
2540 || Data.PreferredType->isMemberPointerType()
2541 || Data.PreferredType->isBlockPointerType();
Douglas Gregor55b037b2010-07-08 20:55:51 +00002542
Douglas Gregorce0e8562010-08-23 21:54:33 +00002543 if (S->getFnParent() &&
2544 !Data.ObjCCollection &&
2545 !Data.IntegralConstantExpression)
2546 AddPrettyFunctionResults(PP.getLangOptions(), Results);
2547
Douglas Gregor7aa6b222010-05-30 01:49:25 +00002548 if (CodeCompleter->includeMacros())
Douglas Gregor55b037b2010-07-08 20:55:51 +00002549 AddMacroResults(PP, Results, PreferredTypeIsPointer);
Douglas Gregor00c37ef2010-08-11 21:23:17 +00002550 HandleCodeCompleteResults(this, CodeCompleter,
Douglas Gregor68762e72010-08-23 21:17:50 +00002551 CodeCompletionContext(CodeCompletionContext::CCC_Expression,
2552 Data.PreferredType),
Douglas Gregor00c37ef2010-08-11 21:23:17 +00002553 Results.data(),Results.size());
Douglas Gregor7aa6b222010-05-30 01:49:25 +00002554}
2555
2556
Douglas Gregor9291bad2009-11-18 01:29:26 +00002557static void AddObjCProperties(ObjCContainerDecl *Container,
Douglas Gregor5d649882009-11-18 22:32:06 +00002558 bool AllowCategories,
Douglas Gregor9291bad2009-11-18 01:29:26 +00002559 DeclContext *CurContext,
2560 ResultBuilder &Results) {
2561 typedef CodeCompleteConsumer::Result Result;
2562
2563 // Add properties in this container.
2564 for (ObjCContainerDecl::prop_iterator P = Container->prop_begin(),
2565 PEnd = Container->prop_end();
2566 P != PEnd;
2567 ++P)
2568 Results.MaybeAddResult(Result(*P, 0), CurContext);
2569
2570 // Add properties in referenced protocols.
2571 if (ObjCProtocolDecl *Protocol = dyn_cast<ObjCProtocolDecl>(Container)) {
2572 for (ObjCProtocolDecl::protocol_iterator P = Protocol->protocol_begin(),
2573 PEnd = Protocol->protocol_end();
2574 P != PEnd; ++P)
Douglas Gregor5d649882009-11-18 22:32:06 +00002575 AddObjCProperties(*P, AllowCategories, CurContext, Results);
Douglas Gregor9291bad2009-11-18 01:29:26 +00002576 } else if (ObjCInterfaceDecl *IFace = dyn_cast<ObjCInterfaceDecl>(Container)){
Douglas Gregor5d649882009-11-18 22:32:06 +00002577 if (AllowCategories) {
2578 // Look through categories.
2579 for (ObjCCategoryDecl *Category = IFace->getCategoryList();
2580 Category; Category = Category->getNextClassCategory())
2581 AddObjCProperties(Category, AllowCategories, CurContext, Results);
2582 }
Douglas Gregor9291bad2009-11-18 01:29:26 +00002583
2584 // Look through protocols.
2585 for (ObjCInterfaceDecl::protocol_iterator I = IFace->protocol_begin(),
2586 E = IFace->protocol_end();
2587 I != E; ++I)
Douglas Gregor5d649882009-11-18 22:32:06 +00002588 AddObjCProperties(*I, AllowCategories, CurContext, Results);
Douglas Gregor9291bad2009-11-18 01:29:26 +00002589
2590 // Look in the superclass.
2591 if (IFace->getSuperClass())
Douglas Gregor5d649882009-11-18 22:32:06 +00002592 AddObjCProperties(IFace->getSuperClass(), AllowCategories, CurContext,
2593 Results);
Douglas Gregor9291bad2009-11-18 01:29:26 +00002594 } else if (const ObjCCategoryDecl *Category
2595 = dyn_cast<ObjCCategoryDecl>(Container)) {
2596 // Look through protocols.
2597 for (ObjCInterfaceDecl::protocol_iterator P = Category->protocol_begin(),
2598 PEnd = Category->protocol_end();
2599 P != PEnd; ++P)
Douglas Gregor5d649882009-11-18 22:32:06 +00002600 AddObjCProperties(*P, AllowCategories, CurContext, Results);
Douglas Gregor9291bad2009-11-18 01:29:26 +00002601 }
2602}
2603
Douglas Gregor2436e712009-09-17 21:32:03 +00002604void Sema::CodeCompleteMemberReferenceExpr(Scope *S, ExprTy *BaseE,
2605 SourceLocation OpLoc,
2606 bool IsArrow) {
2607 if (!BaseE || !CodeCompleter)
2608 return;
2609
Douglas Gregor3545ff42009-09-21 16:56:56 +00002610 typedef CodeCompleteConsumer::Result Result;
2611
Douglas Gregor2436e712009-09-17 21:32:03 +00002612 Expr *Base = static_cast<Expr *>(BaseE);
2613 QualType BaseType = Base->getType();
Douglas Gregor3545ff42009-09-21 16:56:56 +00002614
2615 if (IsArrow) {
2616 if (const PointerType *Ptr = BaseType->getAs<PointerType>())
2617 BaseType = Ptr->getPointeeType();
2618 else if (BaseType->isObjCObjectPointerType())
2619 /*Do nothing*/ ;
2620 else
2621 return;
2622 }
2623
Douglas Gregore412a5a2009-09-23 22:26:46 +00002624 ResultBuilder Results(*this, &ResultBuilder::IsMember);
Douglas Gregor9291bad2009-11-18 01:29:26 +00002625 Results.EnterNewScope();
2626 if (const RecordType *Record = BaseType->getAs<RecordType>()) {
2627 // Access to a C/C++ class, struct, or union.
Douglas Gregor6ae4c522010-01-14 03:21:49 +00002628 Results.allowNestedNameSpecifiers();
Douglas Gregor09bbc652010-01-14 15:47:35 +00002629 CodeCompletionDeclConsumer Consumer(Results, CurContext);
Douglas Gregor39982192010-08-15 06:18:01 +00002630 LookupVisibleDecls(Record->getDecl(), LookupMemberName, Consumer,
2631 CodeCompleter->includeGlobals());
Daniel Dunbar242ea9a2009-11-13 08:58:20 +00002632
Douglas Gregor9291bad2009-11-18 01:29:26 +00002633 if (getLangOptions().CPlusPlus) {
2634 if (!Results.empty()) {
2635 // The "template" keyword can follow "->" or "." in the grammar.
2636 // However, we only want to suggest the template keyword if something
2637 // is dependent.
2638 bool IsDependent = BaseType->isDependentType();
2639 if (!IsDependent) {
2640 for (Scope *DepScope = S; DepScope; DepScope = DepScope->getParent())
2641 if (DeclContext *Ctx = (DeclContext *)DepScope->getEntity()) {
2642 IsDependent = Ctx->isDependentContext();
2643 break;
2644 }
2645 }
Daniel Dunbar242ea9a2009-11-13 08:58:20 +00002646
Douglas Gregor9291bad2009-11-18 01:29:26 +00002647 if (IsDependent)
Douglas Gregor78a21012010-01-14 16:01:26 +00002648 Results.AddResult(Result("template"));
Daniel Dunbar242ea9a2009-11-13 08:58:20 +00002649 }
Daniel Dunbar242ea9a2009-11-13 08:58:20 +00002650 }
Douglas Gregor9291bad2009-11-18 01:29:26 +00002651 } else if (!IsArrow && BaseType->getAsObjCInterfacePointerType()) {
2652 // Objective-C property reference.
2653
2654 // Add property results based on our interface.
2655 const ObjCObjectPointerType *ObjCPtr
2656 = BaseType->getAsObjCInterfacePointerType();
2657 assert(ObjCPtr && "Non-NULL pointer guaranteed above!");
Douglas Gregor5d649882009-11-18 22:32:06 +00002658 AddObjCProperties(ObjCPtr->getInterfaceDecl(), true, CurContext, Results);
Douglas Gregor9291bad2009-11-18 01:29:26 +00002659
2660 // Add properties from the protocols in a qualified interface.
2661 for (ObjCObjectPointerType::qual_iterator I = ObjCPtr->qual_begin(),
2662 E = ObjCPtr->qual_end();
2663 I != E; ++I)
Douglas Gregor5d649882009-11-18 22:32:06 +00002664 AddObjCProperties(*I, true, CurContext, Results);
Douglas Gregor9291bad2009-11-18 01:29:26 +00002665 } else if ((IsArrow && BaseType->isObjCObjectPointerType()) ||
John McCall8b07ec22010-05-15 11:32:37 +00002666 (!IsArrow && BaseType->isObjCObjectType())) {
Douglas Gregor9291bad2009-11-18 01:29:26 +00002667 // Objective-C instance variable access.
2668 ObjCInterfaceDecl *Class = 0;
2669 if (const ObjCObjectPointerType *ObjCPtr
2670 = BaseType->getAs<ObjCObjectPointerType>())
2671 Class = ObjCPtr->getInterfaceDecl();
2672 else
John McCall8b07ec22010-05-15 11:32:37 +00002673 Class = BaseType->getAs<ObjCObjectType>()->getInterface();
Douglas Gregor9291bad2009-11-18 01:29:26 +00002674
2675 // Add all ivars from this class and its superclasses.
Douglas Gregor2b8162b2010-01-14 16:08:12 +00002676 if (Class) {
2677 CodeCompletionDeclConsumer Consumer(Results, CurContext);
2678 Results.setFilter(&ResultBuilder::IsObjCIvar);
Douglas Gregor39982192010-08-15 06:18:01 +00002679 LookupVisibleDecls(Class, LookupMemberName, Consumer,
2680 CodeCompleter->includeGlobals());
Douglas Gregor9291bad2009-11-18 01:29:26 +00002681 }
Douglas Gregor3545ff42009-09-21 16:56:56 +00002682 }
Douglas Gregor9291bad2009-11-18 01:29:26 +00002683
2684 // FIXME: How do we cope with isa?
2685
2686 Results.ExitScope();
Daniel Dunbar242ea9a2009-11-13 08:58:20 +00002687
Daniel Dunbar242ea9a2009-11-13 08:58:20 +00002688 // Hand off the results found for code completion.
Douglas Gregor00c37ef2010-08-11 21:23:17 +00002689 HandleCodeCompleteResults(this, CodeCompleter,
2690 CodeCompletionContext(CodeCompletionContext::CCC_MemberAccess,
2691 BaseType),
2692 Results.data(),Results.size());
Douglas Gregor2436e712009-09-17 21:32:03 +00002693}
2694
Douglas Gregorf45b0cf2009-09-18 15:37:17 +00002695void Sema::CodeCompleteTag(Scope *S, unsigned TagSpec) {
2696 if (!CodeCompleter)
2697 return;
2698
Douglas Gregor3545ff42009-09-21 16:56:56 +00002699 typedef CodeCompleteConsumer::Result Result;
2700 ResultBuilder::LookupFilter Filter = 0;
Douglas Gregor00c37ef2010-08-11 21:23:17 +00002701 enum CodeCompletionContext::Kind ContextKind
2702 = CodeCompletionContext::CCC_Other;
Douglas Gregorf45b0cf2009-09-18 15:37:17 +00002703 switch ((DeclSpec::TST)TagSpec) {
2704 case DeclSpec::TST_enum:
Douglas Gregor3545ff42009-09-21 16:56:56 +00002705 Filter = &ResultBuilder::IsEnum;
Douglas Gregor00c37ef2010-08-11 21:23:17 +00002706 ContextKind = CodeCompletionContext::CCC_EnumTag;
Douglas Gregorf45b0cf2009-09-18 15:37:17 +00002707 break;
2708
2709 case DeclSpec::TST_union:
Douglas Gregor3545ff42009-09-21 16:56:56 +00002710 Filter = &ResultBuilder::IsUnion;
Douglas Gregor00c37ef2010-08-11 21:23:17 +00002711 ContextKind = CodeCompletionContext::CCC_UnionTag;
Douglas Gregorf45b0cf2009-09-18 15:37:17 +00002712 break;
2713
2714 case DeclSpec::TST_struct:
Douglas Gregorf45b0cf2009-09-18 15:37:17 +00002715 case DeclSpec::TST_class:
Douglas Gregor3545ff42009-09-21 16:56:56 +00002716 Filter = &ResultBuilder::IsClassOrStruct;
Douglas Gregor00c37ef2010-08-11 21:23:17 +00002717 ContextKind = CodeCompletionContext::CCC_ClassOrStructTag;
Douglas Gregorf45b0cf2009-09-18 15:37:17 +00002718 break;
2719
2720 default:
2721 assert(false && "Unknown type specifier kind in CodeCompleteTag");
2722 return;
2723 }
Douglas Gregor3545ff42009-09-21 16:56:56 +00002724
John McCalle87beb22010-04-23 18:46:30 +00002725 ResultBuilder Results(*this);
Douglas Gregora6e2edc2010-01-14 03:27:13 +00002726 CodeCompletionDeclConsumer Consumer(Results, CurContext);
John McCalle87beb22010-04-23 18:46:30 +00002727
2728 // First pass: look for tags.
2729 Results.setFilter(Filter);
Douglas Gregor39982192010-08-15 06:18:01 +00002730 LookupVisibleDecls(S, LookupTagName, Consumer,
2731 CodeCompleter->includeGlobals());
John McCalle87beb22010-04-23 18:46:30 +00002732
Douglas Gregor39982192010-08-15 06:18:01 +00002733 if (CodeCompleter->includeGlobals()) {
2734 // Second pass: look for nested name specifiers.
2735 Results.setFilter(&ResultBuilder::IsNestedNameSpecifier);
2736 LookupVisibleDecls(S, LookupNestedNameSpecifierName, Consumer);
2737 }
Douglas Gregor3545ff42009-09-21 16:56:56 +00002738
Douglas Gregor00c37ef2010-08-11 21:23:17 +00002739 HandleCodeCompleteResults(this, CodeCompleter, ContextKind,
2740 Results.data(),Results.size());
Douglas Gregorf45b0cf2009-09-18 15:37:17 +00002741}
2742
Douglas Gregord328d572009-09-21 18:10:23 +00002743void Sema::CodeCompleteCase(Scope *S) {
2744 if (getSwitchStack().empty() || !CodeCompleter)
2745 return;
2746
2747 SwitchStmt *Switch = getSwitchStack().back();
Douglas Gregor85b50632010-07-28 21:50:18 +00002748 if (!Switch->getCond()->getType()->isEnumeralType()) {
Douglas Gregor68762e72010-08-23 21:17:50 +00002749 CodeCompleteExpressionData Data(Switch->getCond()->getType());
2750 Data.IntegralConstantExpression = true;
2751 CodeCompleteExpression(S, Data);
Douglas Gregord328d572009-09-21 18:10:23 +00002752 return;
Douglas Gregor85b50632010-07-28 21:50:18 +00002753 }
Douglas Gregord328d572009-09-21 18:10:23 +00002754
2755 // Code-complete the cases of a switch statement over an enumeration type
2756 // by providing the list of
2757 EnumDecl *Enum = Switch->getCond()->getType()->getAs<EnumType>()->getDecl();
2758
2759 // Determine which enumerators we have already seen in the switch statement.
2760 // FIXME: Ideally, we would also be able to look *past* the code-completion
2761 // token, in case we are code-completing in the middle of the switch and not
2762 // at the end. However, we aren't able to do so at the moment.
2763 llvm::SmallPtrSet<EnumConstantDecl *, 8> EnumeratorsSeen;
Douglas Gregorf2510672009-09-21 19:57:38 +00002764 NestedNameSpecifier *Qualifier = 0;
Douglas Gregord328d572009-09-21 18:10:23 +00002765 for (SwitchCase *SC = Switch->getSwitchCaseList(); SC;
2766 SC = SC->getNextSwitchCase()) {
2767 CaseStmt *Case = dyn_cast<CaseStmt>(SC);
2768 if (!Case)
2769 continue;
2770
2771 Expr *CaseVal = Case->getLHS()->IgnoreParenCasts();
2772 if (DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(CaseVal))
2773 if (EnumConstantDecl *Enumerator
2774 = dyn_cast<EnumConstantDecl>(DRE->getDecl())) {
2775 // We look into the AST of the case statement to determine which
2776 // enumerator was named. Alternatively, we could compute the value of
2777 // the integral constant expression, then compare it against the
2778 // values of each enumerator. However, value-based approach would not
2779 // work as well with C++ templates where enumerators declared within a
2780 // template are type- and value-dependent.
2781 EnumeratorsSeen.insert(Enumerator);
2782
Douglas Gregorf2510672009-09-21 19:57:38 +00002783 // If this is a qualified-id, keep track of the nested-name-specifier
2784 // so that we can reproduce it as part of code completion, e.g.,
Douglas Gregord328d572009-09-21 18:10:23 +00002785 //
2786 // switch (TagD.getKind()) {
2787 // case TagDecl::TK_enum:
2788 // break;
2789 // case XXX
2790 //
Douglas Gregorf2510672009-09-21 19:57:38 +00002791 // At the XXX, our completions are TagDecl::TK_union,
Douglas Gregord328d572009-09-21 18:10:23 +00002792 // TagDecl::TK_struct, and TagDecl::TK_class, rather than TK_union,
2793 // TK_struct, and TK_class.
Douglas Gregor4bd90e52009-10-23 18:54:35 +00002794 Qualifier = DRE->getQualifier();
Douglas Gregord328d572009-09-21 18:10:23 +00002795 }
2796 }
2797
Douglas Gregorf2510672009-09-21 19:57:38 +00002798 if (getLangOptions().CPlusPlus && !Qualifier && EnumeratorsSeen.empty()) {
2799 // If there are no prior enumerators in C++, check whether we have to
2800 // qualify the names of the enumerators that we suggest, because they
2801 // may not be visible in this scope.
2802 Qualifier = getRequiredQualification(Context, CurContext,
2803 Enum->getDeclContext());
2804
2805 // FIXME: Scoped enums need to start with "EnumDecl" as the context!
2806 }
2807
Douglas Gregord328d572009-09-21 18:10:23 +00002808 // Add any enumerators that have not yet been mentioned.
2809 ResultBuilder Results(*this);
2810 Results.EnterNewScope();
2811 for (EnumDecl::enumerator_iterator E = Enum->enumerator_begin(),
2812 EEnd = Enum->enumerator_end();
2813 E != EEnd; ++E) {
2814 if (EnumeratorsSeen.count(*E))
2815 continue;
2816
Douglas Gregorfc59ce12010-01-14 16:14:35 +00002817 Results.AddResult(CodeCompleteConsumer::Result(*E, Qualifier),
2818 CurContext, 0, false);
Douglas Gregord328d572009-09-21 18:10:23 +00002819 }
2820 Results.ExitScope();
Douglas Gregor285560922010-04-06 20:02:15 +00002821
Douglas Gregor9eb77012009-11-07 00:00:49 +00002822 if (CodeCompleter->includeMacros())
Douglas Gregorf98e6a22010-01-13 23:51:12 +00002823 AddMacroResults(PP, Results);
Douglas Gregor00c37ef2010-08-11 21:23:17 +00002824 HandleCodeCompleteResults(this, CodeCompleter,
2825 CodeCompletionContext::CCC_Expression,
2826 Results.data(),Results.size());
Douglas Gregord328d572009-09-21 18:10:23 +00002827}
2828
Douglas Gregorcabea402009-09-22 15:41:20 +00002829namespace {
2830 struct IsBetterOverloadCandidate {
2831 Sema &S;
John McCallbc077cf2010-02-08 23:07:23 +00002832 SourceLocation Loc;
Douglas Gregorcabea402009-09-22 15:41:20 +00002833
2834 public:
John McCallbc077cf2010-02-08 23:07:23 +00002835 explicit IsBetterOverloadCandidate(Sema &S, SourceLocation Loc)
2836 : S(S), Loc(Loc) { }
Douglas Gregorcabea402009-09-22 15:41:20 +00002837
2838 bool
2839 operator()(const OverloadCandidate &X, const OverloadCandidate &Y) const {
John McCallbc077cf2010-02-08 23:07:23 +00002840 return S.isBetterOverloadCandidate(X, Y, Loc);
Douglas Gregorcabea402009-09-22 15:41:20 +00002841 }
2842 };
2843}
2844
Douglas Gregor6ed3eb82010-05-30 06:10:08 +00002845static bool anyNullArguments(Expr **Args, unsigned NumArgs) {
2846 if (NumArgs && !Args)
2847 return true;
2848
2849 for (unsigned I = 0; I != NumArgs; ++I)
2850 if (!Args[I])
2851 return true;
2852
2853 return false;
2854}
2855
Douglas Gregorcabea402009-09-22 15:41:20 +00002856void Sema::CodeCompleteCall(Scope *S, ExprTy *FnIn,
2857 ExprTy **ArgsIn, unsigned NumArgs) {
2858 if (!CodeCompleter)
2859 return;
Douglas Gregor3ef59522009-12-11 19:06:04 +00002860
2861 // When we're code-completing for a call, we fall back to ordinary
2862 // name code-completion whenever we can't produce specific
2863 // results. We may want to revisit this strategy in the future,
2864 // e.g., by merging the two kinds of results.
2865
Douglas Gregorcabea402009-09-22 15:41:20 +00002866 Expr *Fn = (Expr *)FnIn;
2867 Expr **Args = (Expr **)ArgsIn;
Douglas Gregor3ef59522009-12-11 19:06:04 +00002868
Douglas Gregorcabea402009-09-22 15:41:20 +00002869 // Ignore type-dependent call expressions entirely.
Douglas Gregor6ed3eb82010-05-30 06:10:08 +00002870 if (!Fn || Fn->isTypeDependent() || anyNullArguments(Args, NumArgs) ||
Douglas Gregor3ef59522009-12-11 19:06:04 +00002871 Expr::hasAnyTypeDependentArguments(Args, NumArgs)) {
Douglas Gregor00c37ef2010-08-11 21:23:17 +00002872 CodeCompleteOrdinaryName(S, PCC_Expression);
Douglas Gregorcabea402009-09-22 15:41:20 +00002873 return;
Douglas Gregor3ef59522009-12-11 19:06:04 +00002874 }
Douglas Gregorcabea402009-09-22 15:41:20 +00002875
John McCall57500772009-12-16 12:17:52 +00002876 // Build an overload candidate set based on the functions we find.
John McCallbc077cf2010-02-08 23:07:23 +00002877 SourceLocation Loc = Fn->getExprLoc();
2878 OverloadCandidateSet CandidateSet(Loc);
John McCall57500772009-12-16 12:17:52 +00002879
Douglas Gregorcabea402009-09-22 15:41:20 +00002880 // FIXME: What if we're calling something that isn't a function declaration?
2881 // FIXME: What if we're calling a pseudo-destructor?
2882 // FIXME: What if we're calling a member function?
2883
Douglas Gregorff59f672010-01-21 15:46:19 +00002884 typedef CodeCompleteConsumer::OverloadCandidate ResultCandidate;
2885 llvm::SmallVector<ResultCandidate, 8> Results;
2886
John McCall57500772009-12-16 12:17:52 +00002887 Expr *NakedFn = Fn->IgnoreParenCasts();
2888 if (UnresolvedLookupExpr *ULE = dyn_cast<UnresolvedLookupExpr>(NakedFn))
2889 AddOverloadedCallCandidates(ULE, Args, NumArgs, CandidateSet,
2890 /*PartialOverloading=*/ true);
2891 else if (DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(NakedFn)) {
2892 FunctionDecl *FDecl = dyn_cast<FunctionDecl>(DRE->getDecl());
Douglas Gregorff59f672010-01-21 15:46:19 +00002893 if (FDecl) {
Douglas Gregor6ed3eb82010-05-30 06:10:08 +00002894 if (!getLangOptions().CPlusPlus ||
2895 !FDecl->getType()->getAs<FunctionProtoType>())
Douglas Gregorff59f672010-01-21 15:46:19 +00002896 Results.push_back(ResultCandidate(FDecl));
2897 else
John McCallb89836b2010-01-26 01:37:31 +00002898 // FIXME: access?
John McCalla0296f72010-03-19 07:35:19 +00002899 AddOverloadCandidate(FDecl, DeclAccessPair::make(FDecl, AS_none),
2900 Args, NumArgs, CandidateSet,
Douglas Gregorb05275a2010-04-16 17:41:49 +00002901 false, /*PartialOverloading*/true);
Douglas Gregorff59f672010-01-21 15:46:19 +00002902 }
John McCall57500772009-12-16 12:17:52 +00002903 }
Douglas Gregorcabea402009-09-22 15:41:20 +00002904
Douglas Gregor7aa6b222010-05-30 01:49:25 +00002905 QualType ParamType;
2906
Douglas Gregorff59f672010-01-21 15:46:19 +00002907 if (!CandidateSet.empty()) {
2908 // Sort the overload candidate set by placing the best overloads first.
2909 std::stable_sort(CandidateSet.begin(), CandidateSet.end(),
John McCallbc077cf2010-02-08 23:07:23 +00002910 IsBetterOverloadCandidate(*this, Loc));
Douglas Gregorcabea402009-09-22 15:41:20 +00002911
Douglas Gregorff59f672010-01-21 15:46:19 +00002912 // Add the remaining viable overload candidates as code-completion reslults.
2913 for (OverloadCandidateSet::iterator Cand = CandidateSet.begin(),
2914 CandEnd = CandidateSet.end();
2915 Cand != CandEnd; ++Cand) {
2916 if (Cand->Viable)
2917 Results.push_back(ResultCandidate(Cand->Function));
2918 }
Douglas Gregor7aa6b222010-05-30 01:49:25 +00002919
2920 // From the viable candidates, try to determine the type of this parameter.
2921 for (unsigned I = 0, N = Results.size(); I != N; ++I) {
2922 if (const FunctionType *FType = Results[I].getFunctionType())
2923 if (const FunctionProtoType *Proto = dyn_cast<FunctionProtoType>(FType))
2924 if (NumArgs < Proto->getNumArgs()) {
2925 if (ParamType.isNull())
2926 ParamType = Proto->getArgType(NumArgs);
2927 else if (!Context.hasSameUnqualifiedType(
2928 ParamType.getNonReferenceType(),
2929 Proto->getArgType(NumArgs).getNonReferenceType())) {
2930 ParamType = QualType();
2931 break;
2932 }
2933 }
2934 }
2935 } else {
2936 // Try to determine the parameter type from the type of the expression
2937 // being called.
2938 QualType FunctionType = Fn->getType();
2939 if (const PointerType *Ptr = FunctionType->getAs<PointerType>())
2940 FunctionType = Ptr->getPointeeType();
2941 else if (const BlockPointerType *BlockPtr
2942 = FunctionType->getAs<BlockPointerType>())
2943 FunctionType = BlockPtr->getPointeeType();
2944 else if (const MemberPointerType *MemPtr
2945 = FunctionType->getAs<MemberPointerType>())
2946 FunctionType = MemPtr->getPointeeType();
2947
2948 if (const FunctionProtoType *Proto
2949 = FunctionType->getAs<FunctionProtoType>()) {
2950 if (NumArgs < Proto->getNumArgs())
2951 ParamType = Proto->getArgType(NumArgs);
2952 }
Douglas Gregorcabea402009-09-22 15:41:20 +00002953 }
Douglas Gregor3ef59522009-12-11 19:06:04 +00002954
Douglas Gregor7aa6b222010-05-30 01:49:25 +00002955 if (ParamType.isNull())
Douglas Gregor00c37ef2010-08-11 21:23:17 +00002956 CodeCompleteOrdinaryName(S, PCC_Expression);
Douglas Gregor7aa6b222010-05-30 01:49:25 +00002957 else
2958 CodeCompleteExpression(S, ParamType);
2959
Douglas Gregorc01890e2010-04-06 20:19:47 +00002960 if (!Results.empty())
Douglas Gregor3ef59522009-12-11 19:06:04 +00002961 CodeCompleter->ProcessOverloadCandidates(*this, NumArgs, Results.data(),
2962 Results.size());
Douglas Gregorcabea402009-09-22 15:41:20 +00002963}
2964
John McCall48871652010-08-21 09:40:31 +00002965void Sema::CodeCompleteInitializer(Scope *S, Decl *D) {
2966 ValueDecl *VD = dyn_cast_or_null<ValueDecl>(D);
Douglas Gregor7aa6b222010-05-30 01:49:25 +00002967 if (!VD) {
Douglas Gregor00c37ef2010-08-11 21:23:17 +00002968 CodeCompleteOrdinaryName(S, PCC_Expression);
Douglas Gregor7aa6b222010-05-30 01:49:25 +00002969 return;
2970 }
2971
2972 CodeCompleteExpression(S, VD->getType());
2973}
2974
2975void Sema::CodeCompleteReturn(Scope *S) {
2976 QualType ResultType;
2977 if (isa<BlockDecl>(CurContext)) {
2978 if (BlockScopeInfo *BSI = getCurBlock())
2979 ResultType = BSI->ReturnType;
2980 } else if (FunctionDecl *Function = dyn_cast<FunctionDecl>(CurContext))
2981 ResultType = Function->getResultType();
2982 else if (ObjCMethodDecl *Method = dyn_cast<ObjCMethodDecl>(CurContext))
2983 ResultType = Method->getResultType();
2984
2985 if (ResultType.isNull())
Douglas Gregor00c37ef2010-08-11 21:23:17 +00002986 CodeCompleteOrdinaryName(S, PCC_Expression);
Douglas Gregor7aa6b222010-05-30 01:49:25 +00002987 else
2988 CodeCompleteExpression(S, ResultType);
2989}
2990
2991void Sema::CodeCompleteAssignmentRHS(Scope *S, ExprTy *LHS) {
2992 if (LHS)
2993 CodeCompleteExpression(S, static_cast<Expr *>(LHS)->getType());
2994 else
Douglas Gregor00c37ef2010-08-11 21:23:17 +00002995 CodeCompleteOrdinaryName(S, PCC_Expression);
Douglas Gregor7aa6b222010-05-30 01:49:25 +00002996}
2997
Jeffrey Yasskinc76498d2010-04-08 16:38:48 +00002998void Sema::CodeCompleteQualifiedId(Scope *S, CXXScopeSpec &SS,
Douglas Gregor2436e712009-09-17 21:32:03 +00002999 bool EnteringContext) {
3000 if (!SS.getScopeRep() || !CodeCompleter)
3001 return;
3002
Douglas Gregor3545ff42009-09-21 16:56:56 +00003003 DeclContext *Ctx = computeDeclContext(SS, EnteringContext);
3004 if (!Ctx)
3005 return;
Douglas Gregor800f2f02009-12-11 18:28:39 +00003006
3007 // Try to instantiate any non-dependent declaration contexts before
3008 // we look in them.
John McCall0b66eb32010-05-01 00:40:08 +00003009 if (!isDependentScopeSpecifier(SS) && RequireCompleteDeclContext(SS, Ctx))
Douglas Gregor800f2f02009-12-11 18:28:39 +00003010 return;
3011
Douglas Gregor3545ff42009-09-21 16:56:56 +00003012 ResultBuilder Results(*this);
Douglas Gregor200c99d2010-01-14 03:35:48 +00003013 CodeCompletionDeclConsumer Consumer(Results, CurContext);
3014 LookupVisibleDecls(Ctx, LookupOrdinaryName, Consumer);
Douglas Gregor3545ff42009-09-21 16:56:56 +00003015
3016 // The "template" keyword can follow "::" in the grammar, but only
3017 // put it into the grammar if the nested-name-specifier is dependent.
3018 NestedNameSpecifier *NNS = (NestedNameSpecifier *)SS.getScopeRep();
3019 if (!Results.empty() && NNS->isDependent())
Douglas Gregor78a21012010-01-14 16:01:26 +00003020 Results.AddResult("template");
Douglas Gregor3545ff42009-09-21 16:56:56 +00003021
Douglas Gregor00c37ef2010-08-11 21:23:17 +00003022 HandleCodeCompleteResults(this, CodeCompleter,
3023 CodeCompletionContext::CCC_Other,
3024 Results.data(),Results.size());
Douglas Gregor2436e712009-09-17 21:32:03 +00003025}
Douglas Gregor7e90c6d2009-09-18 19:03:04 +00003026
3027void Sema::CodeCompleteUsing(Scope *S) {
3028 if (!CodeCompleter)
3029 return;
3030
Douglas Gregor3545ff42009-09-21 16:56:56 +00003031 ResultBuilder Results(*this, &ResultBuilder::IsNestedNameSpecifier);
Douglas Gregor64b12b52009-09-22 23:31:26 +00003032 Results.EnterNewScope();
Douglas Gregor3545ff42009-09-21 16:56:56 +00003033
3034 // If we aren't in class scope, we could see the "namespace" keyword.
3035 if (!S->isClassScope())
Douglas Gregor78a21012010-01-14 16:01:26 +00003036 Results.AddResult(CodeCompleteConsumer::Result("namespace"));
Douglas Gregor3545ff42009-09-21 16:56:56 +00003037
3038 // After "using", we can see anything that would start a
3039 // nested-name-specifier.
Douglas Gregora6e2edc2010-01-14 03:27:13 +00003040 CodeCompletionDeclConsumer Consumer(Results, CurContext);
Douglas Gregor39982192010-08-15 06:18:01 +00003041 LookupVisibleDecls(S, LookupOrdinaryName, Consumer,
3042 CodeCompleter->includeGlobals());
Douglas Gregor64b12b52009-09-22 23:31:26 +00003043 Results.ExitScope();
Douglas Gregor3545ff42009-09-21 16:56:56 +00003044
Douglas Gregor00c37ef2010-08-11 21:23:17 +00003045 HandleCodeCompleteResults(this, CodeCompleter,
3046 CodeCompletionContext::CCC_Other,
3047 Results.data(),Results.size());
Douglas Gregor7e90c6d2009-09-18 19:03:04 +00003048}
3049
3050void Sema::CodeCompleteUsingDirective(Scope *S) {
3051 if (!CodeCompleter)
3052 return;
3053
Douglas Gregor3545ff42009-09-21 16:56:56 +00003054 // After "using namespace", we expect to see a namespace name or namespace
3055 // alias.
3056 ResultBuilder Results(*this, &ResultBuilder::IsNamespaceOrAlias);
Douglas Gregor64b12b52009-09-22 23:31:26 +00003057 Results.EnterNewScope();
Douglas Gregora6e2edc2010-01-14 03:27:13 +00003058 CodeCompletionDeclConsumer Consumer(Results, CurContext);
Douglas Gregor39982192010-08-15 06:18:01 +00003059 LookupVisibleDecls(S, LookupOrdinaryName, Consumer,
3060 CodeCompleter->includeGlobals());
Douglas Gregor64b12b52009-09-22 23:31:26 +00003061 Results.ExitScope();
Douglas Gregor00c37ef2010-08-11 21:23:17 +00003062 HandleCodeCompleteResults(this, CodeCompleter,
Douglas Gregor39982192010-08-15 06:18:01 +00003063 CodeCompletionContext::CCC_Namespace,
Douglas Gregor00c37ef2010-08-11 21:23:17 +00003064 Results.data(),Results.size());
Douglas Gregor7e90c6d2009-09-18 19:03:04 +00003065}
3066
3067void Sema::CodeCompleteNamespaceDecl(Scope *S) {
3068 if (!CodeCompleter)
3069 return;
3070
Douglas Gregor3545ff42009-09-21 16:56:56 +00003071 ResultBuilder Results(*this, &ResultBuilder::IsNamespace);
3072 DeclContext *Ctx = (DeclContext *)S->getEntity();
3073 if (!S->getParent())
3074 Ctx = Context.getTranslationUnitDecl();
3075
3076 if (Ctx && Ctx->isFileContext()) {
3077 // We only want to see those namespaces that have already been defined
3078 // within this scope, because its likely that the user is creating an
3079 // extended namespace declaration. Keep track of the most recent
3080 // definition of each namespace.
3081 std::map<NamespaceDecl *, NamespaceDecl *> OrigToLatest;
3082 for (DeclContext::specific_decl_iterator<NamespaceDecl>
3083 NS(Ctx->decls_begin()), NSEnd(Ctx->decls_end());
3084 NS != NSEnd; ++NS)
3085 OrigToLatest[NS->getOriginalNamespace()] = *NS;
3086
3087 // Add the most recent definition (or extended definition) of each
3088 // namespace to the list of results.
Douglas Gregor64b12b52009-09-22 23:31:26 +00003089 Results.EnterNewScope();
Douglas Gregor3545ff42009-09-21 16:56:56 +00003090 for (std::map<NamespaceDecl *, NamespaceDecl *>::iterator
3091 NS = OrigToLatest.begin(), NSEnd = OrigToLatest.end();
3092 NS != NSEnd; ++NS)
Douglas Gregorfc59ce12010-01-14 16:14:35 +00003093 Results.AddResult(CodeCompleteConsumer::Result(NS->second, 0),
3094 CurContext, 0, false);
Douglas Gregor64b12b52009-09-22 23:31:26 +00003095 Results.ExitScope();
Douglas Gregor3545ff42009-09-21 16:56:56 +00003096 }
3097
Douglas Gregor00c37ef2010-08-11 21:23:17 +00003098 HandleCodeCompleteResults(this, CodeCompleter,
3099 CodeCompletionContext::CCC_Other,
3100 Results.data(),Results.size());
Douglas Gregor7e90c6d2009-09-18 19:03:04 +00003101}
3102
3103void Sema::CodeCompleteNamespaceAliasDecl(Scope *S) {
3104 if (!CodeCompleter)
3105 return;
3106
Douglas Gregor3545ff42009-09-21 16:56:56 +00003107 // After "namespace", we expect to see a namespace or alias.
3108 ResultBuilder Results(*this, &ResultBuilder::IsNamespaceOrAlias);
Douglas Gregora6e2edc2010-01-14 03:27:13 +00003109 CodeCompletionDeclConsumer Consumer(Results, CurContext);
Douglas Gregor39982192010-08-15 06:18:01 +00003110 LookupVisibleDecls(S, LookupOrdinaryName, Consumer,
3111 CodeCompleter->includeGlobals());
Douglas Gregor00c37ef2010-08-11 21:23:17 +00003112 HandleCodeCompleteResults(this, CodeCompleter,
Douglas Gregor39982192010-08-15 06:18:01 +00003113 CodeCompletionContext::CCC_Namespace,
Douglas Gregor00c37ef2010-08-11 21:23:17 +00003114 Results.data(),Results.size());
Douglas Gregor7e90c6d2009-09-18 19:03:04 +00003115}
3116
Douglas Gregorc811ede2009-09-18 20:05:18 +00003117void Sema::CodeCompleteOperatorName(Scope *S) {
3118 if (!CodeCompleter)
3119 return;
Douglas Gregor3545ff42009-09-21 16:56:56 +00003120
3121 typedef CodeCompleteConsumer::Result Result;
3122 ResultBuilder Results(*this, &ResultBuilder::IsType);
Douglas Gregor64b12b52009-09-22 23:31:26 +00003123 Results.EnterNewScope();
Douglas Gregorc811ede2009-09-18 20:05:18 +00003124
Douglas Gregor3545ff42009-09-21 16:56:56 +00003125 // Add the names of overloadable operators.
3126#define OVERLOADED_OPERATOR(Name,Spelling,Token,Unary,Binary,MemberOnly) \
3127 if (std::strcmp(Spelling, "?")) \
Douglas Gregor78a21012010-01-14 16:01:26 +00003128 Results.AddResult(Result(Spelling));
Douglas Gregor3545ff42009-09-21 16:56:56 +00003129#include "clang/Basic/OperatorKinds.def"
3130
3131 // Add any type names visible from the current scope
Douglas Gregor6ae4c522010-01-14 03:21:49 +00003132 Results.allowNestedNameSpecifiers();
Douglas Gregora6e2edc2010-01-14 03:27:13 +00003133 CodeCompletionDeclConsumer Consumer(Results, CurContext);
Douglas Gregor39982192010-08-15 06:18:01 +00003134 LookupVisibleDecls(S, LookupOrdinaryName, Consumer,
3135 CodeCompleter->includeGlobals());
Douglas Gregor3545ff42009-09-21 16:56:56 +00003136
3137 // Add any type specifiers
Douglas Gregorf98e6a22010-01-13 23:51:12 +00003138 AddTypeSpecifierResults(getLangOptions(), Results);
Douglas Gregor64b12b52009-09-22 23:31:26 +00003139 Results.ExitScope();
Douglas Gregor3545ff42009-09-21 16:56:56 +00003140
Douglas Gregor00c37ef2010-08-11 21:23:17 +00003141 HandleCodeCompleteResults(this, CodeCompleter,
Douglas Gregor39982192010-08-15 06:18:01 +00003142 CodeCompletionContext::CCC_Type,
Douglas Gregor00c37ef2010-08-11 21:23:17 +00003143 Results.data(),Results.size());
Douglas Gregorc811ede2009-09-18 20:05:18 +00003144}
Douglas Gregor7e90c6d2009-09-18 19:03:04 +00003145
Douglas Gregorf1934162010-01-13 21:24:21 +00003146// Macro that expands to @Keyword or Keyword, depending on whether NeedAt is
3147// true or false.
3148#define OBJC_AT_KEYWORD_NAME(NeedAt,Keyword) NeedAt? "@" #Keyword : #Keyword
Douglas Gregorf98e6a22010-01-13 23:51:12 +00003149static void AddObjCImplementationResults(const LangOptions &LangOpts,
Douglas Gregorf1934162010-01-13 21:24:21 +00003150 ResultBuilder &Results,
3151 bool NeedAt) {
3152 typedef CodeCompleteConsumer::Result Result;
3153 // Since we have an implementation, we can end it.
Douglas Gregor78a21012010-01-14 16:01:26 +00003154 Results.AddResult(Result(OBJC_AT_KEYWORD_NAME(NeedAt,end)));
Douglas Gregorf1934162010-01-13 21:24:21 +00003155
3156 CodeCompletionString *Pattern = 0;
3157 if (LangOpts.ObjC2) {
3158 // @dynamic
3159 Pattern = new CodeCompletionString;
3160 Pattern->AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt,dynamic));
3161 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
3162 Pattern->AddPlaceholderChunk("property");
Douglas Gregor78a21012010-01-14 16:01:26 +00003163 Results.AddResult(Result(Pattern));
Douglas Gregorf1934162010-01-13 21:24:21 +00003164
3165 // @synthesize
3166 Pattern = new CodeCompletionString;
3167 Pattern->AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt,synthesize));
3168 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
3169 Pattern->AddPlaceholderChunk("property");
Douglas Gregor78a21012010-01-14 16:01:26 +00003170 Results.AddResult(Result(Pattern));
Douglas Gregorf1934162010-01-13 21:24:21 +00003171 }
3172}
3173
Douglas Gregorf98e6a22010-01-13 23:51:12 +00003174static void AddObjCInterfaceResults(const LangOptions &LangOpts,
Douglas Gregorf1934162010-01-13 21:24:21 +00003175 ResultBuilder &Results,
3176 bool NeedAt) {
3177 typedef CodeCompleteConsumer::Result Result;
3178
3179 // Since we have an interface or protocol, we can end it.
Douglas Gregor78a21012010-01-14 16:01:26 +00003180 Results.AddResult(Result(OBJC_AT_KEYWORD_NAME(NeedAt,end)));
Douglas Gregorf1934162010-01-13 21:24:21 +00003181
3182 if (LangOpts.ObjC2) {
3183 // @property
Douglas Gregor78a21012010-01-14 16:01:26 +00003184 Results.AddResult(Result(OBJC_AT_KEYWORD_NAME(NeedAt,property)));
Douglas Gregorf1934162010-01-13 21:24:21 +00003185
3186 // @required
Douglas Gregor78a21012010-01-14 16:01:26 +00003187 Results.AddResult(Result(OBJC_AT_KEYWORD_NAME(NeedAt,required)));
Douglas Gregorf1934162010-01-13 21:24:21 +00003188
3189 // @optional
Douglas Gregor78a21012010-01-14 16:01:26 +00003190 Results.AddResult(Result(OBJC_AT_KEYWORD_NAME(NeedAt,optional)));
Douglas Gregorf1934162010-01-13 21:24:21 +00003191 }
3192}
3193
Douglas Gregorf98e6a22010-01-13 23:51:12 +00003194static void AddObjCTopLevelResults(ResultBuilder &Results, bool NeedAt) {
Douglas Gregorf1934162010-01-13 21:24:21 +00003195 typedef CodeCompleteConsumer::Result Result;
3196 CodeCompletionString *Pattern = 0;
3197
3198 // @class name ;
3199 Pattern = new CodeCompletionString;
3200 Pattern->AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt,class));
3201 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
Douglas Gregorf4c33342010-05-28 00:22:41 +00003202 Pattern->AddPlaceholderChunk("name");
Douglas Gregor78a21012010-01-14 16:01:26 +00003203 Results.AddResult(Result(Pattern));
Douglas Gregorf1934162010-01-13 21:24:21 +00003204
Douglas Gregorf4c33342010-05-28 00:22:41 +00003205 if (Results.includeCodePatterns()) {
3206 // @interface name
3207 // FIXME: Could introduce the whole pattern, including superclasses and
3208 // such.
3209 Pattern = new CodeCompletionString;
3210 Pattern->AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt,interface));
3211 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
3212 Pattern->AddPlaceholderChunk("class");
3213 Results.AddResult(Result(Pattern));
Douglas Gregorf1934162010-01-13 21:24:21 +00003214
Douglas Gregorf4c33342010-05-28 00:22:41 +00003215 // @protocol name
3216 Pattern = new CodeCompletionString;
3217 Pattern->AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt,protocol));
3218 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
3219 Pattern->AddPlaceholderChunk("protocol");
3220 Results.AddResult(Result(Pattern));
3221
3222 // @implementation name
3223 Pattern = new CodeCompletionString;
3224 Pattern->AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt,implementation));
3225 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
3226 Pattern->AddPlaceholderChunk("class");
3227 Results.AddResult(Result(Pattern));
3228 }
Douglas Gregorf1934162010-01-13 21:24:21 +00003229
3230 // @compatibility_alias name
3231 Pattern = new CodeCompletionString;
3232 Pattern->AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt,compatibility_alias));
3233 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
3234 Pattern->AddPlaceholderChunk("alias");
3235 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
3236 Pattern->AddPlaceholderChunk("class");
Douglas Gregor78a21012010-01-14 16:01:26 +00003237 Results.AddResult(Result(Pattern));
Douglas Gregorf1934162010-01-13 21:24:21 +00003238}
3239
John McCall48871652010-08-21 09:40:31 +00003240void Sema::CodeCompleteObjCAtDirective(Scope *S, Decl *ObjCImpDecl,
Douglas Gregorf48706c2009-12-07 09:27:33 +00003241 bool InInterface) {
3242 typedef CodeCompleteConsumer::Result Result;
3243 ResultBuilder Results(*this);
3244 Results.EnterNewScope();
Douglas Gregorf1934162010-01-13 21:24:21 +00003245 if (ObjCImpDecl)
Douglas Gregorf98e6a22010-01-13 23:51:12 +00003246 AddObjCImplementationResults(getLangOptions(), Results, false);
Douglas Gregorf1934162010-01-13 21:24:21 +00003247 else if (InInterface)
Douglas Gregorf98e6a22010-01-13 23:51:12 +00003248 AddObjCInterfaceResults(getLangOptions(), Results, false);
Douglas Gregorf1934162010-01-13 21:24:21 +00003249 else
Douglas Gregorf98e6a22010-01-13 23:51:12 +00003250 AddObjCTopLevelResults(Results, false);
Douglas Gregorf48706c2009-12-07 09:27:33 +00003251 Results.ExitScope();
Douglas Gregor00c37ef2010-08-11 21:23:17 +00003252 HandleCodeCompleteResults(this, CodeCompleter,
3253 CodeCompletionContext::CCC_Other,
3254 Results.data(),Results.size());
Douglas Gregorf48706c2009-12-07 09:27:33 +00003255}
3256
Douglas Gregorf98e6a22010-01-13 23:51:12 +00003257static void AddObjCExpressionResults(ResultBuilder &Results, bool NeedAt) {
Douglas Gregorbc7c5e42009-12-07 09:51:25 +00003258 typedef CodeCompleteConsumer::Result Result;
3259 CodeCompletionString *Pattern = 0;
3260
3261 // @encode ( type-name )
3262 Pattern = new CodeCompletionString;
Douglas Gregorf1934162010-01-13 21:24:21 +00003263 Pattern->AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt,encode));
Douglas Gregorbc7c5e42009-12-07 09:51:25 +00003264 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
3265 Pattern->AddPlaceholderChunk("type-name");
3266 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
Douglas Gregor78a21012010-01-14 16:01:26 +00003267 Results.AddResult(Result(Pattern));
Douglas Gregorbc7c5e42009-12-07 09:51:25 +00003268
3269 // @protocol ( protocol-name )
3270 Pattern = new CodeCompletionString;
Douglas Gregorf1934162010-01-13 21:24:21 +00003271 Pattern->AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt,protocol));
Douglas Gregorbc7c5e42009-12-07 09:51:25 +00003272 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
3273 Pattern->AddPlaceholderChunk("protocol-name");
3274 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
Douglas Gregor78a21012010-01-14 16:01:26 +00003275 Results.AddResult(Result(Pattern));
Douglas Gregorbc7c5e42009-12-07 09:51:25 +00003276
3277 // @selector ( selector )
3278 Pattern = new CodeCompletionString;
Douglas Gregorf1934162010-01-13 21:24:21 +00003279 Pattern->AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt,selector));
Douglas Gregorbc7c5e42009-12-07 09:51:25 +00003280 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
3281 Pattern->AddPlaceholderChunk("selector");
3282 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
Douglas Gregor78a21012010-01-14 16:01:26 +00003283 Results.AddResult(Result(Pattern));
Douglas Gregorbc7c5e42009-12-07 09:51:25 +00003284}
3285
Douglas Gregorf98e6a22010-01-13 23:51:12 +00003286static void AddObjCStatementResults(ResultBuilder &Results, bool NeedAt) {
Douglas Gregorbc7c5e42009-12-07 09:51:25 +00003287 typedef CodeCompleteConsumer::Result Result;
Douglas Gregorbc7c5e42009-12-07 09:51:25 +00003288 CodeCompletionString *Pattern = 0;
Douglas Gregorf1934162010-01-13 21:24:21 +00003289
Douglas Gregorf4c33342010-05-28 00:22:41 +00003290 if (Results.includeCodePatterns()) {
3291 // @try { statements } @catch ( declaration ) { statements } @finally
3292 // { statements }
3293 Pattern = new CodeCompletionString;
3294 Pattern->AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt,try));
3295 Pattern->AddChunk(CodeCompletionString::CK_LeftBrace);
3296 Pattern->AddPlaceholderChunk("statements");
3297 Pattern->AddChunk(CodeCompletionString::CK_RightBrace);
3298 Pattern->AddTextChunk("@catch");
3299 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
3300 Pattern->AddPlaceholderChunk("parameter");
3301 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
3302 Pattern->AddChunk(CodeCompletionString::CK_LeftBrace);
3303 Pattern->AddPlaceholderChunk("statements");
3304 Pattern->AddChunk(CodeCompletionString::CK_RightBrace);
3305 Pattern->AddTextChunk("@finally");
3306 Pattern->AddChunk(CodeCompletionString::CK_LeftBrace);
3307 Pattern->AddPlaceholderChunk("statements");
3308 Pattern->AddChunk(CodeCompletionString::CK_RightBrace);
3309 Results.AddResult(Result(Pattern));
3310 }
Douglas Gregorf1934162010-01-13 21:24:21 +00003311
Douglas Gregorbc7c5e42009-12-07 09:51:25 +00003312 // @throw
3313 Pattern = new CodeCompletionString;
Douglas Gregorf1934162010-01-13 21:24:21 +00003314 Pattern->AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt,throw));
Douglas Gregor6a803932010-01-12 06:38:28 +00003315 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
Douglas Gregorbc7c5e42009-12-07 09:51:25 +00003316 Pattern->AddPlaceholderChunk("expression");
Douglas Gregor78a21012010-01-14 16:01:26 +00003317 Results.AddResult(Result(Pattern));
Douglas Gregorf1934162010-01-13 21:24:21 +00003318
Douglas Gregorf4c33342010-05-28 00:22:41 +00003319 if (Results.includeCodePatterns()) {
3320 // @synchronized ( expression ) { statements }
3321 Pattern = new CodeCompletionString;
3322 Pattern->AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt,synchronized));
3323 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
3324 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
3325 Pattern->AddPlaceholderChunk("expression");
3326 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
3327 Pattern->AddChunk(CodeCompletionString::CK_LeftBrace);
3328 Pattern->AddPlaceholderChunk("statements");
3329 Pattern->AddChunk(CodeCompletionString::CK_RightBrace);
3330 Results.AddResult(Result(Pattern));
3331 }
Douglas Gregorf1934162010-01-13 21:24:21 +00003332}
Douglas Gregorbc7c5e42009-12-07 09:51:25 +00003333
Douglas Gregorf98e6a22010-01-13 23:51:12 +00003334static void AddObjCVisibilityResults(const LangOptions &LangOpts,
Douglas Gregor48d46252010-01-13 21:54:15 +00003335 ResultBuilder &Results,
3336 bool NeedAt) {
Douglas Gregorf1934162010-01-13 21:24:21 +00003337 typedef CodeCompleteConsumer::Result Result;
Douglas Gregor78a21012010-01-14 16:01:26 +00003338 Results.AddResult(Result(OBJC_AT_KEYWORD_NAME(NeedAt,private)));
3339 Results.AddResult(Result(OBJC_AT_KEYWORD_NAME(NeedAt,protected)));
3340 Results.AddResult(Result(OBJC_AT_KEYWORD_NAME(NeedAt,public)));
Douglas Gregor48d46252010-01-13 21:54:15 +00003341 if (LangOpts.ObjC2)
Douglas Gregor78a21012010-01-14 16:01:26 +00003342 Results.AddResult(Result(OBJC_AT_KEYWORD_NAME(NeedAt,package)));
Douglas Gregor48d46252010-01-13 21:54:15 +00003343}
3344
3345void Sema::CodeCompleteObjCAtVisibility(Scope *S) {
3346 ResultBuilder Results(*this);
3347 Results.EnterNewScope();
Douglas Gregorf98e6a22010-01-13 23:51:12 +00003348 AddObjCVisibilityResults(getLangOptions(), Results, false);
Douglas Gregor48d46252010-01-13 21:54:15 +00003349 Results.ExitScope();
Douglas Gregor00c37ef2010-08-11 21:23:17 +00003350 HandleCodeCompleteResults(this, CodeCompleter,
3351 CodeCompletionContext::CCC_Other,
3352 Results.data(),Results.size());
Douglas Gregor48d46252010-01-13 21:54:15 +00003353}
3354
3355void Sema::CodeCompleteObjCAtStatement(Scope *S) {
Douglas Gregorf1934162010-01-13 21:24:21 +00003356 ResultBuilder Results(*this);
3357 Results.EnterNewScope();
Douglas Gregorf98e6a22010-01-13 23:51:12 +00003358 AddObjCStatementResults(Results, false);
3359 AddObjCExpressionResults(Results, false);
Douglas Gregorbc7c5e42009-12-07 09:51:25 +00003360 Results.ExitScope();
Douglas Gregor00c37ef2010-08-11 21:23:17 +00003361 HandleCodeCompleteResults(this, CodeCompleter,
3362 CodeCompletionContext::CCC_Other,
3363 Results.data(),Results.size());
Douglas Gregorbc7c5e42009-12-07 09:51:25 +00003364}
3365
3366void Sema::CodeCompleteObjCAtExpression(Scope *S) {
3367 ResultBuilder Results(*this);
3368 Results.EnterNewScope();
Douglas Gregorf98e6a22010-01-13 23:51:12 +00003369 AddObjCExpressionResults(Results, false);
Douglas Gregorbc7c5e42009-12-07 09:51:25 +00003370 Results.ExitScope();
Douglas Gregor00c37ef2010-08-11 21:23:17 +00003371 HandleCodeCompleteResults(this, CodeCompleter,
3372 CodeCompletionContext::CCC_Other,
3373 Results.data(),Results.size());
Douglas Gregorbc7c5e42009-12-07 09:51:25 +00003374}
3375
Douglas Gregore6078da2009-11-19 00:14:45 +00003376/// \brief Determine whether the addition of the given flag to an Objective-C
3377/// property's attributes will cause a conflict.
3378static bool ObjCPropertyFlagConflicts(unsigned Attributes, unsigned NewFlag) {
3379 // Check if we've already added this flag.
3380 if (Attributes & NewFlag)
3381 return true;
3382
3383 Attributes |= NewFlag;
3384
3385 // Check for collisions with "readonly".
3386 if ((Attributes & ObjCDeclSpec::DQ_PR_readonly) &&
3387 (Attributes & (ObjCDeclSpec::DQ_PR_readwrite |
3388 ObjCDeclSpec::DQ_PR_assign |
3389 ObjCDeclSpec::DQ_PR_copy |
3390 ObjCDeclSpec::DQ_PR_retain)))
3391 return true;
3392
3393 // Check for more than one of { assign, copy, retain }.
3394 unsigned AssignCopyRetMask = Attributes & (ObjCDeclSpec::DQ_PR_assign |
3395 ObjCDeclSpec::DQ_PR_copy |
3396 ObjCDeclSpec::DQ_PR_retain);
3397 if (AssignCopyRetMask &&
3398 AssignCopyRetMask != ObjCDeclSpec::DQ_PR_assign &&
3399 AssignCopyRetMask != ObjCDeclSpec::DQ_PR_copy &&
3400 AssignCopyRetMask != ObjCDeclSpec::DQ_PR_retain)
3401 return true;
3402
3403 return false;
3404}
3405
Douglas Gregor36029f42009-11-18 23:08:07 +00003406void Sema::CodeCompleteObjCPropertyFlags(Scope *S, ObjCDeclSpec &ODS) {
Steve Naroff936354c2009-10-08 21:55:05 +00003407 if (!CodeCompleter)
3408 return;
Douglas Gregor1b605f72009-11-19 01:08:35 +00003409
Steve Naroff936354c2009-10-08 21:55:05 +00003410 unsigned Attributes = ODS.getPropertyAttributes();
3411
3412 typedef CodeCompleteConsumer::Result Result;
3413 ResultBuilder Results(*this);
3414 Results.EnterNewScope();
Douglas Gregore6078da2009-11-19 00:14:45 +00003415 if (!ObjCPropertyFlagConflicts(Attributes, ObjCDeclSpec::DQ_PR_readonly))
Douglas Gregor78a21012010-01-14 16:01:26 +00003416 Results.AddResult(CodeCompleteConsumer::Result("readonly"));
Douglas Gregore6078da2009-11-19 00:14:45 +00003417 if (!ObjCPropertyFlagConflicts(Attributes, ObjCDeclSpec::DQ_PR_assign))
Douglas Gregor78a21012010-01-14 16:01:26 +00003418 Results.AddResult(CodeCompleteConsumer::Result("assign"));
Douglas Gregore6078da2009-11-19 00:14:45 +00003419 if (!ObjCPropertyFlagConflicts(Attributes, ObjCDeclSpec::DQ_PR_readwrite))
Douglas Gregor78a21012010-01-14 16:01:26 +00003420 Results.AddResult(CodeCompleteConsumer::Result("readwrite"));
Douglas Gregore6078da2009-11-19 00:14:45 +00003421 if (!ObjCPropertyFlagConflicts(Attributes, ObjCDeclSpec::DQ_PR_retain))
Douglas Gregor78a21012010-01-14 16:01:26 +00003422 Results.AddResult(CodeCompleteConsumer::Result("retain"));
Douglas Gregore6078da2009-11-19 00:14:45 +00003423 if (!ObjCPropertyFlagConflicts(Attributes, ObjCDeclSpec::DQ_PR_copy))
Douglas Gregor78a21012010-01-14 16:01:26 +00003424 Results.AddResult(CodeCompleteConsumer::Result("copy"));
Douglas Gregore6078da2009-11-19 00:14:45 +00003425 if (!ObjCPropertyFlagConflicts(Attributes, ObjCDeclSpec::DQ_PR_nonatomic))
Douglas Gregor78a21012010-01-14 16:01:26 +00003426 Results.AddResult(CodeCompleteConsumer::Result("nonatomic"));
Douglas Gregore6078da2009-11-19 00:14:45 +00003427 if (!ObjCPropertyFlagConflicts(Attributes, ObjCDeclSpec::DQ_PR_setter)) {
Douglas Gregor45f83ee2009-11-19 00:01:57 +00003428 CodeCompletionString *Setter = new CodeCompletionString;
3429 Setter->AddTypedTextChunk("setter");
3430 Setter->AddTextChunk(" = ");
3431 Setter->AddPlaceholderChunk("method");
Douglas Gregor78a21012010-01-14 16:01:26 +00003432 Results.AddResult(CodeCompleteConsumer::Result(Setter));
Douglas Gregor45f83ee2009-11-19 00:01:57 +00003433 }
Douglas Gregore6078da2009-11-19 00:14:45 +00003434 if (!ObjCPropertyFlagConflicts(Attributes, ObjCDeclSpec::DQ_PR_getter)) {
Douglas Gregor45f83ee2009-11-19 00:01:57 +00003435 CodeCompletionString *Getter = new CodeCompletionString;
3436 Getter->AddTypedTextChunk("getter");
3437 Getter->AddTextChunk(" = ");
3438 Getter->AddPlaceholderChunk("method");
Douglas Gregor78a21012010-01-14 16:01:26 +00003439 Results.AddResult(CodeCompleteConsumer::Result(Getter));
Douglas Gregor45f83ee2009-11-19 00:01:57 +00003440 }
Steve Naroff936354c2009-10-08 21:55:05 +00003441 Results.ExitScope();
Douglas Gregor00c37ef2010-08-11 21:23:17 +00003442 HandleCodeCompleteResults(this, CodeCompleter,
3443 CodeCompletionContext::CCC_Other,
3444 Results.data(),Results.size());
Steve Naroff936354c2009-10-08 21:55:05 +00003445}
Steve Naroffeae65032009-11-07 02:08:14 +00003446
Douglas Gregorc8537c52009-11-19 07:41:15 +00003447/// \brief Descripts the kind of Objective-C method that we want to find
3448/// via code completion.
3449enum ObjCMethodKind {
3450 MK_Any, //< Any kind of method, provided it means other specified criteria.
3451 MK_ZeroArgSelector, //< Zero-argument (unary) selector.
3452 MK_OneArgSelector //< One-argument selector.
3453};
3454
3455static bool isAcceptableObjCMethod(ObjCMethodDecl *Method,
3456 ObjCMethodKind WantKind,
3457 IdentifierInfo **SelIdents,
3458 unsigned NumSelIdents) {
3459 Selector Sel = Method->getSelector();
3460 if (NumSelIdents > Sel.getNumArgs())
3461 return false;
3462
3463 switch (WantKind) {
3464 case MK_Any: break;
3465 case MK_ZeroArgSelector: return Sel.isUnarySelector();
3466 case MK_OneArgSelector: return Sel.getNumArgs() == 1;
3467 }
3468
3469 for (unsigned I = 0; I != NumSelIdents; ++I)
3470 if (SelIdents[I] != Sel.getIdentifierInfoForSlot(I))
3471 return false;
3472
3473 return true;
3474}
3475
Douglas Gregorbab2b3c2009-11-17 23:22:23 +00003476/// \brief Add all of the Objective-C methods in the given Objective-C
3477/// container to the set of results.
3478///
3479/// The container will be a class, protocol, category, or implementation of
3480/// any of the above. This mether will recurse to include methods from
3481/// the superclasses of classes along with their categories, protocols, and
3482/// implementations.
3483///
3484/// \param Container the container in which we'll look to find methods.
3485///
3486/// \param WantInstance whether to add instance methods (only); if false, this
3487/// routine will add factory methods (only).
3488///
3489/// \param CurContext the context in which we're performing the lookup that
3490/// finds methods.
3491///
3492/// \param Results the structure into which we'll add results.
3493static void AddObjCMethods(ObjCContainerDecl *Container,
3494 bool WantInstanceMethods,
Douglas Gregorc8537c52009-11-19 07:41:15 +00003495 ObjCMethodKind WantKind,
Douglas Gregor1b605f72009-11-19 01:08:35 +00003496 IdentifierInfo **SelIdents,
3497 unsigned NumSelIdents,
Douglas Gregorbab2b3c2009-11-17 23:22:23 +00003498 DeclContext *CurContext,
3499 ResultBuilder &Results) {
3500 typedef CodeCompleteConsumer::Result Result;
3501 for (ObjCContainerDecl::method_iterator M = Container->meth_begin(),
3502 MEnd = Container->meth_end();
3503 M != MEnd; ++M) {
Douglas Gregor1b605f72009-11-19 01:08:35 +00003504 if ((*M)->isInstanceMethod() == WantInstanceMethods) {
3505 // Check whether the selector identifiers we've been given are a
3506 // subset of the identifiers for this particular method.
Douglas Gregorc8537c52009-11-19 07:41:15 +00003507 if (!isAcceptableObjCMethod(*M, WantKind, SelIdents, NumSelIdents))
Douglas Gregor1b605f72009-11-19 01:08:35 +00003508 continue;
Douglas Gregorc8537c52009-11-19 07:41:15 +00003509
Douglas Gregor1b605f72009-11-19 01:08:35 +00003510 Result R = Result(*M, 0);
3511 R.StartParameter = NumSelIdents;
Douglas Gregorc8537c52009-11-19 07:41:15 +00003512 R.AllParametersAreInformative = (WantKind != MK_Any);
Douglas Gregor1b605f72009-11-19 01:08:35 +00003513 Results.MaybeAddResult(R, CurContext);
3514 }
Douglas Gregorbab2b3c2009-11-17 23:22:23 +00003515 }
3516
3517 ObjCInterfaceDecl *IFace = dyn_cast<ObjCInterfaceDecl>(Container);
3518 if (!IFace)
3519 return;
3520
3521 // Add methods in protocols.
3522 const ObjCList<ObjCProtocolDecl> &Protocols= IFace->getReferencedProtocols();
3523 for (ObjCList<ObjCProtocolDecl>::iterator I = Protocols.begin(),
3524 E = Protocols.end();
3525 I != E; ++I)
Douglas Gregorc8537c52009-11-19 07:41:15 +00003526 AddObjCMethods(*I, WantInstanceMethods, WantKind, SelIdents, NumSelIdents,
Douglas Gregor1b605f72009-11-19 01:08:35 +00003527 CurContext, Results);
Douglas Gregorbab2b3c2009-11-17 23:22:23 +00003528
3529 // Add methods in categories.
3530 for (ObjCCategoryDecl *CatDecl = IFace->getCategoryList(); CatDecl;
3531 CatDecl = CatDecl->getNextClassCategory()) {
Douglas Gregorc8537c52009-11-19 07:41:15 +00003532 AddObjCMethods(CatDecl, WantInstanceMethods, WantKind, SelIdents,
3533 NumSelIdents, CurContext, Results);
Douglas Gregorbab2b3c2009-11-17 23:22:23 +00003534
3535 // Add a categories protocol methods.
3536 const ObjCList<ObjCProtocolDecl> &Protocols
3537 = CatDecl->getReferencedProtocols();
3538 for (ObjCList<ObjCProtocolDecl>::iterator I = Protocols.begin(),
3539 E = Protocols.end();
3540 I != E; ++I)
Douglas Gregorc8537c52009-11-19 07:41:15 +00003541 AddObjCMethods(*I, WantInstanceMethods, WantKind, SelIdents,
3542 NumSelIdents, CurContext, Results);
Douglas Gregorbab2b3c2009-11-17 23:22:23 +00003543
3544 // Add methods in category implementations.
3545 if (ObjCCategoryImplDecl *Impl = CatDecl->getImplementation())
Douglas Gregorc8537c52009-11-19 07:41:15 +00003546 AddObjCMethods(Impl, WantInstanceMethods, WantKind, SelIdents,
3547 NumSelIdents, CurContext, Results);
Douglas Gregorbab2b3c2009-11-17 23:22:23 +00003548 }
3549
3550 // Add methods in superclass.
3551 if (IFace->getSuperClass())
Douglas Gregorc8537c52009-11-19 07:41:15 +00003552 AddObjCMethods(IFace->getSuperClass(), WantInstanceMethods, WantKind,
3553 SelIdents, NumSelIdents, CurContext, Results);
Douglas Gregorbab2b3c2009-11-17 23:22:23 +00003554
3555 // Add methods in our implementation, if any.
3556 if (ObjCImplementationDecl *Impl = IFace->getImplementation())
Douglas Gregorc8537c52009-11-19 07:41:15 +00003557 AddObjCMethods(Impl, WantInstanceMethods, WantKind, SelIdents,
3558 NumSelIdents, CurContext, Results);
3559}
3560
3561
John McCall48871652010-08-21 09:40:31 +00003562void Sema::CodeCompleteObjCPropertyGetter(Scope *S, Decl *ClassDecl,
3563 Decl **Methods,
Douglas Gregorc8537c52009-11-19 07:41:15 +00003564 unsigned NumMethods) {
3565 typedef CodeCompleteConsumer::Result Result;
3566
3567 // Try to find the interface where getters might live.
John McCall48871652010-08-21 09:40:31 +00003568 ObjCInterfaceDecl *Class = dyn_cast_or_null<ObjCInterfaceDecl>(ClassDecl);
Douglas Gregorc8537c52009-11-19 07:41:15 +00003569 if (!Class) {
3570 if (ObjCCategoryDecl *Category
John McCall48871652010-08-21 09:40:31 +00003571 = dyn_cast_or_null<ObjCCategoryDecl>(ClassDecl))
Douglas Gregorc8537c52009-11-19 07:41:15 +00003572 Class = Category->getClassInterface();
3573
3574 if (!Class)
3575 return;
3576 }
3577
3578 // Find all of the potential getters.
3579 ResultBuilder Results(*this);
3580 Results.EnterNewScope();
3581
3582 // FIXME: We need to do this because Objective-C methods don't get
3583 // pushed into DeclContexts early enough. Argh!
3584 for (unsigned I = 0; I != NumMethods; ++I) {
3585 if (ObjCMethodDecl *Method
John McCall48871652010-08-21 09:40:31 +00003586 = dyn_cast_or_null<ObjCMethodDecl>(Methods[I]))
Douglas Gregorc8537c52009-11-19 07:41:15 +00003587 if (Method->isInstanceMethod() &&
3588 isAcceptableObjCMethod(Method, MK_ZeroArgSelector, 0, 0)) {
3589 Result R = Result(Method, 0);
3590 R.AllParametersAreInformative = true;
3591 Results.MaybeAddResult(R, CurContext);
3592 }
3593 }
3594
3595 AddObjCMethods(Class, true, MK_ZeroArgSelector, 0, 0, CurContext, Results);
3596 Results.ExitScope();
Douglas Gregor00c37ef2010-08-11 21:23:17 +00003597 HandleCodeCompleteResults(this, CodeCompleter,
3598 CodeCompletionContext::CCC_Other,
3599 Results.data(),Results.size());
Douglas Gregorc8537c52009-11-19 07:41:15 +00003600}
3601
John McCall48871652010-08-21 09:40:31 +00003602void Sema::CodeCompleteObjCPropertySetter(Scope *S, Decl *ObjCImplDecl,
3603 Decl **Methods,
Douglas Gregorc8537c52009-11-19 07:41:15 +00003604 unsigned NumMethods) {
3605 typedef CodeCompleteConsumer::Result Result;
3606
3607 // Try to find the interface where setters might live.
3608 ObjCInterfaceDecl *Class
John McCall48871652010-08-21 09:40:31 +00003609 = dyn_cast_or_null<ObjCInterfaceDecl>(ObjCImplDecl);
Douglas Gregorc8537c52009-11-19 07:41:15 +00003610 if (!Class) {
3611 if (ObjCCategoryDecl *Category
John McCall48871652010-08-21 09:40:31 +00003612 = dyn_cast_or_null<ObjCCategoryDecl>(ObjCImplDecl))
Douglas Gregorc8537c52009-11-19 07:41:15 +00003613 Class = Category->getClassInterface();
3614
3615 if (!Class)
3616 return;
3617 }
3618
3619 // Find all of the potential getters.
3620 ResultBuilder Results(*this);
3621 Results.EnterNewScope();
3622
3623 // FIXME: We need to do this because Objective-C methods don't get
3624 // pushed into DeclContexts early enough. Argh!
3625 for (unsigned I = 0; I != NumMethods; ++I) {
3626 if (ObjCMethodDecl *Method
John McCall48871652010-08-21 09:40:31 +00003627 = dyn_cast_or_null<ObjCMethodDecl>(Methods[I]))
Douglas Gregorc8537c52009-11-19 07:41:15 +00003628 if (Method->isInstanceMethod() &&
3629 isAcceptableObjCMethod(Method, MK_OneArgSelector, 0, 0)) {
3630 Result R = Result(Method, 0);
3631 R.AllParametersAreInformative = true;
3632 Results.MaybeAddResult(R, CurContext);
3633 }
3634 }
3635
3636 AddObjCMethods(Class, true, MK_OneArgSelector, 0, 0, CurContext, Results);
3637
3638 Results.ExitScope();
Douglas Gregor00c37ef2010-08-11 21:23:17 +00003639 HandleCodeCompleteResults(this, CodeCompleter,
3640 CodeCompletionContext::CCC_Other,
3641 Results.data(),Results.size());
Douglas Gregorbab2b3c2009-11-17 23:22:23 +00003642}
3643
Douglas Gregor99fa2642010-08-24 01:06:58 +00003644void Sema::CodeCompleteObjCPassingType(Scope *S, ObjCDeclSpec &DS) {
3645 typedef CodeCompleteConsumer::Result Result;
3646 ResultBuilder Results(*this);
3647 Results.EnterNewScope();
3648
3649 // Add context-sensitive, Objective-C parameter-passing keywords.
3650 bool AddedInOut = false;
3651 if ((DS.getObjCDeclQualifier() &
3652 (ObjCDeclSpec::DQ_In | ObjCDeclSpec::DQ_Inout)) == 0) {
3653 Results.AddResult("in");
3654 Results.AddResult("inout");
3655 AddedInOut = true;
3656 }
3657 if ((DS.getObjCDeclQualifier() &
3658 (ObjCDeclSpec::DQ_Out | ObjCDeclSpec::DQ_Inout)) == 0) {
3659 Results.AddResult("out");
3660 if (!AddedInOut)
3661 Results.AddResult("inout");
3662 }
3663 if ((DS.getObjCDeclQualifier() &
3664 (ObjCDeclSpec::DQ_Bycopy | ObjCDeclSpec::DQ_Byref |
3665 ObjCDeclSpec::DQ_Oneway)) == 0) {
3666 Results.AddResult("bycopy");
3667 Results.AddResult("byref");
3668 Results.AddResult("oneway");
3669 }
3670
3671 // Add various builtin type names and specifiers.
3672 AddOrdinaryNameResults(PCC_Type, S, *this, Results);
3673 Results.ExitScope();
3674
3675 // Add the various type names
3676 Results.setFilter(&ResultBuilder::IsOrdinaryNonValueName);
3677 CodeCompletionDeclConsumer Consumer(Results, CurContext);
3678 LookupVisibleDecls(S, LookupOrdinaryName, Consumer,
3679 CodeCompleter->includeGlobals());
3680
3681 if (CodeCompleter->includeMacros())
3682 AddMacroResults(PP, Results);
3683
3684 HandleCodeCompleteResults(this, CodeCompleter,
3685 CodeCompletionContext::CCC_Type,
3686 Results.data(), Results.size());
3687}
3688
Douglas Gregor9d2ddb22010-04-06 19:22:33 +00003689/// \brief When we have an expression with type "id", we may assume
3690/// that it has some more-specific class type based on knowledge of
3691/// common uses of Objective-C. This routine returns that class type,
3692/// or NULL if no better result could be determined.
3693static ObjCInterfaceDecl *GetAssumedMessageSendExprType(Expr *E) {
3694 ObjCMessageExpr *Msg = dyn_cast<ObjCMessageExpr>(E);
3695 if (!Msg)
3696 return 0;
3697
3698 Selector Sel = Msg->getSelector();
3699 if (Sel.isNull())
3700 return 0;
3701
3702 IdentifierInfo *Id = Sel.getIdentifierInfoForSlot(0);
3703 if (!Id)
3704 return 0;
3705
3706 ObjCMethodDecl *Method = Msg->getMethodDecl();
3707 if (!Method)
3708 return 0;
3709
3710 // Determine the class that we're sending the message to.
Douglas Gregor9a129192010-04-21 00:45:42 +00003711 ObjCInterfaceDecl *IFace = 0;
3712 switch (Msg->getReceiverKind()) {
3713 case ObjCMessageExpr::Class:
John McCall8b07ec22010-05-15 11:32:37 +00003714 if (const ObjCObjectType *ObjType
3715 = Msg->getClassReceiver()->getAs<ObjCObjectType>())
3716 IFace = ObjType->getInterface();
Douglas Gregor9a129192010-04-21 00:45:42 +00003717 break;
3718
3719 case ObjCMessageExpr::Instance: {
3720 QualType T = Msg->getInstanceReceiver()->getType();
3721 if (const ObjCObjectPointerType *Ptr = T->getAs<ObjCObjectPointerType>())
3722 IFace = Ptr->getInterfaceDecl();
3723 break;
3724 }
3725
3726 case ObjCMessageExpr::SuperInstance:
3727 case ObjCMessageExpr::SuperClass:
3728 break;
Douglas Gregor9d2ddb22010-04-06 19:22:33 +00003729 }
3730
3731 if (!IFace)
3732 return 0;
3733
3734 ObjCInterfaceDecl *Super = IFace->getSuperClass();
3735 if (Method->isInstanceMethod())
3736 return llvm::StringSwitch<ObjCInterfaceDecl *>(Id->getName())
3737 .Case("retain", IFace)
3738 .Case("autorelease", IFace)
3739 .Case("copy", IFace)
3740 .Case("copyWithZone", IFace)
3741 .Case("mutableCopy", IFace)
3742 .Case("mutableCopyWithZone", IFace)
3743 .Case("awakeFromCoder", IFace)
3744 .Case("replacementObjectFromCoder", IFace)
3745 .Case("class", IFace)
3746 .Case("classForCoder", IFace)
3747 .Case("superclass", Super)
3748 .Default(0);
3749
3750 return llvm::StringSwitch<ObjCInterfaceDecl *>(Id->getName())
3751 .Case("new", IFace)
3752 .Case("alloc", IFace)
3753 .Case("allocWithZone", IFace)
3754 .Case("class", IFace)
3755 .Case("superclass", Super)
3756 .Default(0);
3757}
3758
Douglas Gregora817a192010-05-27 23:06:34 +00003759void Sema::CodeCompleteObjCMessageReceiver(Scope *S) {
3760 typedef CodeCompleteConsumer::Result Result;
3761 ResultBuilder Results(*this);
3762
3763 // Find anything that looks like it could be a message receiver.
3764 Results.setFilter(&ResultBuilder::IsObjCMessageReceiver);
3765 CodeCompletionDeclConsumer Consumer(Results, CurContext);
3766 Results.EnterNewScope();
Douglas Gregor39982192010-08-15 06:18:01 +00003767 LookupVisibleDecls(S, LookupOrdinaryName, Consumer,
3768 CodeCompleter->includeGlobals());
Douglas Gregora817a192010-05-27 23:06:34 +00003769
3770 // If we are in an Objective-C method inside a class that has a superclass,
3771 // add "super" as an option.
3772 if (ObjCMethodDecl *Method = getCurMethodDecl())
3773 if (ObjCInterfaceDecl *Iface = Method->getClassInterface())
3774 if (Iface->getSuperClass())
3775 Results.AddResult(Result("super"));
3776
3777 Results.ExitScope();
3778
3779 if (CodeCompleter->includeMacros())
3780 AddMacroResults(PP, Results);
Douglas Gregor00c37ef2010-08-11 21:23:17 +00003781 HandleCodeCompleteResults(this, CodeCompleter,
3782 CodeCompletionContext::CCC_ObjCMessageReceiver,
3783 Results.data(), Results.size());
Douglas Gregora817a192010-05-27 23:06:34 +00003784
3785}
3786
Douglas Gregor0c78ad92010-04-21 19:57:20 +00003787void Sema::CodeCompleteObjCSuperMessage(Scope *S, SourceLocation SuperLoc,
3788 IdentifierInfo **SelIdents,
3789 unsigned NumSelIdents) {
3790 ObjCInterfaceDecl *CDecl = 0;
3791 if (ObjCMethodDecl *CurMethod = getCurMethodDecl()) {
3792 // Figure out which interface we're in.
3793 CDecl = CurMethod->getClassInterface();
3794 if (!CDecl)
3795 return;
3796
3797 // Find the superclass of this class.
3798 CDecl = CDecl->getSuperClass();
3799 if (!CDecl)
3800 return;
3801
3802 if (CurMethod->isInstanceMethod()) {
3803 // We are inside an instance method, which means that the message
3804 // send [super ...] is actually calling an instance method on the
3805 // current object. Build the super expression and handle this like
3806 // an instance method.
3807 QualType SuperTy = Context.getObjCInterfaceType(CDecl);
3808 SuperTy = Context.getObjCObjectPointerType(SuperTy);
John McCalldadc5752010-08-24 06:29:42 +00003809 ExprResult Super
Douglas Gregor0c78ad92010-04-21 19:57:20 +00003810 = Owned(new (Context) ObjCSuperExpr(SuperLoc, SuperTy));
3811 return CodeCompleteObjCInstanceMessage(S, (Expr *)Super.get(),
3812 SelIdents, NumSelIdents);
3813 }
3814
3815 // Fall through to send to the superclass in CDecl.
3816 } else {
3817 // "super" may be the name of a type or variable. Figure out which
3818 // it is.
3819 IdentifierInfo *Super = &Context.Idents.get("super");
3820 NamedDecl *ND = LookupSingleName(S, Super, SuperLoc,
3821 LookupOrdinaryName);
3822 if ((CDecl = dyn_cast_or_null<ObjCInterfaceDecl>(ND))) {
3823 // "super" names an interface. Use it.
3824 } else if (TypeDecl *TD = dyn_cast_or_null<TypeDecl>(ND)) {
John McCall8b07ec22010-05-15 11:32:37 +00003825 if (const ObjCObjectType *Iface
3826 = Context.getTypeDeclType(TD)->getAs<ObjCObjectType>())
3827 CDecl = Iface->getInterface();
Douglas Gregor0c78ad92010-04-21 19:57:20 +00003828 } else if (ND && isa<UnresolvedUsingTypenameDecl>(ND)) {
3829 // "super" names an unresolved type; we can't be more specific.
3830 } else {
3831 // Assume that "super" names some kind of value and parse that way.
3832 CXXScopeSpec SS;
3833 UnqualifiedId id;
3834 id.setIdentifier(Super, SuperLoc);
John McCalldadc5752010-08-24 06:29:42 +00003835 ExprResult SuperExpr = ActOnIdExpression(S, SS, id, false, false);
Douglas Gregor0c78ad92010-04-21 19:57:20 +00003836 return CodeCompleteObjCInstanceMessage(S, (Expr *)SuperExpr.get(),
3837 SelIdents, NumSelIdents);
3838 }
3839
3840 // Fall through
3841 }
3842
John McCallba7bf592010-08-24 05:47:05 +00003843 ParsedType Receiver;
Douglas Gregor0c78ad92010-04-21 19:57:20 +00003844 if (CDecl)
John McCallba7bf592010-08-24 05:47:05 +00003845 Receiver = ParsedType::make(Context.getObjCInterfaceType(CDecl));
Douglas Gregor0c78ad92010-04-21 19:57:20 +00003846 return CodeCompleteObjCClassMessage(S, Receiver, SelIdents,
3847 NumSelIdents);
3848}
3849
John McCallba7bf592010-08-24 05:47:05 +00003850void Sema::CodeCompleteObjCClassMessage(Scope *S, ParsedType Receiver,
Douglas Gregor1b605f72009-11-19 01:08:35 +00003851 IdentifierInfo **SelIdents,
3852 unsigned NumSelIdents) {
Steve Naroffeae65032009-11-07 02:08:14 +00003853 typedef CodeCompleteConsumer::Result Result;
Douglas Gregor8ce33212009-11-17 17:59:40 +00003854 ObjCInterfaceDecl *CDecl = 0;
3855
Douglas Gregor8ce33212009-11-17 17:59:40 +00003856 // If the given name refers to an interface type, retrieve the
3857 // corresponding declaration.
Douglas Gregor0c78ad92010-04-21 19:57:20 +00003858 if (Receiver) {
3859 QualType T = GetTypeFromParser(Receiver, 0);
3860 if (!T.isNull())
John McCall8b07ec22010-05-15 11:32:37 +00003861 if (const ObjCObjectType *Interface = T->getAs<ObjCObjectType>())
3862 CDecl = Interface->getInterface();
Douglas Gregor8ce33212009-11-17 17:59:40 +00003863 }
3864
Douglas Gregorbab2b3c2009-11-17 23:22:23 +00003865 // Add all of the factory methods in this Objective-C class, its protocols,
3866 // superclasses, categories, implementation, etc.
Steve Naroffeae65032009-11-07 02:08:14 +00003867 ResultBuilder Results(*this);
3868 Results.EnterNewScope();
Douglas Gregor6285f752010-04-06 16:40:00 +00003869
3870 if (CDecl)
3871 AddObjCMethods(CDecl, false, MK_Any, SelIdents, NumSelIdents, CurContext,
3872 Results);
Douglas Gregor0c78ad92010-04-21 19:57:20 +00003873 else {
Douglas Gregor6285f752010-04-06 16:40:00 +00003874 // We're messaging "id" as a type; provide all class/factory methods.
3875
Douglas Gregord720daf2010-04-06 17:30:22 +00003876 // If we have an external source, load the entire class method
Sebastian Redld44cd6a2010-08-18 23:57:06 +00003877 // pool from the AST file.
Douglas Gregord720daf2010-04-06 17:30:22 +00003878 if (ExternalSource) {
John McCall75b960e2010-06-01 09:23:16 +00003879 for (uint32_t I = 0, N = ExternalSource->GetNumExternalSelectors();
3880 I != N; ++I) {
3881 Selector Sel = ExternalSource->GetExternalSelector(I);
Sebastian Redl75d8a322010-08-02 23:18:59 +00003882 if (Sel.isNull() || MethodPool.count(Sel))
Douglas Gregord720daf2010-04-06 17:30:22 +00003883 continue;
3884
Sebastian Redl75d8a322010-08-02 23:18:59 +00003885 ReadMethodPool(Sel);
Douglas Gregord720daf2010-04-06 17:30:22 +00003886 }
3887 }
3888
Sebastian Redl75d8a322010-08-02 23:18:59 +00003889 for (GlobalMethodPool::iterator M = MethodPool.begin(),
3890 MEnd = MethodPool.end();
3891 M != MEnd; ++M) {
3892 for (ObjCMethodList *MethList = &M->second.second;
3893 MethList && MethList->Method;
Douglas Gregor6285f752010-04-06 16:40:00 +00003894 MethList = MethList->Next) {
3895 if (!isAcceptableObjCMethod(MethList->Method, MK_Any, SelIdents,
3896 NumSelIdents))
3897 continue;
3898
3899 Result R(MethList->Method, 0);
3900 R.StartParameter = NumSelIdents;
3901 R.AllParametersAreInformative = false;
3902 Results.MaybeAddResult(R, CurContext);
3903 }
3904 }
3905 }
3906
Steve Naroffeae65032009-11-07 02:08:14 +00003907 Results.ExitScope();
Douglas Gregor00c37ef2010-08-11 21:23:17 +00003908 HandleCodeCompleteResults(this, CodeCompleter,
3909 CodeCompletionContext::CCC_Other,
3910 Results.data(),Results.size());
Steve Naroffeae65032009-11-07 02:08:14 +00003911}
3912
Douglas Gregor1b605f72009-11-19 01:08:35 +00003913void Sema::CodeCompleteObjCInstanceMessage(Scope *S, ExprTy *Receiver,
3914 IdentifierInfo **SelIdents,
3915 unsigned NumSelIdents) {
Steve Naroffeae65032009-11-07 02:08:14 +00003916 typedef CodeCompleteConsumer::Result Result;
Steve Naroffeae65032009-11-07 02:08:14 +00003917
3918 Expr *RecExpr = static_cast<Expr *>(Receiver);
Steve Naroffeae65032009-11-07 02:08:14 +00003919
Douglas Gregorbab2b3c2009-11-17 23:22:23 +00003920 // If necessary, apply function/array conversion to the receiver.
3921 // C99 6.7.5.3p[7,8].
Douglas Gregorb92a1562010-02-03 00:27:59 +00003922 DefaultFunctionArrayLvalueConversion(RecExpr);
Douglas Gregorbab2b3c2009-11-17 23:22:23 +00003923 QualType ReceiverType = RecExpr->getType();
Steve Naroffeae65032009-11-07 02:08:14 +00003924
Douglas Gregorbab2b3c2009-11-17 23:22:23 +00003925 // Build the set of methods we can see.
3926 ResultBuilder Results(*this);
3927 Results.EnterNewScope();
Douglas Gregor9d2ddb22010-04-06 19:22:33 +00003928
3929 // If we're messaging an expression with type "id" or "Class", check
3930 // whether we know something special about the receiver that allows
3931 // us to assume a more-specific receiver type.
3932 if (ReceiverType->isObjCIdType() || ReceiverType->isObjCClassType())
3933 if (ObjCInterfaceDecl *IFace = GetAssumedMessageSendExprType(RecExpr))
3934 ReceiverType = Context.getObjCObjectPointerType(
3935 Context.getObjCInterfaceType(IFace));
Douglas Gregorbab2b3c2009-11-17 23:22:23 +00003936
Douglas Gregora3329fa2009-11-18 00:06:18 +00003937 // Handle messages to Class. This really isn't a message to an instance
3938 // method, so we treat it the same way we would treat a message send to a
3939 // class method.
3940 if (ReceiverType->isObjCClassType() ||
3941 ReceiverType->isObjCQualifiedClassType()) {
3942 if (ObjCMethodDecl *CurMethod = getCurMethodDecl()) {
3943 if (ObjCInterfaceDecl *ClassDecl = CurMethod->getClassInterface())
Douglas Gregorc8537c52009-11-19 07:41:15 +00003944 AddObjCMethods(ClassDecl, false, MK_Any, SelIdents, NumSelIdents,
3945 CurContext, Results);
Douglas Gregora3329fa2009-11-18 00:06:18 +00003946 }
3947 }
3948 // Handle messages to a qualified ID ("id<foo>").
3949 else if (const ObjCObjectPointerType *QualID
3950 = ReceiverType->getAsObjCQualifiedIdType()) {
3951 // Search protocols for instance methods.
3952 for (ObjCObjectPointerType::qual_iterator I = QualID->qual_begin(),
3953 E = QualID->qual_end();
3954 I != E; ++I)
Douglas Gregorc8537c52009-11-19 07:41:15 +00003955 AddObjCMethods(*I, true, MK_Any, SelIdents, NumSelIdents, CurContext,
3956 Results);
Douglas Gregora3329fa2009-11-18 00:06:18 +00003957 }
3958 // Handle messages to a pointer to interface type.
3959 else if (const ObjCObjectPointerType *IFacePtr
3960 = ReceiverType->getAsObjCInterfacePointerType()) {
3961 // Search the class, its superclasses, etc., for instance methods.
Douglas Gregorc8537c52009-11-19 07:41:15 +00003962 AddObjCMethods(IFacePtr->getInterfaceDecl(), true, MK_Any, SelIdents,
3963 NumSelIdents, CurContext, Results);
Douglas Gregora3329fa2009-11-18 00:06:18 +00003964
3965 // Search protocols for instance methods.
3966 for (ObjCObjectPointerType::qual_iterator I = IFacePtr->qual_begin(),
3967 E = IFacePtr->qual_end();
3968 I != E; ++I)
Douglas Gregorc8537c52009-11-19 07:41:15 +00003969 AddObjCMethods(*I, true, MK_Any, SelIdents, NumSelIdents, CurContext,
3970 Results);
Douglas Gregora3329fa2009-11-18 00:06:18 +00003971 }
Douglas Gregor6285f752010-04-06 16:40:00 +00003972 // Handle messages to "id".
3973 else if (ReceiverType->isObjCIdType()) {
Douglas Gregord720daf2010-04-06 17:30:22 +00003974 // We're messaging "id", so provide all instance methods we know
3975 // about as code-completion results.
3976
3977 // If we have an external source, load the entire class method
Sebastian Redld44cd6a2010-08-18 23:57:06 +00003978 // pool from the AST file.
Douglas Gregord720daf2010-04-06 17:30:22 +00003979 if (ExternalSource) {
John McCall75b960e2010-06-01 09:23:16 +00003980 for (uint32_t I = 0, N = ExternalSource->GetNumExternalSelectors();
3981 I != N; ++I) {
3982 Selector Sel = ExternalSource->GetExternalSelector(I);
Sebastian Redl75d8a322010-08-02 23:18:59 +00003983 if (Sel.isNull() || MethodPool.count(Sel))
Douglas Gregord720daf2010-04-06 17:30:22 +00003984 continue;
3985
Sebastian Redl75d8a322010-08-02 23:18:59 +00003986 ReadMethodPool(Sel);
Douglas Gregord720daf2010-04-06 17:30:22 +00003987 }
3988 }
3989
Sebastian Redl75d8a322010-08-02 23:18:59 +00003990 for (GlobalMethodPool::iterator M = MethodPool.begin(),
3991 MEnd = MethodPool.end();
3992 M != MEnd; ++M) {
3993 for (ObjCMethodList *MethList = &M->second.first;
3994 MethList && MethList->Method;
Douglas Gregor6285f752010-04-06 16:40:00 +00003995 MethList = MethList->Next) {
3996 if (!isAcceptableObjCMethod(MethList->Method, MK_Any, SelIdents,
3997 NumSelIdents))
3998 continue;
3999
4000 Result R(MethList->Method, 0);
4001 R.StartParameter = NumSelIdents;
4002 R.AllParametersAreInformative = false;
4003 Results.MaybeAddResult(R, CurContext);
4004 }
4005 }
4006 }
4007
Steve Naroffeae65032009-11-07 02:08:14 +00004008 Results.ExitScope();
Douglas Gregor00c37ef2010-08-11 21:23:17 +00004009 HandleCodeCompleteResults(this, CodeCompleter,
4010 CodeCompletionContext::CCC_Other,
4011 Results.data(),Results.size());
Steve Naroffeae65032009-11-07 02:08:14 +00004012}
Douglas Gregorbaf69612009-11-18 04:19:12 +00004013
Douglas Gregor68762e72010-08-23 21:17:50 +00004014void Sema::CodeCompleteObjCForCollection(Scope *S,
4015 DeclGroupPtrTy IterationVar) {
4016 CodeCompleteExpressionData Data;
4017 Data.ObjCCollection = true;
4018
4019 if (IterationVar.getAsOpaquePtr()) {
4020 DeclGroupRef DG = IterationVar.getAsVal<DeclGroupRef>();
4021 for (DeclGroupRef::iterator I = DG.begin(), End = DG.end(); I != End; ++I) {
4022 if (*I)
4023 Data.IgnoreDecls.push_back(*I);
4024 }
4025 }
4026
4027 CodeCompleteExpression(S, Data);
4028}
4029
Douglas Gregorbaf69612009-11-18 04:19:12 +00004030/// \brief Add all of the protocol declarations that we find in the given
4031/// (translation unit) context.
4032static void AddProtocolResults(DeclContext *Ctx, DeclContext *CurContext,
Douglas Gregor5b4671c2009-11-18 04:49:41 +00004033 bool OnlyForwardDeclarations,
Douglas Gregorbaf69612009-11-18 04:19:12 +00004034 ResultBuilder &Results) {
4035 typedef CodeCompleteConsumer::Result Result;
4036
4037 for (DeclContext::decl_iterator D = Ctx->decls_begin(),
4038 DEnd = Ctx->decls_end();
4039 D != DEnd; ++D) {
4040 // Record any protocols we find.
4041 if (ObjCProtocolDecl *Proto = dyn_cast<ObjCProtocolDecl>(*D))
Douglas Gregor5b4671c2009-11-18 04:49:41 +00004042 if (!OnlyForwardDeclarations || Proto->isForwardDecl())
Douglas Gregorfc59ce12010-01-14 16:14:35 +00004043 Results.AddResult(Result(Proto, 0), CurContext, 0, false);
Douglas Gregorbaf69612009-11-18 04:19:12 +00004044
4045 // Record any forward-declared protocols we find.
4046 if (ObjCForwardProtocolDecl *Forward
4047 = dyn_cast<ObjCForwardProtocolDecl>(*D)) {
4048 for (ObjCForwardProtocolDecl::protocol_iterator
4049 P = Forward->protocol_begin(),
4050 PEnd = Forward->protocol_end();
4051 P != PEnd; ++P)
Douglas Gregor5b4671c2009-11-18 04:49:41 +00004052 if (!OnlyForwardDeclarations || (*P)->isForwardDecl())
Douglas Gregorfc59ce12010-01-14 16:14:35 +00004053 Results.AddResult(Result(*P, 0), CurContext, 0, false);
Douglas Gregorbaf69612009-11-18 04:19:12 +00004054 }
4055 }
4056}
4057
4058void Sema::CodeCompleteObjCProtocolReferences(IdentifierLocPair *Protocols,
4059 unsigned NumProtocols) {
4060 ResultBuilder Results(*this);
4061 Results.EnterNewScope();
4062
4063 // Tell the result set to ignore all of the protocols we have
4064 // already seen.
4065 for (unsigned I = 0; I != NumProtocols; ++I)
Douglas Gregorb2ccf012010-04-15 22:33:43 +00004066 if (ObjCProtocolDecl *Protocol = LookupProtocol(Protocols[I].first,
4067 Protocols[I].second))
Douglas Gregorbaf69612009-11-18 04:19:12 +00004068 Results.Ignore(Protocol);
4069
4070 // Add all protocols.
Douglas Gregor5b4671c2009-11-18 04:49:41 +00004071 AddProtocolResults(Context.getTranslationUnitDecl(), CurContext, false,
4072 Results);
4073
4074 Results.ExitScope();
Douglas Gregor00c37ef2010-08-11 21:23:17 +00004075 HandleCodeCompleteResults(this, CodeCompleter,
4076 CodeCompletionContext::CCC_ObjCProtocolName,
4077 Results.data(),Results.size());
Douglas Gregor5b4671c2009-11-18 04:49:41 +00004078}
4079
4080void Sema::CodeCompleteObjCProtocolDecl(Scope *) {
4081 ResultBuilder Results(*this);
4082 Results.EnterNewScope();
4083
4084 // Add all protocols.
4085 AddProtocolResults(Context.getTranslationUnitDecl(), CurContext, true,
4086 Results);
Douglas Gregorbaf69612009-11-18 04:19:12 +00004087
4088 Results.ExitScope();
Douglas Gregor00c37ef2010-08-11 21:23:17 +00004089 HandleCodeCompleteResults(this, CodeCompleter,
4090 CodeCompletionContext::CCC_ObjCProtocolName,
4091 Results.data(),Results.size());
Douglas Gregorbaf69612009-11-18 04:19:12 +00004092}
Douglas Gregor49c22a72009-11-18 16:26:39 +00004093
4094/// \brief Add all of the Objective-C interface declarations that we find in
4095/// the given (translation unit) context.
4096static void AddInterfaceResults(DeclContext *Ctx, DeclContext *CurContext,
4097 bool OnlyForwardDeclarations,
4098 bool OnlyUnimplemented,
4099 ResultBuilder &Results) {
4100 typedef CodeCompleteConsumer::Result Result;
4101
4102 for (DeclContext::decl_iterator D = Ctx->decls_begin(),
4103 DEnd = Ctx->decls_end();
4104 D != DEnd; ++D) {
Douglas Gregor1c283312010-08-11 12:19:30 +00004105 // Record any interfaces we find.
4106 if (ObjCInterfaceDecl *Class = dyn_cast<ObjCInterfaceDecl>(*D))
4107 if ((!OnlyForwardDeclarations || Class->isForwardDecl()) &&
4108 (!OnlyUnimplemented || !Class->getImplementation()))
4109 Results.AddResult(Result(Class, 0), CurContext, 0, false);
Douglas Gregor49c22a72009-11-18 16:26:39 +00004110
4111 // Record any forward-declared interfaces we find.
4112 if (ObjCClassDecl *Forward = dyn_cast<ObjCClassDecl>(*D)) {
4113 for (ObjCClassDecl::iterator C = Forward->begin(), CEnd = Forward->end();
Douglas Gregor1c283312010-08-11 12:19:30 +00004114 C != CEnd; ++C)
4115 if ((!OnlyForwardDeclarations || C->getInterface()->isForwardDecl()) &&
4116 (!OnlyUnimplemented || !C->getInterface()->getImplementation()))
4117 Results.AddResult(Result(C->getInterface(), 0), CurContext,
Douglas Gregorfc59ce12010-01-14 16:14:35 +00004118 0, false);
Douglas Gregor49c22a72009-11-18 16:26:39 +00004119 }
4120 }
4121}
4122
4123void Sema::CodeCompleteObjCInterfaceDecl(Scope *S) {
4124 ResultBuilder Results(*this);
4125 Results.EnterNewScope();
4126
4127 // Add all classes.
4128 AddInterfaceResults(Context.getTranslationUnitDecl(), CurContext, true,
4129 false, Results);
4130
4131 Results.ExitScope();
Douglas Gregor00c37ef2010-08-11 21:23:17 +00004132 HandleCodeCompleteResults(this, CodeCompleter,
4133 CodeCompletionContext::CCC_Other,
4134 Results.data(),Results.size());
Douglas Gregor49c22a72009-11-18 16:26:39 +00004135}
4136
Douglas Gregorb2ccf012010-04-15 22:33:43 +00004137void Sema::CodeCompleteObjCSuperclass(Scope *S, IdentifierInfo *ClassName,
4138 SourceLocation ClassNameLoc) {
Douglas Gregor49c22a72009-11-18 16:26:39 +00004139 ResultBuilder Results(*this);
4140 Results.EnterNewScope();
4141
4142 // Make sure that we ignore the class we're currently defining.
4143 NamedDecl *CurClass
Douglas Gregorb2ccf012010-04-15 22:33:43 +00004144 = LookupSingleName(TUScope, ClassName, ClassNameLoc, LookupOrdinaryName);
Douglas Gregor5d34fd32009-11-18 19:08:43 +00004145 if (CurClass && isa<ObjCInterfaceDecl>(CurClass))
Douglas Gregor49c22a72009-11-18 16:26:39 +00004146 Results.Ignore(CurClass);
4147
4148 // Add all classes.
4149 AddInterfaceResults(Context.getTranslationUnitDecl(), CurContext, false,
4150 false, Results);
4151
4152 Results.ExitScope();
Douglas Gregor00c37ef2010-08-11 21:23:17 +00004153 HandleCodeCompleteResults(this, CodeCompleter,
4154 CodeCompletionContext::CCC_Other,
4155 Results.data(),Results.size());
Douglas Gregor49c22a72009-11-18 16:26:39 +00004156}
4157
4158void Sema::CodeCompleteObjCImplementationDecl(Scope *S) {
4159 ResultBuilder Results(*this);
4160 Results.EnterNewScope();
4161
4162 // Add all unimplemented classes.
4163 AddInterfaceResults(Context.getTranslationUnitDecl(), CurContext, false,
4164 true, Results);
4165
4166 Results.ExitScope();
Douglas Gregor00c37ef2010-08-11 21:23:17 +00004167 HandleCodeCompleteResults(this, CodeCompleter,
4168 CodeCompletionContext::CCC_Other,
4169 Results.data(),Results.size());
Douglas Gregor49c22a72009-11-18 16:26:39 +00004170}
Douglas Gregor5d34fd32009-11-18 19:08:43 +00004171
4172void Sema::CodeCompleteObjCInterfaceCategory(Scope *S,
Douglas Gregorb2ccf012010-04-15 22:33:43 +00004173 IdentifierInfo *ClassName,
4174 SourceLocation ClassNameLoc) {
Douglas Gregor5d34fd32009-11-18 19:08:43 +00004175 typedef CodeCompleteConsumer::Result Result;
4176
4177 ResultBuilder Results(*this);
4178
4179 // Ignore any categories we find that have already been implemented by this
4180 // interface.
4181 llvm::SmallPtrSet<IdentifierInfo *, 16> CategoryNames;
4182 NamedDecl *CurClass
Douglas Gregorb2ccf012010-04-15 22:33:43 +00004183 = LookupSingleName(TUScope, ClassName, ClassNameLoc, LookupOrdinaryName);
Douglas Gregor5d34fd32009-11-18 19:08:43 +00004184 if (ObjCInterfaceDecl *Class = dyn_cast_or_null<ObjCInterfaceDecl>(CurClass))
4185 for (ObjCCategoryDecl *Category = Class->getCategoryList(); Category;
4186 Category = Category->getNextClassCategory())
4187 CategoryNames.insert(Category->getIdentifier());
4188
4189 // Add all of the categories we know about.
4190 Results.EnterNewScope();
4191 TranslationUnitDecl *TU = Context.getTranslationUnitDecl();
4192 for (DeclContext::decl_iterator D = TU->decls_begin(),
4193 DEnd = TU->decls_end();
4194 D != DEnd; ++D)
4195 if (ObjCCategoryDecl *Category = dyn_cast<ObjCCategoryDecl>(*D))
4196 if (CategoryNames.insert(Category->getIdentifier()))
Douglas Gregorfc59ce12010-01-14 16:14:35 +00004197 Results.AddResult(Result(Category, 0), CurContext, 0, false);
Douglas Gregor5d34fd32009-11-18 19:08:43 +00004198 Results.ExitScope();
4199
Douglas Gregor00c37ef2010-08-11 21:23:17 +00004200 HandleCodeCompleteResults(this, CodeCompleter,
4201 CodeCompletionContext::CCC_Other,
4202 Results.data(),Results.size());
Douglas Gregor5d34fd32009-11-18 19:08:43 +00004203}
4204
4205void Sema::CodeCompleteObjCImplementationCategory(Scope *S,
Douglas Gregorb2ccf012010-04-15 22:33:43 +00004206 IdentifierInfo *ClassName,
4207 SourceLocation ClassNameLoc) {
Douglas Gregor5d34fd32009-11-18 19:08:43 +00004208 typedef CodeCompleteConsumer::Result Result;
4209
4210 // Find the corresponding interface. If we couldn't find the interface, the
4211 // program itself is ill-formed. However, we'll try to be helpful still by
4212 // providing the list of all of the categories we know about.
4213 NamedDecl *CurClass
Douglas Gregorb2ccf012010-04-15 22:33:43 +00004214 = LookupSingleName(TUScope, ClassName, ClassNameLoc, LookupOrdinaryName);
Douglas Gregor5d34fd32009-11-18 19:08:43 +00004215 ObjCInterfaceDecl *Class = dyn_cast_or_null<ObjCInterfaceDecl>(CurClass);
4216 if (!Class)
Douglas Gregorb2ccf012010-04-15 22:33:43 +00004217 return CodeCompleteObjCInterfaceCategory(S, ClassName, ClassNameLoc);
Douglas Gregor5d34fd32009-11-18 19:08:43 +00004218
4219 ResultBuilder Results(*this);
4220
4221 // Add all of the categories that have have corresponding interface
4222 // declarations in this class and any of its superclasses, except for
4223 // already-implemented categories in the class itself.
4224 llvm::SmallPtrSet<IdentifierInfo *, 16> CategoryNames;
4225 Results.EnterNewScope();
4226 bool IgnoreImplemented = true;
4227 while (Class) {
4228 for (ObjCCategoryDecl *Category = Class->getCategoryList(); Category;
4229 Category = Category->getNextClassCategory())
4230 if ((!IgnoreImplemented || !Category->getImplementation()) &&
4231 CategoryNames.insert(Category->getIdentifier()))
Douglas Gregorfc59ce12010-01-14 16:14:35 +00004232 Results.AddResult(Result(Category, 0), CurContext, 0, false);
Douglas Gregor5d34fd32009-11-18 19:08:43 +00004233
4234 Class = Class->getSuperClass();
4235 IgnoreImplemented = false;
4236 }
4237 Results.ExitScope();
4238
Douglas Gregor00c37ef2010-08-11 21:23:17 +00004239 HandleCodeCompleteResults(this, CodeCompleter,
4240 CodeCompletionContext::CCC_Other,
4241 Results.data(),Results.size());
Douglas Gregor5d34fd32009-11-18 19:08:43 +00004242}
Douglas Gregor5d649882009-11-18 22:32:06 +00004243
John McCall48871652010-08-21 09:40:31 +00004244void Sema::CodeCompleteObjCPropertyDefinition(Scope *S, Decl *ObjCImpDecl) {
Douglas Gregor5d649882009-11-18 22:32:06 +00004245 typedef CodeCompleteConsumer::Result Result;
4246 ResultBuilder Results(*this);
4247
4248 // Figure out where this @synthesize lives.
4249 ObjCContainerDecl *Container
John McCall48871652010-08-21 09:40:31 +00004250 = dyn_cast_or_null<ObjCContainerDecl>(ObjCImpDecl);
Douglas Gregor5d649882009-11-18 22:32:06 +00004251 if (!Container ||
4252 (!isa<ObjCImplementationDecl>(Container) &&
4253 !isa<ObjCCategoryImplDecl>(Container)))
4254 return;
4255
4256 // Ignore any properties that have already been implemented.
4257 for (DeclContext::decl_iterator D = Container->decls_begin(),
4258 DEnd = Container->decls_end();
4259 D != DEnd; ++D)
4260 if (ObjCPropertyImplDecl *PropertyImpl = dyn_cast<ObjCPropertyImplDecl>(*D))
4261 Results.Ignore(PropertyImpl->getPropertyDecl());
4262
4263 // Add any properties that we find.
4264 Results.EnterNewScope();
4265 if (ObjCImplementationDecl *ClassImpl
4266 = dyn_cast<ObjCImplementationDecl>(Container))
4267 AddObjCProperties(ClassImpl->getClassInterface(), false, CurContext,
4268 Results);
4269 else
4270 AddObjCProperties(cast<ObjCCategoryImplDecl>(Container)->getCategoryDecl(),
4271 false, CurContext, Results);
4272 Results.ExitScope();
4273
Douglas Gregor00c37ef2010-08-11 21:23:17 +00004274 HandleCodeCompleteResults(this, CodeCompleter,
4275 CodeCompletionContext::CCC_Other,
4276 Results.data(),Results.size());
Douglas Gregor5d649882009-11-18 22:32:06 +00004277}
4278
4279void Sema::CodeCompleteObjCPropertySynthesizeIvar(Scope *S,
4280 IdentifierInfo *PropertyName,
John McCall48871652010-08-21 09:40:31 +00004281 Decl *ObjCImpDecl) {
Douglas Gregor5d649882009-11-18 22:32:06 +00004282 typedef CodeCompleteConsumer::Result Result;
4283 ResultBuilder Results(*this);
4284
4285 // Figure out where this @synthesize lives.
4286 ObjCContainerDecl *Container
John McCall48871652010-08-21 09:40:31 +00004287 = dyn_cast_or_null<ObjCContainerDecl>(ObjCImpDecl);
Douglas Gregor5d649882009-11-18 22:32:06 +00004288 if (!Container ||
4289 (!isa<ObjCImplementationDecl>(Container) &&
4290 !isa<ObjCCategoryImplDecl>(Container)))
4291 return;
4292
4293 // Figure out which interface we're looking into.
4294 ObjCInterfaceDecl *Class = 0;
4295 if (ObjCImplementationDecl *ClassImpl
4296 = dyn_cast<ObjCImplementationDecl>(Container))
4297 Class = ClassImpl->getClassInterface();
4298 else
4299 Class = cast<ObjCCategoryImplDecl>(Container)->getCategoryDecl()
4300 ->getClassInterface();
4301
4302 // Add all of the instance variables in this class and its superclasses.
4303 Results.EnterNewScope();
4304 for(; Class; Class = Class->getSuperClass()) {
4305 // FIXME: We could screen the type of each ivar for compatibility with
4306 // the property, but is that being too paternal?
4307 for (ObjCInterfaceDecl::ivar_iterator IVar = Class->ivar_begin(),
4308 IVarEnd = Class->ivar_end();
4309 IVar != IVarEnd; ++IVar)
Douglas Gregorfc59ce12010-01-14 16:14:35 +00004310 Results.AddResult(Result(*IVar, 0), CurContext, 0, false);
Douglas Gregor5d649882009-11-18 22:32:06 +00004311 }
4312 Results.ExitScope();
4313
Douglas Gregor00c37ef2010-08-11 21:23:17 +00004314 HandleCodeCompleteResults(this, CodeCompleter,
4315 CodeCompletionContext::CCC_Other,
4316 Results.data(),Results.size());
Douglas Gregor5d649882009-11-18 22:32:06 +00004317}
Douglas Gregor636a61e2010-04-07 00:21:17 +00004318
4319typedef llvm::DenseMap<Selector, ObjCMethodDecl *> KnownMethodsMap;
4320
4321/// \brief Find all of the methods that reside in the given container
4322/// (and its superclasses, protocols, etc.) that meet the given
4323/// criteria. Insert those methods into the map of known methods,
4324/// indexed by selector so they can be easily found.
4325static void FindImplementableMethods(ASTContext &Context,
4326 ObjCContainerDecl *Container,
4327 bool WantInstanceMethods,
4328 QualType ReturnType,
4329 bool IsInImplementation,
4330 KnownMethodsMap &KnownMethods) {
4331 if (ObjCInterfaceDecl *IFace = dyn_cast<ObjCInterfaceDecl>(Container)) {
4332 // Recurse into protocols.
4333 const ObjCList<ObjCProtocolDecl> &Protocols
4334 = IFace->getReferencedProtocols();
4335 for (ObjCList<ObjCProtocolDecl>::iterator I = Protocols.begin(),
4336 E = Protocols.end();
4337 I != E; ++I)
4338 FindImplementableMethods(Context, *I, WantInstanceMethods, ReturnType,
4339 IsInImplementation, KnownMethods);
4340
4341 // If we're not in the implementation of a class, also visit the
4342 // superclass.
4343 if (!IsInImplementation && IFace->getSuperClass())
4344 FindImplementableMethods(Context, IFace->getSuperClass(),
4345 WantInstanceMethods, ReturnType,
4346 IsInImplementation, KnownMethods);
4347
4348 // Add methods from any class extensions (but not from categories;
4349 // those should go into category implementations).
Fariborz Jahanian3bf0ded2010-06-22 23:20:40 +00004350 for (const ObjCCategoryDecl *Cat = IFace->getFirstClassExtension(); Cat;
4351 Cat = Cat->getNextClassExtension())
4352 FindImplementableMethods(Context, const_cast<ObjCCategoryDecl*>(Cat),
4353 WantInstanceMethods, ReturnType,
Douglas Gregor636a61e2010-04-07 00:21:17 +00004354 IsInImplementation, KnownMethods);
Douglas Gregor636a61e2010-04-07 00:21:17 +00004355 }
4356
4357 if (ObjCCategoryDecl *Category = dyn_cast<ObjCCategoryDecl>(Container)) {
4358 // Recurse into protocols.
4359 const ObjCList<ObjCProtocolDecl> &Protocols
4360 = Category->getReferencedProtocols();
4361 for (ObjCList<ObjCProtocolDecl>::iterator I = Protocols.begin(),
4362 E = Protocols.end();
4363 I != E; ++I)
4364 FindImplementableMethods(Context, *I, WantInstanceMethods, ReturnType,
4365 IsInImplementation, KnownMethods);
4366 }
4367
4368 if (ObjCProtocolDecl *Protocol = dyn_cast<ObjCProtocolDecl>(Container)) {
4369 // Recurse into protocols.
4370 const ObjCList<ObjCProtocolDecl> &Protocols
4371 = Protocol->getReferencedProtocols();
4372 for (ObjCList<ObjCProtocolDecl>::iterator I = Protocols.begin(),
4373 E = Protocols.end();
4374 I != E; ++I)
4375 FindImplementableMethods(Context, *I, WantInstanceMethods, ReturnType,
4376 IsInImplementation, KnownMethods);
4377 }
4378
4379 // Add methods in this container. This operation occurs last because
4380 // we want the methods from this container to override any methods
4381 // we've previously seen with the same selector.
4382 for (ObjCContainerDecl::method_iterator M = Container->meth_begin(),
4383 MEnd = Container->meth_end();
4384 M != MEnd; ++M) {
4385 if ((*M)->isInstanceMethod() == WantInstanceMethods) {
4386 if (!ReturnType.isNull() &&
4387 !Context.hasSameUnqualifiedType(ReturnType, (*M)->getResultType()))
4388 continue;
4389
4390 KnownMethods[(*M)->getSelector()] = *M;
4391 }
4392 }
4393}
4394
4395void Sema::CodeCompleteObjCMethodDecl(Scope *S,
4396 bool IsInstanceMethod,
John McCallba7bf592010-08-24 05:47:05 +00004397 ParsedType ReturnTy,
John McCall48871652010-08-21 09:40:31 +00004398 Decl *IDecl) {
Douglas Gregor636a61e2010-04-07 00:21:17 +00004399 // Determine the return type of the method we're declaring, if
4400 // provided.
4401 QualType ReturnType = GetTypeFromParser(ReturnTy);
4402
4403 // Determine where we should start searching for methods, and where we
4404 ObjCContainerDecl *SearchDecl = 0, *CurrentDecl = 0;
4405 bool IsInImplementation = false;
John McCall48871652010-08-21 09:40:31 +00004406 if (Decl *D = IDecl) {
Douglas Gregor636a61e2010-04-07 00:21:17 +00004407 if (ObjCImplementationDecl *Impl = dyn_cast<ObjCImplementationDecl>(D)) {
4408 SearchDecl = Impl->getClassInterface();
4409 CurrentDecl = Impl;
4410 IsInImplementation = true;
4411 } else if (ObjCCategoryImplDecl *CatImpl
4412 = dyn_cast<ObjCCategoryImplDecl>(D)) {
4413 SearchDecl = CatImpl->getCategoryDecl();
4414 CurrentDecl = CatImpl;
4415 IsInImplementation = true;
4416 } else {
4417 SearchDecl = dyn_cast<ObjCContainerDecl>(D);
4418 CurrentDecl = SearchDecl;
4419 }
4420 }
4421
4422 if (!SearchDecl && S) {
4423 if (DeclContext *DC = static_cast<DeclContext *>(S->getEntity())) {
4424 SearchDecl = dyn_cast<ObjCContainerDecl>(DC);
4425 CurrentDecl = SearchDecl;
4426 }
4427 }
4428
4429 if (!SearchDecl || !CurrentDecl) {
Douglas Gregor00c37ef2010-08-11 21:23:17 +00004430 HandleCodeCompleteResults(this, CodeCompleter,
4431 CodeCompletionContext::CCC_Other,
4432 0, 0);
Douglas Gregor636a61e2010-04-07 00:21:17 +00004433 return;
4434 }
4435
4436 // Find all of the methods that we could declare/implement here.
4437 KnownMethodsMap KnownMethods;
4438 FindImplementableMethods(Context, SearchDecl, IsInstanceMethod,
4439 ReturnType, IsInImplementation, KnownMethods);
4440
4441 // Erase any methods that have already been declared or
4442 // implemented here.
4443 for (ObjCContainerDecl::method_iterator M = CurrentDecl->meth_begin(),
4444 MEnd = CurrentDecl->meth_end();
4445 M != MEnd; ++M) {
4446 if ((*M)->isInstanceMethod() != IsInstanceMethod)
4447 continue;
4448
4449 KnownMethodsMap::iterator Pos = KnownMethods.find((*M)->getSelector());
4450 if (Pos != KnownMethods.end())
4451 KnownMethods.erase(Pos);
4452 }
4453
4454 // Add declarations or definitions for each of the known methods.
4455 typedef CodeCompleteConsumer::Result Result;
4456 ResultBuilder Results(*this);
4457 Results.EnterNewScope();
4458 PrintingPolicy Policy(Context.PrintingPolicy);
4459 Policy.AnonymousTagLocations = false;
4460 for (KnownMethodsMap::iterator M = KnownMethods.begin(),
4461 MEnd = KnownMethods.end();
4462 M != MEnd; ++M) {
4463 ObjCMethodDecl *Method = M->second;
4464 CodeCompletionString *Pattern = new CodeCompletionString;
4465
4466 // If the result type was not already provided, add it to the
4467 // pattern as (type).
4468 if (ReturnType.isNull()) {
4469 std::string TypeStr;
4470 Method->getResultType().getAsStringInternal(TypeStr, Policy);
4471 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
4472 Pattern->AddTextChunk(TypeStr);
4473 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
4474 }
4475
4476 Selector Sel = Method->getSelector();
4477
4478 // Add the first part of the selector to the pattern.
4479 Pattern->AddTypedTextChunk(Sel.getIdentifierInfoForSlot(0)->getName());
4480
4481 // Add parameters to the pattern.
4482 unsigned I = 0;
4483 for (ObjCMethodDecl::param_iterator P = Method->param_begin(),
4484 PEnd = Method->param_end();
4485 P != PEnd; (void)++P, ++I) {
4486 // Add the part of the selector name.
4487 if (I == 0)
4488 Pattern->AddChunk(CodeCompletionString::CK_Colon);
4489 else if (I < Sel.getNumArgs()) {
4490 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
Douglas Gregorb0ce9b72010-08-17 15:53:35 +00004491 Pattern->AddTextChunk(Sel.getIdentifierInfoForSlot(I)->getName());
Douglas Gregor636a61e2010-04-07 00:21:17 +00004492 Pattern->AddChunk(CodeCompletionString::CK_Colon);
4493 } else
4494 break;
4495
4496 // Add the parameter type.
4497 std::string TypeStr;
4498 (*P)->getOriginalType().getAsStringInternal(TypeStr, Policy);
4499 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
4500 Pattern->AddTextChunk(TypeStr);
4501 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
4502
4503 if (IdentifierInfo *Id = (*P)->getIdentifier())
4504 Pattern->AddTextChunk(Id->getName());
4505 }
4506
4507 if (Method->isVariadic()) {
4508 if (Method->param_size() > 0)
4509 Pattern->AddChunk(CodeCompletionString::CK_Comma);
4510 Pattern->AddTextChunk("...");
4511 }
4512
Douglas Gregord37c59d2010-05-28 00:57:46 +00004513 if (IsInImplementation && Results.includeCodePatterns()) {
Douglas Gregor636a61e2010-04-07 00:21:17 +00004514 // We will be defining the method here, so add a compound statement.
4515 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
4516 Pattern->AddChunk(CodeCompletionString::CK_LeftBrace);
4517 Pattern->AddChunk(CodeCompletionString::CK_VerticalSpace);
4518 if (!Method->getResultType()->isVoidType()) {
4519 // If the result type is not void, add a return clause.
4520 Pattern->AddTextChunk("return");
4521 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
4522 Pattern->AddPlaceholderChunk("expression");
4523 Pattern->AddChunk(CodeCompletionString::CK_SemiColon);
4524 } else
4525 Pattern->AddPlaceholderChunk("statements");
4526
4527 Pattern->AddChunk(CodeCompletionString::CK_VerticalSpace);
4528 Pattern->AddChunk(CodeCompletionString::CK_RightBrace);
4529 }
4530
Douglas Gregor7116a8c2010-08-17 16:06:07 +00004531 Results.AddResult(Result(Pattern, CCP_CodePattern,
4532 Method->isInstanceMethod()
4533 ? CXCursor_ObjCInstanceMethodDecl
4534 : CXCursor_ObjCClassMethodDecl));
Douglas Gregor636a61e2010-04-07 00:21:17 +00004535 }
4536
4537 Results.ExitScope();
4538
Douglas Gregor00c37ef2010-08-11 21:23:17 +00004539 HandleCodeCompleteResults(this, CodeCompleter,
4540 CodeCompletionContext::CCC_Other,
4541 Results.data(),Results.size());
Douglas Gregor636a61e2010-04-07 00:21:17 +00004542}
Douglas Gregor95887f92010-07-08 23:20:03 +00004543
4544void Sema::CodeCompleteObjCMethodDeclSelector(Scope *S,
4545 bool IsInstanceMethod,
Douglas Gregor45879692010-07-08 23:37:41 +00004546 bool AtParameterName,
John McCallba7bf592010-08-24 05:47:05 +00004547 ParsedType ReturnTy,
Douglas Gregor95887f92010-07-08 23:20:03 +00004548 IdentifierInfo **SelIdents,
4549 unsigned NumSelIdents) {
Douglas Gregor95887f92010-07-08 23:20:03 +00004550 // If we have an external source, load the entire class method
Sebastian Redld44cd6a2010-08-18 23:57:06 +00004551 // pool from the AST file.
Douglas Gregor95887f92010-07-08 23:20:03 +00004552 if (ExternalSource) {
4553 for (uint32_t I = 0, N = ExternalSource->GetNumExternalSelectors();
4554 I != N; ++I) {
4555 Selector Sel = ExternalSource->GetExternalSelector(I);
Sebastian Redl75d8a322010-08-02 23:18:59 +00004556 if (Sel.isNull() || MethodPool.count(Sel))
Douglas Gregor95887f92010-07-08 23:20:03 +00004557 continue;
Sebastian Redl75d8a322010-08-02 23:18:59 +00004558
4559 ReadMethodPool(Sel);
Douglas Gregor95887f92010-07-08 23:20:03 +00004560 }
4561 }
4562
4563 // Build the set of methods we can see.
4564 typedef CodeCompleteConsumer::Result Result;
4565 ResultBuilder Results(*this);
4566
4567 if (ReturnTy)
4568 Results.setPreferredType(GetTypeFromParser(ReturnTy).getNonReferenceType());
Sebastian Redl75d8a322010-08-02 23:18:59 +00004569
Douglas Gregor95887f92010-07-08 23:20:03 +00004570 Results.EnterNewScope();
Sebastian Redl75d8a322010-08-02 23:18:59 +00004571 for (GlobalMethodPool::iterator M = MethodPool.begin(),
4572 MEnd = MethodPool.end();
4573 M != MEnd; ++M) {
4574 for (ObjCMethodList *MethList = IsInstanceMethod ? &M->second.first :
4575 &M->second.second;
4576 MethList && MethList->Method;
Douglas Gregor95887f92010-07-08 23:20:03 +00004577 MethList = MethList->Next) {
4578 if (!isAcceptableObjCMethod(MethList->Method, MK_Any, SelIdents,
4579 NumSelIdents))
4580 continue;
4581
Douglas Gregor45879692010-07-08 23:37:41 +00004582 if (AtParameterName) {
4583 // Suggest parameter names we've seen before.
4584 if (NumSelIdents && NumSelIdents <= MethList->Method->param_size()) {
4585 ParmVarDecl *Param = MethList->Method->param_begin()[NumSelIdents-1];
4586 if (Param->getIdentifier()) {
4587 CodeCompletionString *Pattern = new CodeCompletionString;
4588 Pattern->AddTypedTextChunk(Param->getIdentifier()->getName());
4589 Results.AddResult(Pattern);
4590 }
4591 }
4592
4593 continue;
4594 }
4595
Douglas Gregor95887f92010-07-08 23:20:03 +00004596 Result R(MethList->Method, 0);
4597 R.StartParameter = NumSelIdents;
4598 R.AllParametersAreInformative = false;
4599 R.DeclaringEntity = true;
4600 Results.MaybeAddResult(R, CurContext);
4601 }
4602 }
4603
4604 Results.ExitScope();
Douglas Gregor00c37ef2010-08-11 21:23:17 +00004605 HandleCodeCompleteResults(this, CodeCompleter,
4606 CodeCompletionContext::CCC_Other,
4607 Results.data(),Results.size());
Douglas Gregor95887f92010-07-08 23:20:03 +00004608}
Douglas Gregorb14904c2010-08-13 22:48:40 +00004609
Douglas Gregor3a7ad252010-08-24 19:08:16 +00004610void Sema::CodeCompletePreprocessorDirective(Scope *S, bool InConditional) {
4611 ResultBuilder Results(*this);
4612 Results.EnterNewScope();
4613
4614 // #if <condition>
4615 CodeCompletionString *Pattern = new CodeCompletionString;
4616 Pattern->AddTypedTextChunk("if");
4617 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
4618 Pattern->AddPlaceholderChunk("condition");
4619 Results.AddResult(Pattern);
4620
4621 // #ifdef <macro>
4622 Pattern = new CodeCompletionString;
4623 Pattern->AddTypedTextChunk("ifdef");
4624 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
4625 Pattern->AddPlaceholderChunk("macro");
4626 Results.AddResult(Pattern);
4627
4628 // #ifndef <macro>
4629 Pattern = new CodeCompletionString;
4630 Pattern->AddTypedTextChunk("ifndef");
4631 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
4632 Pattern->AddPlaceholderChunk("macro");
4633 Results.AddResult(Pattern);
4634
4635 if (InConditional) {
4636 // #elif <condition>
4637 Pattern = new CodeCompletionString;
4638 Pattern->AddTypedTextChunk("elif");
4639 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
4640 Pattern->AddPlaceholderChunk("condition");
4641 Results.AddResult(Pattern);
4642
4643 // #else
4644 Pattern = new CodeCompletionString;
4645 Pattern->AddTypedTextChunk("else");
4646 Results.AddResult(Pattern);
4647
4648 // #endif
4649 Pattern = new CodeCompletionString;
4650 Pattern->AddTypedTextChunk("endif");
4651 Results.AddResult(Pattern);
4652 }
4653
4654 // #include "header"
4655 Pattern = new CodeCompletionString;
4656 Pattern->AddTypedTextChunk("include");
4657 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
4658 Pattern->AddTextChunk("\"");
4659 Pattern->AddPlaceholderChunk("header");
4660 Pattern->AddTextChunk("\"");
4661 Results.AddResult(Pattern);
4662
4663 // #include <header>
4664 Pattern = new CodeCompletionString;
4665 Pattern->AddTypedTextChunk("include");
4666 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
4667 Pattern->AddTextChunk("<");
4668 Pattern->AddPlaceholderChunk("header");
4669 Pattern->AddTextChunk(">");
4670 Results.AddResult(Pattern);
4671
4672 // #define <macro>
4673 Pattern = new CodeCompletionString;
4674 Pattern->AddTypedTextChunk("define");
4675 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
4676 Pattern->AddPlaceholderChunk("macro");
4677 Results.AddResult(Pattern);
4678
4679 // #define <macro>(<args>)
4680 Pattern = new CodeCompletionString;
4681 Pattern->AddTypedTextChunk("define");
4682 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
4683 Pattern->AddPlaceholderChunk("macro");
4684 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
4685 Pattern->AddPlaceholderChunk("args");
4686 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
4687 Results.AddResult(Pattern);
4688
4689 // #undef <macro>
4690 Pattern = new CodeCompletionString;
4691 Pattern->AddTypedTextChunk("undef");
4692 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
4693 Pattern->AddPlaceholderChunk("macro");
4694 Results.AddResult(Pattern);
4695
4696 // #line <number>
4697 Pattern = new CodeCompletionString;
4698 Pattern->AddTypedTextChunk("line");
4699 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
4700 Pattern->AddPlaceholderChunk("number");
4701 Results.AddResult(Pattern);
4702
4703 // #line <number> "filename"
4704 Pattern = new CodeCompletionString;
4705 Pattern->AddTypedTextChunk("line");
4706 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
4707 Pattern->AddPlaceholderChunk("number");
4708 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
4709 Pattern->AddTextChunk("\"");
4710 Pattern->AddPlaceholderChunk("filename");
4711 Pattern->AddTextChunk("\"");
4712 Results.AddResult(Pattern);
4713
4714 // #error <message>
4715 Pattern = new CodeCompletionString;
4716 Pattern->AddTypedTextChunk("error");
4717 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
4718 Pattern->AddPlaceholderChunk("message");
4719 Results.AddResult(Pattern);
4720
4721 // #pragma <arguments>
4722 Pattern = new CodeCompletionString;
4723 Pattern->AddTypedTextChunk("pragma");
4724 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
4725 Pattern->AddPlaceholderChunk("arguments");
4726 Results.AddResult(Pattern);
4727
4728 if (getLangOptions().ObjC1) {
4729 // #import "header"
4730 Pattern = new CodeCompletionString;
4731 Pattern->AddTypedTextChunk("import");
4732 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
4733 Pattern->AddTextChunk("\"");
4734 Pattern->AddPlaceholderChunk("header");
4735 Pattern->AddTextChunk("\"");
4736 Results.AddResult(Pattern);
4737
4738 // #import <header>
4739 Pattern = new CodeCompletionString;
4740 Pattern->AddTypedTextChunk("import");
4741 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
4742 Pattern->AddTextChunk("<");
4743 Pattern->AddPlaceholderChunk("header");
4744 Pattern->AddTextChunk(">");
4745 Results.AddResult(Pattern);
4746 }
4747
4748 // #include_next "header"
4749 Pattern = new CodeCompletionString;
4750 Pattern->AddTypedTextChunk("include_next");
4751 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
4752 Pattern->AddTextChunk("\"");
4753 Pattern->AddPlaceholderChunk("header");
4754 Pattern->AddTextChunk("\"");
4755 Results.AddResult(Pattern);
4756
4757 // #include_next <header>
4758 Pattern = new CodeCompletionString;
4759 Pattern->AddTypedTextChunk("include_next");
4760 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
4761 Pattern->AddTextChunk("<");
4762 Pattern->AddPlaceholderChunk("header");
4763 Pattern->AddTextChunk(">");
4764 Results.AddResult(Pattern);
4765
4766 // #warning <message>
4767 Pattern = new CodeCompletionString;
4768 Pattern->AddTypedTextChunk("warning");
4769 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
4770 Pattern->AddPlaceholderChunk("message");
4771 Results.AddResult(Pattern);
4772
4773 // Note: #ident and #sccs are such crazy anachronisms that we don't provide
4774 // completions for them. And __include_macros is a Clang-internal extension
4775 // that we don't want to encourage anyone to use.
4776
4777 // FIXME: we don't support #assert or #unassert, so don't suggest them.
4778 Results.ExitScope();
4779
4780 // FIXME: Create a new code-completion context for this?
4781 HandleCodeCompleteResults(this, CodeCompleter,
4782 CodeCompletionContext::CCC_Other,
4783 Results.data(), Results.size());
4784}
4785
4786void Sema::CodeCompleteInPreprocessorConditionalExclusion(Scope *S) {
4787 CodeCompleteOrdinaryName(S, Action::PCC_RecoveryInFunction);
4788}
4789
Douglas Gregorb14904c2010-08-13 22:48:40 +00004790void Sema::GatherGlobalCodeCompletions(
4791 llvm::SmallVectorImpl<CodeCompleteConsumer::Result> &Results) {
4792 ResultBuilder Builder(*this);
4793
Douglas Gregor39982192010-08-15 06:18:01 +00004794 if (!CodeCompleter || CodeCompleter->includeGlobals()) {
4795 CodeCompletionDeclConsumer Consumer(Builder,
4796 Context.getTranslationUnitDecl());
4797 LookupVisibleDecls(Context.getTranslationUnitDecl(), LookupAnyName,
4798 Consumer);
4799 }
Douglas Gregorb14904c2010-08-13 22:48:40 +00004800
4801 if (!CodeCompleter || CodeCompleter->includeMacros())
4802 AddMacroResults(PP, Builder);
4803
4804 Results.clear();
4805 Results.insert(Results.end(),
4806 Builder.data(), Builder.data() + Builder.size());
4807}