blob: 0e8fb59368330462e01660cea2685a6fb190760b [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
Douglas Gregorf64acca2010-05-25 21:41:55 +0000130 /// \brief Whether we should include code patterns in the completion
131 /// results.
132 bool includeCodePatterns() const {
133 return SemaRef.CodeCompleter &&
134 SemaRef.CodeCompleter->includeCodePatterns();
135 }
136
Douglas Gregor3545ff42009-09-21 16:56:56 +0000137 /// \brief Set the filter used for code-completion results.
138 void setFilter(LookupFilter Filter) {
139 this->Filter = Filter;
140 }
141
142 typedef std::vector<Result>::iterator iterator;
143 iterator begin() { return Results.begin(); }
144 iterator end() { return Results.end(); }
145
146 Result *data() { return Results.empty()? 0 : &Results.front(); }
147 unsigned size() const { return Results.size(); }
148 bool empty() const { return Results.empty(); }
149
Douglas Gregor6ae4c522010-01-14 03:21:49 +0000150 /// \brief Specify whether nested-name-specifiers are allowed.
151 void allowNestedNameSpecifiers(bool Allow = true) {
152 AllowNestedNameSpecifiers = Allow;
153 }
154
Douglas Gregor7c208612010-01-14 00:20:49 +0000155 /// \brief Determine whether the given declaration is at all interesting
156 /// as a code-completion result.
Douglas Gregor6ae4c522010-01-14 03:21:49 +0000157 ///
158 /// \param ND the declaration that we are inspecting.
159 ///
160 /// \param AsNestedNameSpecifier will be set true if this declaration is
161 /// only interesting when it is a nested-name-specifier.
162 bool isInterestingDecl(NamedDecl *ND, bool &AsNestedNameSpecifier) const;
Douglas Gregore0717ab2010-01-14 00:41:07 +0000163
164 /// \brief Check whether the result is hidden by the Hiding declaration.
165 ///
166 /// \returns true if the result is hidden and cannot be found, false if
167 /// the hidden result could still be found. When false, \p R may be
168 /// modified to describe how the result can be found (e.g., via extra
169 /// qualification).
170 bool CheckHiddenResult(Result &R, DeclContext *CurContext,
171 NamedDecl *Hiding);
172
Douglas Gregor3545ff42009-09-21 16:56:56 +0000173 /// \brief Add a new result to this result set (if it isn't already in one
174 /// of the shadow maps), or replace an existing result (for, e.g., a
175 /// redeclaration).
Douglas Gregor2af2f672009-09-21 20:12:40 +0000176 ///
Douglas Gregorc580c522010-01-14 01:09:38 +0000177 /// \param CurContext the result to add (if it is unique).
Douglas Gregor2af2f672009-09-21 20:12:40 +0000178 ///
179 /// \param R the context in which this result will be named.
180 void MaybeAddResult(Result R, DeclContext *CurContext = 0);
Douglas Gregor3545ff42009-09-21 16:56:56 +0000181
Douglas Gregorc580c522010-01-14 01:09:38 +0000182 /// \brief Add a new result to this result set, where we already know
183 /// the hiding declation (if any).
184 ///
185 /// \param R the result to add (if it is unique).
186 ///
187 /// \param CurContext the context in which this result will be named.
188 ///
189 /// \param Hiding the declaration that hides the result.
Douglas Gregor09bbc652010-01-14 15:47:35 +0000190 ///
191 /// \param InBaseClass whether the result was found in a base
192 /// class of the searched context.
193 void AddResult(Result R, DeclContext *CurContext, NamedDecl *Hiding,
194 bool InBaseClass);
Douglas Gregorc580c522010-01-14 01:09:38 +0000195
Douglas Gregor78a21012010-01-14 16:01:26 +0000196 /// \brief Add a new non-declaration result to this result set.
197 void AddResult(Result R);
198
Douglas Gregor3545ff42009-09-21 16:56:56 +0000199 /// \brief Enter into a new scope.
200 void EnterNewScope();
201
202 /// \brief Exit from the current scope.
203 void ExitScope();
204
Douglas Gregorbaf69612009-11-18 04:19:12 +0000205 /// \brief Ignore this declaration, if it is seen again.
206 void Ignore(Decl *D) { AllDeclsFound.insert(D->getCanonicalDecl()); }
207
Douglas Gregor3545ff42009-09-21 16:56:56 +0000208 /// \name Name lookup predicates
209 ///
210 /// These predicates can be passed to the name lookup functions to filter the
211 /// results of name lookup. All of the predicates have the same type, so that
212 ///
213 //@{
Douglas Gregor9d64c5e2009-09-21 20:51:25 +0000214 bool IsOrdinaryName(NamedDecl *ND) const;
Douglas Gregor70febae2010-05-28 00:49:12 +0000215 bool IsOrdinaryNonTypeName(NamedDecl *ND) const;
Douglas Gregor504a6ae2010-01-10 23:08:15 +0000216 bool IsOrdinaryNonValueName(NamedDecl *ND) const;
Douglas Gregor3545ff42009-09-21 16:56:56 +0000217 bool IsNestedNameSpecifier(NamedDecl *ND) const;
218 bool IsEnum(NamedDecl *ND) const;
219 bool IsClassOrStruct(NamedDecl *ND) const;
220 bool IsUnion(NamedDecl *ND) const;
221 bool IsNamespace(NamedDecl *ND) const;
222 bool IsNamespaceOrAlias(NamedDecl *ND) const;
223 bool IsType(NamedDecl *ND) const;
Douglas Gregore412a5a2009-09-23 22:26:46 +0000224 bool IsMember(NamedDecl *ND) const;
Douglas Gregor2b8162b2010-01-14 16:08:12 +0000225 bool IsObjCIvar(NamedDecl *ND) const;
Douglas Gregora817a192010-05-27 23:06:34 +0000226 bool IsObjCMessageReceiver(NamedDecl *ND) const;
Douglas Gregor3545ff42009-09-21 16:56:56 +0000227 //@}
228 };
229}
230
Douglas Gregor05e7ca32009-12-06 20:23:50 +0000231class ResultBuilder::ShadowMapEntry::iterator {
232 llvm::PointerUnion<NamedDecl*, const DeclIndexPair*> DeclOrIterator;
233 unsigned SingleDeclIndex;
234
235public:
236 typedef DeclIndexPair value_type;
237 typedef value_type reference;
238 typedef std::ptrdiff_t difference_type;
239 typedef std::input_iterator_tag iterator_category;
240
241 class pointer {
242 DeclIndexPair Value;
243
244 public:
245 pointer(const DeclIndexPair &Value) : Value(Value) { }
246
247 const DeclIndexPair *operator->() const {
248 return &Value;
249 }
250 };
251
252 iterator() : DeclOrIterator((NamedDecl *)0), SingleDeclIndex(0) { }
253
254 iterator(NamedDecl *SingleDecl, unsigned Index)
255 : DeclOrIterator(SingleDecl), SingleDeclIndex(Index) { }
256
257 iterator(const DeclIndexPair *Iterator)
258 : DeclOrIterator(Iterator), SingleDeclIndex(0) { }
259
260 iterator &operator++() {
261 if (DeclOrIterator.is<NamedDecl *>()) {
262 DeclOrIterator = (NamedDecl *)0;
263 SingleDeclIndex = 0;
264 return *this;
265 }
266
267 const DeclIndexPair *I = DeclOrIterator.get<const DeclIndexPair*>();
268 ++I;
269 DeclOrIterator = I;
270 return *this;
271 }
272
273 iterator operator++(int) {
274 iterator tmp(*this);
275 ++(*this);
276 return tmp;
277 }
278
279 reference operator*() const {
280 if (NamedDecl *ND = DeclOrIterator.dyn_cast<NamedDecl *>())
281 return reference(ND, SingleDeclIndex);
282
Douglas Gregor94bb5e82009-12-06 21:27:58 +0000283 return *DeclOrIterator.get<const DeclIndexPair*>();
Douglas Gregor05e7ca32009-12-06 20:23:50 +0000284 }
285
286 pointer operator->() const {
287 return pointer(**this);
288 }
289
290 friend bool operator==(const iterator &X, const iterator &Y) {
Douglas Gregor94bb5e82009-12-06 21:27:58 +0000291 return X.DeclOrIterator.getOpaqueValue()
292 == Y.DeclOrIterator.getOpaqueValue() &&
Douglas Gregor05e7ca32009-12-06 20:23:50 +0000293 X.SingleDeclIndex == Y.SingleDeclIndex;
294 }
295
296 friend bool operator!=(const iterator &X, const iterator &Y) {
Douglas Gregor94bb5e82009-12-06 21:27:58 +0000297 return !(X == Y);
Douglas Gregor05e7ca32009-12-06 20:23:50 +0000298 }
299};
300
Douglas Gregor05e7ca32009-12-06 20:23:50 +0000301ResultBuilder::ShadowMapEntry::iterator
302ResultBuilder::ShadowMapEntry::begin() const {
303 if (DeclOrVector.isNull())
304 return iterator();
305
306 if (NamedDecl *ND = DeclOrVector.dyn_cast<NamedDecl *>())
307 return iterator(ND, SingleDeclIndex);
308
309 return iterator(DeclOrVector.get<DeclIndexPairVector *>()->begin());
310}
311
312ResultBuilder::ShadowMapEntry::iterator
313ResultBuilder::ShadowMapEntry::end() const {
314 if (DeclOrVector.is<NamedDecl *>() || DeclOrVector.isNull())
315 return iterator();
316
317 return iterator(DeclOrVector.get<DeclIndexPairVector *>()->end());
318}
319
Douglas Gregor2af2f672009-09-21 20:12:40 +0000320/// \brief Compute the qualification required to get from the current context
321/// (\p CurContext) to the target context (\p TargetContext).
322///
323/// \param Context the AST context in which the qualification will be used.
324///
325/// \param CurContext the context where an entity is being named, which is
326/// typically based on the current scope.
327///
328/// \param TargetContext the context in which the named entity actually
329/// resides.
330///
331/// \returns a nested name specifier that refers into the target context, or
332/// NULL if no qualification is needed.
333static NestedNameSpecifier *
334getRequiredQualification(ASTContext &Context,
335 DeclContext *CurContext,
336 DeclContext *TargetContext) {
337 llvm::SmallVector<DeclContext *, 4> TargetParents;
338
339 for (DeclContext *CommonAncestor = TargetContext;
340 CommonAncestor && !CommonAncestor->Encloses(CurContext);
341 CommonAncestor = CommonAncestor->getLookupParent()) {
342 if (CommonAncestor->isTransparentContext() ||
343 CommonAncestor->isFunctionOrMethod())
344 continue;
345
346 TargetParents.push_back(CommonAncestor);
347 }
348
349 NestedNameSpecifier *Result = 0;
350 while (!TargetParents.empty()) {
351 DeclContext *Parent = TargetParents.back();
352 TargetParents.pop_back();
353
354 if (NamespaceDecl *Namespace = dyn_cast<NamespaceDecl>(Parent))
355 Result = NestedNameSpecifier::Create(Context, Result, Namespace);
356 else if (TagDecl *TD = dyn_cast<TagDecl>(Parent))
357 Result = NestedNameSpecifier::Create(Context, Result,
358 false,
359 Context.getTypeDeclType(TD).getTypePtr());
360 else
361 assert(Parent->isTranslationUnit());
Douglas Gregor9eb77012009-11-07 00:00:49 +0000362 }
Douglas Gregor2af2f672009-09-21 20:12:40 +0000363 return Result;
364}
365
Douglas Gregor6ae4c522010-01-14 03:21:49 +0000366bool ResultBuilder::isInterestingDecl(NamedDecl *ND,
367 bool &AsNestedNameSpecifier) const {
368 AsNestedNameSpecifier = false;
369
Douglas Gregor7c208612010-01-14 00:20:49 +0000370 ND = ND->getUnderlyingDecl();
371 unsigned IDNS = ND->getIdentifierNamespace();
Douglas Gregor58acf322009-10-09 22:16:47 +0000372
373 // Skip unnamed entities.
Douglas Gregor7c208612010-01-14 00:20:49 +0000374 if (!ND->getDeclName())
375 return false;
Douglas Gregor3545ff42009-09-21 16:56:56 +0000376
377 // Friend declarations and declarations introduced due to friends are never
378 // added as results.
John McCallbbbbe4e2010-03-11 07:50:04 +0000379 if (IDNS & (Decl::IDNS_OrdinaryFriend | Decl::IDNS_TagFriend))
Douglas Gregor7c208612010-01-14 00:20:49 +0000380 return false;
381
Douglas Gregor99fe2ad2009-12-11 17:31:05 +0000382 // Class template (partial) specializations are never added as results.
Douglas Gregor7c208612010-01-14 00:20:49 +0000383 if (isa<ClassTemplateSpecializationDecl>(ND) ||
384 isa<ClassTemplatePartialSpecializationDecl>(ND))
385 return false;
Douglas Gregor3545ff42009-09-21 16:56:56 +0000386
Douglas Gregor99fe2ad2009-12-11 17:31:05 +0000387 // Using declarations themselves are never added as results.
Douglas Gregor7c208612010-01-14 00:20:49 +0000388 if (isa<UsingDecl>(ND))
389 return false;
390
391 // Some declarations have reserved names that we don't want to ever show.
392 if (const IdentifierInfo *Id = ND->getIdentifier()) {
Douglas Gregor3545ff42009-09-21 16:56:56 +0000393 // __va_list_tag is a freak of nature. Find it and skip it.
394 if (Id->isStr("__va_list_tag") || Id->isStr("__builtin_va_list"))
Douglas Gregor7c208612010-01-14 00:20:49 +0000395 return false;
Douglas Gregor3545ff42009-09-21 16:56:56 +0000396
Douglas Gregor58acf322009-10-09 22:16:47 +0000397 // Filter out names reserved for the implementation (C99 7.1.3,
398 // C++ [lib.global.names]). Users don't need to see those.
Daniel Dunbar2c422dc92009-10-18 20:26:12 +0000399 //
400 // FIXME: Add predicate for this.
Douglas Gregor58acf322009-10-09 22:16:47 +0000401 if (Id->getLength() >= 2) {
Daniel Dunbar2c422dc92009-10-18 20:26:12 +0000402 const char *Name = Id->getNameStart();
Douglas Gregor58acf322009-10-09 22:16:47 +0000403 if (Name[0] == '_' &&
404 (Name[1] == '_' || (Name[1] >= 'A' && Name[1] <= 'Z')))
Douglas Gregor7c208612010-01-14 00:20:49 +0000405 return false;
Douglas Gregor58acf322009-10-09 22:16:47 +0000406 }
Douglas Gregor3545ff42009-09-21 16:56:56 +0000407 }
Douglas Gregor7c208612010-01-14 00:20:49 +0000408
Douglas Gregor3545ff42009-09-21 16:56:56 +0000409 // C++ constructors are never found by name lookup.
Douglas Gregor7c208612010-01-14 00:20:49 +0000410 if (isa<CXXConstructorDecl>(ND))
411 return false;
Douglas Gregor3545ff42009-09-21 16:56:56 +0000412
413 // Filter out any unwanted results.
Douglas Gregor6ae4c522010-01-14 03:21:49 +0000414 if (Filter && !(this->*Filter)(ND)) {
415 // Check whether it is interesting as a nested-name-specifier.
416 if (AllowNestedNameSpecifiers && SemaRef.getLangOptions().CPlusPlus &&
417 IsNestedNameSpecifier(ND) &&
418 (Filter != &ResultBuilder::IsMember ||
419 (isa<CXXRecordDecl>(ND) &&
420 cast<CXXRecordDecl>(ND)->isInjectedClassName()))) {
421 AsNestedNameSpecifier = true;
422 return true;
423 }
424
Douglas Gregor7c208612010-01-14 00:20:49 +0000425 return false;
Douglas Gregor6ae4c522010-01-14 03:21:49 +0000426 }
John McCalle87beb22010-04-23 18:46:30 +0000427
428 if (Filter == &ResultBuilder::IsNestedNameSpecifier)
429 AsNestedNameSpecifier = true;
Douglas Gregor3545ff42009-09-21 16:56:56 +0000430
Douglas Gregor7c208612010-01-14 00:20:49 +0000431 // ... then it must be interesting!
432 return true;
433}
434
Douglas Gregore0717ab2010-01-14 00:41:07 +0000435bool ResultBuilder::CheckHiddenResult(Result &R, DeclContext *CurContext,
436 NamedDecl *Hiding) {
437 // In C, there is no way to refer to a hidden name.
438 // FIXME: This isn't true; we can find a tag name hidden by an ordinary
439 // name if we introduce the tag type.
440 if (!SemaRef.getLangOptions().CPlusPlus)
441 return true;
442
443 DeclContext *HiddenCtx = R.Declaration->getDeclContext()->getLookupContext();
444
445 // There is no way to qualify a name declared in a function or method.
446 if (HiddenCtx->isFunctionOrMethod())
447 return true;
448
449 if (HiddenCtx == Hiding->getDeclContext()->getLookupContext())
450 return true;
451
452 // We can refer to the result with the appropriate qualification. Do it.
453 R.Hidden = true;
454 R.QualifierIsInformative = false;
455
456 if (!R.Qualifier)
457 R.Qualifier = getRequiredQualification(SemaRef.Context,
458 CurContext,
459 R.Declaration->getDeclContext());
460 return false;
461}
462
Douglas Gregor7c208612010-01-14 00:20:49 +0000463void ResultBuilder::MaybeAddResult(Result R, DeclContext *CurContext) {
464 assert(!ShadowMaps.empty() && "Must enter into a results scope");
465
466 if (R.Kind != Result::RK_Declaration) {
467 // For non-declaration results, just add the result.
468 Results.push_back(R);
469 return;
470 }
471
472 // Look through using declarations.
473 if (UsingShadowDecl *Using = dyn_cast<UsingShadowDecl>(R.Declaration)) {
474 MaybeAddResult(Result(Using->getTargetDecl(), R.Qualifier), CurContext);
475 return;
476 }
477
478 Decl *CanonDecl = R.Declaration->getCanonicalDecl();
479 unsigned IDNS = CanonDecl->getIdentifierNamespace();
480
Douglas Gregor6ae4c522010-01-14 03:21:49 +0000481 bool AsNestedNameSpecifier = false;
482 if (!isInterestingDecl(R.Declaration, AsNestedNameSpecifier))
Douglas Gregor7c208612010-01-14 00:20:49 +0000483 return;
484
Douglas Gregor3545ff42009-09-21 16:56:56 +0000485 ShadowMap &SMap = ShadowMaps.back();
Douglas Gregor05e7ca32009-12-06 20:23:50 +0000486 ShadowMapEntry::iterator I, IEnd;
487 ShadowMap::iterator NamePos = SMap.find(R.Declaration->getDeclName());
488 if (NamePos != SMap.end()) {
489 I = NamePos->second.begin();
490 IEnd = NamePos->second.end();
491 }
492
493 for (; I != IEnd; ++I) {
494 NamedDecl *ND = I->first;
495 unsigned Index = I->second;
Douglas Gregor3545ff42009-09-21 16:56:56 +0000496 if (ND->getCanonicalDecl() == CanonDecl) {
497 // This is a redeclaration. Always pick the newer declaration.
Douglas Gregor3545ff42009-09-21 16:56:56 +0000498 Results[Index].Declaration = R.Declaration;
499
Douglas Gregor3545ff42009-09-21 16:56:56 +0000500 // We're done.
501 return;
502 }
503 }
504
505 // This is a new declaration in this scope. However, check whether this
506 // declaration name is hidden by a similarly-named declaration in an outer
507 // scope.
508 std::list<ShadowMap>::iterator SM, SMEnd = ShadowMaps.end();
509 --SMEnd;
510 for (SM = ShadowMaps.begin(); SM != SMEnd; ++SM) {
Douglas Gregor05e7ca32009-12-06 20:23:50 +0000511 ShadowMapEntry::iterator I, IEnd;
512 ShadowMap::iterator NamePos = SM->find(R.Declaration->getDeclName());
513 if (NamePos != SM->end()) {
514 I = NamePos->second.begin();
515 IEnd = NamePos->second.end();
516 }
517 for (; I != IEnd; ++I) {
Douglas Gregor3545ff42009-09-21 16:56:56 +0000518 // A tag declaration does not hide a non-tag declaration.
John McCalle87beb22010-04-23 18:46:30 +0000519 if (I->first->hasTagIdentifierNamespace() &&
Douglas Gregor3545ff42009-09-21 16:56:56 +0000520 (IDNS & (Decl::IDNS_Member | Decl::IDNS_Ordinary |
521 Decl::IDNS_ObjCProtocol)))
522 continue;
523
524 // Protocols are in distinct namespaces from everything else.
Douglas Gregor05e7ca32009-12-06 20:23:50 +0000525 if (((I->first->getIdentifierNamespace() & Decl::IDNS_ObjCProtocol)
Douglas Gregor3545ff42009-09-21 16:56:56 +0000526 || (IDNS & Decl::IDNS_ObjCProtocol)) &&
Douglas Gregor05e7ca32009-12-06 20:23:50 +0000527 I->first->getIdentifierNamespace() != IDNS)
Douglas Gregor3545ff42009-09-21 16:56:56 +0000528 continue;
529
530 // The newly-added result is hidden by an entry in the shadow map.
Douglas Gregore0717ab2010-01-14 00:41:07 +0000531 if (CheckHiddenResult(R, CurContext, I->first))
Douglas Gregor3545ff42009-09-21 16:56:56 +0000532 return;
Douglas Gregor3545ff42009-09-21 16:56:56 +0000533
534 break;
535 }
536 }
537
538 // Make sure that any given declaration only shows up in the result set once.
539 if (!AllDeclsFound.insert(CanonDecl))
540 return;
541
Douglas Gregore412a5a2009-09-23 22:26:46 +0000542 // If the filter is for nested-name-specifiers, then this result starts a
543 // nested-name-specifier.
Douglas Gregora2db7932010-05-26 22:00:08 +0000544 if (AsNestedNameSpecifier) {
Douglas Gregore412a5a2009-09-23 22:26:46 +0000545 R.StartsNestedNameSpecifier = true;
Douglas Gregora2db7932010-05-26 22:00:08 +0000546 R.Priority = CCP_NestedNameSpecifier;
547 }
Douglas Gregore412a5a2009-09-23 22:26:46 +0000548
Douglas Gregor5bf52692009-09-22 23:15:58 +0000549 // If this result is supposed to have an informative qualifier, add one.
Douglas Gregore412a5a2009-09-23 22:26:46 +0000550 if (R.QualifierIsInformative && !R.Qualifier &&
551 !R.StartsNestedNameSpecifier) {
Douglas Gregor5bf52692009-09-22 23:15:58 +0000552 DeclContext *Ctx = R.Declaration->getDeclContext();
553 if (NamespaceDecl *Namespace = dyn_cast<NamespaceDecl>(Ctx))
554 R.Qualifier = NestedNameSpecifier::Create(SemaRef.Context, 0, Namespace);
555 else if (TagDecl *Tag = dyn_cast<TagDecl>(Ctx))
556 R.Qualifier = NestedNameSpecifier::Create(SemaRef.Context, 0, false,
557 SemaRef.Context.getTypeDeclType(Tag).getTypePtr());
558 else
559 R.QualifierIsInformative = false;
560 }
Douglas Gregore412a5a2009-09-23 22:26:46 +0000561
Douglas Gregor3545ff42009-09-21 16:56:56 +0000562 // Insert this result into the set of results and into the current shadow
563 // map.
Douglas Gregor05e7ca32009-12-06 20:23:50 +0000564 SMap[R.Declaration->getDeclName()].Add(R.Declaration, Results.size());
Douglas Gregor3545ff42009-09-21 16:56:56 +0000565 Results.push_back(R);
566}
567
Douglas Gregorc580c522010-01-14 01:09:38 +0000568void ResultBuilder::AddResult(Result R, DeclContext *CurContext,
Douglas Gregor09bbc652010-01-14 15:47:35 +0000569 NamedDecl *Hiding, bool InBaseClass = false) {
Douglas Gregor78a21012010-01-14 16:01:26 +0000570 if (R.Kind != Result::RK_Declaration) {
571 // For non-declaration results, just add the result.
572 Results.push_back(R);
573 return;
574 }
575
Douglas Gregorc580c522010-01-14 01:09:38 +0000576 // Look through using declarations.
577 if (UsingShadowDecl *Using = dyn_cast<UsingShadowDecl>(R.Declaration)) {
578 AddResult(Result(Using->getTargetDecl(), R.Qualifier), CurContext, Hiding);
579 return;
580 }
581
Douglas Gregor6ae4c522010-01-14 03:21:49 +0000582 bool AsNestedNameSpecifier = false;
583 if (!isInterestingDecl(R.Declaration, AsNestedNameSpecifier))
Douglas Gregorc580c522010-01-14 01:09:38 +0000584 return;
585
586 if (Hiding && CheckHiddenResult(R, CurContext, Hiding))
587 return;
588
589 // Make sure that any given declaration only shows up in the result set once.
590 if (!AllDeclsFound.insert(R.Declaration->getCanonicalDecl()))
591 return;
592
593 // If the filter is for nested-name-specifiers, then this result starts a
594 // nested-name-specifier.
Douglas Gregora2db7932010-05-26 22:00:08 +0000595 if (AsNestedNameSpecifier) {
Douglas Gregorc580c522010-01-14 01:09:38 +0000596 R.StartsNestedNameSpecifier = true;
Douglas Gregora2db7932010-05-26 22:00:08 +0000597 R.Priority = CCP_NestedNameSpecifier;
598 }
Douglas Gregor09bbc652010-01-14 15:47:35 +0000599 else if (Filter == &ResultBuilder::IsMember && !R.Qualifier && InBaseClass &&
600 isa<CXXRecordDecl>(R.Declaration->getDeclContext()
601 ->getLookupContext()))
602 R.QualifierIsInformative = true;
603
Douglas Gregorc580c522010-01-14 01:09:38 +0000604 // If this result is supposed to have an informative qualifier, add one.
605 if (R.QualifierIsInformative && !R.Qualifier &&
606 !R.StartsNestedNameSpecifier) {
607 DeclContext *Ctx = R.Declaration->getDeclContext();
608 if (NamespaceDecl *Namespace = dyn_cast<NamespaceDecl>(Ctx))
609 R.Qualifier = NestedNameSpecifier::Create(SemaRef.Context, 0, Namespace);
610 else if (TagDecl *Tag = dyn_cast<TagDecl>(Ctx))
611 R.Qualifier = NestedNameSpecifier::Create(SemaRef.Context, 0, false,
Douglas Gregor6ae4c522010-01-14 03:21:49 +0000612 SemaRef.Context.getTypeDeclType(Tag).getTypePtr());
Douglas Gregorc580c522010-01-14 01:09:38 +0000613 else
614 R.QualifierIsInformative = false;
615 }
616
Douglas Gregora2db7932010-05-26 22:00:08 +0000617 // Adjust the priority if this result comes from a base class.
618 if (InBaseClass)
619 R.Priority += CCD_InBaseClass;
620
Douglas Gregorc580c522010-01-14 01:09:38 +0000621 // Insert this result into the set of results.
622 Results.push_back(R);
623}
624
Douglas Gregor78a21012010-01-14 16:01:26 +0000625void ResultBuilder::AddResult(Result R) {
626 assert(R.Kind != Result::RK_Declaration &&
627 "Declaration results need more context");
628 Results.push_back(R);
629}
630
Douglas Gregor3545ff42009-09-21 16:56:56 +0000631/// \brief Enter into a new scope.
632void ResultBuilder::EnterNewScope() {
633 ShadowMaps.push_back(ShadowMap());
634}
635
636/// \brief Exit from the current scope.
637void ResultBuilder::ExitScope() {
Douglas Gregor05e7ca32009-12-06 20:23:50 +0000638 for (ShadowMap::iterator E = ShadowMaps.back().begin(),
639 EEnd = ShadowMaps.back().end();
640 E != EEnd;
641 ++E)
642 E->second.Destroy();
643
Douglas Gregor3545ff42009-09-21 16:56:56 +0000644 ShadowMaps.pop_back();
645}
646
Douglas Gregor9d64c5e2009-09-21 20:51:25 +0000647/// \brief Determines whether this given declaration will be found by
648/// ordinary name lookup.
649bool ResultBuilder::IsOrdinaryName(NamedDecl *ND) const {
Douglas Gregor70febae2010-05-28 00:49:12 +0000650 ND = cast<NamedDecl>(ND->getUnderlyingDecl());
651
Douglas Gregor9d64c5e2009-09-21 20:51:25 +0000652 unsigned IDNS = Decl::IDNS_Ordinary;
653 if (SemaRef.getLangOptions().CPlusPlus)
John McCalle87beb22010-04-23 18:46:30 +0000654 IDNS |= Decl::IDNS_Tag | Decl::IDNS_Namespace;
Douglas Gregorc580c522010-01-14 01:09:38 +0000655 else if (SemaRef.getLangOptions().ObjC1 && isa<ObjCIvarDecl>(ND))
656 return true;
657
Douglas Gregor9d64c5e2009-09-21 20:51:25 +0000658 return ND->getIdentifierNamespace() & IDNS;
659}
660
Douglas Gregor504a6ae2010-01-10 23:08:15 +0000661/// \brief Determines whether this given declaration will be found by
Douglas Gregor70febae2010-05-28 00:49:12 +0000662/// ordinary name lookup but is not a type name.
663bool ResultBuilder::IsOrdinaryNonTypeName(NamedDecl *ND) const {
664 ND = cast<NamedDecl>(ND->getUnderlyingDecl());
665 if (isa<TypeDecl>(ND) || isa<ObjCInterfaceDecl>(ND))
666 return false;
667
668 unsigned IDNS = Decl::IDNS_Ordinary;
669 if (SemaRef.getLangOptions().CPlusPlus)
670 IDNS |= Decl::IDNS_Tag | Decl::IDNS_Namespace;
671 else if (SemaRef.getLangOptions().ObjC1 && isa<ObjCIvarDecl>(ND))
672 return true;
673
674 return ND->getIdentifierNamespace() & IDNS;
675}
676
677/// \brief Determines whether this given declaration will be found by
Douglas Gregor504a6ae2010-01-10 23:08:15 +0000678/// ordinary name lookup.
679bool ResultBuilder::IsOrdinaryNonValueName(NamedDecl *ND) const {
Douglas Gregor70febae2010-05-28 00:49:12 +0000680 ND = cast<NamedDecl>(ND->getUnderlyingDecl());
681
Douglas Gregor504a6ae2010-01-10 23:08:15 +0000682 unsigned IDNS = Decl::IDNS_Ordinary;
683 if (SemaRef.getLangOptions().CPlusPlus)
John McCalle87beb22010-04-23 18:46:30 +0000684 IDNS |= Decl::IDNS_Tag | Decl::IDNS_Namespace;
Douglas Gregor504a6ae2010-01-10 23:08:15 +0000685
686 return (ND->getIdentifierNamespace() & IDNS) &&
Douglas Gregor70febae2010-05-28 00:49:12 +0000687 !isa<ValueDecl>(ND) && !isa<FunctionTemplateDecl>(ND) &&
688 !isa<ObjCPropertyDecl>(ND);
Douglas Gregor504a6ae2010-01-10 23:08:15 +0000689}
690
Douglas Gregor3545ff42009-09-21 16:56:56 +0000691/// \brief Determines whether the given declaration is suitable as the
692/// start of a C++ nested-name-specifier, e.g., a class or namespace.
693bool ResultBuilder::IsNestedNameSpecifier(NamedDecl *ND) const {
694 // Allow us to find class templates, too.
695 if (ClassTemplateDecl *ClassTemplate = dyn_cast<ClassTemplateDecl>(ND))
696 ND = ClassTemplate->getTemplatedDecl();
697
698 return SemaRef.isAcceptableNestedNameSpecifier(ND);
699}
700
701/// \brief Determines whether the given declaration is an enumeration.
702bool ResultBuilder::IsEnum(NamedDecl *ND) const {
703 return isa<EnumDecl>(ND);
704}
705
706/// \brief Determines whether the given declaration is a class or struct.
707bool ResultBuilder::IsClassOrStruct(NamedDecl *ND) const {
708 // Allow us to find class templates, too.
709 if (ClassTemplateDecl *ClassTemplate = dyn_cast<ClassTemplateDecl>(ND))
710 ND = ClassTemplate->getTemplatedDecl();
711
712 if (RecordDecl *RD = dyn_cast<RecordDecl>(ND))
Abramo Bagnara6150c882010-05-11 21:36:43 +0000713 return RD->getTagKind() == TTK_Class ||
714 RD->getTagKind() == TTK_Struct;
Douglas Gregor3545ff42009-09-21 16:56:56 +0000715
716 return false;
717}
718
719/// \brief Determines whether the given declaration is a union.
720bool ResultBuilder::IsUnion(NamedDecl *ND) const {
721 // Allow us to find class templates, too.
722 if (ClassTemplateDecl *ClassTemplate = dyn_cast<ClassTemplateDecl>(ND))
723 ND = ClassTemplate->getTemplatedDecl();
724
725 if (RecordDecl *RD = dyn_cast<RecordDecl>(ND))
Abramo Bagnara6150c882010-05-11 21:36:43 +0000726 return RD->getTagKind() == TTK_Union;
Douglas Gregor3545ff42009-09-21 16:56:56 +0000727
728 return false;
729}
730
731/// \brief Determines whether the given declaration is a namespace.
732bool ResultBuilder::IsNamespace(NamedDecl *ND) const {
733 return isa<NamespaceDecl>(ND);
734}
735
736/// \brief Determines whether the given declaration is a namespace or
737/// namespace alias.
738bool ResultBuilder::IsNamespaceOrAlias(NamedDecl *ND) const {
739 return isa<NamespaceDecl>(ND) || isa<NamespaceAliasDecl>(ND);
740}
741
Douglas Gregor99fe2ad2009-12-11 17:31:05 +0000742/// \brief Determines whether the given declaration is a type.
Douglas Gregor3545ff42009-09-21 16:56:56 +0000743bool ResultBuilder::IsType(NamedDecl *ND) const {
744 return isa<TypeDecl>(ND);
745}
746
Douglas Gregor99fe2ad2009-12-11 17:31:05 +0000747/// \brief Determines which members of a class should be visible via
748/// "." or "->". Only value declarations, nested name specifiers, and
749/// using declarations thereof should show up.
Douglas Gregore412a5a2009-09-23 22:26:46 +0000750bool ResultBuilder::IsMember(NamedDecl *ND) const {
Douglas Gregor99fe2ad2009-12-11 17:31:05 +0000751 if (UsingShadowDecl *Using = dyn_cast<UsingShadowDecl>(ND))
752 ND = Using->getTargetDecl();
753
Douglas Gregor70788392009-12-11 18:14:22 +0000754 return isa<ValueDecl>(ND) || isa<FunctionTemplateDecl>(ND) ||
755 isa<ObjCPropertyDecl>(ND);
Douglas Gregore412a5a2009-09-23 22:26:46 +0000756}
757
Douglas Gregora817a192010-05-27 23:06:34 +0000758/// \brief Get the type that a given expression will have if this declaration
759/// is used as an expression in its "typical" code-completion form.
760static QualType getDeclUsageType(ASTContext &C, NamedDecl *ND) {
761 ND = cast<NamedDecl>(ND->getUnderlyingDecl());
762
763 if (TypeDecl *Type = dyn_cast<TypeDecl>(ND))
764 return C.getTypeDeclType(Type);
765 if (ObjCInterfaceDecl *Iface = dyn_cast<ObjCInterfaceDecl>(ND))
766 return C.getObjCInterfaceType(Iface);
767
768 QualType T;
769 if (FunctionDecl *Function = dyn_cast<FunctionDecl>(ND))
770 T = Function->getResultType();
771 else if (ObjCMethodDecl *Method = dyn_cast<ObjCMethodDecl>(ND))
772 T = Method->getResultType();
773 else if (FunctionTemplateDecl *FunTmpl = dyn_cast<FunctionTemplateDecl>(ND))
774 T = FunTmpl->getTemplatedDecl()->getResultType();
775 else if (EnumConstantDecl *Enumerator = dyn_cast<EnumConstantDecl>(ND))
776 T = C.getTypeDeclType(cast<EnumDecl>(Enumerator->getDeclContext()));
777 else if (ObjCPropertyDecl *Property = dyn_cast<ObjCPropertyDecl>(ND))
778 T = Property->getType();
779 else if (ValueDecl *Value = dyn_cast<ValueDecl>(ND))
780 T = Value->getType();
781 else
782 return QualType();
783
784 return T.getNonReferenceType();
785}
786
787static bool isObjCReceiverType(ASTContext &C, QualType T) {
788 T = C.getCanonicalType(T);
789 switch (T->getTypeClass()) {
790 case Type::ObjCObject:
791 case Type::ObjCInterface:
792 case Type::ObjCObjectPointer:
793 return true;
794
795 case Type::Builtin:
796 switch (cast<BuiltinType>(T)->getKind()) {
797 case BuiltinType::ObjCId:
798 case BuiltinType::ObjCClass:
799 case BuiltinType::ObjCSel:
800 return true;
801
802 default:
803 break;
804 }
805 return false;
806
807 default:
808 break;
809 }
810
811 if (!C.getLangOptions().CPlusPlus)
812 return false;
813
814 // FIXME: We could perform more analysis here to determine whether a
815 // particular class type has any conversions to Objective-C types. For now,
816 // just accept all class types.
817 return T->isDependentType() || T->isRecordType();
818}
819
820bool ResultBuilder::IsObjCMessageReceiver(NamedDecl *ND) const {
821 QualType T = getDeclUsageType(SemaRef.Context, ND);
822 if (T.isNull())
823 return false;
824
825 T = SemaRef.Context.getBaseElementType(T);
826 return isObjCReceiverType(SemaRef.Context, T);
827}
828
829
Douglas Gregor2b8162b2010-01-14 16:08:12 +0000830/// \rief Determines whether the given declaration is an Objective-C
831/// instance variable.
832bool ResultBuilder::IsObjCIvar(NamedDecl *ND) const {
833 return isa<ObjCIvarDecl>(ND);
834}
835
Douglas Gregorc580c522010-01-14 01:09:38 +0000836namespace {
837 /// \brief Visible declaration consumer that adds a code-completion result
838 /// for each visible declaration.
839 class CodeCompletionDeclConsumer : public VisibleDeclConsumer {
840 ResultBuilder &Results;
841 DeclContext *CurContext;
842
843 public:
844 CodeCompletionDeclConsumer(ResultBuilder &Results, DeclContext *CurContext)
845 : Results(Results), CurContext(CurContext) { }
846
Douglas Gregor09bbc652010-01-14 15:47:35 +0000847 virtual void FoundDecl(NamedDecl *ND, NamedDecl *Hiding, bool InBaseClass) {
848 Results.AddResult(ND, CurContext, Hiding, InBaseClass);
Douglas Gregorc580c522010-01-14 01:09:38 +0000849 }
850 };
851}
852
Douglas Gregor3545ff42009-09-21 16:56:56 +0000853/// \brief Add type specifiers for the current language as keyword results.
Douglas Gregorf98e6a22010-01-13 23:51:12 +0000854static void AddTypeSpecifierResults(const LangOptions &LangOpts,
Douglas Gregor3545ff42009-09-21 16:56:56 +0000855 ResultBuilder &Results) {
856 typedef CodeCompleteConsumer::Result Result;
Douglas Gregora2db7932010-05-26 22:00:08 +0000857 Results.AddResult(Result("short", CCP_Type));
858 Results.AddResult(Result("long", CCP_Type));
859 Results.AddResult(Result("signed", CCP_Type));
860 Results.AddResult(Result("unsigned", CCP_Type));
861 Results.AddResult(Result("void", CCP_Type));
862 Results.AddResult(Result("char", CCP_Type));
863 Results.AddResult(Result("int", CCP_Type));
864 Results.AddResult(Result("float", CCP_Type));
865 Results.AddResult(Result("double", CCP_Type));
866 Results.AddResult(Result("enum", CCP_Type));
867 Results.AddResult(Result("struct", CCP_Type));
868 Results.AddResult(Result("union", CCP_Type));
869 Results.AddResult(Result("const", CCP_Type));
870 Results.AddResult(Result("volatile", CCP_Type));
Douglas Gregor504a6ae2010-01-10 23:08:15 +0000871
Douglas Gregor3545ff42009-09-21 16:56:56 +0000872 if (LangOpts.C99) {
873 // C99-specific
Douglas Gregora2db7932010-05-26 22:00:08 +0000874 Results.AddResult(Result("_Complex", CCP_Type));
875 Results.AddResult(Result("_Imaginary", CCP_Type));
876 Results.AddResult(Result("_Bool", CCP_Type));
877 Results.AddResult(Result("restrict", CCP_Type));
Douglas Gregor3545ff42009-09-21 16:56:56 +0000878 }
879
880 if (LangOpts.CPlusPlus) {
881 // C++-specific
Douglas Gregora2db7932010-05-26 22:00:08 +0000882 Results.AddResult(Result("bool", CCP_Type));
883 Results.AddResult(Result("class", CCP_Type));
884 Results.AddResult(Result("wchar_t", CCP_Type));
Douglas Gregor3545ff42009-09-21 16:56:56 +0000885
Douglas Gregorf4c33342010-05-28 00:22:41 +0000886 // typename qualified-id
887 CodeCompletionString *Pattern = new CodeCompletionString;
888 Pattern->AddTypedTextChunk("typename");
889 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
890 Pattern->AddPlaceholderChunk("qualifier");
891 Pattern->AddTextChunk("::");
892 Pattern->AddPlaceholderChunk("name");
893 Results.AddResult(Result(Pattern));
Douglas Gregorf64acca2010-05-25 21:41:55 +0000894
Douglas Gregor3545ff42009-09-21 16:56:56 +0000895 if (LangOpts.CPlusPlus0x) {
Douglas Gregora2db7932010-05-26 22:00:08 +0000896 Results.AddResult(Result("auto", CCP_Type));
897 Results.AddResult(Result("char16_t", CCP_Type));
898 Results.AddResult(Result("char32_t", CCP_Type));
Douglas Gregorf4c33342010-05-28 00:22:41 +0000899
900 CodeCompletionString *Pattern = new CodeCompletionString;
901 Pattern->AddTypedTextChunk("decltype");
902 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
903 Pattern->AddPlaceholderChunk("expression");
904 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
905 Results.AddResult(Result(Pattern));
Douglas Gregor3545ff42009-09-21 16:56:56 +0000906 }
907 }
908
909 // GNU extensions
910 if (LangOpts.GNUMode) {
911 // FIXME: Enable when we actually support decimal floating point.
Douglas Gregor78a21012010-01-14 16:01:26 +0000912 // Results.AddResult(Result("_Decimal32"));
913 // Results.AddResult(Result("_Decimal64"));
914 // Results.AddResult(Result("_Decimal128"));
Douglas Gregor504a6ae2010-01-10 23:08:15 +0000915
Douglas Gregorf4c33342010-05-28 00:22:41 +0000916 CodeCompletionString *Pattern = new CodeCompletionString;
917 Pattern->AddTypedTextChunk("typeof");
918 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
919 Pattern->AddPlaceholderChunk("expression");
920 Results.AddResult(Result(Pattern));
921
922 Pattern = new CodeCompletionString;
923 Pattern->AddTypedTextChunk("typeof");
924 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
925 Pattern->AddPlaceholderChunk("type");
926 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
927 Results.AddResult(Result(Pattern));
Douglas Gregor3545ff42009-09-21 16:56:56 +0000928 }
929}
930
Douglas Gregor504a6ae2010-01-10 23:08:15 +0000931static void AddStorageSpecifiers(Action::CodeCompletionContext CCC,
932 const LangOptions &LangOpts,
Douglas Gregor504a6ae2010-01-10 23:08:15 +0000933 ResultBuilder &Results) {
934 typedef CodeCompleteConsumer::Result Result;
935 // Note: we don't suggest either "auto" or "register", because both
936 // are pointless as storage specifiers. Elsewhere, we suggest "auto"
937 // in C++0x as a type specifier.
Douglas Gregor78a21012010-01-14 16:01:26 +0000938 Results.AddResult(Result("extern"));
939 Results.AddResult(Result("static"));
Douglas Gregor504a6ae2010-01-10 23:08:15 +0000940}
941
942static void AddFunctionSpecifiers(Action::CodeCompletionContext CCC,
943 const LangOptions &LangOpts,
Douglas Gregor504a6ae2010-01-10 23:08:15 +0000944 ResultBuilder &Results) {
945 typedef CodeCompleteConsumer::Result Result;
946 switch (CCC) {
947 case Action::CCC_Class:
948 case Action::CCC_MemberTemplate:
949 if (LangOpts.CPlusPlus) {
Douglas Gregor78a21012010-01-14 16:01:26 +0000950 Results.AddResult(Result("explicit"));
951 Results.AddResult(Result("friend"));
952 Results.AddResult(Result("mutable"));
953 Results.AddResult(Result("virtual"));
Douglas Gregor504a6ae2010-01-10 23:08:15 +0000954 }
955 // Fall through
956
Douglas Gregorf1934162010-01-13 21:24:21 +0000957 case Action::CCC_ObjCInterface:
958 case Action::CCC_ObjCImplementation:
Douglas Gregor504a6ae2010-01-10 23:08:15 +0000959 case Action::CCC_Namespace:
960 case Action::CCC_Template:
961 if (LangOpts.CPlusPlus || LangOpts.C99)
Douglas Gregor78a21012010-01-14 16:01:26 +0000962 Results.AddResult(Result("inline"));
Douglas Gregor504a6ae2010-01-10 23:08:15 +0000963 break;
964
Douglas Gregor48d46252010-01-13 21:54:15 +0000965 case Action::CCC_ObjCInstanceVariableList:
Douglas Gregor504a6ae2010-01-10 23:08:15 +0000966 case Action::CCC_Expression:
967 case Action::CCC_Statement:
968 case Action::CCC_ForInit:
969 case Action::CCC_Condition:
Douglas Gregor6da3db42010-05-25 05:58:43 +0000970 case Action::CCC_RecoveryInFunction:
Douglas Gregor504a6ae2010-01-10 23:08:15 +0000971 break;
972 }
973}
974
Douglas Gregorf98e6a22010-01-13 23:51:12 +0000975static void AddObjCExpressionResults(ResultBuilder &Results, bool NeedAt);
976static void AddObjCStatementResults(ResultBuilder &Results, bool NeedAt);
977static void AddObjCVisibilityResults(const LangOptions &LangOpts,
Douglas Gregor48d46252010-01-13 21:54:15 +0000978 ResultBuilder &Results,
979 bool NeedAt);
Douglas Gregorf98e6a22010-01-13 23:51:12 +0000980static void AddObjCImplementationResults(const LangOptions &LangOpts,
Douglas Gregorf1934162010-01-13 21:24:21 +0000981 ResultBuilder &Results,
982 bool NeedAt);
Douglas Gregorf98e6a22010-01-13 23:51:12 +0000983static void AddObjCInterfaceResults(const LangOptions &LangOpts,
Douglas Gregorf1934162010-01-13 21:24:21 +0000984 ResultBuilder &Results,
985 bool NeedAt);
Douglas Gregorf98e6a22010-01-13 23:51:12 +0000986static void AddObjCTopLevelResults(ResultBuilder &Results, bool NeedAt);
Douglas Gregorf1934162010-01-13 21:24:21 +0000987
Douglas Gregorf4c33342010-05-28 00:22:41 +0000988static void AddTypedefResult(ResultBuilder &Results) {
989 CodeCompletionString *Pattern = new CodeCompletionString;
990 Pattern->AddTypedTextChunk("typedef");
991 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
992 Pattern->AddPlaceholderChunk("type");
993 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
994 Pattern->AddPlaceholderChunk("name");
995 Results.AddResult(CodeCompleteConsumer::Result(Pattern));
996}
997
Douglas Gregor70febae2010-05-28 00:49:12 +0000998static bool WantTypesInContext(Action::CodeCompletionContext CCC,
999 const LangOptions &LangOpts) {
1000 if (LangOpts.CPlusPlus)
1001 return true;
1002
1003 switch (CCC) {
1004 case Action::CCC_Namespace:
1005 case Action::CCC_Class:
1006 case Action::CCC_ObjCInstanceVariableList:
1007 case Action::CCC_Template:
1008 case Action::CCC_MemberTemplate:
1009 case Action::CCC_Statement:
1010 case Action::CCC_RecoveryInFunction:
1011 return true;
1012
1013 case Action::CCC_ObjCInterface:
1014 case Action::CCC_ObjCImplementation:
1015 case Action::CCC_Expression:
1016 case Action::CCC_Condition:
1017 return false;
1018
1019 case Action::CCC_ForInit:
1020 return LangOpts.ObjC1 || LangOpts.C99;
1021 }
1022
1023 return false;
1024}
1025
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001026/// \brief Add language constructs that show up for "ordinary" names.
1027static void AddOrdinaryNameResults(Action::CodeCompletionContext CCC,
1028 Scope *S,
1029 Sema &SemaRef,
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001030 ResultBuilder &Results) {
1031 typedef CodeCompleteConsumer::Result Result;
1032 switch (CCC) {
1033 case Action::CCC_Namespace:
Douglas Gregorf4c33342010-05-28 00:22:41 +00001034 if (SemaRef.getLangOptions().CPlusPlus) {
1035 CodeCompletionString *Pattern = 0;
1036
1037 if (Results.includeCodePatterns()) {
1038 // namespace <identifier> { declarations }
1039 CodeCompletionString *Pattern = new CodeCompletionString;
1040 Pattern->AddTypedTextChunk("namespace");
1041 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
1042 Pattern->AddPlaceholderChunk("identifier");
1043 Pattern->AddChunk(CodeCompletionString::CK_LeftBrace);
1044 Pattern->AddPlaceholderChunk("declarations");
1045 Pattern->AddChunk(CodeCompletionString::CK_VerticalSpace);
1046 Pattern->AddChunk(CodeCompletionString::CK_RightBrace);
1047 Results.AddResult(Result(Pattern));
1048 }
1049
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001050 // namespace identifier = identifier ;
1051 Pattern = new CodeCompletionString;
1052 Pattern->AddTypedTextChunk("namespace");
1053 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
Douglas Gregorf4c33342010-05-28 00:22:41 +00001054 Pattern->AddPlaceholderChunk("name");
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001055 Pattern->AddChunk(CodeCompletionString::CK_Equal);
Douglas Gregorf4c33342010-05-28 00:22:41 +00001056 Pattern->AddPlaceholderChunk("namespace");
Douglas Gregor78a21012010-01-14 16:01:26 +00001057 Results.AddResult(Result(Pattern));
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001058
1059 // Using directives
1060 Pattern = new CodeCompletionString;
1061 Pattern->AddTypedTextChunk("using");
1062 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
1063 Pattern->AddTextChunk("namespace");
1064 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
1065 Pattern->AddPlaceholderChunk("identifier");
Douglas Gregor78a21012010-01-14 16:01:26 +00001066 Results.AddResult(Result(Pattern));
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001067
1068 // asm(string-literal)
1069 Pattern = new CodeCompletionString;
1070 Pattern->AddTypedTextChunk("asm");
1071 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
1072 Pattern->AddPlaceholderChunk("string-literal");
1073 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
Douglas Gregor78a21012010-01-14 16:01:26 +00001074 Results.AddResult(Result(Pattern));
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001075
Douglas Gregorf4c33342010-05-28 00:22:41 +00001076 if (Results.includeCodePatterns()) {
1077 // Explicit template instantiation
1078 Pattern = new CodeCompletionString;
1079 Pattern->AddTypedTextChunk("template");
1080 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
1081 Pattern->AddPlaceholderChunk("declaration");
1082 Results.AddResult(Result(Pattern));
1083 }
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001084 }
Douglas Gregorf1934162010-01-13 21:24:21 +00001085
1086 if (SemaRef.getLangOptions().ObjC1)
Douglas Gregorf98e6a22010-01-13 23:51:12 +00001087 AddObjCTopLevelResults(Results, true);
Douglas Gregorf1934162010-01-13 21:24:21 +00001088
Douglas Gregorf4c33342010-05-28 00:22:41 +00001089 AddTypedefResult(Results);
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001090 // Fall through
1091
1092 case Action::CCC_Class:
Douglas Gregorf4c33342010-05-28 00:22:41 +00001093 if (SemaRef.getLangOptions().CPlusPlus) {
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001094 // Using declaration
1095 CodeCompletionString *Pattern = new CodeCompletionString;
1096 Pattern->AddTypedTextChunk("using");
1097 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
Douglas Gregorf4c33342010-05-28 00:22:41 +00001098 Pattern->AddPlaceholderChunk("qualifier");
1099 Pattern->AddTextChunk("::");
1100 Pattern->AddPlaceholderChunk("name");
Douglas Gregor78a21012010-01-14 16:01:26 +00001101 Results.AddResult(Result(Pattern));
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001102
Douglas Gregorf4c33342010-05-28 00:22:41 +00001103 // using typename qualifier::name (only in a dependent context)
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001104 if (SemaRef.CurContext->isDependentContext()) {
1105 Pattern = new CodeCompletionString;
1106 Pattern->AddTypedTextChunk("using");
1107 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
1108 Pattern->AddTextChunk("typename");
1109 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
Douglas Gregorf4c33342010-05-28 00:22:41 +00001110 Pattern->AddPlaceholderChunk("qualifier");
1111 Pattern->AddTextChunk("::");
1112 Pattern->AddPlaceholderChunk("name");
Douglas Gregor78a21012010-01-14 16:01:26 +00001113 Results.AddResult(Result(Pattern));
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001114 }
1115
1116 if (CCC == Action::CCC_Class) {
Douglas Gregorf4c33342010-05-28 00:22:41 +00001117 AddTypedefResult(Results);
1118
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001119 // public:
1120 Pattern = new CodeCompletionString;
1121 Pattern->AddTypedTextChunk("public");
1122 Pattern->AddChunk(CodeCompletionString::CK_Colon);
Douglas Gregor78a21012010-01-14 16:01:26 +00001123 Results.AddResult(Result(Pattern));
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001124
1125 // protected:
1126 Pattern = new CodeCompletionString;
1127 Pattern->AddTypedTextChunk("protected");
1128 Pattern->AddChunk(CodeCompletionString::CK_Colon);
Douglas Gregor78a21012010-01-14 16:01:26 +00001129 Results.AddResult(Result(Pattern));
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001130
1131 // private:
1132 Pattern = new CodeCompletionString;
1133 Pattern->AddTypedTextChunk("private");
1134 Pattern->AddChunk(CodeCompletionString::CK_Colon);
Douglas Gregor78a21012010-01-14 16:01:26 +00001135 Results.AddResult(Result(Pattern));
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001136 }
1137 }
1138 // Fall through
1139
1140 case Action::CCC_Template:
1141 case Action::CCC_MemberTemplate:
Douglas Gregorf64acca2010-05-25 21:41:55 +00001142 if (SemaRef.getLangOptions().CPlusPlus && Results.includeCodePatterns()) {
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001143 // template < parameters >
1144 CodeCompletionString *Pattern = new CodeCompletionString;
1145 Pattern->AddTypedTextChunk("template");
1146 Pattern->AddChunk(CodeCompletionString::CK_LeftAngle);
1147 Pattern->AddPlaceholderChunk("parameters");
1148 Pattern->AddChunk(CodeCompletionString::CK_RightAngle);
Douglas Gregor78a21012010-01-14 16:01:26 +00001149 Results.AddResult(Result(Pattern));
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001150 }
1151
Douglas Gregorf98e6a22010-01-13 23:51:12 +00001152 AddStorageSpecifiers(CCC, SemaRef.getLangOptions(), Results);
1153 AddFunctionSpecifiers(CCC, SemaRef.getLangOptions(), Results);
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001154 break;
1155
Douglas Gregorf1934162010-01-13 21:24:21 +00001156 case Action::CCC_ObjCInterface:
Douglas Gregorf98e6a22010-01-13 23:51:12 +00001157 AddObjCInterfaceResults(SemaRef.getLangOptions(), Results, true);
1158 AddStorageSpecifiers(CCC, SemaRef.getLangOptions(), Results);
1159 AddFunctionSpecifiers(CCC, SemaRef.getLangOptions(), Results);
Douglas Gregorf1934162010-01-13 21:24:21 +00001160 break;
1161
1162 case Action::CCC_ObjCImplementation:
Douglas Gregorf98e6a22010-01-13 23:51:12 +00001163 AddObjCImplementationResults(SemaRef.getLangOptions(), Results, true);
1164 AddStorageSpecifiers(CCC, SemaRef.getLangOptions(), Results);
1165 AddFunctionSpecifiers(CCC, SemaRef.getLangOptions(), Results);
Douglas Gregorf1934162010-01-13 21:24:21 +00001166 break;
1167
Douglas Gregor48d46252010-01-13 21:54:15 +00001168 case Action::CCC_ObjCInstanceVariableList:
Douglas Gregorf98e6a22010-01-13 23:51:12 +00001169 AddObjCVisibilityResults(SemaRef.getLangOptions(), Results, true);
Douglas Gregor48d46252010-01-13 21:54:15 +00001170 break;
1171
Douglas Gregor6da3db42010-05-25 05:58:43 +00001172 case Action::CCC_RecoveryInFunction:
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001173 case Action::CCC_Statement: {
Douglas Gregorf4c33342010-05-28 00:22:41 +00001174 AddTypedefResult(Results);
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001175
1176 CodeCompletionString *Pattern = 0;
Douglas Gregorf64acca2010-05-25 21:41:55 +00001177 if (SemaRef.getLangOptions().CPlusPlus && Results.includeCodePatterns()) {
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001178 Pattern = new CodeCompletionString;
1179 Pattern->AddTypedTextChunk("try");
1180 Pattern->AddChunk(CodeCompletionString::CK_LeftBrace);
1181 Pattern->AddPlaceholderChunk("statements");
1182 Pattern->AddChunk(CodeCompletionString::CK_VerticalSpace);
1183 Pattern->AddChunk(CodeCompletionString::CK_RightBrace);
1184 Pattern->AddTextChunk("catch");
1185 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
1186 Pattern->AddPlaceholderChunk("declaration");
1187 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
1188 Pattern->AddChunk(CodeCompletionString::CK_LeftBrace);
1189 Pattern->AddPlaceholderChunk("statements");
1190 Pattern->AddChunk(CodeCompletionString::CK_VerticalSpace);
1191 Pattern->AddChunk(CodeCompletionString::CK_RightBrace);
Douglas Gregor78a21012010-01-14 16:01:26 +00001192 Results.AddResult(Result(Pattern));
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001193 }
Douglas Gregorf1934162010-01-13 21:24:21 +00001194 if (SemaRef.getLangOptions().ObjC1)
Douglas Gregorf98e6a22010-01-13 23:51:12 +00001195 AddObjCStatementResults(Results, true);
Douglas Gregorf1934162010-01-13 21:24:21 +00001196
Douglas Gregorf64acca2010-05-25 21:41:55 +00001197 if (Results.includeCodePatterns()) {
1198 // if (condition) { statements }
1199 Pattern = new CodeCompletionString;
1200 Pattern->AddTypedTextChunk("if");
1201 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
1202 if (SemaRef.getLangOptions().CPlusPlus)
1203 Pattern->AddPlaceholderChunk("condition");
1204 else
1205 Pattern->AddPlaceholderChunk("expression");
1206 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
1207 Pattern->AddChunk(CodeCompletionString::CK_LeftBrace);
1208 Pattern->AddPlaceholderChunk("statements");
1209 Pattern->AddChunk(CodeCompletionString::CK_VerticalSpace);
1210 Pattern->AddChunk(CodeCompletionString::CK_RightBrace);
1211 Results.AddResult(Result(Pattern));
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001212
Douglas Gregorf64acca2010-05-25 21:41:55 +00001213 // switch (condition) { }
1214 Pattern = new CodeCompletionString;
1215 Pattern->AddTypedTextChunk("switch");
1216 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
1217 if (SemaRef.getLangOptions().CPlusPlus)
1218 Pattern->AddPlaceholderChunk("condition");
1219 else
1220 Pattern->AddPlaceholderChunk("expression");
1221 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
1222 Pattern->AddChunk(CodeCompletionString::CK_LeftBrace);
1223 Pattern->AddChunk(CodeCompletionString::CK_VerticalSpace);
1224 Pattern->AddChunk(CodeCompletionString::CK_RightBrace);
1225 Results.AddResult(Result(Pattern));
1226 }
1227
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001228 // Switch-specific statements.
Douglas Gregorf4c33342010-05-28 00:22:41 +00001229 if (!SemaRef.getSwitchStack().empty()) {
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001230 // case expression:
1231 Pattern = new CodeCompletionString;
1232 Pattern->AddTypedTextChunk("case");
Douglas Gregorf4c33342010-05-28 00:22:41 +00001233 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001234 Pattern->AddPlaceholderChunk("expression");
1235 Pattern->AddChunk(CodeCompletionString::CK_Colon);
Douglas Gregor78a21012010-01-14 16:01:26 +00001236 Results.AddResult(Result(Pattern));
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001237
1238 // default:
1239 Pattern = new CodeCompletionString;
1240 Pattern->AddTypedTextChunk("default");
1241 Pattern->AddChunk(CodeCompletionString::CK_Colon);
Douglas Gregor78a21012010-01-14 16:01:26 +00001242 Results.AddResult(Result(Pattern));
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001243 }
1244
Douglas Gregorf64acca2010-05-25 21:41:55 +00001245 if (Results.includeCodePatterns()) {
1246 /// while (condition) { statements }
1247 Pattern = new CodeCompletionString;
1248 Pattern->AddTypedTextChunk("while");
1249 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
1250 if (SemaRef.getLangOptions().CPlusPlus)
1251 Pattern->AddPlaceholderChunk("condition");
1252 else
1253 Pattern->AddPlaceholderChunk("expression");
1254 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
1255 Pattern->AddChunk(CodeCompletionString::CK_LeftBrace);
1256 Pattern->AddPlaceholderChunk("statements");
1257 Pattern->AddChunk(CodeCompletionString::CK_VerticalSpace);
1258 Pattern->AddChunk(CodeCompletionString::CK_RightBrace);
1259 Results.AddResult(Result(Pattern));
1260
1261 // do { statements } while ( expression );
1262 Pattern = new CodeCompletionString;
1263 Pattern->AddTypedTextChunk("do");
1264 Pattern->AddChunk(CodeCompletionString::CK_LeftBrace);
1265 Pattern->AddPlaceholderChunk("statements");
1266 Pattern->AddChunk(CodeCompletionString::CK_VerticalSpace);
1267 Pattern->AddChunk(CodeCompletionString::CK_RightBrace);
1268 Pattern->AddTextChunk("while");
1269 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001270 Pattern->AddPlaceholderChunk("expression");
Douglas Gregorf64acca2010-05-25 21:41:55 +00001271 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
1272 Results.AddResult(Result(Pattern));
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001273
Douglas Gregorf64acca2010-05-25 21:41:55 +00001274 // for ( for-init-statement ; condition ; expression ) { statements }
1275 Pattern = new CodeCompletionString;
1276 Pattern->AddTypedTextChunk("for");
1277 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
1278 if (SemaRef.getLangOptions().CPlusPlus || SemaRef.getLangOptions().C99)
1279 Pattern->AddPlaceholderChunk("init-statement");
1280 else
1281 Pattern->AddPlaceholderChunk("init-expression");
1282 Pattern->AddChunk(CodeCompletionString::CK_SemiColon);
1283 Pattern->AddPlaceholderChunk("condition");
1284 Pattern->AddChunk(CodeCompletionString::CK_SemiColon);
1285 Pattern->AddPlaceholderChunk("inc-expression");
1286 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
1287 Pattern->AddChunk(CodeCompletionString::CK_LeftBrace);
1288 Pattern->AddPlaceholderChunk("statements");
1289 Pattern->AddChunk(CodeCompletionString::CK_VerticalSpace);
1290 Pattern->AddChunk(CodeCompletionString::CK_RightBrace);
1291 Results.AddResult(Result(Pattern));
1292 }
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001293
1294 if (S->getContinueParent()) {
1295 // continue ;
1296 Pattern = new CodeCompletionString;
1297 Pattern->AddTypedTextChunk("continue");
Douglas Gregor78a21012010-01-14 16:01:26 +00001298 Results.AddResult(Result(Pattern));
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001299 }
1300
1301 if (S->getBreakParent()) {
1302 // break ;
1303 Pattern = new CodeCompletionString;
1304 Pattern->AddTypedTextChunk("break");
Douglas Gregor78a21012010-01-14 16:01:26 +00001305 Results.AddResult(Result(Pattern));
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001306 }
1307
1308 // "return expression ;" or "return ;", depending on whether we
1309 // know the function is void or not.
1310 bool isVoid = false;
1311 if (FunctionDecl *Function = dyn_cast<FunctionDecl>(SemaRef.CurContext))
1312 isVoid = Function->getResultType()->isVoidType();
1313 else if (ObjCMethodDecl *Method
1314 = dyn_cast<ObjCMethodDecl>(SemaRef.CurContext))
1315 isVoid = Method->getResultType()->isVoidType();
Douglas Gregor9a28e842010-03-01 23:15:13 +00001316 else if (SemaRef.getCurBlock() &&
1317 !SemaRef.getCurBlock()->ReturnType.isNull())
1318 isVoid = SemaRef.getCurBlock()->ReturnType->isVoidType();
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001319 Pattern = new CodeCompletionString;
1320 Pattern->AddTypedTextChunk("return");
Douglas Gregor44272ca2010-02-18 04:06:48 +00001321 if (!isVoid) {
1322 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001323 Pattern->AddPlaceholderChunk("expression");
Douglas Gregor44272ca2010-02-18 04:06:48 +00001324 }
Douglas Gregor78a21012010-01-14 16:01:26 +00001325 Results.AddResult(Result(Pattern));
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001326
Douglas Gregorf4c33342010-05-28 00:22:41 +00001327 // goto identifier ;
1328 Pattern = new CodeCompletionString;
1329 Pattern->AddTypedTextChunk("goto");
1330 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
1331 Pattern->AddPlaceholderChunk("label");
1332 Results.AddResult(Result(Pattern));
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001333
Douglas Gregorf4c33342010-05-28 00:22:41 +00001334 // Using directives
1335 Pattern = new CodeCompletionString;
1336 Pattern->AddTypedTextChunk("using");
1337 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
1338 Pattern->AddTextChunk("namespace");
1339 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
1340 Pattern->AddPlaceholderChunk("identifier");
1341 Results.AddResult(Result(Pattern));
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001342 }
1343
1344 // Fall through (for statement expressions).
1345 case Action::CCC_ForInit:
1346 case Action::CCC_Condition:
Douglas Gregorf98e6a22010-01-13 23:51:12 +00001347 AddStorageSpecifiers(CCC, SemaRef.getLangOptions(), Results);
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001348 // Fall through: conditions and statements can have expressions.
1349
1350 case Action::CCC_Expression: {
1351 CodeCompletionString *Pattern = 0;
1352 if (SemaRef.getLangOptions().CPlusPlus) {
1353 // 'this', if we're in a non-static member function.
1354 if (CXXMethodDecl *Method = dyn_cast<CXXMethodDecl>(SemaRef.CurContext))
1355 if (!Method->isStatic())
Douglas Gregor78a21012010-01-14 16:01:26 +00001356 Results.AddResult(Result("this"));
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001357
1358 // true, false
Douglas Gregor78a21012010-01-14 16:01:26 +00001359 Results.AddResult(Result("true"));
1360 Results.AddResult(Result("false"));
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001361
Douglas Gregorf4c33342010-05-28 00:22:41 +00001362 // dynamic_cast < type-id > ( expression )
1363 Pattern = new CodeCompletionString;
1364 Pattern->AddTypedTextChunk("dynamic_cast");
1365 Pattern->AddChunk(CodeCompletionString::CK_LeftAngle);
1366 Pattern->AddPlaceholderChunk("type");
1367 Pattern->AddChunk(CodeCompletionString::CK_RightAngle);
1368 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
1369 Pattern->AddPlaceholderChunk("expression");
1370 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
1371 Results.AddResult(Result(Pattern));
1372
1373 // static_cast < type-id > ( expression )
1374 Pattern = new CodeCompletionString;
1375 Pattern->AddTypedTextChunk("static_cast");
1376 Pattern->AddChunk(CodeCompletionString::CK_LeftAngle);
1377 Pattern->AddPlaceholderChunk("type");
1378 Pattern->AddChunk(CodeCompletionString::CK_RightAngle);
1379 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
1380 Pattern->AddPlaceholderChunk("expression");
1381 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
1382 Results.AddResult(Result(Pattern));
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001383
Douglas Gregorf4c33342010-05-28 00:22:41 +00001384 // reinterpret_cast < type-id > ( expression )
1385 Pattern = new CodeCompletionString;
1386 Pattern->AddTypedTextChunk("reinterpret_cast");
1387 Pattern->AddChunk(CodeCompletionString::CK_LeftAngle);
1388 Pattern->AddPlaceholderChunk("type");
1389 Pattern->AddChunk(CodeCompletionString::CK_RightAngle);
1390 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
1391 Pattern->AddPlaceholderChunk("expression");
1392 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
1393 Results.AddResult(Result(Pattern));
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001394
Douglas Gregorf4c33342010-05-28 00:22:41 +00001395 // const_cast < type-id > ( expression )
1396 Pattern = new CodeCompletionString;
1397 Pattern->AddTypedTextChunk("const_cast");
1398 Pattern->AddChunk(CodeCompletionString::CK_LeftAngle);
1399 Pattern->AddPlaceholderChunk("type");
1400 Pattern->AddChunk(CodeCompletionString::CK_RightAngle);
1401 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
1402 Pattern->AddPlaceholderChunk("expression");
1403 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
1404 Results.AddResult(Result(Pattern));
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001405
Douglas Gregorf4c33342010-05-28 00:22:41 +00001406 // typeid ( expression-or-type )
1407 Pattern = new CodeCompletionString;
1408 Pattern->AddTypedTextChunk("typeid");
1409 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
1410 Pattern->AddPlaceholderChunk("expression-or-type");
1411 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
1412 Results.AddResult(Result(Pattern));
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001413
Douglas Gregorf4c33342010-05-28 00:22:41 +00001414 // new T ( ... )
1415 Pattern = new CodeCompletionString;
1416 Pattern->AddTypedTextChunk("new");
1417 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
1418 Pattern->AddPlaceholderChunk("type");
1419 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
1420 Pattern->AddPlaceholderChunk("expressions");
1421 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
1422 Results.AddResult(Result(Pattern));
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001423
Douglas Gregorf4c33342010-05-28 00:22:41 +00001424 // new T [ ] ( ... )
1425 Pattern = new CodeCompletionString;
1426 Pattern->AddTypedTextChunk("new");
1427 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
1428 Pattern->AddPlaceholderChunk("type");
1429 Pattern->AddChunk(CodeCompletionString::CK_LeftBracket);
1430 Pattern->AddPlaceholderChunk("size");
1431 Pattern->AddChunk(CodeCompletionString::CK_RightBracket);
1432 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
1433 Pattern->AddPlaceholderChunk("expressions");
1434 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
1435 Results.AddResult(Result(Pattern));
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001436
Douglas Gregorf4c33342010-05-28 00:22:41 +00001437 // delete expression
1438 Pattern = new CodeCompletionString;
1439 Pattern->AddTypedTextChunk("delete");
1440 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
1441 Pattern->AddPlaceholderChunk("expression");
1442 Results.AddResult(Result(Pattern));
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001443
Douglas Gregorf4c33342010-05-28 00:22:41 +00001444 // delete [] expression
1445 Pattern = new CodeCompletionString;
1446 Pattern->AddTypedTextChunk("delete");
1447 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
1448 Pattern->AddChunk(CodeCompletionString::CK_LeftBracket);
1449 Pattern->AddChunk(CodeCompletionString::CK_RightBracket);
1450 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
1451 Pattern->AddPlaceholderChunk("expression");
1452 Results.AddResult(Result(Pattern));
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001453
Douglas Gregorf4c33342010-05-28 00:22:41 +00001454 // throw expression
1455 Pattern = new CodeCompletionString;
1456 Pattern->AddTypedTextChunk("throw");
1457 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
1458 Pattern->AddPlaceholderChunk("expression");
1459 Results.AddResult(Result(Pattern));
Douglas Gregora2db7932010-05-26 22:00:08 +00001460
1461 // FIXME: Rethrow?
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001462 }
1463
1464 if (SemaRef.getLangOptions().ObjC1) {
1465 // Add "super", if we're in an Objective-C class with a superclass.
1466 if (ObjCMethodDecl *Method = SemaRef.getCurMethodDecl())
1467 if (Method->getClassInterface()->getSuperClass())
Douglas Gregor78a21012010-01-14 16:01:26 +00001468 Results.AddResult(Result("super"));
Douglas Gregorf1934162010-01-13 21:24:21 +00001469
Douglas Gregorf98e6a22010-01-13 23:51:12 +00001470 AddObjCExpressionResults(Results, true);
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001471 }
1472
Douglas Gregorf4c33342010-05-28 00:22:41 +00001473 // sizeof expression
1474 Pattern = new CodeCompletionString;
1475 Pattern->AddTypedTextChunk("sizeof");
1476 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
1477 Pattern->AddPlaceholderChunk("expression-or-type");
1478 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
1479 Results.AddResult(Result(Pattern));
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001480 break;
1481 }
1482 }
1483
Douglas Gregor70febae2010-05-28 00:49:12 +00001484 if (WantTypesInContext(CCC, SemaRef.getLangOptions()))
1485 AddTypeSpecifierResults(SemaRef.getLangOptions(), Results);
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001486
1487 if (SemaRef.getLangOptions().CPlusPlus)
Douglas Gregor78a21012010-01-14 16:01:26 +00001488 Results.AddResult(Result("operator"));
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001489}
1490
Douglas Gregorb3fa9192009-12-18 18:53:37 +00001491/// \brief If the given declaration has an associated type, add it as a result
1492/// type chunk.
1493static void AddResultTypeChunk(ASTContext &Context,
1494 NamedDecl *ND,
1495 CodeCompletionString *Result) {
1496 if (!ND)
1497 return;
1498
1499 // Determine the type of the declaration (if it has a type).
1500 QualType T;
1501 if (FunctionDecl *Function = dyn_cast<FunctionDecl>(ND))
1502 T = Function->getResultType();
1503 else if (ObjCMethodDecl *Method = dyn_cast<ObjCMethodDecl>(ND))
1504 T = Method->getResultType();
1505 else if (FunctionTemplateDecl *FunTmpl = dyn_cast<FunctionTemplateDecl>(ND))
1506 T = FunTmpl->getTemplatedDecl()->getResultType();
1507 else if (EnumConstantDecl *Enumerator = dyn_cast<EnumConstantDecl>(ND))
1508 T = Context.getTypeDeclType(cast<TypeDecl>(Enumerator->getDeclContext()));
1509 else if (isa<UnresolvedUsingValueDecl>(ND)) {
1510 /* Do nothing: ignore unresolved using declarations*/
1511 } else if (ValueDecl *Value = dyn_cast<ValueDecl>(ND))
1512 T = Value->getType();
1513 else if (ObjCPropertyDecl *Property = dyn_cast<ObjCPropertyDecl>(ND))
1514 T = Property->getType();
1515
1516 if (T.isNull() || Context.hasSameType(T, Context.DependentTy))
1517 return;
1518
Douglas Gregorcf04b022010-04-05 21:25:31 +00001519 PrintingPolicy Policy(Context.PrintingPolicy);
1520 Policy.AnonymousTagLocations = false;
1521
Douglas Gregorb3fa9192009-12-18 18:53:37 +00001522 std::string TypeStr;
Douglas Gregorcf04b022010-04-05 21:25:31 +00001523 T.getAsStringInternal(TypeStr, Policy);
Douglas Gregorb3fa9192009-12-18 18:53:37 +00001524 Result->AddResultTypeChunk(TypeStr);
1525}
1526
Douglas Gregor3545ff42009-09-21 16:56:56 +00001527/// \brief Add function parameter chunks to the given code completion string.
1528static void AddFunctionParameterChunks(ASTContext &Context,
1529 FunctionDecl *Function,
1530 CodeCompletionString *Result) {
Douglas Gregor9eb77012009-11-07 00:00:49 +00001531 typedef CodeCompletionString::Chunk Chunk;
1532
Douglas Gregor3545ff42009-09-21 16:56:56 +00001533 CodeCompletionString *CCStr = Result;
1534
1535 for (unsigned P = 0, N = Function->getNumParams(); P != N; ++P) {
1536 ParmVarDecl *Param = Function->getParamDecl(P);
1537
1538 if (Param->hasDefaultArg()) {
1539 // When we see an optional default argument, put that argument and
1540 // the remaining default arguments into a new, optional string.
1541 CodeCompletionString *Opt = new CodeCompletionString;
1542 CCStr->AddOptionalChunk(std::auto_ptr<CodeCompletionString>(Opt));
1543 CCStr = Opt;
1544 }
1545
1546 if (P != 0)
Douglas Gregor9eb77012009-11-07 00:00:49 +00001547 CCStr->AddChunk(Chunk(CodeCompletionString::CK_Comma));
Douglas Gregor3545ff42009-09-21 16:56:56 +00001548
1549 // Format the placeholder string.
1550 std::string PlaceholderStr;
1551 if (Param->getIdentifier())
1552 PlaceholderStr = Param->getIdentifier()->getName();
1553
1554 Param->getType().getAsStringInternal(PlaceholderStr,
1555 Context.PrintingPolicy);
1556
1557 // Add the placeholder string.
Benjamin Kramerb33a97c2009-11-29 20:18:50 +00001558 CCStr->AddPlaceholderChunk(PlaceholderStr);
Douglas Gregor3545ff42009-09-21 16:56:56 +00001559 }
Douglas Gregorba449032009-09-22 21:42:17 +00001560
1561 if (const FunctionProtoType *Proto
1562 = Function->getType()->getAs<FunctionProtoType>())
1563 if (Proto->isVariadic())
1564 CCStr->AddPlaceholderChunk(", ...");
Douglas Gregor3545ff42009-09-21 16:56:56 +00001565}
1566
1567/// \brief Add template parameter chunks to the given code completion string.
1568static void AddTemplateParameterChunks(ASTContext &Context,
1569 TemplateDecl *Template,
1570 CodeCompletionString *Result,
1571 unsigned MaxParameters = 0) {
Douglas Gregor9eb77012009-11-07 00:00:49 +00001572 typedef CodeCompletionString::Chunk Chunk;
1573
Douglas Gregor3545ff42009-09-21 16:56:56 +00001574 CodeCompletionString *CCStr = Result;
1575 bool FirstParameter = true;
1576
1577 TemplateParameterList *Params = Template->getTemplateParameters();
1578 TemplateParameterList::iterator PEnd = Params->end();
1579 if (MaxParameters)
1580 PEnd = Params->begin() + MaxParameters;
1581 for (TemplateParameterList::iterator P = Params->begin(); P != PEnd; ++P) {
1582 bool HasDefaultArg = false;
1583 std::string PlaceholderStr;
1584 if (TemplateTypeParmDecl *TTP = dyn_cast<TemplateTypeParmDecl>(*P)) {
1585 if (TTP->wasDeclaredWithTypename())
1586 PlaceholderStr = "typename";
1587 else
1588 PlaceholderStr = "class";
1589
1590 if (TTP->getIdentifier()) {
1591 PlaceholderStr += ' ';
1592 PlaceholderStr += TTP->getIdentifier()->getName();
1593 }
1594
1595 HasDefaultArg = TTP->hasDefaultArgument();
1596 } else if (NonTypeTemplateParmDecl *NTTP
1597 = dyn_cast<NonTypeTemplateParmDecl>(*P)) {
1598 if (NTTP->getIdentifier())
1599 PlaceholderStr = NTTP->getIdentifier()->getName();
1600 NTTP->getType().getAsStringInternal(PlaceholderStr,
1601 Context.PrintingPolicy);
1602 HasDefaultArg = NTTP->hasDefaultArgument();
1603 } else {
1604 assert(isa<TemplateTemplateParmDecl>(*P));
1605 TemplateTemplateParmDecl *TTP = cast<TemplateTemplateParmDecl>(*P);
1606
1607 // Since putting the template argument list into the placeholder would
1608 // be very, very long, we just use an abbreviation.
1609 PlaceholderStr = "template<...> class";
1610 if (TTP->getIdentifier()) {
1611 PlaceholderStr += ' ';
1612 PlaceholderStr += TTP->getIdentifier()->getName();
1613 }
1614
1615 HasDefaultArg = TTP->hasDefaultArgument();
1616 }
1617
1618 if (HasDefaultArg) {
1619 // When we see an optional default argument, put that argument and
1620 // the remaining default arguments into a new, optional string.
1621 CodeCompletionString *Opt = new CodeCompletionString;
1622 CCStr->AddOptionalChunk(std::auto_ptr<CodeCompletionString>(Opt));
1623 CCStr = Opt;
1624 }
1625
1626 if (FirstParameter)
1627 FirstParameter = false;
1628 else
Douglas Gregor9eb77012009-11-07 00:00:49 +00001629 CCStr->AddChunk(Chunk(CodeCompletionString::CK_Comma));
Douglas Gregor3545ff42009-09-21 16:56:56 +00001630
1631 // Add the placeholder string.
Benjamin Kramerb33a97c2009-11-29 20:18:50 +00001632 CCStr->AddPlaceholderChunk(PlaceholderStr);
Douglas Gregor3545ff42009-09-21 16:56:56 +00001633 }
1634}
1635
Douglas Gregorf2510672009-09-21 19:57:38 +00001636/// \brief Add a qualifier to the given code-completion string, if the
1637/// provided nested-name-specifier is non-NULL.
Douglas Gregor0f622362009-12-11 18:44:16 +00001638static void
1639AddQualifierToCompletionString(CodeCompletionString *Result,
1640 NestedNameSpecifier *Qualifier,
1641 bool QualifierIsInformative,
1642 ASTContext &Context) {
Douglas Gregorf2510672009-09-21 19:57:38 +00001643 if (!Qualifier)
1644 return;
1645
1646 std::string PrintedNNS;
1647 {
1648 llvm::raw_string_ostream OS(PrintedNNS);
1649 Qualifier->print(OS, Context.PrintingPolicy);
1650 }
Douglas Gregor5bf52692009-09-22 23:15:58 +00001651 if (QualifierIsInformative)
Benjamin Kramerb33a97c2009-11-29 20:18:50 +00001652 Result->AddInformativeChunk(PrintedNNS);
Douglas Gregor5bf52692009-09-22 23:15:58 +00001653 else
Benjamin Kramerb33a97c2009-11-29 20:18:50 +00001654 Result->AddTextChunk(PrintedNNS);
Douglas Gregorf2510672009-09-21 19:57:38 +00001655}
1656
Douglas Gregor0f622362009-12-11 18:44:16 +00001657static void AddFunctionTypeQualsToCompletionString(CodeCompletionString *Result,
1658 FunctionDecl *Function) {
1659 const FunctionProtoType *Proto
1660 = Function->getType()->getAs<FunctionProtoType>();
1661 if (!Proto || !Proto->getTypeQuals())
1662 return;
1663
1664 std::string QualsStr;
1665 if (Proto->getTypeQuals() & Qualifiers::Const)
1666 QualsStr += " const";
1667 if (Proto->getTypeQuals() & Qualifiers::Volatile)
1668 QualsStr += " volatile";
1669 if (Proto->getTypeQuals() & Qualifiers::Restrict)
1670 QualsStr += " restrict";
1671 Result->AddInformativeChunk(QualsStr);
1672}
1673
Douglas Gregor3545ff42009-09-21 16:56:56 +00001674/// \brief If possible, create a new code completion string for the given
1675/// result.
1676///
1677/// \returns Either a new, heap-allocated code completion string describing
1678/// how to use this result, or NULL to indicate that the string or name of the
1679/// result is all that is needed.
1680CodeCompletionString *
1681CodeCompleteConsumer::Result::CreateCodeCompletionString(Sema &S) {
Douglas Gregor9eb77012009-11-07 00:00:49 +00001682 typedef CodeCompletionString::Chunk Chunk;
1683
Douglas Gregorf09935f2009-12-01 05:55:20 +00001684 if (Kind == RK_Pattern)
1685 return Pattern->Clone();
1686
1687 CodeCompletionString *Result = new CodeCompletionString;
1688
1689 if (Kind == RK_Keyword) {
1690 Result->AddTypedTextChunk(Keyword);
1691 return Result;
1692 }
Douglas Gregor3545ff42009-09-21 16:56:56 +00001693
Douglas Gregorf329c7c2009-10-30 16:50:04 +00001694 if (Kind == RK_Macro) {
1695 MacroInfo *MI = S.PP.getMacroInfo(Macro);
Douglas Gregorf09935f2009-12-01 05:55:20 +00001696 assert(MI && "Not a macro?");
1697
1698 Result->AddTypedTextChunk(Macro->getName());
1699
1700 if (!MI->isFunctionLike())
1701 return Result;
Douglas Gregorf329c7c2009-10-30 16:50:04 +00001702
1703 // Format a function-like macro with placeholders for the arguments.
Douglas Gregor9eb77012009-11-07 00:00:49 +00001704 Result->AddChunk(Chunk(CodeCompletionString::CK_LeftParen));
Douglas Gregorf329c7c2009-10-30 16:50:04 +00001705 for (MacroInfo::arg_iterator A = MI->arg_begin(), AEnd = MI->arg_end();
1706 A != AEnd; ++A) {
1707 if (A != MI->arg_begin())
Douglas Gregor9eb77012009-11-07 00:00:49 +00001708 Result->AddChunk(Chunk(CodeCompletionString::CK_Comma));
Douglas Gregorf329c7c2009-10-30 16:50:04 +00001709
1710 if (!MI->isVariadic() || A != AEnd - 1) {
1711 // Non-variadic argument.
Benjamin Kramerb33a97c2009-11-29 20:18:50 +00001712 Result->AddPlaceholderChunk((*A)->getName());
Douglas Gregorf329c7c2009-10-30 16:50:04 +00001713 continue;
1714 }
1715
1716 // Variadic argument; cope with the different between GNU and C99
1717 // variadic macros, providing a single placeholder for the rest of the
1718 // arguments.
1719 if ((*A)->isStr("__VA_ARGS__"))
1720 Result->AddPlaceholderChunk("...");
1721 else {
1722 std::string Arg = (*A)->getName();
1723 Arg += "...";
Benjamin Kramerb33a97c2009-11-29 20:18:50 +00001724 Result->AddPlaceholderChunk(Arg);
Douglas Gregorf329c7c2009-10-30 16:50:04 +00001725 }
1726 }
Douglas Gregor9eb77012009-11-07 00:00:49 +00001727 Result->AddChunk(Chunk(CodeCompletionString::CK_RightParen));
Douglas Gregorf329c7c2009-10-30 16:50:04 +00001728 return Result;
1729 }
1730
Douglas Gregorf64acca2010-05-25 21:41:55 +00001731 assert(Kind == RK_Declaration && "Missed a result kind?");
Douglas Gregor3545ff42009-09-21 16:56:56 +00001732 NamedDecl *ND = Declaration;
1733
Douglas Gregor9eb77012009-11-07 00:00:49 +00001734 if (StartsNestedNameSpecifier) {
Benjamin Kramerb33a97c2009-11-29 20:18:50 +00001735 Result->AddTypedTextChunk(ND->getNameAsString());
Douglas Gregor9eb77012009-11-07 00:00:49 +00001736 Result->AddTextChunk("::");
1737 return Result;
1738 }
1739
Douglas Gregorb3fa9192009-12-18 18:53:37 +00001740 AddResultTypeChunk(S.Context, ND, Result);
1741
Douglas Gregor3545ff42009-09-21 16:56:56 +00001742 if (FunctionDecl *Function = dyn_cast<FunctionDecl>(ND)) {
Douglas Gregor5bf52692009-09-22 23:15:58 +00001743 AddQualifierToCompletionString(Result, Qualifier, QualifierIsInformative,
1744 S.Context);
Benjamin Kramerb33a97c2009-11-29 20:18:50 +00001745 Result->AddTypedTextChunk(Function->getNameAsString());
Douglas Gregor9eb77012009-11-07 00:00:49 +00001746 Result->AddChunk(Chunk(CodeCompletionString::CK_LeftParen));
Douglas Gregor3545ff42009-09-21 16:56:56 +00001747 AddFunctionParameterChunks(S.Context, Function, Result);
Douglas Gregor9eb77012009-11-07 00:00:49 +00001748 Result->AddChunk(Chunk(CodeCompletionString::CK_RightParen));
Douglas Gregor0f622362009-12-11 18:44:16 +00001749 AddFunctionTypeQualsToCompletionString(Result, Function);
Douglas Gregor3545ff42009-09-21 16:56:56 +00001750 return Result;
1751 }
1752
1753 if (FunctionTemplateDecl *FunTmpl = dyn_cast<FunctionTemplateDecl>(ND)) {
Douglas Gregor5bf52692009-09-22 23:15:58 +00001754 AddQualifierToCompletionString(Result, Qualifier, QualifierIsInformative,
1755 S.Context);
Douglas Gregor3545ff42009-09-21 16:56:56 +00001756 FunctionDecl *Function = FunTmpl->getTemplatedDecl();
Benjamin Kramerb33a97c2009-11-29 20:18:50 +00001757 Result->AddTypedTextChunk(Function->getNameAsString());
Douglas Gregor3545ff42009-09-21 16:56:56 +00001758
1759 // Figure out which template parameters are deduced (or have default
1760 // arguments).
1761 llvm::SmallVector<bool, 16> Deduced;
1762 S.MarkDeducedTemplateParameters(FunTmpl, Deduced);
1763 unsigned LastDeducibleArgument;
1764 for (LastDeducibleArgument = Deduced.size(); LastDeducibleArgument > 0;
1765 --LastDeducibleArgument) {
1766 if (!Deduced[LastDeducibleArgument - 1]) {
1767 // C++0x: Figure out if the template argument has a default. If so,
1768 // the user doesn't need to type this argument.
1769 // FIXME: We need to abstract template parameters better!
1770 bool HasDefaultArg = false;
1771 NamedDecl *Param = FunTmpl->getTemplateParameters()->getParam(
1772 LastDeducibleArgument - 1);
1773 if (TemplateTypeParmDecl *TTP = dyn_cast<TemplateTypeParmDecl>(Param))
1774 HasDefaultArg = TTP->hasDefaultArgument();
1775 else if (NonTypeTemplateParmDecl *NTTP
1776 = dyn_cast<NonTypeTemplateParmDecl>(Param))
1777 HasDefaultArg = NTTP->hasDefaultArgument();
1778 else {
1779 assert(isa<TemplateTemplateParmDecl>(Param));
1780 HasDefaultArg
Douglas Gregor9eb77012009-11-07 00:00:49 +00001781 = cast<TemplateTemplateParmDecl>(Param)->hasDefaultArgument();
Douglas Gregor3545ff42009-09-21 16:56:56 +00001782 }
1783
1784 if (!HasDefaultArg)
1785 break;
1786 }
1787 }
1788
1789 if (LastDeducibleArgument) {
1790 // Some of the function template arguments cannot be deduced from a
1791 // function call, so we introduce an explicit template argument list
1792 // containing all of the arguments up to the first deducible argument.
Douglas Gregor9eb77012009-11-07 00:00:49 +00001793 Result->AddChunk(Chunk(CodeCompletionString::CK_LeftAngle));
Douglas Gregor3545ff42009-09-21 16:56:56 +00001794 AddTemplateParameterChunks(S.Context, FunTmpl, Result,
1795 LastDeducibleArgument);
Douglas Gregor9eb77012009-11-07 00:00:49 +00001796 Result->AddChunk(Chunk(CodeCompletionString::CK_RightAngle));
Douglas Gregor3545ff42009-09-21 16:56:56 +00001797 }
1798
1799 // Add the function parameters
Douglas Gregor9eb77012009-11-07 00:00:49 +00001800 Result->AddChunk(Chunk(CodeCompletionString::CK_LeftParen));
Douglas Gregor3545ff42009-09-21 16:56:56 +00001801 AddFunctionParameterChunks(S.Context, Function, Result);
Douglas Gregor9eb77012009-11-07 00:00:49 +00001802 Result->AddChunk(Chunk(CodeCompletionString::CK_RightParen));
Douglas Gregor0f622362009-12-11 18:44:16 +00001803 AddFunctionTypeQualsToCompletionString(Result, Function);
Douglas Gregor3545ff42009-09-21 16:56:56 +00001804 return Result;
1805 }
1806
1807 if (TemplateDecl *Template = dyn_cast<TemplateDecl>(ND)) {
Douglas Gregor5bf52692009-09-22 23:15:58 +00001808 AddQualifierToCompletionString(Result, Qualifier, QualifierIsInformative,
1809 S.Context);
Benjamin Kramerb33a97c2009-11-29 20:18:50 +00001810 Result->AddTypedTextChunk(Template->getNameAsString());
Douglas Gregor9eb77012009-11-07 00:00:49 +00001811 Result->AddChunk(Chunk(CodeCompletionString::CK_LeftAngle));
Douglas Gregor3545ff42009-09-21 16:56:56 +00001812 AddTemplateParameterChunks(S.Context, Template, Result);
Douglas Gregor9eb77012009-11-07 00:00:49 +00001813 Result->AddChunk(Chunk(CodeCompletionString::CK_RightAngle));
Douglas Gregor3545ff42009-09-21 16:56:56 +00001814 return Result;
1815 }
1816
Douglas Gregord3c5d792009-11-17 16:44:22 +00001817 if (ObjCMethodDecl *Method = dyn_cast<ObjCMethodDecl>(ND)) {
Douglas Gregord3c5d792009-11-17 16:44:22 +00001818 Selector Sel = Method->getSelector();
1819 if (Sel.isUnarySelector()) {
1820 Result->AddTypedTextChunk(Sel.getIdentifierInfoForSlot(0)->getName());
1821 return Result;
1822 }
1823
Douglas Gregor1b605f72009-11-19 01:08:35 +00001824 std::string SelName = Sel.getIdentifierInfoForSlot(0)->getName().str();
1825 SelName += ':';
1826 if (StartParameter == 0)
1827 Result->AddTypedTextChunk(SelName);
1828 else {
1829 Result->AddInformativeChunk(SelName);
1830
1831 // If there is only one parameter, and we're past it, add an empty
1832 // typed-text chunk since there is nothing to type.
1833 if (Method->param_size() == 1)
1834 Result->AddTypedTextChunk("");
1835 }
Douglas Gregord3c5d792009-11-17 16:44:22 +00001836 unsigned Idx = 0;
1837 for (ObjCMethodDecl::param_iterator P = Method->param_begin(),
1838 PEnd = Method->param_end();
1839 P != PEnd; (void)++P, ++Idx) {
1840 if (Idx > 0) {
Douglas Gregor1b605f72009-11-19 01:08:35 +00001841 std::string Keyword;
1842 if (Idx > StartParameter)
Douglas Gregor6a803932010-01-12 06:38:28 +00001843 Result->AddChunk(CodeCompletionString::CK_HorizontalSpace);
Douglas Gregord3c5d792009-11-17 16:44:22 +00001844 if (IdentifierInfo *II = Sel.getIdentifierInfoForSlot(Idx))
1845 Keyword += II->getName().str();
1846 Keyword += ":";
Douglas Gregorc8537c52009-11-19 07:41:15 +00001847 if (Idx < StartParameter || AllParametersAreInformative) {
Douglas Gregor1b605f72009-11-19 01:08:35 +00001848 Result->AddInformativeChunk(Keyword);
1849 } else if (Idx == StartParameter)
1850 Result->AddTypedTextChunk(Keyword);
1851 else
1852 Result->AddTextChunk(Keyword);
Douglas Gregord3c5d792009-11-17 16:44:22 +00001853 }
Douglas Gregor1b605f72009-11-19 01:08:35 +00001854
1855 // If we're before the starting parameter, skip the placeholder.
1856 if (Idx < StartParameter)
1857 continue;
Douglas Gregord3c5d792009-11-17 16:44:22 +00001858
1859 std::string Arg;
1860 (*P)->getType().getAsStringInternal(Arg, S.Context.PrintingPolicy);
1861 Arg = "(" + Arg + ")";
1862 if (IdentifierInfo *II = (*P)->getIdentifier())
1863 Arg += II->getName().str();
Douglas Gregorc8537c52009-11-19 07:41:15 +00001864 if (AllParametersAreInformative)
1865 Result->AddInformativeChunk(Arg);
1866 else
1867 Result->AddPlaceholderChunk(Arg);
Douglas Gregord3c5d792009-11-17 16:44:22 +00001868 }
1869
Douglas Gregor04c5f972009-12-23 00:21:46 +00001870 if (Method->isVariadic()) {
1871 if (AllParametersAreInformative)
1872 Result->AddInformativeChunk(", ...");
1873 else
1874 Result->AddPlaceholderChunk(", ...");
1875 }
1876
Douglas Gregord3c5d792009-11-17 16:44:22 +00001877 return Result;
1878 }
1879
Douglas Gregorf09935f2009-12-01 05:55:20 +00001880 if (Qualifier)
Douglas Gregor5bf52692009-09-22 23:15:58 +00001881 AddQualifierToCompletionString(Result, Qualifier, QualifierIsInformative,
1882 S.Context);
Douglas Gregorf09935f2009-12-01 05:55:20 +00001883
1884 Result->AddTypedTextChunk(ND->getNameAsString());
1885 return Result;
Douglas Gregor3545ff42009-09-21 16:56:56 +00001886}
1887
Douglas Gregorf0f51982009-09-23 00:34:09 +00001888CodeCompletionString *
1889CodeCompleteConsumer::OverloadCandidate::CreateSignatureString(
1890 unsigned CurrentArg,
1891 Sema &S) const {
Douglas Gregor9eb77012009-11-07 00:00:49 +00001892 typedef CodeCompletionString::Chunk Chunk;
1893
Douglas Gregorf0f51982009-09-23 00:34:09 +00001894 CodeCompletionString *Result = new CodeCompletionString;
1895 FunctionDecl *FDecl = getFunction();
Douglas Gregorb3fa9192009-12-18 18:53:37 +00001896 AddResultTypeChunk(S.Context, FDecl, Result);
Douglas Gregorf0f51982009-09-23 00:34:09 +00001897 const FunctionProtoType *Proto
1898 = dyn_cast<FunctionProtoType>(getFunctionType());
1899 if (!FDecl && !Proto) {
1900 // Function without a prototype. Just give the return type and a
1901 // highlighted ellipsis.
1902 const FunctionType *FT = getFunctionType();
1903 Result->AddTextChunk(
Benjamin Kramerb33a97c2009-11-29 20:18:50 +00001904 FT->getResultType().getAsString(S.Context.PrintingPolicy));
Douglas Gregor9eb77012009-11-07 00:00:49 +00001905 Result->AddChunk(Chunk(CodeCompletionString::CK_LeftParen));
1906 Result->AddChunk(Chunk(CodeCompletionString::CK_CurrentParameter, "..."));
1907 Result->AddChunk(Chunk(CodeCompletionString::CK_RightParen));
Douglas Gregorf0f51982009-09-23 00:34:09 +00001908 return Result;
1909 }
1910
1911 if (FDecl)
Benjamin Kramerb33a97c2009-11-29 20:18:50 +00001912 Result->AddTextChunk(FDecl->getNameAsString());
Douglas Gregorf0f51982009-09-23 00:34:09 +00001913 else
1914 Result->AddTextChunk(
Benjamin Kramerb33a97c2009-11-29 20:18:50 +00001915 Proto->getResultType().getAsString(S.Context.PrintingPolicy));
Douglas Gregorf0f51982009-09-23 00:34:09 +00001916
Douglas Gregor9eb77012009-11-07 00:00:49 +00001917 Result->AddChunk(Chunk(CodeCompletionString::CK_LeftParen));
Douglas Gregorf0f51982009-09-23 00:34:09 +00001918 unsigned NumParams = FDecl? FDecl->getNumParams() : Proto->getNumArgs();
1919 for (unsigned I = 0; I != NumParams; ++I) {
1920 if (I)
Douglas Gregor9eb77012009-11-07 00:00:49 +00001921 Result->AddChunk(Chunk(CodeCompletionString::CK_Comma));
Douglas Gregorf0f51982009-09-23 00:34:09 +00001922
1923 std::string ArgString;
1924 QualType ArgType;
1925
1926 if (FDecl) {
1927 ArgString = FDecl->getParamDecl(I)->getNameAsString();
1928 ArgType = FDecl->getParamDecl(I)->getOriginalType();
1929 } else {
1930 ArgType = Proto->getArgType(I);
1931 }
1932
1933 ArgType.getAsStringInternal(ArgString, S.Context.PrintingPolicy);
1934
1935 if (I == CurrentArg)
Douglas Gregor9eb77012009-11-07 00:00:49 +00001936 Result->AddChunk(Chunk(CodeCompletionString::CK_CurrentParameter,
Benjamin Kramerb33a97c2009-11-29 20:18:50 +00001937 ArgString));
Douglas Gregorf0f51982009-09-23 00:34:09 +00001938 else
Benjamin Kramerb33a97c2009-11-29 20:18:50 +00001939 Result->AddTextChunk(ArgString);
Douglas Gregorf0f51982009-09-23 00:34:09 +00001940 }
1941
1942 if (Proto && Proto->isVariadic()) {
Douglas Gregor9eb77012009-11-07 00:00:49 +00001943 Result->AddChunk(Chunk(CodeCompletionString::CK_Comma));
Douglas Gregorf0f51982009-09-23 00:34:09 +00001944 if (CurrentArg < NumParams)
1945 Result->AddTextChunk("...");
1946 else
Douglas Gregor9eb77012009-11-07 00:00:49 +00001947 Result->AddChunk(Chunk(CodeCompletionString::CK_CurrentParameter, "..."));
Douglas Gregorf0f51982009-09-23 00:34:09 +00001948 }
Douglas Gregor9eb77012009-11-07 00:00:49 +00001949 Result->AddChunk(Chunk(CodeCompletionString::CK_RightParen));
Douglas Gregorf0f51982009-09-23 00:34:09 +00001950
1951 return Result;
1952}
1953
Douglas Gregor3545ff42009-09-21 16:56:56 +00001954namespace {
1955 struct SortCodeCompleteResult {
1956 typedef CodeCompleteConsumer::Result Result;
1957
Douglas Gregore6688e62009-09-28 03:51:44 +00001958 bool isEarlierDeclarationName(DeclarationName X, DeclarationName Y) const {
Douglas Gregor249d6822009-12-05 09:08:56 +00001959 Selector XSel = X.getObjCSelector();
1960 Selector YSel = Y.getObjCSelector();
1961 if (!XSel.isNull() && !YSel.isNull()) {
1962 // We are comparing two selectors.
1963 unsigned N = std::min(XSel.getNumArgs(), YSel.getNumArgs());
1964 if (N == 0)
1965 ++N;
1966 for (unsigned I = 0; I != N; ++I) {
1967 IdentifierInfo *XId = XSel.getIdentifierInfoForSlot(I);
1968 IdentifierInfo *YId = YSel.getIdentifierInfoForSlot(I);
1969 if (!XId || !YId)
1970 return XId && !YId;
1971
1972 switch (XId->getName().compare_lower(YId->getName())) {
1973 case -1: return true;
1974 case 1: return false;
1975 default: break;
1976 }
1977 }
1978
1979 return XSel.getNumArgs() < YSel.getNumArgs();
1980 }
1981
1982 // For non-selectors, order by kind.
1983 if (X.getNameKind() != Y.getNameKind())
Douglas Gregore6688e62009-09-28 03:51:44 +00001984 return X.getNameKind() < Y.getNameKind();
1985
Douglas Gregor249d6822009-12-05 09:08:56 +00001986 // Order identifiers by comparison of their lowercased names.
1987 if (IdentifierInfo *XId = X.getAsIdentifierInfo())
1988 return XId->getName().compare_lower(
1989 Y.getAsIdentifierInfo()->getName()) < 0;
1990
1991 // Order overloaded operators by the order in which they appear
1992 // in our list of operators.
1993 if (OverloadedOperatorKind XOp = X.getCXXOverloadedOperator())
1994 return XOp < Y.getCXXOverloadedOperator();
1995
1996 // Order C++0x user-defined literal operators lexically by their
1997 // lowercased suffixes.
1998 if (IdentifierInfo *XLit = X.getCXXLiteralIdentifier())
1999 return XLit->getName().compare_lower(
2000 Y.getCXXLiteralIdentifier()->getName()) < 0;
2001
2002 // The only stable ordering we have is to turn the name into a
2003 // string and then compare the lower-case strings. This is
2004 // inefficient, but thankfully does not happen too often.
Benjamin Kramer4053e5d2009-12-05 10:22:15 +00002005 return llvm::StringRef(X.getAsString()).compare_lower(
2006 Y.getAsString()) < 0;
Douglas Gregore6688e62009-09-28 03:51:44 +00002007 }
2008
Douglas Gregor52ce62f2010-01-13 23:24:38 +00002009 /// \brief Retrieve the name that should be used to order a result.
2010 ///
2011 /// If the name needs to be constructed as a string, that string will be
2012 /// saved into Saved and the returned StringRef will refer to it.
2013 static llvm::StringRef getOrderedName(const Result &R,
2014 std::string &Saved) {
2015 switch (R.Kind) {
2016 case Result::RK_Keyword:
2017 return R.Keyword;
2018
2019 case Result::RK_Pattern:
2020 return R.Pattern->getTypedText();
2021
2022 case Result::RK_Macro:
2023 return R.Macro->getName();
2024
2025 case Result::RK_Declaration:
2026 // Handle declarations below.
2027 break;
Douglas Gregor45f83ee2009-11-19 00:01:57 +00002028 }
Douglas Gregor52ce62f2010-01-13 23:24:38 +00002029
2030 DeclarationName Name = R.Declaration->getDeclName();
Douglas Gregor45f83ee2009-11-19 00:01:57 +00002031
Douglas Gregor52ce62f2010-01-13 23:24:38 +00002032 // If the name is a simple identifier (by far the common case), or a
2033 // zero-argument selector, just return a reference to that identifier.
2034 if (IdentifierInfo *Id = Name.getAsIdentifierInfo())
2035 return Id->getName();
2036 if (Name.isObjCZeroArgSelector())
2037 if (IdentifierInfo *Id
2038 = Name.getObjCSelector().getIdentifierInfoForSlot(0))
2039 return Id->getName();
2040
2041 Saved = Name.getAsString();
2042 return Saved;
2043 }
2044
2045 bool operator()(const Result &X, const Result &Y) const {
2046 std::string XSaved, YSaved;
2047 llvm::StringRef XStr = getOrderedName(X, XSaved);
2048 llvm::StringRef YStr = getOrderedName(Y, YSaved);
2049 int cmp = XStr.compare_lower(YStr);
2050 if (cmp)
2051 return cmp < 0;
Douglas Gregor3545ff42009-09-21 16:56:56 +00002052
2053 // Non-hidden names precede hidden names.
2054 if (X.Hidden != Y.Hidden)
2055 return !X.Hidden;
2056
Douglas Gregore412a5a2009-09-23 22:26:46 +00002057 // Non-nested-name-specifiers precede nested-name-specifiers.
2058 if (X.StartsNestedNameSpecifier != Y.StartsNestedNameSpecifier)
2059 return !X.StartsNestedNameSpecifier;
2060
Douglas Gregor3545ff42009-09-21 16:56:56 +00002061 return false;
2062 }
2063 };
2064}
2065
Douglas Gregorf98e6a22010-01-13 23:51:12 +00002066static void AddMacroResults(Preprocessor &PP, ResultBuilder &Results) {
Douglas Gregorf329c7c2009-10-30 16:50:04 +00002067 Results.EnterNewScope();
Douglas Gregor9eb77012009-11-07 00:00:49 +00002068 for (Preprocessor::macro_iterator M = PP.macro_begin(),
2069 MEnd = PP.macro_end();
Douglas Gregorf329c7c2009-10-30 16:50:04 +00002070 M != MEnd; ++M)
Douglas Gregor78a21012010-01-14 16:01:26 +00002071 Results.AddResult(M->first);
Douglas Gregorf329c7c2009-10-30 16:50:04 +00002072 Results.ExitScope();
2073}
2074
Daniel Dunbar242ea9a2009-11-13 08:58:20 +00002075static void HandleCodeCompleteResults(Sema *S,
2076 CodeCompleteConsumer *CodeCompleter,
2077 CodeCompleteConsumer::Result *Results,
2078 unsigned NumResults) {
Douglas Gregor3545ff42009-09-21 16:56:56 +00002079 std::stable_sort(Results, Results + NumResults, SortCodeCompleteResult());
2080
2081 if (CodeCompleter)
Daniel Dunbar242ea9a2009-11-13 08:58:20 +00002082 CodeCompleter->ProcessCodeCompleteResults(*S, Results, NumResults);
Douglas Gregor45f83ee2009-11-19 00:01:57 +00002083
2084 for (unsigned I = 0; I != NumResults; ++I)
2085 Results[I].Destroy();
Douglas Gregor3545ff42009-09-21 16:56:56 +00002086}
2087
Douglas Gregor504a6ae2010-01-10 23:08:15 +00002088void Sema::CodeCompleteOrdinaryName(Scope *S,
2089 CodeCompletionContext CompletionContext) {
Douglas Gregor92253692009-12-07 09:54:55 +00002090 typedef CodeCompleteConsumer::Result Result;
Douglas Gregor504a6ae2010-01-10 23:08:15 +00002091 ResultBuilder Results(*this);
2092
2093 // Determine how to filter results, e.g., so that the names of
2094 // values (functions, enumerators, function templates, etc.) are
2095 // only allowed where we can have an expression.
2096 switch (CompletionContext) {
2097 case CCC_Namespace:
2098 case CCC_Class:
Douglas Gregorf1934162010-01-13 21:24:21 +00002099 case CCC_ObjCInterface:
2100 case CCC_ObjCImplementation:
Douglas Gregor48d46252010-01-13 21:54:15 +00002101 case CCC_ObjCInstanceVariableList:
Douglas Gregor504a6ae2010-01-10 23:08:15 +00002102 case CCC_Template:
2103 case CCC_MemberTemplate:
2104 Results.setFilter(&ResultBuilder::IsOrdinaryNonValueName);
2105 break;
2106
2107 case CCC_Expression:
2108 case CCC_Statement:
2109 case CCC_ForInit:
2110 case CCC_Condition:
Douglas Gregor70febae2010-05-28 00:49:12 +00002111 if (WantTypesInContext(CompletionContext, getLangOptions()))
2112 Results.setFilter(&ResultBuilder::IsOrdinaryName);
2113 else
2114 Results.setFilter(&ResultBuilder::IsOrdinaryNonTypeName);
Douglas Gregor504a6ae2010-01-10 23:08:15 +00002115 break;
Douglas Gregor6da3db42010-05-25 05:58:43 +00002116
2117 case CCC_RecoveryInFunction:
2118 // Unfiltered
2119 break;
Douglas Gregor504a6ae2010-01-10 23:08:15 +00002120 }
2121
Douglas Gregorc580c522010-01-14 01:09:38 +00002122 CodeCompletionDeclConsumer Consumer(Results, CurContext);
2123 LookupVisibleDecls(S, LookupOrdinaryName, Consumer);
Douglas Gregor92253692009-12-07 09:54:55 +00002124
2125 Results.EnterNewScope();
Douglas Gregorf98e6a22010-01-13 23:51:12 +00002126 AddOrdinaryNameResults(CompletionContext, S, *this, Results);
Douglas Gregor92253692009-12-07 09:54:55 +00002127 Results.ExitScope();
2128
Douglas Gregor9eb77012009-11-07 00:00:49 +00002129 if (CodeCompleter->includeMacros())
Douglas Gregorf98e6a22010-01-13 23:51:12 +00002130 AddMacroResults(PP, Results);
Daniel Dunbar242ea9a2009-11-13 08:58:20 +00002131 HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
Douglas Gregor9d64c5e2009-09-21 20:51:25 +00002132}
2133
Douglas Gregor9291bad2009-11-18 01:29:26 +00002134static void AddObjCProperties(ObjCContainerDecl *Container,
Douglas Gregor5d649882009-11-18 22:32:06 +00002135 bool AllowCategories,
Douglas Gregor9291bad2009-11-18 01:29:26 +00002136 DeclContext *CurContext,
2137 ResultBuilder &Results) {
2138 typedef CodeCompleteConsumer::Result Result;
2139
2140 // Add properties in this container.
2141 for (ObjCContainerDecl::prop_iterator P = Container->prop_begin(),
2142 PEnd = Container->prop_end();
2143 P != PEnd;
2144 ++P)
2145 Results.MaybeAddResult(Result(*P, 0), CurContext);
2146
2147 // Add properties in referenced protocols.
2148 if (ObjCProtocolDecl *Protocol = dyn_cast<ObjCProtocolDecl>(Container)) {
2149 for (ObjCProtocolDecl::protocol_iterator P = Protocol->protocol_begin(),
2150 PEnd = Protocol->protocol_end();
2151 P != PEnd; ++P)
Douglas Gregor5d649882009-11-18 22:32:06 +00002152 AddObjCProperties(*P, AllowCategories, CurContext, Results);
Douglas Gregor9291bad2009-11-18 01:29:26 +00002153 } else if (ObjCInterfaceDecl *IFace = dyn_cast<ObjCInterfaceDecl>(Container)){
Douglas Gregor5d649882009-11-18 22:32:06 +00002154 if (AllowCategories) {
2155 // Look through categories.
2156 for (ObjCCategoryDecl *Category = IFace->getCategoryList();
2157 Category; Category = Category->getNextClassCategory())
2158 AddObjCProperties(Category, AllowCategories, CurContext, Results);
2159 }
Douglas Gregor9291bad2009-11-18 01:29:26 +00002160
2161 // Look through protocols.
2162 for (ObjCInterfaceDecl::protocol_iterator I = IFace->protocol_begin(),
2163 E = IFace->protocol_end();
2164 I != E; ++I)
Douglas Gregor5d649882009-11-18 22:32:06 +00002165 AddObjCProperties(*I, AllowCategories, CurContext, Results);
Douglas Gregor9291bad2009-11-18 01:29:26 +00002166
2167 // Look in the superclass.
2168 if (IFace->getSuperClass())
Douglas Gregor5d649882009-11-18 22:32:06 +00002169 AddObjCProperties(IFace->getSuperClass(), AllowCategories, CurContext,
2170 Results);
Douglas Gregor9291bad2009-11-18 01:29:26 +00002171 } else if (const ObjCCategoryDecl *Category
2172 = dyn_cast<ObjCCategoryDecl>(Container)) {
2173 // Look through protocols.
2174 for (ObjCInterfaceDecl::protocol_iterator P = Category->protocol_begin(),
2175 PEnd = Category->protocol_end();
2176 P != PEnd; ++P)
Douglas Gregor5d649882009-11-18 22:32:06 +00002177 AddObjCProperties(*P, AllowCategories, CurContext, Results);
Douglas Gregor9291bad2009-11-18 01:29:26 +00002178 }
2179}
2180
Douglas Gregor2436e712009-09-17 21:32:03 +00002181void Sema::CodeCompleteMemberReferenceExpr(Scope *S, ExprTy *BaseE,
2182 SourceLocation OpLoc,
2183 bool IsArrow) {
2184 if (!BaseE || !CodeCompleter)
2185 return;
2186
Douglas Gregor3545ff42009-09-21 16:56:56 +00002187 typedef CodeCompleteConsumer::Result Result;
2188
Douglas Gregor2436e712009-09-17 21:32:03 +00002189 Expr *Base = static_cast<Expr *>(BaseE);
2190 QualType BaseType = Base->getType();
Douglas Gregor3545ff42009-09-21 16:56:56 +00002191
2192 if (IsArrow) {
2193 if (const PointerType *Ptr = BaseType->getAs<PointerType>())
2194 BaseType = Ptr->getPointeeType();
2195 else if (BaseType->isObjCObjectPointerType())
2196 /*Do nothing*/ ;
2197 else
2198 return;
2199 }
2200
Douglas Gregore412a5a2009-09-23 22:26:46 +00002201 ResultBuilder Results(*this, &ResultBuilder::IsMember);
Douglas Gregor9291bad2009-11-18 01:29:26 +00002202 Results.EnterNewScope();
2203 if (const RecordType *Record = BaseType->getAs<RecordType>()) {
2204 // Access to a C/C++ class, struct, or union.
Douglas Gregor6ae4c522010-01-14 03:21:49 +00002205 Results.allowNestedNameSpecifiers();
Douglas Gregor09bbc652010-01-14 15:47:35 +00002206 CodeCompletionDeclConsumer Consumer(Results, CurContext);
2207 LookupVisibleDecls(Record->getDecl(), LookupMemberName, Consumer);
Daniel Dunbar242ea9a2009-11-13 08:58:20 +00002208
Douglas Gregor9291bad2009-11-18 01:29:26 +00002209 if (getLangOptions().CPlusPlus) {
2210 if (!Results.empty()) {
2211 // The "template" keyword can follow "->" or "." in the grammar.
2212 // However, we only want to suggest the template keyword if something
2213 // is dependent.
2214 bool IsDependent = BaseType->isDependentType();
2215 if (!IsDependent) {
2216 for (Scope *DepScope = S; DepScope; DepScope = DepScope->getParent())
2217 if (DeclContext *Ctx = (DeclContext *)DepScope->getEntity()) {
2218 IsDependent = Ctx->isDependentContext();
2219 break;
2220 }
2221 }
Daniel Dunbar242ea9a2009-11-13 08:58:20 +00002222
Douglas Gregor9291bad2009-11-18 01:29:26 +00002223 if (IsDependent)
Douglas Gregor78a21012010-01-14 16:01:26 +00002224 Results.AddResult(Result("template"));
Daniel Dunbar242ea9a2009-11-13 08:58:20 +00002225 }
Daniel Dunbar242ea9a2009-11-13 08:58:20 +00002226 }
Douglas Gregor9291bad2009-11-18 01:29:26 +00002227 } else if (!IsArrow && BaseType->getAsObjCInterfacePointerType()) {
2228 // Objective-C property reference.
2229
2230 // Add property results based on our interface.
2231 const ObjCObjectPointerType *ObjCPtr
2232 = BaseType->getAsObjCInterfacePointerType();
2233 assert(ObjCPtr && "Non-NULL pointer guaranteed above!");
Douglas Gregor5d649882009-11-18 22:32:06 +00002234 AddObjCProperties(ObjCPtr->getInterfaceDecl(), true, CurContext, Results);
Douglas Gregor9291bad2009-11-18 01:29:26 +00002235
2236 // Add properties from the protocols in a qualified interface.
2237 for (ObjCObjectPointerType::qual_iterator I = ObjCPtr->qual_begin(),
2238 E = ObjCPtr->qual_end();
2239 I != E; ++I)
Douglas Gregor5d649882009-11-18 22:32:06 +00002240 AddObjCProperties(*I, true, CurContext, Results);
Douglas Gregor9291bad2009-11-18 01:29:26 +00002241 } else if ((IsArrow && BaseType->isObjCObjectPointerType()) ||
John McCall8b07ec22010-05-15 11:32:37 +00002242 (!IsArrow && BaseType->isObjCObjectType())) {
Douglas Gregor9291bad2009-11-18 01:29:26 +00002243 // Objective-C instance variable access.
2244 ObjCInterfaceDecl *Class = 0;
2245 if (const ObjCObjectPointerType *ObjCPtr
2246 = BaseType->getAs<ObjCObjectPointerType>())
2247 Class = ObjCPtr->getInterfaceDecl();
2248 else
John McCall8b07ec22010-05-15 11:32:37 +00002249 Class = BaseType->getAs<ObjCObjectType>()->getInterface();
Douglas Gregor9291bad2009-11-18 01:29:26 +00002250
2251 // Add all ivars from this class and its superclasses.
Douglas Gregor2b8162b2010-01-14 16:08:12 +00002252 if (Class) {
2253 CodeCompletionDeclConsumer Consumer(Results, CurContext);
2254 Results.setFilter(&ResultBuilder::IsObjCIvar);
2255 LookupVisibleDecls(Class, LookupMemberName, Consumer);
Douglas Gregor9291bad2009-11-18 01:29:26 +00002256 }
Douglas Gregor3545ff42009-09-21 16:56:56 +00002257 }
Douglas Gregor9291bad2009-11-18 01:29:26 +00002258
2259 // FIXME: How do we cope with isa?
2260
2261 Results.ExitScope();
Daniel Dunbar242ea9a2009-11-13 08:58:20 +00002262
Daniel Dunbar242ea9a2009-11-13 08:58:20 +00002263 // Hand off the results found for code completion.
2264 HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
Douglas Gregor2436e712009-09-17 21:32:03 +00002265}
2266
Douglas Gregorf45b0cf2009-09-18 15:37:17 +00002267void Sema::CodeCompleteTag(Scope *S, unsigned TagSpec) {
2268 if (!CodeCompleter)
2269 return;
2270
Douglas Gregor3545ff42009-09-21 16:56:56 +00002271 typedef CodeCompleteConsumer::Result Result;
2272 ResultBuilder::LookupFilter Filter = 0;
Douglas Gregorf45b0cf2009-09-18 15:37:17 +00002273 switch ((DeclSpec::TST)TagSpec) {
2274 case DeclSpec::TST_enum:
Douglas Gregor3545ff42009-09-21 16:56:56 +00002275 Filter = &ResultBuilder::IsEnum;
Douglas Gregorf45b0cf2009-09-18 15:37:17 +00002276 break;
2277
2278 case DeclSpec::TST_union:
Douglas Gregor3545ff42009-09-21 16:56:56 +00002279 Filter = &ResultBuilder::IsUnion;
Douglas Gregorf45b0cf2009-09-18 15:37:17 +00002280 break;
2281
2282 case DeclSpec::TST_struct:
Douglas Gregorf45b0cf2009-09-18 15:37:17 +00002283 case DeclSpec::TST_class:
Douglas Gregor3545ff42009-09-21 16:56:56 +00002284 Filter = &ResultBuilder::IsClassOrStruct;
Douglas Gregorf45b0cf2009-09-18 15:37:17 +00002285 break;
2286
2287 default:
2288 assert(false && "Unknown type specifier kind in CodeCompleteTag");
2289 return;
2290 }
Douglas Gregor3545ff42009-09-21 16:56:56 +00002291
John McCalle87beb22010-04-23 18:46:30 +00002292 ResultBuilder Results(*this);
Douglas Gregora6e2edc2010-01-14 03:27:13 +00002293 CodeCompletionDeclConsumer Consumer(Results, CurContext);
John McCalle87beb22010-04-23 18:46:30 +00002294
2295 // First pass: look for tags.
2296 Results.setFilter(Filter);
Douglas Gregora6e2edc2010-01-14 03:27:13 +00002297 LookupVisibleDecls(S, LookupTagName, Consumer);
John McCalle87beb22010-04-23 18:46:30 +00002298
2299 // Second pass: look for nested name specifiers.
2300 Results.setFilter(&ResultBuilder::IsNestedNameSpecifier);
2301 LookupVisibleDecls(S, LookupNestedNameSpecifierName, Consumer);
Douglas Gregor3545ff42009-09-21 16:56:56 +00002302
Daniel Dunbar242ea9a2009-11-13 08:58:20 +00002303 HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
Douglas Gregorf45b0cf2009-09-18 15:37:17 +00002304}
2305
Douglas Gregord328d572009-09-21 18:10:23 +00002306void Sema::CodeCompleteCase(Scope *S) {
2307 if (getSwitchStack().empty() || !CodeCompleter)
2308 return;
2309
2310 SwitchStmt *Switch = getSwitchStack().back();
2311 if (!Switch->getCond()->getType()->isEnumeralType())
2312 return;
2313
2314 // Code-complete the cases of a switch statement over an enumeration type
2315 // by providing the list of
2316 EnumDecl *Enum = Switch->getCond()->getType()->getAs<EnumType>()->getDecl();
2317
2318 // Determine which enumerators we have already seen in the switch statement.
2319 // FIXME: Ideally, we would also be able to look *past* the code-completion
2320 // token, in case we are code-completing in the middle of the switch and not
2321 // at the end. However, we aren't able to do so at the moment.
2322 llvm::SmallPtrSet<EnumConstantDecl *, 8> EnumeratorsSeen;
Douglas Gregorf2510672009-09-21 19:57:38 +00002323 NestedNameSpecifier *Qualifier = 0;
Douglas Gregord328d572009-09-21 18:10:23 +00002324 for (SwitchCase *SC = Switch->getSwitchCaseList(); SC;
2325 SC = SC->getNextSwitchCase()) {
2326 CaseStmt *Case = dyn_cast<CaseStmt>(SC);
2327 if (!Case)
2328 continue;
2329
2330 Expr *CaseVal = Case->getLHS()->IgnoreParenCasts();
2331 if (DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(CaseVal))
2332 if (EnumConstantDecl *Enumerator
2333 = dyn_cast<EnumConstantDecl>(DRE->getDecl())) {
2334 // We look into the AST of the case statement to determine which
2335 // enumerator was named. Alternatively, we could compute the value of
2336 // the integral constant expression, then compare it against the
2337 // values of each enumerator. However, value-based approach would not
2338 // work as well with C++ templates where enumerators declared within a
2339 // template are type- and value-dependent.
2340 EnumeratorsSeen.insert(Enumerator);
2341
Douglas Gregorf2510672009-09-21 19:57:38 +00002342 // If this is a qualified-id, keep track of the nested-name-specifier
2343 // so that we can reproduce it as part of code completion, e.g.,
Douglas Gregord328d572009-09-21 18:10:23 +00002344 //
2345 // switch (TagD.getKind()) {
2346 // case TagDecl::TK_enum:
2347 // break;
2348 // case XXX
2349 //
Douglas Gregorf2510672009-09-21 19:57:38 +00002350 // At the XXX, our completions are TagDecl::TK_union,
Douglas Gregord328d572009-09-21 18:10:23 +00002351 // TagDecl::TK_struct, and TagDecl::TK_class, rather than TK_union,
2352 // TK_struct, and TK_class.
Douglas Gregor4bd90e52009-10-23 18:54:35 +00002353 Qualifier = DRE->getQualifier();
Douglas Gregord328d572009-09-21 18:10:23 +00002354 }
2355 }
2356
Douglas Gregorf2510672009-09-21 19:57:38 +00002357 if (getLangOptions().CPlusPlus && !Qualifier && EnumeratorsSeen.empty()) {
2358 // If there are no prior enumerators in C++, check whether we have to
2359 // qualify the names of the enumerators that we suggest, because they
2360 // may not be visible in this scope.
2361 Qualifier = getRequiredQualification(Context, CurContext,
2362 Enum->getDeclContext());
2363
2364 // FIXME: Scoped enums need to start with "EnumDecl" as the context!
2365 }
2366
Douglas Gregord328d572009-09-21 18:10:23 +00002367 // Add any enumerators that have not yet been mentioned.
2368 ResultBuilder Results(*this);
2369 Results.EnterNewScope();
2370 for (EnumDecl::enumerator_iterator E = Enum->enumerator_begin(),
2371 EEnd = Enum->enumerator_end();
2372 E != EEnd; ++E) {
2373 if (EnumeratorsSeen.count(*E))
2374 continue;
2375
Douglas Gregorfc59ce12010-01-14 16:14:35 +00002376 Results.AddResult(CodeCompleteConsumer::Result(*E, Qualifier),
2377 CurContext, 0, false);
Douglas Gregord328d572009-09-21 18:10:23 +00002378 }
2379 Results.ExitScope();
Douglas Gregor285560922010-04-06 20:02:15 +00002380
Douglas Gregor9eb77012009-11-07 00:00:49 +00002381 if (CodeCompleter->includeMacros())
Douglas Gregorf98e6a22010-01-13 23:51:12 +00002382 AddMacroResults(PP, Results);
Daniel Dunbar242ea9a2009-11-13 08:58:20 +00002383 HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
Douglas Gregord328d572009-09-21 18:10:23 +00002384}
2385
Douglas Gregorcabea402009-09-22 15:41:20 +00002386namespace {
2387 struct IsBetterOverloadCandidate {
2388 Sema &S;
John McCallbc077cf2010-02-08 23:07:23 +00002389 SourceLocation Loc;
Douglas Gregorcabea402009-09-22 15:41:20 +00002390
2391 public:
John McCallbc077cf2010-02-08 23:07:23 +00002392 explicit IsBetterOverloadCandidate(Sema &S, SourceLocation Loc)
2393 : S(S), Loc(Loc) { }
Douglas Gregorcabea402009-09-22 15:41:20 +00002394
2395 bool
2396 operator()(const OverloadCandidate &X, const OverloadCandidate &Y) const {
John McCallbc077cf2010-02-08 23:07:23 +00002397 return S.isBetterOverloadCandidate(X, Y, Loc);
Douglas Gregorcabea402009-09-22 15:41:20 +00002398 }
2399 };
2400}
2401
2402void Sema::CodeCompleteCall(Scope *S, ExprTy *FnIn,
2403 ExprTy **ArgsIn, unsigned NumArgs) {
2404 if (!CodeCompleter)
2405 return;
Douglas Gregor3ef59522009-12-11 19:06:04 +00002406
2407 // When we're code-completing for a call, we fall back to ordinary
2408 // name code-completion whenever we can't produce specific
2409 // results. We may want to revisit this strategy in the future,
2410 // e.g., by merging the two kinds of results.
2411
Douglas Gregorcabea402009-09-22 15:41:20 +00002412 Expr *Fn = (Expr *)FnIn;
2413 Expr **Args = (Expr **)ArgsIn;
Douglas Gregor3ef59522009-12-11 19:06:04 +00002414
Douglas Gregorcabea402009-09-22 15:41:20 +00002415 // Ignore type-dependent call expressions entirely.
2416 if (Fn->isTypeDependent() ||
Douglas Gregor3ef59522009-12-11 19:06:04 +00002417 Expr::hasAnyTypeDependentArguments(Args, NumArgs)) {
Douglas Gregor504a6ae2010-01-10 23:08:15 +00002418 CodeCompleteOrdinaryName(S, CCC_Expression);
Douglas Gregorcabea402009-09-22 15:41:20 +00002419 return;
Douglas Gregor3ef59522009-12-11 19:06:04 +00002420 }
Douglas Gregorcabea402009-09-22 15:41:20 +00002421
John McCall57500772009-12-16 12:17:52 +00002422 // Build an overload candidate set based on the functions we find.
John McCallbc077cf2010-02-08 23:07:23 +00002423 SourceLocation Loc = Fn->getExprLoc();
2424 OverloadCandidateSet CandidateSet(Loc);
John McCall57500772009-12-16 12:17:52 +00002425
Douglas Gregorcabea402009-09-22 15:41:20 +00002426 // FIXME: What if we're calling something that isn't a function declaration?
2427 // FIXME: What if we're calling a pseudo-destructor?
2428 // FIXME: What if we're calling a member function?
2429
Douglas Gregorff59f672010-01-21 15:46:19 +00002430 typedef CodeCompleteConsumer::OverloadCandidate ResultCandidate;
2431 llvm::SmallVector<ResultCandidate, 8> Results;
2432
John McCall57500772009-12-16 12:17:52 +00002433 Expr *NakedFn = Fn->IgnoreParenCasts();
2434 if (UnresolvedLookupExpr *ULE = dyn_cast<UnresolvedLookupExpr>(NakedFn))
2435 AddOverloadedCallCandidates(ULE, Args, NumArgs, CandidateSet,
2436 /*PartialOverloading=*/ true);
2437 else if (DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(NakedFn)) {
2438 FunctionDecl *FDecl = dyn_cast<FunctionDecl>(DRE->getDecl());
Douglas Gregorff59f672010-01-21 15:46:19 +00002439 if (FDecl) {
2440 if (!FDecl->getType()->getAs<FunctionProtoType>())
2441 Results.push_back(ResultCandidate(FDecl));
2442 else
John McCallb89836b2010-01-26 01:37:31 +00002443 // FIXME: access?
John McCalla0296f72010-03-19 07:35:19 +00002444 AddOverloadCandidate(FDecl, DeclAccessPair::make(FDecl, AS_none),
2445 Args, NumArgs, CandidateSet,
Douglas Gregorb05275a2010-04-16 17:41:49 +00002446 false, /*PartialOverloading*/true);
Douglas Gregorff59f672010-01-21 15:46:19 +00002447 }
John McCall57500772009-12-16 12:17:52 +00002448 }
Douglas Gregorcabea402009-09-22 15:41:20 +00002449
Douglas Gregorff59f672010-01-21 15:46:19 +00002450 if (!CandidateSet.empty()) {
2451 // Sort the overload candidate set by placing the best overloads first.
2452 std::stable_sort(CandidateSet.begin(), CandidateSet.end(),
John McCallbc077cf2010-02-08 23:07:23 +00002453 IsBetterOverloadCandidate(*this, Loc));
Douglas Gregorcabea402009-09-22 15:41:20 +00002454
Douglas Gregorff59f672010-01-21 15:46:19 +00002455 // Add the remaining viable overload candidates as code-completion reslults.
2456 for (OverloadCandidateSet::iterator Cand = CandidateSet.begin(),
2457 CandEnd = CandidateSet.end();
2458 Cand != CandEnd; ++Cand) {
2459 if (Cand->Viable)
2460 Results.push_back(ResultCandidate(Cand->Function));
2461 }
Douglas Gregorcabea402009-09-22 15:41:20 +00002462 }
Douglas Gregor3ef59522009-12-11 19:06:04 +00002463
Douglas Gregorc01890e2010-04-06 20:19:47 +00002464 CodeCompleteOrdinaryName(S, CCC_Expression);
2465 if (!Results.empty())
Douglas Gregor3ef59522009-12-11 19:06:04 +00002466 CodeCompleter->ProcessOverloadCandidates(*this, NumArgs, Results.data(),
2467 Results.size());
Douglas Gregorcabea402009-09-22 15:41:20 +00002468}
2469
Jeffrey Yasskinc76498d2010-04-08 16:38:48 +00002470void Sema::CodeCompleteQualifiedId(Scope *S, CXXScopeSpec &SS,
Douglas Gregor2436e712009-09-17 21:32:03 +00002471 bool EnteringContext) {
2472 if (!SS.getScopeRep() || !CodeCompleter)
2473 return;
2474
Douglas Gregor3545ff42009-09-21 16:56:56 +00002475 DeclContext *Ctx = computeDeclContext(SS, EnteringContext);
2476 if (!Ctx)
2477 return;
Douglas Gregor800f2f02009-12-11 18:28:39 +00002478
2479 // Try to instantiate any non-dependent declaration contexts before
2480 // we look in them.
John McCall0b66eb32010-05-01 00:40:08 +00002481 if (!isDependentScopeSpecifier(SS) && RequireCompleteDeclContext(SS, Ctx))
Douglas Gregor800f2f02009-12-11 18:28:39 +00002482 return;
2483
Douglas Gregor3545ff42009-09-21 16:56:56 +00002484 ResultBuilder Results(*this);
Douglas Gregor200c99d2010-01-14 03:35:48 +00002485 CodeCompletionDeclConsumer Consumer(Results, CurContext);
2486 LookupVisibleDecls(Ctx, LookupOrdinaryName, Consumer);
Douglas Gregor3545ff42009-09-21 16:56:56 +00002487
2488 // The "template" keyword can follow "::" in the grammar, but only
2489 // put it into the grammar if the nested-name-specifier is dependent.
2490 NestedNameSpecifier *NNS = (NestedNameSpecifier *)SS.getScopeRep();
2491 if (!Results.empty() && NNS->isDependent())
Douglas Gregor78a21012010-01-14 16:01:26 +00002492 Results.AddResult("template");
Douglas Gregor3545ff42009-09-21 16:56:56 +00002493
Daniel Dunbar242ea9a2009-11-13 08:58:20 +00002494 HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
Douglas Gregor2436e712009-09-17 21:32:03 +00002495}
Douglas Gregor7e90c6d2009-09-18 19:03:04 +00002496
2497void Sema::CodeCompleteUsing(Scope *S) {
2498 if (!CodeCompleter)
2499 return;
2500
Douglas Gregor3545ff42009-09-21 16:56:56 +00002501 ResultBuilder Results(*this, &ResultBuilder::IsNestedNameSpecifier);
Douglas Gregor64b12b52009-09-22 23:31:26 +00002502 Results.EnterNewScope();
Douglas Gregor3545ff42009-09-21 16:56:56 +00002503
2504 // If we aren't in class scope, we could see the "namespace" keyword.
2505 if (!S->isClassScope())
Douglas Gregor78a21012010-01-14 16:01:26 +00002506 Results.AddResult(CodeCompleteConsumer::Result("namespace"));
Douglas Gregor3545ff42009-09-21 16:56:56 +00002507
2508 // After "using", we can see anything that would start a
2509 // nested-name-specifier.
Douglas Gregora6e2edc2010-01-14 03:27:13 +00002510 CodeCompletionDeclConsumer Consumer(Results, CurContext);
2511 LookupVisibleDecls(S, LookupOrdinaryName, Consumer);
Douglas Gregor64b12b52009-09-22 23:31:26 +00002512 Results.ExitScope();
Douglas Gregor3545ff42009-09-21 16:56:56 +00002513
Daniel Dunbar242ea9a2009-11-13 08:58:20 +00002514 HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
Douglas Gregor7e90c6d2009-09-18 19:03:04 +00002515}
2516
2517void Sema::CodeCompleteUsingDirective(Scope *S) {
2518 if (!CodeCompleter)
2519 return;
2520
Douglas Gregor3545ff42009-09-21 16:56:56 +00002521 // After "using namespace", we expect to see a namespace name or namespace
2522 // alias.
2523 ResultBuilder Results(*this, &ResultBuilder::IsNamespaceOrAlias);
Douglas Gregor64b12b52009-09-22 23:31:26 +00002524 Results.EnterNewScope();
Douglas Gregora6e2edc2010-01-14 03:27:13 +00002525 CodeCompletionDeclConsumer Consumer(Results, CurContext);
2526 LookupVisibleDecls(S, LookupOrdinaryName, Consumer);
Douglas Gregor64b12b52009-09-22 23:31:26 +00002527 Results.ExitScope();
Daniel Dunbar242ea9a2009-11-13 08:58:20 +00002528 HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
Douglas Gregor7e90c6d2009-09-18 19:03:04 +00002529}
2530
2531void Sema::CodeCompleteNamespaceDecl(Scope *S) {
2532 if (!CodeCompleter)
2533 return;
2534
Douglas Gregor3545ff42009-09-21 16:56:56 +00002535 ResultBuilder Results(*this, &ResultBuilder::IsNamespace);
2536 DeclContext *Ctx = (DeclContext *)S->getEntity();
2537 if (!S->getParent())
2538 Ctx = Context.getTranslationUnitDecl();
2539
2540 if (Ctx && Ctx->isFileContext()) {
2541 // We only want to see those namespaces that have already been defined
2542 // within this scope, because its likely that the user is creating an
2543 // extended namespace declaration. Keep track of the most recent
2544 // definition of each namespace.
2545 std::map<NamespaceDecl *, NamespaceDecl *> OrigToLatest;
2546 for (DeclContext::specific_decl_iterator<NamespaceDecl>
2547 NS(Ctx->decls_begin()), NSEnd(Ctx->decls_end());
2548 NS != NSEnd; ++NS)
2549 OrigToLatest[NS->getOriginalNamespace()] = *NS;
2550
2551 // Add the most recent definition (or extended definition) of each
2552 // namespace to the list of results.
Douglas Gregor64b12b52009-09-22 23:31:26 +00002553 Results.EnterNewScope();
Douglas Gregor3545ff42009-09-21 16:56:56 +00002554 for (std::map<NamespaceDecl *, NamespaceDecl *>::iterator
2555 NS = OrigToLatest.begin(), NSEnd = OrigToLatest.end();
2556 NS != NSEnd; ++NS)
Douglas Gregorfc59ce12010-01-14 16:14:35 +00002557 Results.AddResult(CodeCompleteConsumer::Result(NS->second, 0),
2558 CurContext, 0, false);
Douglas Gregor64b12b52009-09-22 23:31:26 +00002559 Results.ExitScope();
Douglas Gregor3545ff42009-09-21 16:56:56 +00002560 }
2561
Daniel Dunbar242ea9a2009-11-13 08:58:20 +00002562 HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
Douglas Gregor7e90c6d2009-09-18 19:03:04 +00002563}
2564
2565void Sema::CodeCompleteNamespaceAliasDecl(Scope *S) {
2566 if (!CodeCompleter)
2567 return;
2568
Douglas Gregor3545ff42009-09-21 16:56:56 +00002569 // After "namespace", we expect to see a namespace or alias.
2570 ResultBuilder Results(*this, &ResultBuilder::IsNamespaceOrAlias);
Douglas Gregora6e2edc2010-01-14 03:27:13 +00002571 CodeCompletionDeclConsumer Consumer(Results, CurContext);
2572 LookupVisibleDecls(S, LookupOrdinaryName, Consumer);
Daniel Dunbar242ea9a2009-11-13 08:58:20 +00002573 HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
Douglas Gregor7e90c6d2009-09-18 19:03:04 +00002574}
2575
Douglas Gregorc811ede2009-09-18 20:05:18 +00002576void Sema::CodeCompleteOperatorName(Scope *S) {
2577 if (!CodeCompleter)
2578 return;
Douglas Gregor3545ff42009-09-21 16:56:56 +00002579
2580 typedef CodeCompleteConsumer::Result Result;
2581 ResultBuilder Results(*this, &ResultBuilder::IsType);
Douglas Gregor64b12b52009-09-22 23:31:26 +00002582 Results.EnterNewScope();
Douglas Gregorc811ede2009-09-18 20:05:18 +00002583
Douglas Gregor3545ff42009-09-21 16:56:56 +00002584 // Add the names of overloadable operators.
2585#define OVERLOADED_OPERATOR(Name,Spelling,Token,Unary,Binary,MemberOnly) \
2586 if (std::strcmp(Spelling, "?")) \
Douglas Gregor78a21012010-01-14 16:01:26 +00002587 Results.AddResult(Result(Spelling));
Douglas Gregor3545ff42009-09-21 16:56:56 +00002588#include "clang/Basic/OperatorKinds.def"
2589
2590 // Add any type names visible from the current scope
Douglas Gregor6ae4c522010-01-14 03:21:49 +00002591 Results.allowNestedNameSpecifiers();
Douglas Gregora6e2edc2010-01-14 03:27:13 +00002592 CodeCompletionDeclConsumer Consumer(Results, CurContext);
2593 LookupVisibleDecls(S, LookupOrdinaryName, Consumer);
Douglas Gregor3545ff42009-09-21 16:56:56 +00002594
2595 // Add any type specifiers
Douglas Gregorf98e6a22010-01-13 23:51:12 +00002596 AddTypeSpecifierResults(getLangOptions(), Results);
Douglas Gregor64b12b52009-09-22 23:31:26 +00002597 Results.ExitScope();
Douglas Gregor3545ff42009-09-21 16:56:56 +00002598
Daniel Dunbar242ea9a2009-11-13 08:58:20 +00002599 HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
Douglas Gregorc811ede2009-09-18 20:05:18 +00002600}
Douglas Gregor7e90c6d2009-09-18 19:03:04 +00002601
Douglas Gregorf1934162010-01-13 21:24:21 +00002602// Macro that expands to @Keyword or Keyword, depending on whether NeedAt is
2603// true or false.
2604#define OBJC_AT_KEYWORD_NAME(NeedAt,Keyword) NeedAt? "@" #Keyword : #Keyword
Douglas Gregorf98e6a22010-01-13 23:51:12 +00002605static void AddObjCImplementationResults(const LangOptions &LangOpts,
Douglas Gregorf1934162010-01-13 21:24:21 +00002606 ResultBuilder &Results,
2607 bool NeedAt) {
2608 typedef CodeCompleteConsumer::Result Result;
2609 // Since we have an implementation, we can end it.
Douglas Gregor78a21012010-01-14 16:01:26 +00002610 Results.AddResult(Result(OBJC_AT_KEYWORD_NAME(NeedAt,end)));
Douglas Gregorf1934162010-01-13 21:24:21 +00002611
2612 CodeCompletionString *Pattern = 0;
2613 if (LangOpts.ObjC2) {
2614 // @dynamic
2615 Pattern = new CodeCompletionString;
2616 Pattern->AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt,dynamic));
2617 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
2618 Pattern->AddPlaceholderChunk("property");
Douglas Gregor78a21012010-01-14 16:01:26 +00002619 Results.AddResult(Result(Pattern));
Douglas Gregorf1934162010-01-13 21:24:21 +00002620
2621 // @synthesize
2622 Pattern = new CodeCompletionString;
2623 Pattern->AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt,synthesize));
2624 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
2625 Pattern->AddPlaceholderChunk("property");
Douglas Gregor78a21012010-01-14 16:01:26 +00002626 Results.AddResult(Result(Pattern));
Douglas Gregorf1934162010-01-13 21:24:21 +00002627 }
2628}
2629
Douglas Gregorf98e6a22010-01-13 23:51:12 +00002630static void AddObjCInterfaceResults(const LangOptions &LangOpts,
Douglas Gregorf1934162010-01-13 21:24:21 +00002631 ResultBuilder &Results,
2632 bool NeedAt) {
2633 typedef CodeCompleteConsumer::Result Result;
2634
2635 // Since we have an interface or protocol, we can end it.
Douglas Gregor78a21012010-01-14 16:01:26 +00002636 Results.AddResult(Result(OBJC_AT_KEYWORD_NAME(NeedAt,end)));
Douglas Gregorf1934162010-01-13 21:24:21 +00002637
2638 if (LangOpts.ObjC2) {
2639 // @property
Douglas Gregor78a21012010-01-14 16:01:26 +00002640 Results.AddResult(Result(OBJC_AT_KEYWORD_NAME(NeedAt,property)));
Douglas Gregorf1934162010-01-13 21:24:21 +00002641
2642 // @required
Douglas Gregor78a21012010-01-14 16:01:26 +00002643 Results.AddResult(Result(OBJC_AT_KEYWORD_NAME(NeedAt,required)));
Douglas Gregorf1934162010-01-13 21:24:21 +00002644
2645 // @optional
Douglas Gregor78a21012010-01-14 16:01:26 +00002646 Results.AddResult(Result(OBJC_AT_KEYWORD_NAME(NeedAt,optional)));
Douglas Gregorf1934162010-01-13 21:24:21 +00002647 }
2648}
2649
Douglas Gregorf98e6a22010-01-13 23:51:12 +00002650static void AddObjCTopLevelResults(ResultBuilder &Results, bool NeedAt) {
Douglas Gregorf1934162010-01-13 21:24:21 +00002651 typedef CodeCompleteConsumer::Result Result;
2652 CodeCompletionString *Pattern = 0;
2653
2654 // @class name ;
2655 Pattern = new CodeCompletionString;
2656 Pattern->AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt,class));
2657 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
Douglas Gregorf4c33342010-05-28 00:22:41 +00002658 Pattern->AddPlaceholderChunk("name");
Douglas Gregor78a21012010-01-14 16:01:26 +00002659 Results.AddResult(Result(Pattern));
Douglas Gregorf1934162010-01-13 21:24:21 +00002660
Douglas Gregorf4c33342010-05-28 00:22:41 +00002661 if (Results.includeCodePatterns()) {
2662 // @interface name
2663 // FIXME: Could introduce the whole pattern, including superclasses and
2664 // such.
2665 Pattern = new CodeCompletionString;
2666 Pattern->AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt,interface));
2667 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
2668 Pattern->AddPlaceholderChunk("class");
2669 Results.AddResult(Result(Pattern));
Douglas Gregorf1934162010-01-13 21:24:21 +00002670
Douglas Gregorf4c33342010-05-28 00:22:41 +00002671 // @protocol name
2672 Pattern = new CodeCompletionString;
2673 Pattern->AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt,protocol));
2674 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
2675 Pattern->AddPlaceholderChunk("protocol");
2676 Results.AddResult(Result(Pattern));
2677
2678 // @implementation name
2679 Pattern = new CodeCompletionString;
2680 Pattern->AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt,implementation));
2681 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
2682 Pattern->AddPlaceholderChunk("class");
2683 Results.AddResult(Result(Pattern));
2684 }
Douglas Gregorf1934162010-01-13 21:24:21 +00002685
2686 // @compatibility_alias name
2687 Pattern = new CodeCompletionString;
2688 Pattern->AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt,compatibility_alias));
2689 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
2690 Pattern->AddPlaceholderChunk("alias");
2691 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
2692 Pattern->AddPlaceholderChunk("class");
Douglas Gregor78a21012010-01-14 16:01:26 +00002693 Results.AddResult(Result(Pattern));
Douglas Gregorf1934162010-01-13 21:24:21 +00002694}
2695
Douglas Gregorf48706c2009-12-07 09:27:33 +00002696void Sema::CodeCompleteObjCAtDirective(Scope *S, DeclPtrTy ObjCImpDecl,
2697 bool InInterface) {
2698 typedef CodeCompleteConsumer::Result Result;
2699 ResultBuilder Results(*this);
2700 Results.EnterNewScope();
Douglas Gregorf1934162010-01-13 21:24:21 +00002701 if (ObjCImpDecl)
Douglas Gregorf98e6a22010-01-13 23:51:12 +00002702 AddObjCImplementationResults(getLangOptions(), Results, false);
Douglas Gregorf1934162010-01-13 21:24:21 +00002703 else if (InInterface)
Douglas Gregorf98e6a22010-01-13 23:51:12 +00002704 AddObjCInterfaceResults(getLangOptions(), Results, false);
Douglas Gregorf1934162010-01-13 21:24:21 +00002705 else
Douglas Gregorf98e6a22010-01-13 23:51:12 +00002706 AddObjCTopLevelResults(Results, false);
Douglas Gregorf48706c2009-12-07 09:27:33 +00002707 Results.ExitScope();
2708 HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
2709}
2710
Douglas Gregorf98e6a22010-01-13 23:51:12 +00002711static void AddObjCExpressionResults(ResultBuilder &Results, bool NeedAt) {
Douglas Gregorbc7c5e42009-12-07 09:51:25 +00002712 typedef CodeCompleteConsumer::Result Result;
2713 CodeCompletionString *Pattern = 0;
2714
2715 // @encode ( type-name )
2716 Pattern = new CodeCompletionString;
Douglas Gregorf1934162010-01-13 21:24:21 +00002717 Pattern->AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt,encode));
Douglas Gregorbc7c5e42009-12-07 09:51:25 +00002718 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
2719 Pattern->AddPlaceholderChunk("type-name");
2720 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
Douglas Gregor78a21012010-01-14 16:01:26 +00002721 Results.AddResult(Result(Pattern));
Douglas Gregorbc7c5e42009-12-07 09:51:25 +00002722
2723 // @protocol ( protocol-name )
2724 Pattern = new CodeCompletionString;
Douglas Gregorf1934162010-01-13 21:24:21 +00002725 Pattern->AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt,protocol));
Douglas Gregorbc7c5e42009-12-07 09:51:25 +00002726 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
2727 Pattern->AddPlaceholderChunk("protocol-name");
2728 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
Douglas Gregor78a21012010-01-14 16:01:26 +00002729 Results.AddResult(Result(Pattern));
Douglas Gregorbc7c5e42009-12-07 09:51:25 +00002730
2731 // @selector ( selector )
2732 Pattern = new CodeCompletionString;
Douglas Gregorf1934162010-01-13 21:24:21 +00002733 Pattern->AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt,selector));
Douglas Gregorbc7c5e42009-12-07 09:51:25 +00002734 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
2735 Pattern->AddPlaceholderChunk("selector");
2736 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
Douglas Gregor78a21012010-01-14 16:01:26 +00002737 Results.AddResult(Result(Pattern));
Douglas Gregorbc7c5e42009-12-07 09:51:25 +00002738}
2739
Douglas Gregorf98e6a22010-01-13 23:51:12 +00002740static void AddObjCStatementResults(ResultBuilder &Results, bool NeedAt) {
Douglas Gregorbc7c5e42009-12-07 09:51:25 +00002741 typedef CodeCompleteConsumer::Result Result;
Douglas Gregorbc7c5e42009-12-07 09:51:25 +00002742 CodeCompletionString *Pattern = 0;
Douglas Gregorf1934162010-01-13 21:24:21 +00002743
Douglas Gregorf4c33342010-05-28 00:22:41 +00002744 if (Results.includeCodePatterns()) {
2745 // @try { statements } @catch ( declaration ) { statements } @finally
2746 // { statements }
2747 Pattern = new CodeCompletionString;
2748 Pattern->AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt,try));
2749 Pattern->AddChunk(CodeCompletionString::CK_LeftBrace);
2750 Pattern->AddPlaceholderChunk("statements");
2751 Pattern->AddChunk(CodeCompletionString::CK_RightBrace);
2752 Pattern->AddTextChunk("@catch");
2753 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
2754 Pattern->AddPlaceholderChunk("parameter");
2755 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
2756 Pattern->AddChunk(CodeCompletionString::CK_LeftBrace);
2757 Pattern->AddPlaceholderChunk("statements");
2758 Pattern->AddChunk(CodeCompletionString::CK_RightBrace);
2759 Pattern->AddTextChunk("@finally");
2760 Pattern->AddChunk(CodeCompletionString::CK_LeftBrace);
2761 Pattern->AddPlaceholderChunk("statements");
2762 Pattern->AddChunk(CodeCompletionString::CK_RightBrace);
2763 Results.AddResult(Result(Pattern));
2764 }
Douglas Gregorf1934162010-01-13 21:24:21 +00002765
Douglas Gregorbc7c5e42009-12-07 09:51:25 +00002766 // @throw
2767 Pattern = new CodeCompletionString;
Douglas Gregorf1934162010-01-13 21:24:21 +00002768 Pattern->AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt,throw));
Douglas Gregor6a803932010-01-12 06:38:28 +00002769 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
Douglas Gregorbc7c5e42009-12-07 09:51:25 +00002770 Pattern->AddPlaceholderChunk("expression");
Douglas Gregor78a21012010-01-14 16:01:26 +00002771 Results.AddResult(Result(Pattern));
Douglas Gregorf1934162010-01-13 21:24:21 +00002772
Douglas Gregorf4c33342010-05-28 00:22:41 +00002773 if (Results.includeCodePatterns()) {
2774 // @synchronized ( expression ) { statements }
2775 Pattern = new CodeCompletionString;
2776 Pattern->AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt,synchronized));
2777 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
2778 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
2779 Pattern->AddPlaceholderChunk("expression");
2780 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
2781 Pattern->AddChunk(CodeCompletionString::CK_LeftBrace);
2782 Pattern->AddPlaceholderChunk("statements");
2783 Pattern->AddChunk(CodeCompletionString::CK_RightBrace);
2784 Results.AddResult(Result(Pattern));
2785 }
Douglas Gregorf1934162010-01-13 21:24:21 +00002786}
Douglas Gregorbc7c5e42009-12-07 09:51:25 +00002787
Douglas Gregorf98e6a22010-01-13 23:51:12 +00002788static void AddObjCVisibilityResults(const LangOptions &LangOpts,
Douglas Gregor48d46252010-01-13 21:54:15 +00002789 ResultBuilder &Results,
2790 bool NeedAt) {
Douglas Gregorf1934162010-01-13 21:24:21 +00002791 typedef CodeCompleteConsumer::Result Result;
Douglas Gregor78a21012010-01-14 16:01:26 +00002792 Results.AddResult(Result(OBJC_AT_KEYWORD_NAME(NeedAt,private)));
2793 Results.AddResult(Result(OBJC_AT_KEYWORD_NAME(NeedAt,protected)));
2794 Results.AddResult(Result(OBJC_AT_KEYWORD_NAME(NeedAt,public)));
Douglas Gregor48d46252010-01-13 21:54:15 +00002795 if (LangOpts.ObjC2)
Douglas Gregor78a21012010-01-14 16:01:26 +00002796 Results.AddResult(Result(OBJC_AT_KEYWORD_NAME(NeedAt,package)));
Douglas Gregor48d46252010-01-13 21:54:15 +00002797}
2798
2799void Sema::CodeCompleteObjCAtVisibility(Scope *S) {
2800 ResultBuilder Results(*this);
2801 Results.EnterNewScope();
Douglas Gregorf98e6a22010-01-13 23:51:12 +00002802 AddObjCVisibilityResults(getLangOptions(), Results, false);
Douglas Gregor48d46252010-01-13 21:54:15 +00002803 Results.ExitScope();
2804 HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
2805}
2806
2807void Sema::CodeCompleteObjCAtStatement(Scope *S) {
Douglas Gregorf1934162010-01-13 21:24:21 +00002808 ResultBuilder Results(*this);
2809 Results.EnterNewScope();
Douglas Gregorf98e6a22010-01-13 23:51:12 +00002810 AddObjCStatementResults(Results, false);
2811 AddObjCExpressionResults(Results, false);
Douglas Gregorbc7c5e42009-12-07 09:51:25 +00002812 Results.ExitScope();
2813 HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
2814}
2815
2816void Sema::CodeCompleteObjCAtExpression(Scope *S) {
2817 ResultBuilder Results(*this);
2818 Results.EnterNewScope();
Douglas Gregorf98e6a22010-01-13 23:51:12 +00002819 AddObjCExpressionResults(Results, false);
Douglas Gregorbc7c5e42009-12-07 09:51:25 +00002820 Results.ExitScope();
2821 HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
2822}
2823
Douglas Gregore6078da2009-11-19 00:14:45 +00002824/// \brief Determine whether the addition of the given flag to an Objective-C
2825/// property's attributes will cause a conflict.
2826static bool ObjCPropertyFlagConflicts(unsigned Attributes, unsigned NewFlag) {
2827 // Check if we've already added this flag.
2828 if (Attributes & NewFlag)
2829 return true;
2830
2831 Attributes |= NewFlag;
2832
2833 // Check for collisions with "readonly".
2834 if ((Attributes & ObjCDeclSpec::DQ_PR_readonly) &&
2835 (Attributes & (ObjCDeclSpec::DQ_PR_readwrite |
2836 ObjCDeclSpec::DQ_PR_assign |
2837 ObjCDeclSpec::DQ_PR_copy |
2838 ObjCDeclSpec::DQ_PR_retain)))
2839 return true;
2840
2841 // Check for more than one of { assign, copy, retain }.
2842 unsigned AssignCopyRetMask = Attributes & (ObjCDeclSpec::DQ_PR_assign |
2843 ObjCDeclSpec::DQ_PR_copy |
2844 ObjCDeclSpec::DQ_PR_retain);
2845 if (AssignCopyRetMask &&
2846 AssignCopyRetMask != ObjCDeclSpec::DQ_PR_assign &&
2847 AssignCopyRetMask != ObjCDeclSpec::DQ_PR_copy &&
2848 AssignCopyRetMask != ObjCDeclSpec::DQ_PR_retain)
2849 return true;
2850
2851 return false;
2852}
2853
Douglas Gregor36029f42009-11-18 23:08:07 +00002854void Sema::CodeCompleteObjCPropertyFlags(Scope *S, ObjCDeclSpec &ODS) {
Steve Naroff936354c2009-10-08 21:55:05 +00002855 if (!CodeCompleter)
2856 return;
Douglas Gregor1b605f72009-11-19 01:08:35 +00002857
Steve Naroff936354c2009-10-08 21:55:05 +00002858 unsigned Attributes = ODS.getPropertyAttributes();
2859
2860 typedef CodeCompleteConsumer::Result Result;
2861 ResultBuilder Results(*this);
2862 Results.EnterNewScope();
Douglas Gregore6078da2009-11-19 00:14:45 +00002863 if (!ObjCPropertyFlagConflicts(Attributes, ObjCDeclSpec::DQ_PR_readonly))
Douglas Gregor78a21012010-01-14 16:01:26 +00002864 Results.AddResult(CodeCompleteConsumer::Result("readonly"));
Douglas Gregore6078da2009-11-19 00:14:45 +00002865 if (!ObjCPropertyFlagConflicts(Attributes, ObjCDeclSpec::DQ_PR_assign))
Douglas Gregor78a21012010-01-14 16:01:26 +00002866 Results.AddResult(CodeCompleteConsumer::Result("assign"));
Douglas Gregore6078da2009-11-19 00:14:45 +00002867 if (!ObjCPropertyFlagConflicts(Attributes, ObjCDeclSpec::DQ_PR_readwrite))
Douglas Gregor78a21012010-01-14 16:01:26 +00002868 Results.AddResult(CodeCompleteConsumer::Result("readwrite"));
Douglas Gregore6078da2009-11-19 00:14:45 +00002869 if (!ObjCPropertyFlagConflicts(Attributes, ObjCDeclSpec::DQ_PR_retain))
Douglas Gregor78a21012010-01-14 16:01:26 +00002870 Results.AddResult(CodeCompleteConsumer::Result("retain"));
Douglas Gregore6078da2009-11-19 00:14:45 +00002871 if (!ObjCPropertyFlagConflicts(Attributes, ObjCDeclSpec::DQ_PR_copy))
Douglas Gregor78a21012010-01-14 16:01:26 +00002872 Results.AddResult(CodeCompleteConsumer::Result("copy"));
Douglas Gregore6078da2009-11-19 00:14:45 +00002873 if (!ObjCPropertyFlagConflicts(Attributes, ObjCDeclSpec::DQ_PR_nonatomic))
Douglas Gregor78a21012010-01-14 16:01:26 +00002874 Results.AddResult(CodeCompleteConsumer::Result("nonatomic"));
Douglas Gregore6078da2009-11-19 00:14:45 +00002875 if (!ObjCPropertyFlagConflicts(Attributes, ObjCDeclSpec::DQ_PR_setter)) {
Douglas Gregor45f83ee2009-11-19 00:01:57 +00002876 CodeCompletionString *Setter = new CodeCompletionString;
2877 Setter->AddTypedTextChunk("setter");
2878 Setter->AddTextChunk(" = ");
2879 Setter->AddPlaceholderChunk("method");
Douglas Gregor78a21012010-01-14 16:01:26 +00002880 Results.AddResult(CodeCompleteConsumer::Result(Setter));
Douglas Gregor45f83ee2009-11-19 00:01:57 +00002881 }
Douglas Gregore6078da2009-11-19 00:14:45 +00002882 if (!ObjCPropertyFlagConflicts(Attributes, ObjCDeclSpec::DQ_PR_getter)) {
Douglas Gregor45f83ee2009-11-19 00:01:57 +00002883 CodeCompletionString *Getter = new CodeCompletionString;
2884 Getter->AddTypedTextChunk("getter");
2885 Getter->AddTextChunk(" = ");
2886 Getter->AddPlaceholderChunk("method");
Douglas Gregor78a21012010-01-14 16:01:26 +00002887 Results.AddResult(CodeCompleteConsumer::Result(Getter));
Douglas Gregor45f83ee2009-11-19 00:01:57 +00002888 }
Steve Naroff936354c2009-10-08 21:55:05 +00002889 Results.ExitScope();
Daniel Dunbar242ea9a2009-11-13 08:58:20 +00002890 HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
Steve Naroff936354c2009-10-08 21:55:05 +00002891}
Steve Naroffeae65032009-11-07 02:08:14 +00002892
Douglas Gregorc8537c52009-11-19 07:41:15 +00002893/// \brief Descripts the kind of Objective-C method that we want to find
2894/// via code completion.
2895enum ObjCMethodKind {
2896 MK_Any, //< Any kind of method, provided it means other specified criteria.
2897 MK_ZeroArgSelector, //< Zero-argument (unary) selector.
2898 MK_OneArgSelector //< One-argument selector.
2899};
2900
2901static bool isAcceptableObjCMethod(ObjCMethodDecl *Method,
2902 ObjCMethodKind WantKind,
2903 IdentifierInfo **SelIdents,
2904 unsigned NumSelIdents) {
2905 Selector Sel = Method->getSelector();
2906 if (NumSelIdents > Sel.getNumArgs())
2907 return false;
2908
2909 switch (WantKind) {
2910 case MK_Any: break;
2911 case MK_ZeroArgSelector: return Sel.isUnarySelector();
2912 case MK_OneArgSelector: return Sel.getNumArgs() == 1;
2913 }
2914
2915 for (unsigned I = 0; I != NumSelIdents; ++I)
2916 if (SelIdents[I] != Sel.getIdentifierInfoForSlot(I))
2917 return false;
2918
2919 return true;
2920}
2921
Douglas Gregorbab2b3c2009-11-17 23:22:23 +00002922/// \brief Add all of the Objective-C methods in the given Objective-C
2923/// container to the set of results.
2924///
2925/// The container will be a class, protocol, category, or implementation of
2926/// any of the above. This mether will recurse to include methods from
2927/// the superclasses of classes along with their categories, protocols, and
2928/// implementations.
2929///
2930/// \param Container the container in which we'll look to find methods.
2931///
2932/// \param WantInstance whether to add instance methods (only); if false, this
2933/// routine will add factory methods (only).
2934///
2935/// \param CurContext the context in which we're performing the lookup that
2936/// finds methods.
2937///
2938/// \param Results the structure into which we'll add results.
2939static void AddObjCMethods(ObjCContainerDecl *Container,
2940 bool WantInstanceMethods,
Douglas Gregorc8537c52009-11-19 07:41:15 +00002941 ObjCMethodKind WantKind,
Douglas Gregor1b605f72009-11-19 01:08:35 +00002942 IdentifierInfo **SelIdents,
2943 unsigned NumSelIdents,
Douglas Gregorbab2b3c2009-11-17 23:22:23 +00002944 DeclContext *CurContext,
2945 ResultBuilder &Results) {
2946 typedef CodeCompleteConsumer::Result Result;
2947 for (ObjCContainerDecl::method_iterator M = Container->meth_begin(),
2948 MEnd = Container->meth_end();
2949 M != MEnd; ++M) {
Douglas Gregor1b605f72009-11-19 01:08:35 +00002950 if ((*M)->isInstanceMethod() == WantInstanceMethods) {
2951 // Check whether the selector identifiers we've been given are a
2952 // subset of the identifiers for this particular method.
Douglas Gregorc8537c52009-11-19 07:41:15 +00002953 if (!isAcceptableObjCMethod(*M, WantKind, SelIdents, NumSelIdents))
Douglas Gregor1b605f72009-11-19 01:08:35 +00002954 continue;
Douglas Gregorc8537c52009-11-19 07:41:15 +00002955
Douglas Gregor1b605f72009-11-19 01:08:35 +00002956 Result R = Result(*M, 0);
2957 R.StartParameter = NumSelIdents;
Douglas Gregorc8537c52009-11-19 07:41:15 +00002958 R.AllParametersAreInformative = (WantKind != MK_Any);
Douglas Gregor1b605f72009-11-19 01:08:35 +00002959 Results.MaybeAddResult(R, CurContext);
2960 }
Douglas Gregorbab2b3c2009-11-17 23:22:23 +00002961 }
2962
2963 ObjCInterfaceDecl *IFace = dyn_cast<ObjCInterfaceDecl>(Container);
2964 if (!IFace)
2965 return;
2966
2967 // Add methods in protocols.
2968 const ObjCList<ObjCProtocolDecl> &Protocols= IFace->getReferencedProtocols();
2969 for (ObjCList<ObjCProtocolDecl>::iterator I = Protocols.begin(),
2970 E = Protocols.end();
2971 I != E; ++I)
Douglas Gregorc8537c52009-11-19 07:41:15 +00002972 AddObjCMethods(*I, WantInstanceMethods, WantKind, SelIdents, NumSelIdents,
Douglas Gregor1b605f72009-11-19 01:08:35 +00002973 CurContext, Results);
Douglas Gregorbab2b3c2009-11-17 23:22:23 +00002974
2975 // Add methods in categories.
2976 for (ObjCCategoryDecl *CatDecl = IFace->getCategoryList(); CatDecl;
2977 CatDecl = CatDecl->getNextClassCategory()) {
Douglas Gregorc8537c52009-11-19 07:41:15 +00002978 AddObjCMethods(CatDecl, WantInstanceMethods, WantKind, SelIdents,
2979 NumSelIdents, CurContext, Results);
Douglas Gregorbab2b3c2009-11-17 23:22:23 +00002980
2981 // Add a categories protocol methods.
2982 const ObjCList<ObjCProtocolDecl> &Protocols
2983 = CatDecl->getReferencedProtocols();
2984 for (ObjCList<ObjCProtocolDecl>::iterator I = Protocols.begin(),
2985 E = Protocols.end();
2986 I != E; ++I)
Douglas Gregorc8537c52009-11-19 07:41:15 +00002987 AddObjCMethods(*I, WantInstanceMethods, WantKind, SelIdents,
2988 NumSelIdents, CurContext, Results);
Douglas Gregorbab2b3c2009-11-17 23:22:23 +00002989
2990 // Add methods in category implementations.
2991 if (ObjCCategoryImplDecl *Impl = CatDecl->getImplementation())
Douglas Gregorc8537c52009-11-19 07:41:15 +00002992 AddObjCMethods(Impl, WantInstanceMethods, WantKind, SelIdents,
2993 NumSelIdents, CurContext, Results);
Douglas Gregorbab2b3c2009-11-17 23:22:23 +00002994 }
2995
2996 // Add methods in superclass.
2997 if (IFace->getSuperClass())
Douglas Gregorc8537c52009-11-19 07:41:15 +00002998 AddObjCMethods(IFace->getSuperClass(), WantInstanceMethods, WantKind,
2999 SelIdents, NumSelIdents, CurContext, Results);
Douglas Gregorbab2b3c2009-11-17 23:22:23 +00003000
3001 // Add methods in our implementation, if any.
3002 if (ObjCImplementationDecl *Impl = IFace->getImplementation())
Douglas Gregorc8537c52009-11-19 07:41:15 +00003003 AddObjCMethods(Impl, WantInstanceMethods, WantKind, SelIdents,
3004 NumSelIdents, CurContext, Results);
3005}
3006
3007
3008void Sema::CodeCompleteObjCPropertyGetter(Scope *S, DeclPtrTy ClassDecl,
3009 DeclPtrTy *Methods,
3010 unsigned NumMethods) {
3011 typedef CodeCompleteConsumer::Result Result;
3012
3013 // Try to find the interface where getters might live.
3014 ObjCInterfaceDecl *Class
3015 = dyn_cast_or_null<ObjCInterfaceDecl>(ClassDecl.getAs<Decl>());
3016 if (!Class) {
3017 if (ObjCCategoryDecl *Category
3018 = dyn_cast_or_null<ObjCCategoryDecl>(ClassDecl.getAs<Decl>()))
3019 Class = Category->getClassInterface();
3020
3021 if (!Class)
3022 return;
3023 }
3024
3025 // Find all of the potential getters.
3026 ResultBuilder Results(*this);
3027 Results.EnterNewScope();
3028
3029 // FIXME: We need to do this because Objective-C methods don't get
3030 // pushed into DeclContexts early enough. Argh!
3031 for (unsigned I = 0; I != NumMethods; ++I) {
3032 if (ObjCMethodDecl *Method
3033 = dyn_cast_or_null<ObjCMethodDecl>(Methods[I].getAs<Decl>()))
3034 if (Method->isInstanceMethod() &&
3035 isAcceptableObjCMethod(Method, MK_ZeroArgSelector, 0, 0)) {
3036 Result R = Result(Method, 0);
3037 R.AllParametersAreInformative = true;
3038 Results.MaybeAddResult(R, CurContext);
3039 }
3040 }
3041
3042 AddObjCMethods(Class, true, MK_ZeroArgSelector, 0, 0, CurContext, Results);
3043 Results.ExitScope();
3044 HandleCodeCompleteResults(this, CodeCompleter,Results.data(),Results.size());
3045}
3046
3047void Sema::CodeCompleteObjCPropertySetter(Scope *S, DeclPtrTy ObjCImplDecl,
3048 DeclPtrTy *Methods,
3049 unsigned NumMethods) {
3050 typedef CodeCompleteConsumer::Result Result;
3051
3052 // Try to find the interface where setters might live.
3053 ObjCInterfaceDecl *Class
3054 = dyn_cast_or_null<ObjCInterfaceDecl>(ObjCImplDecl.getAs<Decl>());
3055 if (!Class) {
3056 if (ObjCCategoryDecl *Category
3057 = dyn_cast_or_null<ObjCCategoryDecl>(ObjCImplDecl.getAs<Decl>()))
3058 Class = Category->getClassInterface();
3059
3060 if (!Class)
3061 return;
3062 }
3063
3064 // Find all of the potential getters.
3065 ResultBuilder Results(*this);
3066 Results.EnterNewScope();
3067
3068 // FIXME: We need to do this because Objective-C methods don't get
3069 // pushed into DeclContexts early enough. Argh!
3070 for (unsigned I = 0; I != NumMethods; ++I) {
3071 if (ObjCMethodDecl *Method
3072 = dyn_cast_or_null<ObjCMethodDecl>(Methods[I].getAs<Decl>()))
3073 if (Method->isInstanceMethod() &&
3074 isAcceptableObjCMethod(Method, MK_OneArgSelector, 0, 0)) {
3075 Result R = Result(Method, 0);
3076 R.AllParametersAreInformative = true;
3077 Results.MaybeAddResult(R, CurContext);
3078 }
3079 }
3080
3081 AddObjCMethods(Class, true, MK_OneArgSelector, 0, 0, CurContext, Results);
3082
3083 Results.ExitScope();
3084 HandleCodeCompleteResults(this, CodeCompleter,Results.data(),Results.size());
Douglas Gregorbab2b3c2009-11-17 23:22:23 +00003085}
3086
Douglas Gregor9d2ddb22010-04-06 19:22:33 +00003087/// \brief When we have an expression with type "id", we may assume
3088/// that it has some more-specific class type based on knowledge of
3089/// common uses of Objective-C. This routine returns that class type,
3090/// or NULL if no better result could be determined.
3091static ObjCInterfaceDecl *GetAssumedMessageSendExprType(Expr *E) {
3092 ObjCMessageExpr *Msg = dyn_cast<ObjCMessageExpr>(E);
3093 if (!Msg)
3094 return 0;
3095
3096 Selector Sel = Msg->getSelector();
3097 if (Sel.isNull())
3098 return 0;
3099
3100 IdentifierInfo *Id = Sel.getIdentifierInfoForSlot(0);
3101 if (!Id)
3102 return 0;
3103
3104 ObjCMethodDecl *Method = Msg->getMethodDecl();
3105 if (!Method)
3106 return 0;
3107
3108 // Determine the class that we're sending the message to.
Douglas Gregor9a129192010-04-21 00:45:42 +00003109 ObjCInterfaceDecl *IFace = 0;
3110 switch (Msg->getReceiverKind()) {
3111 case ObjCMessageExpr::Class:
John McCall8b07ec22010-05-15 11:32:37 +00003112 if (const ObjCObjectType *ObjType
3113 = Msg->getClassReceiver()->getAs<ObjCObjectType>())
3114 IFace = ObjType->getInterface();
Douglas Gregor9a129192010-04-21 00:45:42 +00003115 break;
3116
3117 case ObjCMessageExpr::Instance: {
3118 QualType T = Msg->getInstanceReceiver()->getType();
3119 if (const ObjCObjectPointerType *Ptr = T->getAs<ObjCObjectPointerType>())
3120 IFace = Ptr->getInterfaceDecl();
3121 break;
3122 }
3123
3124 case ObjCMessageExpr::SuperInstance:
3125 case ObjCMessageExpr::SuperClass:
3126 break;
Douglas Gregor9d2ddb22010-04-06 19:22:33 +00003127 }
3128
3129 if (!IFace)
3130 return 0;
3131
3132 ObjCInterfaceDecl *Super = IFace->getSuperClass();
3133 if (Method->isInstanceMethod())
3134 return llvm::StringSwitch<ObjCInterfaceDecl *>(Id->getName())
3135 .Case("retain", IFace)
3136 .Case("autorelease", IFace)
3137 .Case("copy", IFace)
3138 .Case("copyWithZone", IFace)
3139 .Case("mutableCopy", IFace)
3140 .Case("mutableCopyWithZone", IFace)
3141 .Case("awakeFromCoder", IFace)
3142 .Case("replacementObjectFromCoder", IFace)
3143 .Case("class", IFace)
3144 .Case("classForCoder", IFace)
3145 .Case("superclass", Super)
3146 .Default(0);
3147
3148 return llvm::StringSwitch<ObjCInterfaceDecl *>(Id->getName())
3149 .Case("new", IFace)
3150 .Case("alloc", IFace)
3151 .Case("allocWithZone", IFace)
3152 .Case("class", IFace)
3153 .Case("superclass", Super)
3154 .Default(0);
3155}
3156
Douglas Gregora817a192010-05-27 23:06:34 +00003157void Sema::CodeCompleteObjCMessageReceiver(Scope *S) {
3158 typedef CodeCompleteConsumer::Result Result;
3159 ResultBuilder Results(*this);
3160
3161 // Find anything that looks like it could be a message receiver.
3162 Results.setFilter(&ResultBuilder::IsObjCMessageReceiver);
3163 CodeCompletionDeclConsumer Consumer(Results, CurContext);
3164 Results.EnterNewScope();
3165 LookupVisibleDecls(S, LookupOrdinaryName, Consumer);
3166
3167 // If we are in an Objective-C method inside a class that has a superclass,
3168 // add "super" as an option.
3169 if (ObjCMethodDecl *Method = getCurMethodDecl())
3170 if (ObjCInterfaceDecl *Iface = Method->getClassInterface())
3171 if (Iface->getSuperClass())
3172 Results.AddResult(Result("super"));
3173
3174 Results.ExitScope();
3175
3176 if (CodeCompleter->includeMacros())
3177 AddMacroResults(PP, Results);
3178 HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
3179
3180}
3181
Douglas Gregor0c78ad92010-04-21 19:57:20 +00003182void Sema::CodeCompleteObjCSuperMessage(Scope *S, SourceLocation SuperLoc,
3183 IdentifierInfo **SelIdents,
3184 unsigned NumSelIdents) {
3185 ObjCInterfaceDecl *CDecl = 0;
3186 if (ObjCMethodDecl *CurMethod = getCurMethodDecl()) {
3187 // Figure out which interface we're in.
3188 CDecl = CurMethod->getClassInterface();
3189 if (!CDecl)
3190 return;
3191
3192 // Find the superclass of this class.
3193 CDecl = CDecl->getSuperClass();
3194 if (!CDecl)
3195 return;
3196
3197 if (CurMethod->isInstanceMethod()) {
3198 // We are inside an instance method, which means that the message
3199 // send [super ...] is actually calling an instance method on the
3200 // current object. Build the super expression and handle this like
3201 // an instance method.
3202 QualType SuperTy = Context.getObjCInterfaceType(CDecl);
3203 SuperTy = Context.getObjCObjectPointerType(SuperTy);
3204 OwningExprResult Super
3205 = Owned(new (Context) ObjCSuperExpr(SuperLoc, SuperTy));
3206 return CodeCompleteObjCInstanceMessage(S, (Expr *)Super.get(),
3207 SelIdents, NumSelIdents);
3208 }
3209
3210 // Fall through to send to the superclass in CDecl.
3211 } else {
3212 // "super" may be the name of a type or variable. Figure out which
3213 // it is.
3214 IdentifierInfo *Super = &Context.Idents.get("super");
3215 NamedDecl *ND = LookupSingleName(S, Super, SuperLoc,
3216 LookupOrdinaryName);
3217 if ((CDecl = dyn_cast_or_null<ObjCInterfaceDecl>(ND))) {
3218 // "super" names an interface. Use it.
3219 } else if (TypeDecl *TD = dyn_cast_or_null<TypeDecl>(ND)) {
John McCall8b07ec22010-05-15 11:32:37 +00003220 if (const ObjCObjectType *Iface
3221 = Context.getTypeDeclType(TD)->getAs<ObjCObjectType>())
3222 CDecl = Iface->getInterface();
Douglas Gregor0c78ad92010-04-21 19:57:20 +00003223 } else if (ND && isa<UnresolvedUsingTypenameDecl>(ND)) {
3224 // "super" names an unresolved type; we can't be more specific.
3225 } else {
3226 // Assume that "super" names some kind of value and parse that way.
3227 CXXScopeSpec SS;
3228 UnqualifiedId id;
3229 id.setIdentifier(Super, SuperLoc);
3230 OwningExprResult SuperExpr = ActOnIdExpression(S, SS, id, false, false);
3231 return CodeCompleteObjCInstanceMessage(S, (Expr *)SuperExpr.get(),
3232 SelIdents, NumSelIdents);
3233 }
3234
3235 // Fall through
3236 }
3237
3238 TypeTy *Receiver = 0;
3239 if (CDecl)
3240 Receiver = Context.getObjCInterfaceType(CDecl).getAsOpaquePtr();
3241 return CodeCompleteObjCClassMessage(S, Receiver, SelIdents,
3242 NumSelIdents);
3243}
3244
3245void Sema::CodeCompleteObjCClassMessage(Scope *S, TypeTy *Receiver,
Douglas Gregor1b605f72009-11-19 01:08:35 +00003246 IdentifierInfo **SelIdents,
3247 unsigned NumSelIdents) {
Steve Naroffeae65032009-11-07 02:08:14 +00003248 typedef CodeCompleteConsumer::Result Result;
Douglas Gregor8ce33212009-11-17 17:59:40 +00003249 ObjCInterfaceDecl *CDecl = 0;
3250
Douglas Gregor8ce33212009-11-17 17:59:40 +00003251 // If the given name refers to an interface type, retrieve the
3252 // corresponding declaration.
Douglas Gregor0c78ad92010-04-21 19:57:20 +00003253 if (Receiver) {
3254 QualType T = GetTypeFromParser(Receiver, 0);
3255 if (!T.isNull())
John McCall8b07ec22010-05-15 11:32:37 +00003256 if (const ObjCObjectType *Interface = T->getAs<ObjCObjectType>())
3257 CDecl = Interface->getInterface();
Douglas Gregor8ce33212009-11-17 17:59:40 +00003258 }
3259
Douglas Gregorbab2b3c2009-11-17 23:22:23 +00003260 // Add all of the factory methods in this Objective-C class, its protocols,
3261 // superclasses, categories, implementation, etc.
Steve Naroffeae65032009-11-07 02:08:14 +00003262 ResultBuilder Results(*this);
3263 Results.EnterNewScope();
Douglas Gregor6285f752010-04-06 16:40:00 +00003264
3265 if (CDecl)
3266 AddObjCMethods(CDecl, false, MK_Any, SelIdents, NumSelIdents, CurContext,
3267 Results);
Douglas Gregor0c78ad92010-04-21 19:57:20 +00003268 else {
Douglas Gregor6285f752010-04-06 16:40:00 +00003269 // We're messaging "id" as a type; provide all class/factory methods.
3270
Douglas Gregord720daf2010-04-06 17:30:22 +00003271 // If we have an external source, load the entire class method
3272 // pool from the PCH file.
3273 if (ExternalSource) {
3274 for (uint32_t I = 0, N = ExternalSource->GetNumKnownSelectors(); I != N;
3275 ++I) {
3276 Selector Sel = ExternalSource->GetSelector(I);
3277 if (Sel.isNull() || FactoryMethodPool.count(Sel) ||
3278 InstanceMethodPool.count(Sel))
3279 continue;
3280
3281 ReadMethodPool(Sel, /*isInstance=*/false);
3282 }
3283 }
3284
Douglas Gregor6285f752010-04-06 16:40:00 +00003285 for (llvm::DenseMap<Selector, ObjCMethodList>::iterator
3286 M = FactoryMethodPool.begin(),
3287 MEnd = FactoryMethodPool.end();
3288 M != MEnd;
3289 ++M) {
Douglas Gregord720daf2010-04-06 17:30:22 +00003290 for (ObjCMethodList *MethList = &M->second; MethList && MethList->Method;
Douglas Gregor6285f752010-04-06 16:40:00 +00003291 MethList = MethList->Next) {
3292 if (!isAcceptableObjCMethod(MethList->Method, MK_Any, SelIdents,
3293 NumSelIdents))
3294 continue;
3295
3296 Result R(MethList->Method, 0);
3297 R.StartParameter = NumSelIdents;
3298 R.AllParametersAreInformative = false;
3299 Results.MaybeAddResult(R, CurContext);
3300 }
3301 }
3302 }
3303
Steve Naroffeae65032009-11-07 02:08:14 +00003304 Results.ExitScope();
Daniel Dunbar242ea9a2009-11-13 08:58:20 +00003305 HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
Steve Naroffeae65032009-11-07 02:08:14 +00003306}
3307
Douglas Gregor1b605f72009-11-19 01:08:35 +00003308void Sema::CodeCompleteObjCInstanceMessage(Scope *S, ExprTy *Receiver,
3309 IdentifierInfo **SelIdents,
3310 unsigned NumSelIdents) {
Steve Naroffeae65032009-11-07 02:08:14 +00003311 typedef CodeCompleteConsumer::Result Result;
Steve Naroffeae65032009-11-07 02:08:14 +00003312
3313 Expr *RecExpr = static_cast<Expr *>(Receiver);
Steve Naroffeae65032009-11-07 02:08:14 +00003314
Douglas Gregorbab2b3c2009-11-17 23:22:23 +00003315 // If necessary, apply function/array conversion to the receiver.
3316 // C99 6.7.5.3p[7,8].
Douglas Gregorb92a1562010-02-03 00:27:59 +00003317 DefaultFunctionArrayLvalueConversion(RecExpr);
Douglas Gregorbab2b3c2009-11-17 23:22:23 +00003318 QualType ReceiverType = RecExpr->getType();
Steve Naroffeae65032009-11-07 02:08:14 +00003319
Douglas Gregorbab2b3c2009-11-17 23:22:23 +00003320 // Build the set of methods we can see.
3321 ResultBuilder Results(*this);
3322 Results.EnterNewScope();
Douglas Gregor9d2ddb22010-04-06 19:22:33 +00003323
3324 // If we're messaging an expression with type "id" or "Class", check
3325 // whether we know something special about the receiver that allows
3326 // us to assume a more-specific receiver type.
3327 if (ReceiverType->isObjCIdType() || ReceiverType->isObjCClassType())
3328 if (ObjCInterfaceDecl *IFace = GetAssumedMessageSendExprType(RecExpr))
3329 ReceiverType = Context.getObjCObjectPointerType(
3330 Context.getObjCInterfaceType(IFace));
Douglas Gregorbab2b3c2009-11-17 23:22:23 +00003331
Douglas Gregora3329fa2009-11-18 00:06:18 +00003332 // Handle messages to Class. This really isn't a message to an instance
3333 // method, so we treat it the same way we would treat a message send to a
3334 // class method.
3335 if (ReceiverType->isObjCClassType() ||
3336 ReceiverType->isObjCQualifiedClassType()) {
3337 if (ObjCMethodDecl *CurMethod = getCurMethodDecl()) {
3338 if (ObjCInterfaceDecl *ClassDecl = CurMethod->getClassInterface())
Douglas Gregorc8537c52009-11-19 07:41:15 +00003339 AddObjCMethods(ClassDecl, false, MK_Any, SelIdents, NumSelIdents,
3340 CurContext, Results);
Douglas Gregora3329fa2009-11-18 00:06:18 +00003341 }
3342 }
3343 // Handle messages to a qualified ID ("id<foo>").
3344 else if (const ObjCObjectPointerType *QualID
3345 = ReceiverType->getAsObjCQualifiedIdType()) {
3346 // Search protocols for instance methods.
3347 for (ObjCObjectPointerType::qual_iterator I = QualID->qual_begin(),
3348 E = QualID->qual_end();
3349 I != E; ++I)
Douglas Gregorc8537c52009-11-19 07:41:15 +00003350 AddObjCMethods(*I, true, MK_Any, SelIdents, NumSelIdents, CurContext,
3351 Results);
Douglas Gregora3329fa2009-11-18 00:06:18 +00003352 }
3353 // Handle messages to a pointer to interface type.
3354 else if (const ObjCObjectPointerType *IFacePtr
3355 = ReceiverType->getAsObjCInterfacePointerType()) {
3356 // Search the class, its superclasses, etc., for instance methods.
Douglas Gregorc8537c52009-11-19 07:41:15 +00003357 AddObjCMethods(IFacePtr->getInterfaceDecl(), true, MK_Any, SelIdents,
3358 NumSelIdents, CurContext, Results);
Douglas Gregora3329fa2009-11-18 00:06:18 +00003359
3360 // Search protocols for instance methods.
3361 for (ObjCObjectPointerType::qual_iterator I = IFacePtr->qual_begin(),
3362 E = IFacePtr->qual_end();
3363 I != E; ++I)
Douglas Gregorc8537c52009-11-19 07:41:15 +00003364 AddObjCMethods(*I, true, MK_Any, SelIdents, NumSelIdents, CurContext,
3365 Results);
Douglas Gregora3329fa2009-11-18 00:06:18 +00003366 }
Douglas Gregor6285f752010-04-06 16:40:00 +00003367 // Handle messages to "id".
3368 else if (ReceiverType->isObjCIdType()) {
Douglas Gregord720daf2010-04-06 17:30:22 +00003369 // We're messaging "id", so provide all instance methods we know
3370 // about as code-completion results.
3371
3372 // If we have an external source, load the entire class method
3373 // pool from the PCH file.
3374 if (ExternalSource) {
3375 for (uint32_t I = 0, N = ExternalSource->GetNumKnownSelectors(); I != N;
3376 ++I) {
3377 Selector Sel = ExternalSource->GetSelector(I);
3378 if (Sel.isNull() || InstanceMethodPool.count(Sel) ||
3379 FactoryMethodPool.count(Sel))
3380 continue;
3381
3382 ReadMethodPool(Sel, /*isInstance=*/true);
3383 }
3384 }
3385
Douglas Gregor6285f752010-04-06 16:40:00 +00003386 for (llvm::DenseMap<Selector, ObjCMethodList>::iterator
3387 M = InstanceMethodPool.begin(),
3388 MEnd = InstanceMethodPool.end();
3389 M != MEnd;
3390 ++M) {
Douglas Gregord720daf2010-04-06 17:30:22 +00003391 for (ObjCMethodList *MethList = &M->second; MethList && MethList->Method;
Douglas Gregor6285f752010-04-06 16:40:00 +00003392 MethList = MethList->Next) {
3393 if (!isAcceptableObjCMethod(MethList->Method, MK_Any, SelIdents,
3394 NumSelIdents))
3395 continue;
3396
3397 Result R(MethList->Method, 0);
3398 R.StartParameter = NumSelIdents;
3399 R.AllParametersAreInformative = false;
3400 Results.MaybeAddResult(R, CurContext);
3401 }
3402 }
3403 }
3404
Steve Naroffeae65032009-11-07 02:08:14 +00003405 Results.ExitScope();
Daniel Dunbar242ea9a2009-11-13 08:58:20 +00003406 HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
Steve Naroffeae65032009-11-07 02:08:14 +00003407}
Douglas Gregorbaf69612009-11-18 04:19:12 +00003408
3409/// \brief Add all of the protocol declarations that we find in the given
3410/// (translation unit) context.
3411static void AddProtocolResults(DeclContext *Ctx, DeclContext *CurContext,
Douglas Gregor5b4671c2009-11-18 04:49:41 +00003412 bool OnlyForwardDeclarations,
Douglas Gregorbaf69612009-11-18 04:19:12 +00003413 ResultBuilder &Results) {
3414 typedef CodeCompleteConsumer::Result Result;
3415
3416 for (DeclContext::decl_iterator D = Ctx->decls_begin(),
3417 DEnd = Ctx->decls_end();
3418 D != DEnd; ++D) {
3419 // Record any protocols we find.
3420 if (ObjCProtocolDecl *Proto = dyn_cast<ObjCProtocolDecl>(*D))
Douglas Gregor5b4671c2009-11-18 04:49:41 +00003421 if (!OnlyForwardDeclarations || Proto->isForwardDecl())
Douglas Gregorfc59ce12010-01-14 16:14:35 +00003422 Results.AddResult(Result(Proto, 0), CurContext, 0, false);
Douglas Gregorbaf69612009-11-18 04:19:12 +00003423
3424 // Record any forward-declared protocols we find.
3425 if (ObjCForwardProtocolDecl *Forward
3426 = dyn_cast<ObjCForwardProtocolDecl>(*D)) {
3427 for (ObjCForwardProtocolDecl::protocol_iterator
3428 P = Forward->protocol_begin(),
3429 PEnd = Forward->protocol_end();
3430 P != PEnd; ++P)
Douglas Gregor5b4671c2009-11-18 04:49:41 +00003431 if (!OnlyForwardDeclarations || (*P)->isForwardDecl())
Douglas Gregorfc59ce12010-01-14 16:14:35 +00003432 Results.AddResult(Result(*P, 0), CurContext, 0, false);
Douglas Gregorbaf69612009-11-18 04:19:12 +00003433 }
3434 }
3435}
3436
3437void Sema::CodeCompleteObjCProtocolReferences(IdentifierLocPair *Protocols,
3438 unsigned NumProtocols) {
3439 ResultBuilder Results(*this);
3440 Results.EnterNewScope();
3441
3442 // Tell the result set to ignore all of the protocols we have
3443 // already seen.
3444 for (unsigned I = 0; I != NumProtocols; ++I)
Douglas Gregorb2ccf012010-04-15 22:33:43 +00003445 if (ObjCProtocolDecl *Protocol = LookupProtocol(Protocols[I].first,
3446 Protocols[I].second))
Douglas Gregorbaf69612009-11-18 04:19:12 +00003447 Results.Ignore(Protocol);
3448
3449 // Add all protocols.
Douglas Gregor5b4671c2009-11-18 04:49:41 +00003450 AddProtocolResults(Context.getTranslationUnitDecl(), CurContext, false,
3451 Results);
3452
3453 Results.ExitScope();
3454 HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
3455}
3456
3457void Sema::CodeCompleteObjCProtocolDecl(Scope *) {
3458 ResultBuilder Results(*this);
3459 Results.EnterNewScope();
3460
3461 // Add all protocols.
3462 AddProtocolResults(Context.getTranslationUnitDecl(), CurContext, true,
3463 Results);
Douglas Gregorbaf69612009-11-18 04:19:12 +00003464
3465 Results.ExitScope();
3466 HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
3467}
Douglas Gregor49c22a72009-11-18 16:26:39 +00003468
3469/// \brief Add all of the Objective-C interface declarations that we find in
3470/// the given (translation unit) context.
3471static void AddInterfaceResults(DeclContext *Ctx, DeclContext *CurContext,
3472 bool OnlyForwardDeclarations,
3473 bool OnlyUnimplemented,
3474 ResultBuilder &Results) {
3475 typedef CodeCompleteConsumer::Result Result;
3476
3477 for (DeclContext::decl_iterator D = Ctx->decls_begin(),
3478 DEnd = Ctx->decls_end();
3479 D != DEnd; ++D) {
3480 // Record any interfaces we find.
3481 if (ObjCInterfaceDecl *Class = dyn_cast<ObjCInterfaceDecl>(*D))
3482 if ((!OnlyForwardDeclarations || Class->isForwardDecl()) &&
3483 (!OnlyUnimplemented || !Class->getImplementation()))
Douglas Gregorfc59ce12010-01-14 16:14:35 +00003484 Results.AddResult(Result(Class, 0), CurContext, 0, false);
Douglas Gregor49c22a72009-11-18 16:26:39 +00003485
3486 // Record any forward-declared interfaces we find.
3487 if (ObjCClassDecl *Forward = dyn_cast<ObjCClassDecl>(*D)) {
3488 for (ObjCClassDecl::iterator C = Forward->begin(), CEnd = Forward->end();
3489 C != CEnd; ++C)
3490 if ((!OnlyForwardDeclarations || C->getInterface()->isForwardDecl()) &&
3491 (!OnlyUnimplemented || !C->getInterface()->getImplementation()))
Douglas Gregorfc59ce12010-01-14 16:14:35 +00003492 Results.AddResult(Result(C->getInterface(), 0), CurContext,
3493 0, false);
Douglas Gregor49c22a72009-11-18 16:26:39 +00003494 }
3495 }
3496}
3497
3498void Sema::CodeCompleteObjCInterfaceDecl(Scope *S) {
3499 ResultBuilder Results(*this);
3500 Results.EnterNewScope();
3501
3502 // Add all classes.
3503 AddInterfaceResults(Context.getTranslationUnitDecl(), CurContext, true,
3504 false, Results);
3505
3506 Results.ExitScope();
3507 HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
3508}
3509
Douglas Gregorb2ccf012010-04-15 22:33:43 +00003510void Sema::CodeCompleteObjCSuperclass(Scope *S, IdentifierInfo *ClassName,
3511 SourceLocation ClassNameLoc) {
Douglas Gregor49c22a72009-11-18 16:26:39 +00003512 ResultBuilder Results(*this);
3513 Results.EnterNewScope();
3514
3515 // Make sure that we ignore the class we're currently defining.
3516 NamedDecl *CurClass
Douglas Gregorb2ccf012010-04-15 22:33:43 +00003517 = LookupSingleName(TUScope, ClassName, ClassNameLoc, LookupOrdinaryName);
Douglas Gregor5d34fd32009-11-18 19:08:43 +00003518 if (CurClass && isa<ObjCInterfaceDecl>(CurClass))
Douglas Gregor49c22a72009-11-18 16:26:39 +00003519 Results.Ignore(CurClass);
3520
3521 // Add all classes.
3522 AddInterfaceResults(Context.getTranslationUnitDecl(), CurContext, false,
3523 false, Results);
3524
3525 Results.ExitScope();
3526 HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
3527}
3528
3529void Sema::CodeCompleteObjCImplementationDecl(Scope *S) {
3530 ResultBuilder Results(*this);
3531 Results.EnterNewScope();
3532
3533 // Add all unimplemented classes.
3534 AddInterfaceResults(Context.getTranslationUnitDecl(), CurContext, false,
3535 true, Results);
3536
3537 Results.ExitScope();
3538 HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
3539}
Douglas Gregor5d34fd32009-11-18 19:08:43 +00003540
3541void Sema::CodeCompleteObjCInterfaceCategory(Scope *S,
Douglas Gregorb2ccf012010-04-15 22:33:43 +00003542 IdentifierInfo *ClassName,
3543 SourceLocation ClassNameLoc) {
Douglas Gregor5d34fd32009-11-18 19:08:43 +00003544 typedef CodeCompleteConsumer::Result Result;
3545
3546 ResultBuilder Results(*this);
3547
3548 // Ignore any categories we find that have already been implemented by this
3549 // interface.
3550 llvm::SmallPtrSet<IdentifierInfo *, 16> CategoryNames;
3551 NamedDecl *CurClass
Douglas Gregorb2ccf012010-04-15 22:33:43 +00003552 = LookupSingleName(TUScope, ClassName, ClassNameLoc, LookupOrdinaryName);
Douglas Gregor5d34fd32009-11-18 19:08:43 +00003553 if (ObjCInterfaceDecl *Class = dyn_cast_or_null<ObjCInterfaceDecl>(CurClass))
3554 for (ObjCCategoryDecl *Category = Class->getCategoryList(); Category;
3555 Category = Category->getNextClassCategory())
3556 CategoryNames.insert(Category->getIdentifier());
3557
3558 // Add all of the categories we know about.
3559 Results.EnterNewScope();
3560 TranslationUnitDecl *TU = Context.getTranslationUnitDecl();
3561 for (DeclContext::decl_iterator D = TU->decls_begin(),
3562 DEnd = TU->decls_end();
3563 D != DEnd; ++D)
3564 if (ObjCCategoryDecl *Category = dyn_cast<ObjCCategoryDecl>(*D))
3565 if (CategoryNames.insert(Category->getIdentifier()))
Douglas Gregorfc59ce12010-01-14 16:14:35 +00003566 Results.AddResult(Result(Category, 0), CurContext, 0, false);
Douglas Gregor5d34fd32009-11-18 19:08:43 +00003567 Results.ExitScope();
3568
3569 HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
3570}
3571
3572void Sema::CodeCompleteObjCImplementationCategory(Scope *S,
Douglas Gregorb2ccf012010-04-15 22:33:43 +00003573 IdentifierInfo *ClassName,
3574 SourceLocation ClassNameLoc) {
Douglas Gregor5d34fd32009-11-18 19:08:43 +00003575 typedef CodeCompleteConsumer::Result Result;
3576
3577 // Find the corresponding interface. If we couldn't find the interface, the
3578 // program itself is ill-formed. However, we'll try to be helpful still by
3579 // providing the list of all of the categories we know about.
3580 NamedDecl *CurClass
Douglas Gregorb2ccf012010-04-15 22:33:43 +00003581 = LookupSingleName(TUScope, ClassName, ClassNameLoc, LookupOrdinaryName);
Douglas Gregor5d34fd32009-11-18 19:08:43 +00003582 ObjCInterfaceDecl *Class = dyn_cast_or_null<ObjCInterfaceDecl>(CurClass);
3583 if (!Class)
Douglas Gregorb2ccf012010-04-15 22:33:43 +00003584 return CodeCompleteObjCInterfaceCategory(S, ClassName, ClassNameLoc);
Douglas Gregor5d34fd32009-11-18 19:08:43 +00003585
3586 ResultBuilder Results(*this);
3587
3588 // Add all of the categories that have have corresponding interface
3589 // declarations in this class and any of its superclasses, except for
3590 // already-implemented categories in the class itself.
3591 llvm::SmallPtrSet<IdentifierInfo *, 16> CategoryNames;
3592 Results.EnterNewScope();
3593 bool IgnoreImplemented = true;
3594 while (Class) {
3595 for (ObjCCategoryDecl *Category = Class->getCategoryList(); Category;
3596 Category = Category->getNextClassCategory())
3597 if ((!IgnoreImplemented || !Category->getImplementation()) &&
3598 CategoryNames.insert(Category->getIdentifier()))
Douglas Gregorfc59ce12010-01-14 16:14:35 +00003599 Results.AddResult(Result(Category, 0), CurContext, 0, false);
Douglas Gregor5d34fd32009-11-18 19:08:43 +00003600
3601 Class = Class->getSuperClass();
3602 IgnoreImplemented = false;
3603 }
3604 Results.ExitScope();
3605
3606 HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
3607}
Douglas Gregor5d649882009-11-18 22:32:06 +00003608
Douglas Gregor52e78bd2009-11-18 22:56:13 +00003609void Sema::CodeCompleteObjCPropertyDefinition(Scope *S, DeclPtrTy ObjCImpDecl) {
Douglas Gregor5d649882009-11-18 22:32:06 +00003610 typedef CodeCompleteConsumer::Result Result;
3611 ResultBuilder Results(*this);
3612
3613 // Figure out where this @synthesize lives.
3614 ObjCContainerDecl *Container
3615 = dyn_cast_or_null<ObjCContainerDecl>(ObjCImpDecl.getAs<Decl>());
3616 if (!Container ||
3617 (!isa<ObjCImplementationDecl>(Container) &&
3618 !isa<ObjCCategoryImplDecl>(Container)))
3619 return;
3620
3621 // Ignore any properties that have already been implemented.
3622 for (DeclContext::decl_iterator D = Container->decls_begin(),
3623 DEnd = Container->decls_end();
3624 D != DEnd; ++D)
3625 if (ObjCPropertyImplDecl *PropertyImpl = dyn_cast<ObjCPropertyImplDecl>(*D))
3626 Results.Ignore(PropertyImpl->getPropertyDecl());
3627
3628 // Add any properties that we find.
3629 Results.EnterNewScope();
3630 if (ObjCImplementationDecl *ClassImpl
3631 = dyn_cast<ObjCImplementationDecl>(Container))
3632 AddObjCProperties(ClassImpl->getClassInterface(), false, CurContext,
3633 Results);
3634 else
3635 AddObjCProperties(cast<ObjCCategoryImplDecl>(Container)->getCategoryDecl(),
3636 false, CurContext, Results);
3637 Results.ExitScope();
3638
3639 HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
3640}
3641
3642void Sema::CodeCompleteObjCPropertySynthesizeIvar(Scope *S,
3643 IdentifierInfo *PropertyName,
3644 DeclPtrTy ObjCImpDecl) {
3645 typedef CodeCompleteConsumer::Result Result;
3646 ResultBuilder Results(*this);
3647
3648 // Figure out where this @synthesize lives.
3649 ObjCContainerDecl *Container
3650 = dyn_cast_or_null<ObjCContainerDecl>(ObjCImpDecl.getAs<Decl>());
3651 if (!Container ||
3652 (!isa<ObjCImplementationDecl>(Container) &&
3653 !isa<ObjCCategoryImplDecl>(Container)))
3654 return;
3655
3656 // Figure out which interface we're looking into.
3657 ObjCInterfaceDecl *Class = 0;
3658 if (ObjCImplementationDecl *ClassImpl
3659 = dyn_cast<ObjCImplementationDecl>(Container))
3660 Class = ClassImpl->getClassInterface();
3661 else
3662 Class = cast<ObjCCategoryImplDecl>(Container)->getCategoryDecl()
3663 ->getClassInterface();
3664
3665 // Add all of the instance variables in this class and its superclasses.
3666 Results.EnterNewScope();
3667 for(; Class; Class = Class->getSuperClass()) {
3668 // FIXME: We could screen the type of each ivar for compatibility with
3669 // the property, but is that being too paternal?
3670 for (ObjCInterfaceDecl::ivar_iterator IVar = Class->ivar_begin(),
3671 IVarEnd = Class->ivar_end();
3672 IVar != IVarEnd; ++IVar)
Douglas Gregorfc59ce12010-01-14 16:14:35 +00003673 Results.AddResult(Result(*IVar, 0), CurContext, 0, false);
Douglas Gregor5d649882009-11-18 22:32:06 +00003674 }
3675 Results.ExitScope();
3676
3677 HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
3678}
Douglas Gregor636a61e2010-04-07 00:21:17 +00003679
3680typedef llvm::DenseMap<Selector, ObjCMethodDecl *> KnownMethodsMap;
3681
3682/// \brief Find all of the methods that reside in the given container
3683/// (and its superclasses, protocols, etc.) that meet the given
3684/// criteria. Insert those methods into the map of known methods,
3685/// indexed by selector so they can be easily found.
3686static void FindImplementableMethods(ASTContext &Context,
3687 ObjCContainerDecl *Container,
3688 bool WantInstanceMethods,
3689 QualType ReturnType,
3690 bool IsInImplementation,
3691 KnownMethodsMap &KnownMethods) {
3692 if (ObjCInterfaceDecl *IFace = dyn_cast<ObjCInterfaceDecl>(Container)) {
3693 // Recurse into protocols.
3694 const ObjCList<ObjCProtocolDecl> &Protocols
3695 = IFace->getReferencedProtocols();
3696 for (ObjCList<ObjCProtocolDecl>::iterator I = Protocols.begin(),
3697 E = Protocols.end();
3698 I != E; ++I)
3699 FindImplementableMethods(Context, *I, WantInstanceMethods, ReturnType,
3700 IsInImplementation, KnownMethods);
3701
3702 // If we're not in the implementation of a class, also visit the
3703 // superclass.
3704 if (!IsInImplementation && IFace->getSuperClass())
3705 FindImplementableMethods(Context, IFace->getSuperClass(),
3706 WantInstanceMethods, ReturnType,
3707 IsInImplementation, KnownMethods);
3708
3709 // Add methods from any class extensions (but not from categories;
3710 // those should go into category implementations).
3711 for (ObjCCategoryDecl *Cat = IFace->getCategoryList(); Cat;
3712 Cat = Cat->getNextClassCategory()) {
3713 if (!Cat->IsClassExtension())
3714 continue;
3715
3716 FindImplementableMethods(Context, Cat, WantInstanceMethods, ReturnType,
3717 IsInImplementation, KnownMethods);
3718 }
3719 }
3720
3721 if (ObjCCategoryDecl *Category = dyn_cast<ObjCCategoryDecl>(Container)) {
3722 // Recurse into protocols.
3723 const ObjCList<ObjCProtocolDecl> &Protocols
3724 = Category->getReferencedProtocols();
3725 for (ObjCList<ObjCProtocolDecl>::iterator I = Protocols.begin(),
3726 E = Protocols.end();
3727 I != E; ++I)
3728 FindImplementableMethods(Context, *I, WantInstanceMethods, ReturnType,
3729 IsInImplementation, KnownMethods);
3730 }
3731
3732 if (ObjCProtocolDecl *Protocol = dyn_cast<ObjCProtocolDecl>(Container)) {
3733 // Recurse into protocols.
3734 const ObjCList<ObjCProtocolDecl> &Protocols
3735 = Protocol->getReferencedProtocols();
3736 for (ObjCList<ObjCProtocolDecl>::iterator I = Protocols.begin(),
3737 E = Protocols.end();
3738 I != E; ++I)
3739 FindImplementableMethods(Context, *I, WantInstanceMethods, ReturnType,
3740 IsInImplementation, KnownMethods);
3741 }
3742
3743 // Add methods in this container. This operation occurs last because
3744 // we want the methods from this container to override any methods
3745 // we've previously seen with the same selector.
3746 for (ObjCContainerDecl::method_iterator M = Container->meth_begin(),
3747 MEnd = Container->meth_end();
3748 M != MEnd; ++M) {
3749 if ((*M)->isInstanceMethod() == WantInstanceMethods) {
3750 if (!ReturnType.isNull() &&
3751 !Context.hasSameUnqualifiedType(ReturnType, (*M)->getResultType()))
3752 continue;
3753
3754 KnownMethods[(*M)->getSelector()] = *M;
3755 }
3756 }
3757}
3758
3759void Sema::CodeCompleteObjCMethodDecl(Scope *S,
3760 bool IsInstanceMethod,
3761 TypeTy *ReturnTy,
3762 DeclPtrTy IDecl) {
3763 // Determine the return type of the method we're declaring, if
3764 // provided.
3765 QualType ReturnType = GetTypeFromParser(ReturnTy);
3766
3767 // Determine where we should start searching for methods, and where we
3768 ObjCContainerDecl *SearchDecl = 0, *CurrentDecl = 0;
3769 bool IsInImplementation = false;
3770 if (Decl *D = IDecl.getAs<Decl>()) {
3771 if (ObjCImplementationDecl *Impl = dyn_cast<ObjCImplementationDecl>(D)) {
3772 SearchDecl = Impl->getClassInterface();
3773 CurrentDecl = Impl;
3774 IsInImplementation = true;
3775 } else if (ObjCCategoryImplDecl *CatImpl
3776 = dyn_cast<ObjCCategoryImplDecl>(D)) {
3777 SearchDecl = CatImpl->getCategoryDecl();
3778 CurrentDecl = CatImpl;
3779 IsInImplementation = true;
3780 } else {
3781 SearchDecl = dyn_cast<ObjCContainerDecl>(D);
3782 CurrentDecl = SearchDecl;
3783 }
3784 }
3785
3786 if (!SearchDecl && S) {
3787 if (DeclContext *DC = static_cast<DeclContext *>(S->getEntity())) {
3788 SearchDecl = dyn_cast<ObjCContainerDecl>(DC);
3789 CurrentDecl = SearchDecl;
3790 }
3791 }
3792
3793 if (!SearchDecl || !CurrentDecl) {
3794 HandleCodeCompleteResults(this, CodeCompleter, 0, 0);
3795 return;
3796 }
3797
3798 // Find all of the methods that we could declare/implement here.
3799 KnownMethodsMap KnownMethods;
3800 FindImplementableMethods(Context, SearchDecl, IsInstanceMethod,
3801 ReturnType, IsInImplementation, KnownMethods);
3802
3803 // Erase any methods that have already been declared or
3804 // implemented here.
3805 for (ObjCContainerDecl::method_iterator M = CurrentDecl->meth_begin(),
3806 MEnd = CurrentDecl->meth_end();
3807 M != MEnd; ++M) {
3808 if ((*M)->isInstanceMethod() != IsInstanceMethod)
3809 continue;
3810
3811 KnownMethodsMap::iterator Pos = KnownMethods.find((*M)->getSelector());
3812 if (Pos != KnownMethods.end())
3813 KnownMethods.erase(Pos);
3814 }
3815
3816 // Add declarations or definitions for each of the known methods.
3817 typedef CodeCompleteConsumer::Result Result;
3818 ResultBuilder Results(*this);
3819 Results.EnterNewScope();
3820 PrintingPolicy Policy(Context.PrintingPolicy);
3821 Policy.AnonymousTagLocations = false;
3822 for (KnownMethodsMap::iterator M = KnownMethods.begin(),
3823 MEnd = KnownMethods.end();
3824 M != MEnd; ++M) {
3825 ObjCMethodDecl *Method = M->second;
3826 CodeCompletionString *Pattern = new CodeCompletionString;
3827
3828 // If the result type was not already provided, add it to the
3829 // pattern as (type).
3830 if (ReturnType.isNull()) {
3831 std::string TypeStr;
3832 Method->getResultType().getAsStringInternal(TypeStr, Policy);
3833 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
3834 Pattern->AddTextChunk(TypeStr);
3835 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
3836 }
3837
3838 Selector Sel = Method->getSelector();
3839
3840 // Add the first part of the selector to the pattern.
3841 Pattern->AddTypedTextChunk(Sel.getIdentifierInfoForSlot(0)->getName());
3842
3843 // Add parameters to the pattern.
3844 unsigned I = 0;
3845 for (ObjCMethodDecl::param_iterator P = Method->param_begin(),
3846 PEnd = Method->param_end();
3847 P != PEnd; (void)++P, ++I) {
3848 // Add the part of the selector name.
3849 if (I == 0)
3850 Pattern->AddChunk(CodeCompletionString::CK_Colon);
3851 else if (I < Sel.getNumArgs()) {
3852 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
3853 Pattern->AddTextChunk(Sel.getIdentifierInfoForSlot(1)->getName());
3854 Pattern->AddChunk(CodeCompletionString::CK_Colon);
3855 } else
3856 break;
3857
3858 // Add the parameter type.
3859 std::string TypeStr;
3860 (*P)->getOriginalType().getAsStringInternal(TypeStr, Policy);
3861 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
3862 Pattern->AddTextChunk(TypeStr);
3863 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
3864
3865 if (IdentifierInfo *Id = (*P)->getIdentifier())
3866 Pattern->AddTextChunk(Id->getName());
3867 }
3868
3869 if (Method->isVariadic()) {
3870 if (Method->param_size() > 0)
3871 Pattern->AddChunk(CodeCompletionString::CK_Comma);
3872 Pattern->AddTextChunk("...");
3873 }
3874
3875 if (IsInImplementation) {
3876 // We will be defining the method here, so add a compound statement.
3877 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
3878 Pattern->AddChunk(CodeCompletionString::CK_LeftBrace);
3879 Pattern->AddChunk(CodeCompletionString::CK_VerticalSpace);
3880 if (!Method->getResultType()->isVoidType()) {
3881 // If the result type is not void, add a return clause.
3882 Pattern->AddTextChunk("return");
3883 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
3884 Pattern->AddPlaceholderChunk("expression");
3885 Pattern->AddChunk(CodeCompletionString::CK_SemiColon);
3886 } else
3887 Pattern->AddPlaceholderChunk("statements");
3888
3889 Pattern->AddChunk(CodeCompletionString::CK_VerticalSpace);
3890 Pattern->AddChunk(CodeCompletionString::CK_RightBrace);
3891 }
3892
3893 Results.AddResult(Result(Pattern));
3894 }
3895
3896 Results.ExitScope();
3897
3898 HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
3899}