blob: ee100e496b274fd6c83dc22f7d7c941c17262b86 [file] [log] [blame]
Douglas Gregor81b747b2009-09-17 21:32:03 +00001//===---------------- SemaCodeComplete.cpp - Code Completion ----*- C++ -*-===//
2//
3// The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9//
10// This file defines the code-completion semantic actions.
11//
12//===----------------------------------------------------------------------===//
Douglas Gregore737f502010-08-12 20:07:10 +000013#include "clang/Sema/Sema.h"
14#include "clang/Sema/Lookup.h"
Douglas Gregor81b747b2009-09-17 21:32:03 +000015#include "clang/Sema/CodeCompleteConsumer.h"
Douglas Gregor719770d2010-04-06 17:30:22 +000016#include "clang/Sema/ExternalSemaSource.h"
John McCall5f1e0942010-08-24 08:50:51 +000017#include "clang/Sema/Scope.h"
John McCall7cd088e2010-08-24 07:21:54 +000018#include "clang/AST/DeclObjC.h"
Douglas Gregorb9d0ef72009-09-21 19:57:38 +000019#include "clang/AST/ExprCXX.h"
Douglas Gregor24a069f2009-11-17 17:59:40 +000020#include "clang/AST/ExprObjC.h"
Douglas Gregor3f7c7f42009-10-30 16:50:04 +000021#include "clang/Lex/MacroInfo.h"
22#include "clang/Lex/Preprocessor.h"
Douglas Gregor86d9a522009-09-21 16:56:56 +000023#include "llvm/ADT/SmallPtrSet.h"
Douglas Gregor6a684032009-09-28 03:51:44 +000024#include "llvm/ADT/StringExtras.h"
Douglas Gregor22f56992010-04-06 19:22:33 +000025#include "llvm/ADT/StringSwitch.h"
Douglas Gregor86d9a522009-09-21 16:56:56 +000026#include <list>
27#include <map>
28#include <vector>
Douglas Gregor81b747b2009-09-17 21:32:03 +000029
30using namespace clang;
31
Douglas Gregor86d9a522009-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 Gregorfbcb5d62009-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 Gregor86d9a522009-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 Gregorfbcb5d62009-12-06 20:23:50 +0000110 typedef llvm::DenseMap<DeclarationName, ShadowMapEntry> ShadowMap;
Douglas Gregor86d9a522009-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 Gregor45bcd432010-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 Gregor5ac3bdb2010-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 Gregor86d9a522009-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 Gregor1f5537a2010-07-08 23:20:03 +0000135 void AdjustResultPriorityForPreferredType(Result &R);
136
Douglas Gregor86d9a522009-09-21 16:56:56 +0000137 public:
138 explicit ResultBuilder(Sema &SemaRef, LookupFilter Filter = 0)
Douglas Gregor45bcd432010-01-14 03:21:49 +0000139 : SemaRef(SemaRef), Filter(Filter), AllowNestedNameSpecifiers(false) { }
Douglas Gregor86d9a522009-09-21 16:56:56 +0000140
Douglas Gregord8e8a582010-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 Gregor86d9a522009-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 Gregor5ac3bdb2010-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 Gregor45bcd432010-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 Gregore495b7f2010-01-14 00:20:49 +0000171 /// \brief Determine whether the given declaration is at all interesting
172 /// as a code-completion result.
Douglas Gregor45bcd432010-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 Gregor6660d842010-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 Gregor86d9a522009-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 Gregor456c4a12009-09-21 20:12:40 +0000192 ///
Douglas Gregor1ca6ae82010-01-14 01:09:38 +0000193 /// \param CurContext the result to add (if it is unique).
Douglas Gregor456c4a12009-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 Gregor86d9a522009-09-21 16:56:56 +0000197
Douglas Gregor1ca6ae82010-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 Gregor0cc84042010-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 Gregor1ca6ae82010-01-14 01:09:38 +0000211
Douglas Gregora4477812010-01-14 16:01:26 +0000212 /// \brief Add a new non-declaration result to this result set.
213 void AddResult(Result R);
214
Douglas Gregor86d9a522009-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 Gregor55385fe2009-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 Gregor86d9a522009-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 Gregor791215b2009-09-21 20:51:25 +0000230 bool IsOrdinaryName(NamedDecl *ND) const;
Douglas Gregor4710e5b2010-05-28 00:49:12 +0000231 bool IsOrdinaryNonTypeName(NamedDecl *ND) const;
Douglas Gregorf9578432010-07-28 21:50:18 +0000232 bool IsIntegralConstantValue(NamedDecl *ND) const;
Douglas Gregor01dfea02010-01-10 23:08:15 +0000233 bool IsOrdinaryNonValueName(NamedDecl *ND) const;
Douglas Gregor86d9a522009-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 Gregoreb5758b2009-09-23 22:26:46 +0000241 bool IsMember(NamedDecl *ND) const;
Douglas Gregor80f4f4c2010-01-14 16:08:12 +0000242 bool IsObjCIvar(NamedDecl *ND) const;
Douglas Gregor8e254cf2010-05-27 23:06:34 +0000243 bool IsObjCMessageReceiver(NamedDecl *ND) const;
Douglas Gregorfb629412010-08-23 21:17:50 +0000244 bool IsObjCCollection(NamedDecl *ND) const;
Douglas Gregor86d9a522009-09-21 16:56:56 +0000245 //@}
246 };
247}
248
Douglas Gregorfbcb5d62009-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 Gregord490f952009-12-06 21:27:58 +0000301 return *DeclOrIterator.get<const DeclIndexPair*>();
Douglas Gregorfbcb5d62009-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 Gregord490f952009-12-06 21:27:58 +0000309 return X.DeclOrIterator.getOpaqueValue()
310 == Y.DeclOrIterator.getOpaqueValue() &&
Douglas Gregorfbcb5d62009-12-06 20:23:50 +0000311 X.SingleDeclIndex == Y.SingleDeclIndex;
312 }
313
314 friend bool operator!=(const iterator &X, const iterator &Y) {
Douglas Gregord490f952009-12-06 21:27:58 +0000315 return !(X == Y);
Douglas Gregorfbcb5d62009-12-06 20:23:50 +0000316 }
317};
318
Douglas Gregorfbcb5d62009-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 Gregor456c4a12009-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 Gregorfb629412010-08-23 21:17:50 +0000372 if (NamespaceDecl *Namespace = dyn_cast<NamespaceDecl>(Parent)) {
373 if (!Namespace->getIdentifier())
374 continue;
375
Douglas Gregor456c4a12009-09-21 20:12:40 +0000376 Result = NestedNameSpecifier::Create(Context, Result, Namespace);
Douglas Gregorfb629412010-08-23 21:17:50 +0000377 }
Douglas Gregor456c4a12009-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 Gregor0c8296d2009-11-07 00:00:49 +0000382 }
Douglas Gregor456c4a12009-09-21 20:12:40 +0000383 return Result;
384}
385
Douglas Gregor45bcd432010-01-14 03:21:49 +0000386bool ResultBuilder::isInterestingDecl(NamedDecl *ND,
387 bool &AsNestedNameSpecifier) const {
388 AsNestedNameSpecifier = false;
389
Douglas Gregore495b7f2010-01-14 00:20:49 +0000390 ND = ND->getUnderlyingDecl();
391 unsigned IDNS = ND->getIdentifierNamespace();
Douglas Gregorf52cede2009-10-09 22:16:47 +0000392
393 // Skip unnamed entities.
Douglas Gregore495b7f2010-01-14 00:20:49 +0000394 if (!ND->getDeclName())
395 return false;
Douglas Gregor86d9a522009-09-21 16:56:56 +0000396
397 // Friend declarations and declarations introduced due to friends are never
398 // added as results.
John McCall92b7f702010-03-11 07:50:04 +0000399 if (IDNS & (Decl::IDNS_OrdinaryFriend | Decl::IDNS_TagFriend))
Douglas Gregore495b7f2010-01-14 00:20:49 +0000400 return false;
401
Douglas Gregor76282942009-12-11 17:31:05 +0000402 // Class template (partial) specializations are never added as results.
Douglas Gregore495b7f2010-01-14 00:20:49 +0000403 if (isa<ClassTemplateSpecializationDecl>(ND) ||
404 isa<ClassTemplatePartialSpecializationDecl>(ND))
405 return false;
Douglas Gregor86d9a522009-09-21 16:56:56 +0000406
Douglas Gregor76282942009-12-11 17:31:05 +0000407 // Using declarations themselves are never added as results.
Douglas Gregore495b7f2010-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 Gregor86d9a522009-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 Gregore495b7f2010-01-14 00:20:49 +0000415 return false;
Douglas Gregor86d9a522009-09-21 16:56:56 +0000416
Douglas Gregorf52cede2009-10-09 22:16:47 +0000417 // Filter out names reserved for the implementation (C99 7.1.3,
Douglas Gregor797efb52010-07-14 17:44:04 +0000418 // C++ [lib.global.names]) if they come from a system header.
Daniel Dunbare013d682009-10-18 20:26:12 +0000419 //
420 // FIXME: Add predicate for this.
Douglas Gregorf52cede2009-10-09 22:16:47 +0000421 if (Id->getLength() >= 2) {
Daniel Dunbare013d682009-10-18 20:26:12 +0000422 const char *Name = Id->getNameStart();
Douglas Gregorf52cede2009-10-09 22:16:47 +0000423 if (Name[0] == '_' &&
Douglas Gregor797efb52010-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 Gregore495b7f2010-01-14 00:20:49 +0000428 return false;
Douglas Gregorf52cede2009-10-09 22:16:47 +0000429 }
Douglas Gregor86d9a522009-09-21 16:56:56 +0000430 }
Douglas Gregore495b7f2010-01-14 00:20:49 +0000431
Douglas Gregor86d9a522009-09-21 16:56:56 +0000432 // C++ constructors are never found by name lookup.
Douglas Gregore495b7f2010-01-14 00:20:49 +0000433 if (isa<CXXConstructorDecl>(ND))
434 return false;
Douglas Gregor86d9a522009-09-21 16:56:56 +0000435
Douglas Gregora5fb7c32010-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 Gregor86d9a522009-09-21 16:56:56 +0000442 // Filter out any unwanted results.
Douglas Gregor45bcd432010-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 Gregore495b7f2010-01-14 00:20:49 +0000454 return false;
Douglas Gregora5fb7c32010-08-16 23:05:20 +0000455 }
Douglas Gregore495b7f2010-01-14 00:20:49 +0000456 // ... then it must be interesting!
457 return true;
458}
459
Douglas Gregor6660d842010-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 Gregor1f5537a2010-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 Gregor1827e102010-08-16 16:18:59 +0000490SimplifiedTypeClass clang::getSimplifiedTypeClass(CanQualType T) {
Douglas Gregor1f5537a2010-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 Gregor1827e102010-08-16 16:18:59 +0000561QualType clang::getDeclUsageType(ASTContext &C, NamedDecl *ND) {
Douglas Gregor1f5537a2010-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 Gregor5291c3c2010-07-13 08:18:22 +0000571 T = Function->getCallResultType();
Douglas Gregor1f5537a2010-07-08 23:20:03 +0000572 else if (ObjCMethodDecl *Method = dyn_cast<ObjCMethodDecl>(ND))
Douglas Gregor5291c3c2010-07-13 08:18:22 +0000573 T = Method->getSendResultType();
Douglas Gregor1f5537a2010-07-08 23:20:03 +0000574 else if (FunctionTemplateDecl *FunTmpl = dyn_cast<FunctionTemplateDecl>(ND))
Douglas Gregor5291c3c2010-07-13 08:18:22 +0000575 T = FunTmpl->getTemplatedDecl()->getCallResultType();
Douglas Gregor1f5537a2010-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 Gregore495b7f2010-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 Gregor45bcd432010-01-14 03:21:49 +0000622 bool AsNestedNameSpecifier = false;
623 if (!isInterestingDecl(R.Declaration, AsNestedNameSpecifier))
Douglas Gregore495b7f2010-01-14 00:20:49 +0000624 return;
625
Douglas Gregor86d9a522009-09-21 16:56:56 +0000626 ShadowMap &SMap = ShadowMaps.back();
Douglas Gregorfbcb5d62009-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 Gregor86d9a522009-09-21 16:56:56 +0000637 if (ND->getCanonicalDecl() == CanonDecl) {
638 // This is a redeclaration. Always pick the newer declaration.
Douglas Gregor86d9a522009-09-21 16:56:56 +0000639 Results[Index].Declaration = R.Declaration;
640
Douglas Gregor86d9a522009-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 Gregorfbcb5d62009-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 Gregor86d9a522009-09-21 16:56:56 +0000659 // A tag declaration does not hide a non-tag declaration.
John McCall0d6b1642010-04-23 18:46:30 +0000660 if (I->first->hasTagIdentifierNamespace() &&
Douglas Gregor86d9a522009-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 Gregorfbcb5d62009-12-06 20:23:50 +0000666 if (((I->first->getIdentifierNamespace() & Decl::IDNS_ObjCProtocol)
Douglas Gregor86d9a522009-09-21 16:56:56 +0000667 || (IDNS & Decl::IDNS_ObjCProtocol)) &&
Douglas Gregorfbcb5d62009-12-06 20:23:50 +0000668 I->first->getIdentifierNamespace() != IDNS)
Douglas Gregor86d9a522009-09-21 16:56:56 +0000669 continue;
670
671 // The newly-added result is hidden by an entry in the shadow map.
Douglas Gregor6660d842010-01-14 00:41:07 +0000672 if (CheckHiddenResult(R, CurContext, I->first))
Douglas Gregor86d9a522009-09-21 16:56:56 +0000673 return;
Douglas Gregor86d9a522009-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 Gregoreb5758b2009-09-23 22:26:46 +0000683 // If the filter is for nested-name-specifiers, then this result starts a
684 // nested-name-specifier.
Douglas Gregor12e13132010-05-26 22:00:08 +0000685 if (AsNestedNameSpecifier) {
Douglas Gregoreb5758b2009-09-23 22:26:46 +0000686 R.StartsNestedNameSpecifier = true;
Douglas Gregor12e13132010-05-26 22:00:08 +0000687 R.Priority = CCP_NestedNameSpecifier;
Douglas Gregor1f5537a2010-07-08 23:20:03 +0000688 } else if (!PreferredType.isNull())
689 AdjustResultPriorityForPreferredType(R);
690
Douglas Gregor0563c262009-09-22 23:15:58 +0000691 // If this result is supposed to have an informative qualifier, add one.
Douglas Gregoreb5758b2009-09-23 22:26:46 +0000692 if (R.QualifierIsInformative && !R.Qualifier &&
693 !R.StartsNestedNameSpecifier) {
Douglas Gregor0563c262009-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 Gregoreb5758b2009-09-23 22:26:46 +0000703
Douglas Gregor86d9a522009-09-21 16:56:56 +0000704 // Insert this result into the set of results and into the current shadow
705 // map.
Douglas Gregorfbcb5d62009-12-06 20:23:50 +0000706 SMap[R.Declaration->getDeclName()].Add(R.Declaration, Results.size());
Douglas Gregor86d9a522009-09-21 16:56:56 +0000707 Results.push_back(R);
708}
709
Douglas Gregor1ca6ae82010-01-14 01:09:38 +0000710void ResultBuilder::AddResult(Result R, DeclContext *CurContext,
Douglas Gregor0cc84042010-01-14 15:47:35 +0000711 NamedDecl *Hiding, bool InBaseClass = false) {
Douglas Gregora4477812010-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 Gregor1ca6ae82010-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 Gregor45bcd432010-01-14 03:21:49 +0000724 bool AsNestedNameSpecifier = false;
725 if (!isInterestingDecl(R.Declaration, AsNestedNameSpecifier))
Douglas Gregor1ca6ae82010-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 Gregor12e13132010-05-26 22:00:08 +0000737 if (AsNestedNameSpecifier) {
Douglas Gregor1ca6ae82010-01-14 01:09:38 +0000738 R.StartsNestedNameSpecifier = true;
Douglas Gregor12e13132010-05-26 22:00:08 +0000739 R.Priority = CCP_NestedNameSpecifier;
740 }
Douglas Gregor0cc84042010-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 Gregor1ca6ae82010-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 Gregor45bcd432010-01-14 03:21:49 +0000754 SemaRef.Context.getTypeDeclType(Tag).getTypePtr());
Douglas Gregor1ca6ae82010-01-14 01:09:38 +0000755 else
756 R.QualifierIsInformative = false;
757 }
758
Douglas Gregor12e13132010-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 Gregor1f5537a2010-07-08 23:20:03 +0000763 if (!PreferredType.isNull())
764 AdjustResultPriorityForPreferredType(R);
Douglas Gregor5ac3bdb2010-05-30 01:49:25 +0000765
Douglas Gregor1ca6ae82010-01-14 01:09:38 +0000766 // Insert this result into the set of results.
767 Results.push_back(R);
768}
769
Douglas Gregora4477812010-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 Gregor86d9a522009-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 Gregorfbcb5d62009-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 Gregor86d9a522009-09-21 16:56:56 +0000789 ShadowMaps.pop_back();
790}
791
Douglas Gregor791215b2009-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 Gregor4710e5b2010-05-28 00:49:12 +0000795 ND = cast<NamedDecl>(ND->getUnderlyingDecl());
796
Douglas Gregor791215b2009-09-21 20:51:25 +0000797 unsigned IDNS = Decl::IDNS_Ordinary;
798 if (SemaRef.getLangOptions().CPlusPlus)
Douglas Gregor9b30b262010-06-15 20:26:51 +0000799 IDNS |= Decl::IDNS_Tag | Decl::IDNS_Namespace | Decl::IDNS_Member;
Douglas Gregor1ca6ae82010-01-14 01:09:38 +0000800 else if (SemaRef.getLangOptions().ObjC1 && isa<ObjCIvarDecl>(ND))
801 return true;
802
Douglas Gregor791215b2009-09-21 20:51:25 +0000803 return ND->getIdentifierNamespace() & IDNS;
804}
805
Douglas Gregor01dfea02010-01-10 23:08:15 +0000806/// \brief Determines whether this given declaration will be found by
Douglas Gregor4710e5b2010-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 Gregor9b30b262010-06-15 20:26:51 +0000815 IDNS |= Decl::IDNS_Tag | Decl::IDNS_Namespace | Decl::IDNS_Member;
Douglas Gregor4710e5b2010-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 Gregorf9578432010-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 Gregor4710e5b2010-05-28 00:49:12 +0000833/// \brief Determines whether this given declaration will be found by
Douglas Gregor01dfea02010-01-10 23:08:15 +0000834/// ordinary name lookup.
835bool ResultBuilder::IsOrdinaryNonValueName(NamedDecl *ND) const {
Douglas Gregor4710e5b2010-05-28 00:49:12 +0000836 ND = cast<NamedDecl>(ND->getUnderlyingDecl());
837
Douglas Gregor01dfea02010-01-10 23:08:15 +0000838 unsigned IDNS = Decl::IDNS_Ordinary;
839 if (SemaRef.getLangOptions().CPlusPlus)
John McCall0d6b1642010-04-23 18:46:30 +0000840 IDNS |= Decl::IDNS_Tag | Decl::IDNS_Namespace;
Douglas Gregor01dfea02010-01-10 23:08:15 +0000841
842 return (ND->getIdentifierNamespace() & IDNS) &&
Douglas Gregor4710e5b2010-05-28 00:49:12 +0000843 !isa<ValueDecl>(ND) && !isa<FunctionTemplateDecl>(ND) &&
844 !isa<ObjCPropertyDecl>(ND);
Douglas Gregor01dfea02010-01-10 23:08:15 +0000845}
846
Douglas Gregor86d9a522009-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 Bagnara465d41b2010-05-11 21:36:43 +0000869 return RD->getTagKind() == TTK_Class ||
870 RD->getTagKind() == TTK_Struct;
Douglas Gregor86d9a522009-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 Bagnara465d41b2010-05-11 21:36:43 +0000882 return RD->getTagKind() == TTK_Union;
Douglas Gregor86d9a522009-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 Gregor76282942009-12-11 17:31:05 +0000898/// \brief Determines whether the given declaration is a type.
Douglas Gregor86d9a522009-09-21 16:56:56 +0000899bool ResultBuilder::IsType(NamedDecl *ND) const {
Douglas Gregord32b0222010-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 Gregor86d9a522009-09-21 16:56:56 +0000904}
905
Douglas Gregor76282942009-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 Gregoreb5758b2009-09-23 22:26:46 +0000909bool ResultBuilder::IsMember(NamedDecl *ND) const {
Douglas Gregor76282942009-12-11 17:31:05 +0000910 if (UsingShadowDecl *Using = dyn_cast<UsingShadowDecl>(ND))
911 ND = Using->getTargetDecl();
912
Douglas Gregorce821962009-12-11 18:14:22 +0000913 return isa<ValueDecl>(ND) || isa<FunctionTemplateDecl>(ND) ||
914 isa<ObjCPropertyDecl>(ND);
Douglas Gregoreb5758b2009-09-23 22:26:46 +0000915}
916
Douglas Gregor8e254cf2010-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 Gregorfb629412010-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 Gregor8e254cf2010-05-27 23:06:34 +0000973
Douglas Gregor80f4f4c2010-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 Gregor1ca6ae82010-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 Gregor0cc84042010-01-14 15:47:35 +0000991 virtual void FoundDecl(NamedDecl *ND, NamedDecl *Hiding, bool InBaseClass) {
992 Results.AddResult(ND, CurContext, Hiding, InBaseClass);
Douglas Gregor1ca6ae82010-01-14 01:09:38 +0000993 }
994 };
995}
996
Douglas Gregor86d9a522009-09-21 16:56:56 +0000997/// \brief Add type specifiers for the current language as keyword results.
Douglas Gregorbca403c2010-01-13 23:51:12 +0000998static void AddTypeSpecifierResults(const LangOptions &LangOpts,
Douglas Gregor86d9a522009-09-21 16:56:56 +0000999 ResultBuilder &Results) {
1000 typedef CodeCompleteConsumer::Result Result;
Douglas Gregor12e13132010-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 Gregor01dfea02010-01-10 23:08:15 +00001015
Douglas Gregor86d9a522009-09-21 16:56:56 +00001016 if (LangOpts.C99) {
1017 // C99-specific
Douglas Gregor12e13132010-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 Gregor86d9a522009-09-21 16:56:56 +00001022 }
1023
1024 if (LangOpts.CPlusPlus) {
1025 // C++-specific
Douglas Gregor12e13132010-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 Gregor86d9a522009-09-21 16:56:56 +00001029
Douglas Gregorc8bddde2010-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 Gregord8e8a582010-05-25 21:41:55 +00001038
Douglas Gregor86d9a522009-09-21 16:56:56 +00001039 if (LangOpts.CPlusPlus0x) {
Douglas Gregor12e13132010-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 Gregorc8bddde2010-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 Gregor86d9a522009-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 Gregora4477812010-01-14 16:01:26 +00001056 // Results.AddResult(Result("_Decimal32"));
1057 // Results.AddResult(Result("_Decimal64"));
1058 // Results.AddResult(Result("_Decimal128"));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001059
Douglas Gregorc8bddde2010-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 Gregor86d9a522009-09-21 16:56:56 +00001072 }
1073}
1074
Douglas Gregore6b1bb62010-08-11 21:23:17 +00001075static void AddStorageSpecifiers(Action::ParserCompletionContext CCC,
Douglas Gregor01dfea02010-01-10 23:08:15 +00001076 const LangOptions &LangOpts,
Douglas Gregor01dfea02010-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 Gregora4477812010-01-14 16:01:26 +00001082 Results.AddResult(Result("extern"));
1083 Results.AddResult(Result("static"));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001084}
1085
Douglas Gregore6b1bb62010-08-11 21:23:17 +00001086static void AddFunctionSpecifiers(Action::ParserCompletionContext CCC,
Douglas Gregor01dfea02010-01-10 23:08:15 +00001087 const LangOptions &LangOpts,
Douglas Gregor01dfea02010-01-10 23:08:15 +00001088 ResultBuilder &Results) {
1089 typedef CodeCompleteConsumer::Result Result;
1090 switch (CCC) {
Douglas Gregore6b1bb62010-08-11 21:23:17 +00001091 case Action::PCC_Class:
1092 case Action::PCC_MemberTemplate:
Douglas Gregor01dfea02010-01-10 23:08:15 +00001093 if (LangOpts.CPlusPlus) {
Douglas Gregora4477812010-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 Gregor01dfea02010-01-10 23:08:15 +00001098 }
1099 // Fall through
1100
Douglas Gregore6b1bb62010-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 Gregor01dfea02010-01-10 23:08:15 +00001105 if (LangOpts.CPlusPlus || LangOpts.C99)
Douglas Gregora4477812010-01-14 16:01:26 +00001106 Results.AddResult(Result("inline"));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001107 break;
1108
Douglas Gregore6b1bb62010-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 Gregord32b0222010-08-24 01:06:58 +00001115 case Action::PCC_Type:
Douglas Gregor01dfea02010-01-10 23:08:15 +00001116 break;
1117 }
1118}
1119
Douglas Gregorbca403c2010-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 Gregorc38c3e12010-01-13 21:54:15 +00001123 ResultBuilder &Results,
1124 bool NeedAt);
Douglas Gregorbca403c2010-01-13 23:51:12 +00001125static void AddObjCImplementationResults(const LangOptions &LangOpts,
Douglas Gregorb6ac2452010-01-13 21:24:21 +00001126 ResultBuilder &Results,
1127 bool NeedAt);
Douglas Gregorbca403c2010-01-13 23:51:12 +00001128static void AddObjCInterfaceResults(const LangOptions &LangOpts,
Douglas Gregorb6ac2452010-01-13 21:24:21 +00001129 ResultBuilder &Results,
1130 bool NeedAt);
Douglas Gregorbca403c2010-01-13 23:51:12 +00001131static void AddObjCTopLevelResults(ResultBuilder &Results, bool NeedAt);
Douglas Gregorb6ac2452010-01-13 21:24:21 +00001132
Douglas Gregorc8bddde2010-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 Gregore6b1bb62010-08-11 21:23:17 +00001143static bool WantTypesInContext(Action::ParserCompletionContext CCC,
Douglas Gregor4710e5b2010-05-28 00:49:12 +00001144 const LangOptions &LangOpts) {
1145 if (LangOpts.CPlusPlus)
1146 return true;
1147
1148 switch (CCC) {
Douglas Gregore6b1bb62010-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 Gregord32b0222010-08-24 01:06:58 +00001156 case Action::PCC_Type:
Douglas Gregor4710e5b2010-05-28 00:49:12 +00001157 return true;
1158
Douglas Gregore6b1bb62010-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 Gregor4710e5b2010-05-28 00:49:12 +00001163 return false;
1164
Douglas Gregore6b1bb62010-08-11 21:23:17 +00001165 case Action::PCC_ForInit:
Douglas Gregor4710e5b2010-05-28 00:49:12 +00001166 return LangOpts.ObjC1 || LangOpts.C99;
1167 }
1168
1169 return false;
1170}
1171
Douglas Gregor01dfea02010-01-10 23:08:15 +00001172/// \brief Add language constructs that show up for "ordinary" names.
Douglas Gregore6b1bb62010-08-11 21:23:17 +00001173static void AddOrdinaryNameResults(Action::ParserCompletionContext CCC,
Douglas Gregor01dfea02010-01-10 23:08:15 +00001174 Scope *S,
1175 Sema &SemaRef,
Douglas Gregor01dfea02010-01-10 23:08:15 +00001176 ResultBuilder &Results) {
1177 typedef CodeCompleteConsumer::Result Result;
1178 switch (CCC) {
Douglas Gregore6b1bb62010-08-11 21:23:17 +00001179 case Action::PCC_Namespace:
Douglas Gregorc8bddde2010-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 Gregor01dfea02010-01-10 23:08:15 +00001196 // namespace identifier = identifier ;
1197 Pattern = new CodeCompletionString;
1198 Pattern->AddTypedTextChunk("namespace");
1199 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
Douglas Gregorc8bddde2010-05-28 00:22:41 +00001200 Pattern->AddPlaceholderChunk("name");
Douglas Gregor01dfea02010-01-10 23:08:15 +00001201 Pattern->AddChunk(CodeCompletionString::CK_Equal);
Douglas Gregorc8bddde2010-05-28 00:22:41 +00001202 Pattern->AddPlaceholderChunk("namespace");
Douglas Gregora4477812010-01-14 16:01:26 +00001203 Results.AddResult(Result(Pattern));
Douglas Gregor01dfea02010-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 Gregora4477812010-01-14 16:01:26 +00001212 Results.AddResult(Result(Pattern));
Douglas Gregor01dfea02010-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 Gregora4477812010-01-14 16:01:26 +00001220 Results.AddResult(Result(Pattern));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001221
Douglas Gregorc8bddde2010-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 Gregor01dfea02010-01-10 23:08:15 +00001230 }
Douglas Gregorb6ac2452010-01-13 21:24:21 +00001231
1232 if (SemaRef.getLangOptions().ObjC1)
Douglas Gregorbca403c2010-01-13 23:51:12 +00001233 AddObjCTopLevelResults(Results, true);
Douglas Gregorb6ac2452010-01-13 21:24:21 +00001234
Douglas Gregorc8bddde2010-05-28 00:22:41 +00001235 AddTypedefResult(Results);
Douglas Gregor01dfea02010-01-10 23:08:15 +00001236 // Fall through
1237
Douglas Gregore6b1bb62010-08-11 21:23:17 +00001238 case Action::PCC_Class:
Douglas Gregorc8bddde2010-05-28 00:22:41 +00001239 if (SemaRef.getLangOptions().CPlusPlus) {
Douglas Gregor01dfea02010-01-10 23:08:15 +00001240 // Using declaration
1241 CodeCompletionString *Pattern = new CodeCompletionString;
1242 Pattern->AddTypedTextChunk("using");
1243 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
Douglas Gregorc8bddde2010-05-28 00:22:41 +00001244 Pattern->AddPlaceholderChunk("qualifier");
1245 Pattern->AddTextChunk("::");
1246 Pattern->AddPlaceholderChunk("name");
Douglas Gregora4477812010-01-14 16:01:26 +00001247 Results.AddResult(Result(Pattern));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001248
Douglas Gregorc8bddde2010-05-28 00:22:41 +00001249 // using typename qualifier::name (only in a dependent context)
Douglas Gregor01dfea02010-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 Gregorc8bddde2010-05-28 00:22:41 +00001256 Pattern->AddPlaceholderChunk("qualifier");
1257 Pattern->AddTextChunk("::");
1258 Pattern->AddPlaceholderChunk("name");
Douglas Gregora4477812010-01-14 16:01:26 +00001259 Results.AddResult(Result(Pattern));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001260 }
1261
Douglas Gregore6b1bb62010-08-11 21:23:17 +00001262 if (CCC == Action::PCC_Class) {
Douglas Gregorc8bddde2010-05-28 00:22:41 +00001263 AddTypedefResult(Results);
1264
Douglas Gregor01dfea02010-01-10 23:08:15 +00001265 // public:
1266 Pattern = new CodeCompletionString;
1267 Pattern->AddTypedTextChunk("public");
1268 Pattern->AddChunk(CodeCompletionString::CK_Colon);
Douglas Gregora4477812010-01-14 16:01:26 +00001269 Results.AddResult(Result(Pattern));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001270
1271 // protected:
1272 Pattern = new CodeCompletionString;
1273 Pattern->AddTypedTextChunk("protected");
1274 Pattern->AddChunk(CodeCompletionString::CK_Colon);
Douglas Gregora4477812010-01-14 16:01:26 +00001275 Results.AddResult(Result(Pattern));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001276
1277 // private:
1278 Pattern = new CodeCompletionString;
1279 Pattern->AddTypedTextChunk("private");
1280 Pattern->AddChunk(CodeCompletionString::CK_Colon);
Douglas Gregora4477812010-01-14 16:01:26 +00001281 Results.AddResult(Result(Pattern));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001282 }
1283 }
1284 // Fall through
1285
Douglas Gregore6b1bb62010-08-11 21:23:17 +00001286 case Action::PCC_Template:
1287 case Action::PCC_MemberTemplate:
Douglas Gregord8e8a582010-05-25 21:41:55 +00001288 if (SemaRef.getLangOptions().CPlusPlus && Results.includeCodePatterns()) {
Douglas Gregor01dfea02010-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 Gregora4477812010-01-14 16:01:26 +00001295 Results.AddResult(Result(Pattern));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001296 }
1297
Douglas Gregorbca403c2010-01-13 23:51:12 +00001298 AddStorageSpecifiers(CCC, SemaRef.getLangOptions(), Results);
1299 AddFunctionSpecifiers(CCC, SemaRef.getLangOptions(), Results);
Douglas Gregor01dfea02010-01-10 23:08:15 +00001300 break;
1301
Douglas Gregore6b1bb62010-08-11 21:23:17 +00001302 case Action::PCC_ObjCInterface:
Douglas Gregorbca403c2010-01-13 23:51:12 +00001303 AddObjCInterfaceResults(SemaRef.getLangOptions(), Results, true);
1304 AddStorageSpecifiers(CCC, SemaRef.getLangOptions(), Results);
1305 AddFunctionSpecifiers(CCC, SemaRef.getLangOptions(), Results);
Douglas Gregorb6ac2452010-01-13 21:24:21 +00001306 break;
1307
Douglas Gregore6b1bb62010-08-11 21:23:17 +00001308 case Action::PCC_ObjCImplementation:
Douglas Gregorbca403c2010-01-13 23:51:12 +00001309 AddObjCImplementationResults(SemaRef.getLangOptions(), Results, true);
1310 AddStorageSpecifiers(CCC, SemaRef.getLangOptions(), Results);
1311 AddFunctionSpecifiers(CCC, SemaRef.getLangOptions(), Results);
Douglas Gregorb6ac2452010-01-13 21:24:21 +00001312 break;
1313
Douglas Gregore6b1bb62010-08-11 21:23:17 +00001314 case Action::PCC_ObjCInstanceVariableList:
Douglas Gregorbca403c2010-01-13 23:51:12 +00001315 AddObjCVisibilityResults(SemaRef.getLangOptions(), Results, true);
Douglas Gregorc38c3e12010-01-13 21:54:15 +00001316 break;
1317
Douglas Gregore6b1bb62010-08-11 21:23:17 +00001318 case Action::PCC_RecoveryInFunction:
1319 case Action::PCC_Statement: {
Douglas Gregorc8bddde2010-05-28 00:22:41 +00001320 AddTypedefResult(Results);
Douglas Gregor01dfea02010-01-10 23:08:15 +00001321
1322 CodeCompletionString *Pattern = 0;
Douglas Gregord8e8a582010-05-25 21:41:55 +00001323 if (SemaRef.getLangOptions().CPlusPlus && Results.includeCodePatterns()) {
Douglas Gregor01dfea02010-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 Gregora4477812010-01-14 16:01:26 +00001338 Results.AddResult(Result(Pattern));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001339 }
Douglas Gregorb6ac2452010-01-13 21:24:21 +00001340 if (SemaRef.getLangOptions().ObjC1)
Douglas Gregorbca403c2010-01-13 23:51:12 +00001341 AddObjCStatementResults(Results, true);
Douglas Gregorb6ac2452010-01-13 21:24:21 +00001342
Douglas Gregord8e8a582010-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 Gregor01dfea02010-01-10 23:08:15 +00001358
Douglas Gregord8e8a582010-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 Gregor01dfea02010-01-10 23:08:15 +00001374 // Switch-specific statements.
Douglas Gregorc8bddde2010-05-28 00:22:41 +00001375 if (!SemaRef.getSwitchStack().empty()) {
Douglas Gregor01dfea02010-01-10 23:08:15 +00001376 // case expression:
1377 Pattern = new CodeCompletionString;
1378 Pattern->AddTypedTextChunk("case");
Douglas Gregorc8bddde2010-05-28 00:22:41 +00001379 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
Douglas Gregor01dfea02010-01-10 23:08:15 +00001380 Pattern->AddPlaceholderChunk("expression");
1381 Pattern->AddChunk(CodeCompletionString::CK_Colon);
Douglas Gregora4477812010-01-14 16:01:26 +00001382 Results.AddResult(Result(Pattern));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001383
1384 // default:
1385 Pattern = new CodeCompletionString;
1386 Pattern->AddTypedTextChunk("default");
1387 Pattern->AddChunk(CodeCompletionString::CK_Colon);
Douglas Gregora4477812010-01-14 16:01:26 +00001388 Results.AddResult(Result(Pattern));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001389 }
1390
Douglas Gregord8e8a582010-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 Gregor01dfea02010-01-10 23:08:15 +00001416 Pattern->AddPlaceholderChunk("expression");
Douglas Gregord8e8a582010-05-25 21:41:55 +00001417 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
1418 Results.AddResult(Result(Pattern));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001419
Douglas Gregord8e8a582010-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 Gregor01dfea02010-01-10 23:08:15 +00001439
1440 if (S->getContinueParent()) {
1441 // continue ;
1442 Pattern = new CodeCompletionString;
1443 Pattern->AddTypedTextChunk("continue");
Douglas Gregora4477812010-01-14 16:01:26 +00001444 Results.AddResult(Result(Pattern));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001445 }
1446
1447 if (S->getBreakParent()) {
1448 // break ;
1449 Pattern = new CodeCompletionString;
1450 Pattern->AddTypedTextChunk("break");
Douglas Gregora4477812010-01-14 16:01:26 +00001451 Results.AddResult(Result(Pattern));
Douglas Gregor01dfea02010-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 Gregor9ea9bdb2010-03-01 23:15:13 +00001462 else if (SemaRef.getCurBlock() &&
1463 !SemaRef.getCurBlock()->ReturnType.isNull())
1464 isVoid = SemaRef.getCurBlock()->ReturnType->isVoidType();
Douglas Gregor01dfea02010-01-10 23:08:15 +00001465 Pattern = new CodeCompletionString;
1466 Pattern->AddTypedTextChunk("return");
Douglas Gregor93298002010-02-18 04:06:48 +00001467 if (!isVoid) {
1468 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
Douglas Gregor01dfea02010-01-10 23:08:15 +00001469 Pattern->AddPlaceholderChunk("expression");
Douglas Gregor93298002010-02-18 04:06:48 +00001470 }
Douglas Gregora4477812010-01-14 16:01:26 +00001471 Results.AddResult(Result(Pattern));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001472
Douglas Gregorc8bddde2010-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 Gregor01dfea02010-01-10 23:08:15 +00001479
Douglas Gregorc8bddde2010-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 Gregor01dfea02010-01-10 23:08:15 +00001488 }
1489
1490 // Fall through (for statement expressions).
Douglas Gregore6b1bb62010-08-11 21:23:17 +00001491 case Action::PCC_ForInit:
1492 case Action::PCC_Condition:
Douglas Gregorbca403c2010-01-13 23:51:12 +00001493 AddStorageSpecifiers(CCC, SemaRef.getLangOptions(), Results);
Douglas Gregor01dfea02010-01-10 23:08:15 +00001494 // Fall through: conditions and statements can have expressions.
1495
Douglas Gregore6b1bb62010-08-11 21:23:17 +00001496 case Action::PCC_Expression: {
Douglas Gregor01dfea02010-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 Gregora4477812010-01-14 16:01:26 +00001502 Results.AddResult(Result("this"));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001503
1504 // true, false
Douglas Gregora4477812010-01-14 16:01:26 +00001505 Results.AddResult(Result("true"));
1506 Results.AddResult(Result("false"));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001507
Douglas Gregorc8bddde2010-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 Gregor01dfea02010-01-10 23:08:15 +00001529
Douglas Gregorc8bddde2010-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 Gregor01dfea02010-01-10 23:08:15 +00001540
Douglas Gregorc8bddde2010-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 Gregor01dfea02010-01-10 23:08:15 +00001551
Douglas Gregorc8bddde2010-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 Gregor01dfea02010-01-10 23:08:15 +00001559
Douglas Gregorc8bddde2010-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 Gregor01dfea02010-01-10 23:08:15 +00001569
Douglas Gregorc8bddde2010-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 Gregor01dfea02010-01-10 23:08:15 +00001582
Douglas Gregorc8bddde2010-05-28 00:22:41 +00001583 // delete expression
1584 Pattern = new CodeCompletionString;
1585 Pattern->AddTypedTextChunk("delete");
1586 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
1587 Pattern->AddPlaceholderChunk("expression");
1588 Results.AddResult(Result(Pattern));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001589
Douglas Gregorc8bddde2010-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 Gregor01dfea02010-01-10 23:08:15 +00001599
Douglas Gregorc8bddde2010-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 Gregor12e13132010-05-26 22:00:08 +00001606
1607 // FIXME: Rethrow?
Douglas Gregor01dfea02010-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 Kremenek681e2562010-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 Gregorbca403c2010-01-13 23:51:12 +00001619 AddObjCExpressionResults(Results, true);
Douglas Gregor01dfea02010-01-10 23:08:15 +00001620 }
1621
Douglas Gregorc8bddde2010-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 Gregor01dfea02010-01-10 23:08:15 +00001629 break;
1630 }
Douglas Gregord32b0222010-08-24 01:06:58 +00001631
1632 case Action::PCC_Type:
1633 break;
Douglas Gregor01dfea02010-01-10 23:08:15 +00001634 }
1635
Douglas Gregor4710e5b2010-05-28 00:49:12 +00001636 if (WantTypesInContext(CCC, SemaRef.getLangOptions()))
1637 AddTypeSpecifierResults(SemaRef.getLangOptions(), Results);
Douglas Gregor01dfea02010-01-10 23:08:15 +00001638
Douglas Gregord32b0222010-08-24 01:06:58 +00001639 if (SemaRef.getLangOptions().CPlusPlus && CCC != Action::PCC_Type)
Douglas Gregora4477812010-01-14 16:01:26 +00001640 Results.AddResult(Result("operator"));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001641}
1642
Douglas Gregorff5ce6e2009-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 Gregor84139d62010-04-05 21:25:31 +00001671 PrintingPolicy Policy(Context.PrintingPolicy);
1672 Policy.AnonymousTagLocations = false;
1673
Douglas Gregorff5ce6e2009-12-18 18:53:37 +00001674 std::string TypeStr;
Douglas Gregor84139d62010-04-05 21:25:31 +00001675 T.getAsStringInternal(TypeStr, Policy);
Douglas Gregorff5ce6e2009-12-18 18:53:37 +00001676 Result->AddResultTypeChunk(TypeStr);
1677}
1678
Douglas Gregoraaa107a2010-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 Gregor86d9a522009-09-21 16:56:56 +00001693/// \brief Add function parameter chunks to the given code completion string.
1694static void AddFunctionParameterChunks(ASTContext &Context,
1695 FunctionDecl *Function,
1696 CodeCompletionString *Result) {
Douglas Gregor0c8296d2009-11-07 00:00:49 +00001697 typedef CodeCompletionString::Chunk Chunk;
1698
Douglas Gregor86d9a522009-09-21 16:56:56 +00001699 CodeCompletionString *CCStr = Result;
1700
1701 for (unsigned P = 0, N = Function->getNumParams(); P != N; ++P) {
1702 ParmVarDecl *Param = Function->getParamDecl(P);
1703
1704 if (Param->hasDefaultArg()) {
1705 // When we see an optional default argument, put that argument and
1706 // the remaining default arguments into a new, optional string.
1707 CodeCompletionString *Opt = new CodeCompletionString;
1708 CCStr->AddOptionalChunk(std::auto_ptr<CodeCompletionString>(Opt));
1709 CCStr = Opt;
1710 }
1711
1712 if (P != 0)
Douglas Gregor0c8296d2009-11-07 00:00:49 +00001713 CCStr->AddChunk(Chunk(CodeCompletionString::CK_Comma));
Douglas Gregor86d9a522009-09-21 16:56:56 +00001714
1715 // Format the placeholder string.
1716 std::string PlaceholderStr;
1717 if (Param->getIdentifier())
1718 PlaceholderStr = Param->getIdentifier()->getName();
1719
1720 Param->getType().getAsStringInternal(PlaceholderStr,
1721 Context.PrintingPolicy);
1722
1723 // Add the placeholder string.
Benjamin Kramer660cc182009-11-29 20:18:50 +00001724 CCStr->AddPlaceholderChunk(PlaceholderStr);
Douglas Gregor86d9a522009-09-21 16:56:56 +00001725 }
Douglas Gregorb3d45252009-09-22 21:42:17 +00001726
1727 if (const FunctionProtoType *Proto
1728 = Function->getType()->getAs<FunctionProtoType>())
Douglas Gregoraaa107a2010-08-23 23:51:41 +00001729 if (Proto->isVariadic()) {
Douglas Gregorb3d45252009-09-22 21:42:17 +00001730 CCStr->AddPlaceholderChunk(", ...");
Douglas Gregoraaa107a2010-08-23 23:51:41 +00001731
1732 MaybeAddSentinel(Context, Function, CCStr);
1733 }
Douglas Gregor86d9a522009-09-21 16:56:56 +00001734}
1735
1736/// \brief Add template parameter chunks to the given code completion string.
1737static void AddTemplateParameterChunks(ASTContext &Context,
1738 TemplateDecl *Template,
1739 CodeCompletionString *Result,
1740 unsigned MaxParameters = 0) {
Douglas Gregor0c8296d2009-11-07 00:00:49 +00001741 typedef CodeCompletionString::Chunk Chunk;
1742
Douglas Gregor86d9a522009-09-21 16:56:56 +00001743 CodeCompletionString *CCStr = Result;
1744 bool FirstParameter = true;
1745
1746 TemplateParameterList *Params = Template->getTemplateParameters();
1747 TemplateParameterList::iterator PEnd = Params->end();
1748 if (MaxParameters)
1749 PEnd = Params->begin() + MaxParameters;
1750 for (TemplateParameterList::iterator P = Params->begin(); P != PEnd; ++P) {
1751 bool HasDefaultArg = false;
1752 std::string PlaceholderStr;
1753 if (TemplateTypeParmDecl *TTP = dyn_cast<TemplateTypeParmDecl>(*P)) {
1754 if (TTP->wasDeclaredWithTypename())
1755 PlaceholderStr = "typename";
1756 else
1757 PlaceholderStr = "class";
1758
1759 if (TTP->getIdentifier()) {
1760 PlaceholderStr += ' ';
1761 PlaceholderStr += TTP->getIdentifier()->getName();
1762 }
1763
1764 HasDefaultArg = TTP->hasDefaultArgument();
1765 } else if (NonTypeTemplateParmDecl *NTTP
1766 = dyn_cast<NonTypeTemplateParmDecl>(*P)) {
1767 if (NTTP->getIdentifier())
1768 PlaceholderStr = NTTP->getIdentifier()->getName();
1769 NTTP->getType().getAsStringInternal(PlaceholderStr,
1770 Context.PrintingPolicy);
1771 HasDefaultArg = NTTP->hasDefaultArgument();
1772 } else {
1773 assert(isa<TemplateTemplateParmDecl>(*P));
1774 TemplateTemplateParmDecl *TTP = cast<TemplateTemplateParmDecl>(*P);
1775
1776 // Since putting the template argument list into the placeholder would
1777 // be very, very long, we just use an abbreviation.
1778 PlaceholderStr = "template<...> class";
1779 if (TTP->getIdentifier()) {
1780 PlaceholderStr += ' ';
1781 PlaceholderStr += TTP->getIdentifier()->getName();
1782 }
1783
1784 HasDefaultArg = TTP->hasDefaultArgument();
1785 }
1786
1787 if (HasDefaultArg) {
1788 // When we see an optional default argument, put that argument and
1789 // the remaining default arguments into a new, optional string.
1790 CodeCompletionString *Opt = new CodeCompletionString;
1791 CCStr->AddOptionalChunk(std::auto_ptr<CodeCompletionString>(Opt));
1792 CCStr = Opt;
1793 }
1794
1795 if (FirstParameter)
1796 FirstParameter = false;
1797 else
Douglas Gregor0c8296d2009-11-07 00:00:49 +00001798 CCStr->AddChunk(Chunk(CodeCompletionString::CK_Comma));
Douglas Gregor86d9a522009-09-21 16:56:56 +00001799
1800 // Add the placeholder string.
Benjamin Kramer660cc182009-11-29 20:18:50 +00001801 CCStr->AddPlaceholderChunk(PlaceholderStr);
Douglas Gregor86d9a522009-09-21 16:56:56 +00001802 }
1803}
1804
Douglas Gregorb9d0ef72009-09-21 19:57:38 +00001805/// \brief Add a qualifier to the given code-completion string, if the
1806/// provided nested-name-specifier is non-NULL.
Douglas Gregora61a8792009-12-11 18:44:16 +00001807static void
1808AddQualifierToCompletionString(CodeCompletionString *Result,
1809 NestedNameSpecifier *Qualifier,
1810 bool QualifierIsInformative,
1811 ASTContext &Context) {
Douglas Gregorb9d0ef72009-09-21 19:57:38 +00001812 if (!Qualifier)
1813 return;
1814
1815 std::string PrintedNNS;
1816 {
1817 llvm::raw_string_ostream OS(PrintedNNS);
1818 Qualifier->print(OS, Context.PrintingPolicy);
1819 }
Douglas Gregor0563c262009-09-22 23:15:58 +00001820 if (QualifierIsInformative)
Benjamin Kramer660cc182009-11-29 20:18:50 +00001821 Result->AddInformativeChunk(PrintedNNS);
Douglas Gregor0563c262009-09-22 23:15:58 +00001822 else
Benjamin Kramer660cc182009-11-29 20:18:50 +00001823 Result->AddTextChunk(PrintedNNS);
Douglas Gregorb9d0ef72009-09-21 19:57:38 +00001824}
1825
Douglas Gregora61a8792009-12-11 18:44:16 +00001826static void AddFunctionTypeQualsToCompletionString(CodeCompletionString *Result,
1827 FunctionDecl *Function) {
1828 const FunctionProtoType *Proto
1829 = Function->getType()->getAs<FunctionProtoType>();
1830 if (!Proto || !Proto->getTypeQuals())
1831 return;
1832
1833 std::string QualsStr;
1834 if (Proto->getTypeQuals() & Qualifiers::Const)
1835 QualsStr += " const";
1836 if (Proto->getTypeQuals() & Qualifiers::Volatile)
1837 QualsStr += " volatile";
1838 if (Proto->getTypeQuals() & Qualifiers::Restrict)
1839 QualsStr += " restrict";
1840 Result->AddInformativeChunk(QualsStr);
1841}
1842
Douglas Gregor86d9a522009-09-21 16:56:56 +00001843/// \brief If possible, create a new code completion string for the given
1844/// result.
1845///
1846/// \returns Either a new, heap-allocated code completion string describing
1847/// how to use this result, or NULL to indicate that the string or name of the
1848/// result is all that is needed.
1849CodeCompletionString *
Douglas Gregor1abc6bc2010-08-04 16:47:14 +00001850CodeCompleteConsumer::Result::CreateCodeCompletionString(Sema &S,
1851 CodeCompletionString *Result) {
Douglas Gregor0c8296d2009-11-07 00:00:49 +00001852 typedef CodeCompletionString::Chunk Chunk;
1853
Douglas Gregor2b4074f2009-12-01 05:55:20 +00001854 if (Kind == RK_Pattern)
Douglas Gregor1abc6bc2010-08-04 16:47:14 +00001855 return Pattern->Clone(Result);
Douglas Gregor2b4074f2009-12-01 05:55:20 +00001856
Douglas Gregor1abc6bc2010-08-04 16:47:14 +00001857 if (!Result)
1858 Result = new CodeCompletionString;
Douglas Gregor2b4074f2009-12-01 05:55:20 +00001859
1860 if (Kind == RK_Keyword) {
1861 Result->AddTypedTextChunk(Keyword);
1862 return Result;
1863 }
Douglas Gregor86d9a522009-09-21 16:56:56 +00001864
Douglas Gregor3f7c7f42009-10-30 16:50:04 +00001865 if (Kind == RK_Macro) {
1866 MacroInfo *MI = S.PP.getMacroInfo(Macro);
Douglas Gregor2b4074f2009-12-01 05:55:20 +00001867 assert(MI && "Not a macro?");
1868
1869 Result->AddTypedTextChunk(Macro->getName());
1870
1871 if (!MI->isFunctionLike())
1872 return Result;
Douglas Gregor3f7c7f42009-10-30 16:50:04 +00001873
1874 // Format a function-like macro with placeholders for the arguments.
Douglas Gregor0c8296d2009-11-07 00:00:49 +00001875 Result->AddChunk(Chunk(CodeCompletionString::CK_LeftParen));
Douglas Gregor3f7c7f42009-10-30 16:50:04 +00001876 for (MacroInfo::arg_iterator A = MI->arg_begin(), AEnd = MI->arg_end();
1877 A != AEnd; ++A) {
1878 if (A != MI->arg_begin())
Douglas Gregor0c8296d2009-11-07 00:00:49 +00001879 Result->AddChunk(Chunk(CodeCompletionString::CK_Comma));
Douglas Gregor3f7c7f42009-10-30 16:50:04 +00001880
1881 if (!MI->isVariadic() || A != AEnd - 1) {
1882 // Non-variadic argument.
Benjamin Kramer660cc182009-11-29 20:18:50 +00001883 Result->AddPlaceholderChunk((*A)->getName());
Douglas Gregor3f7c7f42009-10-30 16:50:04 +00001884 continue;
1885 }
1886
1887 // Variadic argument; cope with the different between GNU and C99
1888 // variadic macros, providing a single placeholder for the rest of the
1889 // arguments.
1890 if ((*A)->isStr("__VA_ARGS__"))
1891 Result->AddPlaceholderChunk("...");
1892 else {
1893 std::string Arg = (*A)->getName();
1894 Arg += "...";
Benjamin Kramer660cc182009-11-29 20:18:50 +00001895 Result->AddPlaceholderChunk(Arg);
Douglas Gregor3f7c7f42009-10-30 16:50:04 +00001896 }
1897 }
Douglas Gregor0c8296d2009-11-07 00:00:49 +00001898 Result->AddChunk(Chunk(CodeCompletionString::CK_RightParen));
Douglas Gregor3f7c7f42009-10-30 16:50:04 +00001899 return Result;
1900 }
1901
Douglas Gregord8e8a582010-05-25 21:41:55 +00001902 assert(Kind == RK_Declaration && "Missed a result kind?");
Douglas Gregor86d9a522009-09-21 16:56:56 +00001903 NamedDecl *ND = Declaration;
1904
Douglas Gregor0c8296d2009-11-07 00:00:49 +00001905 if (StartsNestedNameSpecifier) {
Benjamin Kramer660cc182009-11-29 20:18:50 +00001906 Result->AddTypedTextChunk(ND->getNameAsString());
Douglas Gregor0c8296d2009-11-07 00:00:49 +00001907 Result->AddTextChunk("::");
1908 return Result;
1909 }
1910
Douglas Gregorff5ce6e2009-12-18 18:53:37 +00001911 AddResultTypeChunk(S.Context, ND, Result);
1912
Douglas Gregor86d9a522009-09-21 16:56:56 +00001913 if (FunctionDecl *Function = dyn_cast<FunctionDecl>(ND)) {
Douglas Gregor0563c262009-09-22 23:15:58 +00001914 AddQualifierToCompletionString(Result, Qualifier, QualifierIsInformative,
1915 S.Context);
Benjamin Kramer660cc182009-11-29 20:18:50 +00001916 Result->AddTypedTextChunk(Function->getNameAsString());
Douglas Gregor0c8296d2009-11-07 00:00:49 +00001917 Result->AddChunk(Chunk(CodeCompletionString::CK_LeftParen));
Douglas Gregor86d9a522009-09-21 16:56:56 +00001918 AddFunctionParameterChunks(S.Context, Function, Result);
Douglas Gregor0c8296d2009-11-07 00:00:49 +00001919 Result->AddChunk(Chunk(CodeCompletionString::CK_RightParen));
Douglas Gregora61a8792009-12-11 18:44:16 +00001920 AddFunctionTypeQualsToCompletionString(Result, Function);
Douglas Gregor86d9a522009-09-21 16:56:56 +00001921 return Result;
1922 }
1923
1924 if (FunctionTemplateDecl *FunTmpl = dyn_cast<FunctionTemplateDecl>(ND)) {
Douglas Gregor0563c262009-09-22 23:15:58 +00001925 AddQualifierToCompletionString(Result, Qualifier, QualifierIsInformative,
1926 S.Context);
Douglas Gregor86d9a522009-09-21 16:56:56 +00001927 FunctionDecl *Function = FunTmpl->getTemplatedDecl();
Benjamin Kramer660cc182009-11-29 20:18:50 +00001928 Result->AddTypedTextChunk(Function->getNameAsString());
Douglas Gregor86d9a522009-09-21 16:56:56 +00001929
1930 // Figure out which template parameters are deduced (or have default
1931 // arguments).
1932 llvm::SmallVector<bool, 16> Deduced;
1933 S.MarkDeducedTemplateParameters(FunTmpl, Deduced);
1934 unsigned LastDeducibleArgument;
1935 for (LastDeducibleArgument = Deduced.size(); LastDeducibleArgument > 0;
1936 --LastDeducibleArgument) {
1937 if (!Deduced[LastDeducibleArgument - 1]) {
1938 // C++0x: Figure out if the template argument has a default. If so,
1939 // the user doesn't need to type this argument.
1940 // FIXME: We need to abstract template parameters better!
1941 bool HasDefaultArg = false;
1942 NamedDecl *Param = FunTmpl->getTemplateParameters()->getParam(
1943 LastDeducibleArgument - 1);
1944 if (TemplateTypeParmDecl *TTP = dyn_cast<TemplateTypeParmDecl>(Param))
1945 HasDefaultArg = TTP->hasDefaultArgument();
1946 else if (NonTypeTemplateParmDecl *NTTP
1947 = dyn_cast<NonTypeTemplateParmDecl>(Param))
1948 HasDefaultArg = NTTP->hasDefaultArgument();
1949 else {
1950 assert(isa<TemplateTemplateParmDecl>(Param));
1951 HasDefaultArg
Douglas Gregor0c8296d2009-11-07 00:00:49 +00001952 = cast<TemplateTemplateParmDecl>(Param)->hasDefaultArgument();
Douglas Gregor86d9a522009-09-21 16:56:56 +00001953 }
1954
1955 if (!HasDefaultArg)
1956 break;
1957 }
1958 }
1959
1960 if (LastDeducibleArgument) {
1961 // Some of the function template arguments cannot be deduced from a
1962 // function call, so we introduce an explicit template argument list
1963 // containing all of the arguments up to the first deducible argument.
Douglas Gregor0c8296d2009-11-07 00:00:49 +00001964 Result->AddChunk(Chunk(CodeCompletionString::CK_LeftAngle));
Douglas Gregor86d9a522009-09-21 16:56:56 +00001965 AddTemplateParameterChunks(S.Context, FunTmpl, Result,
1966 LastDeducibleArgument);
Douglas Gregor0c8296d2009-11-07 00:00:49 +00001967 Result->AddChunk(Chunk(CodeCompletionString::CK_RightAngle));
Douglas Gregor86d9a522009-09-21 16:56:56 +00001968 }
1969
1970 // Add the function parameters
Douglas Gregor0c8296d2009-11-07 00:00:49 +00001971 Result->AddChunk(Chunk(CodeCompletionString::CK_LeftParen));
Douglas Gregor86d9a522009-09-21 16:56:56 +00001972 AddFunctionParameterChunks(S.Context, Function, Result);
Douglas Gregor0c8296d2009-11-07 00:00:49 +00001973 Result->AddChunk(Chunk(CodeCompletionString::CK_RightParen));
Douglas Gregora61a8792009-12-11 18:44:16 +00001974 AddFunctionTypeQualsToCompletionString(Result, Function);
Douglas Gregor86d9a522009-09-21 16:56:56 +00001975 return Result;
1976 }
1977
1978 if (TemplateDecl *Template = dyn_cast<TemplateDecl>(ND)) {
Douglas Gregor0563c262009-09-22 23:15:58 +00001979 AddQualifierToCompletionString(Result, Qualifier, QualifierIsInformative,
1980 S.Context);
Benjamin Kramer660cc182009-11-29 20:18:50 +00001981 Result->AddTypedTextChunk(Template->getNameAsString());
Douglas Gregor0c8296d2009-11-07 00:00:49 +00001982 Result->AddChunk(Chunk(CodeCompletionString::CK_LeftAngle));
Douglas Gregor86d9a522009-09-21 16:56:56 +00001983 AddTemplateParameterChunks(S.Context, Template, Result);
Douglas Gregor0c8296d2009-11-07 00:00:49 +00001984 Result->AddChunk(Chunk(CodeCompletionString::CK_RightAngle));
Douglas Gregor86d9a522009-09-21 16:56:56 +00001985 return Result;
1986 }
1987
Douglas Gregor9630eb62009-11-17 16:44:22 +00001988 if (ObjCMethodDecl *Method = dyn_cast<ObjCMethodDecl>(ND)) {
Douglas Gregor9630eb62009-11-17 16:44:22 +00001989 Selector Sel = Method->getSelector();
1990 if (Sel.isUnarySelector()) {
1991 Result->AddTypedTextChunk(Sel.getIdentifierInfoForSlot(0)->getName());
1992 return Result;
1993 }
1994
Douglas Gregord3c68542009-11-19 01:08:35 +00001995 std::string SelName = Sel.getIdentifierInfoForSlot(0)->getName().str();
1996 SelName += ':';
1997 if (StartParameter == 0)
1998 Result->AddTypedTextChunk(SelName);
1999 else {
2000 Result->AddInformativeChunk(SelName);
2001
2002 // If there is only one parameter, and we're past it, add an empty
2003 // typed-text chunk since there is nothing to type.
2004 if (Method->param_size() == 1)
2005 Result->AddTypedTextChunk("");
2006 }
Douglas Gregor9630eb62009-11-17 16:44:22 +00002007 unsigned Idx = 0;
2008 for (ObjCMethodDecl::param_iterator P = Method->param_begin(),
2009 PEnd = Method->param_end();
2010 P != PEnd; (void)++P, ++Idx) {
2011 if (Idx > 0) {
Douglas Gregord3c68542009-11-19 01:08:35 +00002012 std::string Keyword;
2013 if (Idx > StartParameter)
Douglas Gregor834389b2010-01-12 06:38:28 +00002014 Result->AddChunk(CodeCompletionString::CK_HorizontalSpace);
Douglas Gregor9630eb62009-11-17 16:44:22 +00002015 if (IdentifierInfo *II = Sel.getIdentifierInfoForSlot(Idx))
2016 Keyword += II->getName().str();
2017 Keyword += ":";
Douglas Gregor1f5537a2010-07-08 23:20:03 +00002018 if (Idx < StartParameter || AllParametersAreInformative)
Douglas Gregord3c68542009-11-19 01:08:35 +00002019 Result->AddInformativeChunk(Keyword);
Douglas Gregor1f5537a2010-07-08 23:20:03 +00002020 else if (Idx == StartParameter)
Douglas Gregord3c68542009-11-19 01:08:35 +00002021 Result->AddTypedTextChunk(Keyword);
2022 else
2023 Result->AddTextChunk(Keyword);
Douglas Gregor9630eb62009-11-17 16:44:22 +00002024 }
Douglas Gregord3c68542009-11-19 01:08:35 +00002025
2026 // If we're before the starting parameter, skip the placeholder.
2027 if (Idx < StartParameter)
2028 continue;
Douglas Gregor9630eb62009-11-17 16:44:22 +00002029
2030 std::string Arg;
2031 (*P)->getType().getAsStringInternal(Arg, S.Context.PrintingPolicy);
2032 Arg = "(" + Arg + ")";
2033 if (IdentifierInfo *II = (*P)->getIdentifier())
2034 Arg += II->getName().str();
Douglas Gregor1f5537a2010-07-08 23:20:03 +00002035 if (DeclaringEntity)
2036 Result->AddTextChunk(Arg);
2037 else if (AllParametersAreInformative)
Douglas Gregor4ad96852009-11-19 07:41:15 +00002038 Result->AddInformativeChunk(Arg);
2039 else
2040 Result->AddPlaceholderChunk(Arg);
Douglas Gregor9630eb62009-11-17 16:44:22 +00002041 }
2042
Douglas Gregor2a17af02009-12-23 00:21:46 +00002043 if (Method->isVariadic()) {
Douglas Gregor1f5537a2010-07-08 23:20:03 +00002044 if (DeclaringEntity)
2045 Result->AddTextChunk(", ...");
2046 else if (AllParametersAreInformative)
Douglas Gregor2a17af02009-12-23 00:21:46 +00002047 Result->AddInformativeChunk(", ...");
2048 else
2049 Result->AddPlaceholderChunk(", ...");
Douglas Gregoraaa107a2010-08-23 23:51:41 +00002050
2051 MaybeAddSentinel(S.Context, Method, Result);
Douglas Gregor2a17af02009-12-23 00:21:46 +00002052 }
2053
Douglas Gregor9630eb62009-11-17 16:44:22 +00002054 return Result;
2055 }
2056
Douglas Gregor2b4074f2009-12-01 05:55:20 +00002057 if (Qualifier)
Douglas Gregor0563c262009-09-22 23:15:58 +00002058 AddQualifierToCompletionString(Result, Qualifier, QualifierIsInformative,
2059 S.Context);
Douglas Gregor2b4074f2009-12-01 05:55:20 +00002060
2061 Result->AddTypedTextChunk(ND->getNameAsString());
2062 return Result;
Douglas Gregor86d9a522009-09-21 16:56:56 +00002063}
2064
Douglas Gregor86d802e2009-09-23 00:34:09 +00002065CodeCompletionString *
2066CodeCompleteConsumer::OverloadCandidate::CreateSignatureString(
2067 unsigned CurrentArg,
2068 Sema &S) const {
Douglas Gregor0c8296d2009-11-07 00:00:49 +00002069 typedef CodeCompletionString::Chunk Chunk;
2070
Douglas Gregor86d802e2009-09-23 00:34:09 +00002071 CodeCompletionString *Result = new CodeCompletionString;
2072 FunctionDecl *FDecl = getFunction();
Douglas Gregorff5ce6e2009-12-18 18:53:37 +00002073 AddResultTypeChunk(S.Context, FDecl, Result);
Douglas Gregor86d802e2009-09-23 00:34:09 +00002074 const FunctionProtoType *Proto
2075 = dyn_cast<FunctionProtoType>(getFunctionType());
2076 if (!FDecl && !Proto) {
2077 // Function without a prototype. Just give the return type and a
2078 // highlighted ellipsis.
2079 const FunctionType *FT = getFunctionType();
2080 Result->AddTextChunk(
Benjamin Kramer660cc182009-11-29 20:18:50 +00002081 FT->getResultType().getAsString(S.Context.PrintingPolicy));
Douglas Gregor0c8296d2009-11-07 00:00:49 +00002082 Result->AddChunk(Chunk(CodeCompletionString::CK_LeftParen));
2083 Result->AddChunk(Chunk(CodeCompletionString::CK_CurrentParameter, "..."));
2084 Result->AddChunk(Chunk(CodeCompletionString::CK_RightParen));
Douglas Gregor86d802e2009-09-23 00:34:09 +00002085 return Result;
2086 }
2087
2088 if (FDecl)
Benjamin Kramer660cc182009-11-29 20:18:50 +00002089 Result->AddTextChunk(FDecl->getNameAsString());
Douglas Gregor86d802e2009-09-23 00:34:09 +00002090 else
2091 Result->AddTextChunk(
Benjamin Kramer660cc182009-11-29 20:18:50 +00002092 Proto->getResultType().getAsString(S.Context.PrintingPolicy));
Douglas Gregor86d802e2009-09-23 00:34:09 +00002093
Douglas Gregor0c8296d2009-11-07 00:00:49 +00002094 Result->AddChunk(Chunk(CodeCompletionString::CK_LeftParen));
Douglas Gregor86d802e2009-09-23 00:34:09 +00002095 unsigned NumParams = FDecl? FDecl->getNumParams() : Proto->getNumArgs();
2096 for (unsigned I = 0; I != NumParams; ++I) {
2097 if (I)
Douglas Gregor0c8296d2009-11-07 00:00:49 +00002098 Result->AddChunk(Chunk(CodeCompletionString::CK_Comma));
Douglas Gregor86d802e2009-09-23 00:34:09 +00002099
2100 std::string ArgString;
2101 QualType ArgType;
2102
2103 if (FDecl) {
2104 ArgString = FDecl->getParamDecl(I)->getNameAsString();
2105 ArgType = FDecl->getParamDecl(I)->getOriginalType();
2106 } else {
2107 ArgType = Proto->getArgType(I);
2108 }
2109
2110 ArgType.getAsStringInternal(ArgString, S.Context.PrintingPolicy);
2111
2112 if (I == CurrentArg)
Douglas Gregor0c8296d2009-11-07 00:00:49 +00002113 Result->AddChunk(Chunk(CodeCompletionString::CK_CurrentParameter,
Benjamin Kramer660cc182009-11-29 20:18:50 +00002114 ArgString));
Douglas Gregor86d802e2009-09-23 00:34:09 +00002115 else
Benjamin Kramer660cc182009-11-29 20:18:50 +00002116 Result->AddTextChunk(ArgString);
Douglas Gregor86d802e2009-09-23 00:34:09 +00002117 }
2118
2119 if (Proto && Proto->isVariadic()) {
Douglas Gregor0c8296d2009-11-07 00:00:49 +00002120 Result->AddChunk(Chunk(CodeCompletionString::CK_Comma));
Douglas Gregor86d802e2009-09-23 00:34:09 +00002121 if (CurrentArg < NumParams)
2122 Result->AddTextChunk("...");
2123 else
Douglas Gregor0c8296d2009-11-07 00:00:49 +00002124 Result->AddChunk(Chunk(CodeCompletionString::CK_CurrentParameter, "..."));
Douglas Gregor86d802e2009-09-23 00:34:09 +00002125 }
Douglas Gregor0c8296d2009-11-07 00:00:49 +00002126 Result->AddChunk(Chunk(CodeCompletionString::CK_RightParen));
Douglas Gregor86d802e2009-09-23 00:34:09 +00002127
2128 return Result;
2129}
2130
Douglas Gregor86d9a522009-09-21 16:56:56 +00002131namespace {
2132 struct SortCodeCompleteResult {
2133 typedef CodeCompleteConsumer::Result Result;
2134
Douglas Gregorab0b4f12010-01-13 23:24:38 +00002135 /// \brief Retrieve the name that should be used to order a result.
2136 ///
2137 /// If the name needs to be constructed as a string, that string will be
2138 /// saved into Saved and the returned StringRef will refer to it.
2139 static llvm::StringRef getOrderedName(const Result &R,
2140 std::string &Saved) {
2141 switch (R.Kind) {
2142 case Result::RK_Keyword:
2143 return R.Keyword;
2144
2145 case Result::RK_Pattern:
2146 return R.Pattern->getTypedText();
2147
2148 case Result::RK_Macro:
2149 return R.Macro->getName();
2150
2151 case Result::RK_Declaration:
2152 // Handle declarations below.
2153 break;
Douglas Gregor54f01612009-11-19 00:01:57 +00002154 }
Douglas Gregorab0b4f12010-01-13 23:24:38 +00002155
2156 DeclarationName Name = R.Declaration->getDeclName();
Douglas Gregor54f01612009-11-19 00:01:57 +00002157
Douglas Gregorab0b4f12010-01-13 23:24:38 +00002158 // If the name is a simple identifier (by far the common case), or a
2159 // zero-argument selector, just return a reference to that identifier.
2160 if (IdentifierInfo *Id = Name.getAsIdentifierInfo())
2161 return Id->getName();
2162 if (Name.isObjCZeroArgSelector())
2163 if (IdentifierInfo *Id
2164 = Name.getObjCSelector().getIdentifierInfoForSlot(0))
2165 return Id->getName();
2166
2167 Saved = Name.getAsString();
2168 return Saved;
2169 }
2170
2171 bool operator()(const Result &X, const Result &Y) const {
2172 std::string XSaved, YSaved;
2173 llvm::StringRef XStr = getOrderedName(X, XSaved);
2174 llvm::StringRef YStr = getOrderedName(Y, YSaved);
2175 int cmp = XStr.compare_lower(YStr);
2176 if (cmp)
2177 return cmp < 0;
Douglas Gregor86d9a522009-09-21 16:56:56 +00002178
2179 // Non-hidden names precede hidden names.
2180 if (X.Hidden != Y.Hidden)
2181 return !X.Hidden;
2182
Douglas Gregoreb5758b2009-09-23 22:26:46 +00002183 // Non-nested-name-specifiers precede nested-name-specifiers.
2184 if (X.StartsNestedNameSpecifier != Y.StartsNestedNameSpecifier)
2185 return !X.StartsNestedNameSpecifier;
2186
Douglas Gregor86d9a522009-09-21 16:56:56 +00002187 return false;
2188 }
2189 };
2190}
2191
Douglas Gregor1827e102010-08-16 16:18:59 +00002192unsigned clang::getMacroUsagePriority(llvm::StringRef MacroName,
2193 bool PreferredTypeIsPointer) {
2194 unsigned Priority = CCP_Macro;
2195
2196 // Treat the "nil" and "NULL" macros as null pointer constants.
2197 if (MacroName.equals("nil") || MacroName.equals("NULL")) {
2198 Priority = CCP_Constant;
2199 if (PreferredTypeIsPointer)
2200 Priority = Priority / CCF_SimilarTypeMatch;
2201 }
2202
2203 return Priority;
2204}
2205
Douglas Gregor590c7d52010-07-08 20:55:51 +00002206static void AddMacroResults(Preprocessor &PP, ResultBuilder &Results,
2207 bool TargetTypeIsPointer = false) {
2208 typedef CodeCompleteConsumer::Result Result;
2209
Douglas Gregor3f7c7f42009-10-30 16:50:04 +00002210 Results.EnterNewScope();
Douglas Gregor0c8296d2009-11-07 00:00:49 +00002211 for (Preprocessor::macro_iterator M = PP.macro_begin(),
2212 MEnd = PP.macro_end();
Douglas Gregor590c7d52010-07-08 20:55:51 +00002213 M != MEnd; ++M) {
Douglas Gregor1827e102010-08-16 16:18:59 +00002214 Results.AddResult(Result(M->first,
2215 getMacroUsagePriority(M->first->getName(),
2216 TargetTypeIsPointer)));
Douglas Gregor590c7d52010-07-08 20:55:51 +00002217 }
Douglas Gregor3f7c7f42009-10-30 16:50:04 +00002218 Results.ExitScope();
2219}
2220
Douglas Gregoraa5f77b2010-08-23 21:54:33 +00002221static void AddPrettyFunctionResults(const LangOptions &LangOpts,
2222 ResultBuilder &Results) {
2223 typedef CodeCompleteConsumer::Result Result;
2224
2225 Results.EnterNewScope();
2226 Results.AddResult(Result("__PRETTY_FUNCTION__", CCP_Constant));
2227 Results.AddResult(Result("__FUNCTION__", CCP_Constant));
2228 if (LangOpts.C99 || LangOpts.CPlusPlus0x)
2229 Results.AddResult(Result("__func__", CCP_Constant));
2230 Results.ExitScope();
2231}
2232
Daniel Dunbar3a2838d2009-11-13 08:58:20 +00002233static void HandleCodeCompleteResults(Sema *S,
2234 CodeCompleteConsumer *CodeCompleter,
Douglas Gregore6b1bb62010-08-11 21:23:17 +00002235 CodeCompletionContext Context,
2236 CodeCompleteConsumer::Result *Results,
2237 unsigned NumResults) {
Douglas Gregor86d9a522009-09-21 16:56:56 +00002238 std::stable_sort(Results, Results + NumResults, SortCodeCompleteResult());
2239
2240 if (CodeCompleter)
Douglas Gregore6b1bb62010-08-11 21:23:17 +00002241 CodeCompleter->ProcessCodeCompleteResults(*S, Context, Results, NumResults);
Douglas Gregor54f01612009-11-19 00:01:57 +00002242
2243 for (unsigned I = 0; I != NumResults; ++I)
2244 Results[I].Destroy();
Douglas Gregor86d9a522009-09-21 16:56:56 +00002245}
2246
Douglas Gregore6b1bb62010-08-11 21:23:17 +00002247static enum CodeCompletionContext::Kind mapCodeCompletionContext(Sema &S,
2248 Sema::ParserCompletionContext PCC) {
2249 switch (PCC) {
2250 case Action::PCC_Namespace:
2251 return CodeCompletionContext::CCC_TopLevel;
2252
2253 case Action::PCC_Class:
2254 return CodeCompletionContext::CCC_ClassStructUnion;
2255
2256 case Action::PCC_ObjCInterface:
2257 return CodeCompletionContext::CCC_ObjCInterface;
2258
2259 case Action::PCC_ObjCImplementation:
2260 return CodeCompletionContext::CCC_ObjCImplementation;
2261
2262 case Action::PCC_ObjCInstanceVariableList:
2263 return CodeCompletionContext::CCC_ObjCIvarList;
2264
2265 case Action::PCC_Template:
2266 case Action::PCC_MemberTemplate:
2267 case Action::PCC_RecoveryInFunction:
2268 return CodeCompletionContext::CCC_Other;
2269
2270 case Action::PCC_Expression:
2271 case Action::PCC_ForInit:
2272 case Action::PCC_Condition:
2273 return CodeCompletionContext::CCC_Expression;
2274
2275 case Action::PCC_Statement:
2276 return CodeCompletionContext::CCC_Statement;
Douglas Gregor72db1082010-08-24 01:11:00 +00002277
2278 case Action::PCC_Type:
2279 return CodeCompletionContext::CCC_Type;
Douglas Gregore6b1bb62010-08-11 21:23:17 +00002280 }
2281
2282 return CodeCompletionContext::CCC_Other;
2283}
2284
Douglas Gregor01dfea02010-01-10 23:08:15 +00002285void Sema::CodeCompleteOrdinaryName(Scope *S,
Douglas Gregore6b1bb62010-08-11 21:23:17 +00002286 ParserCompletionContext CompletionContext) {
Douglas Gregor2a7925c2009-12-07 09:54:55 +00002287 typedef CodeCompleteConsumer::Result Result;
Douglas Gregor2ccccb32010-08-23 18:23:48 +00002288 ResultBuilder Results(*this);
Douglas Gregor01dfea02010-01-10 23:08:15 +00002289
2290 // Determine how to filter results, e.g., so that the names of
2291 // values (functions, enumerators, function templates, etc.) are
2292 // only allowed where we can have an expression.
2293 switch (CompletionContext) {
Douglas Gregore6b1bb62010-08-11 21:23:17 +00002294 case PCC_Namespace:
2295 case PCC_Class:
2296 case PCC_ObjCInterface:
2297 case PCC_ObjCImplementation:
2298 case PCC_ObjCInstanceVariableList:
2299 case PCC_Template:
2300 case PCC_MemberTemplate:
Douglas Gregor72db1082010-08-24 01:11:00 +00002301 case PCC_Type:
Douglas Gregor01dfea02010-01-10 23:08:15 +00002302 Results.setFilter(&ResultBuilder::IsOrdinaryNonValueName);
2303 break;
2304
Douglas Gregore6b1bb62010-08-11 21:23:17 +00002305 case PCC_Expression:
2306 case PCC_Statement:
2307 case PCC_ForInit:
2308 case PCC_Condition:
Douglas Gregor4710e5b2010-05-28 00:49:12 +00002309 if (WantTypesInContext(CompletionContext, getLangOptions()))
2310 Results.setFilter(&ResultBuilder::IsOrdinaryName);
2311 else
2312 Results.setFilter(&ResultBuilder::IsOrdinaryNonTypeName);
Douglas Gregor01dfea02010-01-10 23:08:15 +00002313 break;
Douglas Gregordc845342010-05-25 05:58:43 +00002314
Douglas Gregore6b1bb62010-08-11 21:23:17 +00002315 case PCC_RecoveryInFunction:
Douglas Gregordc845342010-05-25 05:58:43 +00002316 // Unfiltered
2317 break;
Douglas Gregor01dfea02010-01-10 23:08:15 +00002318 }
2319
Douglas Gregor1ca6ae82010-01-14 01:09:38 +00002320 CodeCompletionDeclConsumer Consumer(Results, CurContext);
Douglas Gregor8071e422010-08-15 06:18:01 +00002321 LookupVisibleDecls(S, LookupOrdinaryName, Consumer,
2322 CodeCompleter->includeGlobals());
Douglas Gregor2a7925c2009-12-07 09:54:55 +00002323
2324 Results.EnterNewScope();
Douglas Gregorbca403c2010-01-13 23:51:12 +00002325 AddOrdinaryNameResults(CompletionContext, S, *this, Results);
Douglas Gregor2a7925c2009-12-07 09:54:55 +00002326 Results.ExitScope();
2327
Douglas Gregoraa5f77b2010-08-23 21:54:33 +00002328 switch (CompletionContext) {
Douglas Gregor72db1082010-08-24 01:11:00 +00002329 case PCC_Expression:
2330 case PCC_Statement:
2331 case PCC_RecoveryInFunction:
2332 if (S->getFnParent())
2333 AddPrettyFunctionResults(PP.getLangOptions(), Results);
2334 break;
2335
2336 case PCC_Namespace:
2337 case PCC_Class:
2338 case PCC_ObjCInterface:
2339 case PCC_ObjCImplementation:
2340 case PCC_ObjCInstanceVariableList:
2341 case PCC_Template:
2342 case PCC_MemberTemplate:
2343 case PCC_ForInit:
2344 case PCC_Condition:
2345 case PCC_Type:
2346 break;
Douglas Gregoraa5f77b2010-08-23 21:54:33 +00002347 }
2348
Douglas Gregor0c8296d2009-11-07 00:00:49 +00002349 if (CodeCompleter->includeMacros())
Douglas Gregorbca403c2010-01-13 23:51:12 +00002350 AddMacroResults(PP, Results);
Douglas Gregoraa5f77b2010-08-23 21:54:33 +00002351
Douglas Gregore6b1bb62010-08-11 21:23:17 +00002352 HandleCodeCompleteResults(this, CodeCompleter,
2353 mapCodeCompletionContext(*this, CompletionContext),
2354 Results.data(),Results.size());
Douglas Gregor791215b2009-09-21 20:51:25 +00002355}
2356
Douglas Gregor2ccccb32010-08-23 18:23:48 +00002357void Sema::CodeCompleteDeclarator(Scope *S,
2358 bool AllowNonIdentifiers,
2359 bool AllowNestedNameSpecifiers) {
2360 typedef CodeCompleteConsumer::Result Result;
2361 ResultBuilder Results(*this);
2362 Results.EnterNewScope();
2363
2364 // Type qualifiers can come after names.
2365 Results.AddResult(Result("const"));
2366 Results.AddResult(Result("volatile"));
2367 if (getLangOptions().C99)
2368 Results.AddResult(Result("restrict"));
2369
2370 if (getLangOptions().CPlusPlus) {
2371 if (AllowNonIdentifiers) {
2372 Results.AddResult(Result("operator"));
2373 }
2374
2375 // Add nested-name-specifiers.
2376 if (AllowNestedNameSpecifiers) {
2377 Results.allowNestedNameSpecifiers();
2378 CodeCompletionDeclConsumer Consumer(Results, CurContext);
2379 LookupVisibleDecls(S, LookupNestedNameSpecifierName, Consumer,
2380 CodeCompleter->includeGlobals());
2381 }
2382 }
2383 Results.ExitScope();
2384
Douglas Gregor4497dd42010-08-24 04:59:56 +00002385 // Note that we intentionally suppress macro results here, since we do not
2386 // encourage using macros to produce the names of entities.
2387
Douglas Gregor2ccccb32010-08-23 18:23:48 +00002388 HandleCodeCompleteResults(this, CodeCompleter,
2389 AllowNestedNameSpecifiers
2390 ? CodeCompletionContext::CCC_PotentiallyQualifiedName
2391 : CodeCompletionContext::CCC_Name,
2392 Results.data(), Results.size());
2393}
2394
Douglas Gregorfb629412010-08-23 21:17:50 +00002395struct Sema::CodeCompleteExpressionData {
2396 CodeCompleteExpressionData(QualType PreferredType = QualType())
2397 : PreferredType(PreferredType), IntegralConstantExpression(false),
2398 ObjCCollection(false) { }
2399
2400 QualType PreferredType;
2401 bool IntegralConstantExpression;
2402 bool ObjCCollection;
2403 llvm::SmallVector<Decl *, 4> IgnoreDecls;
2404};
2405
Douglas Gregor5ac3bdb2010-05-30 01:49:25 +00002406/// \brief Perform code-completion in an expression context when we know what
2407/// type we're looking for.
Douglas Gregorf9578432010-07-28 21:50:18 +00002408///
2409/// \param IntegralConstantExpression Only permit integral constant
2410/// expressions.
Douglas Gregorfb629412010-08-23 21:17:50 +00002411void Sema::CodeCompleteExpression(Scope *S,
2412 const CodeCompleteExpressionData &Data) {
Douglas Gregor5ac3bdb2010-05-30 01:49:25 +00002413 typedef CodeCompleteConsumer::Result Result;
2414 ResultBuilder Results(*this);
2415
Douglas Gregorfb629412010-08-23 21:17:50 +00002416 if (Data.ObjCCollection)
2417 Results.setFilter(&ResultBuilder::IsObjCCollection);
2418 else if (Data.IntegralConstantExpression)
Douglas Gregorf9578432010-07-28 21:50:18 +00002419 Results.setFilter(&ResultBuilder::IsIntegralConstantValue);
Douglas Gregore6b1bb62010-08-11 21:23:17 +00002420 else if (WantTypesInContext(PCC_Expression, getLangOptions()))
Douglas Gregor5ac3bdb2010-05-30 01:49:25 +00002421 Results.setFilter(&ResultBuilder::IsOrdinaryName);
2422 else
2423 Results.setFilter(&ResultBuilder::IsOrdinaryNonTypeName);
Douglas Gregorfb629412010-08-23 21:17:50 +00002424
2425 if (!Data.PreferredType.isNull())
2426 Results.setPreferredType(Data.PreferredType.getNonReferenceType());
2427
2428 // Ignore any declarations that we were told that we don't care about.
2429 for (unsigned I = 0, N = Data.IgnoreDecls.size(); I != N; ++I)
2430 Results.Ignore(Data.IgnoreDecls[I]);
Douglas Gregor5ac3bdb2010-05-30 01:49:25 +00002431
2432 CodeCompletionDeclConsumer Consumer(Results, CurContext);
Douglas Gregor8071e422010-08-15 06:18:01 +00002433 LookupVisibleDecls(S, LookupOrdinaryName, Consumer,
2434 CodeCompleter->includeGlobals());
Douglas Gregor5ac3bdb2010-05-30 01:49:25 +00002435
2436 Results.EnterNewScope();
Douglas Gregore6b1bb62010-08-11 21:23:17 +00002437 AddOrdinaryNameResults(PCC_Expression, S, *this, Results);
Douglas Gregor5ac3bdb2010-05-30 01:49:25 +00002438 Results.ExitScope();
2439
Douglas Gregor590c7d52010-07-08 20:55:51 +00002440 bool PreferredTypeIsPointer = false;
Douglas Gregorfb629412010-08-23 21:17:50 +00002441 if (!Data.PreferredType.isNull())
2442 PreferredTypeIsPointer = Data.PreferredType->isAnyPointerType()
2443 || Data.PreferredType->isMemberPointerType()
2444 || Data.PreferredType->isBlockPointerType();
Douglas Gregor590c7d52010-07-08 20:55:51 +00002445
Douglas Gregoraa5f77b2010-08-23 21:54:33 +00002446 if (S->getFnParent() &&
2447 !Data.ObjCCollection &&
2448 !Data.IntegralConstantExpression)
2449 AddPrettyFunctionResults(PP.getLangOptions(), Results);
2450
Douglas Gregor5ac3bdb2010-05-30 01:49:25 +00002451 if (CodeCompleter->includeMacros())
Douglas Gregor590c7d52010-07-08 20:55:51 +00002452 AddMacroResults(PP, Results, PreferredTypeIsPointer);
Douglas Gregore6b1bb62010-08-11 21:23:17 +00002453 HandleCodeCompleteResults(this, CodeCompleter,
Douglas Gregorfb629412010-08-23 21:17:50 +00002454 CodeCompletionContext(CodeCompletionContext::CCC_Expression,
2455 Data.PreferredType),
Douglas Gregore6b1bb62010-08-11 21:23:17 +00002456 Results.data(),Results.size());
Douglas Gregor5ac3bdb2010-05-30 01:49:25 +00002457}
2458
2459
Douglas Gregor95ac6552009-11-18 01:29:26 +00002460static void AddObjCProperties(ObjCContainerDecl *Container,
Douglas Gregor322328b2009-11-18 22:32:06 +00002461 bool AllowCategories,
Douglas Gregor95ac6552009-11-18 01:29:26 +00002462 DeclContext *CurContext,
2463 ResultBuilder &Results) {
2464 typedef CodeCompleteConsumer::Result Result;
2465
2466 // Add properties in this container.
2467 for (ObjCContainerDecl::prop_iterator P = Container->prop_begin(),
2468 PEnd = Container->prop_end();
2469 P != PEnd;
2470 ++P)
2471 Results.MaybeAddResult(Result(*P, 0), CurContext);
2472
2473 // Add properties in referenced protocols.
2474 if (ObjCProtocolDecl *Protocol = dyn_cast<ObjCProtocolDecl>(Container)) {
2475 for (ObjCProtocolDecl::protocol_iterator P = Protocol->protocol_begin(),
2476 PEnd = Protocol->protocol_end();
2477 P != PEnd; ++P)
Douglas Gregor322328b2009-11-18 22:32:06 +00002478 AddObjCProperties(*P, AllowCategories, CurContext, Results);
Douglas Gregor95ac6552009-11-18 01:29:26 +00002479 } else if (ObjCInterfaceDecl *IFace = dyn_cast<ObjCInterfaceDecl>(Container)){
Douglas Gregor322328b2009-11-18 22:32:06 +00002480 if (AllowCategories) {
2481 // Look through categories.
2482 for (ObjCCategoryDecl *Category = IFace->getCategoryList();
2483 Category; Category = Category->getNextClassCategory())
2484 AddObjCProperties(Category, AllowCategories, CurContext, Results);
2485 }
Douglas Gregor95ac6552009-11-18 01:29:26 +00002486
2487 // Look through protocols.
2488 for (ObjCInterfaceDecl::protocol_iterator I = IFace->protocol_begin(),
2489 E = IFace->protocol_end();
2490 I != E; ++I)
Douglas Gregor322328b2009-11-18 22:32:06 +00002491 AddObjCProperties(*I, AllowCategories, CurContext, Results);
Douglas Gregor95ac6552009-11-18 01:29:26 +00002492
2493 // Look in the superclass.
2494 if (IFace->getSuperClass())
Douglas Gregor322328b2009-11-18 22:32:06 +00002495 AddObjCProperties(IFace->getSuperClass(), AllowCategories, CurContext,
2496 Results);
Douglas Gregor95ac6552009-11-18 01:29:26 +00002497 } else if (const ObjCCategoryDecl *Category
2498 = dyn_cast<ObjCCategoryDecl>(Container)) {
2499 // Look through protocols.
2500 for (ObjCInterfaceDecl::protocol_iterator P = Category->protocol_begin(),
2501 PEnd = Category->protocol_end();
2502 P != PEnd; ++P)
Douglas Gregor322328b2009-11-18 22:32:06 +00002503 AddObjCProperties(*P, AllowCategories, CurContext, Results);
Douglas Gregor95ac6552009-11-18 01:29:26 +00002504 }
2505}
2506
Douglas Gregor81b747b2009-09-17 21:32:03 +00002507void Sema::CodeCompleteMemberReferenceExpr(Scope *S, ExprTy *BaseE,
2508 SourceLocation OpLoc,
2509 bool IsArrow) {
2510 if (!BaseE || !CodeCompleter)
2511 return;
2512
Douglas Gregor86d9a522009-09-21 16:56:56 +00002513 typedef CodeCompleteConsumer::Result Result;
2514
Douglas Gregor81b747b2009-09-17 21:32:03 +00002515 Expr *Base = static_cast<Expr *>(BaseE);
2516 QualType BaseType = Base->getType();
Douglas Gregor86d9a522009-09-21 16:56:56 +00002517
2518 if (IsArrow) {
2519 if (const PointerType *Ptr = BaseType->getAs<PointerType>())
2520 BaseType = Ptr->getPointeeType();
2521 else if (BaseType->isObjCObjectPointerType())
2522 /*Do nothing*/ ;
2523 else
2524 return;
2525 }
2526
Douglas Gregoreb5758b2009-09-23 22:26:46 +00002527 ResultBuilder Results(*this, &ResultBuilder::IsMember);
Douglas Gregor95ac6552009-11-18 01:29:26 +00002528 Results.EnterNewScope();
2529 if (const RecordType *Record = BaseType->getAs<RecordType>()) {
2530 // Access to a C/C++ class, struct, or union.
Douglas Gregor45bcd432010-01-14 03:21:49 +00002531 Results.allowNestedNameSpecifiers();
Douglas Gregor0cc84042010-01-14 15:47:35 +00002532 CodeCompletionDeclConsumer Consumer(Results, CurContext);
Douglas Gregor8071e422010-08-15 06:18:01 +00002533 LookupVisibleDecls(Record->getDecl(), LookupMemberName, Consumer,
2534 CodeCompleter->includeGlobals());
Daniel Dunbar3a2838d2009-11-13 08:58:20 +00002535
Douglas Gregor95ac6552009-11-18 01:29:26 +00002536 if (getLangOptions().CPlusPlus) {
2537 if (!Results.empty()) {
2538 // The "template" keyword can follow "->" or "." in the grammar.
2539 // However, we only want to suggest the template keyword if something
2540 // is dependent.
2541 bool IsDependent = BaseType->isDependentType();
2542 if (!IsDependent) {
2543 for (Scope *DepScope = S; DepScope; DepScope = DepScope->getParent())
2544 if (DeclContext *Ctx = (DeclContext *)DepScope->getEntity()) {
2545 IsDependent = Ctx->isDependentContext();
2546 break;
2547 }
2548 }
Daniel Dunbar3a2838d2009-11-13 08:58:20 +00002549
Douglas Gregor95ac6552009-11-18 01:29:26 +00002550 if (IsDependent)
Douglas Gregora4477812010-01-14 16:01:26 +00002551 Results.AddResult(Result("template"));
Daniel Dunbar3a2838d2009-11-13 08:58:20 +00002552 }
Daniel Dunbar3a2838d2009-11-13 08:58:20 +00002553 }
Douglas Gregor95ac6552009-11-18 01:29:26 +00002554 } else if (!IsArrow && BaseType->getAsObjCInterfacePointerType()) {
2555 // Objective-C property reference.
2556
2557 // Add property results based on our interface.
2558 const ObjCObjectPointerType *ObjCPtr
2559 = BaseType->getAsObjCInterfacePointerType();
2560 assert(ObjCPtr && "Non-NULL pointer guaranteed above!");
Douglas Gregor322328b2009-11-18 22:32:06 +00002561 AddObjCProperties(ObjCPtr->getInterfaceDecl(), true, CurContext, Results);
Douglas Gregor95ac6552009-11-18 01:29:26 +00002562
2563 // Add properties from the protocols in a qualified interface.
2564 for (ObjCObjectPointerType::qual_iterator I = ObjCPtr->qual_begin(),
2565 E = ObjCPtr->qual_end();
2566 I != E; ++I)
Douglas Gregor322328b2009-11-18 22:32:06 +00002567 AddObjCProperties(*I, true, CurContext, Results);
Douglas Gregor95ac6552009-11-18 01:29:26 +00002568 } else if ((IsArrow && BaseType->isObjCObjectPointerType()) ||
John McCallc12c5bb2010-05-15 11:32:37 +00002569 (!IsArrow && BaseType->isObjCObjectType())) {
Douglas Gregor95ac6552009-11-18 01:29:26 +00002570 // Objective-C instance variable access.
2571 ObjCInterfaceDecl *Class = 0;
2572 if (const ObjCObjectPointerType *ObjCPtr
2573 = BaseType->getAs<ObjCObjectPointerType>())
2574 Class = ObjCPtr->getInterfaceDecl();
2575 else
John McCallc12c5bb2010-05-15 11:32:37 +00002576 Class = BaseType->getAs<ObjCObjectType>()->getInterface();
Douglas Gregor95ac6552009-11-18 01:29:26 +00002577
2578 // Add all ivars from this class and its superclasses.
Douglas Gregor80f4f4c2010-01-14 16:08:12 +00002579 if (Class) {
2580 CodeCompletionDeclConsumer Consumer(Results, CurContext);
2581 Results.setFilter(&ResultBuilder::IsObjCIvar);
Douglas Gregor8071e422010-08-15 06:18:01 +00002582 LookupVisibleDecls(Class, LookupMemberName, Consumer,
2583 CodeCompleter->includeGlobals());
Douglas Gregor95ac6552009-11-18 01:29:26 +00002584 }
Douglas Gregor86d9a522009-09-21 16:56:56 +00002585 }
Douglas Gregor95ac6552009-11-18 01:29:26 +00002586
2587 // FIXME: How do we cope with isa?
2588
2589 Results.ExitScope();
Daniel Dunbar3a2838d2009-11-13 08:58:20 +00002590
Daniel Dunbar3a2838d2009-11-13 08:58:20 +00002591 // Hand off the results found for code completion.
Douglas Gregore6b1bb62010-08-11 21:23:17 +00002592 HandleCodeCompleteResults(this, CodeCompleter,
2593 CodeCompletionContext(CodeCompletionContext::CCC_MemberAccess,
2594 BaseType),
2595 Results.data(),Results.size());
Douglas Gregor81b747b2009-09-17 21:32:03 +00002596}
2597
Douglas Gregor374929f2009-09-18 15:37:17 +00002598void Sema::CodeCompleteTag(Scope *S, unsigned TagSpec) {
2599 if (!CodeCompleter)
2600 return;
2601
Douglas Gregor86d9a522009-09-21 16:56:56 +00002602 typedef CodeCompleteConsumer::Result Result;
2603 ResultBuilder::LookupFilter Filter = 0;
Douglas Gregore6b1bb62010-08-11 21:23:17 +00002604 enum CodeCompletionContext::Kind ContextKind
2605 = CodeCompletionContext::CCC_Other;
Douglas Gregor374929f2009-09-18 15:37:17 +00002606 switch ((DeclSpec::TST)TagSpec) {
2607 case DeclSpec::TST_enum:
Douglas Gregor86d9a522009-09-21 16:56:56 +00002608 Filter = &ResultBuilder::IsEnum;
Douglas Gregore6b1bb62010-08-11 21:23:17 +00002609 ContextKind = CodeCompletionContext::CCC_EnumTag;
Douglas Gregor374929f2009-09-18 15:37:17 +00002610 break;
2611
2612 case DeclSpec::TST_union:
Douglas Gregor86d9a522009-09-21 16:56:56 +00002613 Filter = &ResultBuilder::IsUnion;
Douglas Gregore6b1bb62010-08-11 21:23:17 +00002614 ContextKind = CodeCompletionContext::CCC_UnionTag;
Douglas Gregor374929f2009-09-18 15:37:17 +00002615 break;
2616
2617 case DeclSpec::TST_struct:
Douglas Gregor374929f2009-09-18 15:37:17 +00002618 case DeclSpec::TST_class:
Douglas Gregor86d9a522009-09-21 16:56:56 +00002619 Filter = &ResultBuilder::IsClassOrStruct;
Douglas Gregore6b1bb62010-08-11 21:23:17 +00002620 ContextKind = CodeCompletionContext::CCC_ClassOrStructTag;
Douglas Gregor374929f2009-09-18 15:37:17 +00002621 break;
2622
2623 default:
2624 assert(false && "Unknown type specifier kind in CodeCompleteTag");
2625 return;
2626 }
Douglas Gregor86d9a522009-09-21 16:56:56 +00002627
John McCall0d6b1642010-04-23 18:46:30 +00002628 ResultBuilder Results(*this);
Douglas Gregor5d2fc402010-01-14 03:27:13 +00002629 CodeCompletionDeclConsumer Consumer(Results, CurContext);
John McCall0d6b1642010-04-23 18:46:30 +00002630
2631 // First pass: look for tags.
2632 Results.setFilter(Filter);
Douglas Gregor8071e422010-08-15 06:18:01 +00002633 LookupVisibleDecls(S, LookupTagName, Consumer,
2634 CodeCompleter->includeGlobals());
John McCall0d6b1642010-04-23 18:46:30 +00002635
Douglas Gregor8071e422010-08-15 06:18:01 +00002636 if (CodeCompleter->includeGlobals()) {
2637 // Second pass: look for nested name specifiers.
2638 Results.setFilter(&ResultBuilder::IsNestedNameSpecifier);
2639 LookupVisibleDecls(S, LookupNestedNameSpecifierName, Consumer);
2640 }
Douglas Gregor86d9a522009-09-21 16:56:56 +00002641
Douglas Gregore6b1bb62010-08-11 21:23:17 +00002642 HandleCodeCompleteResults(this, CodeCompleter, ContextKind,
2643 Results.data(),Results.size());
Douglas Gregor374929f2009-09-18 15:37:17 +00002644}
2645
Douglas Gregor3e1005f2009-09-21 18:10:23 +00002646void Sema::CodeCompleteCase(Scope *S) {
2647 if (getSwitchStack().empty() || !CodeCompleter)
2648 return;
2649
2650 SwitchStmt *Switch = getSwitchStack().back();
Douglas Gregorf9578432010-07-28 21:50:18 +00002651 if (!Switch->getCond()->getType()->isEnumeralType()) {
Douglas Gregorfb629412010-08-23 21:17:50 +00002652 CodeCompleteExpressionData Data(Switch->getCond()->getType());
2653 Data.IntegralConstantExpression = true;
2654 CodeCompleteExpression(S, Data);
Douglas Gregor3e1005f2009-09-21 18:10:23 +00002655 return;
Douglas Gregorf9578432010-07-28 21:50:18 +00002656 }
Douglas Gregor3e1005f2009-09-21 18:10:23 +00002657
2658 // Code-complete the cases of a switch statement over an enumeration type
2659 // by providing the list of
2660 EnumDecl *Enum = Switch->getCond()->getType()->getAs<EnumType>()->getDecl();
2661
2662 // Determine which enumerators we have already seen in the switch statement.
2663 // FIXME: Ideally, we would also be able to look *past* the code-completion
2664 // token, in case we are code-completing in the middle of the switch and not
2665 // at the end. However, we aren't able to do so at the moment.
2666 llvm::SmallPtrSet<EnumConstantDecl *, 8> EnumeratorsSeen;
Douglas Gregorb9d0ef72009-09-21 19:57:38 +00002667 NestedNameSpecifier *Qualifier = 0;
Douglas Gregor3e1005f2009-09-21 18:10:23 +00002668 for (SwitchCase *SC = Switch->getSwitchCaseList(); SC;
2669 SC = SC->getNextSwitchCase()) {
2670 CaseStmt *Case = dyn_cast<CaseStmt>(SC);
2671 if (!Case)
2672 continue;
2673
2674 Expr *CaseVal = Case->getLHS()->IgnoreParenCasts();
2675 if (DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(CaseVal))
2676 if (EnumConstantDecl *Enumerator
2677 = dyn_cast<EnumConstantDecl>(DRE->getDecl())) {
2678 // We look into the AST of the case statement to determine which
2679 // enumerator was named. Alternatively, we could compute the value of
2680 // the integral constant expression, then compare it against the
2681 // values of each enumerator. However, value-based approach would not
2682 // work as well with C++ templates where enumerators declared within a
2683 // template are type- and value-dependent.
2684 EnumeratorsSeen.insert(Enumerator);
2685
Douglas Gregorb9d0ef72009-09-21 19:57:38 +00002686 // If this is a qualified-id, keep track of the nested-name-specifier
2687 // so that we can reproduce it as part of code completion, e.g.,
Douglas Gregor3e1005f2009-09-21 18:10:23 +00002688 //
2689 // switch (TagD.getKind()) {
2690 // case TagDecl::TK_enum:
2691 // break;
2692 // case XXX
2693 //
Douglas Gregorb9d0ef72009-09-21 19:57:38 +00002694 // At the XXX, our completions are TagDecl::TK_union,
Douglas Gregor3e1005f2009-09-21 18:10:23 +00002695 // TagDecl::TK_struct, and TagDecl::TK_class, rather than TK_union,
2696 // TK_struct, and TK_class.
Douglas Gregora2813ce2009-10-23 18:54:35 +00002697 Qualifier = DRE->getQualifier();
Douglas Gregor3e1005f2009-09-21 18:10:23 +00002698 }
2699 }
2700
Douglas Gregorb9d0ef72009-09-21 19:57:38 +00002701 if (getLangOptions().CPlusPlus && !Qualifier && EnumeratorsSeen.empty()) {
2702 // If there are no prior enumerators in C++, check whether we have to
2703 // qualify the names of the enumerators that we suggest, because they
2704 // may not be visible in this scope.
2705 Qualifier = getRequiredQualification(Context, CurContext,
2706 Enum->getDeclContext());
2707
2708 // FIXME: Scoped enums need to start with "EnumDecl" as the context!
2709 }
2710
Douglas Gregor3e1005f2009-09-21 18:10:23 +00002711 // Add any enumerators that have not yet been mentioned.
2712 ResultBuilder Results(*this);
2713 Results.EnterNewScope();
2714 for (EnumDecl::enumerator_iterator E = Enum->enumerator_begin(),
2715 EEnd = Enum->enumerator_end();
2716 E != EEnd; ++E) {
2717 if (EnumeratorsSeen.count(*E))
2718 continue;
2719
Douglas Gregor608300b2010-01-14 16:14:35 +00002720 Results.AddResult(CodeCompleteConsumer::Result(*E, Qualifier),
2721 CurContext, 0, false);
Douglas Gregor3e1005f2009-09-21 18:10:23 +00002722 }
2723 Results.ExitScope();
Douglas Gregor2f880e42010-04-06 20:02:15 +00002724
Douglas Gregor0c8296d2009-11-07 00:00:49 +00002725 if (CodeCompleter->includeMacros())
Douglas Gregorbca403c2010-01-13 23:51:12 +00002726 AddMacroResults(PP, Results);
Douglas Gregore6b1bb62010-08-11 21:23:17 +00002727 HandleCodeCompleteResults(this, CodeCompleter,
2728 CodeCompletionContext::CCC_Expression,
2729 Results.data(),Results.size());
Douglas Gregor3e1005f2009-09-21 18:10:23 +00002730}
2731
Douglas Gregor9c6a0e92009-09-22 15:41:20 +00002732namespace {
2733 struct IsBetterOverloadCandidate {
2734 Sema &S;
John McCall5769d612010-02-08 23:07:23 +00002735 SourceLocation Loc;
Douglas Gregor9c6a0e92009-09-22 15:41:20 +00002736
2737 public:
John McCall5769d612010-02-08 23:07:23 +00002738 explicit IsBetterOverloadCandidate(Sema &S, SourceLocation Loc)
2739 : S(S), Loc(Loc) { }
Douglas Gregor9c6a0e92009-09-22 15:41:20 +00002740
2741 bool
2742 operator()(const OverloadCandidate &X, const OverloadCandidate &Y) const {
John McCall5769d612010-02-08 23:07:23 +00002743 return S.isBetterOverloadCandidate(X, Y, Loc);
Douglas Gregor9c6a0e92009-09-22 15:41:20 +00002744 }
2745 };
2746}
2747
Douglas Gregord28dcd72010-05-30 06:10:08 +00002748static bool anyNullArguments(Expr **Args, unsigned NumArgs) {
2749 if (NumArgs && !Args)
2750 return true;
2751
2752 for (unsigned I = 0; I != NumArgs; ++I)
2753 if (!Args[I])
2754 return true;
2755
2756 return false;
2757}
2758
Douglas Gregor9c6a0e92009-09-22 15:41:20 +00002759void Sema::CodeCompleteCall(Scope *S, ExprTy *FnIn,
2760 ExprTy **ArgsIn, unsigned NumArgs) {
2761 if (!CodeCompleter)
2762 return;
Douglas Gregoref96eac2009-12-11 19:06:04 +00002763
2764 // When we're code-completing for a call, we fall back to ordinary
2765 // name code-completion whenever we can't produce specific
2766 // results. We may want to revisit this strategy in the future,
2767 // e.g., by merging the two kinds of results.
2768
Douglas Gregor9c6a0e92009-09-22 15:41:20 +00002769 Expr *Fn = (Expr *)FnIn;
2770 Expr **Args = (Expr **)ArgsIn;
Douglas Gregoref96eac2009-12-11 19:06:04 +00002771
Douglas Gregor9c6a0e92009-09-22 15:41:20 +00002772 // Ignore type-dependent call expressions entirely.
Douglas Gregord28dcd72010-05-30 06:10:08 +00002773 if (!Fn || Fn->isTypeDependent() || anyNullArguments(Args, NumArgs) ||
Douglas Gregoref96eac2009-12-11 19:06:04 +00002774 Expr::hasAnyTypeDependentArguments(Args, NumArgs)) {
Douglas Gregore6b1bb62010-08-11 21:23:17 +00002775 CodeCompleteOrdinaryName(S, PCC_Expression);
Douglas Gregor9c6a0e92009-09-22 15:41:20 +00002776 return;
Douglas Gregoref96eac2009-12-11 19:06:04 +00002777 }
Douglas Gregor9c6a0e92009-09-22 15:41:20 +00002778
John McCall3b4294e2009-12-16 12:17:52 +00002779 // Build an overload candidate set based on the functions we find.
John McCall5769d612010-02-08 23:07:23 +00002780 SourceLocation Loc = Fn->getExprLoc();
2781 OverloadCandidateSet CandidateSet(Loc);
John McCall3b4294e2009-12-16 12:17:52 +00002782
Douglas Gregor9c6a0e92009-09-22 15:41:20 +00002783 // FIXME: What if we're calling something that isn't a function declaration?
2784 // FIXME: What if we're calling a pseudo-destructor?
2785 // FIXME: What if we're calling a member function?
2786
Douglas Gregorc0265402010-01-21 15:46:19 +00002787 typedef CodeCompleteConsumer::OverloadCandidate ResultCandidate;
2788 llvm::SmallVector<ResultCandidate, 8> Results;
2789
John McCall3b4294e2009-12-16 12:17:52 +00002790 Expr *NakedFn = Fn->IgnoreParenCasts();
2791 if (UnresolvedLookupExpr *ULE = dyn_cast<UnresolvedLookupExpr>(NakedFn))
2792 AddOverloadedCallCandidates(ULE, Args, NumArgs, CandidateSet,
2793 /*PartialOverloading=*/ true);
2794 else if (DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(NakedFn)) {
2795 FunctionDecl *FDecl = dyn_cast<FunctionDecl>(DRE->getDecl());
Douglas Gregorc0265402010-01-21 15:46:19 +00002796 if (FDecl) {
Douglas Gregord28dcd72010-05-30 06:10:08 +00002797 if (!getLangOptions().CPlusPlus ||
2798 !FDecl->getType()->getAs<FunctionProtoType>())
Douglas Gregorc0265402010-01-21 15:46:19 +00002799 Results.push_back(ResultCandidate(FDecl));
2800 else
John McCall86820f52010-01-26 01:37:31 +00002801 // FIXME: access?
John McCall9aa472c2010-03-19 07:35:19 +00002802 AddOverloadCandidate(FDecl, DeclAccessPair::make(FDecl, AS_none),
2803 Args, NumArgs, CandidateSet,
Douglas Gregorc27d6c52010-04-16 17:41:49 +00002804 false, /*PartialOverloading*/true);
Douglas Gregorc0265402010-01-21 15:46:19 +00002805 }
John McCall3b4294e2009-12-16 12:17:52 +00002806 }
Douglas Gregor9c6a0e92009-09-22 15:41:20 +00002807
Douglas Gregor5ac3bdb2010-05-30 01:49:25 +00002808 QualType ParamType;
2809
Douglas Gregorc0265402010-01-21 15:46:19 +00002810 if (!CandidateSet.empty()) {
2811 // Sort the overload candidate set by placing the best overloads first.
2812 std::stable_sort(CandidateSet.begin(), CandidateSet.end(),
John McCall5769d612010-02-08 23:07:23 +00002813 IsBetterOverloadCandidate(*this, Loc));
Douglas Gregor9c6a0e92009-09-22 15:41:20 +00002814
Douglas Gregorc0265402010-01-21 15:46:19 +00002815 // Add the remaining viable overload candidates as code-completion reslults.
2816 for (OverloadCandidateSet::iterator Cand = CandidateSet.begin(),
2817 CandEnd = CandidateSet.end();
2818 Cand != CandEnd; ++Cand) {
2819 if (Cand->Viable)
2820 Results.push_back(ResultCandidate(Cand->Function));
2821 }
Douglas Gregor5ac3bdb2010-05-30 01:49:25 +00002822
2823 // From the viable candidates, try to determine the type of this parameter.
2824 for (unsigned I = 0, N = Results.size(); I != N; ++I) {
2825 if (const FunctionType *FType = Results[I].getFunctionType())
2826 if (const FunctionProtoType *Proto = dyn_cast<FunctionProtoType>(FType))
2827 if (NumArgs < Proto->getNumArgs()) {
2828 if (ParamType.isNull())
2829 ParamType = Proto->getArgType(NumArgs);
2830 else if (!Context.hasSameUnqualifiedType(
2831 ParamType.getNonReferenceType(),
2832 Proto->getArgType(NumArgs).getNonReferenceType())) {
2833 ParamType = QualType();
2834 break;
2835 }
2836 }
2837 }
2838 } else {
2839 // Try to determine the parameter type from the type of the expression
2840 // being called.
2841 QualType FunctionType = Fn->getType();
2842 if (const PointerType *Ptr = FunctionType->getAs<PointerType>())
2843 FunctionType = Ptr->getPointeeType();
2844 else if (const BlockPointerType *BlockPtr
2845 = FunctionType->getAs<BlockPointerType>())
2846 FunctionType = BlockPtr->getPointeeType();
2847 else if (const MemberPointerType *MemPtr
2848 = FunctionType->getAs<MemberPointerType>())
2849 FunctionType = MemPtr->getPointeeType();
2850
2851 if (const FunctionProtoType *Proto
2852 = FunctionType->getAs<FunctionProtoType>()) {
2853 if (NumArgs < Proto->getNumArgs())
2854 ParamType = Proto->getArgType(NumArgs);
2855 }
Douglas Gregor9c6a0e92009-09-22 15:41:20 +00002856 }
Douglas Gregoref96eac2009-12-11 19:06:04 +00002857
Douglas Gregor5ac3bdb2010-05-30 01:49:25 +00002858 if (ParamType.isNull())
Douglas Gregore6b1bb62010-08-11 21:23:17 +00002859 CodeCompleteOrdinaryName(S, PCC_Expression);
Douglas Gregor5ac3bdb2010-05-30 01:49:25 +00002860 else
2861 CodeCompleteExpression(S, ParamType);
2862
Douglas Gregor2e4c7a52010-04-06 20:19:47 +00002863 if (!Results.empty())
Douglas Gregoref96eac2009-12-11 19:06:04 +00002864 CodeCompleter->ProcessOverloadCandidates(*this, NumArgs, Results.data(),
2865 Results.size());
Douglas Gregor9c6a0e92009-09-22 15:41:20 +00002866}
2867
John McCalld226f652010-08-21 09:40:31 +00002868void Sema::CodeCompleteInitializer(Scope *S, Decl *D) {
2869 ValueDecl *VD = dyn_cast_or_null<ValueDecl>(D);
Douglas Gregor5ac3bdb2010-05-30 01:49:25 +00002870 if (!VD) {
Douglas Gregore6b1bb62010-08-11 21:23:17 +00002871 CodeCompleteOrdinaryName(S, PCC_Expression);
Douglas Gregor5ac3bdb2010-05-30 01:49:25 +00002872 return;
2873 }
2874
2875 CodeCompleteExpression(S, VD->getType());
2876}
2877
2878void Sema::CodeCompleteReturn(Scope *S) {
2879 QualType ResultType;
2880 if (isa<BlockDecl>(CurContext)) {
2881 if (BlockScopeInfo *BSI = getCurBlock())
2882 ResultType = BSI->ReturnType;
2883 } else if (FunctionDecl *Function = dyn_cast<FunctionDecl>(CurContext))
2884 ResultType = Function->getResultType();
2885 else if (ObjCMethodDecl *Method = dyn_cast<ObjCMethodDecl>(CurContext))
2886 ResultType = Method->getResultType();
2887
2888 if (ResultType.isNull())
Douglas Gregore6b1bb62010-08-11 21:23:17 +00002889 CodeCompleteOrdinaryName(S, PCC_Expression);
Douglas Gregor5ac3bdb2010-05-30 01:49:25 +00002890 else
2891 CodeCompleteExpression(S, ResultType);
2892}
2893
2894void Sema::CodeCompleteAssignmentRHS(Scope *S, ExprTy *LHS) {
2895 if (LHS)
2896 CodeCompleteExpression(S, static_cast<Expr *>(LHS)->getType());
2897 else
Douglas Gregore6b1bb62010-08-11 21:23:17 +00002898 CodeCompleteOrdinaryName(S, PCC_Expression);
Douglas Gregor5ac3bdb2010-05-30 01:49:25 +00002899}
2900
Jeffrey Yasskin9ab14542010-04-08 16:38:48 +00002901void Sema::CodeCompleteQualifiedId(Scope *S, CXXScopeSpec &SS,
Douglas Gregor81b747b2009-09-17 21:32:03 +00002902 bool EnteringContext) {
2903 if (!SS.getScopeRep() || !CodeCompleter)
2904 return;
2905
Douglas Gregor86d9a522009-09-21 16:56:56 +00002906 DeclContext *Ctx = computeDeclContext(SS, EnteringContext);
2907 if (!Ctx)
2908 return;
Douglas Gregord1cd31a2009-12-11 18:28:39 +00002909
2910 // Try to instantiate any non-dependent declaration contexts before
2911 // we look in them.
John McCall77bb1aa2010-05-01 00:40:08 +00002912 if (!isDependentScopeSpecifier(SS) && RequireCompleteDeclContext(SS, Ctx))
Douglas Gregord1cd31a2009-12-11 18:28:39 +00002913 return;
2914
Douglas Gregor86d9a522009-09-21 16:56:56 +00002915 ResultBuilder Results(*this);
Douglas Gregordef91072010-01-14 03:35:48 +00002916 CodeCompletionDeclConsumer Consumer(Results, CurContext);
2917 LookupVisibleDecls(Ctx, LookupOrdinaryName, Consumer);
Douglas Gregor86d9a522009-09-21 16:56:56 +00002918
2919 // The "template" keyword can follow "::" in the grammar, but only
2920 // put it into the grammar if the nested-name-specifier is dependent.
2921 NestedNameSpecifier *NNS = (NestedNameSpecifier *)SS.getScopeRep();
2922 if (!Results.empty() && NNS->isDependent())
Douglas Gregora4477812010-01-14 16:01:26 +00002923 Results.AddResult("template");
Douglas Gregor86d9a522009-09-21 16:56:56 +00002924
Douglas Gregore6b1bb62010-08-11 21:23:17 +00002925 HandleCodeCompleteResults(this, CodeCompleter,
2926 CodeCompletionContext::CCC_Other,
2927 Results.data(),Results.size());
Douglas Gregor81b747b2009-09-17 21:32:03 +00002928}
Douglas Gregor49f40bd2009-09-18 19:03:04 +00002929
2930void Sema::CodeCompleteUsing(Scope *S) {
2931 if (!CodeCompleter)
2932 return;
2933
Douglas Gregor86d9a522009-09-21 16:56:56 +00002934 ResultBuilder Results(*this, &ResultBuilder::IsNestedNameSpecifier);
Douglas Gregor8e0a0e42009-09-22 23:31:26 +00002935 Results.EnterNewScope();
Douglas Gregor86d9a522009-09-21 16:56:56 +00002936
2937 // If we aren't in class scope, we could see the "namespace" keyword.
2938 if (!S->isClassScope())
Douglas Gregora4477812010-01-14 16:01:26 +00002939 Results.AddResult(CodeCompleteConsumer::Result("namespace"));
Douglas Gregor86d9a522009-09-21 16:56:56 +00002940
2941 // After "using", we can see anything that would start a
2942 // nested-name-specifier.
Douglas Gregor5d2fc402010-01-14 03:27:13 +00002943 CodeCompletionDeclConsumer Consumer(Results, CurContext);
Douglas Gregor8071e422010-08-15 06:18:01 +00002944 LookupVisibleDecls(S, LookupOrdinaryName, Consumer,
2945 CodeCompleter->includeGlobals());
Douglas Gregor8e0a0e42009-09-22 23:31:26 +00002946 Results.ExitScope();
Douglas Gregor86d9a522009-09-21 16:56:56 +00002947
Douglas Gregore6b1bb62010-08-11 21:23:17 +00002948 HandleCodeCompleteResults(this, CodeCompleter,
2949 CodeCompletionContext::CCC_Other,
2950 Results.data(),Results.size());
Douglas Gregor49f40bd2009-09-18 19:03:04 +00002951}
2952
2953void Sema::CodeCompleteUsingDirective(Scope *S) {
2954 if (!CodeCompleter)
2955 return;
2956
Douglas Gregor86d9a522009-09-21 16:56:56 +00002957 // After "using namespace", we expect to see a namespace name or namespace
2958 // alias.
2959 ResultBuilder Results(*this, &ResultBuilder::IsNamespaceOrAlias);
Douglas Gregor8e0a0e42009-09-22 23:31:26 +00002960 Results.EnterNewScope();
Douglas Gregor5d2fc402010-01-14 03:27:13 +00002961 CodeCompletionDeclConsumer Consumer(Results, CurContext);
Douglas Gregor8071e422010-08-15 06:18:01 +00002962 LookupVisibleDecls(S, LookupOrdinaryName, Consumer,
2963 CodeCompleter->includeGlobals());
Douglas Gregor8e0a0e42009-09-22 23:31:26 +00002964 Results.ExitScope();
Douglas Gregore6b1bb62010-08-11 21:23:17 +00002965 HandleCodeCompleteResults(this, CodeCompleter,
Douglas Gregor8071e422010-08-15 06:18:01 +00002966 CodeCompletionContext::CCC_Namespace,
Douglas Gregore6b1bb62010-08-11 21:23:17 +00002967 Results.data(),Results.size());
Douglas Gregor49f40bd2009-09-18 19:03:04 +00002968}
2969
2970void Sema::CodeCompleteNamespaceDecl(Scope *S) {
2971 if (!CodeCompleter)
2972 return;
2973
Douglas Gregor86d9a522009-09-21 16:56:56 +00002974 ResultBuilder Results(*this, &ResultBuilder::IsNamespace);
2975 DeclContext *Ctx = (DeclContext *)S->getEntity();
2976 if (!S->getParent())
2977 Ctx = Context.getTranslationUnitDecl();
2978
2979 if (Ctx && Ctx->isFileContext()) {
2980 // We only want to see those namespaces that have already been defined
2981 // within this scope, because its likely that the user is creating an
2982 // extended namespace declaration. Keep track of the most recent
2983 // definition of each namespace.
2984 std::map<NamespaceDecl *, NamespaceDecl *> OrigToLatest;
2985 for (DeclContext::specific_decl_iterator<NamespaceDecl>
2986 NS(Ctx->decls_begin()), NSEnd(Ctx->decls_end());
2987 NS != NSEnd; ++NS)
2988 OrigToLatest[NS->getOriginalNamespace()] = *NS;
2989
2990 // Add the most recent definition (or extended definition) of each
2991 // namespace to the list of results.
Douglas Gregor8e0a0e42009-09-22 23:31:26 +00002992 Results.EnterNewScope();
Douglas Gregor86d9a522009-09-21 16:56:56 +00002993 for (std::map<NamespaceDecl *, NamespaceDecl *>::iterator
2994 NS = OrigToLatest.begin(), NSEnd = OrigToLatest.end();
2995 NS != NSEnd; ++NS)
Douglas Gregor608300b2010-01-14 16:14:35 +00002996 Results.AddResult(CodeCompleteConsumer::Result(NS->second, 0),
2997 CurContext, 0, false);
Douglas Gregor8e0a0e42009-09-22 23:31:26 +00002998 Results.ExitScope();
Douglas Gregor86d9a522009-09-21 16:56:56 +00002999 }
3000
Douglas Gregore6b1bb62010-08-11 21:23:17 +00003001 HandleCodeCompleteResults(this, CodeCompleter,
3002 CodeCompletionContext::CCC_Other,
3003 Results.data(),Results.size());
Douglas Gregor49f40bd2009-09-18 19:03:04 +00003004}
3005
3006void Sema::CodeCompleteNamespaceAliasDecl(Scope *S) {
3007 if (!CodeCompleter)
3008 return;
3009
Douglas Gregor86d9a522009-09-21 16:56:56 +00003010 // After "namespace", we expect to see a namespace or alias.
3011 ResultBuilder Results(*this, &ResultBuilder::IsNamespaceOrAlias);
Douglas Gregor5d2fc402010-01-14 03:27:13 +00003012 CodeCompletionDeclConsumer Consumer(Results, CurContext);
Douglas Gregor8071e422010-08-15 06:18:01 +00003013 LookupVisibleDecls(S, LookupOrdinaryName, Consumer,
3014 CodeCompleter->includeGlobals());
Douglas Gregore6b1bb62010-08-11 21:23:17 +00003015 HandleCodeCompleteResults(this, CodeCompleter,
Douglas Gregor8071e422010-08-15 06:18:01 +00003016 CodeCompletionContext::CCC_Namespace,
Douglas Gregore6b1bb62010-08-11 21:23:17 +00003017 Results.data(),Results.size());
Douglas Gregor49f40bd2009-09-18 19:03:04 +00003018}
3019
Douglas Gregored8d3222009-09-18 20:05:18 +00003020void Sema::CodeCompleteOperatorName(Scope *S) {
3021 if (!CodeCompleter)
3022 return;
Douglas Gregor86d9a522009-09-21 16:56:56 +00003023
3024 typedef CodeCompleteConsumer::Result Result;
3025 ResultBuilder Results(*this, &ResultBuilder::IsType);
Douglas Gregor8e0a0e42009-09-22 23:31:26 +00003026 Results.EnterNewScope();
Douglas Gregored8d3222009-09-18 20:05:18 +00003027
Douglas Gregor86d9a522009-09-21 16:56:56 +00003028 // Add the names of overloadable operators.
3029#define OVERLOADED_OPERATOR(Name,Spelling,Token,Unary,Binary,MemberOnly) \
3030 if (std::strcmp(Spelling, "?")) \
Douglas Gregora4477812010-01-14 16:01:26 +00003031 Results.AddResult(Result(Spelling));
Douglas Gregor86d9a522009-09-21 16:56:56 +00003032#include "clang/Basic/OperatorKinds.def"
3033
3034 // Add any type names visible from the current scope
Douglas Gregor45bcd432010-01-14 03:21:49 +00003035 Results.allowNestedNameSpecifiers();
Douglas Gregor5d2fc402010-01-14 03:27:13 +00003036 CodeCompletionDeclConsumer Consumer(Results, CurContext);
Douglas Gregor8071e422010-08-15 06:18:01 +00003037 LookupVisibleDecls(S, LookupOrdinaryName, Consumer,
3038 CodeCompleter->includeGlobals());
Douglas Gregor86d9a522009-09-21 16:56:56 +00003039
3040 // Add any type specifiers
Douglas Gregorbca403c2010-01-13 23:51:12 +00003041 AddTypeSpecifierResults(getLangOptions(), Results);
Douglas Gregor8e0a0e42009-09-22 23:31:26 +00003042 Results.ExitScope();
Douglas Gregor86d9a522009-09-21 16:56:56 +00003043
Douglas Gregore6b1bb62010-08-11 21:23:17 +00003044 HandleCodeCompleteResults(this, CodeCompleter,
Douglas Gregor8071e422010-08-15 06:18:01 +00003045 CodeCompletionContext::CCC_Type,
Douglas Gregore6b1bb62010-08-11 21:23:17 +00003046 Results.data(),Results.size());
Douglas Gregored8d3222009-09-18 20:05:18 +00003047}
Douglas Gregor49f40bd2009-09-18 19:03:04 +00003048
Douglas Gregorb6ac2452010-01-13 21:24:21 +00003049// Macro that expands to @Keyword or Keyword, depending on whether NeedAt is
3050// true or false.
3051#define OBJC_AT_KEYWORD_NAME(NeedAt,Keyword) NeedAt? "@" #Keyword : #Keyword
Douglas Gregorbca403c2010-01-13 23:51:12 +00003052static void AddObjCImplementationResults(const LangOptions &LangOpts,
Douglas Gregorb6ac2452010-01-13 21:24:21 +00003053 ResultBuilder &Results,
3054 bool NeedAt) {
3055 typedef CodeCompleteConsumer::Result Result;
3056 // Since we have an implementation, we can end it.
Douglas Gregora4477812010-01-14 16:01:26 +00003057 Results.AddResult(Result(OBJC_AT_KEYWORD_NAME(NeedAt,end)));
Douglas Gregorb6ac2452010-01-13 21:24:21 +00003058
3059 CodeCompletionString *Pattern = 0;
3060 if (LangOpts.ObjC2) {
3061 // @dynamic
3062 Pattern = new CodeCompletionString;
3063 Pattern->AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt,dynamic));
3064 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
3065 Pattern->AddPlaceholderChunk("property");
Douglas Gregora4477812010-01-14 16:01:26 +00003066 Results.AddResult(Result(Pattern));
Douglas Gregorb6ac2452010-01-13 21:24:21 +00003067
3068 // @synthesize
3069 Pattern = new CodeCompletionString;
3070 Pattern->AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt,synthesize));
3071 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
3072 Pattern->AddPlaceholderChunk("property");
Douglas Gregora4477812010-01-14 16:01:26 +00003073 Results.AddResult(Result(Pattern));
Douglas Gregorb6ac2452010-01-13 21:24:21 +00003074 }
3075}
3076
Douglas Gregorbca403c2010-01-13 23:51:12 +00003077static void AddObjCInterfaceResults(const LangOptions &LangOpts,
Douglas Gregorb6ac2452010-01-13 21:24:21 +00003078 ResultBuilder &Results,
3079 bool NeedAt) {
3080 typedef CodeCompleteConsumer::Result Result;
3081
3082 // Since we have an interface or protocol, we can end it.
Douglas Gregora4477812010-01-14 16:01:26 +00003083 Results.AddResult(Result(OBJC_AT_KEYWORD_NAME(NeedAt,end)));
Douglas Gregorb6ac2452010-01-13 21:24:21 +00003084
3085 if (LangOpts.ObjC2) {
3086 // @property
Douglas Gregora4477812010-01-14 16:01:26 +00003087 Results.AddResult(Result(OBJC_AT_KEYWORD_NAME(NeedAt,property)));
Douglas Gregorb6ac2452010-01-13 21:24:21 +00003088
3089 // @required
Douglas Gregora4477812010-01-14 16:01:26 +00003090 Results.AddResult(Result(OBJC_AT_KEYWORD_NAME(NeedAt,required)));
Douglas Gregorb6ac2452010-01-13 21:24:21 +00003091
3092 // @optional
Douglas Gregora4477812010-01-14 16:01:26 +00003093 Results.AddResult(Result(OBJC_AT_KEYWORD_NAME(NeedAt,optional)));
Douglas Gregorb6ac2452010-01-13 21:24:21 +00003094 }
3095}
3096
Douglas Gregorbca403c2010-01-13 23:51:12 +00003097static void AddObjCTopLevelResults(ResultBuilder &Results, bool NeedAt) {
Douglas Gregorb6ac2452010-01-13 21:24:21 +00003098 typedef CodeCompleteConsumer::Result Result;
3099 CodeCompletionString *Pattern = 0;
3100
3101 // @class name ;
3102 Pattern = new CodeCompletionString;
3103 Pattern->AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt,class));
3104 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
Douglas Gregorc8bddde2010-05-28 00:22:41 +00003105 Pattern->AddPlaceholderChunk("name");
Douglas Gregora4477812010-01-14 16:01:26 +00003106 Results.AddResult(Result(Pattern));
Douglas Gregorb6ac2452010-01-13 21:24:21 +00003107
Douglas Gregorc8bddde2010-05-28 00:22:41 +00003108 if (Results.includeCodePatterns()) {
3109 // @interface name
3110 // FIXME: Could introduce the whole pattern, including superclasses and
3111 // such.
3112 Pattern = new CodeCompletionString;
3113 Pattern->AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt,interface));
3114 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
3115 Pattern->AddPlaceholderChunk("class");
3116 Results.AddResult(Result(Pattern));
Douglas Gregorb6ac2452010-01-13 21:24:21 +00003117
Douglas Gregorc8bddde2010-05-28 00:22:41 +00003118 // @protocol name
3119 Pattern = new CodeCompletionString;
3120 Pattern->AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt,protocol));
3121 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
3122 Pattern->AddPlaceholderChunk("protocol");
3123 Results.AddResult(Result(Pattern));
3124
3125 // @implementation name
3126 Pattern = new CodeCompletionString;
3127 Pattern->AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt,implementation));
3128 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
3129 Pattern->AddPlaceholderChunk("class");
3130 Results.AddResult(Result(Pattern));
3131 }
Douglas Gregorb6ac2452010-01-13 21:24:21 +00003132
3133 // @compatibility_alias name
3134 Pattern = new CodeCompletionString;
3135 Pattern->AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt,compatibility_alias));
3136 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
3137 Pattern->AddPlaceholderChunk("alias");
3138 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
3139 Pattern->AddPlaceholderChunk("class");
Douglas Gregora4477812010-01-14 16:01:26 +00003140 Results.AddResult(Result(Pattern));
Douglas Gregorb6ac2452010-01-13 21:24:21 +00003141}
3142
John McCalld226f652010-08-21 09:40:31 +00003143void Sema::CodeCompleteObjCAtDirective(Scope *S, Decl *ObjCImpDecl,
Douglas Gregorc464ae82009-12-07 09:27:33 +00003144 bool InInterface) {
3145 typedef CodeCompleteConsumer::Result Result;
3146 ResultBuilder Results(*this);
3147 Results.EnterNewScope();
Douglas Gregorb6ac2452010-01-13 21:24:21 +00003148 if (ObjCImpDecl)
Douglas Gregorbca403c2010-01-13 23:51:12 +00003149 AddObjCImplementationResults(getLangOptions(), Results, false);
Douglas Gregorb6ac2452010-01-13 21:24:21 +00003150 else if (InInterface)
Douglas Gregorbca403c2010-01-13 23:51:12 +00003151 AddObjCInterfaceResults(getLangOptions(), Results, false);
Douglas Gregorb6ac2452010-01-13 21:24:21 +00003152 else
Douglas Gregorbca403c2010-01-13 23:51:12 +00003153 AddObjCTopLevelResults(Results, false);
Douglas Gregorc464ae82009-12-07 09:27:33 +00003154 Results.ExitScope();
Douglas Gregore6b1bb62010-08-11 21:23:17 +00003155 HandleCodeCompleteResults(this, CodeCompleter,
3156 CodeCompletionContext::CCC_Other,
3157 Results.data(),Results.size());
Douglas Gregorc464ae82009-12-07 09:27:33 +00003158}
3159
Douglas Gregorbca403c2010-01-13 23:51:12 +00003160static void AddObjCExpressionResults(ResultBuilder &Results, bool NeedAt) {
Douglas Gregor9a0c85e2009-12-07 09:51:25 +00003161 typedef CodeCompleteConsumer::Result Result;
3162 CodeCompletionString *Pattern = 0;
3163
3164 // @encode ( type-name )
3165 Pattern = new CodeCompletionString;
Douglas Gregorb6ac2452010-01-13 21:24:21 +00003166 Pattern->AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt,encode));
Douglas Gregor9a0c85e2009-12-07 09:51:25 +00003167 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
3168 Pattern->AddPlaceholderChunk("type-name");
3169 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
Douglas Gregora4477812010-01-14 16:01:26 +00003170 Results.AddResult(Result(Pattern));
Douglas Gregor9a0c85e2009-12-07 09:51:25 +00003171
3172 // @protocol ( protocol-name )
3173 Pattern = new CodeCompletionString;
Douglas Gregorb6ac2452010-01-13 21:24:21 +00003174 Pattern->AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt,protocol));
Douglas Gregor9a0c85e2009-12-07 09:51:25 +00003175 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
3176 Pattern->AddPlaceholderChunk("protocol-name");
3177 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
Douglas Gregora4477812010-01-14 16:01:26 +00003178 Results.AddResult(Result(Pattern));
Douglas Gregor9a0c85e2009-12-07 09:51:25 +00003179
3180 // @selector ( selector )
3181 Pattern = new CodeCompletionString;
Douglas Gregorb6ac2452010-01-13 21:24:21 +00003182 Pattern->AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt,selector));
Douglas Gregor9a0c85e2009-12-07 09:51:25 +00003183 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
3184 Pattern->AddPlaceholderChunk("selector");
3185 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
Douglas Gregora4477812010-01-14 16:01:26 +00003186 Results.AddResult(Result(Pattern));
Douglas Gregor9a0c85e2009-12-07 09:51:25 +00003187}
3188
Douglas Gregorbca403c2010-01-13 23:51:12 +00003189static void AddObjCStatementResults(ResultBuilder &Results, bool NeedAt) {
Douglas Gregor9a0c85e2009-12-07 09:51:25 +00003190 typedef CodeCompleteConsumer::Result Result;
Douglas Gregor9a0c85e2009-12-07 09:51:25 +00003191 CodeCompletionString *Pattern = 0;
Douglas Gregorb6ac2452010-01-13 21:24:21 +00003192
Douglas Gregorc8bddde2010-05-28 00:22:41 +00003193 if (Results.includeCodePatterns()) {
3194 // @try { statements } @catch ( declaration ) { statements } @finally
3195 // { statements }
3196 Pattern = new CodeCompletionString;
3197 Pattern->AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt,try));
3198 Pattern->AddChunk(CodeCompletionString::CK_LeftBrace);
3199 Pattern->AddPlaceholderChunk("statements");
3200 Pattern->AddChunk(CodeCompletionString::CK_RightBrace);
3201 Pattern->AddTextChunk("@catch");
3202 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
3203 Pattern->AddPlaceholderChunk("parameter");
3204 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
3205 Pattern->AddChunk(CodeCompletionString::CK_LeftBrace);
3206 Pattern->AddPlaceholderChunk("statements");
3207 Pattern->AddChunk(CodeCompletionString::CK_RightBrace);
3208 Pattern->AddTextChunk("@finally");
3209 Pattern->AddChunk(CodeCompletionString::CK_LeftBrace);
3210 Pattern->AddPlaceholderChunk("statements");
3211 Pattern->AddChunk(CodeCompletionString::CK_RightBrace);
3212 Results.AddResult(Result(Pattern));
3213 }
Douglas Gregorb6ac2452010-01-13 21:24:21 +00003214
Douglas Gregor9a0c85e2009-12-07 09:51:25 +00003215 // @throw
3216 Pattern = new CodeCompletionString;
Douglas Gregorb6ac2452010-01-13 21:24:21 +00003217 Pattern->AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt,throw));
Douglas Gregor834389b2010-01-12 06:38:28 +00003218 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
Douglas Gregor9a0c85e2009-12-07 09:51:25 +00003219 Pattern->AddPlaceholderChunk("expression");
Douglas Gregora4477812010-01-14 16:01:26 +00003220 Results.AddResult(Result(Pattern));
Douglas Gregorb6ac2452010-01-13 21:24:21 +00003221
Douglas Gregorc8bddde2010-05-28 00:22:41 +00003222 if (Results.includeCodePatterns()) {
3223 // @synchronized ( expression ) { statements }
3224 Pattern = new CodeCompletionString;
3225 Pattern->AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt,synchronized));
3226 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
3227 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
3228 Pattern->AddPlaceholderChunk("expression");
3229 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
3230 Pattern->AddChunk(CodeCompletionString::CK_LeftBrace);
3231 Pattern->AddPlaceholderChunk("statements");
3232 Pattern->AddChunk(CodeCompletionString::CK_RightBrace);
3233 Results.AddResult(Result(Pattern));
3234 }
Douglas Gregorb6ac2452010-01-13 21:24:21 +00003235}
Douglas Gregor9a0c85e2009-12-07 09:51:25 +00003236
Douglas Gregorbca403c2010-01-13 23:51:12 +00003237static void AddObjCVisibilityResults(const LangOptions &LangOpts,
Douglas Gregorc38c3e12010-01-13 21:54:15 +00003238 ResultBuilder &Results,
3239 bool NeedAt) {
Douglas Gregorb6ac2452010-01-13 21:24:21 +00003240 typedef CodeCompleteConsumer::Result Result;
Douglas Gregora4477812010-01-14 16:01:26 +00003241 Results.AddResult(Result(OBJC_AT_KEYWORD_NAME(NeedAt,private)));
3242 Results.AddResult(Result(OBJC_AT_KEYWORD_NAME(NeedAt,protected)));
3243 Results.AddResult(Result(OBJC_AT_KEYWORD_NAME(NeedAt,public)));
Douglas Gregorc38c3e12010-01-13 21:54:15 +00003244 if (LangOpts.ObjC2)
Douglas Gregora4477812010-01-14 16:01:26 +00003245 Results.AddResult(Result(OBJC_AT_KEYWORD_NAME(NeedAt,package)));
Douglas Gregorc38c3e12010-01-13 21:54:15 +00003246}
3247
3248void Sema::CodeCompleteObjCAtVisibility(Scope *S) {
3249 ResultBuilder Results(*this);
3250 Results.EnterNewScope();
Douglas Gregorbca403c2010-01-13 23:51:12 +00003251 AddObjCVisibilityResults(getLangOptions(), Results, false);
Douglas Gregorc38c3e12010-01-13 21:54:15 +00003252 Results.ExitScope();
Douglas Gregore6b1bb62010-08-11 21:23:17 +00003253 HandleCodeCompleteResults(this, CodeCompleter,
3254 CodeCompletionContext::CCC_Other,
3255 Results.data(),Results.size());
Douglas Gregorc38c3e12010-01-13 21:54:15 +00003256}
3257
3258void Sema::CodeCompleteObjCAtStatement(Scope *S) {
Douglas Gregorb6ac2452010-01-13 21:24:21 +00003259 ResultBuilder Results(*this);
3260 Results.EnterNewScope();
Douglas Gregorbca403c2010-01-13 23:51:12 +00003261 AddObjCStatementResults(Results, false);
3262 AddObjCExpressionResults(Results, false);
Douglas Gregor9a0c85e2009-12-07 09:51:25 +00003263 Results.ExitScope();
Douglas Gregore6b1bb62010-08-11 21:23:17 +00003264 HandleCodeCompleteResults(this, CodeCompleter,
3265 CodeCompletionContext::CCC_Other,
3266 Results.data(),Results.size());
Douglas Gregor9a0c85e2009-12-07 09:51:25 +00003267}
3268
3269void Sema::CodeCompleteObjCAtExpression(Scope *S) {
3270 ResultBuilder Results(*this);
3271 Results.EnterNewScope();
Douglas Gregorbca403c2010-01-13 23:51:12 +00003272 AddObjCExpressionResults(Results, false);
Douglas Gregor9a0c85e2009-12-07 09:51:25 +00003273 Results.ExitScope();
Douglas Gregore6b1bb62010-08-11 21:23:17 +00003274 HandleCodeCompleteResults(this, CodeCompleter,
3275 CodeCompletionContext::CCC_Other,
3276 Results.data(),Results.size());
Douglas Gregor9a0c85e2009-12-07 09:51:25 +00003277}
3278
Douglas Gregor988358f2009-11-19 00:14:45 +00003279/// \brief Determine whether the addition of the given flag to an Objective-C
3280/// property's attributes will cause a conflict.
3281static bool ObjCPropertyFlagConflicts(unsigned Attributes, unsigned NewFlag) {
3282 // Check if we've already added this flag.
3283 if (Attributes & NewFlag)
3284 return true;
3285
3286 Attributes |= NewFlag;
3287
3288 // Check for collisions with "readonly".
3289 if ((Attributes & ObjCDeclSpec::DQ_PR_readonly) &&
3290 (Attributes & (ObjCDeclSpec::DQ_PR_readwrite |
3291 ObjCDeclSpec::DQ_PR_assign |
3292 ObjCDeclSpec::DQ_PR_copy |
3293 ObjCDeclSpec::DQ_PR_retain)))
3294 return true;
3295
3296 // Check for more than one of { assign, copy, retain }.
3297 unsigned AssignCopyRetMask = Attributes & (ObjCDeclSpec::DQ_PR_assign |
3298 ObjCDeclSpec::DQ_PR_copy |
3299 ObjCDeclSpec::DQ_PR_retain);
3300 if (AssignCopyRetMask &&
3301 AssignCopyRetMask != ObjCDeclSpec::DQ_PR_assign &&
3302 AssignCopyRetMask != ObjCDeclSpec::DQ_PR_copy &&
3303 AssignCopyRetMask != ObjCDeclSpec::DQ_PR_retain)
3304 return true;
3305
3306 return false;
3307}
3308
Douglas Gregora93b1082009-11-18 23:08:07 +00003309void Sema::CodeCompleteObjCPropertyFlags(Scope *S, ObjCDeclSpec &ODS) {
Steve Naroffece8e712009-10-08 21:55:05 +00003310 if (!CodeCompleter)
3311 return;
Douglas Gregord3c68542009-11-19 01:08:35 +00003312
Steve Naroffece8e712009-10-08 21:55:05 +00003313 unsigned Attributes = ODS.getPropertyAttributes();
3314
3315 typedef CodeCompleteConsumer::Result Result;
3316 ResultBuilder Results(*this);
3317 Results.EnterNewScope();
Douglas Gregor988358f2009-11-19 00:14:45 +00003318 if (!ObjCPropertyFlagConflicts(Attributes, ObjCDeclSpec::DQ_PR_readonly))
Douglas Gregora4477812010-01-14 16:01:26 +00003319 Results.AddResult(CodeCompleteConsumer::Result("readonly"));
Douglas Gregor988358f2009-11-19 00:14:45 +00003320 if (!ObjCPropertyFlagConflicts(Attributes, ObjCDeclSpec::DQ_PR_assign))
Douglas Gregora4477812010-01-14 16:01:26 +00003321 Results.AddResult(CodeCompleteConsumer::Result("assign"));
Douglas Gregor988358f2009-11-19 00:14:45 +00003322 if (!ObjCPropertyFlagConflicts(Attributes, ObjCDeclSpec::DQ_PR_readwrite))
Douglas Gregora4477812010-01-14 16:01:26 +00003323 Results.AddResult(CodeCompleteConsumer::Result("readwrite"));
Douglas Gregor988358f2009-11-19 00:14:45 +00003324 if (!ObjCPropertyFlagConflicts(Attributes, ObjCDeclSpec::DQ_PR_retain))
Douglas Gregora4477812010-01-14 16:01:26 +00003325 Results.AddResult(CodeCompleteConsumer::Result("retain"));
Douglas Gregor988358f2009-11-19 00:14:45 +00003326 if (!ObjCPropertyFlagConflicts(Attributes, ObjCDeclSpec::DQ_PR_copy))
Douglas Gregora4477812010-01-14 16:01:26 +00003327 Results.AddResult(CodeCompleteConsumer::Result("copy"));
Douglas Gregor988358f2009-11-19 00:14:45 +00003328 if (!ObjCPropertyFlagConflicts(Attributes, ObjCDeclSpec::DQ_PR_nonatomic))
Douglas Gregora4477812010-01-14 16:01:26 +00003329 Results.AddResult(CodeCompleteConsumer::Result("nonatomic"));
Douglas Gregor988358f2009-11-19 00:14:45 +00003330 if (!ObjCPropertyFlagConflicts(Attributes, ObjCDeclSpec::DQ_PR_setter)) {
Douglas Gregor54f01612009-11-19 00:01:57 +00003331 CodeCompletionString *Setter = new CodeCompletionString;
3332 Setter->AddTypedTextChunk("setter");
3333 Setter->AddTextChunk(" = ");
3334 Setter->AddPlaceholderChunk("method");
Douglas Gregora4477812010-01-14 16:01:26 +00003335 Results.AddResult(CodeCompleteConsumer::Result(Setter));
Douglas Gregor54f01612009-11-19 00:01:57 +00003336 }
Douglas Gregor988358f2009-11-19 00:14:45 +00003337 if (!ObjCPropertyFlagConflicts(Attributes, ObjCDeclSpec::DQ_PR_getter)) {
Douglas Gregor54f01612009-11-19 00:01:57 +00003338 CodeCompletionString *Getter = new CodeCompletionString;
3339 Getter->AddTypedTextChunk("getter");
3340 Getter->AddTextChunk(" = ");
3341 Getter->AddPlaceholderChunk("method");
Douglas Gregora4477812010-01-14 16:01:26 +00003342 Results.AddResult(CodeCompleteConsumer::Result(Getter));
Douglas Gregor54f01612009-11-19 00:01:57 +00003343 }
Steve Naroffece8e712009-10-08 21:55:05 +00003344 Results.ExitScope();
Douglas Gregore6b1bb62010-08-11 21:23:17 +00003345 HandleCodeCompleteResults(this, CodeCompleter,
3346 CodeCompletionContext::CCC_Other,
3347 Results.data(),Results.size());
Steve Naroffece8e712009-10-08 21:55:05 +00003348}
Steve Naroffc4df6d22009-11-07 02:08:14 +00003349
Douglas Gregor4ad96852009-11-19 07:41:15 +00003350/// \brief Descripts the kind of Objective-C method that we want to find
3351/// via code completion.
3352enum ObjCMethodKind {
3353 MK_Any, //< Any kind of method, provided it means other specified criteria.
3354 MK_ZeroArgSelector, //< Zero-argument (unary) selector.
3355 MK_OneArgSelector //< One-argument selector.
3356};
3357
3358static bool isAcceptableObjCMethod(ObjCMethodDecl *Method,
3359 ObjCMethodKind WantKind,
3360 IdentifierInfo **SelIdents,
3361 unsigned NumSelIdents) {
3362 Selector Sel = Method->getSelector();
3363 if (NumSelIdents > Sel.getNumArgs())
3364 return false;
3365
3366 switch (WantKind) {
3367 case MK_Any: break;
3368 case MK_ZeroArgSelector: return Sel.isUnarySelector();
3369 case MK_OneArgSelector: return Sel.getNumArgs() == 1;
3370 }
3371
3372 for (unsigned I = 0; I != NumSelIdents; ++I)
3373 if (SelIdents[I] != Sel.getIdentifierInfoForSlot(I))
3374 return false;
3375
3376 return true;
3377}
3378
Douglas Gregor36ecb042009-11-17 23:22:23 +00003379/// \brief Add all of the Objective-C methods in the given Objective-C
3380/// container to the set of results.
3381///
3382/// The container will be a class, protocol, category, or implementation of
3383/// any of the above. This mether will recurse to include methods from
3384/// the superclasses of classes along with their categories, protocols, and
3385/// implementations.
3386///
3387/// \param Container the container in which we'll look to find methods.
3388///
3389/// \param WantInstance whether to add instance methods (only); if false, this
3390/// routine will add factory methods (only).
3391///
3392/// \param CurContext the context in which we're performing the lookup that
3393/// finds methods.
3394///
3395/// \param Results the structure into which we'll add results.
3396static void AddObjCMethods(ObjCContainerDecl *Container,
3397 bool WantInstanceMethods,
Douglas Gregor4ad96852009-11-19 07:41:15 +00003398 ObjCMethodKind WantKind,
Douglas Gregord3c68542009-11-19 01:08:35 +00003399 IdentifierInfo **SelIdents,
3400 unsigned NumSelIdents,
Douglas Gregor36ecb042009-11-17 23:22:23 +00003401 DeclContext *CurContext,
3402 ResultBuilder &Results) {
3403 typedef CodeCompleteConsumer::Result Result;
3404 for (ObjCContainerDecl::method_iterator M = Container->meth_begin(),
3405 MEnd = Container->meth_end();
3406 M != MEnd; ++M) {
Douglas Gregord3c68542009-11-19 01:08:35 +00003407 if ((*M)->isInstanceMethod() == WantInstanceMethods) {
3408 // Check whether the selector identifiers we've been given are a
3409 // subset of the identifiers for this particular method.
Douglas Gregor4ad96852009-11-19 07:41:15 +00003410 if (!isAcceptableObjCMethod(*M, WantKind, SelIdents, NumSelIdents))
Douglas Gregord3c68542009-11-19 01:08:35 +00003411 continue;
Douglas Gregor4ad96852009-11-19 07:41:15 +00003412
Douglas Gregord3c68542009-11-19 01:08:35 +00003413 Result R = Result(*M, 0);
3414 R.StartParameter = NumSelIdents;
Douglas Gregor4ad96852009-11-19 07:41:15 +00003415 R.AllParametersAreInformative = (WantKind != MK_Any);
Douglas Gregord3c68542009-11-19 01:08:35 +00003416 Results.MaybeAddResult(R, CurContext);
3417 }
Douglas Gregor36ecb042009-11-17 23:22:23 +00003418 }
3419
3420 ObjCInterfaceDecl *IFace = dyn_cast<ObjCInterfaceDecl>(Container);
3421 if (!IFace)
3422 return;
3423
3424 // Add methods in protocols.
3425 const ObjCList<ObjCProtocolDecl> &Protocols= IFace->getReferencedProtocols();
3426 for (ObjCList<ObjCProtocolDecl>::iterator I = Protocols.begin(),
3427 E = Protocols.end();
3428 I != E; ++I)
Douglas Gregor4ad96852009-11-19 07:41:15 +00003429 AddObjCMethods(*I, WantInstanceMethods, WantKind, SelIdents, NumSelIdents,
Douglas Gregord3c68542009-11-19 01:08:35 +00003430 CurContext, Results);
Douglas Gregor36ecb042009-11-17 23:22:23 +00003431
3432 // Add methods in categories.
3433 for (ObjCCategoryDecl *CatDecl = IFace->getCategoryList(); CatDecl;
3434 CatDecl = CatDecl->getNextClassCategory()) {
Douglas Gregor4ad96852009-11-19 07:41:15 +00003435 AddObjCMethods(CatDecl, WantInstanceMethods, WantKind, SelIdents,
3436 NumSelIdents, CurContext, Results);
Douglas Gregor36ecb042009-11-17 23:22:23 +00003437
3438 // Add a categories protocol methods.
3439 const ObjCList<ObjCProtocolDecl> &Protocols
3440 = CatDecl->getReferencedProtocols();
3441 for (ObjCList<ObjCProtocolDecl>::iterator I = Protocols.begin(),
3442 E = Protocols.end();
3443 I != E; ++I)
Douglas Gregor4ad96852009-11-19 07:41:15 +00003444 AddObjCMethods(*I, WantInstanceMethods, WantKind, SelIdents,
3445 NumSelIdents, CurContext, Results);
Douglas Gregor36ecb042009-11-17 23:22:23 +00003446
3447 // Add methods in category implementations.
3448 if (ObjCCategoryImplDecl *Impl = CatDecl->getImplementation())
Douglas Gregor4ad96852009-11-19 07:41:15 +00003449 AddObjCMethods(Impl, WantInstanceMethods, WantKind, SelIdents,
3450 NumSelIdents, CurContext, Results);
Douglas Gregor36ecb042009-11-17 23:22:23 +00003451 }
3452
3453 // Add methods in superclass.
3454 if (IFace->getSuperClass())
Douglas Gregor4ad96852009-11-19 07:41:15 +00003455 AddObjCMethods(IFace->getSuperClass(), WantInstanceMethods, WantKind,
3456 SelIdents, NumSelIdents, CurContext, Results);
Douglas Gregor36ecb042009-11-17 23:22:23 +00003457
3458 // Add methods in our implementation, if any.
3459 if (ObjCImplementationDecl *Impl = IFace->getImplementation())
Douglas Gregor4ad96852009-11-19 07:41:15 +00003460 AddObjCMethods(Impl, WantInstanceMethods, WantKind, SelIdents,
3461 NumSelIdents, CurContext, Results);
3462}
3463
3464
John McCalld226f652010-08-21 09:40:31 +00003465void Sema::CodeCompleteObjCPropertyGetter(Scope *S, Decl *ClassDecl,
3466 Decl **Methods,
Douglas Gregor4ad96852009-11-19 07:41:15 +00003467 unsigned NumMethods) {
3468 typedef CodeCompleteConsumer::Result Result;
3469
3470 // Try to find the interface where getters might live.
John McCalld226f652010-08-21 09:40:31 +00003471 ObjCInterfaceDecl *Class = dyn_cast_or_null<ObjCInterfaceDecl>(ClassDecl);
Douglas Gregor4ad96852009-11-19 07:41:15 +00003472 if (!Class) {
3473 if (ObjCCategoryDecl *Category
John McCalld226f652010-08-21 09:40:31 +00003474 = dyn_cast_or_null<ObjCCategoryDecl>(ClassDecl))
Douglas Gregor4ad96852009-11-19 07:41:15 +00003475 Class = Category->getClassInterface();
3476
3477 if (!Class)
3478 return;
3479 }
3480
3481 // Find all of the potential getters.
3482 ResultBuilder Results(*this);
3483 Results.EnterNewScope();
3484
3485 // FIXME: We need to do this because Objective-C methods don't get
3486 // pushed into DeclContexts early enough. Argh!
3487 for (unsigned I = 0; I != NumMethods; ++I) {
3488 if (ObjCMethodDecl *Method
John McCalld226f652010-08-21 09:40:31 +00003489 = dyn_cast_or_null<ObjCMethodDecl>(Methods[I]))
Douglas Gregor4ad96852009-11-19 07:41:15 +00003490 if (Method->isInstanceMethod() &&
3491 isAcceptableObjCMethod(Method, MK_ZeroArgSelector, 0, 0)) {
3492 Result R = Result(Method, 0);
3493 R.AllParametersAreInformative = true;
3494 Results.MaybeAddResult(R, CurContext);
3495 }
3496 }
3497
3498 AddObjCMethods(Class, true, MK_ZeroArgSelector, 0, 0, CurContext, Results);
3499 Results.ExitScope();
Douglas Gregore6b1bb62010-08-11 21:23:17 +00003500 HandleCodeCompleteResults(this, CodeCompleter,
3501 CodeCompletionContext::CCC_Other,
3502 Results.data(),Results.size());
Douglas Gregor4ad96852009-11-19 07:41:15 +00003503}
3504
John McCalld226f652010-08-21 09:40:31 +00003505void Sema::CodeCompleteObjCPropertySetter(Scope *S, Decl *ObjCImplDecl,
3506 Decl **Methods,
Douglas Gregor4ad96852009-11-19 07:41:15 +00003507 unsigned NumMethods) {
3508 typedef CodeCompleteConsumer::Result Result;
3509
3510 // Try to find the interface where setters might live.
3511 ObjCInterfaceDecl *Class
John McCalld226f652010-08-21 09:40:31 +00003512 = dyn_cast_or_null<ObjCInterfaceDecl>(ObjCImplDecl);
Douglas Gregor4ad96852009-11-19 07:41:15 +00003513 if (!Class) {
3514 if (ObjCCategoryDecl *Category
John McCalld226f652010-08-21 09:40:31 +00003515 = dyn_cast_or_null<ObjCCategoryDecl>(ObjCImplDecl))
Douglas Gregor4ad96852009-11-19 07:41:15 +00003516 Class = Category->getClassInterface();
3517
3518 if (!Class)
3519 return;
3520 }
3521
3522 // Find all of the potential getters.
3523 ResultBuilder Results(*this);
3524 Results.EnterNewScope();
3525
3526 // FIXME: We need to do this because Objective-C methods don't get
3527 // pushed into DeclContexts early enough. Argh!
3528 for (unsigned I = 0; I != NumMethods; ++I) {
3529 if (ObjCMethodDecl *Method
John McCalld226f652010-08-21 09:40:31 +00003530 = dyn_cast_or_null<ObjCMethodDecl>(Methods[I]))
Douglas Gregor4ad96852009-11-19 07:41:15 +00003531 if (Method->isInstanceMethod() &&
3532 isAcceptableObjCMethod(Method, MK_OneArgSelector, 0, 0)) {
3533 Result R = Result(Method, 0);
3534 R.AllParametersAreInformative = true;
3535 Results.MaybeAddResult(R, CurContext);
3536 }
3537 }
3538
3539 AddObjCMethods(Class, true, MK_OneArgSelector, 0, 0, CurContext, Results);
3540
3541 Results.ExitScope();
Douglas Gregore6b1bb62010-08-11 21:23:17 +00003542 HandleCodeCompleteResults(this, CodeCompleter,
3543 CodeCompletionContext::CCC_Other,
3544 Results.data(),Results.size());
Douglas Gregor36ecb042009-11-17 23:22:23 +00003545}
3546
Douglas Gregord32b0222010-08-24 01:06:58 +00003547void Sema::CodeCompleteObjCPassingType(Scope *S, ObjCDeclSpec &DS) {
3548 typedef CodeCompleteConsumer::Result Result;
3549 ResultBuilder Results(*this);
3550 Results.EnterNewScope();
3551
3552 // Add context-sensitive, Objective-C parameter-passing keywords.
3553 bool AddedInOut = false;
3554 if ((DS.getObjCDeclQualifier() &
3555 (ObjCDeclSpec::DQ_In | ObjCDeclSpec::DQ_Inout)) == 0) {
3556 Results.AddResult("in");
3557 Results.AddResult("inout");
3558 AddedInOut = true;
3559 }
3560 if ((DS.getObjCDeclQualifier() &
3561 (ObjCDeclSpec::DQ_Out | ObjCDeclSpec::DQ_Inout)) == 0) {
3562 Results.AddResult("out");
3563 if (!AddedInOut)
3564 Results.AddResult("inout");
3565 }
3566 if ((DS.getObjCDeclQualifier() &
3567 (ObjCDeclSpec::DQ_Bycopy | ObjCDeclSpec::DQ_Byref |
3568 ObjCDeclSpec::DQ_Oneway)) == 0) {
3569 Results.AddResult("bycopy");
3570 Results.AddResult("byref");
3571 Results.AddResult("oneway");
3572 }
3573
3574 // Add various builtin type names and specifiers.
3575 AddOrdinaryNameResults(PCC_Type, S, *this, Results);
3576 Results.ExitScope();
3577
3578 // Add the various type names
3579 Results.setFilter(&ResultBuilder::IsOrdinaryNonValueName);
3580 CodeCompletionDeclConsumer Consumer(Results, CurContext);
3581 LookupVisibleDecls(S, LookupOrdinaryName, Consumer,
3582 CodeCompleter->includeGlobals());
3583
3584 if (CodeCompleter->includeMacros())
3585 AddMacroResults(PP, Results);
3586
3587 HandleCodeCompleteResults(this, CodeCompleter,
3588 CodeCompletionContext::CCC_Type,
3589 Results.data(), Results.size());
3590}
3591
Douglas Gregor22f56992010-04-06 19:22:33 +00003592/// \brief When we have an expression with type "id", we may assume
3593/// that it has some more-specific class type based on knowledge of
3594/// common uses of Objective-C. This routine returns that class type,
3595/// or NULL if no better result could be determined.
3596static ObjCInterfaceDecl *GetAssumedMessageSendExprType(Expr *E) {
3597 ObjCMessageExpr *Msg = dyn_cast<ObjCMessageExpr>(E);
3598 if (!Msg)
3599 return 0;
3600
3601 Selector Sel = Msg->getSelector();
3602 if (Sel.isNull())
3603 return 0;
3604
3605 IdentifierInfo *Id = Sel.getIdentifierInfoForSlot(0);
3606 if (!Id)
3607 return 0;
3608
3609 ObjCMethodDecl *Method = Msg->getMethodDecl();
3610 if (!Method)
3611 return 0;
3612
3613 // Determine the class that we're sending the message to.
Douglas Gregor04badcf2010-04-21 00:45:42 +00003614 ObjCInterfaceDecl *IFace = 0;
3615 switch (Msg->getReceiverKind()) {
3616 case ObjCMessageExpr::Class:
John McCallc12c5bb2010-05-15 11:32:37 +00003617 if (const ObjCObjectType *ObjType
3618 = Msg->getClassReceiver()->getAs<ObjCObjectType>())
3619 IFace = ObjType->getInterface();
Douglas Gregor04badcf2010-04-21 00:45:42 +00003620 break;
3621
3622 case ObjCMessageExpr::Instance: {
3623 QualType T = Msg->getInstanceReceiver()->getType();
3624 if (const ObjCObjectPointerType *Ptr = T->getAs<ObjCObjectPointerType>())
3625 IFace = Ptr->getInterfaceDecl();
3626 break;
3627 }
3628
3629 case ObjCMessageExpr::SuperInstance:
3630 case ObjCMessageExpr::SuperClass:
3631 break;
Douglas Gregor22f56992010-04-06 19:22:33 +00003632 }
3633
3634 if (!IFace)
3635 return 0;
3636
3637 ObjCInterfaceDecl *Super = IFace->getSuperClass();
3638 if (Method->isInstanceMethod())
3639 return llvm::StringSwitch<ObjCInterfaceDecl *>(Id->getName())
3640 .Case("retain", IFace)
3641 .Case("autorelease", IFace)
3642 .Case("copy", IFace)
3643 .Case("copyWithZone", IFace)
3644 .Case("mutableCopy", IFace)
3645 .Case("mutableCopyWithZone", IFace)
3646 .Case("awakeFromCoder", IFace)
3647 .Case("replacementObjectFromCoder", IFace)
3648 .Case("class", IFace)
3649 .Case("classForCoder", IFace)
3650 .Case("superclass", Super)
3651 .Default(0);
3652
3653 return llvm::StringSwitch<ObjCInterfaceDecl *>(Id->getName())
3654 .Case("new", IFace)
3655 .Case("alloc", IFace)
3656 .Case("allocWithZone", IFace)
3657 .Case("class", IFace)
3658 .Case("superclass", Super)
3659 .Default(0);
3660}
3661
Douglas Gregor8e254cf2010-05-27 23:06:34 +00003662void Sema::CodeCompleteObjCMessageReceiver(Scope *S) {
3663 typedef CodeCompleteConsumer::Result Result;
3664 ResultBuilder Results(*this);
3665
3666 // Find anything that looks like it could be a message receiver.
3667 Results.setFilter(&ResultBuilder::IsObjCMessageReceiver);
3668 CodeCompletionDeclConsumer Consumer(Results, CurContext);
3669 Results.EnterNewScope();
Douglas Gregor8071e422010-08-15 06:18:01 +00003670 LookupVisibleDecls(S, LookupOrdinaryName, Consumer,
3671 CodeCompleter->includeGlobals());
Douglas Gregor8e254cf2010-05-27 23:06:34 +00003672
3673 // If we are in an Objective-C method inside a class that has a superclass,
3674 // add "super" as an option.
3675 if (ObjCMethodDecl *Method = getCurMethodDecl())
3676 if (ObjCInterfaceDecl *Iface = Method->getClassInterface())
3677 if (Iface->getSuperClass())
3678 Results.AddResult(Result("super"));
3679
3680 Results.ExitScope();
3681
3682 if (CodeCompleter->includeMacros())
3683 AddMacroResults(PP, Results);
Douglas Gregore6b1bb62010-08-11 21:23:17 +00003684 HandleCodeCompleteResults(this, CodeCompleter,
3685 CodeCompletionContext::CCC_ObjCMessageReceiver,
3686 Results.data(), Results.size());
Douglas Gregor8e254cf2010-05-27 23:06:34 +00003687
3688}
3689
Douglas Gregor2725ca82010-04-21 19:57:20 +00003690void Sema::CodeCompleteObjCSuperMessage(Scope *S, SourceLocation SuperLoc,
3691 IdentifierInfo **SelIdents,
3692 unsigned NumSelIdents) {
3693 ObjCInterfaceDecl *CDecl = 0;
3694 if (ObjCMethodDecl *CurMethod = getCurMethodDecl()) {
3695 // Figure out which interface we're in.
3696 CDecl = CurMethod->getClassInterface();
3697 if (!CDecl)
3698 return;
3699
3700 // Find the superclass of this class.
3701 CDecl = CDecl->getSuperClass();
3702 if (!CDecl)
3703 return;
3704
3705 if (CurMethod->isInstanceMethod()) {
3706 // We are inside an instance method, which means that the message
3707 // send [super ...] is actually calling an instance method on the
3708 // current object. Build the super expression and handle this like
3709 // an instance method.
3710 QualType SuperTy = Context.getObjCInterfaceType(CDecl);
3711 SuperTy = Context.getObjCObjectPointerType(SuperTy);
John McCall60d7b3a2010-08-24 06:29:42 +00003712 ExprResult Super
Douglas Gregor2725ca82010-04-21 19:57:20 +00003713 = Owned(new (Context) ObjCSuperExpr(SuperLoc, SuperTy));
3714 return CodeCompleteObjCInstanceMessage(S, (Expr *)Super.get(),
3715 SelIdents, NumSelIdents);
3716 }
3717
3718 // Fall through to send to the superclass in CDecl.
3719 } else {
3720 // "super" may be the name of a type or variable. Figure out which
3721 // it is.
3722 IdentifierInfo *Super = &Context.Idents.get("super");
3723 NamedDecl *ND = LookupSingleName(S, Super, SuperLoc,
3724 LookupOrdinaryName);
3725 if ((CDecl = dyn_cast_or_null<ObjCInterfaceDecl>(ND))) {
3726 // "super" names an interface. Use it.
3727 } else if (TypeDecl *TD = dyn_cast_or_null<TypeDecl>(ND)) {
John McCallc12c5bb2010-05-15 11:32:37 +00003728 if (const ObjCObjectType *Iface
3729 = Context.getTypeDeclType(TD)->getAs<ObjCObjectType>())
3730 CDecl = Iface->getInterface();
Douglas Gregor2725ca82010-04-21 19:57:20 +00003731 } else if (ND && isa<UnresolvedUsingTypenameDecl>(ND)) {
3732 // "super" names an unresolved type; we can't be more specific.
3733 } else {
3734 // Assume that "super" names some kind of value and parse that way.
3735 CXXScopeSpec SS;
3736 UnqualifiedId id;
3737 id.setIdentifier(Super, SuperLoc);
John McCall60d7b3a2010-08-24 06:29:42 +00003738 ExprResult SuperExpr = ActOnIdExpression(S, SS, id, false, false);
Douglas Gregor2725ca82010-04-21 19:57:20 +00003739 return CodeCompleteObjCInstanceMessage(S, (Expr *)SuperExpr.get(),
3740 SelIdents, NumSelIdents);
3741 }
3742
3743 // Fall through
3744 }
3745
John McCallb3d87482010-08-24 05:47:05 +00003746 ParsedType Receiver;
Douglas Gregor2725ca82010-04-21 19:57:20 +00003747 if (CDecl)
John McCallb3d87482010-08-24 05:47:05 +00003748 Receiver = ParsedType::make(Context.getObjCInterfaceType(CDecl));
Douglas Gregor2725ca82010-04-21 19:57:20 +00003749 return CodeCompleteObjCClassMessage(S, Receiver, SelIdents,
3750 NumSelIdents);
3751}
3752
John McCallb3d87482010-08-24 05:47:05 +00003753void Sema::CodeCompleteObjCClassMessage(Scope *S, ParsedType Receiver,
Douglas Gregord3c68542009-11-19 01:08:35 +00003754 IdentifierInfo **SelIdents,
3755 unsigned NumSelIdents) {
Steve Naroffc4df6d22009-11-07 02:08:14 +00003756 typedef CodeCompleteConsumer::Result Result;
Douglas Gregor24a069f2009-11-17 17:59:40 +00003757 ObjCInterfaceDecl *CDecl = 0;
3758
Douglas Gregor24a069f2009-11-17 17:59:40 +00003759 // If the given name refers to an interface type, retrieve the
3760 // corresponding declaration.
Douglas Gregor2725ca82010-04-21 19:57:20 +00003761 if (Receiver) {
3762 QualType T = GetTypeFromParser(Receiver, 0);
3763 if (!T.isNull())
John McCallc12c5bb2010-05-15 11:32:37 +00003764 if (const ObjCObjectType *Interface = T->getAs<ObjCObjectType>())
3765 CDecl = Interface->getInterface();
Douglas Gregor24a069f2009-11-17 17:59:40 +00003766 }
3767
Douglas Gregor36ecb042009-11-17 23:22:23 +00003768 // Add all of the factory methods in this Objective-C class, its protocols,
3769 // superclasses, categories, implementation, etc.
Steve Naroffc4df6d22009-11-07 02:08:14 +00003770 ResultBuilder Results(*this);
3771 Results.EnterNewScope();
Douglas Gregor13438f92010-04-06 16:40:00 +00003772
3773 if (CDecl)
3774 AddObjCMethods(CDecl, false, MK_Any, SelIdents, NumSelIdents, CurContext,
3775 Results);
Douglas Gregor2725ca82010-04-21 19:57:20 +00003776 else {
Douglas Gregor13438f92010-04-06 16:40:00 +00003777 // We're messaging "id" as a type; provide all class/factory methods.
3778
Douglas Gregor719770d2010-04-06 17:30:22 +00003779 // If we have an external source, load the entire class method
Sebastian Redl3c7f4132010-08-18 23:57:06 +00003780 // pool from the AST file.
Douglas Gregor719770d2010-04-06 17:30:22 +00003781 if (ExternalSource) {
John McCall76bd1f32010-06-01 09:23:16 +00003782 for (uint32_t I = 0, N = ExternalSource->GetNumExternalSelectors();
3783 I != N; ++I) {
3784 Selector Sel = ExternalSource->GetExternalSelector(I);
Sebastian Redldb9d2142010-08-02 23:18:59 +00003785 if (Sel.isNull() || MethodPool.count(Sel))
Douglas Gregor719770d2010-04-06 17:30:22 +00003786 continue;
3787
Sebastian Redldb9d2142010-08-02 23:18:59 +00003788 ReadMethodPool(Sel);
Douglas Gregor719770d2010-04-06 17:30:22 +00003789 }
3790 }
3791
Sebastian Redldb9d2142010-08-02 23:18:59 +00003792 for (GlobalMethodPool::iterator M = MethodPool.begin(),
3793 MEnd = MethodPool.end();
3794 M != MEnd; ++M) {
3795 for (ObjCMethodList *MethList = &M->second.second;
3796 MethList && MethList->Method;
Douglas Gregor13438f92010-04-06 16:40:00 +00003797 MethList = MethList->Next) {
3798 if (!isAcceptableObjCMethod(MethList->Method, MK_Any, SelIdents,
3799 NumSelIdents))
3800 continue;
3801
3802 Result R(MethList->Method, 0);
3803 R.StartParameter = NumSelIdents;
3804 R.AllParametersAreInformative = false;
3805 Results.MaybeAddResult(R, CurContext);
3806 }
3807 }
3808 }
3809
Steve Naroffc4df6d22009-11-07 02:08:14 +00003810 Results.ExitScope();
Douglas Gregore6b1bb62010-08-11 21:23:17 +00003811 HandleCodeCompleteResults(this, CodeCompleter,
3812 CodeCompletionContext::CCC_Other,
3813 Results.data(),Results.size());
Steve Naroffc4df6d22009-11-07 02:08:14 +00003814}
3815
Douglas Gregord3c68542009-11-19 01:08:35 +00003816void Sema::CodeCompleteObjCInstanceMessage(Scope *S, ExprTy *Receiver,
3817 IdentifierInfo **SelIdents,
3818 unsigned NumSelIdents) {
Steve Naroffc4df6d22009-11-07 02:08:14 +00003819 typedef CodeCompleteConsumer::Result Result;
Steve Naroffc4df6d22009-11-07 02:08:14 +00003820
3821 Expr *RecExpr = static_cast<Expr *>(Receiver);
Steve Naroffc4df6d22009-11-07 02:08:14 +00003822
Douglas Gregor36ecb042009-11-17 23:22:23 +00003823 // If necessary, apply function/array conversion to the receiver.
3824 // C99 6.7.5.3p[7,8].
Douglas Gregora873dfc2010-02-03 00:27:59 +00003825 DefaultFunctionArrayLvalueConversion(RecExpr);
Douglas Gregor36ecb042009-11-17 23:22:23 +00003826 QualType ReceiverType = RecExpr->getType();
Steve Naroffc4df6d22009-11-07 02:08:14 +00003827
Douglas Gregor36ecb042009-11-17 23:22:23 +00003828 // Build the set of methods we can see.
3829 ResultBuilder Results(*this);
3830 Results.EnterNewScope();
Douglas Gregor22f56992010-04-06 19:22:33 +00003831
3832 // If we're messaging an expression with type "id" or "Class", check
3833 // whether we know something special about the receiver that allows
3834 // us to assume a more-specific receiver type.
3835 if (ReceiverType->isObjCIdType() || ReceiverType->isObjCClassType())
3836 if (ObjCInterfaceDecl *IFace = GetAssumedMessageSendExprType(RecExpr))
3837 ReceiverType = Context.getObjCObjectPointerType(
3838 Context.getObjCInterfaceType(IFace));
Douglas Gregor36ecb042009-11-17 23:22:23 +00003839
Douglas Gregorf74a4192009-11-18 00:06:18 +00003840 // Handle messages to Class. This really isn't a message to an instance
3841 // method, so we treat it the same way we would treat a message send to a
3842 // class method.
3843 if (ReceiverType->isObjCClassType() ||
3844 ReceiverType->isObjCQualifiedClassType()) {
3845 if (ObjCMethodDecl *CurMethod = getCurMethodDecl()) {
3846 if (ObjCInterfaceDecl *ClassDecl = CurMethod->getClassInterface())
Douglas Gregor4ad96852009-11-19 07:41:15 +00003847 AddObjCMethods(ClassDecl, false, MK_Any, SelIdents, NumSelIdents,
3848 CurContext, Results);
Douglas Gregorf74a4192009-11-18 00:06:18 +00003849 }
3850 }
3851 // Handle messages to a qualified ID ("id<foo>").
3852 else if (const ObjCObjectPointerType *QualID
3853 = ReceiverType->getAsObjCQualifiedIdType()) {
3854 // Search protocols for instance methods.
3855 for (ObjCObjectPointerType::qual_iterator I = QualID->qual_begin(),
3856 E = QualID->qual_end();
3857 I != E; ++I)
Douglas Gregor4ad96852009-11-19 07:41:15 +00003858 AddObjCMethods(*I, true, MK_Any, SelIdents, NumSelIdents, CurContext,
3859 Results);
Douglas Gregorf74a4192009-11-18 00:06:18 +00003860 }
3861 // Handle messages to a pointer to interface type.
3862 else if (const ObjCObjectPointerType *IFacePtr
3863 = ReceiverType->getAsObjCInterfacePointerType()) {
3864 // Search the class, its superclasses, etc., for instance methods.
Douglas Gregor4ad96852009-11-19 07:41:15 +00003865 AddObjCMethods(IFacePtr->getInterfaceDecl(), true, MK_Any, SelIdents,
3866 NumSelIdents, CurContext, Results);
Douglas Gregorf74a4192009-11-18 00:06:18 +00003867
3868 // Search protocols for instance methods.
3869 for (ObjCObjectPointerType::qual_iterator I = IFacePtr->qual_begin(),
3870 E = IFacePtr->qual_end();
3871 I != E; ++I)
Douglas Gregor4ad96852009-11-19 07:41:15 +00003872 AddObjCMethods(*I, true, MK_Any, SelIdents, NumSelIdents, CurContext,
3873 Results);
Douglas Gregorf74a4192009-11-18 00:06:18 +00003874 }
Douglas Gregor13438f92010-04-06 16:40:00 +00003875 // Handle messages to "id".
3876 else if (ReceiverType->isObjCIdType()) {
Douglas Gregor719770d2010-04-06 17:30:22 +00003877 // We're messaging "id", so provide all instance methods we know
3878 // about as code-completion results.
3879
3880 // If we have an external source, load the entire class method
Sebastian Redl3c7f4132010-08-18 23:57:06 +00003881 // pool from the AST file.
Douglas Gregor719770d2010-04-06 17:30:22 +00003882 if (ExternalSource) {
John McCall76bd1f32010-06-01 09:23:16 +00003883 for (uint32_t I = 0, N = ExternalSource->GetNumExternalSelectors();
3884 I != N; ++I) {
3885 Selector Sel = ExternalSource->GetExternalSelector(I);
Sebastian Redldb9d2142010-08-02 23:18:59 +00003886 if (Sel.isNull() || MethodPool.count(Sel))
Douglas Gregor719770d2010-04-06 17:30:22 +00003887 continue;
3888
Sebastian Redldb9d2142010-08-02 23:18:59 +00003889 ReadMethodPool(Sel);
Douglas Gregor719770d2010-04-06 17:30:22 +00003890 }
3891 }
3892
Sebastian Redldb9d2142010-08-02 23:18:59 +00003893 for (GlobalMethodPool::iterator M = MethodPool.begin(),
3894 MEnd = MethodPool.end();
3895 M != MEnd; ++M) {
3896 for (ObjCMethodList *MethList = &M->second.first;
3897 MethList && MethList->Method;
Douglas Gregor13438f92010-04-06 16:40:00 +00003898 MethList = MethList->Next) {
3899 if (!isAcceptableObjCMethod(MethList->Method, MK_Any, SelIdents,
3900 NumSelIdents))
3901 continue;
3902
3903 Result R(MethList->Method, 0);
3904 R.StartParameter = NumSelIdents;
3905 R.AllParametersAreInformative = false;
3906 Results.MaybeAddResult(R, CurContext);
3907 }
3908 }
3909 }
3910
Steve Naroffc4df6d22009-11-07 02:08:14 +00003911 Results.ExitScope();
Douglas Gregore6b1bb62010-08-11 21:23:17 +00003912 HandleCodeCompleteResults(this, CodeCompleter,
3913 CodeCompletionContext::CCC_Other,
3914 Results.data(),Results.size());
Steve Naroffc4df6d22009-11-07 02:08:14 +00003915}
Douglas Gregor55385fe2009-11-18 04:19:12 +00003916
Douglas Gregorfb629412010-08-23 21:17:50 +00003917void Sema::CodeCompleteObjCForCollection(Scope *S,
3918 DeclGroupPtrTy IterationVar) {
3919 CodeCompleteExpressionData Data;
3920 Data.ObjCCollection = true;
3921
3922 if (IterationVar.getAsOpaquePtr()) {
3923 DeclGroupRef DG = IterationVar.getAsVal<DeclGroupRef>();
3924 for (DeclGroupRef::iterator I = DG.begin(), End = DG.end(); I != End; ++I) {
3925 if (*I)
3926 Data.IgnoreDecls.push_back(*I);
3927 }
3928 }
3929
3930 CodeCompleteExpression(S, Data);
3931}
3932
Douglas Gregor55385fe2009-11-18 04:19:12 +00003933/// \brief Add all of the protocol declarations that we find in the given
3934/// (translation unit) context.
3935static void AddProtocolResults(DeclContext *Ctx, DeclContext *CurContext,
Douglas Gregor083128f2009-11-18 04:49:41 +00003936 bool OnlyForwardDeclarations,
Douglas Gregor55385fe2009-11-18 04:19:12 +00003937 ResultBuilder &Results) {
3938 typedef CodeCompleteConsumer::Result Result;
3939
3940 for (DeclContext::decl_iterator D = Ctx->decls_begin(),
3941 DEnd = Ctx->decls_end();
3942 D != DEnd; ++D) {
3943 // Record any protocols we find.
3944 if (ObjCProtocolDecl *Proto = dyn_cast<ObjCProtocolDecl>(*D))
Douglas Gregor083128f2009-11-18 04:49:41 +00003945 if (!OnlyForwardDeclarations || Proto->isForwardDecl())
Douglas Gregor608300b2010-01-14 16:14:35 +00003946 Results.AddResult(Result(Proto, 0), CurContext, 0, false);
Douglas Gregor55385fe2009-11-18 04:19:12 +00003947
3948 // Record any forward-declared protocols we find.
3949 if (ObjCForwardProtocolDecl *Forward
3950 = dyn_cast<ObjCForwardProtocolDecl>(*D)) {
3951 for (ObjCForwardProtocolDecl::protocol_iterator
3952 P = Forward->protocol_begin(),
3953 PEnd = Forward->protocol_end();
3954 P != PEnd; ++P)
Douglas Gregor083128f2009-11-18 04:49:41 +00003955 if (!OnlyForwardDeclarations || (*P)->isForwardDecl())
Douglas Gregor608300b2010-01-14 16:14:35 +00003956 Results.AddResult(Result(*P, 0), CurContext, 0, false);
Douglas Gregor55385fe2009-11-18 04:19:12 +00003957 }
3958 }
3959}
3960
3961void Sema::CodeCompleteObjCProtocolReferences(IdentifierLocPair *Protocols,
3962 unsigned NumProtocols) {
3963 ResultBuilder Results(*this);
3964 Results.EnterNewScope();
3965
3966 // Tell the result set to ignore all of the protocols we have
3967 // already seen.
3968 for (unsigned I = 0; I != NumProtocols; ++I)
Douglas Gregorc83c6872010-04-15 22:33:43 +00003969 if (ObjCProtocolDecl *Protocol = LookupProtocol(Protocols[I].first,
3970 Protocols[I].second))
Douglas Gregor55385fe2009-11-18 04:19:12 +00003971 Results.Ignore(Protocol);
3972
3973 // Add all protocols.
Douglas Gregor083128f2009-11-18 04:49:41 +00003974 AddProtocolResults(Context.getTranslationUnitDecl(), CurContext, false,
3975 Results);
3976
3977 Results.ExitScope();
Douglas Gregore6b1bb62010-08-11 21:23:17 +00003978 HandleCodeCompleteResults(this, CodeCompleter,
3979 CodeCompletionContext::CCC_ObjCProtocolName,
3980 Results.data(),Results.size());
Douglas Gregor083128f2009-11-18 04:49:41 +00003981}
3982
3983void Sema::CodeCompleteObjCProtocolDecl(Scope *) {
3984 ResultBuilder Results(*this);
3985 Results.EnterNewScope();
3986
3987 // Add all protocols.
3988 AddProtocolResults(Context.getTranslationUnitDecl(), CurContext, true,
3989 Results);
Douglas Gregor55385fe2009-11-18 04:19:12 +00003990
3991 Results.ExitScope();
Douglas Gregore6b1bb62010-08-11 21:23:17 +00003992 HandleCodeCompleteResults(this, CodeCompleter,
3993 CodeCompletionContext::CCC_ObjCProtocolName,
3994 Results.data(),Results.size());
Douglas Gregor55385fe2009-11-18 04:19:12 +00003995}
Douglas Gregor3b49aca2009-11-18 16:26:39 +00003996
3997/// \brief Add all of the Objective-C interface declarations that we find in
3998/// the given (translation unit) context.
3999static void AddInterfaceResults(DeclContext *Ctx, DeclContext *CurContext,
4000 bool OnlyForwardDeclarations,
4001 bool OnlyUnimplemented,
4002 ResultBuilder &Results) {
4003 typedef CodeCompleteConsumer::Result Result;
4004
4005 for (DeclContext::decl_iterator D = Ctx->decls_begin(),
4006 DEnd = Ctx->decls_end();
4007 D != DEnd; ++D) {
Douglas Gregordeacbdc2010-08-11 12:19:30 +00004008 // Record any interfaces we find.
4009 if (ObjCInterfaceDecl *Class = dyn_cast<ObjCInterfaceDecl>(*D))
4010 if ((!OnlyForwardDeclarations || Class->isForwardDecl()) &&
4011 (!OnlyUnimplemented || !Class->getImplementation()))
4012 Results.AddResult(Result(Class, 0), CurContext, 0, false);
Douglas Gregor3b49aca2009-11-18 16:26:39 +00004013
4014 // Record any forward-declared interfaces we find.
4015 if (ObjCClassDecl *Forward = dyn_cast<ObjCClassDecl>(*D)) {
4016 for (ObjCClassDecl::iterator C = Forward->begin(), CEnd = Forward->end();
Douglas Gregordeacbdc2010-08-11 12:19:30 +00004017 C != CEnd; ++C)
4018 if ((!OnlyForwardDeclarations || C->getInterface()->isForwardDecl()) &&
4019 (!OnlyUnimplemented || !C->getInterface()->getImplementation()))
4020 Results.AddResult(Result(C->getInterface(), 0), CurContext,
Douglas Gregor608300b2010-01-14 16:14:35 +00004021 0, false);
Douglas Gregor3b49aca2009-11-18 16:26:39 +00004022 }
4023 }
4024}
4025
4026void Sema::CodeCompleteObjCInterfaceDecl(Scope *S) {
4027 ResultBuilder Results(*this);
4028 Results.EnterNewScope();
4029
4030 // Add all classes.
4031 AddInterfaceResults(Context.getTranslationUnitDecl(), CurContext, true,
4032 false, Results);
4033
4034 Results.ExitScope();
Douglas Gregore6b1bb62010-08-11 21:23:17 +00004035 HandleCodeCompleteResults(this, CodeCompleter,
4036 CodeCompletionContext::CCC_Other,
4037 Results.data(),Results.size());
Douglas Gregor3b49aca2009-11-18 16:26:39 +00004038}
4039
Douglas Gregorc83c6872010-04-15 22:33:43 +00004040void Sema::CodeCompleteObjCSuperclass(Scope *S, IdentifierInfo *ClassName,
4041 SourceLocation ClassNameLoc) {
Douglas Gregor3b49aca2009-11-18 16:26:39 +00004042 ResultBuilder Results(*this);
4043 Results.EnterNewScope();
4044
4045 // Make sure that we ignore the class we're currently defining.
4046 NamedDecl *CurClass
Douglas Gregorc83c6872010-04-15 22:33:43 +00004047 = LookupSingleName(TUScope, ClassName, ClassNameLoc, LookupOrdinaryName);
Douglas Gregor33ced0b2009-11-18 19:08:43 +00004048 if (CurClass && isa<ObjCInterfaceDecl>(CurClass))
Douglas Gregor3b49aca2009-11-18 16:26:39 +00004049 Results.Ignore(CurClass);
4050
4051 // Add all classes.
4052 AddInterfaceResults(Context.getTranslationUnitDecl(), CurContext, false,
4053 false, Results);
4054
4055 Results.ExitScope();
Douglas Gregore6b1bb62010-08-11 21:23:17 +00004056 HandleCodeCompleteResults(this, CodeCompleter,
4057 CodeCompletionContext::CCC_Other,
4058 Results.data(),Results.size());
Douglas Gregor3b49aca2009-11-18 16:26:39 +00004059}
4060
4061void Sema::CodeCompleteObjCImplementationDecl(Scope *S) {
4062 ResultBuilder Results(*this);
4063 Results.EnterNewScope();
4064
4065 // Add all unimplemented classes.
4066 AddInterfaceResults(Context.getTranslationUnitDecl(), CurContext, false,
4067 true, Results);
4068
4069 Results.ExitScope();
Douglas Gregore6b1bb62010-08-11 21:23:17 +00004070 HandleCodeCompleteResults(this, CodeCompleter,
4071 CodeCompletionContext::CCC_Other,
4072 Results.data(),Results.size());
Douglas Gregor3b49aca2009-11-18 16:26:39 +00004073}
Douglas Gregor33ced0b2009-11-18 19:08:43 +00004074
4075void Sema::CodeCompleteObjCInterfaceCategory(Scope *S,
Douglas Gregorc83c6872010-04-15 22:33:43 +00004076 IdentifierInfo *ClassName,
4077 SourceLocation ClassNameLoc) {
Douglas Gregor33ced0b2009-11-18 19:08:43 +00004078 typedef CodeCompleteConsumer::Result Result;
4079
4080 ResultBuilder Results(*this);
4081
4082 // Ignore any categories we find that have already been implemented by this
4083 // interface.
4084 llvm::SmallPtrSet<IdentifierInfo *, 16> CategoryNames;
4085 NamedDecl *CurClass
Douglas Gregorc83c6872010-04-15 22:33:43 +00004086 = LookupSingleName(TUScope, ClassName, ClassNameLoc, LookupOrdinaryName);
Douglas Gregor33ced0b2009-11-18 19:08:43 +00004087 if (ObjCInterfaceDecl *Class = dyn_cast_or_null<ObjCInterfaceDecl>(CurClass))
4088 for (ObjCCategoryDecl *Category = Class->getCategoryList(); Category;
4089 Category = Category->getNextClassCategory())
4090 CategoryNames.insert(Category->getIdentifier());
4091
4092 // Add all of the categories we know about.
4093 Results.EnterNewScope();
4094 TranslationUnitDecl *TU = Context.getTranslationUnitDecl();
4095 for (DeclContext::decl_iterator D = TU->decls_begin(),
4096 DEnd = TU->decls_end();
4097 D != DEnd; ++D)
4098 if (ObjCCategoryDecl *Category = dyn_cast<ObjCCategoryDecl>(*D))
4099 if (CategoryNames.insert(Category->getIdentifier()))
Douglas Gregor608300b2010-01-14 16:14:35 +00004100 Results.AddResult(Result(Category, 0), CurContext, 0, false);
Douglas Gregor33ced0b2009-11-18 19:08:43 +00004101 Results.ExitScope();
4102
Douglas Gregore6b1bb62010-08-11 21:23:17 +00004103 HandleCodeCompleteResults(this, CodeCompleter,
4104 CodeCompletionContext::CCC_Other,
4105 Results.data(),Results.size());
Douglas Gregor33ced0b2009-11-18 19:08:43 +00004106}
4107
4108void Sema::CodeCompleteObjCImplementationCategory(Scope *S,
Douglas Gregorc83c6872010-04-15 22:33:43 +00004109 IdentifierInfo *ClassName,
4110 SourceLocation ClassNameLoc) {
Douglas Gregor33ced0b2009-11-18 19:08:43 +00004111 typedef CodeCompleteConsumer::Result Result;
4112
4113 // Find the corresponding interface. If we couldn't find the interface, the
4114 // program itself is ill-formed. However, we'll try to be helpful still by
4115 // providing the list of all of the categories we know about.
4116 NamedDecl *CurClass
Douglas Gregorc83c6872010-04-15 22:33:43 +00004117 = LookupSingleName(TUScope, ClassName, ClassNameLoc, LookupOrdinaryName);
Douglas Gregor33ced0b2009-11-18 19:08:43 +00004118 ObjCInterfaceDecl *Class = dyn_cast_or_null<ObjCInterfaceDecl>(CurClass);
4119 if (!Class)
Douglas Gregorc83c6872010-04-15 22:33:43 +00004120 return CodeCompleteObjCInterfaceCategory(S, ClassName, ClassNameLoc);
Douglas Gregor33ced0b2009-11-18 19:08:43 +00004121
4122 ResultBuilder Results(*this);
4123
4124 // Add all of the categories that have have corresponding interface
4125 // declarations in this class and any of its superclasses, except for
4126 // already-implemented categories in the class itself.
4127 llvm::SmallPtrSet<IdentifierInfo *, 16> CategoryNames;
4128 Results.EnterNewScope();
4129 bool IgnoreImplemented = true;
4130 while (Class) {
4131 for (ObjCCategoryDecl *Category = Class->getCategoryList(); Category;
4132 Category = Category->getNextClassCategory())
4133 if ((!IgnoreImplemented || !Category->getImplementation()) &&
4134 CategoryNames.insert(Category->getIdentifier()))
Douglas Gregor608300b2010-01-14 16:14:35 +00004135 Results.AddResult(Result(Category, 0), CurContext, 0, false);
Douglas Gregor33ced0b2009-11-18 19:08:43 +00004136
4137 Class = Class->getSuperClass();
4138 IgnoreImplemented = false;
4139 }
4140 Results.ExitScope();
4141
Douglas Gregore6b1bb62010-08-11 21:23:17 +00004142 HandleCodeCompleteResults(this, CodeCompleter,
4143 CodeCompletionContext::CCC_Other,
4144 Results.data(),Results.size());
Douglas Gregor33ced0b2009-11-18 19:08:43 +00004145}
Douglas Gregor322328b2009-11-18 22:32:06 +00004146
John McCalld226f652010-08-21 09:40:31 +00004147void Sema::CodeCompleteObjCPropertyDefinition(Scope *S, Decl *ObjCImpDecl) {
Douglas Gregor322328b2009-11-18 22:32:06 +00004148 typedef CodeCompleteConsumer::Result Result;
4149 ResultBuilder Results(*this);
4150
4151 // Figure out where this @synthesize lives.
4152 ObjCContainerDecl *Container
John McCalld226f652010-08-21 09:40:31 +00004153 = dyn_cast_or_null<ObjCContainerDecl>(ObjCImpDecl);
Douglas Gregor322328b2009-11-18 22:32:06 +00004154 if (!Container ||
4155 (!isa<ObjCImplementationDecl>(Container) &&
4156 !isa<ObjCCategoryImplDecl>(Container)))
4157 return;
4158
4159 // Ignore any properties that have already been implemented.
4160 for (DeclContext::decl_iterator D = Container->decls_begin(),
4161 DEnd = Container->decls_end();
4162 D != DEnd; ++D)
4163 if (ObjCPropertyImplDecl *PropertyImpl = dyn_cast<ObjCPropertyImplDecl>(*D))
4164 Results.Ignore(PropertyImpl->getPropertyDecl());
4165
4166 // Add any properties that we find.
4167 Results.EnterNewScope();
4168 if (ObjCImplementationDecl *ClassImpl
4169 = dyn_cast<ObjCImplementationDecl>(Container))
4170 AddObjCProperties(ClassImpl->getClassInterface(), false, CurContext,
4171 Results);
4172 else
4173 AddObjCProperties(cast<ObjCCategoryImplDecl>(Container)->getCategoryDecl(),
4174 false, CurContext, Results);
4175 Results.ExitScope();
4176
Douglas Gregore6b1bb62010-08-11 21:23:17 +00004177 HandleCodeCompleteResults(this, CodeCompleter,
4178 CodeCompletionContext::CCC_Other,
4179 Results.data(),Results.size());
Douglas Gregor322328b2009-11-18 22:32:06 +00004180}
4181
4182void Sema::CodeCompleteObjCPropertySynthesizeIvar(Scope *S,
4183 IdentifierInfo *PropertyName,
John McCalld226f652010-08-21 09:40:31 +00004184 Decl *ObjCImpDecl) {
Douglas Gregor322328b2009-11-18 22:32:06 +00004185 typedef CodeCompleteConsumer::Result Result;
4186 ResultBuilder Results(*this);
4187
4188 // Figure out where this @synthesize lives.
4189 ObjCContainerDecl *Container
John McCalld226f652010-08-21 09:40:31 +00004190 = dyn_cast_or_null<ObjCContainerDecl>(ObjCImpDecl);
Douglas Gregor322328b2009-11-18 22:32:06 +00004191 if (!Container ||
4192 (!isa<ObjCImplementationDecl>(Container) &&
4193 !isa<ObjCCategoryImplDecl>(Container)))
4194 return;
4195
4196 // Figure out which interface we're looking into.
4197 ObjCInterfaceDecl *Class = 0;
4198 if (ObjCImplementationDecl *ClassImpl
4199 = dyn_cast<ObjCImplementationDecl>(Container))
4200 Class = ClassImpl->getClassInterface();
4201 else
4202 Class = cast<ObjCCategoryImplDecl>(Container)->getCategoryDecl()
4203 ->getClassInterface();
4204
4205 // Add all of the instance variables in this class and its superclasses.
4206 Results.EnterNewScope();
4207 for(; Class; Class = Class->getSuperClass()) {
4208 // FIXME: We could screen the type of each ivar for compatibility with
4209 // the property, but is that being too paternal?
4210 for (ObjCInterfaceDecl::ivar_iterator IVar = Class->ivar_begin(),
4211 IVarEnd = Class->ivar_end();
4212 IVar != IVarEnd; ++IVar)
Douglas Gregor608300b2010-01-14 16:14:35 +00004213 Results.AddResult(Result(*IVar, 0), CurContext, 0, false);
Douglas Gregor322328b2009-11-18 22:32:06 +00004214 }
4215 Results.ExitScope();
4216
Douglas Gregore6b1bb62010-08-11 21:23:17 +00004217 HandleCodeCompleteResults(this, CodeCompleter,
4218 CodeCompletionContext::CCC_Other,
4219 Results.data(),Results.size());
Douglas Gregor322328b2009-11-18 22:32:06 +00004220}
Douglas Gregore8f5a172010-04-07 00:21:17 +00004221
4222typedef llvm::DenseMap<Selector, ObjCMethodDecl *> KnownMethodsMap;
4223
4224/// \brief Find all of the methods that reside in the given container
4225/// (and its superclasses, protocols, etc.) that meet the given
4226/// criteria. Insert those methods into the map of known methods,
4227/// indexed by selector so they can be easily found.
4228static void FindImplementableMethods(ASTContext &Context,
4229 ObjCContainerDecl *Container,
4230 bool WantInstanceMethods,
4231 QualType ReturnType,
4232 bool IsInImplementation,
4233 KnownMethodsMap &KnownMethods) {
4234 if (ObjCInterfaceDecl *IFace = dyn_cast<ObjCInterfaceDecl>(Container)) {
4235 // Recurse into protocols.
4236 const ObjCList<ObjCProtocolDecl> &Protocols
4237 = IFace->getReferencedProtocols();
4238 for (ObjCList<ObjCProtocolDecl>::iterator I = Protocols.begin(),
4239 E = Protocols.end();
4240 I != E; ++I)
4241 FindImplementableMethods(Context, *I, WantInstanceMethods, ReturnType,
4242 IsInImplementation, KnownMethods);
4243
4244 // If we're not in the implementation of a class, also visit the
4245 // superclass.
4246 if (!IsInImplementation && IFace->getSuperClass())
4247 FindImplementableMethods(Context, IFace->getSuperClass(),
4248 WantInstanceMethods, ReturnType,
4249 IsInImplementation, KnownMethods);
4250
4251 // Add methods from any class extensions (but not from categories;
4252 // those should go into category implementations).
Fariborz Jahanian80aa1cd2010-06-22 23:20:40 +00004253 for (const ObjCCategoryDecl *Cat = IFace->getFirstClassExtension(); Cat;
4254 Cat = Cat->getNextClassExtension())
4255 FindImplementableMethods(Context, const_cast<ObjCCategoryDecl*>(Cat),
4256 WantInstanceMethods, ReturnType,
Douglas Gregore8f5a172010-04-07 00:21:17 +00004257 IsInImplementation, KnownMethods);
Douglas Gregore8f5a172010-04-07 00:21:17 +00004258 }
4259
4260 if (ObjCCategoryDecl *Category = dyn_cast<ObjCCategoryDecl>(Container)) {
4261 // Recurse into protocols.
4262 const ObjCList<ObjCProtocolDecl> &Protocols
4263 = Category->getReferencedProtocols();
4264 for (ObjCList<ObjCProtocolDecl>::iterator I = Protocols.begin(),
4265 E = Protocols.end();
4266 I != E; ++I)
4267 FindImplementableMethods(Context, *I, WantInstanceMethods, ReturnType,
4268 IsInImplementation, KnownMethods);
4269 }
4270
4271 if (ObjCProtocolDecl *Protocol = dyn_cast<ObjCProtocolDecl>(Container)) {
4272 // Recurse into protocols.
4273 const ObjCList<ObjCProtocolDecl> &Protocols
4274 = Protocol->getReferencedProtocols();
4275 for (ObjCList<ObjCProtocolDecl>::iterator I = Protocols.begin(),
4276 E = Protocols.end();
4277 I != E; ++I)
4278 FindImplementableMethods(Context, *I, WantInstanceMethods, ReturnType,
4279 IsInImplementation, KnownMethods);
4280 }
4281
4282 // Add methods in this container. This operation occurs last because
4283 // we want the methods from this container to override any methods
4284 // we've previously seen with the same selector.
4285 for (ObjCContainerDecl::method_iterator M = Container->meth_begin(),
4286 MEnd = Container->meth_end();
4287 M != MEnd; ++M) {
4288 if ((*M)->isInstanceMethod() == WantInstanceMethods) {
4289 if (!ReturnType.isNull() &&
4290 !Context.hasSameUnqualifiedType(ReturnType, (*M)->getResultType()))
4291 continue;
4292
4293 KnownMethods[(*M)->getSelector()] = *M;
4294 }
4295 }
4296}
4297
4298void Sema::CodeCompleteObjCMethodDecl(Scope *S,
4299 bool IsInstanceMethod,
John McCallb3d87482010-08-24 05:47:05 +00004300 ParsedType ReturnTy,
John McCalld226f652010-08-21 09:40:31 +00004301 Decl *IDecl) {
Douglas Gregore8f5a172010-04-07 00:21:17 +00004302 // Determine the return type of the method we're declaring, if
4303 // provided.
4304 QualType ReturnType = GetTypeFromParser(ReturnTy);
4305
4306 // Determine where we should start searching for methods, and where we
4307 ObjCContainerDecl *SearchDecl = 0, *CurrentDecl = 0;
4308 bool IsInImplementation = false;
John McCalld226f652010-08-21 09:40:31 +00004309 if (Decl *D = IDecl) {
Douglas Gregore8f5a172010-04-07 00:21:17 +00004310 if (ObjCImplementationDecl *Impl = dyn_cast<ObjCImplementationDecl>(D)) {
4311 SearchDecl = Impl->getClassInterface();
4312 CurrentDecl = Impl;
4313 IsInImplementation = true;
4314 } else if (ObjCCategoryImplDecl *CatImpl
4315 = dyn_cast<ObjCCategoryImplDecl>(D)) {
4316 SearchDecl = CatImpl->getCategoryDecl();
4317 CurrentDecl = CatImpl;
4318 IsInImplementation = true;
4319 } else {
4320 SearchDecl = dyn_cast<ObjCContainerDecl>(D);
4321 CurrentDecl = SearchDecl;
4322 }
4323 }
4324
4325 if (!SearchDecl && S) {
4326 if (DeclContext *DC = static_cast<DeclContext *>(S->getEntity())) {
4327 SearchDecl = dyn_cast<ObjCContainerDecl>(DC);
4328 CurrentDecl = SearchDecl;
4329 }
4330 }
4331
4332 if (!SearchDecl || !CurrentDecl) {
Douglas Gregore6b1bb62010-08-11 21:23:17 +00004333 HandleCodeCompleteResults(this, CodeCompleter,
4334 CodeCompletionContext::CCC_Other,
4335 0, 0);
Douglas Gregore8f5a172010-04-07 00:21:17 +00004336 return;
4337 }
4338
4339 // Find all of the methods that we could declare/implement here.
4340 KnownMethodsMap KnownMethods;
4341 FindImplementableMethods(Context, SearchDecl, IsInstanceMethod,
4342 ReturnType, IsInImplementation, KnownMethods);
4343
4344 // Erase any methods that have already been declared or
4345 // implemented here.
4346 for (ObjCContainerDecl::method_iterator M = CurrentDecl->meth_begin(),
4347 MEnd = CurrentDecl->meth_end();
4348 M != MEnd; ++M) {
4349 if ((*M)->isInstanceMethod() != IsInstanceMethod)
4350 continue;
4351
4352 KnownMethodsMap::iterator Pos = KnownMethods.find((*M)->getSelector());
4353 if (Pos != KnownMethods.end())
4354 KnownMethods.erase(Pos);
4355 }
4356
4357 // Add declarations or definitions for each of the known methods.
4358 typedef CodeCompleteConsumer::Result Result;
4359 ResultBuilder Results(*this);
4360 Results.EnterNewScope();
4361 PrintingPolicy Policy(Context.PrintingPolicy);
4362 Policy.AnonymousTagLocations = false;
4363 for (KnownMethodsMap::iterator M = KnownMethods.begin(),
4364 MEnd = KnownMethods.end();
4365 M != MEnd; ++M) {
4366 ObjCMethodDecl *Method = M->second;
4367 CodeCompletionString *Pattern = new CodeCompletionString;
4368
4369 // If the result type was not already provided, add it to the
4370 // pattern as (type).
4371 if (ReturnType.isNull()) {
4372 std::string TypeStr;
4373 Method->getResultType().getAsStringInternal(TypeStr, Policy);
4374 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
4375 Pattern->AddTextChunk(TypeStr);
4376 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
4377 }
4378
4379 Selector Sel = Method->getSelector();
4380
4381 // Add the first part of the selector to the pattern.
4382 Pattern->AddTypedTextChunk(Sel.getIdentifierInfoForSlot(0)->getName());
4383
4384 // Add parameters to the pattern.
4385 unsigned I = 0;
4386 for (ObjCMethodDecl::param_iterator P = Method->param_begin(),
4387 PEnd = Method->param_end();
4388 P != PEnd; (void)++P, ++I) {
4389 // Add the part of the selector name.
4390 if (I == 0)
4391 Pattern->AddChunk(CodeCompletionString::CK_Colon);
4392 else if (I < Sel.getNumArgs()) {
4393 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
Douglas Gregor47c03a72010-08-17 15:53:35 +00004394 Pattern->AddTextChunk(Sel.getIdentifierInfoForSlot(I)->getName());
Douglas Gregore8f5a172010-04-07 00:21:17 +00004395 Pattern->AddChunk(CodeCompletionString::CK_Colon);
4396 } else
4397 break;
4398
4399 // Add the parameter type.
4400 std::string TypeStr;
4401 (*P)->getOriginalType().getAsStringInternal(TypeStr, Policy);
4402 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
4403 Pattern->AddTextChunk(TypeStr);
4404 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
4405
4406 if (IdentifierInfo *Id = (*P)->getIdentifier())
4407 Pattern->AddTextChunk(Id->getName());
4408 }
4409
4410 if (Method->isVariadic()) {
4411 if (Method->param_size() > 0)
4412 Pattern->AddChunk(CodeCompletionString::CK_Comma);
4413 Pattern->AddTextChunk("...");
4414 }
4415
Douglas Gregor447107d2010-05-28 00:57:46 +00004416 if (IsInImplementation && Results.includeCodePatterns()) {
Douglas Gregore8f5a172010-04-07 00:21:17 +00004417 // We will be defining the method here, so add a compound statement.
4418 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
4419 Pattern->AddChunk(CodeCompletionString::CK_LeftBrace);
4420 Pattern->AddChunk(CodeCompletionString::CK_VerticalSpace);
4421 if (!Method->getResultType()->isVoidType()) {
4422 // If the result type is not void, add a return clause.
4423 Pattern->AddTextChunk("return");
4424 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
4425 Pattern->AddPlaceholderChunk("expression");
4426 Pattern->AddChunk(CodeCompletionString::CK_SemiColon);
4427 } else
4428 Pattern->AddPlaceholderChunk("statements");
4429
4430 Pattern->AddChunk(CodeCompletionString::CK_VerticalSpace);
4431 Pattern->AddChunk(CodeCompletionString::CK_RightBrace);
4432 }
4433
Douglas Gregor16ed9ad2010-08-17 16:06:07 +00004434 Results.AddResult(Result(Pattern, CCP_CodePattern,
4435 Method->isInstanceMethod()
4436 ? CXCursor_ObjCInstanceMethodDecl
4437 : CXCursor_ObjCClassMethodDecl));
Douglas Gregore8f5a172010-04-07 00:21:17 +00004438 }
4439
4440 Results.ExitScope();
4441
Douglas Gregore6b1bb62010-08-11 21:23:17 +00004442 HandleCodeCompleteResults(this, CodeCompleter,
4443 CodeCompletionContext::CCC_Other,
4444 Results.data(),Results.size());
Douglas Gregore8f5a172010-04-07 00:21:17 +00004445}
Douglas Gregor1f5537a2010-07-08 23:20:03 +00004446
4447void Sema::CodeCompleteObjCMethodDeclSelector(Scope *S,
4448 bool IsInstanceMethod,
Douglas Gregor40ed9a12010-07-08 23:37:41 +00004449 bool AtParameterName,
John McCallb3d87482010-08-24 05:47:05 +00004450 ParsedType ReturnTy,
Douglas Gregor1f5537a2010-07-08 23:20:03 +00004451 IdentifierInfo **SelIdents,
4452 unsigned NumSelIdents) {
Douglas Gregor1f5537a2010-07-08 23:20:03 +00004453 // If we have an external source, load the entire class method
Sebastian Redl3c7f4132010-08-18 23:57:06 +00004454 // pool from the AST file.
Douglas Gregor1f5537a2010-07-08 23:20:03 +00004455 if (ExternalSource) {
4456 for (uint32_t I = 0, N = ExternalSource->GetNumExternalSelectors();
4457 I != N; ++I) {
4458 Selector Sel = ExternalSource->GetExternalSelector(I);
Sebastian Redldb9d2142010-08-02 23:18:59 +00004459 if (Sel.isNull() || MethodPool.count(Sel))
Douglas Gregor1f5537a2010-07-08 23:20:03 +00004460 continue;
Sebastian Redldb9d2142010-08-02 23:18:59 +00004461
4462 ReadMethodPool(Sel);
Douglas Gregor1f5537a2010-07-08 23:20:03 +00004463 }
4464 }
4465
4466 // Build the set of methods we can see.
4467 typedef CodeCompleteConsumer::Result Result;
4468 ResultBuilder Results(*this);
4469
4470 if (ReturnTy)
4471 Results.setPreferredType(GetTypeFromParser(ReturnTy).getNonReferenceType());
Sebastian Redldb9d2142010-08-02 23:18:59 +00004472
Douglas Gregor1f5537a2010-07-08 23:20:03 +00004473 Results.EnterNewScope();
Sebastian Redldb9d2142010-08-02 23:18:59 +00004474 for (GlobalMethodPool::iterator M = MethodPool.begin(),
4475 MEnd = MethodPool.end();
4476 M != MEnd; ++M) {
4477 for (ObjCMethodList *MethList = IsInstanceMethod ? &M->second.first :
4478 &M->second.second;
4479 MethList && MethList->Method;
Douglas Gregor1f5537a2010-07-08 23:20:03 +00004480 MethList = MethList->Next) {
4481 if (!isAcceptableObjCMethod(MethList->Method, MK_Any, SelIdents,
4482 NumSelIdents))
4483 continue;
4484
Douglas Gregor40ed9a12010-07-08 23:37:41 +00004485 if (AtParameterName) {
4486 // Suggest parameter names we've seen before.
4487 if (NumSelIdents && NumSelIdents <= MethList->Method->param_size()) {
4488 ParmVarDecl *Param = MethList->Method->param_begin()[NumSelIdents-1];
4489 if (Param->getIdentifier()) {
4490 CodeCompletionString *Pattern = new CodeCompletionString;
4491 Pattern->AddTypedTextChunk(Param->getIdentifier()->getName());
4492 Results.AddResult(Pattern);
4493 }
4494 }
4495
4496 continue;
4497 }
4498
Douglas Gregor1f5537a2010-07-08 23:20:03 +00004499 Result R(MethList->Method, 0);
4500 R.StartParameter = NumSelIdents;
4501 R.AllParametersAreInformative = false;
4502 R.DeclaringEntity = true;
4503 Results.MaybeAddResult(R, CurContext);
4504 }
4505 }
4506
4507 Results.ExitScope();
Douglas Gregore6b1bb62010-08-11 21:23:17 +00004508 HandleCodeCompleteResults(this, CodeCompleter,
4509 CodeCompletionContext::CCC_Other,
4510 Results.data(),Results.size());
Douglas Gregor1f5537a2010-07-08 23:20:03 +00004511}
Douglas Gregor87c08a52010-08-13 22:48:40 +00004512
4513void Sema::GatherGlobalCodeCompletions(
4514 llvm::SmallVectorImpl<CodeCompleteConsumer::Result> &Results) {
4515 ResultBuilder Builder(*this);
4516
Douglas Gregor8071e422010-08-15 06:18:01 +00004517 if (!CodeCompleter || CodeCompleter->includeGlobals()) {
4518 CodeCompletionDeclConsumer Consumer(Builder,
4519 Context.getTranslationUnitDecl());
4520 LookupVisibleDecls(Context.getTranslationUnitDecl(), LookupAnyName,
4521 Consumer);
4522 }
Douglas Gregor87c08a52010-08-13 22:48:40 +00004523
4524 if (!CodeCompleter || CodeCompleter->includeMacros())
4525 AddMacroResults(PP, Builder);
4526
4527 Results.clear();
4528 Results.insert(Results.end(),
4529 Builder.data(), Builder.data() + Builder.size());
4530}