blob: 8be3da06ac426240b6eab14cc7b63a000c9a29e1 [file] [log] [blame]
Douglas Gregor2436e712009-09-17 21:32:03 +00001//===---------------- SemaCodeComplete.cpp - Code Completion ----*- C++ -*-===//
2//
3// The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9//
10// This file defines the code-completion semantic actions.
11//
12//===----------------------------------------------------------------------===//
13#include "Sema.h"
Douglas Gregorc580c522010-01-14 01:09:38 +000014#include "Lookup.h"
Douglas Gregor2436e712009-09-17 21:32:03 +000015#include "clang/Sema/CodeCompleteConsumer.h"
Douglas Gregord720daf2010-04-06 17:30:22 +000016#include "clang/Sema/ExternalSemaSource.h"
Douglas Gregorf2510672009-09-21 19:57:38 +000017#include "clang/AST/ExprCXX.h"
Douglas Gregor8ce33212009-11-17 17:59:40 +000018#include "clang/AST/ExprObjC.h"
Douglas Gregorf329c7c2009-10-30 16:50:04 +000019#include "clang/Lex/MacroInfo.h"
20#include "clang/Lex/Preprocessor.h"
Douglas Gregor3545ff42009-09-21 16:56:56 +000021#include "llvm/ADT/SmallPtrSet.h"
Douglas Gregore6688e62009-09-28 03:51:44 +000022#include "llvm/ADT/StringExtras.h"
Douglas Gregor9d2ddb22010-04-06 19:22:33 +000023#include "llvm/ADT/StringSwitch.h"
Douglas Gregor3545ff42009-09-21 16:56:56 +000024#include <list>
25#include <map>
26#include <vector>
Douglas Gregor2436e712009-09-17 21:32:03 +000027
28using namespace clang;
29
Douglas Gregor3545ff42009-09-21 16:56:56 +000030namespace {
31 /// \brief A container of code-completion results.
32 class ResultBuilder {
33 public:
34 /// \brief The type of a name-lookup filter, which can be provided to the
35 /// name-lookup routines to specify which declarations should be included in
36 /// the result set (when it returns true) and which declarations should be
37 /// filtered out (returns false).
38 typedef bool (ResultBuilder::*LookupFilter)(NamedDecl *) const;
39
40 typedef CodeCompleteConsumer::Result Result;
41
42 private:
43 /// \brief The actual results we have found.
44 std::vector<Result> Results;
45
46 /// \brief A record of all of the declarations we have found and placed
47 /// into the result set, used to ensure that no declaration ever gets into
48 /// the result set twice.
49 llvm::SmallPtrSet<Decl*, 16> AllDeclsFound;
50
Douglas Gregor05e7ca32009-12-06 20:23:50 +000051 typedef std::pair<NamedDecl *, unsigned> DeclIndexPair;
52
53 /// \brief An entry in the shadow map, which is optimized to store
54 /// a single (declaration, index) mapping (the common case) but
55 /// can also store a list of (declaration, index) mappings.
56 class ShadowMapEntry {
57 typedef llvm::SmallVector<DeclIndexPair, 4> DeclIndexPairVector;
58
59 /// \brief Contains either the solitary NamedDecl * or a vector
60 /// of (declaration, index) pairs.
61 llvm::PointerUnion<NamedDecl *, DeclIndexPairVector*> DeclOrVector;
62
63 /// \brief When the entry contains a single declaration, this is
64 /// the index associated with that entry.
65 unsigned SingleDeclIndex;
66
67 public:
68 ShadowMapEntry() : DeclOrVector(), SingleDeclIndex(0) { }
69
70 void Add(NamedDecl *ND, unsigned Index) {
71 if (DeclOrVector.isNull()) {
72 // 0 - > 1 elements: just set the single element information.
73 DeclOrVector = ND;
74 SingleDeclIndex = Index;
75 return;
76 }
77
78 if (NamedDecl *PrevND = DeclOrVector.dyn_cast<NamedDecl *>()) {
79 // 1 -> 2 elements: create the vector of results and push in the
80 // existing declaration.
81 DeclIndexPairVector *Vec = new DeclIndexPairVector;
82 Vec->push_back(DeclIndexPair(PrevND, SingleDeclIndex));
83 DeclOrVector = Vec;
84 }
85
86 // Add the new element to the end of the vector.
87 DeclOrVector.get<DeclIndexPairVector*>()->push_back(
88 DeclIndexPair(ND, Index));
89 }
90
91 void Destroy() {
92 if (DeclIndexPairVector *Vec
93 = DeclOrVector.dyn_cast<DeclIndexPairVector *>()) {
94 delete Vec;
95 DeclOrVector = ((NamedDecl *)0);
96 }
97 }
98
99 // Iteration.
100 class iterator;
101 iterator begin() const;
102 iterator end() const;
103 };
104
Douglas Gregor3545ff42009-09-21 16:56:56 +0000105 /// \brief A mapping from declaration names to the declarations that have
106 /// this name within a particular scope and their index within the list of
107 /// results.
Douglas Gregor05e7ca32009-12-06 20:23:50 +0000108 typedef llvm::DenseMap<DeclarationName, ShadowMapEntry> ShadowMap;
Douglas Gregor3545ff42009-09-21 16:56:56 +0000109
110 /// \brief The semantic analysis object for which results are being
111 /// produced.
112 Sema &SemaRef;
113
114 /// \brief If non-NULL, a filter function used to remove any code-completion
115 /// results that are not desirable.
116 LookupFilter Filter;
Douglas Gregor6ae4c522010-01-14 03:21:49 +0000117
118 /// \brief Whether we should allow declarations as
119 /// nested-name-specifiers that would otherwise be filtered out.
120 bool AllowNestedNameSpecifiers;
121
Douglas Gregor3545ff42009-09-21 16:56:56 +0000122 /// \brief A list of shadow maps, which is used to model name hiding at
123 /// different levels of, e.g., the inheritance hierarchy.
124 std::list<ShadowMap> ShadowMaps;
125
126 public:
127 explicit ResultBuilder(Sema &SemaRef, LookupFilter Filter = 0)
Douglas Gregor6ae4c522010-01-14 03:21:49 +0000128 : SemaRef(SemaRef), Filter(Filter), AllowNestedNameSpecifiers(false) { }
Douglas Gregor3545ff42009-09-21 16:56:56 +0000129
130 /// \brief Set the filter used for code-completion results.
131 void setFilter(LookupFilter Filter) {
132 this->Filter = Filter;
133 }
134
135 typedef std::vector<Result>::iterator iterator;
136 iterator begin() { return Results.begin(); }
137 iterator end() { return Results.end(); }
138
139 Result *data() { return Results.empty()? 0 : &Results.front(); }
140 unsigned size() const { return Results.size(); }
141 bool empty() const { return Results.empty(); }
142
Douglas Gregor6ae4c522010-01-14 03:21:49 +0000143 /// \brief Specify whether nested-name-specifiers are allowed.
144 void allowNestedNameSpecifiers(bool Allow = true) {
145 AllowNestedNameSpecifiers = Allow;
146 }
147
Douglas Gregor7c208612010-01-14 00:20:49 +0000148 /// \brief Determine whether the given declaration is at all interesting
149 /// as a code-completion result.
Douglas Gregor6ae4c522010-01-14 03:21:49 +0000150 ///
151 /// \param ND the declaration that we are inspecting.
152 ///
153 /// \param AsNestedNameSpecifier will be set true if this declaration is
154 /// only interesting when it is a nested-name-specifier.
155 bool isInterestingDecl(NamedDecl *ND, bool &AsNestedNameSpecifier) const;
Douglas Gregore0717ab2010-01-14 00:41:07 +0000156
157 /// \brief Check whether the result is hidden by the Hiding declaration.
158 ///
159 /// \returns true if the result is hidden and cannot be found, false if
160 /// the hidden result could still be found. When false, \p R may be
161 /// modified to describe how the result can be found (e.g., via extra
162 /// qualification).
163 bool CheckHiddenResult(Result &R, DeclContext *CurContext,
164 NamedDecl *Hiding);
165
Douglas Gregor3545ff42009-09-21 16:56:56 +0000166 /// \brief Add a new result to this result set (if it isn't already in one
167 /// of the shadow maps), or replace an existing result (for, e.g., a
168 /// redeclaration).
Douglas Gregor2af2f672009-09-21 20:12:40 +0000169 ///
Douglas Gregorc580c522010-01-14 01:09:38 +0000170 /// \param CurContext the result to add (if it is unique).
Douglas Gregor2af2f672009-09-21 20:12:40 +0000171 ///
172 /// \param R the context in which this result will be named.
173 void MaybeAddResult(Result R, DeclContext *CurContext = 0);
Douglas Gregor3545ff42009-09-21 16:56:56 +0000174
Douglas Gregorc580c522010-01-14 01:09:38 +0000175 /// \brief Add a new result to this result set, where we already know
176 /// the hiding declation (if any).
177 ///
178 /// \param R the result to add (if it is unique).
179 ///
180 /// \param CurContext the context in which this result will be named.
181 ///
182 /// \param Hiding the declaration that hides the result.
Douglas Gregor09bbc652010-01-14 15:47:35 +0000183 ///
184 /// \param InBaseClass whether the result was found in a base
185 /// class of the searched context.
186 void AddResult(Result R, DeclContext *CurContext, NamedDecl *Hiding,
187 bool InBaseClass);
Douglas Gregorc580c522010-01-14 01:09:38 +0000188
Douglas Gregor78a21012010-01-14 16:01:26 +0000189 /// \brief Add a new non-declaration result to this result set.
190 void AddResult(Result R);
191
Douglas Gregor3545ff42009-09-21 16:56:56 +0000192 /// \brief Enter into a new scope.
193 void EnterNewScope();
194
195 /// \brief Exit from the current scope.
196 void ExitScope();
197
Douglas Gregorbaf69612009-11-18 04:19:12 +0000198 /// \brief Ignore this declaration, if it is seen again.
199 void Ignore(Decl *D) { AllDeclsFound.insert(D->getCanonicalDecl()); }
200
Douglas Gregor3545ff42009-09-21 16:56:56 +0000201 /// \name Name lookup predicates
202 ///
203 /// These predicates can be passed to the name lookup functions to filter the
204 /// results of name lookup. All of the predicates have the same type, so that
205 ///
206 //@{
Douglas Gregor9d64c5e2009-09-21 20:51:25 +0000207 bool IsOrdinaryName(NamedDecl *ND) const;
Douglas Gregor504a6ae2010-01-10 23:08:15 +0000208 bool IsOrdinaryNonValueName(NamedDecl *ND) const;
Douglas Gregor3545ff42009-09-21 16:56:56 +0000209 bool IsNestedNameSpecifier(NamedDecl *ND) const;
210 bool IsEnum(NamedDecl *ND) const;
211 bool IsClassOrStruct(NamedDecl *ND) const;
212 bool IsUnion(NamedDecl *ND) const;
213 bool IsNamespace(NamedDecl *ND) const;
214 bool IsNamespaceOrAlias(NamedDecl *ND) const;
215 bool IsType(NamedDecl *ND) const;
Douglas Gregore412a5a2009-09-23 22:26:46 +0000216 bool IsMember(NamedDecl *ND) const;
Douglas Gregor2b8162b2010-01-14 16:08:12 +0000217 bool IsObjCIvar(NamedDecl *ND) const;
Douglas Gregor3545ff42009-09-21 16:56:56 +0000218 //@}
219 };
220}
221
Douglas Gregor05e7ca32009-12-06 20:23:50 +0000222class ResultBuilder::ShadowMapEntry::iterator {
223 llvm::PointerUnion<NamedDecl*, const DeclIndexPair*> DeclOrIterator;
224 unsigned SingleDeclIndex;
225
226public:
227 typedef DeclIndexPair value_type;
228 typedef value_type reference;
229 typedef std::ptrdiff_t difference_type;
230 typedef std::input_iterator_tag iterator_category;
231
232 class pointer {
233 DeclIndexPair Value;
234
235 public:
236 pointer(const DeclIndexPair &Value) : Value(Value) { }
237
238 const DeclIndexPair *operator->() const {
239 return &Value;
240 }
241 };
242
243 iterator() : DeclOrIterator((NamedDecl *)0), SingleDeclIndex(0) { }
244
245 iterator(NamedDecl *SingleDecl, unsigned Index)
246 : DeclOrIterator(SingleDecl), SingleDeclIndex(Index) { }
247
248 iterator(const DeclIndexPair *Iterator)
249 : DeclOrIterator(Iterator), SingleDeclIndex(0) { }
250
251 iterator &operator++() {
252 if (DeclOrIterator.is<NamedDecl *>()) {
253 DeclOrIterator = (NamedDecl *)0;
254 SingleDeclIndex = 0;
255 return *this;
256 }
257
258 const DeclIndexPair *I = DeclOrIterator.get<const DeclIndexPair*>();
259 ++I;
260 DeclOrIterator = I;
261 return *this;
262 }
263
264 iterator operator++(int) {
265 iterator tmp(*this);
266 ++(*this);
267 return tmp;
268 }
269
270 reference operator*() const {
271 if (NamedDecl *ND = DeclOrIterator.dyn_cast<NamedDecl *>())
272 return reference(ND, SingleDeclIndex);
273
Douglas Gregor94bb5e82009-12-06 21:27:58 +0000274 return *DeclOrIterator.get<const DeclIndexPair*>();
Douglas Gregor05e7ca32009-12-06 20:23:50 +0000275 }
276
277 pointer operator->() const {
278 return pointer(**this);
279 }
280
281 friend bool operator==(const iterator &X, const iterator &Y) {
Douglas Gregor94bb5e82009-12-06 21:27:58 +0000282 return X.DeclOrIterator.getOpaqueValue()
283 == Y.DeclOrIterator.getOpaqueValue() &&
Douglas Gregor05e7ca32009-12-06 20:23:50 +0000284 X.SingleDeclIndex == Y.SingleDeclIndex;
285 }
286
287 friend bool operator!=(const iterator &X, const iterator &Y) {
Douglas Gregor94bb5e82009-12-06 21:27:58 +0000288 return !(X == Y);
Douglas Gregor05e7ca32009-12-06 20:23:50 +0000289 }
290};
291
Douglas Gregor05e7ca32009-12-06 20:23:50 +0000292ResultBuilder::ShadowMapEntry::iterator
293ResultBuilder::ShadowMapEntry::begin() const {
294 if (DeclOrVector.isNull())
295 return iterator();
296
297 if (NamedDecl *ND = DeclOrVector.dyn_cast<NamedDecl *>())
298 return iterator(ND, SingleDeclIndex);
299
300 return iterator(DeclOrVector.get<DeclIndexPairVector *>()->begin());
301}
302
303ResultBuilder::ShadowMapEntry::iterator
304ResultBuilder::ShadowMapEntry::end() const {
305 if (DeclOrVector.is<NamedDecl *>() || DeclOrVector.isNull())
306 return iterator();
307
308 return iterator(DeclOrVector.get<DeclIndexPairVector *>()->end());
309}
310
Douglas Gregor2af2f672009-09-21 20:12:40 +0000311/// \brief Compute the qualification required to get from the current context
312/// (\p CurContext) to the target context (\p TargetContext).
313///
314/// \param Context the AST context in which the qualification will be used.
315///
316/// \param CurContext the context where an entity is being named, which is
317/// typically based on the current scope.
318///
319/// \param TargetContext the context in which the named entity actually
320/// resides.
321///
322/// \returns a nested name specifier that refers into the target context, or
323/// NULL if no qualification is needed.
324static NestedNameSpecifier *
325getRequiredQualification(ASTContext &Context,
326 DeclContext *CurContext,
327 DeclContext *TargetContext) {
328 llvm::SmallVector<DeclContext *, 4> TargetParents;
329
330 for (DeclContext *CommonAncestor = TargetContext;
331 CommonAncestor && !CommonAncestor->Encloses(CurContext);
332 CommonAncestor = CommonAncestor->getLookupParent()) {
333 if (CommonAncestor->isTransparentContext() ||
334 CommonAncestor->isFunctionOrMethod())
335 continue;
336
337 TargetParents.push_back(CommonAncestor);
338 }
339
340 NestedNameSpecifier *Result = 0;
341 while (!TargetParents.empty()) {
342 DeclContext *Parent = TargetParents.back();
343 TargetParents.pop_back();
344
345 if (NamespaceDecl *Namespace = dyn_cast<NamespaceDecl>(Parent))
346 Result = NestedNameSpecifier::Create(Context, Result, Namespace);
347 else if (TagDecl *TD = dyn_cast<TagDecl>(Parent))
348 Result = NestedNameSpecifier::Create(Context, Result,
349 false,
350 Context.getTypeDeclType(TD).getTypePtr());
351 else
352 assert(Parent->isTranslationUnit());
Douglas Gregor9eb77012009-11-07 00:00:49 +0000353 }
Douglas Gregor2af2f672009-09-21 20:12:40 +0000354 return Result;
355}
356
Douglas Gregor6ae4c522010-01-14 03:21:49 +0000357bool ResultBuilder::isInterestingDecl(NamedDecl *ND,
358 bool &AsNestedNameSpecifier) const {
359 AsNestedNameSpecifier = false;
360
Douglas Gregor7c208612010-01-14 00:20:49 +0000361 ND = ND->getUnderlyingDecl();
362 unsigned IDNS = ND->getIdentifierNamespace();
Douglas Gregor58acf322009-10-09 22:16:47 +0000363
364 // Skip unnamed entities.
Douglas Gregor7c208612010-01-14 00:20:49 +0000365 if (!ND->getDeclName())
366 return false;
Douglas Gregor3545ff42009-09-21 16:56:56 +0000367
368 // Friend declarations and declarations introduced due to friends are never
369 // added as results.
John McCallbbbbe4e2010-03-11 07:50:04 +0000370 if (IDNS & (Decl::IDNS_OrdinaryFriend | Decl::IDNS_TagFriend))
Douglas Gregor7c208612010-01-14 00:20:49 +0000371 return false;
372
Douglas Gregor99fe2ad2009-12-11 17:31:05 +0000373 // Class template (partial) specializations are never added as results.
Douglas Gregor7c208612010-01-14 00:20:49 +0000374 if (isa<ClassTemplateSpecializationDecl>(ND) ||
375 isa<ClassTemplatePartialSpecializationDecl>(ND))
376 return false;
Douglas Gregor3545ff42009-09-21 16:56:56 +0000377
Douglas Gregor99fe2ad2009-12-11 17:31:05 +0000378 // Using declarations themselves are never added as results.
Douglas Gregor7c208612010-01-14 00:20:49 +0000379 if (isa<UsingDecl>(ND))
380 return false;
381
382 // Some declarations have reserved names that we don't want to ever show.
383 if (const IdentifierInfo *Id = ND->getIdentifier()) {
Douglas Gregor3545ff42009-09-21 16:56:56 +0000384 // __va_list_tag is a freak of nature. Find it and skip it.
385 if (Id->isStr("__va_list_tag") || Id->isStr("__builtin_va_list"))
Douglas Gregor7c208612010-01-14 00:20:49 +0000386 return false;
Douglas Gregor3545ff42009-09-21 16:56:56 +0000387
Douglas Gregor58acf322009-10-09 22:16:47 +0000388 // Filter out names reserved for the implementation (C99 7.1.3,
389 // C++ [lib.global.names]). Users don't need to see those.
Daniel Dunbar2c422dc92009-10-18 20:26:12 +0000390 //
391 // FIXME: Add predicate for this.
Douglas Gregor58acf322009-10-09 22:16:47 +0000392 if (Id->getLength() >= 2) {
Daniel Dunbar2c422dc92009-10-18 20:26:12 +0000393 const char *Name = Id->getNameStart();
Douglas Gregor58acf322009-10-09 22:16:47 +0000394 if (Name[0] == '_' &&
395 (Name[1] == '_' || (Name[1] >= 'A' && Name[1] <= 'Z')))
Douglas Gregor7c208612010-01-14 00:20:49 +0000396 return false;
Douglas Gregor58acf322009-10-09 22:16:47 +0000397 }
Douglas Gregor3545ff42009-09-21 16:56:56 +0000398 }
Douglas Gregor7c208612010-01-14 00:20:49 +0000399
Douglas Gregor3545ff42009-09-21 16:56:56 +0000400 // C++ constructors are never found by name lookup.
Douglas Gregor7c208612010-01-14 00:20:49 +0000401 if (isa<CXXConstructorDecl>(ND))
402 return false;
Douglas Gregor3545ff42009-09-21 16:56:56 +0000403
404 // Filter out any unwanted results.
Douglas Gregor6ae4c522010-01-14 03:21:49 +0000405 if (Filter && !(this->*Filter)(ND)) {
406 // Check whether it is interesting as a nested-name-specifier.
407 if (AllowNestedNameSpecifiers && SemaRef.getLangOptions().CPlusPlus &&
408 IsNestedNameSpecifier(ND) &&
409 (Filter != &ResultBuilder::IsMember ||
410 (isa<CXXRecordDecl>(ND) &&
411 cast<CXXRecordDecl>(ND)->isInjectedClassName()))) {
412 AsNestedNameSpecifier = true;
413 return true;
414 }
415
Douglas Gregor7c208612010-01-14 00:20:49 +0000416 return false;
Douglas Gregor6ae4c522010-01-14 03:21:49 +0000417 }
John McCalla2456712010-04-23 02:41:41 +0000418
419 if (Filter == &ResultBuilder::IsNestedNameSpecifier)
420 AsNestedNameSpecifier = true;
Douglas Gregor3545ff42009-09-21 16:56:56 +0000421
Douglas Gregor7c208612010-01-14 00:20:49 +0000422 // ... then it must be interesting!
423 return true;
424}
425
Douglas Gregore0717ab2010-01-14 00:41:07 +0000426bool ResultBuilder::CheckHiddenResult(Result &R, DeclContext *CurContext,
427 NamedDecl *Hiding) {
428 // In C, there is no way to refer to a hidden name.
429 // FIXME: This isn't true; we can find a tag name hidden by an ordinary
430 // name if we introduce the tag type.
431 if (!SemaRef.getLangOptions().CPlusPlus)
432 return true;
433
434 DeclContext *HiddenCtx = R.Declaration->getDeclContext()->getLookupContext();
435
436 // There is no way to qualify a name declared in a function or method.
437 if (HiddenCtx->isFunctionOrMethod())
438 return true;
439
440 if (HiddenCtx == Hiding->getDeclContext()->getLookupContext())
441 return true;
442
443 // We can refer to the result with the appropriate qualification. Do it.
444 R.Hidden = true;
445 R.QualifierIsInformative = false;
446
447 if (!R.Qualifier)
448 R.Qualifier = getRequiredQualification(SemaRef.Context,
449 CurContext,
450 R.Declaration->getDeclContext());
451 return false;
452}
453
Douglas Gregor7c208612010-01-14 00:20:49 +0000454void ResultBuilder::MaybeAddResult(Result R, DeclContext *CurContext) {
455 assert(!ShadowMaps.empty() && "Must enter into a results scope");
456
457 if (R.Kind != Result::RK_Declaration) {
458 // For non-declaration results, just add the result.
459 Results.push_back(R);
460 return;
461 }
462
463 // Look through using declarations.
464 if (UsingShadowDecl *Using = dyn_cast<UsingShadowDecl>(R.Declaration)) {
465 MaybeAddResult(Result(Using->getTargetDecl(), R.Qualifier), CurContext);
466 return;
467 }
468
469 Decl *CanonDecl = R.Declaration->getCanonicalDecl();
470 unsigned IDNS = CanonDecl->getIdentifierNamespace();
471
Douglas Gregor6ae4c522010-01-14 03:21:49 +0000472 bool AsNestedNameSpecifier = false;
473 if (!isInterestingDecl(R.Declaration, AsNestedNameSpecifier))
Douglas Gregor7c208612010-01-14 00:20:49 +0000474 return;
475
Douglas Gregor3545ff42009-09-21 16:56:56 +0000476 ShadowMap &SMap = ShadowMaps.back();
Douglas Gregor05e7ca32009-12-06 20:23:50 +0000477 ShadowMapEntry::iterator I, IEnd;
478 ShadowMap::iterator NamePos = SMap.find(R.Declaration->getDeclName());
479 if (NamePos != SMap.end()) {
480 I = NamePos->second.begin();
481 IEnd = NamePos->second.end();
482 }
483
484 for (; I != IEnd; ++I) {
485 NamedDecl *ND = I->first;
486 unsigned Index = I->second;
Douglas Gregor3545ff42009-09-21 16:56:56 +0000487 if (ND->getCanonicalDecl() == CanonDecl) {
488 // This is a redeclaration. Always pick the newer declaration.
Douglas Gregor3545ff42009-09-21 16:56:56 +0000489 Results[Index].Declaration = R.Declaration;
490
Douglas Gregor3545ff42009-09-21 16:56:56 +0000491 // We're done.
492 return;
493 }
494 }
495
496 // This is a new declaration in this scope. However, check whether this
497 // declaration name is hidden by a similarly-named declaration in an outer
498 // scope.
499 std::list<ShadowMap>::iterator SM, SMEnd = ShadowMaps.end();
500 --SMEnd;
501 for (SM = ShadowMaps.begin(); SM != SMEnd; ++SM) {
Douglas Gregor05e7ca32009-12-06 20:23:50 +0000502 ShadowMapEntry::iterator I, IEnd;
503 ShadowMap::iterator NamePos = SM->find(R.Declaration->getDeclName());
504 if (NamePos != SM->end()) {
505 I = NamePos->second.begin();
506 IEnd = NamePos->second.end();
507 }
508 for (; I != IEnd; ++I) {
Douglas Gregor3545ff42009-09-21 16:56:56 +0000509 // A tag declaration does not hide a non-tag declaration.
John McCalla2456712010-04-23 02:41:41 +0000510 if (I->first->getIdentifierNamespace()
511 == (Decl::IDNS_Tag | Decl::IDNS_Type) &&
Douglas Gregor3545ff42009-09-21 16:56:56 +0000512 (IDNS & (Decl::IDNS_Member | Decl::IDNS_Ordinary |
513 Decl::IDNS_ObjCProtocol)))
514 continue;
515
516 // Protocols are in distinct namespaces from everything else.
Douglas Gregor05e7ca32009-12-06 20:23:50 +0000517 if (((I->first->getIdentifierNamespace() & Decl::IDNS_ObjCProtocol)
Douglas Gregor3545ff42009-09-21 16:56:56 +0000518 || (IDNS & Decl::IDNS_ObjCProtocol)) &&
Douglas Gregor05e7ca32009-12-06 20:23:50 +0000519 I->first->getIdentifierNamespace() != IDNS)
Douglas Gregor3545ff42009-09-21 16:56:56 +0000520 continue;
521
522 // The newly-added result is hidden by an entry in the shadow map.
Douglas Gregore0717ab2010-01-14 00:41:07 +0000523 if (CheckHiddenResult(R, CurContext, I->first))
Douglas Gregor3545ff42009-09-21 16:56:56 +0000524 return;
Douglas Gregor3545ff42009-09-21 16:56:56 +0000525
526 break;
527 }
528 }
529
530 // Make sure that any given declaration only shows up in the result set once.
531 if (!AllDeclsFound.insert(CanonDecl))
532 return;
533
Douglas Gregore412a5a2009-09-23 22:26:46 +0000534 // If the filter is for nested-name-specifiers, then this result starts a
535 // nested-name-specifier.
Douglas Gregor6ae4c522010-01-14 03:21:49 +0000536 if (AsNestedNameSpecifier)
Douglas Gregore412a5a2009-09-23 22:26:46 +0000537 R.StartsNestedNameSpecifier = true;
538
Douglas Gregor5bf52692009-09-22 23:15:58 +0000539 // If this result is supposed to have an informative qualifier, add one.
Douglas Gregore412a5a2009-09-23 22:26:46 +0000540 if (R.QualifierIsInformative && !R.Qualifier &&
541 !R.StartsNestedNameSpecifier) {
Douglas Gregor5bf52692009-09-22 23:15:58 +0000542 DeclContext *Ctx = R.Declaration->getDeclContext();
543 if (NamespaceDecl *Namespace = dyn_cast<NamespaceDecl>(Ctx))
544 R.Qualifier = NestedNameSpecifier::Create(SemaRef.Context, 0, Namespace);
545 else if (TagDecl *Tag = dyn_cast<TagDecl>(Ctx))
546 R.Qualifier = NestedNameSpecifier::Create(SemaRef.Context, 0, false,
547 SemaRef.Context.getTypeDeclType(Tag).getTypePtr());
548 else
549 R.QualifierIsInformative = false;
550 }
Douglas Gregore412a5a2009-09-23 22:26:46 +0000551
Douglas Gregor3545ff42009-09-21 16:56:56 +0000552 // Insert this result into the set of results and into the current shadow
553 // map.
Douglas Gregor05e7ca32009-12-06 20:23:50 +0000554 SMap[R.Declaration->getDeclName()].Add(R.Declaration, Results.size());
Douglas Gregor3545ff42009-09-21 16:56:56 +0000555 Results.push_back(R);
556}
557
Douglas Gregorc580c522010-01-14 01:09:38 +0000558void ResultBuilder::AddResult(Result R, DeclContext *CurContext,
Douglas Gregor09bbc652010-01-14 15:47:35 +0000559 NamedDecl *Hiding, bool InBaseClass = false) {
Douglas Gregor78a21012010-01-14 16:01:26 +0000560 if (R.Kind != Result::RK_Declaration) {
561 // For non-declaration results, just add the result.
562 Results.push_back(R);
563 return;
564 }
565
Douglas Gregorc580c522010-01-14 01:09:38 +0000566 // Look through using declarations.
567 if (UsingShadowDecl *Using = dyn_cast<UsingShadowDecl>(R.Declaration)) {
568 AddResult(Result(Using->getTargetDecl(), R.Qualifier), CurContext, Hiding);
569 return;
570 }
571
Douglas Gregor6ae4c522010-01-14 03:21:49 +0000572 bool AsNestedNameSpecifier = false;
573 if (!isInterestingDecl(R.Declaration, AsNestedNameSpecifier))
Douglas Gregorc580c522010-01-14 01:09:38 +0000574 return;
575
576 if (Hiding && CheckHiddenResult(R, CurContext, Hiding))
577 return;
578
579 // Make sure that any given declaration only shows up in the result set once.
580 if (!AllDeclsFound.insert(R.Declaration->getCanonicalDecl()))
581 return;
582
583 // If the filter is for nested-name-specifiers, then this result starts a
584 // nested-name-specifier.
Douglas Gregor6ae4c522010-01-14 03:21:49 +0000585 if (AsNestedNameSpecifier)
Douglas Gregorc580c522010-01-14 01:09:38 +0000586 R.StartsNestedNameSpecifier = true;
Douglas Gregor09bbc652010-01-14 15:47:35 +0000587 else if (Filter == &ResultBuilder::IsMember && !R.Qualifier && InBaseClass &&
588 isa<CXXRecordDecl>(R.Declaration->getDeclContext()
589 ->getLookupContext()))
590 R.QualifierIsInformative = true;
591
Douglas Gregorc580c522010-01-14 01:09:38 +0000592 // If this result is supposed to have an informative qualifier, add one.
593 if (R.QualifierIsInformative && !R.Qualifier &&
594 !R.StartsNestedNameSpecifier) {
595 DeclContext *Ctx = R.Declaration->getDeclContext();
596 if (NamespaceDecl *Namespace = dyn_cast<NamespaceDecl>(Ctx))
597 R.Qualifier = NestedNameSpecifier::Create(SemaRef.Context, 0, Namespace);
598 else if (TagDecl *Tag = dyn_cast<TagDecl>(Ctx))
599 R.Qualifier = NestedNameSpecifier::Create(SemaRef.Context, 0, false,
Douglas Gregor6ae4c522010-01-14 03:21:49 +0000600 SemaRef.Context.getTypeDeclType(Tag).getTypePtr());
Douglas Gregorc580c522010-01-14 01:09:38 +0000601 else
602 R.QualifierIsInformative = false;
603 }
604
605 // Insert this result into the set of results.
606 Results.push_back(R);
607}
608
Douglas Gregor78a21012010-01-14 16:01:26 +0000609void ResultBuilder::AddResult(Result R) {
610 assert(R.Kind != Result::RK_Declaration &&
611 "Declaration results need more context");
612 Results.push_back(R);
613}
614
Douglas Gregor3545ff42009-09-21 16:56:56 +0000615/// \brief Enter into a new scope.
616void ResultBuilder::EnterNewScope() {
617 ShadowMaps.push_back(ShadowMap());
618}
619
620/// \brief Exit from the current scope.
621void ResultBuilder::ExitScope() {
Douglas Gregor05e7ca32009-12-06 20:23:50 +0000622 for (ShadowMap::iterator E = ShadowMaps.back().begin(),
623 EEnd = ShadowMaps.back().end();
624 E != EEnd;
625 ++E)
626 E->second.Destroy();
627
Douglas Gregor3545ff42009-09-21 16:56:56 +0000628 ShadowMaps.pop_back();
629}
630
Douglas Gregor9d64c5e2009-09-21 20:51:25 +0000631/// \brief Determines whether this given declaration will be found by
632/// ordinary name lookup.
633bool ResultBuilder::IsOrdinaryName(NamedDecl *ND) const {
634 unsigned IDNS = Decl::IDNS_Ordinary;
635 if (SemaRef.getLangOptions().CPlusPlus)
John McCalla2456712010-04-23 02:41:41 +0000636 IDNS |= Decl::IDNS_Tag | Decl::IDNS_Namespace;
Douglas Gregorc580c522010-01-14 01:09:38 +0000637 else if (SemaRef.getLangOptions().ObjC1 && isa<ObjCIvarDecl>(ND))
638 return true;
639
Douglas Gregor9d64c5e2009-09-21 20:51:25 +0000640 return ND->getIdentifierNamespace() & IDNS;
641}
642
Douglas Gregor504a6ae2010-01-10 23:08:15 +0000643/// \brief Determines whether this given declaration will be found by
644/// ordinary name lookup.
645bool ResultBuilder::IsOrdinaryNonValueName(NamedDecl *ND) const {
646 unsigned IDNS = Decl::IDNS_Ordinary;
647 if (SemaRef.getLangOptions().CPlusPlus)
John McCalla2456712010-04-23 02:41:41 +0000648 IDNS |= Decl::IDNS_Tag | Decl::IDNS_Namespace;
Douglas Gregor504a6ae2010-01-10 23:08:15 +0000649
650 return (ND->getIdentifierNamespace() & IDNS) &&
651 !isa<ValueDecl>(ND) && !isa<FunctionTemplateDecl>(ND);
652}
653
Douglas Gregor3545ff42009-09-21 16:56:56 +0000654/// \brief Determines whether the given declaration is suitable as the
655/// start of a C++ nested-name-specifier, e.g., a class or namespace.
656bool ResultBuilder::IsNestedNameSpecifier(NamedDecl *ND) const {
657 // Allow us to find class templates, too.
658 if (ClassTemplateDecl *ClassTemplate = dyn_cast<ClassTemplateDecl>(ND))
659 ND = ClassTemplate->getTemplatedDecl();
660
661 return SemaRef.isAcceptableNestedNameSpecifier(ND);
662}
663
664/// \brief Determines whether the given declaration is an enumeration.
665bool ResultBuilder::IsEnum(NamedDecl *ND) const {
666 return isa<EnumDecl>(ND);
667}
668
669/// \brief Determines whether the given declaration is a class or struct.
670bool ResultBuilder::IsClassOrStruct(NamedDecl *ND) const {
671 // Allow us to find class templates, too.
672 if (ClassTemplateDecl *ClassTemplate = dyn_cast<ClassTemplateDecl>(ND))
673 ND = ClassTemplate->getTemplatedDecl();
674
675 if (RecordDecl *RD = dyn_cast<RecordDecl>(ND))
676 return RD->getTagKind() == TagDecl::TK_class ||
677 RD->getTagKind() == TagDecl::TK_struct;
678
679 return false;
680}
681
682/// \brief Determines whether the given declaration is a union.
683bool ResultBuilder::IsUnion(NamedDecl *ND) const {
684 // Allow us to find class templates, too.
685 if (ClassTemplateDecl *ClassTemplate = dyn_cast<ClassTemplateDecl>(ND))
686 ND = ClassTemplate->getTemplatedDecl();
687
688 if (RecordDecl *RD = dyn_cast<RecordDecl>(ND))
689 return RD->getTagKind() == TagDecl::TK_union;
690
691 return false;
692}
693
694/// \brief Determines whether the given declaration is a namespace.
695bool ResultBuilder::IsNamespace(NamedDecl *ND) const {
696 return isa<NamespaceDecl>(ND);
697}
698
699/// \brief Determines whether the given declaration is a namespace or
700/// namespace alias.
701bool ResultBuilder::IsNamespaceOrAlias(NamedDecl *ND) const {
702 return isa<NamespaceDecl>(ND) || isa<NamespaceAliasDecl>(ND);
703}
704
Douglas Gregor99fe2ad2009-12-11 17:31:05 +0000705/// \brief Determines whether the given declaration is a type.
Douglas Gregor3545ff42009-09-21 16:56:56 +0000706bool ResultBuilder::IsType(NamedDecl *ND) const {
707 return isa<TypeDecl>(ND);
708}
709
Douglas Gregor99fe2ad2009-12-11 17:31:05 +0000710/// \brief Determines which members of a class should be visible via
711/// "." or "->". Only value declarations, nested name specifiers, and
712/// using declarations thereof should show up.
Douglas Gregore412a5a2009-09-23 22:26:46 +0000713bool ResultBuilder::IsMember(NamedDecl *ND) const {
Douglas Gregor99fe2ad2009-12-11 17:31:05 +0000714 if (UsingShadowDecl *Using = dyn_cast<UsingShadowDecl>(ND))
715 ND = Using->getTargetDecl();
716
Douglas Gregor70788392009-12-11 18:14:22 +0000717 return isa<ValueDecl>(ND) || isa<FunctionTemplateDecl>(ND) ||
718 isa<ObjCPropertyDecl>(ND);
Douglas Gregore412a5a2009-09-23 22:26:46 +0000719}
720
Douglas Gregor2b8162b2010-01-14 16:08:12 +0000721/// \rief Determines whether the given declaration is an Objective-C
722/// instance variable.
723bool ResultBuilder::IsObjCIvar(NamedDecl *ND) const {
724 return isa<ObjCIvarDecl>(ND);
725}
726
Douglas Gregorc580c522010-01-14 01:09:38 +0000727namespace {
728 /// \brief Visible declaration consumer that adds a code-completion result
729 /// for each visible declaration.
730 class CodeCompletionDeclConsumer : public VisibleDeclConsumer {
731 ResultBuilder &Results;
732 DeclContext *CurContext;
733
734 public:
735 CodeCompletionDeclConsumer(ResultBuilder &Results, DeclContext *CurContext)
736 : Results(Results), CurContext(CurContext) { }
737
Douglas Gregor09bbc652010-01-14 15:47:35 +0000738 virtual void FoundDecl(NamedDecl *ND, NamedDecl *Hiding, bool InBaseClass) {
739 Results.AddResult(ND, CurContext, Hiding, InBaseClass);
Douglas Gregorc580c522010-01-14 01:09:38 +0000740 }
741 };
742}
743
Douglas Gregor3545ff42009-09-21 16:56:56 +0000744/// \brief Add type specifiers for the current language as keyword results.
Douglas Gregorf98e6a22010-01-13 23:51:12 +0000745static void AddTypeSpecifierResults(const LangOptions &LangOpts,
Douglas Gregor3545ff42009-09-21 16:56:56 +0000746 ResultBuilder &Results) {
747 typedef CodeCompleteConsumer::Result Result;
Douglas Gregor78a21012010-01-14 16:01:26 +0000748 Results.AddResult(Result("short"));
749 Results.AddResult(Result("long"));
750 Results.AddResult(Result("signed"));
751 Results.AddResult(Result("unsigned"));
752 Results.AddResult(Result("void"));
753 Results.AddResult(Result("char"));
754 Results.AddResult(Result("int"));
755 Results.AddResult(Result("float"));
756 Results.AddResult(Result("double"));
757 Results.AddResult(Result("enum"));
758 Results.AddResult(Result("struct"));
759 Results.AddResult(Result("union"));
760 Results.AddResult(Result("const"));
761 Results.AddResult(Result("volatile"));
Douglas Gregor504a6ae2010-01-10 23:08:15 +0000762
Douglas Gregor3545ff42009-09-21 16:56:56 +0000763 if (LangOpts.C99) {
764 // C99-specific
Douglas Gregor78a21012010-01-14 16:01:26 +0000765 Results.AddResult(Result("_Complex"));
766 Results.AddResult(Result("_Imaginary"));
767 Results.AddResult(Result("_Bool"));
768 Results.AddResult(Result("restrict"));
Douglas Gregor3545ff42009-09-21 16:56:56 +0000769 }
770
771 if (LangOpts.CPlusPlus) {
772 // C++-specific
Douglas Gregor78a21012010-01-14 16:01:26 +0000773 Results.AddResult(Result("bool"));
774 Results.AddResult(Result("class"));
775 Results.AddResult(Result("wchar_t"));
Douglas Gregor3545ff42009-09-21 16:56:56 +0000776
Douglas Gregor504a6ae2010-01-10 23:08:15 +0000777 // typename qualified-id
778 CodeCompletionString *Pattern = new CodeCompletionString;
779 Pattern->AddTypedTextChunk("typename");
780 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
781 Pattern->AddPlaceholderChunk("qualified-id");
Douglas Gregor78a21012010-01-14 16:01:26 +0000782 Results.AddResult(Result(Pattern));
Douglas Gregor504a6ae2010-01-10 23:08:15 +0000783
Douglas Gregor3545ff42009-09-21 16:56:56 +0000784 if (LangOpts.CPlusPlus0x) {
Douglas Gregor78a21012010-01-14 16:01:26 +0000785 Results.AddResult(Result("auto"));
786 Results.AddResult(Result("char16_t"));
787 Results.AddResult(Result("char32_t"));
788 Results.AddResult(Result("decltype"));
Douglas Gregor3545ff42009-09-21 16:56:56 +0000789 }
790 }
791
792 // GNU extensions
793 if (LangOpts.GNUMode) {
794 // FIXME: Enable when we actually support decimal floating point.
Douglas Gregor78a21012010-01-14 16:01:26 +0000795 // Results.AddResult(Result("_Decimal32"));
796 // Results.AddResult(Result("_Decimal64"));
797 // Results.AddResult(Result("_Decimal128"));
Douglas Gregor504a6ae2010-01-10 23:08:15 +0000798
799 CodeCompletionString *Pattern = new CodeCompletionString;
800 Pattern->AddTypedTextChunk("typeof");
801 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
802 Pattern->AddPlaceholderChunk("expression-or-type");
803 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
Douglas Gregor78a21012010-01-14 16:01:26 +0000804 Results.AddResult(Result(Pattern));
Douglas Gregor3545ff42009-09-21 16:56:56 +0000805 }
806}
807
Douglas Gregor504a6ae2010-01-10 23:08:15 +0000808static void AddStorageSpecifiers(Action::CodeCompletionContext CCC,
809 const LangOptions &LangOpts,
Douglas Gregor504a6ae2010-01-10 23:08:15 +0000810 ResultBuilder &Results) {
811 typedef CodeCompleteConsumer::Result Result;
812 // Note: we don't suggest either "auto" or "register", because both
813 // are pointless as storage specifiers. Elsewhere, we suggest "auto"
814 // in C++0x as a type specifier.
Douglas Gregor78a21012010-01-14 16:01:26 +0000815 Results.AddResult(Result("extern"));
816 Results.AddResult(Result("static"));
Douglas Gregor504a6ae2010-01-10 23:08:15 +0000817}
818
819static void AddFunctionSpecifiers(Action::CodeCompletionContext CCC,
820 const LangOptions &LangOpts,
Douglas Gregor504a6ae2010-01-10 23:08:15 +0000821 ResultBuilder &Results) {
822 typedef CodeCompleteConsumer::Result Result;
823 switch (CCC) {
824 case Action::CCC_Class:
825 case Action::CCC_MemberTemplate:
826 if (LangOpts.CPlusPlus) {
Douglas Gregor78a21012010-01-14 16:01:26 +0000827 Results.AddResult(Result("explicit"));
828 Results.AddResult(Result("friend"));
829 Results.AddResult(Result("mutable"));
830 Results.AddResult(Result("virtual"));
Douglas Gregor504a6ae2010-01-10 23:08:15 +0000831 }
832 // Fall through
833
Douglas Gregorf1934162010-01-13 21:24:21 +0000834 case Action::CCC_ObjCInterface:
835 case Action::CCC_ObjCImplementation:
Douglas Gregor504a6ae2010-01-10 23:08:15 +0000836 case Action::CCC_Namespace:
837 case Action::CCC_Template:
838 if (LangOpts.CPlusPlus || LangOpts.C99)
Douglas Gregor78a21012010-01-14 16:01:26 +0000839 Results.AddResult(Result("inline"));
Douglas Gregor504a6ae2010-01-10 23:08:15 +0000840 break;
841
Douglas Gregor48d46252010-01-13 21:54:15 +0000842 case Action::CCC_ObjCInstanceVariableList:
Douglas Gregor504a6ae2010-01-10 23:08:15 +0000843 case Action::CCC_Expression:
844 case Action::CCC_Statement:
845 case Action::CCC_ForInit:
846 case Action::CCC_Condition:
847 break;
848 }
849}
850
Douglas Gregorf98e6a22010-01-13 23:51:12 +0000851static void AddObjCExpressionResults(ResultBuilder &Results, bool NeedAt);
852static void AddObjCStatementResults(ResultBuilder &Results, bool NeedAt);
853static void AddObjCVisibilityResults(const LangOptions &LangOpts,
Douglas Gregor48d46252010-01-13 21:54:15 +0000854 ResultBuilder &Results,
855 bool NeedAt);
Douglas Gregorf98e6a22010-01-13 23:51:12 +0000856static void AddObjCImplementationResults(const LangOptions &LangOpts,
Douglas Gregorf1934162010-01-13 21:24:21 +0000857 ResultBuilder &Results,
858 bool NeedAt);
Douglas Gregorf98e6a22010-01-13 23:51:12 +0000859static void AddObjCInterfaceResults(const LangOptions &LangOpts,
Douglas Gregorf1934162010-01-13 21:24:21 +0000860 ResultBuilder &Results,
861 bool NeedAt);
Douglas Gregorf98e6a22010-01-13 23:51:12 +0000862static void AddObjCTopLevelResults(ResultBuilder &Results, bool NeedAt);
Douglas Gregorf1934162010-01-13 21:24:21 +0000863
Douglas Gregor504a6ae2010-01-10 23:08:15 +0000864/// \brief Add language constructs that show up for "ordinary" names.
865static void AddOrdinaryNameResults(Action::CodeCompletionContext CCC,
866 Scope *S,
867 Sema &SemaRef,
Douglas Gregor504a6ae2010-01-10 23:08:15 +0000868 ResultBuilder &Results) {
869 typedef CodeCompleteConsumer::Result Result;
870 switch (CCC) {
871 case Action::CCC_Namespace:
872 if (SemaRef.getLangOptions().CPlusPlus) {
873 // namespace <identifier> { }
874 CodeCompletionString *Pattern = new CodeCompletionString;
875 Pattern->AddTypedTextChunk("namespace");
876 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
877 Pattern->AddPlaceholderChunk("identifier");
878 Pattern->AddChunk(CodeCompletionString::CK_LeftBrace);
879 Pattern->AddPlaceholderChunk("declarations");
880 Pattern->AddChunk(CodeCompletionString::CK_VerticalSpace);
881 Pattern->AddChunk(CodeCompletionString::CK_RightBrace);
Douglas Gregor78a21012010-01-14 16:01:26 +0000882 Results.AddResult(Result(Pattern));
Douglas Gregor504a6ae2010-01-10 23:08:15 +0000883
884 // namespace identifier = identifier ;
885 Pattern = new CodeCompletionString;
886 Pattern->AddTypedTextChunk("namespace");
887 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
888 Pattern->AddPlaceholderChunk("identifier");
889 Pattern->AddChunk(CodeCompletionString::CK_Equal);
890 Pattern->AddPlaceholderChunk("identifier");
Douglas Gregor78a21012010-01-14 16:01:26 +0000891 Results.AddResult(Result(Pattern));
Douglas Gregor504a6ae2010-01-10 23:08:15 +0000892
893 // Using directives
894 Pattern = new CodeCompletionString;
895 Pattern->AddTypedTextChunk("using");
896 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
897 Pattern->AddTextChunk("namespace");
898 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
899 Pattern->AddPlaceholderChunk("identifier");
Douglas Gregor78a21012010-01-14 16:01:26 +0000900 Results.AddResult(Result(Pattern));
Douglas Gregor504a6ae2010-01-10 23:08:15 +0000901
902 // asm(string-literal)
903 Pattern = new CodeCompletionString;
904 Pattern->AddTypedTextChunk("asm");
905 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
906 Pattern->AddPlaceholderChunk("string-literal");
907 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
Douglas Gregor78a21012010-01-14 16:01:26 +0000908 Results.AddResult(Result(Pattern));
Douglas Gregor504a6ae2010-01-10 23:08:15 +0000909
910 // Explicit template instantiation
911 Pattern = new CodeCompletionString;
912 Pattern->AddTypedTextChunk("template");
913 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
914 Pattern->AddPlaceholderChunk("declaration");
Douglas Gregor78a21012010-01-14 16:01:26 +0000915 Results.AddResult(Result(Pattern));
Douglas Gregor504a6ae2010-01-10 23:08:15 +0000916 }
Douglas Gregorf1934162010-01-13 21:24:21 +0000917
918 if (SemaRef.getLangOptions().ObjC1)
Douglas Gregorf98e6a22010-01-13 23:51:12 +0000919 AddObjCTopLevelResults(Results, true);
Douglas Gregorf1934162010-01-13 21:24:21 +0000920
Douglas Gregor504a6ae2010-01-10 23:08:15 +0000921 // Fall through
922
923 case Action::CCC_Class:
Douglas Gregor78a21012010-01-14 16:01:26 +0000924 Results.AddResult(Result("typedef"));
Douglas Gregor504a6ae2010-01-10 23:08:15 +0000925 if (SemaRef.getLangOptions().CPlusPlus) {
926 // Using declaration
927 CodeCompletionString *Pattern = new CodeCompletionString;
928 Pattern->AddTypedTextChunk("using");
929 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
930 Pattern->AddPlaceholderChunk("qualified-id");
Douglas Gregor78a21012010-01-14 16:01:26 +0000931 Results.AddResult(Result(Pattern));
Douglas Gregor504a6ae2010-01-10 23:08:15 +0000932
933 // using typename qualified-id; (only in a dependent context)
934 if (SemaRef.CurContext->isDependentContext()) {
935 Pattern = new CodeCompletionString;
936 Pattern->AddTypedTextChunk("using");
937 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
938 Pattern->AddTextChunk("typename");
939 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
940 Pattern->AddPlaceholderChunk("qualified-id");
Douglas Gregor78a21012010-01-14 16:01:26 +0000941 Results.AddResult(Result(Pattern));
Douglas Gregor504a6ae2010-01-10 23:08:15 +0000942 }
943
944 if (CCC == Action::CCC_Class) {
945 // public:
946 Pattern = new CodeCompletionString;
947 Pattern->AddTypedTextChunk("public");
948 Pattern->AddChunk(CodeCompletionString::CK_Colon);
Douglas Gregor78a21012010-01-14 16:01:26 +0000949 Results.AddResult(Result(Pattern));
Douglas Gregor504a6ae2010-01-10 23:08:15 +0000950
951 // protected:
952 Pattern = new CodeCompletionString;
953 Pattern->AddTypedTextChunk("protected");
954 Pattern->AddChunk(CodeCompletionString::CK_Colon);
Douglas Gregor78a21012010-01-14 16:01:26 +0000955 Results.AddResult(Result(Pattern));
Douglas Gregor504a6ae2010-01-10 23:08:15 +0000956
957 // private:
958 Pattern = new CodeCompletionString;
959 Pattern->AddTypedTextChunk("private");
960 Pattern->AddChunk(CodeCompletionString::CK_Colon);
Douglas Gregor78a21012010-01-14 16:01:26 +0000961 Results.AddResult(Result(Pattern));
Douglas Gregor504a6ae2010-01-10 23:08:15 +0000962 }
963 }
964 // Fall through
965
966 case Action::CCC_Template:
967 case Action::CCC_MemberTemplate:
968 if (SemaRef.getLangOptions().CPlusPlus) {
969 // template < parameters >
970 CodeCompletionString *Pattern = new CodeCompletionString;
971 Pattern->AddTypedTextChunk("template");
972 Pattern->AddChunk(CodeCompletionString::CK_LeftAngle);
973 Pattern->AddPlaceholderChunk("parameters");
974 Pattern->AddChunk(CodeCompletionString::CK_RightAngle);
Douglas Gregor78a21012010-01-14 16:01:26 +0000975 Results.AddResult(Result(Pattern));
Douglas Gregor504a6ae2010-01-10 23:08:15 +0000976 }
977
Douglas Gregorf98e6a22010-01-13 23:51:12 +0000978 AddStorageSpecifiers(CCC, SemaRef.getLangOptions(), Results);
979 AddFunctionSpecifiers(CCC, SemaRef.getLangOptions(), Results);
Douglas Gregor504a6ae2010-01-10 23:08:15 +0000980 break;
981
Douglas Gregorf1934162010-01-13 21:24:21 +0000982 case Action::CCC_ObjCInterface:
Douglas Gregorf98e6a22010-01-13 23:51:12 +0000983 AddObjCInterfaceResults(SemaRef.getLangOptions(), Results, true);
984 AddStorageSpecifiers(CCC, SemaRef.getLangOptions(), Results);
985 AddFunctionSpecifiers(CCC, SemaRef.getLangOptions(), Results);
Douglas Gregorf1934162010-01-13 21:24:21 +0000986 break;
987
988 case Action::CCC_ObjCImplementation:
Douglas Gregorf98e6a22010-01-13 23:51:12 +0000989 AddObjCImplementationResults(SemaRef.getLangOptions(), Results, true);
990 AddStorageSpecifiers(CCC, SemaRef.getLangOptions(), Results);
991 AddFunctionSpecifiers(CCC, SemaRef.getLangOptions(), Results);
Douglas Gregorf1934162010-01-13 21:24:21 +0000992 break;
993
Douglas Gregor48d46252010-01-13 21:54:15 +0000994 case Action::CCC_ObjCInstanceVariableList:
Douglas Gregorf98e6a22010-01-13 23:51:12 +0000995 AddObjCVisibilityResults(SemaRef.getLangOptions(), Results, true);
Douglas Gregor48d46252010-01-13 21:54:15 +0000996 break;
997
Douglas Gregor504a6ae2010-01-10 23:08:15 +0000998 case Action::CCC_Statement: {
Douglas Gregor78a21012010-01-14 16:01:26 +0000999 Results.AddResult(Result("typedef"));
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001000
1001 CodeCompletionString *Pattern = 0;
1002 if (SemaRef.getLangOptions().CPlusPlus) {
1003 Pattern = new CodeCompletionString;
1004 Pattern->AddTypedTextChunk("try");
1005 Pattern->AddChunk(CodeCompletionString::CK_LeftBrace);
1006 Pattern->AddPlaceholderChunk("statements");
1007 Pattern->AddChunk(CodeCompletionString::CK_VerticalSpace);
1008 Pattern->AddChunk(CodeCompletionString::CK_RightBrace);
1009 Pattern->AddTextChunk("catch");
1010 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
1011 Pattern->AddPlaceholderChunk("declaration");
1012 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
1013 Pattern->AddChunk(CodeCompletionString::CK_LeftBrace);
1014 Pattern->AddPlaceholderChunk("statements");
1015 Pattern->AddChunk(CodeCompletionString::CK_VerticalSpace);
1016 Pattern->AddChunk(CodeCompletionString::CK_RightBrace);
Douglas Gregor78a21012010-01-14 16:01:26 +00001017 Results.AddResult(Result(Pattern));
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001018 }
Douglas Gregorf1934162010-01-13 21:24:21 +00001019 if (SemaRef.getLangOptions().ObjC1)
Douglas Gregorf98e6a22010-01-13 23:51:12 +00001020 AddObjCStatementResults(Results, true);
Douglas Gregorf1934162010-01-13 21:24:21 +00001021
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001022 // if (condition) { statements }
1023 Pattern = new CodeCompletionString;
1024 Pattern->AddTypedTextChunk("if");
1025 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
1026 if (SemaRef.getLangOptions().CPlusPlus)
1027 Pattern->AddPlaceholderChunk("condition");
1028 else
1029 Pattern->AddPlaceholderChunk("expression");
1030 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
1031 Pattern->AddChunk(CodeCompletionString::CK_LeftBrace);
1032 Pattern->AddPlaceholderChunk("statements");
1033 Pattern->AddChunk(CodeCompletionString::CK_VerticalSpace);
1034 Pattern->AddChunk(CodeCompletionString::CK_RightBrace);
Douglas Gregor78a21012010-01-14 16:01:26 +00001035 Results.AddResult(Result(Pattern));
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001036
1037 // switch (condition) { }
1038 Pattern = new CodeCompletionString;
1039 Pattern->AddTypedTextChunk("switch");
1040 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
1041 if (SemaRef.getLangOptions().CPlusPlus)
1042 Pattern->AddPlaceholderChunk("condition");
1043 else
1044 Pattern->AddPlaceholderChunk("expression");
1045 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
1046 Pattern->AddChunk(CodeCompletionString::CK_LeftBrace);
1047 Pattern->AddChunk(CodeCompletionString::CK_VerticalSpace);
1048 Pattern->AddChunk(CodeCompletionString::CK_RightBrace);
Douglas Gregor78a21012010-01-14 16:01:26 +00001049 Results.AddResult(Result(Pattern));
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001050
1051 // Switch-specific statements.
1052 if (!SemaRef.getSwitchStack().empty()) {
1053 // case expression:
1054 Pattern = new CodeCompletionString;
1055 Pattern->AddTypedTextChunk("case");
1056 Pattern->AddPlaceholderChunk("expression");
1057 Pattern->AddChunk(CodeCompletionString::CK_Colon);
Douglas Gregor78a21012010-01-14 16:01:26 +00001058 Results.AddResult(Result(Pattern));
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001059
1060 // default:
1061 Pattern = new CodeCompletionString;
1062 Pattern->AddTypedTextChunk("default");
1063 Pattern->AddChunk(CodeCompletionString::CK_Colon);
Douglas Gregor78a21012010-01-14 16:01:26 +00001064 Results.AddResult(Result(Pattern));
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001065 }
1066
1067 /// while (condition) { statements }
1068 Pattern = new CodeCompletionString;
1069 Pattern->AddTypedTextChunk("while");
1070 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
1071 if (SemaRef.getLangOptions().CPlusPlus)
1072 Pattern->AddPlaceholderChunk("condition");
1073 else
1074 Pattern->AddPlaceholderChunk("expression");
1075 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
1076 Pattern->AddChunk(CodeCompletionString::CK_LeftBrace);
1077 Pattern->AddPlaceholderChunk("statements");
1078 Pattern->AddChunk(CodeCompletionString::CK_VerticalSpace);
1079 Pattern->AddChunk(CodeCompletionString::CK_RightBrace);
Douglas Gregor78a21012010-01-14 16:01:26 +00001080 Results.AddResult(Result(Pattern));
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001081
1082 // do { statements } while ( expression );
1083 Pattern = new CodeCompletionString;
1084 Pattern->AddTypedTextChunk("do");
1085 Pattern->AddChunk(CodeCompletionString::CK_LeftBrace);
1086 Pattern->AddPlaceholderChunk("statements");
1087 Pattern->AddChunk(CodeCompletionString::CK_VerticalSpace);
1088 Pattern->AddChunk(CodeCompletionString::CK_RightBrace);
1089 Pattern->AddTextChunk("while");
1090 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
1091 Pattern->AddPlaceholderChunk("expression");
1092 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
Douglas Gregor78a21012010-01-14 16:01:26 +00001093 Results.AddResult(Result(Pattern));
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001094
1095 // for ( for-init-statement ; condition ; expression ) { statements }
1096 Pattern = new CodeCompletionString;
1097 Pattern->AddTypedTextChunk("for");
1098 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
1099 if (SemaRef.getLangOptions().CPlusPlus || SemaRef.getLangOptions().C99)
1100 Pattern->AddPlaceholderChunk("init-statement");
1101 else
1102 Pattern->AddPlaceholderChunk("init-expression");
1103 Pattern->AddChunk(CodeCompletionString::CK_SemiColon);
1104 Pattern->AddPlaceholderChunk("condition");
1105 Pattern->AddChunk(CodeCompletionString::CK_SemiColon);
1106 Pattern->AddPlaceholderChunk("inc-expression");
1107 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
1108 Pattern->AddChunk(CodeCompletionString::CK_LeftBrace);
1109 Pattern->AddPlaceholderChunk("statements");
1110 Pattern->AddChunk(CodeCompletionString::CK_VerticalSpace);
1111 Pattern->AddChunk(CodeCompletionString::CK_RightBrace);
Douglas Gregor78a21012010-01-14 16:01:26 +00001112 Results.AddResult(Result(Pattern));
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001113
1114 if (S->getContinueParent()) {
1115 // continue ;
1116 Pattern = new CodeCompletionString;
1117 Pattern->AddTypedTextChunk("continue");
Douglas Gregor78a21012010-01-14 16:01:26 +00001118 Results.AddResult(Result(Pattern));
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001119 }
1120
1121 if (S->getBreakParent()) {
1122 // break ;
1123 Pattern = new CodeCompletionString;
1124 Pattern->AddTypedTextChunk("break");
Douglas Gregor78a21012010-01-14 16:01:26 +00001125 Results.AddResult(Result(Pattern));
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001126 }
1127
1128 // "return expression ;" or "return ;", depending on whether we
1129 // know the function is void or not.
1130 bool isVoid = false;
1131 if (FunctionDecl *Function = dyn_cast<FunctionDecl>(SemaRef.CurContext))
1132 isVoid = Function->getResultType()->isVoidType();
1133 else if (ObjCMethodDecl *Method
1134 = dyn_cast<ObjCMethodDecl>(SemaRef.CurContext))
1135 isVoid = Method->getResultType()->isVoidType();
Douglas Gregor9a28e842010-03-01 23:15:13 +00001136 else if (SemaRef.getCurBlock() &&
1137 !SemaRef.getCurBlock()->ReturnType.isNull())
1138 isVoid = SemaRef.getCurBlock()->ReturnType->isVoidType();
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001139 Pattern = new CodeCompletionString;
1140 Pattern->AddTypedTextChunk("return");
Douglas Gregor44272ca2010-02-18 04:06:48 +00001141 if (!isVoid) {
1142 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001143 Pattern->AddPlaceholderChunk("expression");
Douglas Gregor44272ca2010-02-18 04:06:48 +00001144 }
Douglas Gregor78a21012010-01-14 16:01:26 +00001145 Results.AddResult(Result(Pattern));
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001146
1147 // goto identifier ;
1148 Pattern = new CodeCompletionString;
1149 Pattern->AddTypedTextChunk("goto");
1150 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
1151 Pattern->AddPlaceholderChunk("identifier");
Douglas Gregor78a21012010-01-14 16:01:26 +00001152 Results.AddResult(Result(Pattern));
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001153
1154 // Using directives
1155 Pattern = new CodeCompletionString;
1156 Pattern->AddTypedTextChunk("using");
1157 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
1158 Pattern->AddTextChunk("namespace");
1159 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
1160 Pattern->AddPlaceholderChunk("identifier");
Douglas Gregor78a21012010-01-14 16:01:26 +00001161 Results.AddResult(Result(Pattern));
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001162 }
1163
1164 // Fall through (for statement expressions).
1165 case Action::CCC_ForInit:
1166 case Action::CCC_Condition:
Douglas Gregorf98e6a22010-01-13 23:51:12 +00001167 AddStorageSpecifiers(CCC, SemaRef.getLangOptions(), Results);
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001168 // Fall through: conditions and statements can have expressions.
1169
1170 case Action::CCC_Expression: {
1171 CodeCompletionString *Pattern = 0;
1172 if (SemaRef.getLangOptions().CPlusPlus) {
1173 // 'this', if we're in a non-static member function.
1174 if (CXXMethodDecl *Method = dyn_cast<CXXMethodDecl>(SemaRef.CurContext))
1175 if (!Method->isStatic())
Douglas Gregor78a21012010-01-14 16:01:26 +00001176 Results.AddResult(Result("this"));
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001177
1178 // true, false
Douglas Gregor78a21012010-01-14 16:01:26 +00001179 Results.AddResult(Result("true"));
1180 Results.AddResult(Result("false"));
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001181
1182 // dynamic_cast < type-id > ( expression )
1183 Pattern = new CodeCompletionString;
1184 Pattern->AddTypedTextChunk("dynamic_cast");
1185 Pattern->AddChunk(CodeCompletionString::CK_LeftAngle);
1186 Pattern->AddPlaceholderChunk("type-id");
1187 Pattern->AddChunk(CodeCompletionString::CK_RightAngle);
1188 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
1189 Pattern->AddPlaceholderChunk("expression");
1190 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
Douglas Gregor78a21012010-01-14 16:01:26 +00001191 Results.AddResult(Result(Pattern));
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001192
1193 // static_cast < type-id > ( expression )
1194 Pattern = new CodeCompletionString;
1195 Pattern->AddTypedTextChunk("static_cast");
1196 Pattern->AddChunk(CodeCompletionString::CK_LeftAngle);
1197 Pattern->AddPlaceholderChunk("type-id");
1198 Pattern->AddChunk(CodeCompletionString::CK_RightAngle);
1199 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
1200 Pattern->AddPlaceholderChunk("expression");
1201 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
Douglas Gregor78a21012010-01-14 16:01:26 +00001202 Results.AddResult(Result(Pattern));
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001203
1204 // reinterpret_cast < type-id > ( expression )
1205 Pattern = new CodeCompletionString;
1206 Pattern->AddTypedTextChunk("reinterpret_cast");
1207 Pattern->AddChunk(CodeCompletionString::CK_LeftAngle);
1208 Pattern->AddPlaceholderChunk("type-id");
1209 Pattern->AddChunk(CodeCompletionString::CK_RightAngle);
1210 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
1211 Pattern->AddPlaceholderChunk("expression");
1212 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
Douglas Gregor78a21012010-01-14 16:01:26 +00001213 Results.AddResult(Result(Pattern));
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001214
1215 // const_cast < type-id > ( expression )
1216 Pattern = new CodeCompletionString;
1217 Pattern->AddTypedTextChunk("const_cast");
1218 Pattern->AddChunk(CodeCompletionString::CK_LeftAngle);
1219 Pattern->AddPlaceholderChunk("type-id");
1220 Pattern->AddChunk(CodeCompletionString::CK_RightAngle);
1221 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
1222 Pattern->AddPlaceholderChunk("expression");
1223 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
Douglas Gregor78a21012010-01-14 16:01:26 +00001224 Results.AddResult(Result(Pattern));
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001225
1226 // typeid ( expression-or-type )
1227 Pattern = new CodeCompletionString;
1228 Pattern->AddTypedTextChunk("typeid");
1229 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
1230 Pattern->AddPlaceholderChunk("expression-or-type");
1231 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
Douglas Gregor78a21012010-01-14 16:01:26 +00001232 Results.AddResult(Result(Pattern));
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001233
1234 // new T ( ... )
1235 Pattern = new CodeCompletionString;
1236 Pattern->AddTypedTextChunk("new");
1237 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
1238 Pattern->AddPlaceholderChunk("type-id");
1239 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
1240 Pattern->AddPlaceholderChunk("expressions");
1241 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
Douglas Gregor78a21012010-01-14 16:01:26 +00001242 Results.AddResult(Result(Pattern));
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001243
1244 // new T [ ] ( ... )
1245 Pattern = new CodeCompletionString;
1246 Pattern->AddTypedTextChunk("new");
1247 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
1248 Pattern->AddPlaceholderChunk("type-id");
1249 Pattern->AddChunk(CodeCompletionString::CK_LeftBracket);
1250 Pattern->AddPlaceholderChunk("size");
1251 Pattern->AddChunk(CodeCompletionString::CK_RightBracket);
1252 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
1253 Pattern->AddPlaceholderChunk("expressions");
1254 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
Douglas Gregor78a21012010-01-14 16:01:26 +00001255 Results.AddResult(Result(Pattern));
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001256
1257 // delete expression
1258 Pattern = new CodeCompletionString;
1259 Pattern->AddTypedTextChunk("delete");
1260 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
1261 Pattern->AddPlaceholderChunk("expression");
Douglas Gregor78a21012010-01-14 16:01:26 +00001262 Results.AddResult(Result(Pattern));
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001263
1264 // delete [] expression
1265 Pattern = new CodeCompletionString;
1266 Pattern->AddTypedTextChunk("delete");
1267 Pattern->AddChunk(CodeCompletionString::CK_LeftBracket);
1268 Pattern->AddChunk(CodeCompletionString::CK_RightBracket);
1269 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
1270 Pattern->AddPlaceholderChunk("expression");
Douglas Gregor78a21012010-01-14 16:01:26 +00001271 Results.AddResult(Result(Pattern));
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001272
1273 // throw expression
1274 Pattern = new CodeCompletionString;
1275 Pattern->AddTypedTextChunk("throw");
1276 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
1277 Pattern->AddPlaceholderChunk("expression");
Douglas Gregor78a21012010-01-14 16:01:26 +00001278 Results.AddResult(Result(Pattern));
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001279 }
1280
1281 if (SemaRef.getLangOptions().ObjC1) {
1282 // Add "super", if we're in an Objective-C class with a superclass.
1283 if (ObjCMethodDecl *Method = SemaRef.getCurMethodDecl())
1284 if (Method->getClassInterface()->getSuperClass())
Douglas Gregor78a21012010-01-14 16:01:26 +00001285 Results.AddResult(Result("super"));
Douglas Gregorf1934162010-01-13 21:24:21 +00001286
Douglas Gregorf98e6a22010-01-13 23:51:12 +00001287 AddObjCExpressionResults(Results, true);
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001288 }
1289
1290 // sizeof expression
1291 Pattern = new CodeCompletionString;
1292 Pattern->AddTypedTextChunk("sizeof");
1293 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
1294 Pattern->AddPlaceholderChunk("expression-or-type");
1295 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
Douglas Gregor78a21012010-01-14 16:01:26 +00001296 Results.AddResult(Result(Pattern));
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001297 break;
1298 }
1299 }
1300
Douglas Gregorf98e6a22010-01-13 23:51:12 +00001301 AddTypeSpecifierResults(SemaRef.getLangOptions(), Results);
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001302
1303 if (SemaRef.getLangOptions().CPlusPlus)
Douglas Gregor78a21012010-01-14 16:01:26 +00001304 Results.AddResult(Result("operator"));
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001305}
1306
Douglas Gregorb3fa9192009-12-18 18:53:37 +00001307/// \brief If the given declaration has an associated type, add it as a result
1308/// type chunk.
1309static void AddResultTypeChunk(ASTContext &Context,
1310 NamedDecl *ND,
1311 CodeCompletionString *Result) {
1312 if (!ND)
1313 return;
1314
1315 // Determine the type of the declaration (if it has a type).
1316 QualType T;
1317 if (FunctionDecl *Function = dyn_cast<FunctionDecl>(ND))
1318 T = Function->getResultType();
1319 else if (ObjCMethodDecl *Method = dyn_cast<ObjCMethodDecl>(ND))
1320 T = Method->getResultType();
1321 else if (FunctionTemplateDecl *FunTmpl = dyn_cast<FunctionTemplateDecl>(ND))
1322 T = FunTmpl->getTemplatedDecl()->getResultType();
1323 else if (EnumConstantDecl *Enumerator = dyn_cast<EnumConstantDecl>(ND))
1324 T = Context.getTypeDeclType(cast<TypeDecl>(Enumerator->getDeclContext()));
1325 else if (isa<UnresolvedUsingValueDecl>(ND)) {
1326 /* Do nothing: ignore unresolved using declarations*/
1327 } else if (ValueDecl *Value = dyn_cast<ValueDecl>(ND))
1328 T = Value->getType();
1329 else if (ObjCPropertyDecl *Property = dyn_cast<ObjCPropertyDecl>(ND))
1330 T = Property->getType();
1331
1332 if (T.isNull() || Context.hasSameType(T, Context.DependentTy))
1333 return;
1334
Douglas Gregorcf04b022010-04-05 21:25:31 +00001335 PrintingPolicy Policy(Context.PrintingPolicy);
1336 Policy.AnonymousTagLocations = false;
1337
Douglas Gregorb3fa9192009-12-18 18:53:37 +00001338 std::string TypeStr;
Douglas Gregorcf04b022010-04-05 21:25:31 +00001339 T.getAsStringInternal(TypeStr, Policy);
Douglas Gregorb3fa9192009-12-18 18:53:37 +00001340 Result->AddResultTypeChunk(TypeStr);
1341}
1342
Douglas Gregor3545ff42009-09-21 16:56:56 +00001343/// \brief Add function parameter chunks to the given code completion string.
1344static void AddFunctionParameterChunks(ASTContext &Context,
1345 FunctionDecl *Function,
1346 CodeCompletionString *Result) {
Douglas Gregor9eb77012009-11-07 00:00:49 +00001347 typedef CodeCompletionString::Chunk Chunk;
1348
Douglas Gregor3545ff42009-09-21 16:56:56 +00001349 CodeCompletionString *CCStr = Result;
1350
1351 for (unsigned P = 0, N = Function->getNumParams(); P != N; ++P) {
1352 ParmVarDecl *Param = Function->getParamDecl(P);
1353
1354 if (Param->hasDefaultArg()) {
1355 // When we see an optional default argument, put that argument and
1356 // the remaining default arguments into a new, optional string.
1357 CodeCompletionString *Opt = new CodeCompletionString;
1358 CCStr->AddOptionalChunk(std::auto_ptr<CodeCompletionString>(Opt));
1359 CCStr = Opt;
1360 }
1361
1362 if (P != 0)
Douglas Gregor9eb77012009-11-07 00:00:49 +00001363 CCStr->AddChunk(Chunk(CodeCompletionString::CK_Comma));
Douglas Gregor3545ff42009-09-21 16:56:56 +00001364
1365 // Format the placeholder string.
1366 std::string PlaceholderStr;
1367 if (Param->getIdentifier())
1368 PlaceholderStr = Param->getIdentifier()->getName();
1369
1370 Param->getType().getAsStringInternal(PlaceholderStr,
1371 Context.PrintingPolicy);
1372
1373 // Add the placeholder string.
Benjamin Kramerb33a97c2009-11-29 20:18:50 +00001374 CCStr->AddPlaceholderChunk(PlaceholderStr);
Douglas Gregor3545ff42009-09-21 16:56:56 +00001375 }
Douglas Gregorba449032009-09-22 21:42:17 +00001376
1377 if (const FunctionProtoType *Proto
1378 = Function->getType()->getAs<FunctionProtoType>())
1379 if (Proto->isVariadic())
1380 CCStr->AddPlaceholderChunk(", ...");
Douglas Gregor3545ff42009-09-21 16:56:56 +00001381}
1382
1383/// \brief Add template parameter chunks to the given code completion string.
1384static void AddTemplateParameterChunks(ASTContext &Context,
1385 TemplateDecl *Template,
1386 CodeCompletionString *Result,
1387 unsigned MaxParameters = 0) {
Douglas Gregor9eb77012009-11-07 00:00:49 +00001388 typedef CodeCompletionString::Chunk Chunk;
1389
Douglas Gregor3545ff42009-09-21 16:56:56 +00001390 CodeCompletionString *CCStr = Result;
1391 bool FirstParameter = true;
1392
1393 TemplateParameterList *Params = Template->getTemplateParameters();
1394 TemplateParameterList::iterator PEnd = Params->end();
1395 if (MaxParameters)
1396 PEnd = Params->begin() + MaxParameters;
1397 for (TemplateParameterList::iterator P = Params->begin(); P != PEnd; ++P) {
1398 bool HasDefaultArg = false;
1399 std::string PlaceholderStr;
1400 if (TemplateTypeParmDecl *TTP = dyn_cast<TemplateTypeParmDecl>(*P)) {
1401 if (TTP->wasDeclaredWithTypename())
1402 PlaceholderStr = "typename";
1403 else
1404 PlaceholderStr = "class";
1405
1406 if (TTP->getIdentifier()) {
1407 PlaceholderStr += ' ';
1408 PlaceholderStr += TTP->getIdentifier()->getName();
1409 }
1410
1411 HasDefaultArg = TTP->hasDefaultArgument();
1412 } else if (NonTypeTemplateParmDecl *NTTP
1413 = dyn_cast<NonTypeTemplateParmDecl>(*P)) {
1414 if (NTTP->getIdentifier())
1415 PlaceholderStr = NTTP->getIdentifier()->getName();
1416 NTTP->getType().getAsStringInternal(PlaceholderStr,
1417 Context.PrintingPolicy);
1418 HasDefaultArg = NTTP->hasDefaultArgument();
1419 } else {
1420 assert(isa<TemplateTemplateParmDecl>(*P));
1421 TemplateTemplateParmDecl *TTP = cast<TemplateTemplateParmDecl>(*P);
1422
1423 // Since putting the template argument list into the placeholder would
1424 // be very, very long, we just use an abbreviation.
1425 PlaceholderStr = "template<...> class";
1426 if (TTP->getIdentifier()) {
1427 PlaceholderStr += ' ';
1428 PlaceholderStr += TTP->getIdentifier()->getName();
1429 }
1430
1431 HasDefaultArg = TTP->hasDefaultArgument();
1432 }
1433
1434 if (HasDefaultArg) {
1435 // When we see an optional default argument, put that argument and
1436 // the remaining default arguments into a new, optional string.
1437 CodeCompletionString *Opt = new CodeCompletionString;
1438 CCStr->AddOptionalChunk(std::auto_ptr<CodeCompletionString>(Opt));
1439 CCStr = Opt;
1440 }
1441
1442 if (FirstParameter)
1443 FirstParameter = false;
1444 else
Douglas Gregor9eb77012009-11-07 00:00:49 +00001445 CCStr->AddChunk(Chunk(CodeCompletionString::CK_Comma));
Douglas Gregor3545ff42009-09-21 16:56:56 +00001446
1447 // Add the placeholder string.
Benjamin Kramerb33a97c2009-11-29 20:18:50 +00001448 CCStr->AddPlaceholderChunk(PlaceholderStr);
Douglas Gregor3545ff42009-09-21 16:56:56 +00001449 }
1450}
1451
Douglas Gregorf2510672009-09-21 19:57:38 +00001452/// \brief Add a qualifier to the given code-completion string, if the
1453/// provided nested-name-specifier is non-NULL.
Douglas Gregor0f622362009-12-11 18:44:16 +00001454static void
1455AddQualifierToCompletionString(CodeCompletionString *Result,
1456 NestedNameSpecifier *Qualifier,
1457 bool QualifierIsInformative,
1458 ASTContext &Context) {
Douglas Gregorf2510672009-09-21 19:57:38 +00001459 if (!Qualifier)
1460 return;
1461
1462 std::string PrintedNNS;
1463 {
1464 llvm::raw_string_ostream OS(PrintedNNS);
1465 Qualifier->print(OS, Context.PrintingPolicy);
1466 }
Douglas Gregor5bf52692009-09-22 23:15:58 +00001467 if (QualifierIsInformative)
Benjamin Kramerb33a97c2009-11-29 20:18:50 +00001468 Result->AddInformativeChunk(PrintedNNS);
Douglas Gregor5bf52692009-09-22 23:15:58 +00001469 else
Benjamin Kramerb33a97c2009-11-29 20:18:50 +00001470 Result->AddTextChunk(PrintedNNS);
Douglas Gregorf2510672009-09-21 19:57:38 +00001471}
1472
Douglas Gregor0f622362009-12-11 18:44:16 +00001473static void AddFunctionTypeQualsToCompletionString(CodeCompletionString *Result,
1474 FunctionDecl *Function) {
1475 const FunctionProtoType *Proto
1476 = Function->getType()->getAs<FunctionProtoType>();
1477 if (!Proto || !Proto->getTypeQuals())
1478 return;
1479
1480 std::string QualsStr;
1481 if (Proto->getTypeQuals() & Qualifiers::Const)
1482 QualsStr += " const";
1483 if (Proto->getTypeQuals() & Qualifiers::Volatile)
1484 QualsStr += " volatile";
1485 if (Proto->getTypeQuals() & Qualifiers::Restrict)
1486 QualsStr += " restrict";
1487 Result->AddInformativeChunk(QualsStr);
1488}
1489
Douglas Gregor3545ff42009-09-21 16:56:56 +00001490/// \brief If possible, create a new code completion string for the given
1491/// result.
1492///
1493/// \returns Either a new, heap-allocated code completion string describing
1494/// how to use this result, or NULL to indicate that the string or name of the
1495/// result is all that is needed.
1496CodeCompletionString *
1497CodeCompleteConsumer::Result::CreateCodeCompletionString(Sema &S) {
Douglas Gregor9eb77012009-11-07 00:00:49 +00001498 typedef CodeCompletionString::Chunk Chunk;
1499
Douglas Gregorf09935f2009-12-01 05:55:20 +00001500 if (Kind == RK_Pattern)
1501 return Pattern->Clone();
1502
1503 CodeCompletionString *Result = new CodeCompletionString;
1504
1505 if (Kind == RK_Keyword) {
1506 Result->AddTypedTextChunk(Keyword);
1507 return Result;
1508 }
Douglas Gregor3545ff42009-09-21 16:56:56 +00001509
Douglas Gregorf329c7c2009-10-30 16:50:04 +00001510 if (Kind == RK_Macro) {
1511 MacroInfo *MI = S.PP.getMacroInfo(Macro);
Douglas Gregorf09935f2009-12-01 05:55:20 +00001512 assert(MI && "Not a macro?");
1513
1514 Result->AddTypedTextChunk(Macro->getName());
1515
1516 if (!MI->isFunctionLike())
1517 return Result;
Douglas Gregorf329c7c2009-10-30 16:50:04 +00001518
1519 // Format a function-like macro with placeholders for the arguments.
Douglas Gregor9eb77012009-11-07 00:00:49 +00001520 Result->AddChunk(Chunk(CodeCompletionString::CK_LeftParen));
Douglas Gregorf329c7c2009-10-30 16:50:04 +00001521 for (MacroInfo::arg_iterator A = MI->arg_begin(), AEnd = MI->arg_end();
1522 A != AEnd; ++A) {
1523 if (A != MI->arg_begin())
Douglas Gregor9eb77012009-11-07 00:00:49 +00001524 Result->AddChunk(Chunk(CodeCompletionString::CK_Comma));
Douglas Gregorf329c7c2009-10-30 16:50:04 +00001525
1526 if (!MI->isVariadic() || A != AEnd - 1) {
1527 // Non-variadic argument.
Benjamin Kramerb33a97c2009-11-29 20:18:50 +00001528 Result->AddPlaceholderChunk((*A)->getName());
Douglas Gregorf329c7c2009-10-30 16:50:04 +00001529 continue;
1530 }
1531
1532 // Variadic argument; cope with the different between GNU and C99
1533 // variadic macros, providing a single placeholder for the rest of the
1534 // arguments.
1535 if ((*A)->isStr("__VA_ARGS__"))
1536 Result->AddPlaceholderChunk("...");
1537 else {
1538 std::string Arg = (*A)->getName();
1539 Arg += "...";
Benjamin Kramerb33a97c2009-11-29 20:18:50 +00001540 Result->AddPlaceholderChunk(Arg);
Douglas Gregorf329c7c2009-10-30 16:50:04 +00001541 }
1542 }
Douglas Gregor9eb77012009-11-07 00:00:49 +00001543 Result->AddChunk(Chunk(CodeCompletionString::CK_RightParen));
Douglas Gregorf329c7c2009-10-30 16:50:04 +00001544 return Result;
1545 }
1546
1547 assert(Kind == RK_Declaration && "Missed a macro kind?");
Douglas Gregor3545ff42009-09-21 16:56:56 +00001548 NamedDecl *ND = Declaration;
1549
Douglas Gregor9eb77012009-11-07 00:00:49 +00001550 if (StartsNestedNameSpecifier) {
Benjamin Kramerb33a97c2009-11-29 20:18:50 +00001551 Result->AddTypedTextChunk(ND->getNameAsString());
Douglas Gregor9eb77012009-11-07 00:00:49 +00001552 Result->AddTextChunk("::");
1553 return Result;
1554 }
1555
Douglas Gregorb3fa9192009-12-18 18:53:37 +00001556 AddResultTypeChunk(S.Context, ND, Result);
1557
Douglas Gregor3545ff42009-09-21 16:56:56 +00001558 if (FunctionDecl *Function = dyn_cast<FunctionDecl>(ND)) {
Douglas Gregor5bf52692009-09-22 23:15:58 +00001559 AddQualifierToCompletionString(Result, Qualifier, QualifierIsInformative,
1560 S.Context);
Benjamin Kramerb33a97c2009-11-29 20:18:50 +00001561 Result->AddTypedTextChunk(Function->getNameAsString());
Douglas Gregor9eb77012009-11-07 00:00:49 +00001562 Result->AddChunk(Chunk(CodeCompletionString::CK_LeftParen));
Douglas Gregor3545ff42009-09-21 16:56:56 +00001563 AddFunctionParameterChunks(S.Context, Function, Result);
Douglas Gregor9eb77012009-11-07 00:00:49 +00001564 Result->AddChunk(Chunk(CodeCompletionString::CK_RightParen));
Douglas Gregor0f622362009-12-11 18:44:16 +00001565 AddFunctionTypeQualsToCompletionString(Result, Function);
Douglas Gregor3545ff42009-09-21 16:56:56 +00001566 return Result;
1567 }
1568
1569 if (FunctionTemplateDecl *FunTmpl = dyn_cast<FunctionTemplateDecl>(ND)) {
Douglas Gregor5bf52692009-09-22 23:15:58 +00001570 AddQualifierToCompletionString(Result, Qualifier, QualifierIsInformative,
1571 S.Context);
Douglas Gregor3545ff42009-09-21 16:56:56 +00001572 FunctionDecl *Function = FunTmpl->getTemplatedDecl();
Benjamin Kramerb33a97c2009-11-29 20:18:50 +00001573 Result->AddTypedTextChunk(Function->getNameAsString());
Douglas Gregor3545ff42009-09-21 16:56:56 +00001574
1575 // Figure out which template parameters are deduced (or have default
1576 // arguments).
1577 llvm::SmallVector<bool, 16> Deduced;
1578 S.MarkDeducedTemplateParameters(FunTmpl, Deduced);
1579 unsigned LastDeducibleArgument;
1580 for (LastDeducibleArgument = Deduced.size(); LastDeducibleArgument > 0;
1581 --LastDeducibleArgument) {
1582 if (!Deduced[LastDeducibleArgument - 1]) {
1583 // C++0x: Figure out if the template argument has a default. If so,
1584 // the user doesn't need to type this argument.
1585 // FIXME: We need to abstract template parameters better!
1586 bool HasDefaultArg = false;
1587 NamedDecl *Param = FunTmpl->getTemplateParameters()->getParam(
1588 LastDeducibleArgument - 1);
1589 if (TemplateTypeParmDecl *TTP = dyn_cast<TemplateTypeParmDecl>(Param))
1590 HasDefaultArg = TTP->hasDefaultArgument();
1591 else if (NonTypeTemplateParmDecl *NTTP
1592 = dyn_cast<NonTypeTemplateParmDecl>(Param))
1593 HasDefaultArg = NTTP->hasDefaultArgument();
1594 else {
1595 assert(isa<TemplateTemplateParmDecl>(Param));
1596 HasDefaultArg
Douglas Gregor9eb77012009-11-07 00:00:49 +00001597 = cast<TemplateTemplateParmDecl>(Param)->hasDefaultArgument();
Douglas Gregor3545ff42009-09-21 16:56:56 +00001598 }
1599
1600 if (!HasDefaultArg)
1601 break;
1602 }
1603 }
1604
1605 if (LastDeducibleArgument) {
1606 // Some of the function template arguments cannot be deduced from a
1607 // function call, so we introduce an explicit template argument list
1608 // containing all of the arguments up to the first deducible argument.
Douglas Gregor9eb77012009-11-07 00:00:49 +00001609 Result->AddChunk(Chunk(CodeCompletionString::CK_LeftAngle));
Douglas Gregor3545ff42009-09-21 16:56:56 +00001610 AddTemplateParameterChunks(S.Context, FunTmpl, Result,
1611 LastDeducibleArgument);
Douglas Gregor9eb77012009-11-07 00:00:49 +00001612 Result->AddChunk(Chunk(CodeCompletionString::CK_RightAngle));
Douglas Gregor3545ff42009-09-21 16:56:56 +00001613 }
1614
1615 // Add the function parameters
Douglas Gregor9eb77012009-11-07 00:00:49 +00001616 Result->AddChunk(Chunk(CodeCompletionString::CK_LeftParen));
Douglas Gregor3545ff42009-09-21 16:56:56 +00001617 AddFunctionParameterChunks(S.Context, Function, Result);
Douglas Gregor9eb77012009-11-07 00:00:49 +00001618 Result->AddChunk(Chunk(CodeCompletionString::CK_RightParen));
Douglas Gregor0f622362009-12-11 18:44:16 +00001619 AddFunctionTypeQualsToCompletionString(Result, Function);
Douglas Gregor3545ff42009-09-21 16:56:56 +00001620 return Result;
1621 }
1622
1623 if (TemplateDecl *Template = dyn_cast<TemplateDecl>(ND)) {
Douglas Gregor5bf52692009-09-22 23:15:58 +00001624 AddQualifierToCompletionString(Result, Qualifier, QualifierIsInformative,
1625 S.Context);
Benjamin Kramerb33a97c2009-11-29 20:18:50 +00001626 Result->AddTypedTextChunk(Template->getNameAsString());
Douglas Gregor9eb77012009-11-07 00:00:49 +00001627 Result->AddChunk(Chunk(CodeCompletionString::CK_LeftAngle));
Douglas Gregor3545ff42009-09-21 16:56:56 +00001628 AddTemplateParameterChunks(S.Context, Template, Result);
Douglas Gregor9eb77012009-11-07 00:00:49 +00001629 Result->AddChunk(Chunk(CodeCompletionString::CK_RightAngle));
Douglas Gregor3545ff42009-09-21 16:56:56 +00001630 return Result;
1631 }
1632
Douglas Gregord3c5d792009-11-17 16:44:22 +00001633 if (ObjCMethodDecl *Method = dyn_cast<ObjCMethodDecl>(ND)) {
Douglas Gregord3c5d792009-11-17 16:44:22 +00001634 Selector Sel = Method->getSelector();
1635 if (Sel.isUnarySelector()) {
1636 Result->AddTypedTextChunk(Sel.getIdentifierInfoForSlot(0)->getName());
1637 return Result;
1638 }
1639
Douglas Gregor1b605f72009-11-19 01:08:35 +00001640 std::string SelName = Sel.getIdentifierInfoForSlot(0)->getName().str();
1641 SelName += ':';
1642 if (StartParameter == 0)
1643 Result->AddTypedTextChunk(SelName);
1644 else {
1645 Result->AddInformativeChunk(SelName);
1646
1647 // If there is only one parameter, and we're past it, add an empty
1648 // typed-text chunk since there is nothing to type.
1649 if (Method->param_size() == 1)
1650 Result->AddTypedTextChunk("");
1651 }
Douglas Gregord3c5d792009-11-17 16:44:22 +00001652 unsigned Idx = 0;
1653 for (ObjCMethodDecl::param_iterator P = Method->param_begin(),
1654 PEnd = Method->param_end();
1655 P != PEnd; (void)++P, ++Idx) {
1656 if (Idx > 0) {
Douglas Gregor1b605f72009-11-19 01:08:35 +00001657 std::string Keyword;
1658 if (Idx > StartParameter)
Douglas Gregor6a803932010-01-12 06:38:28 +00001659 Result->AddChunk(CodeCompletionString::CK_HorizontalSpace);
Douglas Gregord3c5d792009-11-17 16:44:22 +00001660 if (IdentifierInfo *II = Sel.getIdentifierInfoForSlot(Idx))
1661 Keyword += II->getName().str();
1662 Keyword += ":";
Douglas Gregorc8537c52009-11-19 07:41:15 +00001663 if (Idx < StartParameter || AllParametersAreInformative) {
Douglas Gregor1b605f72009-11-19 01:08:35 +00001664 Result->AddInformativeChunk(Keyword);
1665 } else if (Idx == StartParameter)
1666 Result->AddTypedTextChunk(Keyword);
1667 else
1668 Result->AddTextChunk(Keyword);
Douglas Gregord3c5d792009-11-17 16:44:22 +00001669 }
Douglas Gregor1b605f72009-11-19 01:08:35 +00001670
1671 // If we're before the starting parameter, skip the placeholder.
1672 if (Idx < StartParameter)
1673 continue;
Douglas Gregord3c5d792009-11-17 16:44:22 +00001674
1675 std::string Arg;
1676 (*P)->getType().getAsStringInternal(Arg, S.Context.PrintingPolicy);
1677 Arg = "(" + Arg + ")";
1678 if (IdentifierInfo *II = (*P)->getIdentifier())
1679 Arg += II->getName().str();
Douglas Gregorc8537c52009-11-19 07:41:15 +00001680 if (AllParametersAreInformative)
1681 Result->AddInformativeChunk(Arg);
1682 else
1683 Result->AddPlaceholderChunk(Arg);
Douglas Gregord3c5d792009-11-17 16:44:22 +00001684 }
1685
Douglas Gregor04c5f972009-12-23 00:21:46 +00001686 if (Method->isVariadic()) {
1687 if (AllParametersAreInformative)
1688 Result->AddInformativeChunk(", ...");
1689 else
1690 Result->AddPlaceholderChunk(", ...");
1691 }
1692
Douglas Gregord3c5d792009-11-17 16:44:22 +00001693 return Result;
1694 }
1695
Douglas Gregorf09935f2009-12-01 05:55:20 +00001696 if (Qualifier)
Douglas Gregor5bf52692009-09-22 23:15:58 +00001697 AddQualifierToCompletionString(Result, Qualifier, QualifierIsInformative,
1698 S.Context);
Douglas Gregorf09935f2009-12-01 05:55:20 +00001699
1700 Result->AddTypedTextChunk(ND->getNameAsString());
1701 return Result;
Douglas Gregor3545ff42009-09-21 16:56:56 +00001702}
1703
Douglas Gregorf0f51982009-09-23 00:34:09 +00001704CodeCompletionString *
1705CodeCompleteConsumer::OverloadCandidate::CreateSignatureString(
1706 unsigned CurrentArg,
1707 Sema &S) const {
Douglas Gregor9eb77012009-11-07 00:00:49 +00001708 typedef CodeCompletionString::Chunk Chunk;
1709
Douglas Gregorf0f51982009-09-23 00:34:09 +00001710 CodeCompletionString *Result = new CodeCompletionString;
1711 FunctionDecl *FDecl = getFunction();
Douglas Gregorb3fa9192009-12-18 18:53:37 +00001712 AddResultTypeChunk(S.Context, FDecl, Result);
Douglas Gregorf0f51982009-09-23 00:34:09 +00001713 const FunctionProtoType *Proto
1714 = dyn_cast<FunctionProtoType>(getFunctionType());
1715 if (!FDecl && !Proto) {
1716 // Function without a prototype. Just give the return type and a
1717 // highlighted ellipsis.
1718 const FunctionType *FT = getFunctionType();
1719 Result->AddTextChunk(
Benjamin Kramerb33a97c2009-11-29 20:18:50 +00001720 FT->getResultType().getAsString(S.Context.PrintingPolicy));
Douglas Gregor9eb77012009-11-07 00:00:49 +00001721 Result->AddChunk(Chunk(CodeCompletionString::CK_LeftParen));
1722 Result->AddChunk(Chunk(CodeCompletionString::CK_CurrentParameter, "..."));
1723 Result->AddChunk(Chunk(CodeCompletionString::CK_RightParen));
Douglas Gregorf0f51982009-09-23 00:34:09 +00001724 return Result;
1725 }
1726
1727 if (FDecl)
Benjamin Kramerb33a97c2009-11-29 20:18:50 +00001728 Result->AddTextChunk(FDecl->getNameAsString());
Douglas Gregorf0f51982009-09-23 00:34:09 +00001729 else
1730 Result->AddTextChunk(
Benjamin Kramerb33a97c2009-11-29 20:18:50 +00001731 Proto->getResultType().getAsString(S.Context.PrintingPolicy));
Douglas Gregorf0f51982009-09-23 00:34:09 +00001732
Douglas Gregor9eb77012009-11-07 00:00:49 +00001733 Result->AddChunk(Chunk(CodeCompletionString::CK_LeftParen));
Douglas Gregorf0f51982009-09-23 00:34:09 +00001734 unsigned NumParams = FDecl? FDecl->getNumParams() : Proto->getNumArgs();
1735 for (unsigned I = 0; I != NumParams; ++I) {
1736 if (I)
Douglas Gregor9eb77012009-11-07 00:00:49 +00001737 Result->AddChunk(Chunk(CodeCompletionString::CK_Comma));
Douglas Gregorf0f51982009-09-23 00:34:09 +00001738
1739 std::string ArgString;
1740 QualType ArgType;
1741
1742 if (FDecl) {
1743 ArgString = FDecl->getParamDecl(I)->getNameAsString();
1744 ArgType = FDecl->getParamDecl(I)->getOriginalType();
1745 } else {
1746 ArgType = Proto->getArgType(I);
1747 }
1748
1749 ArgType.getAsStringInternal(ArgString, S.Context.PrintingPolicy);
1750
1751 if (I == CurrentArg)
Douglas Gregor9eb77012009-11-07 00:00:49 +00001752 Result->AddChunk(Chunk(CodeCompletionString::CK_CurrentParameter,
Benjamin Kramerb33a97c2009-11-29 20:18:50 +00001753 ArgString));
Douglas Gregorf0f51982009-09-23 00:34:09 +00001754 else
Benjamin Kramerb33a97c2009-11-29 20:18:50 +00001755 Result->AddTextChunk(ArgString);
Douglas Gregorf0f51982009-09-23 00:34:09 +00001756 }
1757
1758 if (Proto && Proto->isVariadic()) {
Douglas Gregor9eb77012009-11-07 00:00:49 +00001759 Result->AddChunk(Chunk(CodeCompletionString::CK_Comma));
Douglas Gregorf0f51982009-09-23 00:34:09 +00001760 if (CurrentArg < NumParams)
1761 Result->AddTextChunk("...");
1762 else
Douglas Gregor9eb77012009-11-07 00:00:49 +00001763 Result->AddChunk(Chunk(CodeCompletionString::CK_CurrentParameter, "..."));
Douglas Gregorf0f51982009-09-23 00:34:09 +00001764 }
Douglas Gregor9eb77012009-11-07 00:00:49 +00001765 Result->AddChunk(Chunk(CodeCompletionString::CK_RightParen));
Douglas Gregorf0f51982009-09-23 00:34:09 +00001766
1767 return Result;
1768}
1769
Douglas Gregor3545ff42009-09-21 16:56:56 +00001770namespace {
1771 struct SortCodeCompleteResult {
1772 typedef CodeCompleteConsumer::Result Result;
1773
Douglas Gregore6688e62009-09-28 03:51:44 +00001774 bool isEarlierDeclarationName(DeclarationName X, DeclarationName Y) const {
Douglas Gregor249d6822009-12-05 09:08:56 +00001775 Selector XSel = X.getObjCSelector();
1776 Selector YSel = Y.getObjCSelector();
1777 if (!XSel.isNull() && !YSel.isNull()) {
1778 // We are comparing two selectors.
1779 unsigned N = std::min(XSel.getNumArgs(), YSel.getNumArgs());
1780 if (N == 0)
1781 ++N;
1782 for (unsigned I = 0; I != N; ++I) {
1783 IdentifierInfo *XId = XSel.getIdentifierInfoForSlot(I);
1784 IdentifierInfo *YId = YSel.getIdentifierInfoForSlot(I);
1785 if (!XId || !YId)
1786 return XId && !YId;
1787
1788 switch (XId->getName().compare_lower(YId->getName())) {
1789 case -1: return true;
1790 case 1: return false;
1791 default: break;
1792 }
1793 }
1794
1795 return XSel.getNumArgs() < YSel.getNumArgs();
1796 }
1797
1798 // For non-selectors, order by kind.
1799 if (X.getNameKind() != Y.getNameKind())
Douglas Gregore6688e62009-09-28 03:51:44 +00001800 return X.getNameKind() < Y.getNameKind();
1801
Douglas Gregor249d6822009-12-05 09:08:56 +00001802 // Order identifiers by comparison of their lowercased names.
1803 if (IdentifierInfo *XId = X.getAsIdentifierInfo())
1804 return XId->getName().compare_lower(
1805 Y.getAsIdentifierInfo()->getName()) < 0;
1806
1807 // Order overloaded operators by the order in which they appear
1808 // in our list of operators.
1809 if (OverloadedOperatorKind XOp = X.getCXXOverloadedOperator())
1810 return XOp < Y.getCXXOverloadedOperator();
1811
1812 // Order C++0x user-defined literal operators lexically by their
1813 // lowercased suffixes.
1814 if (IdentifierInfo *XLit = X.getCXXLiteralIdentifier())
1815 return XLit->getName().compare_lower(
1816 Y.getCXXLiteralIdentifier()->getName()) < 0;
1817
1818 // The only stable ordering we have is to turn the name into a
1819 // string and then compare the lower-case strings. This is
1820 // inefficient, but thankfully does not happen too often.
Benjamin Kramer4053e5d2009-12-05 10:22:15 +00001821 return llvm::StringRef(X.getAsString()).compare_lower(
1822 Y.getAsString()) < 0;
Douglas Gregore6688e62009-09-28 03:51:44 +00001823 }
1824
Douglas Gregor52ce62f2010-01-13 23:24:38 +00001825 /// \brief Retrieve the name that should be used to order a result.
1826 ///
1827 /// If the name needs to be constructed as a string, that string will be
1828 /// saved into Saved and the returned StringRef will refer to it.
1829 static llvm::StringRef getOrderedName(const Result &R,
1830 std::string &Saved) {
1831 switch (R.Kind) {
1832 case Result::RK_Keyword:
1833 return R.Keyword;
1834
1835 case Result::RK_Pattern:
1836 return R.Pattern->getTypedText();
1837
1838 case Result::RK_Macro:
1839 return R.Macro->getName();
1840
1841 case Result::RK_Declaration:
1842 // Handle declarations below.
1843 break;
Douglas Gregor45f83ee2009-11-19 00:01:57 +00001844 }
Douglas Gregor52ce62f2010-01-13 23:24:38 +00001845
1846 DeclarationName Name = R.Declaration->getDeclName();
Douglas Gregor45f83ee2009-11-19 00:01:57 +00001847
Douglas Gregor52ce62f2010-01-13 23:24:38 +00001848 // If the name is a simple identifier (by far the common case), or a
1849 // zero-argument selector, just return a reference to that identifier.
1850 if (IdentifierInfo *Id = Name.getAsIdentifierInfo())
1851 return Id->getName();
1852 if (Name.isObjCZeroArgSelector())
1853 if (IdentifierInfo *Id
1854 = Name.getObjCSelector().getIdentifierInfoForSlot(0))
1855 return Id->getName();
1856
1857 Saved = Name.getAsString();
1858 return Saved;
1859 }
1860
1861 bool operator()(const Result &X, const Result &Y) const {
1862 std::string XSaved, YSaved;
1863 llvm::StringRef XStr = getOrderedName(X, XSaved);
1864 llvm::StringRef YStr = getOrderedName(Y, YSaved);
1865 int cmp = XStr.compare_lower(YStr);
1866 if (cmp)
1867 return cmp < 0;
Douglas Gregor3545ff42009-09-21 16:56:56 +00001868
1869 // Non-hidden names precede hidden names.
1870 if (X.Hidden != Y.Hidden)
1871 return !X.Hidden;
1872
Douglas Gregore412a5a2009-09-23 22:26:46 +00001873 // Non-nested-name-specifiers precede nested-name-specifiers.
1874 if (X.StartsNestedNameSpecifier != Y.StartsNestedNameSpecifier)
1875 return !X.StartsNestedNameSpecifier;
1876
Douglas Gregor3545ff42009-09-21 16:56:56 +00001877 return false;
1878 }
1879 };
1880}
1881
Douglas Gregorf98e6a22010-01-13 23:51:12 +00001882static void AddMacroResults(Preprocessor &PP, ResultBuilder &Results) {
Douglas Gregorf329c7c2009-10-30 16:50:04 +00001883 Results.EnterNewScope();
Douglas Gregor9eb77012009-11-07 00:00:49 +00001884 for (Preprocessor::macro_iterator M = PP.macro_begin(),
1885 MEnd = PP.macro_end();
Douglas Gregorf329c7c2009-10-30 16:50:04 +00001886 M != MEnd; ++M)
Douglas Gregor78a21012010-01-14 16:01:26 +00001887 Results.AddResult(M->first);
Douglas Gregorf329c7c2009-10-30 16:50:04 +00001888 Results.ExitScope();
1889}
1890
Daniel Dunbar242ea9a2009-11-13 08:58:20 +00001891static void HandleCodeCompleteResults(Sema *S,
1892 CodeCompleteConsumer *CodeCompleter,
1893 CodeCompleteConsumer::Result *Results,
1894 unsigned NumResults) {
Douglas Gregor3545ff42009-09-21 16:56:56 +00001895 std::stable_sort(Results, Results + NumResults, SortCodeCompleteResult());
1896
1897 if (CodeCompleter)
Daniel Dunbar242ea9a2009-11-13 08:58:20 +00001898 CodeCompleter->ProcessCodeCompleteResults(*S, Results, NumResults);
Douglas Gregor45f83ee2009-11-19 00:01:57 +00001899
1900 for (unsigned I = 0; I != NumResults; ++I)
1901 Results[I].Destroy();
Douglas Gregor3545ff42009-09-21 16:56:56 +00001902}
1903
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001904void Sema::CodeCompleteOrdinaryName(Scope *S,
1905 CodeCompletionContext CompletionContext) {
Douglas Gregor92253692009-12-07 09:54:55 +00001906 typedef CodeCompleteConsumer::Result Result;
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001907 ResultBuilder Results(*this);
1908
1909 // Determine how to filter results, e.g., so that the names of
1910 // values (functions, enumerators, function templates, etc.) are
1911 // only allowed where we can have an expression.
1912 switch (CompletionContext) {
1913 case CCC_Namespace:
1914 case CCC_Class:
Douglas Gregorf1934162010-01-13 21:24:21 +00001915 case CCC_ObjCInterface:
1916 case CCC_ObjCImplementation:
Douglas Gregor48d46252010-01-13 21:54:15 +00001917 case CCC_ObjCInstanceVariableList:
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001918 case CCC_Template:
1919 case CCC_MemberTemplate:
1920 Results.setFilter(&ResultBuilder::IsOrdinaryNonValueName);
1921 break;
1922
1923 case CCC_Expression:
1924 case CCC_Statement:
1925 case CCC_ForInit:
1926 case CCC_Condition:
1927 Results.setFilter(&ResultBuilder::IsOrdinaryName);
1928 break;
1929 }
1930
Douglas Gregorc580c522010-01-14 01:09:38 +00001931 CodeCompletionDeclConsumer Consumer(Results, CurContext);
1932 LookupVisibleDecls(S, LookupOrdinaryName, Consumer);
Douglas Gregor92253692009-12-07 09:54:55 +00001933
1934 Results.EnterNewScope();
Douglas Gregorf98e6a22010-01-13 23:51:12 +00001935 AddOrdinaryNameResults(CompletionContext, S, *this, Results);
Douglas Gregor92253692009-12-07 09:54:55 +00001936 Results.ExitScope();
1937
Douglas Gregor9eb77012009-11-07 00:00:49 +00001938 if (CodeCompleter->includeMacros())
Douglas Gregorf98e6a22010-01-13 23:51:12 +00001939 AddMacroResults(PP, Results);
Daniel Dunbar242ea9a2009-11-13 08:58:20 +00001940 HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
Douglas Gregor9d64c5e2009-09-21 20:51:25 +00001941}
1942
Douglas Gregor9291bad2009-11-18 01:29:26 +00001943static void AddObjCProperties(ObjCContainerDecl *Container,
Douglas Gregor5d649882009-11-18 22:32:06 +00001944 bool AllowCategories,
Douglas Gregor9291bad2009-11-18 01:29:26 +00001945 DeclContext *CurContext,
1946 ResultBuilder &Results) {
1947 typedef CodeCompleteConsumer::Result Result;
1948
1949 // Add properties in this container.
1950 for (ObjCContainerDecl::prop_iterator P = Container->prop_begin(),
1951 PEnd = Container->prop_end();
1952 P != PEnd;
1953 ++P)
1954 Results.MaybeAddResult(Result(*P, 0), CurContext);
1955
1956 // Add properties in referenced protocols.
1957 if (ObjCProtocolDecl *Protocol = dyn_cast<ObjCProtocolDecl>(Container)) {
1958 for (ObjCProtocolDecl::protocol_iterator P = Protocol->protocol_begin(),
1959 PEnd = Protocol->protocol_end();
1960 P != PEnd; ++P)
Douglas Gregor5d649882009-11-18 22:32:06 +00001961 AddObjCProperties(*P, AllowCategories, CurContext, Results);
Douglas Gregor9291bad2009-11-18 01:29:26 +00001962 } else if (ObjCInterfaceDecl *IFace = dyn_cast<ObjCInterfaceDecl>(Container)){
Douglas Gregor5d649882009-11-18 22:32:06 +00001963 if (AllowCategories) {
1964 // Look through categories.
1965 for (ObjCCategoryDecl *Category = IFace->getCategoryList();
1966 Category; Category = Category->getNextClassCategory())
1967 AddObjCProperties(Category, AllowCategories, CurContext, Results);
1968 }
Douglas Gregor9291bad2009-11-18 01:29:26 +00001969
1970 // Look through protocols.
1971 for (ObjCInterfaceDecl::protocol_iterator I = IFace->protocol_begin(),
1972 E = IFace->protocol_end();
1973 I != E; ++I)
Douglas Gregor5d649882009-11-18 22:32:06 +00001974 AddObjCProperties(*I, AllowCategories, CurContext, Results);
Douglas Gregor9291bad2009-11-18 01:29:26 +00001975
1976 // Look in the superclass.
1977 if (IFace->getSuperClass())
Douglas Gregor5d649882009-11-18 22:32:06 +00001978 AddObjCProperties(IFace->getSuperClass(), AllowCategories, CurContext,
1979 Results);
Douglas Gregor9291bad2009-11-18 01:29:26 +00001980 } else if (const ObjCCategoryDecl *Category
1981 = dyn_cast<ObjCCategoryDecl>(Container)) {
1982 // Look through protocols.
1983 for (ObjCInterfaceDecl::protocol_iterator P = Category->protocol_begin(),
1984 PEnd = Category->protocol_end();
1985 P != PEnd; ++P)
Douglas Gregor5d649882009-11-18 22:32:06 +00001986 AddObjCProperties(*P, AllowCategories, CurContext, Results);
Douglas Gregor9291bad2009-11-18 01:29:26 +00001987 }
1988}
1989
Douglas Gregor2436e712009-09-17 21:32:03 +00001990void Sema::CodeCompleteMemberReferenceExpr(Scope *S, ExprTy *BaseE,
1991 SourceLocation OpLoc,
1992 bool IsArrow) {
1993 if (!BaseE || !CodeCompleter)
1994 return;
1995
Douglas Gregor3545ff42009-09-21 16:56:56 +00001996 typedef CodeCompleteConsumer::Result Result;
1997
Douglas Gregor2436e712009-09-17 21:32:03 +00001998 Expr *Base = static_cast<Expr *>(BaseE);
1999 QualType BaseType = Base->getType();
Douglas Gregor3545ff42009-09-21 16:56:56 +00002000
2001 if (IsArrow) {
2002 if (const PointerType *Ptr = BaseType->getAs<PointerType>())
2003 BaseType = Ptr->getPointeeType();
2004 else if (BaseType->isObjCObjectPointerType())
2005 /*Do nothing*/ ;
2006 else
2007 return;
2008 }
2009
Douglas Gregore412a5a2009-09-23 22:26:46 +00002010 ResultBuilder Results(*this, &ResultBuilder::IsMember);
Douglas Gregor9291bad2009-11-18 01:29:26 +00002011 Results.EnterNewScope();
2012 if (const RecordType *Record = BaseType->getAs<RecordType>()) {
2013 // Access to a C/C++ class, struct, or union.
Douglas Gregor6ae4c522010-01-14 03:21:49 +00002014 Results.allowNestedNameSpecifiers();
Douglas Gregor09bbc652010-01-14 15:47:35 +00002015 CodeCompletionDeclConsumer Consumer(Results, CurContext);
2016 LookupVisibleDecls(Record->getDecl(), LookupMemberName, Consumer);
Daniel Dunbar242ea9a2009-11-13 08:58:20 +00002017
Douglas Gregor9291bad2009-11-18 01:29:26 +00002018 if (getLangOptions().CPlusPlus) {
2019 if (!Results.empty()) {
2020 // The "template" keyword can follow "->" or "." in the grammar.
2021 // However, we only want to suggest the template keyword if something
2022 // is dependent.
2023 bool IsDependent = BaseType->isDependentType();
2024 if (!IsDependent) {
2025 for (Scope *DepScope = S; DepScope; DepScope = DepScope->getParent())
2026 if (DeclContext *Ctx = (DeclContext *)DepScope->getEntity()) {
2027 IsDependent = Ctx->isDependentContext();
2028 break;
2029 }
2030 }
Daniel Dunbar242ea9a2009-11-13 08:58:20 +00002031
Douglas Gregor9291bad2009-11-18 01:29:26 +00002032 if (IsDependent)
Douglas Gregor78a21012010-01-14 16:01:26 +00002033 Results.AddResult(Result("template"));
Daniel Dunbar242ea9a2009-11-13 08:58:20 +00002034 }
Daniel Dunbar242ea9a2009-11-13 08:58:20 +00002035 }
Douglas Gregor9291bad2009-11-18 01:29:26 +00002036 } else if (!IsArrow && BaseType->getAsObjCInterfacePointerType()) {
2037 // Objective-C property reference.
2038
2039 // Add property results based on our interface.
2040 const ObjCObjectPointerType *ObjCPtr
2041 = BaseType->getAsObjCInterfacePointerType();
2042 assert(ObjCPtr && "Non-NULL pointer guaranteed above!");
Douglas Gregor5d649882009-11-18 22:32:06 +00002043 AddObjCProperties(ObjCPtr->getInterfaceDecl(), true, CurContext, Results);
Douglas Gregor9291bad2009-11-18 01:29:26 +00002044
2045 // Add properties from the protocols in a qualified interface.
2046 for (ObjCObjectPointerType::qual_iterator I = ObjCPtr->qual_begin(),
2047 E = ObjCPtr->qual_end();
2048 I != E; ++I)
Douglas Gregor5d649882009-11-18 22:32:06 +00002049 AddObjCProperties(*I, true, CurContext, Results);
Douglas Gregor9291bad2009-11-18 01:29:26 +00002050 } else if ((IsArrow && BaseType->isObjCObjectPointerType()) ||
2051 (!IsArrow && BaseType->isObjCInterfaceType())) {
2052 // Objective-C instance variable access.
2053 ObjCInterfaceDecl *Class = 0;
2054 if (const ObjCObjectPointerType *ObjCPtr
2055 = BaseType->getAs<ObjCObjectPointerType>())
2056 Class = ObjCPtr->getInterfaceDecl();
2057 else
2058 Class = BaseType->getAs<ObjCInterfaceType>()->getDecl();
2059
2060 // Add all ivars from this class and its superclasses.
Douglas Gregor2b8162b2010-01-14 16:08:12 +00002061 if (Class) {
2062 CodeCompletionDeclConsumer Consumer(Results, CurContext);
2063 Results.setFilter(&ResultBuilder::IsObjCIvar);
2064 LookupVisibleDecls(Class, LookupMemberName, Consumer);
Douglas Gregor9291bad2009-11-18 01:29:26 +00002065 }
Douglas Gregor3545ff42009-09-21 16:56:56 +00002066 }
Douglas Gregor9291bad2009-11-18 01:29:26 +00002067
2068 // FIXME: How do we cope with isa?
2069
2070 Results.ExitScope();
Daniel Dunbar242ea9a2009-11-13 08:58:20 +00002071
Daniel Dunbar242ea9a2009-11-13 08:58:20 +00002072 // Hand off the results found for code completion.
2073 HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
Douglas Gregor2436e712009-09-17 21:32:03 +00002074}
2075
Douglas Gregorf45b0cf2009-09-18 15:37:17 +00002076void Sema::CodeCompleteTag(Scope *S, unsigned TagSpec) {
2077 if (!CodeCompleter)
2078 return;
2079
Douglas Gregor3545ff42009-09-21 16:56:56 +00002080 typedef CodeCompleteConsumer::Result Result;
2081 ResultBuilder::LookupFilter Filter = 0;
Douglas Gregorf45b0cf2009-09-18 15:37:17 +00002082 switch ((DeclSpec::TST)TagSpec) {
2083 case DeclSpec::TST_enum:
Douglas Gregor3545ff42009-09-21 16:56:56 +00002084 Filter = &ResultBuilder::IsEnum;
Douglas Gregorf45b0cf2009-09-18 15:37:17 +00002085 break;
2086
2087 case DeclSpec::TST_union:
Douglas Gregor3545ff42009-09-21 16:56:56 +00002088 Filter = &ResultBuilder::IsUnion;
Douglas Gregorf45b0cf2009-09-18 15:37:17 +00002089 break;
2090
2091 case DeclSpec::TST_struct:
Douglas Gregorf45b0cf2009-09-18 15:37:17 +00002092 case DeclSpec::TST_class:
Douglas Gregor3545ff42009-09-21 16:56:56 +00002093 Filter = &ResultBuilder::IsClassOrStruct;
Douglas Gregorf45b0cf2009-09-18 15:37:17 +00002094 break;
2095
2096 default:
2097 assert(false && "Unknown type specifier kind in CodeCompleteTag");
2098 return;
2099 }
Douglas Gregor3545ff42009-09-21 16:56:56 +00002100
John McCalla2456712010-04-23 02:41:41 +00002101 ResultBuilder Results(*this);
Douglas Gregora6e2edc2010-01-14 03:27:13 +00002102 CodeCompletionDeclConsumer Consumer(Results, CurContext);
John McCalla2456712010-04-23 02:41:41 +00002103
2104 // First pass: look for tags.
2105 Results.setFilter(Filter);
Douglas Gregora6e2edc2010-01-14 03:27:13 +00002106 LookupVisibleDecls(S, LookupTagName, Consumer);
John McCalla2456712010-04-23 02:41:41 +00002107
2108 // Second pass: look for nested name specifiers.
2109 Results.setFilter(&ResultBuilder::IsNestedNameSpecifier);
2110 LookupVisibleDecls(S, LookupNestedNameSpecifierName, Consumer);
Douglas Gregor3545ff42009-09-21 16:56:56 +00002111
Daniel Dunbar242ea9a2009-11-13 08:58:20 +00002112 HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
Douglas Gregorf45b0cf2009-09-18 15:37:17 +00002113}
2114
Douglas Gregord328d572009-09-21 18:10:23 +00002115void Sema::CodeCompleteCase(Scope *S) {
2116 if (getSwitchStack().empty() || !CodeCompleter)
2117 return;
2118
2119 SwitchStmt *Switch = getSwitchStack().back();
2120 if (!Switch->getCond()->getType()->isEnumeralType())
2121 return;
2122
2123 // Code-complete the cases of a switch statement over an enumeration type
2124 // by providing the list of
2125 EnumDecl *Enum = Switch->getCond()->getType()->getAs<EnumType>()->getDecl();
2126
2127 // Determine which enumerators we have already seen in the switch statement.
2128 // FIXME: Ideally, we would also be able to look *past* the code-completion
2129 // token, in case we are code-completing in the middle of the switch and not
2130 // at the end. However, we aren't able to do so at the moment.
2131 llvm::SmallPtrSet<EnumConstantDecl *, 8> EnumeratorsSeen;
Douglas Gregorf2510672009-09-21 19:57:38 +00002132 NestedNameSpecifier *Qualifier = 0;
Douglas Gregord328d572009-09-21 18:10:23 +00002133 for (SwitchCase *SC = Switch->getSwitchCaseList(); SC;
2134 SC = SC->getNextSwitchCase()) {
2135 CaseStmt *Case = dyn_cast<CaseStmt>(SC);
2136 if (!Case)
2137 continue;
2138
2139 Expr *CaseVal = Case->getLHS()->IgnoreParenCasts();
2140 if (DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(CaseVal))
2141 if (EnumConstantDecl *Enumerator
2142 = dyn_cast<EnumConstantDecl>(DRE->getDecl())) {
2143 // We look into the AST of the case statement to determine which
2144 // enumerator was named. Alternatively, we could compute the value of
2145 // the integral constant expression, then compare it against the
2146 // values of each enumerator. However, value-based approach would not
2147 // work as well with C++ templates where enumerators declared within a
2148 // template are type- and value-dependent.
2149 EnumeratorsSeen.insert(Enumerator);
2150
Douglas Gregorf2510672009-09-21 19:57:38 +00002151 // If this is a qualified-id, keep track of the nested-name-specifier
2152 // so that we can reproduce it as part of code completion, e.g.,
Douglas Gregord328d572009-09-21 18:10:23 +00002153 //
2154 // switch (TagD.getKind()) {
2155 // case TagDecl::TK_enum:
2156 // break;
2157 // case XXX
2158 //
Douglas Gregorf2510672009-09-21 19:57:38 +00002159 // At the XXX, our completions are TagDecl::TK_union,
Douglas Gregord328d572009-09-21 18:10:23 +00002160 // TagDecl::TK_struct, and TagDecl::TK_class, rather than TK_union,
2161 // TK_struct, and TK_class.
Douglas Gregor4bd90e52009-10-23 18:54:35 +00002162 Qualifier = DRE->getQualifier();
Douglas Gregord328d572009-09-21 18:10:23 +00002163 }
2164 }
2165
Douglas Gregorf2510672009-09-21 19:57:38 +00002166 if (getLangOptions().CPlusPlus && !Qualifier && EnumeratorsSeen.empty()) {
2167 // If there are no prior enumerators in C++, check whether we have to
2168 // qualify the names of the enumerators that we suggest, because they
2169 // may not be visible in this scope.
2170 Qualifier = getRequiredQualification(Context, CurContext,
2171 Enum->getDeclContext());
2172
2173 // FIXME: Scoped enums need to start with "EnumDecl" as the context!
2174 }
2175
Douglas Gregord328d572009-09-21 18:10:23 +00002176 // Add any enumerators that have not yet been mentioned.
2177 ResultBuilder Results(*this);
2178 Results.EnterNewScope();
2179 for (EnumDecl::enumerator_iterator E = Enum->enumerator_begin(),
2180 EEnd = Enum->enumerator_end();
2181 E != EEnd; ++E) {
2182 if (EnumeratorsSeen.count(*E))
2183 continue;
2184
Douglas Gregorfc59ce12010-01-14 16:14:35 +00002185 Results.AddResult(CodeCompleteConsumer::Result(*E, Qualifier),
2186 CurContext, 0, false);
Douglas Gregord328d572009-09-21 18:10:23 +00002187 }
2188 Results.ExitScope();
Douglas Gregor285560922010-04-06 20:02:15 +00002189
Douglas Gregor9eb77012009-11-07 00:00:49 +00002190 if (CodeCompleter->includeMacros())
Douglas Gregorf98e6a22010-01-13 23:51:12 +00002191 AddMacroResults(PP, Results);
Daniel Dunbar242ea9a2009-11-13 08:58:20 +00002192 HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
Douglas Gregord328d572009-09-21 18:10:23 +00002193}
2194
Douglas Gregorcabea402009-09-22 15:41:20 +00002195namespace {
2196 struct IsBetterOverloadCandidate {
2197 Sema &S;
John McCallbc077cf2010-02-08 23:07:23 +00002198 SourceLocation Loc;
Douglas Gregorcabea402009-09-22 15:41:20 +00002199
2200 public:
John McCallbc077cf2010-02-08 23:07:23 +00002201 explicit IsBetterOverloadCandidate(Sema &S, SourceLocation Loc)
2202 : S(S), Loc(Loc) { }
Douglas Gregorcabea402009-09-22 15:41:20 +00002203
2204 bool
2205 operator()(const OverloadCandidate &X, const OverloadCandidate &Y) const {
John McCallbc077cf2010-02-08 23:07:23 +00002206 return S.isBetterOverloadCandidate(X, Y, Loc);
Douglas Gregorcabea402009-09-22 15:41:20 +00002207 }
2208 };
2209}
2210
2211void Sema::CodeCompleteCall(Scope *S, ExprTy *FnIn,
2212 ExprTy **ArgsIn, unsigned NumArgs) {
2213 if (!CodeCompleter)
2214 return;
Douglas Gregor3ef59522009-12-11 19:06:04 +00002215
2216 // When we're code-completing for a call, we fall back to ordinary
2217 // name code-completion whenever we can't produce specific
2218 // results. We may want to revisit this strategy in the future,
2219 // e.g., by merging the two kinds of results.
2220
Douglas Gregorcabea402009-09-22 15:41:20 +00002221 Expr *Fn = (Expr *)FnIn;
2222 Expr **Args = (Expr **)ArgsIn;
Douglas Gregor3ef59522009-12-11 19:06:04 +00002223
Douglas Gregorcabea402009-09-22 15:41:20 +00002224 // Ignore type-dependent call expressions entirely.
2225 if (Fn->isTypeDependent() ||
Douglas Gregor3ef59522009-12-11 19:06:04 +00002226 Expr::hasAnyTypeDependentArguments(Args, NumArgs)) {
Douglas Gregor504a6ae2010-01-10 23:08:15 +00002227 CodeCompleteOrdinaryName(S, CCC_Expression);
Douglas Gregorcabea402009-09-22 15:41:20 +00002228 return;
Douglas Gregor3ef59522009-12-11 19:06:04 +00002229 }
Douglas Gregorcabea402009-09-22 15:41:20 +00002230
John McCall57500772009-12-16 12:17:52 +00002231 // Build an overload candidate set based on the functions we find.
John McCallbc077cf2010-02-08 23:07:23 +00002232 SourceLocation Loc = Fn->getExprLoc();
2233 OverloadCandidateSet CandidateSet(Loc);
John McCall57500772009-12-16 12:17:52 +00002234
Douglas Gregorcabea402009-09-22 15:41:20 +00002235 // FIXME: What if we're calling something that isn't a function declaration?
2236 // FIXME: What if we're calling a pseudo-destructor?
2237 // FIXME: What if we're calling a member function?
2238
Douglas Gregorff59f672010-01-21 15:46:19 +00002239 typedef CodeCompleteConsumer::OverloadCandidate ResultCandidate;
2240 llvm::SmallVector<ResultCandidate, 8> Results;
2241
John McCall57500772009-12-16 12:17:52 +00002242 Expr *NakedFn = Fn->IgnoreParenCasts();
2243 if (UnresolvedLookupExpr *ULE = dyn_cast<UnresolvedLookupExpr>(NakedFn))
2244 AddOverloadedCallCandidates(ULE, Args, NumArgs, CandidateSet,
2245 /*PartialOverloading=*/ true);
2246 else if (DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(NakedFn)) {
2247 FunctionDecl *FDecl = dyn_cast<FunctionDecl>(DRE->getDecl());
Douglas Gregorff59f672010-01-21 15:46:19 +00002248 if (FDecl) {
2249 if (!FDecl->getType()->getAs<FunctionProtoType>())
2250 Results.push_back(ResultCandidate(FDecl));
2251 else
John McCallb89836b2010-01-26 01:37:31 +00002252 // FIXME: access?
John McCalla0296f72010-03-19 07:35:19 +00002253 AddOverloadCandidate(FDecl, DeclAccessPair::make(FDecl, AS_none),
2254 Args, NumArgs, CandidateSet,
Douglas Gregorb05275a2010-04-16 17:41:49 +00002255 false, /*PartialOverloading*/true);
Douglas Gregorff59f672010-01-21 15:46:19 +00002256 }
John McCall57500772009-12-16 12:17:52 +00002257 }
Douglas Gregorcabea402009-09-22 15:41:20 +00002258
Douglas Gregorff59f672010-01-21 15:46:19 +00002259 if (!CandidateSet.empty()) {
2260 // Sort the overload candidate set by placing the best overloads first.
2261 std::stable_sort(CandidateSet.begin(), CandidateSet.end(),
John McCallbc077cf2010-02-08 23:07:23 +00002262 IsBetterOverloadCandidate(*this, Loc));
Douglas Gregorcabea402009-09-22 15:41:20 +00002263
Douglas Gregorff59f672010-01-21 15:46:19 +00002264 // Add the remaining viable overload candidates as code-completion reslults.
2265 for (OverloadCandidateSet::iterator Cand = CandidateSet.begin(),
2266 CandEnd = CandidateSet.end();
2267 Cand != CandEnd; ++Cand) {
2268 if (Cand->Viable)
2269 Results.push_back(ResultCandidate(Cand->Function));
2270 }
Douglas Gregorcabea402009-09-22 15:41:20 +00002271 }
Douglas Gregor3ef59522009-12-11 19:06:04 +00002272
Douglas Gregorc01890e2010-04-06 20:19:47 +00002273 CodeCompleteOrdinaryName(S, CCC_Expression);
2274 if (!Results.empty())
Douglas Gregor3ef59522009-12-11 19:06:04 +00002275 CodeCompleter->ProcessOverloadCandidates(*this, NumArgs, Results.data(),
2276 Results.size());
Douglas Gregorcabea402009-09-22 15:41:20 +00002277}
2278
Jeffrey Yasskinc76498d2010-04-08 16:38:48 +00002279void Sema::CodeCompleteQualifiedId(Scope *S, CXXScopeSpec &SS,
Douglas Gregor2436e712009-09-17 21:32:03 +00002280 bool EnteringContext) {
2281 if (!SS.getScopeRep() || !CodeCompleter)
2282 return;
2283
Douglas Gregor3545ff42009-09-21 16:56:56 +00002284 DeclContext *Ctx = computeDeclContext(SS, EnteringContext);
2285 if (!Ctx)
2286 return;
Douglas Gregor800f2f02009-12-11 18:28:39 +00002287
2288 // Try to instantiate any non-dependent declaration contexts before
2289 // we look in them.
2290 if (!isDependentScopeSpecifier(SS) && RequireCompleteDeclContext(SS))
2291 return;
2292
Douglas Gregor3545ff42009-09-21 16:56:56 +00002293 ResultBuilder Results(*this);
Douglas Gregor200c99d2010-01-14 03:35:48 +00002294 CodeCompletionDeclConsumer Consumer(Results, CurContext);
2295 LookupVisibleDecls(Ctx, LookupOrdinaryName, Consumer);
Douglas Gregor3545ff42009-09-21 16:56:56 +00002296
2297 // The "template" keyword can follow "::" in the grammar, but only
2298 // put it into the grammar if the nested-name-specifier is dependent.
2299 NestedNameSpecifier *NNS = (NestedNameSpecifier *)SS.getScopeRep();
2300 if (!Results.empty() && NNS->isDependent())
Douglas Gregor78a21012010-01-14 16:01:26 +00002301 Results.AddResult("template");
Douglas Gregor3545ff42009-09-21 16:56:56 +00002302
Daniel Dunbar242ea9a2009-11-13 08:58:20 +00002303 HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
Douglas Gregor2436e712009-09-17 21:32:03 +00002304}
Douglas Gregor7e90c6d2009-09-18 19:03:04 +00002305
2306void Sema::CodeCompleteUsing(Scope *S) {
2307 if (!CodeCompleter)
2308 return;
2309
Douglas Gregor3545ff42009-09-21 16:56:56 +00002310 ResultBuilder Results(*this, &ResultBuilder::IsNestedNameSpecifier);
Douglas Gregor64b12b52009-09-22 23:31:26 +00002311 Results.EnterNewScope();
Douglas Gregor3545ff42009-09-21 16:56:56 +00002312
2313 // If we aren't in class scope, we could see the "namespace" keyword.
2314 if (!S->isClassScope())
Douglas Gregor78a21012010-01-14 16:01:26 +00002315 Results.AddResult(CodeCompleteConsumer::Result("namespace"));
Douglas Gregor3545ff42009-09-21 16:56:56 +00002316
2317 // After "using", we can see anything that would start a
2318 // nested-name-specifier.
Douglas Gregora6e2edc2010-01-14 03:27:13 +00002319 CodeCompletionDeclConsumer Consumer(Results, CurContext);
2320 LookupVisibleDecls(S, LookupOrdinaryName, Consumer);
Douglas Gregor64b12b52009-09-22 23:31:26 +00002321 Results.ExitScope();
Douglas Gregor3545ff42009-09-21 16:56:56 +00002322
Daniel Dunbar242ea9a2009-11-13 08:58:20 +00002323 HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
Douglas Gregor7e90c6d2009-09-18 19:03:04 +00002324}
2325
2326void Sema::CodeCompleteUsingDirective(Scope *S) {
2327 if (!CodeCompleter)
2328 return;
2329
Douglas Gregor3545ff42009-09-21 16:56:56 +00002330 // After "using namespace", we expect to see a namespace name or namespace
2331 // alias.
2332 ResultBuilder Results(*this, &ResultBuilder::IsNamespaceOrAlias);
Douglas Gregor64b12b52009-09-22 23:31:26 +00002333 Results.EnterNewScope();
Douglas Gregora6e2edc2010-01-14 03:27:13 +00002334 CodeCompletionDeclConsumer Consumer(Results, CurContext);
2335 LookupVisibleDecls(S, LookupOrdinaryName, Consumer);
Douglas Gregor64b12b52009-09-22 23:31:26 +00002336 Results.ExitScope();
Daniel Dunbar242ea9a2009-11-13 08:58:20 +00002337 HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
Douglas Gregor7e90c6d2009-09-18 19:03:04 +00002338}
2339
2340void Sema::CodeCompleteNamespaceDecl(Scope *S) {
2341 if (!CodeCompleter)
2342 return;
2343
Douglas Gregor3545ff42009-09-21 16:56:56 +00002344 ResultBuilder Results(*this, &ResultBuilder::IsNamespace);
2345 DeclContext *Ctx = (DeclContext *)S->getEntity();
2346 if (!S->getParent())
2347 Ctx = Context.getTranslationUnitDecl();
2348
2349 if (Ctx && Ctx->isFileContext()) {
2350 // We only want to see those namespaces that have already been defined
2351 // within this scope, because its likely that the user is creating an
2352 // extended namespace declaration. Keep track of the most recent
2353 // definition of each namespace.
2354 std::map<NamespaceDecl *, NamespaceDecl *> OrigToLatest;
2355 for (DeclContext::specific_decl_iterator<NamespaceDecl>
2356 NS(Ctx->decls_begin()), NSEnd(Ctx->decls_end());
2357 NS != NSEnd; ++NS)
2358 OrigToLatest[NS->getOriginalNamespace()] = *NS;
2359
2360 // Add the most recent definition (or extended definition) of each
2361 // namespace to the list of results.
Douglas Gregor64b12b52009-09-22 23:31:26 +00002362 Results.EnterNewScope();
Douglas Gregor3545ff42009-09-21 16:56:56 +00002363 for (std::map<NamespaceDecl *, NamespaceDecl *>::iterator
2364 NS = OrigToLatest.begin(), NSEnd = OrigToLatest.end();
2365 NS != NSEnd; ++NS)
Douglas Gregorfc59ce12010-01-14 16:14:35 +00002366 Results.AddResult(CodeCompleteConsumer::Result(NS->second, 0),
2367 CurContext, 0, false);
Douglas Gregor64b12b52009-09-22 23:31:26 +00002368 Results.ExitScope();
Douglas Gregor3545ff42009-09-21 16:56:56 +00002369 }
2370
Daniel Dunbar242ea9a2009-11-13 08:58:20 +00002371 HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
Douglas Gregor7e90c6d2009-09-18 19:03:04 +00002372}
2373
2374void Sema::CodeCompleteNamespaceAliasDecl(Scope *S) {
2375 if (!CodeCompleter)
2376 return;
2377
Douglas Gregor3545ff42009-09-21 16:56:56 +00002378 // After "namespace", we expect to see a namespace or alias.
2379 ResultBuilder Results(*this, &ResultBuilder::IsNamespaceOrAlias);
Douglas Gregora6e2edc2010-01-14 03:27:13 +00002380 CodeCompletionDeclConsumer Consumer(Results, CurContext);
2381 LookupVisibleDecls(S, LookupOrdinaryName, Consumer);
Daniel Dunbar242ea9a2009-11-13 08:58:20 +00002382 HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
Douglas Gregor7e90c6d2009-09-18 19:03:04 +00002383}
2384
Douglas Gregorc811ede2009-09-18 20:05:18 +00002385void Sema::CodeCompleteOperatorName(Scope *S) {
2386 if (!CodeCompleter)
2387 return;
Douglas Gregor3545ff42009-09-21 16:56:56 +00002388
2389 typedef CodeCompleteConsumer::Result Result;
2390 ResultBuilder Results(*this, &ResultBuilder::IsType);
Douglas Gregor64b12b52009-09-22 23:31:26 +00002391 Results.EnterNewScope();
Douglas Gregorc811ede2009-09-18 20:05:18 +00002392
Douglas Gregor3545ff42009-09-21 16:56:56 +00002393 // Add the names of overloadable operators.
2394#define OVERLOADED_OPERATOR(Name,Spelling,Token,Unary,Binary,MemberOnly) \
2395 if (std::strcmp(Spelling, "?")) \
Douglas Gregor78a21012010-01-14 16:01:26 +00002396 Results.AddResult(Result(Spelling));
Douglas Gregor3545ff42009-09-21 16:56:56 +00002397#include "clang/Basic/OperatorKinds.def"
2398
2399 // Add any type names visible from the current scope
Douglas Gregor6ae4c522010-01-14 03:21:49 +00002400 Results.allowNestedNameSpecifiers();
Douglas Gregora6e2edc2010-01-14 03:27:13 +00002401 CodeCompletionDeclConsumer Consumer(Results, CurContext);
2402 LookupVisibleDecls(S, LookupOrdinaryName, Consumer);
Douglas Gregor3545ff42009-09-21 16:56:56 +00002403
2404 // Add any type specifiers
Douglas Gregorf98e6a22010-01-13 23:51:12 +00002405 AddTypeSpecifierResults(getLangOptions(), Results);
Douglas Gregor64b12b52009-09-22 23:31:26 +00002406 Results.ExitScope();
Douglas Gregor3545ff42009-09-21 16:56:56 +00002407
Daniel Dunbar242ea9a2009-11-13 08:58:20 +00002408 HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
Douglas Gregorc811ede2009-09-18 20:05:18 +00002409}
Douglas Gregor7e90c6d2009-09-18 19:03:04 +00002410
Douglas Gregorf1934162010-01-13 21:24:21 +00002411// Macro that expands to @Keyword or Keyword, depending on whether NeedAt is
2412// true or false.
2413#define OBJC_AT_KEYWORD_NAME(NeedAt,Keyword) NeedAt? "@" #Keyword : #Keyword
Douglas Gregorf98e6a22010-01-13 23:51:12 +00002414static void AddObjCImplementationResults(const LangOptions &LangOpts,
Douglas Gregorf1934162010-01-13 21:24:21 +00002415 ResultBuilder &Results,
2416 bool NeedAt) {
2417 typedef CodeCompleteConsumer::Result Result;
2418 // Since we have an implementation, we can end it.
Douglas Gregor78a21012010-01-14 16:01:26 +00002419 Results.AddResult(Result(OBJC_AT_KEYWORD_NAME(NeedAt,end)));
Douglas Gregorf1934162010-01-13 21:24:21 +00002420
2421 CodeCompletionString *Pattern = 0;
2422 if (LangOpts.ObjC2) {
2423 // @dynamic
2424 Pattern = new CodeCompletionString;
2425 Pattern->AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt,dynamic));
2426 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
2427 Pattern->AddPlaceholderChunk("property");
Douglas Gregor78a21012010-01-14 16:01:26 +00002428 Results.AddResult(Result(Pattern));
Douglas Gregorf1934162010-01-13 21:24:21 +00002429
2430 // @synthesize
2431 Pattern = new CodeCompletionString;
2432 Pattern->AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt,synthesize));
2433 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
2434 Pattern->AddPlaceholderChunk("property");
Douglas Gregor78a21012010-01-14 16:01:26 +00002435 Results.AddResult(Result(Pattern));
Douglas Gregorf1934162010-01-13 21:24:21 +00002436 }
2437}
2438
Douglas Gregorf98e6a22010-01-13 23:51:12 +00002439static void AddObjCInterfaceResults(const LangOptions &LangOpts,
Douglas Gregorf1934162010-01-13 21:24:21 +00002440 ResultBuilder &Results,
2441 bool NeedAt) {
2442 typedef CodeCompleteConsumer::Result Result;
2443
2444 // Since we have an interface or protocol, we can end it.
Douglas Gregor78a21012010-01-14 16:01:26 +00002445 Results.AddResult(Result(OBJC_AT_KEYWORD_NAME(NeedAt,end)));
Douglas Gregorf1934162010-01-13 21:24:21 +00002446
2447 if (LangOpts.ObjC2) {
2448 // @property
Douglas Gregor78a21012010-01-14 16:01:26 +00002449 Results.AddResult(Result(OBJC_AT_KEYWORD_NAME(NeedAt,property)));
Douglas Gregorf1934162010-01-13 21:24:21 +00002450
2451 // @required
Douglas Gregor78a21012010-01-14 16:01:26 +00002452 Results.AddResult(Result(OBJC_AT_KEYWORD_NAME(NeedAt,required)));
Douglas Gregorf1934162010-01-13 21:24:21 +00002453
2454 // @optional
Douglas Gregor78a21012010-01-14 16:01:26 +00002455 Results.AddResult(Result(OBJC_AT_KEYWORD_NAME(NeedAt,optional)));
Douglas Gregorf1934162010-01-13 21:24:21 +00002456 }
2457}
2458
Douglas Gregorf98e6a22010-01-13 23:51:12 +00002459static void AddObjCTopLevelResults(ResultBuilder &Results, bool NeedAt) {
Douglas Gregorf1934162010-01-13 21:24:21 +00002460 typedef CodeCompleteConsumer::Result Result;
2461 CodeCompletionString *Pattern = 0;
2462
2463 // @class name ;
2464 Pattern = new CodeCompletionString;
2465 Pattern->AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt,class));
2466 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
2467 Pattern->AddPlaceholderChunk("identifier");
Douglas Gregor78a21012010-01-14 16:01:26 +00002468 Results.AddResult(Result(Pattern));
Douglas Gregorf1934162010-01-13 21:24:21 +00002469
2470 // @interface name
2471 // FIXME: Could introduce the whole pattern, including superclasses and
2472 // such.
2473 Pattern = new CodeCompletionString;
2474 Pattern->AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt,interface));
2475 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
2476 Pattern->AddPlaceholderChunk("class");
Douglas Gregor78a21012010-01-14 16:01:26 +00002477 Results.AddResult(Result(Pattern));
Douglas Gregorf1934162010-01-13 21:24:21 +00002478
2479 // @protocol name
2480 Pattern = new CodeCompletionString;
2481 Pattern->AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt,protocol));
2482 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
2483 Pattern->AddPlaceholderChunk("protocol");
Douglas Gregor78a21012010-01-14 16:01:26 +00002484 Results.AddResult(Result(Pattern));
Douglas Gregorf1934162010-01-13 21:24:21 +00002485
2486 // @implementation name
2487 Pattern = new CodeCompletionString;
2488 Pattern->AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt,implementation));
2489 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
2490 Pattern->AddPlaceholderChunk("class");
Douglas Gregor78a21012010-01-14 16:01:26 +00002491 Results.AddResult(Result(Pattern));
Douglas Gregorf1934162010-01-13 21:24:21 +00002492
2493 // @compatibility_alias name
2494 Pattern = new CodeCompletionString;
2495 Pattern->AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt,compatibility_alias));
2496 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
2497 Pattern->AddPlaceholderChunk("alias");
2498 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
2499 Pattern->AddPlaceholderChunk("class");
Douglas Gregor78a21012010-01-14 16:01:26 +00002500 Results.AddResult(Result(Pattern));
Douglas Gregorf1934162010-01-13 21:24:21 +00002501}
2502
Douglas Gregorf48706c2009-12-07 09:27:33 +00002503void Sema::CodeCompleteObjCAtDirective(Scope *S, DeclPtrTy ObjCImpDecl,
2504 bool InInterface) {
2505 typedef CodeCompleteConsumer::Result Result;
2506 ResultBuilder Results(*this);
2507 Results.EnterNewScope();
Douglas Gregorf1934162010-01-13 21:24:21 +00002508 if (ObjCImpDecl)
Douglas Gregorf98e6a22010-01-13 23:51:12 +00002509 AddObjCImplementationResults(getLangOptions(), Results, false);
Douglas Gregorf1934162010-01-13 21:24:21 +00002510 else if (InInterface)
Douglas Gregorf98e6a22010-01-13 23:51:12 +00002511 AddObjCInterfaceResults(getLangOptions(), Results, false);
Douglas Gregorf1934162010-01-13 21:24:21 +00002512 else
Douglas Gregorf98e6a22010-01-13 23:51:12 +00002513 AddObjCTopLevelResults(Results, false);
Douglas Gregorf48706c2009-12-07 09:27:33 +00002514 Results.ExitScope();
2515 HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
2516}
2517
Douglas Gregorf98e6a22010-01-13 23:51:12 +00002518static void AddObjCExpressionResults(ResultBuilder &Results, bool NeedAt) {
Douglas Gregorbc7c5e42009-12-07 09:51:25 +00002519 typedef CodeCompleteConsumer::Result Result;
2520 CodeCompletionString *Pattern = 0;
2521
2522 // @encode ( type-name )
2523 Pattern = new CodeCompletionString;
Douglas Gregorf1934162010-01-13 21:24:21 +00002524 Pattern->AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt,encode));
Douglas Gregorbc7c5e42009-12-07 09:51:25 +00002525 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
2526 Pattern->AddPlaceholderChunk("type-name");
2527 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
Douglas Gregor78a21012010-01-14 16:01:26 +00002528 Results.AddResult(Result(Pattern));
Douglas Gregorbc7c5e42009-12-07 09:51:25 +00002529
2530 // @protocol ( protocol-name )
2531 Pattern = new CodeCompletionString;
Douglas Gregorf1934162010-01-13 21:24:21 +00002532 Pattern->AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt,protocol));
Douglas Gregorbc7c5e42009-12-07 09:51:25 +00002533 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
2534 Pattern->AddPlaceholderChunk("protocol-name");
2535 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
Douglas Gregor78a21012010-01-14 16:01:26 +00002536 Results.AddResult(Result(Pattern));
Douglas Gregorbc7c5e42009-12-07 09:51:25 +00002537
2538 // @selector ( selector )
2539 Pattern = new CodeCompletionString;
Douglas Gregorf1934162010-01-13 21:24:21 +00002540 Pattern->AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt,selector));
Douglas Gregorbc7c5e42009-12-07 09:51:25 +00002541 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
2542 Pattern->AddPlaceholderChunk("selector");
2543 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
Douglas Gregor78a21012010-01-14 16:01:26 +00002544 Results.AddResult(Result(Pattern));
Douglas Gregorbc7c5e42009-12-07 09:51:25 +00002545}
2546
Douglas Gregorf98e6a22010-01-13 23:51:12 +00002547static void AddObjCStatementResults(ResultBuilder &Results, bool NeedAt) {
Douglas Gregorbc7c5e42009-12-07 09:51:25 +00002548 typedef CodeCompleteConsumer::Result Result;
Douglas Gregorbc7c5e42009-12-07 09:51:25 +00002549 CodeCompletionString *Pattern = 0;
Douglas Gregorf1934162010-01-13 21:24:21 +00002550
Douglas Gregorbc7c5e42009-12-07 09:51:25 +00002551 // @try { statements } @catch ( declaration ) { statements } @finally
2552 // { statements }
2553 Pattern = new CodeCompletionString;
Douglas Gregorf1934162010-01-13 21:24:21 +00002554 Pattern->AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt,try));
Douglas Gregorbc7c5e42009-12-07 09:51:25 +00002555 Pattern->AddChunk(CodeCompletionString::CK_LeftBrace);
2556 Pattern->AddPlaceholderChunk("statements");
2557 Pattern->AddChunk(CodeCompletionString::CK_RightBrace);
2558 Pattern->AddTextChunk("@catch");
2559 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
2560 Pattern->AddPlaceholderChunk("parameter");
2561 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
2562 Pattern->AddChunk(CodeCompletionString::CK_LeftBrace);
2563 Pattern->AddPlaceholderChunk("statements");
2564 Pattern->AddChunk(CodeCompletionString::CK_RightBrace);
2565 Pattern->AddTextChunk("@finally");
2566 Pattern->AddChunk(CodeCompletionString::CK_LeftBrace);
2567 Pattern->AddPlaceholderChunk("statements");
2568 Pattern->AddChunk(CodeCompletionString::CK_RightBrace);
Douglas Gregor78a21012010-01-14 16:01:26 +00002569 Results.AddResult(Result(Pattern));
Douglas Gregorf1934162010-01-13 21:24:21 +00002570
Douglas Gregorbc7c5e42009-12-07 09:51:25 +00002571 // @throw
2572 Pattern = new CodeCompletionString;
Douglas Gregorf1934162010-01-13 21:24:21 +00002573 Pattern->AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt,throw));
Douglas Gregor6a803932010-01-12 06:38:28 +00002574 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
Douglas Gregorbc7c5e42009-12-07 09:51:25 +00002575 Pattern->AddPlaceholderChunk("expression");
Douglas Gregor78a21012010-01-14 16:01:26 +00002576 Results.AddResult(Result(Pattern));
Douglas Gregorf1934162010-01-13 21:24:21 +00002577
Douglas Gregorbc7c5e42009-12-07 09:51:25 +00002578 // @synchronized ( expression ) { statements }
2579 Pattern = new CodeCompletionString;
Douglas Gregorf1934162010-01-13 21:24:21 +00002580 Pattern->AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt,synchronized));
Douglas Gregor6a803932010-01-12 06:38:28 +00002581 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
Douglas Gregorbc7c5e42009-12-07 09:51:25 +00002582 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
2583 Pattern->AddPlaceholderChunk("expression");
2584 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
2585 Pattern->AddChunk(CodeCompletionString::CK_LeftBrace);
2586 Pattern->AddPlaceholderChunk("statements");
2587 Pattern->AddChunk(CodeCompletionString::CK_RightBrace);
Douglas Gregor78a21012010-01-14 16:01:26 +00002588 Results.AddResult(Result(Pattern));
Douglas Gregorf1934162010-01-13 21:24:21 +00002589}
Douglas Gregorbc7c5e42009-12-07 09:51:25 +00002590
Douglas Gregorf98e6a22010-01-13 23:51:12 +00002591static void AddObjCVisibilityResults(const LangOptions &LangOpts,
Douglas Gregor48d46252010-01-13 21:54:15 +00002592 ResultBuilder &Results,
2593 bool NeedAt) {
Douglas Gregorf1934162010-01-13 21:24:21 +00002594 typedef CodeCompleteConsumer::Result Result;
Douglas Gregor78a21012010-01-14 16:01:26 +00002595 Results.AddResult(Result(OBJC_AT_KEYWORD_NAME(NeedAt,private)));
2596 Results.AddResult(Result(OBJC_AT_KEYWORD_NAME(NeedAt,protected)));
2597 Results.AddResult(Result(OBJC_AT_KEYWORD_NAME(NeedAt,public)));
Douglas Gregor48d46252010-01-13 21:54:15 +00002598 if (LangOpts.ObjC2)
Douglas Gregor78a21012010-01-14 16:01:26 +00002599 Results.AddResult(Result(OBJC_AT_KEYWORD_NAME(NeedAt,package)));
Douglas Gregor48d46252010-01-13 21:54:15 +00002600}
2601
2602void Sema::CodeCompleteObjCAtVisibility(Scope *S) {
2603 ResultBuilder Results(*this);
2604 Results.EnterNewScope();
Douglas Gregorf98e6a22010-01-13 23:51:12 +00002605 AddObjCVisibilityResults(getLangOptions(), Results, false);
Douglas Gregor48d46252010-01-13 21:54:15 +00002606 Results.ExitScope();
2607 HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
2608}
2609
2610void Sema::CodeCompleteObjCAtStatement(Scope *S) {
Douglas Gregorf1934162010-01-13 21:24:21 +00002611 ResultBuilder Results(*this);
2612 Results.EnterNewScope();
Douglas Gregorf98e6a22010-01-13 23:51:12 +00002613 AddObjCStatementResults(Results, false);
2614 AddObjCExpressionResults(Results, false);
Douglas Gregorbc7c5e42009-12-07 09:51:25 +00002615 Results.ExitScope();
2616 HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
2617}
2618
2619void Sema::CodeCompleteObjCAtExpression(Scope *S) {
2620 ResultBuilder Results(*this);
2621 Results.EnterNewScope();
Douglas Gregorf98e6a22010-01-13 23:51:12 +00002622 AddObjCExpressionResults(Results, false);
Douglas Gregorbc7c5e42009-12-07 09:51:25 +00002623 Results.ExitScope();
2624 HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
2625}
2626
Douglas Gregore6078da2009-11-19 00:14:45 +00002627/// \brief Determine whether the addition of the given flag to an Objective-C
2628/// property's attributes will cause a conflict.
2629static bool ObjCPropertyFlagConflicts(unsigned Attributes, unsigned NewFlag) {
2630 // Check if we've already added this flag.
2631 if (Attributes & NewFlag)
2632 return true;
2633
2634 Attributes |= NewFlag;
2635
2636 // Check for collisions with "readonly".
2637 if ((Attributes & ObjCDeclSpec::DQ_PR_readonly) &&
2638 (Attributes & (ObjCDeclSpec::DQ_PR_readwrite |
2639 ObjCDeclSpec::DQ_PR_assign |
2640 ObjCDeclSpec::DQ_PR_copy |
2641 ObjCDeclSpec::DQ_PR_retain)))
2642 return true;
2643
2644 // Check for more than one of { assign, copy, retain }.
2645 unsigned AssignCopyRetMask = Attributes & (ObjCDeclSpec::DQ_PR_assign |
2646 ObjCDeclSpec::DQ_PR_copy |
2647 ObjCDeclSpec::DQ_PR_retain);
2648 if (AssignCopyRetMask &&
2649 AssignCopyRetMask != ObjCDeclSpec::DQ_PR_assign &&
2650 AssignCopyRetMask != ObjCDeclSpec::DQ_PR_copy &&
2651 AssignCopyRetMask != ObjCDeclSpec::DQ_PR_retain)
2652 return true;
2653
2654 return false;
2655}
2656
Douglas Gregor36029f42009-11-18 23:08:07 +00002657void Sema::CodeCompleteObjCPropertyFlags(Scope *S, ObjCDeclSpec &ODS) {
Steve Naroff936354c2009-10-08 21:55:05 +00002658 if (!CodeCompleter)
2659 return;
Douglas Gregor1b605f72009-11-19 01:08:35 +00002660
Steve Naroff936354c2009-10-08 21:55:05 +00002661 unsigned Attributes = ODS.getPropertyAttributes();
2662
2663 typedef CodeCompleteConsumer::Result Result;
2664 ResultBuilder Results(*this);
2665 Results.EnterNewScope();
Douglas Gregore6078da2009-11-19 00:14:45 +00002666 if (!ObjCPropertyFlagConflicts(Attributes, ObjCDeclSpec::DQ_PR_readonly))
Douglas Gregor78a21012010-01-14 16:01:26 +00002667 Results.AddResult(CodeCompleteConsumer::Result("readonly"));
Douglas Gregore6078da2009-11-19 00:14:45 +00002668 if (!ObjCPropertyFlagConflicts(Attributes, ObjCDeclSpec::DQ_PR_assign))
Douglas Gregor78a21012010-01-14 16:01:26 +00002669 Results.AddResult(CodeCompleteConsumer::Result("assign"));
Douglas Gregore6078da2009-11-19 00:14:45 +00002670 if (!ObjCPropertyFlagConflicts(Attributes, ObjCDeclSpec::DQ_PR_readwrite))
Douglas Gregor78a21012010-01-14 16:01:26 +00002671 Results.AddResult(CodeCompleteConsumer::Result("readwrite"));
Douglas Gregore6078da2009-11-19 00:14:45 +00002672 if (!ObjCPropertyFlagConflicts(Attributes, ObjCDeclSpec::DQ_PR_retain))
Douglas Gregor78a21012010-01-14 16:01:26 +00002673 Results.AddResult(CodeCompleteConsumer::Result("retain"));
Douglas Gregore6078da2009-11-19 00:14:45 +00002674 if (!ObjCPropertyFlagConflicts(Attributes, ObjCDeclSpec::DQ_PR_copy))
Douglas Gregor78a21012010-01-14 16:01:26 +00002675 Results.AddResult(CodeCompleteConsumer::Result("copy"));
Douglas Gregore6078da2009-11-19 00:14:45 +00002676 if (!ObjCPropertyFlagConflicts(Attributes, ObjCDeclSpec::DQ_PR_nonatomic))
Douglas Gregor78a21012010-01-14 16:01:26 +00002677 Results.AddResult(CodeCompleteConsumer::Result("nonatomic"));
Douglas Gregore6078da2009-11-19 00:14:45 +00002678 if (!ObjCPropertyFlagConflicts(Attributes, ObjCDeclSpec::DQ_PR_setter)) {
Douglas Gregor45f83ee2009-11-19 00:01:57 +00002679 CodeCompletionString *Setter = new CodeCompletionString;
2680 Setter->AddTypedTextChunk("setter");
2681 Setter->AddTextChunk(" = ");
2682 Setter->AddPlaceholderChunk("method");
Douglas Gregor78a21012010-01-14 16:01:26 +00002683 Results.AddResult(CodeCompleteConsumer::Result(Setter));
Douglas Gregor45f83ee2009-11-19 00:01:57 +00002684 }
Douglas Gregore6078da2009-11-19 00:14:45 +00002685 if (!ObjCPropertyFlagConflicts(Attributes, ObjCDeclSpec::DQ_PR_getter)) {
Douglas Gregor45f83ee2009-11-19 00:01:57 +00002686 CodeCompletionString *Getter = new CodeCompletionString;
2687 Getter->AddTypedTextChunk("getter");
2688 Getter->AddTextChunk(" = ");
2689 Getter->AddPlaceholderChunk("method");
Douglas Gregor78a21012010-01-14 16:01:26 +00002690 Results.AddResult(CodeCompleteConsumer::Result(Getter));
Douglas Gregor45f83ee2009-11-19 00:01:57 +00002691 }
Steve Naroff936354c2009-10-08 21:55:05 +00002692 Results.ExitScope();
Daniel Dunbar242ea9a2009-11-13 08:58:20 +00002693 HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
Steve Naroff936354c2009-10-08 21:55:05 +00002694}
Steve Naroffeae65032009-11-07 02:08:14 +00002695
Douglas Gregorc8537c52009-11-19 07:41:15 +00002696/// \brief Descripts the kind of Objective-C method that we want to find
2697/// via code completion.
2698enum ObjCMethodKind {
2699 MK_Any, //< Any kind of method, provided it means other specified criteria.
2700 MK_ZeroArgSelector, //< Zero-argument (unary) selector.
2701 MK_OneArgSelector //< One-argument selector.
2702};
2703
2704static bool isAcceptableObjCMethod(ObjCMethodDecl *Method,
2705 ObjCMethodKind WantKind,
2706 IdentifierInfo **SelIdents,
2707 unsigned NumSelIdents) {
2708 Selector Sel = Method->getSelector();
2709 if (NumSelIdents > Sel.getNumArgs())
2710 return false;
2711
2712 switch (WantKind) {
2713 case MK_Any: break;
2714 case MK_ZeroArgSelector: return Sel.isUnarySelector();
2715 case MK_OneArgSelector: return Sel.getNumArgs() == 1;
2716 }
2717
2718 for (unsigned I = 0; I != NumSelIdents; ++I)
2719 if (SelIdents[I] != Sel.getIdentifierInfoForSlot(I))
2720 return false;
2721
2722 return true;
2723}
2724
Douglas Gregorbab2b3c2009-11-17 23:22:23 +00002725/// \brief Add all of the Objective-C methods in the given Objective-C
2726/// container to the set of results.
2727///
2728/// The container will be a class, protocol, category, or implementation of
2729/// any of the above. This mether will recurse to include methods from
2730/// the superclasses of classes along with their categories, protocols, and
2731/// implementations.
2732///
2733/// \param Container the container in which we'll look to find methods.
2734///
2735/// \param WantInstance whether to add instance methods (only); if false, this
2736/// routine will add factory methods (only).
2737///
2738/// \param CurContext the context in which we're performing the lookup that
2739/// finds methods.
2740///
2741/// \param Results the structure into which we'll add results.
2742static void AddObjCMethods(ObjCContainerDecl *Container,
2743 bool WantInstanceMethods,
Douglas Gregorc8537c52009-11-19 07:41:15 +00002744 ObjCMethodKind WantKind,
Douglas Gregor1b605f72009-11-19 01:08:35 +00002745 IdentifierInfo **SelIdents,
2746 unsigned NumSelIdents,
Douglas Gregorbab2b3c2009-11-17 23:22:23 +00002747 DeclContext *CurContext,
2748 ResultBuilder &Results) {
2749 typedef CodeCompleteConsumer::Result Result;
2750 for (ObjCContainerDecl::method_iterator M = Container->meth_begin(),
2751 MEnd = Container->meth_end();
2752 M != MEnd; ++M) {
Douglas Gregor1b605f72009-11-19 01:08:35 +00002753 if ((*M)->isInstanceMethod() == WantInstanceMethods) {
2754 // Check whether the selector identifiers we've been given are a
2755 // subset of the identifiers for this particular method.
Douglas Gregorc8537c52009-11-19 07:41:15 +00002756 if (!isAcceptableObjCMethod(*M, WantKind, SelIdents, NumSelIdents))
Douglas Gregor1b605f72009-11-19 01:08:35 +00002757 continue;
Douglas Gregorc8537c52009-11-19 07:41:15 +00002758
Douglas Gregor1b605f72009-11-19 01:08:35 +00002759 Result R = Result(*M, 0);
2760 R.StartParameter = NumSelIdents;
Douglas Gregorc8537c52009-11-19 07:41:15 +00002761 R.AllParametersAreInformative = (WantKind != MK_Any);
Douglas Gregor1b605f72009-11-19 01:08:35 +00002762 Results.MaybeAddResult(R, CurContext);
2763 }
Douglas Gregorbab2b3c2009-11-17 23:22:23 +00002764 }
2765
2766 ObjCInterfaceDecl *IFace = dyn_cast<ObjCInterfaceDecl>(Container);
2767 if (!IFace)
2768 return;
2769
2770 // Add methods in protocols.
2771 const ObjCList<ObjCProtocolDecl> &Protocols= IFace->getReferencedProtocols();
2772 for (ObjCList<ObjCProtocolDecl>::iterator I = Protocols.begin(),
2773 E = Protocols.end();
2774 I != E; ++I)
Douglas Gregorc8537c52009-11-19 07:41:15 +00002775 AddObjCMethods(*I, WantInstanceMethods, WantKind, SelIdents, NumSelIdents,
Douglas Gregor1b605f72009-11-19 01:08:35 +00002776 CurContext, Results);
Douglas Gregorbab2b3c2009-11-17 23:22:23 +00002777
2778 // Add methods in categories.
2779 for (ObjCCategoryDecl *CatDecl = IFace->getCategoryList(); CatDecl;
2780 CatDecl = CatDecl->getNextClassCategory()) {
Douglas Gregorc8537c52009-11-19 07:41:15 +00002781 AddObjCMethods(CatDecl, WantInstanceMethods, WantKind, SelIdents,
2782 NumSelIdents, CurContext, Results);
Douglas Gregorbab2b3c2009-11-17 23:22:23 +00002783
2784 // Add a categories protocol methods.
2785 const ObjCList<ObjCProtocolDecl> &Protocols
2786 = CatDecl->getReferencedProtocols();
2787 for (ObjCList<ObjCProtocolDecl>::iterator I = Protocols.begin(),
2788 E = Protocols.end();
2789 I != E; ++I)
Douglas Gregorc8537c52009-11-19 07:41:15 +00002790 AddObjCMethods(*I, WantInstanceMethods, WantKind, SelIdents,
2791 NumSelIdents, CurContext, Results);
Douglas Gregorbab2b3c2009-11-17 23:22:23 +00002792
2793 // Add methods in category implementations.
2794 if (ObjCCategoryImplDecl *Impl = CatDecl->getImplementation())
Douglas Gregorc8537c52009-11-19 07:41:15 +00002795 AddObjCMethods(Impl, WantInstanceMethods, WantKind, SelIdents,
2796 NumSelIdents, CurContext, Results);
Douglas Gregorbab2b3c2009-11-17 23:22:23 +00002797 }
2798
2799 // Add methods in superclass.
2800 if (IFace->getSuperClass())
Douglas Gregorc8537c52009-11-19 07:41:15 +00002801 AddObjCMethods(IFace->getSuperClass(), WantInstanceMethods, WantKind,
2802 SelIdents, NumSelIdents, CurContext, Results);
Douglas Gregorbab2b3c2009-11-17 23:22:23 +00002803
2804 // Add methods in our implementation, if any.
2805 if (ObjCImplementationDecl *Impl = IFace->getImplementation())
Douglas Gregorc8537c52009-11-19 07:41:15 +00002806 AddObjCMethods(Impl, WantInstanceMethods, WantKind, SelIdents,
2807 NumSelIdents, CurContext, Results);
2808}
2809
2810
2811void Sema::CodeCompleteObjCPropertyGetter(Scope *S, DeclPtrTy ClassDecl,
2812 DeclPtrTy *Methods,
2813 unsigned NumMethods) {
2814 typedef CodeCompleteConsumer::Result Result;
2815
2816 // Try to find the interface where getters might live.
2817 ObjCInterfaceDecl *Class
2818 = dyn_cast_or_null<ObjCInterfaceDecl>(ClassDecl.getAs<Decl>());
2819 if (!Class) {
2820 if (ObjCCategoryDecl *Category
2821 = dyn_cast_or_null<ObjCCategoryDecl>(ClassDecl.getAs<Decl>()))
2822 Class = Category->getClassInterface();
2823
2824 if (!Class)
2825 return;
2826 }
2827
2828 // Find all of the potential getters.
2829 ResultBuilder Results(*this);
2830 Results.EnterNewScope();
2831
2832 // FIXME: We need to do this because Objective-C methods don't get
2833 // pushed into DeclContexts early enough. Argh!
2834 for (unsigned I = 0; I != NumMethods; ++I) {
2835 if (ObjCMethodDecl *Method
2836 = dyn_cast_or_null<ObjCMethodDecl>(Methods[I].getAs<Decl>()))
2837 if (Method->isInstanceMethod() &&
2838 isAcceptableObjCMethod(Method, MK_ZeroArgSelector, 0, 0)) {
2839 Result R = Result(Method, 0);
2840 R.AllParametersAreInformative = true;
2841 Results.MaybeAddResult(R, CurContext);
2842 }
2843 }
2844
2845 AddObjCMethods(Class, true, MK_ZeroArgSelector, 0, 0, CurContext, Results);
2846 Results.ExitScope();
2847 HandleCodeCompleteResults(this, CodeCompleter,Results.data(),Results.size());
2848}
2849
2850void Sema::CodeCompleteObjCPropertySetter(Scope *S, DeclPtrTy ObjCImplDecl,
2851 DeclPtrTy *Methods,
2852 unsigned NumMethods) {
2853 typedef CodeCompleteConsumer::Result Result;
2854
2855 // Try to find the interface where setters might live.
2856 ObjCInterfaceDecl *Class
2857 = dyn_cast_or_null<ObjCInterfaceDecl>(ObjCImplDecl.getAs<Decl>());
2858 if (!Class) {
2859 if (ObjCCategoryDecl *Category
2860 = dyn_cast_or_null<ObjCCategoryDecl>(ObjCImplDecl.getAs<Decl>()))
2861 Class = Category->getClassInterface();
2862
2863 if (!Class)
2864 return;
2865 }
2866
2867 // Find all of the potential getters.
2868 ResultBuilder Results(*this);
2869 Results.EnterNewScope();
2870
2871 // FIXME: We need to do this because Objective-C methods don't get
2872 // pushed into DeclContexts early enough. Argh!
2873 for (unsigned I = 0; I != NumMethods; ++I) {
2874 if (ObjCMethodDecl *Method
2875 = dyn_cast_or_null<ObjCMethodDecl>(Methods[I].getAs<Decl>()))
2876 if (Method->isInstanceMethod() &&
2877 isAcceptableObjCMethod(Method, MK_OneArgSelector, 0, 0)) {
2878 Result R = Result(Method, 0);
2879 R.AllParametersAreInformative = true;
2880 Results.MaybeAddResult(R, CurContext);
2881 }
2882 }
2883
2884 AddObjCMethods(Class, true, MK_OneArgSelector, 0, 0, CurContext, Results);
2885
2886 Results.ExitScope();
2887 HandleCodeCompleteResults(this, CodeCompleter,Results.data(),Results.size());
Douglas Gregorbab2b3c2009-11-17 23:22:23 +00002888}
2889
Douglas Gregor9d2ddb22010-04-06 19:22:33 +00002890/// \brief When we have an expression with type "id", we may assume
2891/// that it has some more-specific class type based on knowledge of
2892/// common uses of Objective-C. This routine returns that class type,
2893/// or NULL if no better result could be determined.
2894static ObjCInterfaceDecl *GetAssumedMessageSendExprType(Expr *E) {
2895 ObjCMessageExpr *Msg = dyn_cast<ObjCMessageExpr>(E);
2896 if (!Msg)
2897 return 0;
2898
2899 Selector Sel = Msg->getSelector();
2900 if (Sel.isNull())
2901 return 0;
2902
2903 IdentifierInfo *Id = Sel.getIdentifierInfoForSlot(0);
2904 if (!Id)
2905 return 0;
2906
2907 ObjCMethodDecl *Method = Msg->getMethodDecl();
2908 if (!Method)
2909 return 0;
2910
2911 // Determine the class that we're sending the message to.
Douglas Gregor9a129192010-04-21 00:45:42 +00002912 ObjCInterfaceDecl *IFace = 0;
2913 switch (Msg->getReceiverKind()) {
2914 case ObjCMessageExpr::Class:
2915 if (const ObjCInterfaceType *IFaceType
2916 = Msg->getClassReceiver()->getAs<ObjCInterfaceType>())
2917 IFace = IFaceType->getDecl();
2918 break;
2919
2920 case ObjCMessageExpr::Instance: {
2921 QualType T = Msg->getInstanceReceiver()->getType();
2922 if (const ObjCObjectPointerType *Ptr = T->getAs<ObjCObjectPointerType>())
2923 IFace = Ptr->getInterfaceDecl();
2924 break;
2925 }
2926
2927 case ObjCMessageExpr::SuperInstance:
2928 case ObjCMessageExpr::SuperClass:
2929 break;
Douglas Gregor9d2ddb22010-04-06 19:22:33 +00002930 }
2931
2932 if (!IFace)
2933 return 0;
2934
2935 ObjCInterfaceDecl *Super = IFace->getSuperClass();
2936 if (Method->isInstanceMethod())
2937 return llvm::StringSwitch<ObjCInterfaceDecl *>(Id->getName())
2938 .Case("retain", IFace)
2939 .Case("autorelease", IFace)
2940 .Case("copy", IFace)
2941 .Case("copyWithZone", IFace)
2942 .Case("mutableCopy", IFace)
2943 .Case("mutableCopyWithZone", IFace)
2944 .Case("awakeFromCoder", IFace)
2945 .Case("replacementObjectFromCoder", IFace)
2946 .Case("class", IFace)
2947 .Case("classForCoder", IFace)
2948 .Case("superclass", Super)
2949 .Default(0);
2950
2951 return llvm::StringSwitch<ObjCInterfaceDecl *>(Id->getName())
2952 .Case("new", IFace)
2953 .Case("alloc", IFace)
2954 .Case("allocWithZone", IFace)
2955 .Case("class", IFace)
2956 .Case("superclass", Super)
2957 .Default(0);
2958}
2959
Douglas Gregor0c78ad92010-04-21 19:57:20 +00002960void Sema::CodeCompleteObjCSuperMessage(Scope *S, SourceLocation SuperLoc,
2961 IdentifierInfo **SelIdents,
2962 unsigned NumSelIdents) {
2963 ObjCInterfaceDecl *CDecl = 0;
2964 if (ObjCMethodDecl *CurMethod = getCurMethodDecl()) {
2965 // Figure out which interface we're in.
2966 CDecl = CurMethod->getClassInterface();
2967 if (!CDecl)
2968 return;
2969
2970 // Find the superclass of this class.
2971 CDecl = CDecl->getSuperClass();
2972 if (!CDecl)
2973 return;
2974
2975 if (CurMethod->isInstanceMethod()) {
2976 // We are inside an instance method, which means that the message
2977 // send [super ...] is actually calling an instance method on the
2978 // current object. Build the super expression and handle this like
2979 // an instance method.
2980 QualType SuperTy = Context.getObjCInterfaceType(CDecl);
2981 SuperTy = Context.getObjCObjectPointerType(SuperTy);
2982 OwningExprResult Super
2983 = Owned(new (Context) ObjCSuperExpr(SuperLoc, SuperTy));
2984 return CodeCompleteObjCInstanceMessage(S, (Expr *)Super.get(),
2985 SelIdents, NumSelIdents);
2986 }
2987
2988 // Fall through to send to the superclass in CDecl.
2989 } else {
2990 // "super" may be the name of a type or variable. Figure out which
2991 // it is.
2992 IdentifierInfo *Super = &Context.Idents.get("super");
2993 NamedDecl *ND = LookupSingleName(S, Super, SuperLoc,
2994 LookupOrdinaryName);
2995 if ((CDecl = dyn_cast_or_null<ObjCInterfaceDecl>(ND))) {
2996 // "super" names an interface. Use it.
2997 } else if (TypeDecl *TD = dyn_cast_or_null<TypeDecl>(ND)) {
2998 if (const ObjCInterfaceType *Iface
2999 = Context.getTypeDeclType(TD)->getAs<ObjCInterfaceType>())
3000 CDecl = Iface->getDecl();
3001 } else if (ND && isa<UnresolvedUsingTypenameDecl>(ND)) {
3002 // "super" names an unresolved type; we can't be more specific.
3003 } else {
3004 // Assume that "super" names some kind of value and parse that way.
3005 CXXScopeSpec SS;
3006 UnqualifiedId id;
3007 id.setIdentifier(Super, SuperLoc);
3008 OwningExprResult SuperExpr = ActOnIdExpression(S, SS, id, false, false);
3009 return CodeCompleteObjCInstanceMessage(S, (Expr *)SuperExpr.get(),
3010 SelIdents, NumSelIdents);
3011 }
3012
3013 // Fall through
3014 }
3015
3016 TypeTy *Receiver = 0;
3017 if (CDecl)
3018 Receiver = Context.getObjCInterfaceType(CDecl).getAsOpaquePtr();
3019 return CodeCompleteObjCClassMessage(S, Receiver, SelIdents,
3020 NumSelIdents);
3021}
3022
3023void Sema::CodeCompleteObjCClassMessage(Scope *S, TypeTy *Receiver,
Douglas Gregor1b605f72009-11-19 01:08:35 +00003024 IdentifierInfo **SelIdents,
3025 unsigned NumSelIdents) {
Steve Naroffeae65032009-11-07 02:08:14 +00003026 typedef CodeCompleteConsumer::Result Result;
Douglas Gregor8ce33212009-11-17 17:59:40 +00003027 ObjCInterfaceDecl *CDecl = 0;
3028
Douglas Gregor8ce33212009-11-17 17:59:40 +00003029 // If the given name refers to an interface type, retrieve the
3030 // corresponding declaration.
Douglas Gregor0c78ad92010-04-21 19:57:20 +00003031 if (Receiver) {
3032 QualType T = GetTypeFromParser(Receiver, 0);
3033 if (!T.isNull())
3034 if (const ObjCInterfaceType *Interface = T->getAs<ObjCInterfaceType>())
3035 CDecl = Interface->getDecl();
Douglas Gregor8ce33212009-11-17 17:59:40 +00003036 }
3037
Douglas Gregorbab2b3c2009-11-17 23:22:23 +00003038 // Add all of the factory methods in this Objective-C class, its protocols,
3039 // superclasses, categories, implementation, etc.
Steve Naroffeae65032009-11-07 02:08:14 +00003040 ResultBuilder Results(*this);
3041 Results.EnterNewScope();
Douglas Gregor6285f752010-04-06 16:40:00 +00003042
3043 if (CDecl)
3044 AddObjCMethods(CDecl, false, MK_Any, SelIdents, NumSelIdents, CurContext,
3045 Results);
Douglas Gregor0c78ad92010-04-21 19:57:20 +00003046 else {
Douglas Gregor6285f752010-04-06 16:40:00 +00003047 // We're messaging "id" as a type; provide all class/factory methods.
3048
Douglas Gregord720daf2010-04-06 17:30:22 +00003049 // If we have an external source, load the entire class method
3050 // pool from the PCH file.
3051 if (ExternalSource) {
3052 for (uint32_t I = 0, N = ExternalSource->GetNumKnownSelectors(); I != N;
3053 ++I) {
3054 Selector Sel = ExternalSource->GetSelector(I);
3055 if (Sel.isNull() || FactoryMethodPool.count(Sel) ||
3056 InstanceMethodPool.count(Sel))
3057 continue;
3058
3059 ReadMethodPool(Sel, /*isInstance=*/false);
3060 }
3061 }
3062
Douglas Gregor6285f752010-04-06 16:40:00 +00003063 for (llvm::DenseMap<Selector, ObjCMethodList>::iterator
3064 M = FactoryMethodPool.begin(),
3065 MEnd = FactoryMethodPool.end();
3066 M != MEnd;
3067 ++M) {
Douglas Gregord720daf2010-04-06 17:30:22 +00003068 for (ObjCMethodList *MethList = &M->second; MethList && MethList->Method;
Douglas Gregor6285f752010-04-06 16:40:00 +00003069 MethList = MethList->Next) {
3070 if (!isAcceptableObjCMethod(MethList->Method, MK_Any, SelIdents,
3071 NumSelIdents))
3072 continue;
3073
3074 Result R(MethList->Method, 0);
3075 R.StartParameter = NumSelIdents;
3076 R.AllParametersAreInformative = false;
3077 Results.MaybeAddResult(R, CurContext);
3078 }
3079 }
3080 }
3081
Steve Naroffeae65032009-11-07 02:08:14 +00003082 Results.ExitScope();
Douglas Gregorbab2b3c2009-11-17 23:22:23 +00003083
Steve Naroffeae65032009-11-07 02:08:14 +00003084 // This also suppresses remaining diagnostics.
Daniel Dunbar242ea9a2009-11-13 08:58:20 +00003085 HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
Steve Naroffeae65032009-11-07 02:08:14 +00003086}
3087
Douglas Gregor1b605f72009-11-19 01:08:35 +00003088void Sema::CodeCompleteObjCInstanceMessage(Scope *S, ExprTy *Receiver,
3089 IdentifierInfo **SelIdents,
3090 unsigned NumSelIdents) {
Steve Naroffeae65032009-11-07 02:08:14 +00003091 typedef CodeCompleteConsumer::Result Result;
Steve Naroffeae65032009-11-07 02:08:14 +00003092
3093 Expr *RecExpr = static_cast<Expr *>(Receiver);
Steve Naroffeae65032009-11-07 02:08:14 +00003094
Douglas Gregorbab2b3c2009-11-17 23:22:23 +00003095 // If necessary, apply function/array conversion to the receiver.
3096 // C99 6.7.5.3p[7,8].
Douglas Gregorb92a1562010-02-03 00:27:59 +00003097 DefaultFunctionArrayLvalueConversion(RecExpr);
Douglas Gregorbab2b3c2009-11-17 23:22:23 +00003098 QualType ReceiverType = RecExpr->getType();
Steve Naroffeae65032009-11-07 02:08:14 +00003099
Douglas Gregorbab2b3c2009-11-17 23:22:23 +00003100 // Build the set of methods we can see.
3101 ResultBuilder Results(*this);
3102 Results.EnterNewScope();
Douglas Gregor9d2ddb22010-04-06 19:22:33 +00003103
3104 // If we're messaging an expression with type "id" or "Class", check
3105 // whether we know something special about the receiver that allows
3106 // us to assume a more-specific receiver type.
3107 if (ReceiverType->isObjCIdType() || ReceiverType->isObjCClassType())
3108 if (ObjCInterfaceDecl *IFace = GetAssumedMessageSendExprType(RecExpr))
3109 ReceiverType = Context.getObjCObjectPointerType(
3110 Context.getObjCInterfaceType(IFace));
Douglas Gregorbab2b3c2009-11-17 23:22:23 +00003111
Douglas Gregora3329fa2009-11-18 00:06:18 +00003112 // Handle messages to Class. This really isn't a message to an instance
3113 // method, so we treat it the same way we would treat a message send to a
3114 // class method.
3115 if (ReceiverType->isObjCClassType() ||
3116 ReceiverType->isObjCQualifiedClassType()) {
3117 if (ObjCMethodDecl *CurMethod = getCurMethodDecl()) {
3118 if (ObjCInterfaceDecl *ClassDecl = CurMethod->getClassInterface())
Douglas Gregorc8537c52009-11-19 07:41:15 +00003119 AddObjCMethods(ClassDecl, false, MK_Any, SelIdents, NumSelIdents,
3120 CurContext, Results);
Douglas Gregora3329fa2009-11-18 00:06:18 +00003121 }
3122 }
3123 // Handle messages to a qualified ID ("id<foo>").
3124 else if (const ObjCObjectPointerType *QualID
3125 = ReceiverType->getAsObjCQualifiedIdType()) {
3126 // Search protocols for instance methods.
3127 for (ObjCObjectPointerType::qual_iterator I = QualID->qual_begin(),
3128 E = QualID->qual_end();
3129 I != E; ++I)
Douglas Gregorc8537c52009-11-19 07:41:15 +00003130 AddObjCMethods(*I, true, MK_Any, SelIdents, NumSelIdents, CurContext,
3131 Results);
Douglas Gregora3329fa2009-11-18 00:06:18 +00003132 }
3133 // Handle messages to a pointer to interface type.
3134 else if (const ObjCObjectPointerType *IFacePtr
3135 = ReceiverType->getAsObjCInterfacePointerType()) {
3136 // Search the class, its superclasses, etc., for instance methods.
Douglas Gregorc8537c52009-11-19 07:41:15 +00003137 AddObjCMethods(IFacePtr->getInterfaceDecl(), true, MK_Any, SelIdents,
3138 NumSelIdents, CurContext, Results);
Douglas Gregora3329fa2009-11-18 00:06:18 +00003139
3140 // Search protocols for instance methods.
3141 for (ObjCObjectPointerType::qual_iterator I = IFacePtr->qual_begin(),
3142 E = IFacePtr->qual_end();
3143 I != E; ++I)
Douglas Gregorc8537c52009-11-19 07:41:15 +00003144 AddObjCMethods(*I, true, MK_Any, SelIdents, NumSelIdents, CurContext,
3145 Results);
Douglas Gregora3329fa2009-11-18 00:06:18 +00003146 }
Douglas Gregor6285f752010-04-06 16:40:00 +00003147 // Handle messages to "id".
3148 else if (ReceiverType->isObjCIdType()) {
Douglas Gregord720daf2010-04-06 17:30:22 +00003149 // We're messaging "id", so provide all instance methods we know
3150 // about as code-completion results.
3151
3152 // If we have an external source, load the entire class method
3153 // pool from the PCH file.
3154 if (ExternalSource) {
3155 for (uint32_t I = 0, N = ExternalSource->GetNumKnownSelectors(); I != N;
3156 ++I) {
3157 Selector Sel = ExternalSource->GetSelector(I);
3158 if (Sel.isNull() || InstanceMethodPool.count(Sel) ||
3159 FactoryMethodPool.count(Sel))
3160 continue;
3161
3162 ReadMethodPool(Sel, /*isInstance=*/true);
3163 }
3164 }
3165
Douglas Gregor6285f752010-04-06 16:40:00 +00003166 for (llvm::DenseMap<Selector, ObjCMethodList>::iterator
3167 M = InstanceMethodPool.begin(),
3168 MEnd = InstanceMethodPool.end();
3169 M != MEnd;
3170 ++M) {
Douglas Gregord720daf2010-04-06 17:30:22 +00003171 for (ObjCMethodList *MethList = &M->second; MethList && MethList->Method;
Douglas Gregor6285f752010-04-06 16:40:00 +00003172 MethList = MethList->Next) {
3173 if (!isAcceptableObjCMethod(MethList->Method, MK_Any, SelIdents,
3174 NumSelIdents))
3175 continue;
3176
3177 Result R(MethList->Method, 0);
3178 R.StartParameter = NumSelIdents;
3179 R.AllParametersAreInformative = false;
3180 Results.MaybeAddResult(R, CurContext);
3181 }
3182 }
3183 }
3184
Steve Naroffeae65032009-11-07 02:08:14 +00003185 Results.ExitScope();
Daniel Dunbar242ea9a2009-11-13 08:58:20 +00003186 HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
Steve Naroffeae65032009-11-07 02:08:14 +00003187}
Douglas Gregorbaf69612009-11-18 04:19:12 +00003188
3189/// \brief Add all of the protocol declarations that we find in the given
3190/// (translation unit) context.
3191static void AddProtocolResults(DeclContext *Ctx, DeclContext *CurContext,
Douglas Gregor5b4671c2009-11-18 04:49:41 +00003192 bool OnlyForwardDeclarations,
Douglas Gregorbaf69612009-11-18 04:19:12 +00003193 ResultBuilder &Results) {
3194 typedef CodeCompleteConsumer::Result Result;
3195
3196 for (DeclContext::decl_iterator D = Ctx->decls_begin(),
3197 DEnd = Ctx->decls_end();
3198 D != DEnd; ++D) {
3199 // Record any protocols we find.
3200 if (ObjCProtocolDecl *Proto = dyn_cast<ObjCProtocolDecl>(*D))
Douglas Gregor5b4671c2009-11-18 04:49:41 +00003201 if (!OnlyForwardDeclarations || Proto->isForwardDecl())
Douglas Gregorfc59ce12010-01-14 16:14:35 +00003202 Results.AddResult(Result(Proto, 0), CurContext, 0, false);
Douglas Gregorbaf69612009-11-18 04:19:12 +00003203
3204 // Record any forward-declared protocols we find.
3205 if (ObjCForwardProtocolDecl *Forward
3206 = dyn_cast<ObjCForwardProtocolDecl>(*D)) {
3207 for (ObjCForwardProtocolDecl::protocol_iterator
3208 P = Forward->protocol_begin(),
3209 PEnd = Forward->protocol_end();
3210 P != PEnd; ++P)
Douglas Gregor5b4671c2009-11-18 04:49:41 +00003211 if (!OnlyForwardDeclarations || (*P)->isForwardDecl())
Douglas Gregorfc59ce12010-01-14 16:14:35 +00003212 Results.AddResult(Result(*P, 0), CurContext, 0, false);
Douglas Gregorbaf69612009-11-18 04:19:12 +00003213 }
3214 }
3215}
3216
3217void Sema::CodeCompleteObjCProtocolReferences(IdentifierLocPair *Protocols,
3218 unsigned NumProtocols) {
3219 ResultBuilder Results(*this);
3220 Results.EnterNewScope();
3221
3222 // Tell the result set to ignore all of the protocols we have
3223 // already seen.
3224 for (unsigned I = 0; I != NumProtocols; ++I)
Douglas Gregorb2ccf012010-04-15 22:33:43 +00003225 if (ObjCProtocolDecl *Protocol = LookupProtocol(Protocols[I].first,
3226 Protocols[I].second))
Douglas Gregorbaf69612009-11-18 04:19:12 +00003227 Results.Ignore(Protocol);
3228
3229 // Add all protocols.
Douglas Gregor5b4671c2009-11-18 04:49:41 +00003230 AddProtocolResults(Context.getTranslationUnitDecl(), CurContext, false,
3231 Results);
3232
3233 Results.ExitScope();
3234 HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
3235}
3236
3237void Sema::CodeCompleteObjCProtocolDecl(Scope *) {
3238 ResultBuilder Results(*this);
3239 Results.EnterNewScope();
3240
3241 // Add all protocols.
3242 AddProtocolResults(Context.getTranslationUnitDecl(), CurContext, true,
3243 Results);
Douglas Gregorbaf69612009-11-18 04:19:12 +00003244
3245 Results.ExitScope();
3246 HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
3247}
Douglas Gregor49c22a72009-11-18 16:26:39 +00003248
3249/// \brief Add all of the Objective-C interface declarations that we find in
3250/// the given (translation unit) context.
3251static void AddInterfaceResults(DeclContext *Ctx, DeclContext *CurContext,
3252 bool OnlyForwardDeclarations,
3253 bool OnlyUnimplemented,
3254 ResultBuilder &Results) {
3255 typedef CodeCompleteConsumer::Result Result;
3256
3257 for (DeclContext::decl_iterator D = Ctx->decls_begin(),
3258 DEnd = Ctx->decls_end();
3259 D != DEnd; ++D) {
3260 // Record any interfaces we find.
3261 if (ObjCInterfaceDecl *Class = dyn_cast<ObjCInterfaceDecl>(*D))
3262 if ((!OnlyForwardDeclarations || Class->isForwardDecl()) &&
3263 (!OnlyUnimplemented || !Class->getImplementation()))
Douglas Gregorfc59ce12010-01-14 16:14:35 +00003264 Results.AddResult(Result(Class, 0), CurContext, 0, false);
Douglas Gregor49c22a72009-11-18 16:26:39 +00003265
3266 // Record any forward-declared interfaces we find.
3267 if (ObjCClassDecl *Forward = dyn_cast<ObjCClassDecl>(*D)) {
3268 for (ObjCClassDecl::iterator C = Forward->begin(), CEnd = Forward->end();
3269 C != CEnd; ++C)
3270 if ((!OnlyForwardDeclarations || C->getInterface()->isForwardDecl()) &&
3271 (!OnlyUnimplemented || !C->getInterface()->getImplementation()))
Douglas Gregorfc59ce12010-01-14 16:14:35 +00003272 Results.AddResult(Result(C->getInterface(), 0), CurContext,
3273 0, false);
Douglas Gregor49c22a72009-11-18 16:26:39 +00003274 }
3275 }
3276}
3277
3278void Sema::CodeCompleteObjCInterfaceDecl(Scope *S) {
3279 ResultBuilder Results(*this);
3280 Results.EnterNewScope();
3281
3282 // Add all classes.
3283 AddInterfaceResults(Context.getTranslationUnitDecl(), CurContext, true,
3284 false, Results);
3285
3286 Results.ExitScope();
3287 HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
3288}
3289
Douglas Gregorb2ccf012010-04-15 22:33:43 +00003290void Sema::CodeCompleteObjCSuperclass(Scope *S, IdentifierInfo *ClassName,
3291 SourceLocation ClassNameLoc) {
Douglas Gregor49c22a72009-11-18 16:26:39 +00003292 ResultBuilder Results(*this);
3293 Results.EnterNewScope();
3294
3295 // Make sure that we ignore the class we're currently defining.
3296 NamedDecl *CurClass
Douglas Gregorb2ccf012010-04-15 22:33:43 +00003297 = LookupSingleName(TUScope, ClassName, ClassNameLoc, LookupOrdinaryName);
Douglas Gregor5d34fd32009-11-18 19:08:43 +00003298 if (CurClass && isa<ObjCInterfaceDecl>(CurClass))
Douglas Gregor49c22a72009-11-18 16:26:39 +00003299 Results.Ignore(CurClass);
3300
3301 // Add all classes.
3302 AddInterfaceResults(Context.getTranslationUnitDecl(), CurContext, false,
3303 false, Results);
3304
3305 Results.ExitScope();
3306 HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
3307}
3308
3309void Sema::CodeCompleteObjCImplementationDecl(Scope *S) {
3310 ResultBuilder Results(*this);
3311 Results.EnterNewScope();
3312
3313 // Add all unimplemented classes.
3314 AddInterfaceResults(Context.getTranslationUnitDecl(), CurContext, false,
3315 true, Results);
3316
3317 Results.ExitScope();
3318 HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
3319}
Douglas Gregor5d34fd32009-11-18 19:08:43 +00003320
3321void Sema::CodeCompleteObjCInterfaceCategory(Scope *S,
Douglas Gregorb2ccf012010-04-15 22:33:43 +00003322 IdentifierInfo *ClassName,
3323 SourceLocation ClassNameLoc) {
Douglas Gregor5d34fd32009-11-18 19:08:43 +00003324 typedef CodeCompleteConsumer::Result Result;
3325
3326 ResultBuilder Results(*this);
3327
3328 // Ignore any categories we find that have already been implemented by this
3329 // interface.
3330 llvm::SmallPtrSet<IdentifierInfo *, 16> CategoryNames;
3331 NamedDecl *CurClass
Douglas Gregorb2ccf012010-04-15 22:33:43 +00003332 = LookupSingleName(TUScope, ClassName, ClassNameLoc, LookupOrdinaryName);
Douglas Gregor5d34fd32009-11-18 19:08:43 +00003333 if (ObjCInterfaceDecl *Class = dyn_cast_or_null<ObjCInterfaceDecl>(CurClass))
3334 for (ObjCCategoryDecl *Category = Class->getCategoryList(); Category;
3335 Category = Category->getNextClassCategory())
3336 CategoryNames.insert(Category->getIdentifier());
3337
3338 // Add all of the categories we know about.
3339 Results.EnterNewScope();
3340 TranslationUnitDecl *TU = Context.getTranslationUnitDecl();
3341 for (DeclContext::decl_iterator D = TU->decls_begin(),
3342 DEnd = TU->decls_end();
3343 D != DEnd; ++D)
3344 if (ObjCCategoryDecl *Category = dyn_cast<ObjCCategoryDecl>(*D))
3345 if (CategoryNames.insert(Category->getIdentifier()))
Douglas Gregorfc59ce12010-01-14 16:14:35 +00003346 Results.AddResult(Result(Category, 0), CurContext, 0, false);
Douglas Gregor5d34fd32009-11-18 19:08:43 +00003347 Results.ExitScope();
3348
3349 HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
3350}
3351
3352void Sema::CodeCompleteObjCImplementationCategory(Scope *S,
Douglas Gregorb2ccf012010-04-15 22:33:43 +00003353 IdentifierInfo *ClassName,
3354 SourceLocation ClassNameLoc) {
Douglas Gregor5d34fd32009-11-18 19:08:43 +00003355 typedef CodeCompleteConsumer::Result Result;
3356
3357 // Find the corresponding interface. If we couldn't find the interface, the
3358 // program itself is ill-formed. However, we'll try to be helpful still by
3359 // providing the list of all of the categories we know about.
3360 NamedDecl *CurClass
Douglas Gregorb2ccf012010-04-15 22:33:43 +00003361 = LookupSingleName(TUScope, ClassName, ClassNameLoc, LookupOrdinaryName);
Douglas Gregor5d34fd32009-11-18 19:08:43 +00003362 ObjCInterfaceDecl *Class = dyn_cast_or_null<ObjCInterfaceDecl>(CurClass);
3363 if (!Class)
Douglas Gregorb2ccf012010-04-15 22:33:43 +00003364 return CodeCompleteObjCInterfaceCategory(S, ClassName, ClassNameLoc);
Douglas Gregor5d34fd32009-11-18 19:08:43 +00003365
3366 ResultBuilder Results(*this);
3367
3368 // Add all of the categories that have have corresponding interface
3369 // declarations in this class and any of its superclasses, except for
3370 // already-implemented categories in the class itself.
3371 llvm::SmallPtrSet<IdentifierInfo *, 16> CategoryNames;
3372 Results.EnterNewScope();
3373 bool IgnoreImplemented = true;
3374 while (Class) {
3375 for (ObjCCategoryDecl *Category = Class->getCategoryList(); Category;
3376 Category = Category->getNextClassCategory())
3377 if ((!IgnoreImplemented || !Category->getImplementation()) &&
3378 CategoryNames.insert(Category->getIdentifier()))
Douglas Gregorfc59ce12010-01-14 16:14:35 +00003379 Results.AddResult(Result(Category, 0), CurContext, 0, false);
Douglas Gregor5d34fd32009-11-18 19:08:43 +00003380
3381 Class = Class->getSuperClass();
3382 IgnoreImplemented = false;
3383 }
3384 Results.ExitScope();
3385
3386 HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
3387}
Douglas Gregor5d649882009-11-18 22:32:06 +00003388
Douglas Gregor52e78bd2009-11-18 22:56:13 +00003389void Sema::CodeCompleteObjCPropertyDefinition(Scope *S, DeclPtrTy ObjCImpDecl) {
Douglas Gregor5d649882009-11-18 22:32:06 +00003390 typedef CodeCompleteConsumer::Result Result;
3391 ResultBuilder Results(*this);
3392
3393 // Figure out where this @synthesize lives.
3394 ObjCContainerDecl *Container
3395 = dyn_cast_or_null<ObjCContainerDecl>(ObjCImpDecl.getAs<Decl>());
3396 if (!Container ||
3397 (!isa<ObjCImplementationDecl>(Container) &&
3398 !isa<ObjCCategoryImplDecl>(Container)))
3399 return;
3400
3401 // Ignore any properties that have already been implemented.
3402 for (DeclContext::decl_iterator D = Container->decls_begin(),
3403 DEnd = Container->decls_end();
3404 D != DEnd; ++D)
3405 if (ObjCPropertyImplDecl *PropertyImpl = dyn_cast<ObjCPropertyImplDecl>(*D))
3406 Results.Ignore(PropertyImpl->getPropertyDecl());
3407
3408 // Add any properties that we find.
3409 Results.EnterNewScope();
3410 if (ObjCImplementationDecl *ClassImpl
3411 = dyn_cast<ObjCImplementationDecl>(Container))
3412 AddObjCProperties(ClassImpl->getClassInterface(), false, CurContext,
3413 Results);
3414 else
3415 AddObjCProperties(cast<ObjCCategoryImplDecl>(Container)->getCategoryDecl(),
3416 false, CurContext, Results);
3417 Results.ExitScope();
3418
3419 HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
3420}
3421
3422void Sema::CodeCompleteObjCPropertySynthesizeIvar(Scope *S,
3423 IdentifierInfo *PropertyName,
3424 DeclPtrTy ObjCImpDecl) {
3425 typedef CodeCompleteConsumer::Result Result;
3426 ResultBuilder Results(*this);
3427
3428 // Figure out where this @synthesize lives.
3429 ObjCContainerDecl *Container
3430 = dyn_cast_or_null<ObjCContainerDecl>(ObjCImpDecl.getAs<Decl>());
3431 if (!Container ||
3432 (!isa<ObjCImplementationDecl>(Container) &&
3433 !isa<ObjCCategoryImplDecl>(Container)))
3434 return;
3435
3436 // Figure out which interface we're looking into.
3437 ObjCInterfaceDecl *Class = 0;
3438 if (ObjCImplementationDecl *ClassImpl
3439 = dyn_cast<ObjCImplementationDecl>(Container))
3440 Class = ClassImpl->getClassInterface();
3441 else
3442 Class = cast<ObjCCategoryImplDecl>(Container)->getCategoryDecl()
3443 ->getClassInterface();
3444
3445 // Add all of the instance variables in this class and its superclasses.
3446 Results.EnterNewScope();
3447 for(; Class; Class = Class->getSuperClass()) {
3448 // FIXME: We could screen the type of each ivar for compatibility with
3449 // the property, but is that being too paternal?
3450 for (ObjCInterfaceDecl::ivar_iterator IVar = Class->ivar_begin(),
3451 IVarEnd = Class->ivar_end();
3452 IVar != IVarEnd; ++IVar)
Douglas Gregorfc59ce12010-01-14 16:14:35 +00003453 Results.AddResult(Result(*IVar, 0), CurContext, 0, false);
Douglas Gregor5d649882009-11-18 22:32:06 +00003454 }
3455 Results.ExitScope();
3456
3457 HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
3458}
Douglas Gregor636a61e2010-04-07 00:21:17 +00003459
3460typedef llvm::DenseMap<Selector, ObjCMethodDecl *> KnownMethodsMap;
3461
3462/// \brief Find all of the methods that reside in the given container
3463/// (and its superclasses, protocols, etc.) that meet the given
3464/// criteria. Insert those methods into the map of known methods,
3465/// indexed by selector so they can be easily found.
3466static void FindImplementableMethods(ASTContext &Context,
3467 ObjCContainerDecl *Container,
3468 bool WantInstanceMethods,
3469 QualType ReturnType,
3470 bool IsInImplementation,
3471 KnownMethodsMap &KnownMethods) {
3472 if (ObjCInterfaceDecl *IFace = dyn_cast<ObjCInterfaceDecl>(Container)) {
3473 // Recurse into protocols.
3474 const ObjCList<ObjCProtocolDecl> &Protocols
3475 = IFace->getReferencedProtocols();
3476 for (ObjCList<ObjCProtocolDecl>::iterator I = Protocols.begin(),
3477 E = Protocols.end();
3478 I != E; ++I)
3479 FindImplementableMethods(Context, *I, WantInstanceMethods, ReturnType,
3480 IsInImplementation, KnownMethods);
3481
3482 // If we're not in the implementation of a class, also visit the
3483 // superclass.
3484 if (!IsInImplementation && IFace->getSuperClass())
3485 FindImplementableMethods(Context, IFace->getSuperClass(),
3486 WantInstanceMethods, ReturnType,
3487 IsInImplementation, KnownMethods);
3488
3489 // Add methods from any class extensions (but not from categories;
3490 // those should go into category implementations).
3491 for (ObjCCategoryDecl *Cat = IFace->getCategoryList(); Cat;
3492 Cat = Cat->getNextClassCategory()) {
3493 if (!Cat->IsClassExtension())
3494 continue;
3495
3496 FindImplementableMethods(Context, Cat, WantInstanceMethods, ReturnType,
3497 IsInImplementation, KnownMethods);
3498 }
3499 }
3500
3501 if (ObjCCategoryDecl *Category = dyn_cast<ObjCCategoryDecl>(Container)) {
3502 // Recurse into protocols.
3503 const ObjCList<ObjCProtocolDecl> &Protocols
3504 = Category->getReferencedProtocols();
3505 for (ObjCList<ObjCProtocolDecl>::iterator I = Protocols.begin(),
3506 E = Protocols.end();
3507 I != E; ++I)
3508 FindImplementableMethods(Context, *I, WantInstanceMethods, ReturnType,
3509 IsInImplementation, KnownMethods);
3510 }
3511
3512 if (ObjCProtocolDecl *Protocol = dyn_cast<ObjCProtocolDecl>(Container)) {
3513 // Recurse into protocols.
3514 const ObjCList<ObjCProtocolDecl> &Protocols
3515 = Protocol->getReferencedProtocols();
3516 for (ObjCList<ObjCProtocolDecl>::iterator I = Protocols.begin(),
3517 E = Protocols.end();
3518 I != E; ++I)
3519 FindImplementableMethods(Context, *I, WantInstanceMethods, ReturnType,
3520 IsInImplementation, KnownMethods);
3521 }
3522
3523 // Add methods in this container. This operation occurs last because
3524 // we want the methods from this container to override any methods
3525 // we've previously seen with the same selector.
3526 for (ObjCContainerDecl::method_iterator M = Container->meth_begin(),
3527 MEnd = Container->meth_end();
3528 M != MEnd; ++M) {
3529 if ((*M)->isInstanceMethod() == WantInstanceMethods) {
3530 if (!ReturnType.isNull() &&
3531 !Context.hasSameUnqualifiedType(ReturnType, (*M)->getResultType()))
3532 continue;
3533
3534 KnownMethods[(*M)->getSelector()] = *M;
3535 }
3536 }
3537}
3538
3539void Sema::CodeCompleteObjCMethodDecl(Scope *S,
3540 bool IsInstanceMethod,
3541 TypeTy *ReturnTy,
3542 DeclPtrTy IDecl) {
3543 // Determine the return type of the method we're declaring, if
3544 // provided.
3545 QualType ReturnType = GetTypeFromParser(ReturnTy);
3546
3547 // Determine where we should start searching for methods, and where we
3548 ObjCContainerDecl *SearchDecl = 0, *CurrentDecl = 0;
3549 bool IsInImplementation = false;
3550 if (Decl *D = IDecl.getAs<Decl>()) {
3551 if (ObjCImplementationDecl *Impl = dyn_cast<ObjCImplementationDecl>(D)) {
3552 SearchDecl = Impl->getClassInterface();
3553 CurrentDecl = Impl;
3554 IsInImplementation = true;
3555 } else if (ObjCCategoryImplDecl *CatImpl
3556 = dyn_cast<ObjCCategoryImplDecl>(D)) {
3557 SearchDecl = CatImpl->getCategoryDecl();
3558 CurrentDecl = CatImpl;
3559 IsInImplementation = true;
3560 } else {
3561 SearchDecl = dyn_cast<ObjCContainerDecl>(D);
3562 CurrentDecl = SearchDecl;
3563 }
3564 }
3565
3566 if (!SearchDecl && S) {
3567 if (DeclContext *DC = static_cast<DeclContext *>(S->getEntity())) {
3568 SearchDecl = dyn_cast<ObjCContainerDecl>(DC);
3569 CurrentDecl = SearchDecl;
3570 }
3571 }
3572
3573 if (!SearchDecl || !CurrentDecl) {
3574 HandleCodeCompleteResults(this, CodeCompleter, 0, 0);
3575 return;
3576 }
3577
3578 // Find all of the methods that we could declare/implement here.
3579 KnownMethodsMap KnownMethods;
3580 FindImplementableMethods(Context, SearchDecl, IsInstanceMethod,
3581 ReturnType, IsInImplementation, KnownMethods);
3582
3583 // Erase any methods that have already been declared or
3584 // implemented here.
3585 for (ObjCContainerDecl::method_iterator M = CurrentDecl->meth_begin(),
3586 MEnd = CurrentDecl->meth_end();
3587 M != MEnd; ++M) {
3588 if ((*M)->isInstanceMethod() != IsInstanceMethod)
3589 continue;
3590
3591 KnownMethodsMap::iterator Pos = KnownMethods.find((*M)->getSelector());
3592 if (Pos != KnownMethods.end())
3593 KnownMethods.erase(Pos);
3594 }
3595
3596 // Add declarations or definitions for each of the known methods.
3597 typedef CodeCompleteConsumer::Result Result;
3598 ResultBuilder Results(*this);
3599 Results.EnterNewScope();
3600 PrintingPolicy Policy(Context.PrintingPolicy);
3601 Policy.AnonymousTagLocations = false;
3602 for (KnownMethodsMap::iterator M = KnownMethods.begin(),
3603 MEnd = KnownMethods.end();
3604 M != MEnd; ++M) {
3605 ObjCMethodDecl *Method = M->second;
3606 CodeCompletionString *Pattern = new CodeCompletionString;
3607
3608 // If the result type was not already provided, add it to the
3609 // pattern as (type).
3610 if (ReturnType.isNull()) {
3611 std::string TypeStr;
3612 Method->getResultType().getAsStringInternal(TypeStr, Policy);
3613 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
3614 Pattern->AddTextChunk(TypeStr);
3615 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
3616 }
3617
3618 Selector Sel = Method->getSelector();
3619
3620 // Add the first part of the selector to the pattern.
3621 Pattern->AddTypedTextChunk(Sel.getIdentifierInfoForSlot(0)->getName());
3622
3623 // Add parameters to the pattern.
3624 unsigned I = 0;
3625 for (ObjCMethodDecl::param_iterator P = Method->param_begin(),
3626 PEnd = Method->param_end();
3627 P != PEnd; (void)++P, ++I) {
3628 // Add the part of the selector name.
3629 if (I == 0)
3630 Pattern->AddChunk(CodeCompletionString::CK_Colon);
3631 else if (I < Sel.getNumArgs()) {
3632 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
3633 Pattern->AddTextChunk(Sel.getIdentifierInfoForSlot(1)->getName());
3634 Pattern->AddChunk(CodeCompletionString::CK_Colon);
3635 } else
3636 break;
3637
3638 // Add the parameter type.
3639 std::string TypeStr;
3640 (*P)->getOriginalType().getAsStringInternal(TypeStr, Policy);
3641 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
3642 Pattern->AddTextChunk(TypeStr);
3643 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
3644
3645 if (IdentifierInfo *Id = (*P)->getIdentifier())
3646 Pattern->AddTextChunk(Id->getName());
3647 }
3648
3649 if (Method->isVariadic()) {
3650 if (Method->param_size() > 0)
3651 Pattern->AddChunk(CodeCompletionString::CK_Comma);
3652 Pattern->AddTextChunk("...");
3653 }
3654
3655 if (IsInImplementation) {
3656 // We will be defining the method here, so add a compound statement.
3657 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
3658 Pattern->AddChunk(CodeCompletionString::CK_LeftBrace);
3659 Pattern->AddChunk(CodeCompletionString::CK_VerticalSpace);
3660 if (!Method->getResultType()->isVoidType()) {
3661 // If the result type is not void, add a return clause.
3662 Pattern->AddTextChunk("return");
3663 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
3664 Pattern->AddPlaceholderChunk("expression");
3665 Pattern->AddChunk(CodeCompletionString::CK_SemiColon);
3666 } else
3667 Pattern->AddPlaceholderChunk("statements");
3668
3669 Pattern->AddChunk(CodeCompletionString::CK_VerticalSpace);
3670 Pattern->AddChunk(CodeCompletionString::CK_RightBrace);
3671 }
3672
3673 Results.AddResult(Result(Pattern));
3674 }
3675
3676 Results.ExitScope();
3677
3678 HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
3679}