blob: 3e482532ca21d2929a60a682fe8271af8ae48913 [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 Gregor7aa6b222010-05-30 01:49:25 +0000122 /// \brief If set, the type that we would prefer our resulting value
123 /// declarations to have.
124 ///
125 /// Closely matching the preferred type gives a boost to a result's
126 /// priority.
127 CanQualType PreferredType;
128
Douglas Gregor3545ff42009-09-21 16:56:56 +0000129 /// \brief A list of shadow maps, which is used to model name hiding at
130 /// different levels of, e.g., the inheritance hierarchy.
131 std::list<ShadowMap> ShadowMaps;
132
133 public:
134 explicit ResultBuilder(Sema &SemaRef, LookupFilter Filter = 0)
Douglas Gregor6ae4c522010-01-14 03:21:49 +0000135 : SemaRef(SemaRef), Filter(Filter), AllowNestedNameSpecifiers(false) { }
Douglas Gregor3545ff42009-09-21 16:56:56 +0000136
Douglas Gregorf64acca2010-05-25 21:41:55 +0000137 /// \brief Whether we should include code patterns in the completion
138 /// results.
139 bool includeCodePatterns() const {
140 return SemaRef.CodeCompleter &&
141 SemaRef.CodeCompleter->includeCodePatterns();
142 }
143
Douglas Gregor3545ff42009-09-21 16:56:56 +0000144 /// \brief Set the filter used for code-completion results.
145 void setFilter(LookupFilter Filter) {
146 this->Filter = Filter;
147 }
148
149 typedef std::vector<Result>::iterator iterator;
150 iterator begin() { return Results.begin(); }
151 iterator end() { return Results.end(); }
152
153 Result *data() { return Results.empty()? 0 : &Results.front(); }
154 unsigned size() const { return Results.size(); }
155 bool empty() const { return Results.empty(); }
156
Douglas Gregor7aa6b222010-05-30 01:49:25 +0000157 /// \brief Specify the preferred type.
158 void setPreferredType(QualType T) {
159 PreferredType = SemaRef.Context.getCanonicalType(T);
160 }
161
Douglas Gregor6ae4c522010-01-14 03:21:49 +0000162 /// \brief Specify whether nested-name-specifiers are allowed.
163 void allowNestedNameSpecifiers(bool Allow = true) {
164 AllowNestedNameSpecifiers = Allow;
165 }
166
Douglas Gregor7c208612010-01-14 00:20:49 +0000167 /// \brief Determine whether the given declaration is at all interesting
168 /// as a code-completion result.
Douglas Gregor6ae4c522010-01-14 03:21:49 +0000169 ///
170 /// \param ND the declaration that we are inspecting.
171 ///
172 /// \param AsNestedNameSpecifier will be set true if this declaration is
173 /// only interesting when it is a nested-name-specifier.
174 bool isInterestingDecl(NamedDecl *ND, bool &AsNestedNameSpecifier) const;
Douglas Gregore0717ab2010-01-14 00:41:07 +0000175
176 /// \brief Check whether the result is hidden by the Hiding declaration.
177 ///
178 /// \returns true if the result is hidden and cannot be found, false if
179 /// the hidden result could still be found. When false, \p R may be
180 /// modified to describe how the result can be found (e.g., via extra
181 /// qualification).
182 bool CheckHiddenResult(Result &R, DeclContext *CurContext,
183 NamedDecl *Hiding);
184
Douglas Gregor3545ff42009-09-21 16:56:56 +0000185 /// \brief Add a new result to this result set (if it isn't already in one
186 /// of the shadow maps), or replace an existing result (for, e.g., a
187 /// redeclaration).
Douglas Gregor2af2f672009-09-21 20:12:40 +0000188 ///
Douglas Gregorc580c522010-01-14 01:09:38 +0000189 /// \param CurContext the result to add (if it is unique).
Douglas Gregor2af2f672009-09-21 20:12:40 +0000190 ///
191 /// \param R the context in which this result will be named.
192 void MaybeAddResult(Result R, DeclContext *CurContext = 0);
Douglas Gregor3545ff42009-09-21 16:56:56 +0000193
Douglas Gregorc580c522010-01-14 01:09:38 +0000194 /// \brief Add a new result to this result set, where we already know
195 /// the hiding declation (if any).
196 ///
197 /// \param R the result to add (if it is unique).
198 ///
199 /// \param CurContext the context in which this result will be named.
200 ///
201 /// \param Hiding the declaration that hides the result.
Douglas Gregor09bbc652010-01-14 15:47:35 +0000202 ///
203 /// \param InBaseClass whether the result was found in a base
204 /// class of the searched context.
205 void AddResult(Result R, DeclContext *CurContext, NamedDecl *Hiding,
206 bool InBaseClass);
Douglas Gregorc580c522010-01-14 01:09:38 +0000207
Douglas Gregor78a21012010-01-14 16:01:26 +0000208 /// \brief Add a new non-declaration result to this result set.
209 void AddResult(Result R);
210
Douglas Gregor3545ff42009-09-21 16:56:56 +0000211 /// \brief Enter into a new scope.
212 void EnterNewScope();
213
214 /// \brief Exit from the current scope.
215 void ExitScope();
216
Douglas Gregorbaf69612009-11-18 04:19:12 +0000217 /// \brief Ignore this declaration, if it is seen again.
218 void Ignore(Decl *D) { AllDeclsFound.insert(D->getCanonicalDecl()); }
219
Douglas Gregor3545ff42009-09-21 16:56:56 +0000220 /// \name Name lookup predicates
221 ///
222 /// These predicates can be passed to the name lookup functions to filter the
223 /// results of name lookup. All of the predicates have the same type, so that
224 ///
225 //@{
Douglas Gregor9d64c5e2009-09-21 20:51:25 +0000226 bool IsOrdinaryName(NamedDecl *ND) const;
Douglas Gregor70febae2010-05-28 00:49:12 +0000227 bool IsOrdinaryNonTypeName(NamedDecl *ND) const;
Douglas Gregor504a6ae2010-01-10 23:08:15 +0000228 bool IsOrdinaryNonValueName(NamedDecl *ND) const;
Douglas Gregor3545ff42009-09-21 16:56:56 +0000229 bool IsNestedNameSpecifier(NamedDecl *ND) const;
230 bool IsEnum(NamedDecl *ND) const;
231 bool IsClassOrStruct(NamedDecl *ND) const;
232 bool IsUnion(NamedDecl *ND) const;
233 bool IsNamespace(NamedDecl *ND) const;
234 bool IsNamespaceOrAlias(NamedDecl *ND) const;
235 bool IsType(NamedDecl *ND) const;
Douglas Gregore412a5a2009-09-23 22:26:46 +0000236 bool IsMember(NamedDecl *ND) const;
Douglas Gregor2b8162b2010-01-14 16:08:12 +0000237 bool IsObjCIvar(NamedDecl *ND) const;
Douglas Gregora817a192010-05-27 23:06:34 +0000238 bool IsObjCMessageReceiver(NamedDecl *ND) const;
Douglas Gregor3545ff42009-09-21 16:56:56 +0000239 //@}
240 };
241}
242
Douglas Gregor05e7ca32009-12-06 20:23:50 +0000243class ResultBuilder::ShadowMapEntry::iterator {
244 llvm::PointerUnion<NamedDecl*, const DeclIndexPair*> DeclOrIterator;
245 unsigned SingleDeclIndex;
246
247public:
248 typedef DeclIndexPair value_type;
249 typedef value_type reference;
250 typedef std::ptrdiff_t difference_type;
251 typedef std::input_iterator_tag iterator_category;
252
253 class pointer {
254 DeclIndexPair Value;
255
256 public:
257 pointer(const DeclIndexPair &Value) : Value(Value) { }
258
259 const DeclIndexPair *operator->() const {
260 return &Value;
261 }
262 };
263
264 iterator() : DeclOrIterator((NamedDecl *)0), SingleDeclIndex(0) { }
265
266 iterator(NamedDecl *SingleDecl, unsigned Index)
267 : DeclOrIterator(SingleDecl), SingleDeclIndex(Index) { }
268
269 iterator(const DeclIndexPair *Iterator)
270 : DeclOrIterator(Iterator), SingleDeclIndex(0) { }
271
272 iterator &operator++() {
273 if (DeclOrIterator.is<NamedDecl *>()) {
274 DeclOrIterator = (NamedDecl *)0;
275 SingleDeclIndex = 0;
276 return *this;
277 }
278
279 const DeclIndexPair *I = DeclOrIterator.get<const DeclIndexPair*>();
280 ++I;
281 DeclOrIterator = I;
282 return *this;
283 }
284
285 iterator operator++(int) {
286 iterator tmp(*this);
287 ++(*this);
288 return tmp;
289 }
290
291 reference operator*() const {
292 if (NamedDecl *ND = DeclOrIterator.dyn_cast<NamedDecl *>())
293 return reference(ND, SingleDeclIndex);
294
Douglas Gregor94bb5e82009-12-06 21:27:58 +0000295 return *DeclOrIterator.get<const DeclIndexPair*>();
Douglas Gregor05e7ca32009-12-06 20:23:50 +0000296 }
297
298 pointer operator->() const {
299 return pointer(**this);
300 }
301
302 friend bool operator==(const iterator &X, const iterator &Y) {
Douglas Gregor94bb5e82009-12-06 21:27:58 +0000303 return X.DeclOrIterator.getOpaqueValue()
304 == Y.DeclOrIterator.getOpaqueValue() &&
Douglas Gregor05e7ca32009-12-06 20:23:50 +0000305 X.SingleDeclIndex == Y.SingleDeclIndex;
306 }
307
308 friend bool operator!=(const iterator &X, const iterator &Y) {
Douglas Gregor94bb5e82009-12-06 21:27:58 +0000309 return !(X == Y);
Douglas Gregor05e7ca32009-12-06 20:23:50 +0000310 }
311};
312
Douglas Gregor05e7ca32009-12-06 20:23:50 +0000313ResultBuilder::ShadowMapEntry::iterator
314ResultBuilder::ShadowMapEntry::begin() const {
315 if (DeclOrVector.isNull())
316 return iterator();
317
318 if (NamedDecl *ND = DeclOrVector.dyn_cast<NamedDecl *>())
319 return iterator(ND, SingleDeclIndex);
320
321 return iterator(DeclOrVector.get<DeclIndexPairVector *>()->begin());
322}
323
324ResultBuilder::ShadowMapEntry::iterator
325ResultBuilder::ShadowMapEntry::end() const {
326 if (DeclOrVector.is<NamedDecl *>() || DeclOrVector.isNull())
327 return iterator();
328
329 return iterator(DeclOrVector.get<DeclIndexPairVector *>()->end());
330}
331
Douglas Gregor2af2f672009-09-21 20:12:40 +0000332/// \brief Compute the qualification required to get from the current context
333/// (\p CurContext) to the target context (\p TargetContext).
334///
335/// \param Context the AST context in which the qualification will be used.
336///
337/// \param CurContext the context where an entity is being named, which is
338/// typically based on the current scope.
339///
340/// \param TargetContext the context in which the named entity actually
341/// resides.
342///
343/// \returns a nested name specifier that refers into the target context, or
344/// NULL if no qualification is needed.
345static NestedNameSpecifier *
346getRequiredQualification(ASTContext &Context,
347 DeclContext *CurContext,
348 DeclContext *TargetContext) {
349 llvm::SmallVector<DeclContext *, 4> TargetParents;
350
351 for (DeclContext *CommonAncestor = TargetContext;
352 CommonAncestor && !CommonAncestor->Encloses(CurContext);
353 CommonAncestor = CommonAncestor->getLookupParent()) {
354 if (CommonAncestor->isTransparentContext() ||
355 CommonAncestor->isFunctionOrMethod())
356 continue;
357
358 TargetParents.push_back(CommonAncestor);
359 }
360
361 NestedNameSpecifier *Result = 0;
362 while (!TargetParents.empty()) {
363 DeclContext *Parent = TargetParents.back();
364 TargetParents.pop_back();
365
366 if (NamespaceDecl *Namespace = dyn_cast<NamespaceDecl>(Parent))
367 Result = NestedNameSpecifier::Create(Context, Result, Namespace);
368 else if (TagDecl *TD = dyn_cast<TagDecl>(Parent))
369 Result = NestedNameSpecifier::Create(Context, Result,
370 false,
371 Context.getTypeDeclType(TD).getTypePtr());
Douglas Gregor9eb77012009-11-07 00:00:49 +0000372 }
Douglas Gregor2af2f672009-09-21 20:12:40 +0000373 return Result;
374}
375
Douglas Gregor6ae4c522010-01-14 03:21:49 +0000376bool ResultBuilder::isInterestingDecl(NamedDecl *ND,
377 bool &AsNestedNameSpecifier) const {
378 AsNestedNameSpecifier = false;
379
Douglas Gregor7c208612010-01-14 00:20:49 +0000380 ND = ND->getUnderlyingDecl();
381 unsigned IDNS = ND->getIdentifierNamespace();
Douglas Gregor58acf322009-10-09 22:16:47 +0000382
383 // Skip unnamed entities.
Douglas Gregor7c208612010-01-14 00:20:49 +0000384 if (!ND->getDeclName())
385 return false;
Douglas Gregor3545ff42009-09-21 16:56:56 +0000386
387 // Friend declarations and declarations introduced due to friends are never
388 // added as results.
John McCallbbbbe4e2010-03-11 07:50:04 +0000389 if (IDNS & (Decl::IDNS_OrdinaryFriend | Decl::IDNS_TagFriend))
Douglas Gregor7c208612010-01-14 00:20:49 +0000390 return false;
391
Douglas Gregor99fe2ad2009-12-11 17:31:05 +0000392 // Class template (partial) specializations are never added as results.
Douglas Gregor7c208612010-01-14 00:20:49 +0000393 if (isa<ClassTemplateSpecializationDecl>(ND) ||
394 isa<ClassTemplatePartialSpecializationDecl>(ND))
395 return false;
Douglas Gregor3545ff42009-09-21 16:56:56 +0000396
Douglas Gregor99fe2ad2009-12-11 17:31:05 +0000397 // Using declarations themselves are never added as results.
Douglas Gregor7c208612010-01-14 00:20:49 +0000398 if (isa<UsingDecl>(ND))
399 return false;
400
401 // Some declarations have reserved names that we don't want to ever show.
402 if (const IdentifierInfo *Id = ND->getIdentifier()) {
Douglas Gregor3545ff42009-09-21 16:56:56 +0000403 // __va_list_tag is a freak of nature. Find it and skip it.
404 if (Id->isStr("__va_list_tag") || Id->isStr("__builtin_va_list"))
Douglas Gregor7c208612010-01-14 00:20:49 +0000405 return false;
Douglas Gregor3545ff42009-09-21 16:56:56 +0000406
Douglas Gregor58acf322009-10-09 22:16:47 +0000407 // Filter out names reserved for the implementation (C99 7.1.3,
408 // C++ [lib.global.names]). Users don't need to see those.
Daniel Dunbar2c422dc92009-10-18 20:26:12 +0000409 //
410 // FIXME: Add predicate for this.
Douglas Gregor58acf322009-10-09 22:16:47 +0000411 if (Id->getLength() >= 2) {
Daniel Dunbar2c422dc92009-10-18 20:26:12 +0000412 const char *Name = Id->getNameStart();
Douglas Gregor58acf322009-10-09 22:16:47 +0000413 if (Name[0] == '_' &&
414 (Name[1] == '_' || (Name[1] >= 'A' && Name[1] <= 'Z')))
Douglas Gregor7c208612010-01-14 00:20:49 +0000415 return false;
Douglas Gregor58acf322009-10-09 22:16:47 +0000416 }
Douglas Gregor3545ff42009-09-21 16:56:56 +0000417 }
Douglas Gregor7c208612010-01-14 00:20:49 +0000418
Douglas Gregor3545ff42009-09-21 16:56:56 +0000419 // C++ constructors are never found by name lookup.
Douglas Gregor7c208612010-01-14 00:20:49 +0000420 if (isa<CXXConstructorDecl>(ND))
421 return false;
Douglas Gregor3545ff42009-09-21 16:56:56 +0000422
423 // Filter out any unwanted results.
Douglas Gregor6ae4c522010-01-14 03:21:49 +0000424 if (Filter && !(this->*Filter)(ND)) {
425 // Check whether it is interesting as a nested-name-specifier.
426 if (AllowNestedNameSpecifiers && SemaRef.getLangOptions().CPlusPlus &&
427 IsNestedNameSpecifier(ND) &&
428 (Filter != &ResultBuilder::IsMember ||
429 (isa<CXXRecordDecl>(ND) &&
430 cast<CXXRecordDecl>(ND)->isInjectedClassName()))) {
431 AsNestedNameSpecifier = true;
432 return true;
433 }
434
Douglas Gregor7c208612010-01-14 00:20:49 +0000435 return false;
Douglas Gregor6ae4c522010-01-14 03:21:49 +0000436 }
John McCalle87beb22010-04-23 18:46:30 +0000437
438 if (Filter == &ResultBuilder::IsNestedNameSpecifier)
439 AsNestedNameSpecifier = true;
Douglas Gregor3545ff42009-09-21 16:56:56 +0000440
Douglas Gregor7c208612010-01-14 00:20:49 +0000441 // ... then it must be interesting!
442 return true;
443}
444
Douglas Gregore0717ab2010-01-14 00:41:07 +0000445bool ResultBuilder::CheckHiddenResult(Result &R, DeclContext *CurContext,
446 NamedDecl *Hiding) {
447 // In C, there is no way to refer to a hidden name.
448 // FIXME: This isn't true; we can find a tag name hidden by an ordinary
449 // name if we introduce the tag type.
450 if (!SemaRef.getLangOptions().CPlusPlus)
451 return true;
452
453 DeclContext *HiddenCtx = R.Declaration->getDeclContext()->getLookupContext();
454
455 // There is no way to qualify a name declared in a function or method.
456 if (HiddenCtx->isFunctionOrMethod())
457 return true;
458
459 if (HiddenCtx == Hiding->getDeclContext()->getLookupContext())
460 return true;
461
462 // We can refer to the result with the appropriate qualification. Do it.
463 R.Hidden = true;
464 R.QualifierIsInformative = false;
465
466 if (!R.Qualifier)
467 R.Qualifier = getRequiredQualification(SemaRef.Context,
468 CurContext,
469 R.Declaration->getDeclContext());
470 return false;
471}
472
Douglas Gregor7c208612010-01-14 00:20:49 +0000473void ResultBuilder::MaybeAddResult(Result R, DeclContext *CurContext) {
474 assert(!ShadowMaps.empty() && "Must enter into a results scope");
475
476 if (R.Kind != Result::RK_Declaration) {
477 // For non-declaration results, just add the result.
478 Results.push_back(R);
479 return;
480 }
481
482 // Look through using declarations.
483 if (UsingShadowDecl *Using = dyn_cast<UsingShadowDecl>(R.Declaration)) {
484 MaybeAddResult(Result(Using->getTargetDecl(), R.Qualifier), CurContext);
485 return;
486 }
487
488 Decl *CanonDecl = R.Declaration->getCanonicalDecl();
489 unsigned IDNS = CanonDecl->getIdentifierNamespace();
490
Douglas Gregor6ae4c522010-01-14 03:21:49 +0000491 bool AsNestedNameSpecifier = false;
492 if (!isInterestingDecl(R.Declaration, AsNestedNameSpecifier))
Douglas Gregor7c208612010-01-14 00:20:49 +0000493 return;
494
Douglas Gregor3545ff42009-09-21 16:56:56 +0000495 ShadowMap &SMap = ShadowMaps.back();
Douglas Gregor05e7ca32009-12-06 20:23:50 +0000496 ShadowMapEntry::iterator I, IEnd;
497 ShadowMap::iterator NamePos = SMap.find(R.Declaration->getDeclName());
498 if (NamePos != SMap.end()) {
499 I = NamePos->second.begin();
500 IEnd = NamePos->second.end();
501 }
502
503 for (; I != IEnd; ++I) {
504 NamedDecl *ND = I->first;
505 unsigned Index = I->second;
Douglas Gregor3545ff42009-09-21 16:56:56 +0000506 if (ND->getCanonicalDecl() == CanonDecl) {
507 // This is a redeclaration. Always pick the newer declaration.
Douglas Gregor3545ff42009-09-21 16:56:56 +0000508 Results[Index].Declaration = R.Declaration;
509
Douglas Gregor3545ff42009-09-21 16:56:56 +0000510 // We're done.
511 return;
512 }
513 }
514
515 // This is a new declaration in this scope. However, check whether this
516 // declaration name is hidden by a similarly-named declaration in an outer
517 // scope.
518 std::list<ShadowMap>::iterator SM, SMEnd = ShadowMaps.end();
519 --SMEnd;
520 for (SM = ShadowMaps.begin(); SM != SMEnd; ++SM) {
Douglas Gregor05e7ca32009-12-06 20:23:50 +0000521 ShadowMapEntry::iterator I, IEnd;
522 ShadowMap::iterator NamePos = SM->find(R.Declaration->getDeclName());
523 if (NamePos != SM->end()) {
524 I = NamePos->second.begin();
525 IEnd = NamePos->second.end();
526 }
527 for (; I != IEnd; ++I) {
Douglas Gregor3545ff42009-09-21 16:56:56 +0000528 // A tag declaration does not hide a non-tag declaration.
John McCalle87beb22010-04-23 18:46:30 +0000529 if (I->first->hasTagIdentifierNamespace() &&
Douglas Gregor3545ff42009-09-21 16:56:56 +0000530 (IDNS & (Decl::IDNS_Member | Decl::IDNS_Ordinary |
531 Decl::IDNS_ObjCProtocol)))
532 continue;
533
534 // Protocols are in distinct namespaces from everything else.
Douglas Gregor05e7ca32009-12-06 20:23:50 +0000535 if (((I->first->getIdentifierNamespace() & Decl::IDNS_ObjCProtocol)
Douglas Gregor3545ff42009-09-21 16:56:56 +0000536 || (IDNS & Decl::IDNS_ObjCProtocol)) &&
Douglas Gregor05e7ca32009-12-06 20:23:50 +0000537 I->first->getIdentifierNamespace() != IDNS)
Douglas Gregor3545ff42009-09-21 16:56:56 +0000538 continue;
539
540 // The newly-added result is hidden by an entry in the shadow map.
Douglas Gregore0717ab2010-01-14 00:41:07 +0000541 if (CheckHiddenResult(R, CurContext, I->first))
Douglas Gregor3545ff42009-09-21 16:56:56 +0000542 return;
Douglas Gregor3545ff42009-09-21 16:56:56 +0000543
544 break;
545 }
546 }
547
548 // Make sure that any given declaration only shows up in the result set once.
549 if (!AllDeclsFound.insert(CanonDecl))
550 return;
551
Douglas Gregore412a5a2009-09-23 22:26:46 +0000552 // If the filter is for nested-name-specifiers, then this result starts a
553 // nested-name-specifier.
Douglas Gregora2db7932010-05-26 22:00:08 +0000554 if (AsNestedNameSpecifier) {
Douglas Gregore412a5a2009-09-23 22:26:46 +0000555 R.StartsNestedNameSpecifier = true;
Douglas Gregora2db7932010-05-26 22:00:08 +0000556 R.Priority = CCP_NestedNameSpecifier;
557 }
Douglas Gregore412a5a2009-09-23 22:26:46 +0000558
Douglas Gregor5bf52692009-09-22 23:15:58 +0000559 // If this result is supposed to have an informative qualifier, add one.
Douglas Gregore412a5a2009-09-23 22:26:46 +0000560 if (R.QualifierIsInformative && !R.Qualifier &&
561 !R.StartsNestedNameSpecifier) {
Douglas Gregor5bf52692009-09-22 23:15:58 +0000562 DeclContext *Ctx = R.Declaration->getDeclContext();
563 if (NamespaceDecl *Namespace = dyn_cast<NamespaceDecl>(Ctx))
564 R.Qualifier = NestedNameSpecifier::Create(SemaRef.Context, 0, Namespace);
565 else if (TagDecl *Tag = dyn_cast<TagDecl>(Ctx))
566 R.Qualifier = NestedNameSpecifier::Create(SemaRef.Context, 0, false,
567 SemaRef.Context.getTypeDeclType(Tag).getTypePtr());
568 else
569 R.QualifierIsInformative = false;
570 }
Douglas Gregore412a5a2009-09-23 22:26:46 +0000571
Douglas Gregor3545ff42009-09-21 16:56:56 +0000572 // Insert this result into the set of results and into the current shadow
573 // map.
Douglas Gregor05e7ca32009-12-06 20:23:50 +0000574 SMap[R.Declaration->getDeclName()].Add(R.Declaration, Results.size());
Douglas Gregor3545ff42009-09-21 16:56:56 +0000575 Results.push_back(R);
576}
577
Douglas Gregor7aa6b222010-05-30 01:49:25 +0000578enum SimplifiedTypeClass {
579 STC_Arithmetic,
580 STC_Array,
581 STC_Block,
582 STC_Function,
583 STC_ObjectiveC,
584 STC_Other,
585 STC_Pointer,
586 STC_Record,
587 STC_Void
588};
589
590/// \brief A simplified classification of types used to determine whether two
591/// types are "similar enough" when adjusting priorities.
592static SimplifiedTypeClass getSimplifiedTypeClass(CanQualType T) {
593 switch (T->getTypeClass()) {
594 case Type::Builtin:
595 switch (cast<BuiltinType>(T)->getKind()) {
596 case BuiltinType::Void:
597 return STC_Void;
598
599 case BuiltinType::NullPtr:
600 return STC_Pointer;
601
602 case BuiltinType::Overload:
603 case BuiltinType::Dependent:
604 case BuiltinType::UndeducedAuto:
605 return STC_Other;
606
607 case BuiltinType::ObjCId:
608 case BuiltinType::ObjCClass:
609 case BuiltinType::ObjCSel:
610 return STC_ObjectiveC;
611
612 default:
613 return STC_Arithmetic;
614 }
615 return STC_Other;
616
617 case Type::Complex:
618 return STC_Arithmetic;
619
620 case Type::Pointer:
621 return STC_Pointer;
622
623 case Type::BlockPointer:
624 return STC_Block;
625
626 case Type::LValueReference:
627 case Type::RValueReference:
628 return getSimplifiedTypeClass(T->getAs<ReferenceType>()->getPointeeType());
629
630 case Type::ConstantArray:
631 case Type::IncompleteArray:
632 case Type::VariableArray:
633 case Type::DependentSizedArray:
634 return STC_Array;
635
636 case Type::DependentSizedExtVector:
637 case Type::Vector:
638 case Type::ExtVector:
639 return STC_Arithmetic;
640
641 case Type::FunctionProto:
642 case Type::FunctionNoProto:
643 return STC_Function;
644
645 case Type::Record:
646 return STC_Record;
647
648 case Type::Enum:
649 return STC_Arithmetic;
650
651 case Type::ObjCObject:
652 case Type::ObjCInterface:
653 case Type::ObjCObjectPointer:
654 return STC_ObjectiveC;
655
656 default:
657 return STC_Other;
658 }
659}
660
661/// \brief Get the type that a given expression will have if this declaration
662/// is used as an expression in its "typical" code-completion form.
663static QualType getDeclUsageType(ASTContext &C, NamedDecl *ND) {
664 ND = cast<NamedDecl>(ND->getUnderlyingDecl());
665
666 if (TypeDecl *Type = dyn_cast<TypeDecl>(ND))
667 return C.getTypeDeclType(Type);
668 if (ObjCInterfaceDecl *Iface = dyn_cast<ObjCInterfaceDecl>(ND))
669 return C.getObjCInterfaceType(Iface);
670
671 QualType T;
672 if (FunctionDecl *Function = dyn_cast<FunctionDecl>(ND))
673 T = Function->getResultType();
674 else if (ObjCMethodDecl *Method = dyn_cast<ObjCMethodDecl>(ND))
675 T = Method->getResultType();
676 else if (FunctionTemplateDecl *FunTmpl = dyn_cast<FunctionTemplateDecl>(ND))
677 T = FunTmpl->getTemplatedDecl()->getResultType();
678 else if (EnumConstantDecl *Enumerator = dyn_cast<EnumConstantDecl>(ND))
679 T = C.getTypeDeclType(cast<EnumDecl>(Enumerator->getDeclContext()));
680 else if (ObjCPropertyDecl *Property = dyn_cast<ObjCPropertyDecl>(ND))
681 T = Property->getType();
682 else if (ValueDecl *Value = dyn_cast<ValueDecl>(ND))
683 T = Value->getType();
684 else
685 return QualType();
686
687 return T.getNonReferenceType();
688}
689
Douglas Gregorc580c522010-01-14 01:09:38 +0000690void ResultBuilder::AddResult(Result R, DeclContext *CurContext,
Douglas Gregor09bbc652010-01-14 15:47:35 +0000691 NamedDecl *Hiding, bool InBaseClass = false) {
Douglas Gregor78a21012010-01-14 16:01:26 +0000692 if (R.Kind != Result::RK_Declaration) {
693 // For non-declaration results, just add the result.
694 Results.push_back(R);
695 return;
696 }
697
Douglas Gregorc580c522010-01-14 01:09:38 +0000698 // Look through using declarations.
699 if (UsingShadowDecl *Using = dyn_cast<UsingShadowDecl>(R.Declaration)) {
700 AddResult(Result(Using->getTargetDecl(), R.Qualifier), CurContext, Hiding);
701 return;
702 }
703
Douglas Gregor6ae4c522010-01-14 03:21:49 +0000704 bool AsNestedNameSpecifier = false;
705 if (!isInterestingDecl(R.Declaration, AsNestedNameSpecifier))
Douglas Gregorc580c522010-01-14 01:09:38 +0000706 return;
707
708 if (Hiding && CheckHiddenResult(R, CurContext, Hiding))
709 return;
710
711 // Make sure that any given declaration only shows up in the result set once.
712 if (!AllDeclsFound.insert(R.Declaration->getCanonicalDecl()))
713 return;
714
715 // If the filter is for nested-name-specifiers, then this result starts a
716 // nested-name-specifier.
Douglas Gregora2db7932010-05-26 22:00:08 +0000717 if (AsNestedNameSpecifier) {
Douglas Gregorc580c522010-01-14 01:09:38 +0000718 R.StartsNestedNameSpecifier = true;
Douglas Gregora2db7932010-05-26 22:00:08 +0000719 R.Priority = CCP_NestedNameSpecifier;
720 }
Douglas Gregor09bbc652010-01-14 15:47:35 +0000721 else if (Filter == &ResultBuilder::IsMember && !R.Qualifier && InBaseClass &&
722 isa<CXXRecordDecl>(R.Declaration->getDeclContext()
723 ->getLookupContext()))
724 R.QualifierIsInformative = true;
725
Douglas Gregorc580c522010-01-14 01:09:38 +0000726 // If this result is supposed to have an informative qualifier, add one.
727 if (R.QualifierIsInformative && !R.Qualifier &&
728 !R.StartsNestedNameSpecifier) {
729 DeclContext *Ctx = R.Declaration->getDeclContext();
730 if (NamespaceDecl *Namespace = dyn_cast<NamespaceDecl>(Ctx))
731 R.Qualifier = NestedNameSpecifier::Create(SemaRef.Context, 0, Namespace);
732 else if (TagDecl *Tag = dyn_cast<TagDecl>(Ctx))
733 R.Qualifier = NestedNameSpecifier::Create(SemaRef.Context, 0, false,
Douglas Gregor6ae4c522010-01-14 03:21:49 +0000734 SemaRef.Context.getTypeDeclType(Tag).getTypePtr());
Douglas Gregorc580c522010-01-14 01:09:38 +0000735 else
736 R.QualifierIsInformative = false;
737 }
738
Douglas Gregora2db7932010-05-26 22:00:08 +0000739 // Adjust the priority if this result comes from a base class.
740 if (InBaseClass)
741 R.Priority += CCD_InBaseClass;
742
Douglas Gregor7aa6b222010-05-30 01:49:25 +0000743 if (!PreferredType.isNull()) {
744 if (ValueDecl *Value = dyn_cast<ValueDecl>(R.Declaration)) {
745 CanQualType T = SemaRef.Context.getCanonicalType(
746 getDeclUsageType(SemaRef.Context, Value));
747 // Check for exactly-matching types (modulo qualifiers).
748 if (SemaRef.Context.hasSameUnqualifiedType(PreferredType, T))
749 R.Priority /= CCF_ExactTypeMatch;
750 // Check for nearly-matching types, based on classification of each.
751 else if ((getSimplifiedTypeClass(PreferredType)
752 == getSimplifiedTypeClass(T)) &&
753 !(PreferredType->isEnumeralType() && T->isEnumeralType()))
754 R.Priority /= CCF_SimilarTypeMatch;
755 }
756 }
757
Douglas Gregorc580c522010-01-14 01:09:38 +0000758 // Insert this result into the set of results.
759 Results.push_back(R);
760}
761
Douglas Gregor78a21012010-01-14 16:01:26 +0000762void ResultBuilder::AddResult(Result R) {
763 assert(R.Kind != Result::RK_Declaration &&
764 "Declaration results need more context");
765 Results.push_back(R);
766}
767
Douglas Gregor3545ff42009-09-21 16:56:56 +0000768/// \brief Enter into a new scope.
769void ResultBuilder::EnterNewScope() {
770 ShadowMaps.push_back(ShadowMap());
771}
772
773/// \brief Exit from the current scope.
774void ResultBuilder::ExitScope() {
Douglas Gregor05e7ca32009-12-06 20:23:50 +0000775 for (ShadowMap::iterator E = ShadowMaps.back().begin(),
776 EEnd = ShadowMaps.back().end();
777 E != EEnd;
778 ++E)
779 E->second.Destroy();
780
Douglas Gregor3545ff42009-09-21 16:56:56 +0000781 ShadowMaps.pop_back();
782}
783
Douglas Gregor9d64c5e2009-09-21 20:51:25 +0000784/// \brief Determines whether this given declaration will be found by
785/// ordinary name lookup.
786bool ResultBuilder::IsOrdinaryName(NamedDecl *ND) const {
Douglas Gregor70febae2010-05-28 00:49:12 +0000787 ND = cast<NamedDecl>(ND->getUnderlyingDecl());
788
Douglas Gregor9d64c5e2009-09-21 20:51:25 +0000789 unsigned IDNS = Decl::IDNS_Ordinary;
790 if (SemaRef.getLangOptions().CPlusPlus)
Douglas Gregor9858ed52010-06-15 20:26:51 +0000791 IDNS |= Decl::IDNS_Tag | Decl::IDNS_Namespace | Decl::IDNS_Member;
Douglas Gregorc580c522010-01-14 01:09:38 +0000792 else if (SemaRef.getLangOptions().ObjC1 && isa<ObjCIvarDecl>(ND))
793 return true;
794
Douglas Gregor9d64c5e2009-09-21 20:51:25 +0000795 return ND->getIdentifierNamespace() & IDNS;
796}
797
Douglas Gregor504a6ae2010-01-10 23:08:15 +0000798/// \brief Determines whether this given declaration will be found by
Douglas Gregor70febae2010-05-28 00:49:12 +0000799/// ordinary name lookup but is not a type name.
800bool ResultBuilder::IsOrdinaryNonTypeName(NamedDecl *ND) const {
801 ND = cast<NamedDecl>(ND->getUnderlyingDecl());
802 if (isa<TypeDecl>(ND) || isa<ObjCInterfaceDecl>(ND))
803 return false;
804
805 unsigned IDNS = Decl::IDNS_Ordinary;
806 if (SemaRef.getLangOptions().CPlusPlus)
Douglas Gregor9858ed52010-06-15 20:26:51 +0000807 IDNS |= Decl::IDNS_Tag | Decl::IDNS_Namespace | Decl::IDNS_Member;
Douglas Gregor70febae2010-05-28 00:49:12 +0000808 else if (SemaRef.getLangOptions().ObjC1 && isa<ObjCIvarDecl>(ND))
809 return true;
810
811 return ND->getIdentifierNamespace() & IDNS;
812}
813
814/// \brief Determines whether this given declaration will be found by
Douglas Gregor504a6ae2010-01-10 23:08:15 +0000815/// ordinary name lookup.
816bool ResultBuilder::IsOrdinaryNonValueName(NamedDecl *ND) const {
Douglas Gregor70febae2010-05-28 00:49:12 +0000817 ND = cast<NamedDecl>(ND->getUnderlyingDecl());
818
Douglas Gregor504a6ae2010-01-10 23:08:15 +0000819 unsigned IDNS = Decl::IDNS_Ordinary;
820 if (SemaRef.getLangOptions().CPlusPlus)
John McCalle87beb22010-04-23 18:46:30 +0000821 IDNS |= Decl::IDNS_Tag | Decl::IDNS_Namespace;
Douglas Gregor504a6ae2010-01-10 23:08:15 +0000822
823 return (ND->getIdentifierNamespace() & IDNS) &&
Douglas Gregor70febae2010-05-28 00:49:12 +0000824 !isa<ValueDecl>(ND) && !isa<FunctionTemplateDecl>(ND) &&
825 !isa<ObjCPropertyDecl>(ND);
Douglas Gregor504a6ae2010-01-10 23:08:15 +0000826}
827
Douglas Gregor3545ff42009-09-21 16:56:56 +0000828/// \brief Determines whether the given declaration is suitable as the
829/// start of a C++ nested-name-specifier, e.g., a class or namespace.
830bool ResultBuilder::IsNestedNameSpecifier(NamedDecl *ND) const {
831 // Allow us to find class templates, too.
832 if (ClassTemplateDecl *ClassTemplate = dyn_cast<ClassTemplateDecl>(ND))
833 ND = ClassTemplate->getTemplatedDecl();
834
835 return SemaRef.isAcceptableNestedNameSpecifier(ND);
836}
837
838/// \brief Determines whether the given declaration is an enumeration.
839bool ResultBuilder::IsEnum(NamedDecl *ND) const {
840 return isa<EnumDecl>(ND);
841}
842
843/// \brief Determines whether the given declaration is a class or struct.
844bool ResultBuilder::IsClassOrStruct(NamedDecl *ND) const {
845 // Allow us to find class templates, too.
846 if (ClassTemplateDecl *ClassTemplate = dyn_cast<ClassTemplateDecl>(ND))
847 ND = ClassTemplate->getTemplatedDecl();
848
849 if (RecordDecl *RD = dyn_cast<RecordDecl>(ND))
Abramo Bagnara6150c882010-05-11 21:36:43 +0000850 return RD->getTagKind() == TTK_Class ||
851 RD->getTagKind() == TTK_Struct;
Douglas Gregor3545ff42009-09-21 16:56:56 +0000852
853 return false;
854}
855
856/// \brief Determines whether the given declaration is a union.
857bool ResultBuilder::IsUnion(NamedDecl *ND) const {
858 // Allow us to find class templates, too.
859 if (ClassTemplateDecl *ClassTemplate = dyn_cast<ClassTemplateDecl>(ND))
860 ND = ClassTemplate->getTemplatedDecl();
861
862 if (RecordDecl *RD = dyn_cast<RecordDecl>(ND))
Abramo Bagnara6150c882010-05-11 21:36:43 +0000863 return RD->getTagKind() == TTK_Union;
Douglas Gregor3545ff42009-09-21 16:56:56 +0000864
865 return false;
866}
867
868/// \brief Determines whether the given declaration is a namespace.
869bool ResultBuilder::IsNamespace(NamedDecl *ND) const {
870 return isa<NamespaceDecl>(ND);
871}
872
873/// \brief Determines whether the given declaration is a namespace or
874/// namespace alias.
875bool ResultBuilder::IsNamespaceOrAlias(NamedDecl *ND) const {
876 return isa<NamespaceDecl>(ND) || isa<NamespaceAliasDecl>(ND);
877}
878
Douglas Gregor99fe2ad2009-12-11 17:31:05 +0000879/// \brief Determines whether the given declaration is a type.
Douglas Gregor3545ff42009-09-21 16:56:56 +0000880bool ResultBuilder::IsType(NamedDecl *ND) const {
881 return isa<TypeDecl>(ND);
882}
883
Douglas Gregor99fe2ad2009-12-11 17:31:05 +0000884/// \brief Determines which members of a class should be visible via
885/// "." or "->". Only value declarations, nested name specifiers, and
886/// using declarations thereof should show up.
Douglas Gregore412a5a2009-09-23 22:26:46 +0000887bool ResultBuilder::IsMember(NamedDecl *ND) const {
Douglas Gregor99fe2ad2009-12-11 17:31:05 +0000888 if (UsingShadowDecl *Using = dyn_cast<UsingShadowDecl>(ND))
889 ND = Using->getTargetDecl();
890
Douglas Gregor70788392009-12-11 18:14:22 +0000891 return isa<ValueDecl>(ND) || isa<FunctionTemplateDecl>(ND) ||
892 isa<ObjCPropertyDecl>(ND);
Douglas Gregore412a5a2009-09-23 22:26:46 +0000893}
894
Douglas Gregora817a192010-05-27 23:06:34 +0000895static bool isObjCReceiverType(ASTContext &C, QualType T) {
896 T = C.getCanonicalType(T);
897 switch (T->getTypeClass()) {
898 case Type::ObjCObject:
899 case Type::ObjCInterface:
900 case Type::ObjCObjectPointer:
901 return true;
902
903 case Type::Builtin:
904 switch (cast<BuiltinType>(T)->getKind()) {
905 case BuiltinType::ObjCId:
906 case BuiltinType::ObjCClass:
907 case BuiltinType::ObjCSel:
908 return true;
909
910 default:
911 break;
912 }
913 return false;
914
915 default:
916 break;
917 }
918
919 if (!C.getLangOptions().CPlusPlus)
920 return false;
921
922 // FIXME: We could perform more analysis here to determine whether a
923 // particular class type has any conversions to Objective-C types. For now,
924 // just accept all class types.
925 return T->isDependentType() || T->isRecordType();
926}
927
928bool ResultBuilder::IsObjCMessageReceiver(NamedDecl *ND) const {
929 QualType T = getDeclUsageType(SemaRef.Context, ND);
930 if (T.isNull())
931 return false;
932
933 T = SemaRef.Context.getBaseElementType(T);
934 return isObjCReceiverType(SemaRef.Context, T);
935}
936
937
Douglas Gregor2b8162b2010-01-14 16:08:12 +0000938/// \rief Determines whether the given declaration is an Objective-C
939/// instance variable.
940bool ResultBuilder::IsObjCIvar(NamedDecl *ND) const {
941 return isa<ObjCIvarDecl>(ND);
942}
943
Douglas Gregorc580c522010-01-14 01:09:38 +0000944namespace {
945 /// \brief Visible declaration consumer that adds a code-completion result
946 /// for each visible declaration.
947 class CodeCompletionDeclConsumer : public VisibleDeclConsumer {
948 ResultBuilder &Results;
949 DeclContext *CurContext;
950
951 public:
952 CodeCompletionDeclConsumer(ResultBuilder &Results, DeclContext *CurContext)
953 : Results(Results), CurContext(CurContext) { }
954
Douglas Gregor09bbc652010-01-14 15:47:35 +0000955 virtual void FoundDecl(NamedDecl *ND, NamedDecl *Hiding, bool InBaseClass) {
956 Results.AddResult(ND, CurContext, Hiding, InBaseClass);
Douglas Gregorc580c522010-01-14 01:09:38 +0000957 }
958 };
959}
960
Douglas Gregor3545ff42009-09-21 16:56:56 +0000961/// \brief Add type specifiers for the current language as keyword results.
Douglas Gregorf98e6a22010-01-13 23:51:12 +0000962static void AddTypeSpecifierResults(const LangOptions &LangOpts,
Douglas Gregor3545ff42009-09-21 16:56:56 +0000963 ResultBuilder &Results) {
964 typedef CodeCompleteConsumer::Result Result;
Douglas Gregora2db7932010-05-26 22:00:08 +0000965 Results.AddResult(Result("short", CCP_Type));
966 Results.AddResult(Result("long", CCP_Type));
967 Results.AddResult(Result("signed", CCP_Type));
968 Results.AddResult(Result("unsigned", CCP_Type));
969 Results.AddResult(Result("void", CCP_Type));
970 Results.AddResult(Result("char", CCP_Type));
971 Results.AddResult(Result("int", CCP_Type));
972 Results.AddResult(Result("float", CCP_Type));
973 Results.AddResult(Result("double", CCP_Type));
974 Results.AddResult(Result("enum", CCP_Type));
975 Results.AddResult(Result("struct", CCP_Type));
976 Results.AddResult(Result("union", CCP_Type));
977 Results.AddResult(Result("const", CCP_Type));
978 Results.AddResult(Result("volatile", CCP_Type));
Douglas Gregor504a6ae2010-01-10 23:08:15 +0000979
Douglas Gregor3545ff42009-09-21 16:56:56 +0000980 if (LangOpts.C99) {
981 // C99-specific
Douglas Gregora2db7932010-05-26 22:00:08 +0000982 Results.AddResult(Result("_Complex", CCP_Type));
983 Results.AddResult(Result("_Imaginary", CCP_Type));
984 Results.AddResult(Result("_Bool", CCP_Type));
985 Results.AddResult(Result("restrict", CCP_Type));
Douglas Gregor3545ff42009-09-21 16:56:56 +0000986 }
987
988 if (LangOpts.CPlusPlus) {
989 // C++-specific
Douglas Gregora2db7932010-05-26 22:00:08 +0000990 Results.AddResult(Result("bool", CCP_Type));
991 Results.AddResult(Result("class", CCP_Type));
992 Results.AddResult(Result("wchar_t", CCP_Type));
Douglas Gregor3545ff42009-09-21 16:56:56 +0000993
Douglas Gregorf4c33342010-05-28 00:22:41 +0000994 // typename qualified-id
995 CodeCompletionString *Pattern = new CodeCompletionString;
996 Pattern->AddTypedTextChunk("typename");
997 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
998 Pattern->AddPlaceholderChunk("qualifier");
999 Pattern->AddTextChunk("::");
1000 Pattern->AddPlaceholderChunk("name");
1001 Results.AddResult(Result(Pattern));
Douglas Gregorf64acca2010-05-25 21:41:55 +00001002
Douglas Gregor3545ff42009-09-21 16:56:56 +00001003 if (LangOpts.CPlusPlus0x) {
Douglas Gregora2db7932010-05-26 22:00:08 +00001004 Results.AddResult(Result("auto", CCP_Type));
1005 Results.AddResult(Result("char16_t", CCP_Type));
1006 Results.AddResult(Result("char32_t", CCP_Type));
Douglas Gregorf4c33342010-05-28 00:22:41 +00001007
1008 CodeCompletionString *Pattern = new CodeCompletionString;
1009 Pattern->AddTypedTextChunk("decltype");
1010 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
1011 Pattern->AddPlaceholderChunk("expression");
1012 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
1013 Results.AddResult(Result(Pattern));
Douglas Gregor3545ff42009-09-21 16:56:56 +00001014 }
1015 }
1016
1017 // GNU extensions
1018 if (LangOpts.GNUMode) {
1019 // FIXME: Enable when we actually support decimal floating point.
Douglas Gregor78a21012010-01-14 16:01:26 +00001020 // Results.AddResult(Result("_Decimal32"));
1021 // Results.AddResult(Result("_Decimal64"));
1022 // Results.AddResult(Result("_Decimal128"));
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001023
Douglas Gregorf4c33342010-05-28 00:22:41 +00001024 CodeCompletionString *Pattern = new CodeCompletionString;
1025 Pattern->AddTypedTextChunk("typeof");
1026 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
1027 Pattern->AddPlaceholderChunk("expression");
1028 Results.AddResult(Result(Pattern));
1029
1030 Pattern = new CodeCompletionString;
1031 Pattern->AddTypedTextChunk("typeof");
1032 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
1033 Pattern->AddPlaceholderChunk("type");
1034 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
1035 Results.AddResult(Result(Pattern));
Douglas Gregor3545ff42009-09-21 16:56:56 +00001036 }
1037}
1038
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001039static void AddStorageSpecifiers(Action::CodeCompletionContext CCC,
1040 const LangOptions &LangOpts,
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001041 ResultBuilder &Results) {
1042 typedef CodeCompleteConsumer::Result Result;
1043 // Note: we don't suggest either "auto" or "register", because both
1044 // are pointless as storage specifiers. Elsewhere, we suggest "auto"
1045 // in C++0x as a type specifier.
Douglas Gregor78a21012010-01-14 16:01:26 +00001046 Results.AddResult(Result("extern"));
1047 Results.AddResult(Result("static"));
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001048}
1049
1050static void AddFunctionSpecifiers(Action::CodeCompletionContext CCC,
1051 const LangOptions &LangOpts,
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001052 ResultBuilder &Results) {
1053 typedef CodeCompleteConsumer::Result Result;
1054 switch (CCC) {
1055 case Action::CCC_Class:
1056 case Action::CCC_MemberTemplate:
1057 if (LangOpts.CPlusPlus) {
Douglas Gregor78a21012010-01-14 16:01:26 +00001058 Results.AddResult(Result("explicit"));
1059 Results.AddResult(Result("friend"));
1060 Results.AddResult(Result("mutable"));
1061 Results.AddResult(Result("virtual"));
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001062 }
1063 // Fall through
1064
Douglas Gregorf1934162010-01-13 21:24:21 +00001065 case Action::CCC_ObjCInterface:
1066 case Action::CCC_ObjCImplementation:
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001067 case Action::CCC_Namespace:
1068 case Action::CCC_Template:
1069 if (LangOpts.CPlusPlus || LangOpts.C99)
Douglas Gregor78a21012010-01-14 16:01:26 +00001070 Results.AddResult(Result("inline"));
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001071 break;
1072
Douglas Gregor48d46252010-01-13 21:54:15 +00001073 case Action::CCC_ObjCInstanceVariableList:
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001074 case Action::CCC_Expression:
1075 case Action::CCC_Statement:
1076 case Action::CCC_ForInit:
1077 case Action::CCC_Condition:
Douglas Gregor6da3db42010-05-25 05:58:43 +00001078 case Action::CCC_RecoveryInFunction:
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001079 break;
1080 }
1081}
1082
Douglas Gregorf98e6a22010-01-13 23:51:12 +00001083static void AddObjCExpressionResults(ResultBuilder &Results, bool NeedAt);
1084static void AddObjCStatementResults(ResultBuilder &Results, bool NeedAt);
1085static void AddObjCVisibilityResults(const LangOptions &LangOpts,
Douglas Gregor48d46252010-01-13 21:54:15 +00001086 ResultBuilder &Results,
1087 bool NeedAt);
Douglas Gregorf98e6a22010-01-13 23:51:12 +00001088static void AddObjCImplementationResults(const LangOptions &LangOpts,
Douglas Gregorf1934162010-01-13 21:24:21 +00001089 ResultBuilder &Results,
1090 bool NeedAt);
Douglas Gregorf98e6a22010-01-13 23:51:12 +00001091static void AddObjCInterfaceResults(const LangOptions &LangOpts,
Douglas Gregorf1934162010-01-13 21:24:21 +00001092 ResultBuilder &Results,
1093 bool NeedAt);
Douglas Gregorf98e6a22010-01-13 23:51:12 +00001094static void AddObjCTopLevelResults(ResultBuilder &Results, bool NeedAt);
Douglas Gregorf1934162010-01-13 21:24:21 +00001095
Douglas Gregorf4c33342010-05-28 00:22:41 +00001096static void AddTypedefResult(ResultBuilder &Results) {
1097 CodeCompletionString *Pattern = new CodeCompletionString;
1098 Pattern->AddTypedTextChunk("typedef");
1099 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
1100 Pattern->AddPlaceholderChunk("type");
1101 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
1102 Pattern->AddPlaceholderChunk("name");
1103 Results.AddResult(CodeCompleteConsumer::Result(Pattern));
1104}
1105
Douglas Gregor70febae2010-05-28 00:49:12 +00001106static bool WantTypesInContext(Action::CodeCompletionContext CCC,
1107 const LangOptions &LangOpts) {
1108 if (LangOpts.CPlusPlus)
1109 return true;
1110
1111 switch (CCC) {
1112 case Action::CCC_Namespace:
1113 case Action::CCC_Class:
1114 case Action::CCC_ObjCInstanceVariableList:
1115 case Action::CCC_Template:
1116 case Action::CCC_MemberTemplate:
1117 case Action::CCC_Statement:
1118 case Action::CCC_RecoveryInFunction:
1119 return true;
1120
1121 case Action::CCC_ObjCInterface:
1122 case Action::CCC_ObjCImplementation:
1123 case Action::CCC_Expression:
1124 case Action::CCC_Condition:
1125 return false;
1126
1127 case Action::CCC_ForInit:
1128 return LangOpts.ObjC1 || LangOpts.C99;
1129 }
1130
1131 return false;
1132}
1133
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001134/// \brief Add language constructs that show up for "ordinary" names.
1135static void AddOrdinaryNameResults(Action::CodeCompletionContext CCC,
1136 Scope *S,
1137 Sema &SemaRef,
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001138 ResultBuilder &Results) {
1139 typedef CodeCompleteConsumer::Result Result;
1140 switch (CCC) {
1141 case Action::CCC_Namespace:
Douglas Gregorf4c33342010-05-28 00:22:41 +00001142 if (SemaRef.getLangOptions().CPlusPlus) {
1143 CodeCompletionString *Pattern = 0;
1144
1145 if (Results.includeCodePatterns()) {
1146 // namespace <identifier> { declarations }
1147 CodeCompletionString *Pattern = new CodeCompletionString;
1148 Pattern->AddTypedTextChunk("namespace");
1149 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
1150 Pattern->AddPlaceholderChunk("identifier");
1151 Pattern->AddChunk(CodeCompletionString::CK_LeftBrace);
1152 Pattern->AddPlaceholderChunk("declarations");
1153 Pattern->AddChunk(CodeCompletionString::CK_VerticalSpace);
1154 Pattern->AddChunk(CodeCompletionString::CK_RightBrace);
1155 Results.AddResult(Result(Pattern));
1156 }
1157
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001158 // namespace identifier = identifier ;
1159 Pattern = new CodeCompletionString;
1160 Pattern->AddTypedTextChunk("namespace");
1161 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
Douglas Gregorf4c33342010-05-28 00:22:41 +00001162 Pattern->AddPlaceholderChunk("name");
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001163 Pattern->AddChunk(CodeCompletionString::CK_Equal);
Douglas Gregorf4c33342010-05-28 00:22:41 +00001164 Pattern->AddPlaceholderChunk("namespace");
Douglas Gregor78a21012010-01-14 16:01:26 +00001165 Results.AddResult(Result(Pattern));
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001166
1167 // Using directives
1168 Pattern = new CodeCompletionString;
1169 Pattern->AddTypedTextChunk("using");
1170 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
1171 Pattern->AddTextChunk("namespace");
1172 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
1173 Pattern->AddPlaceholderChunk("identifier");
Douglas Gregor78a21012010-01-14 16:01:26 +00001174 Results.AddResult(Result(Pattern));
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001175
1176 // asm(string-literal)
1177 Pattern = new CodeCompletionString;
1178 Pattern->AddTypedTextChunk("asm");
1179 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
1180 Pattern->AddPlaceholderChunk("string-literal");
1181 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
Douglas Gregor78a21012010-01-14 16:01:26 +00001182 Results.AddResult(Result(Pattern));
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001183
Douglas Gregorf4c33342010-05-28 00:22:41 +00001184 if (Results.includeCodePatterns()) {
1185 // Explicit template instantiation
1186 Pattern = new CodeCompletionString;
1187 Pattern->AddTypedTextChunk("template");
1188 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
1189 Pattern->AddPlaceholderChunk("declaration");
1190 Results.AddResult(Result(Pattern));
1191 }
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001192 }
Douglas Gregorf1934162010-01-13 21:24:21 +00001193
1194 if (SemaRef.getLangOptions().ObjC1)
Douglas Gregorf98e6a22010-01-13 23:51:12 +00001195 AddObjCTopLevelResults(Results, true);
Douglas Gregorf1934162010-01-13 21:24:21 +00001196
Douglas Gregorf4c33342010-05-28 00:22:41 +00001197 AddTypedefResult(Results);
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001198 // Fall through
1199
1200 case Action::CCC_Class:
Douglas Gregorf4c33342010-05-28 00:22:41 +00001201 if (SemaRef.getLangOptions().CPlusPlus) {
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001202 // Using declaration
1203 CodeCompletionString *Pattern = new CodeCompletionString;
1204 Pattern->AddTypedTextChunk("using");
1205 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
Douglas Gregorf4c33342010-05-28 00:22:41 +00001206 Pattern->AddPlaceholderChunk("qualifier");
1207 Pattern->AddTextChunk("::");
1208 Pattern->AddPlaceholderChunk("name");
Douglas Gregor78a21012010-01-14 16:01:26 +00001209 Results.AddResult(Result(Pattern));
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001210
Douglas Gregorf4c33342010-05-28 00:22:41 +00001211 // using typename qualifier::name (only in a dependent context)
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001212 if (SemaRef.CurContext->isDependentContext()) {
1213 Pattern = new CodeCompletionString;
1214 Pattern->AddTypedTextChunk("using");
1215 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
1216 Pattern->AddTextChunk("typename");
1217 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
Douglas Gregorf4c33342010-05-28 00:22:41 +00001218 Pattern->AddPlaceholderChunk("qualifier");
1219 Pattern->AddTextChunk("::");
1220 Pattern->AddPlaceholderChunk("name");
Douglas Gregor78a21012010-01-14 16:01:26 +00001221 Results.AddResult(Result(Pattern));
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001222 }
1223
1224 if (CCC == Action::CCC_Class) {
Douglas Gregorf4c33342010-05-28 00:22:41 +00001225 AddTypedefResult(Results);
1226
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001227 // public:
1228 Pattern = new CodeCompletionString;
1229 Pattern->AddTypedTextChunk("public");
1230 Pattern->AddChunk(CodeCompletionString::CK_Colon);
Douglas Gregor78a21012010-01-14 16:01:26 +00001231 Results.AddResult(Result(Pattern));
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001232
1233 // protected:
1234 Pattern = new CodeCompletionString;
1235 Pattern->AddTypedTextChunk("protected");
1236 Pattern->AddChunk(CodeCompletionString::CK_Colon);
Douglas Gregor78a21012010-01-14 16:01:26 +00001237 Results.AddResult(Result(Pattern));
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001238
1239 // private:
1240 Pattern = new CodeCompletionString;
1241 Pattern->AddTypedTextChunk("private");
1242 Pattern->AddChunk(CodeCompletionString::CK_Colon);
Douglas Gregor78a21012010-01-14 16:01:26 +00001243 Results.AddResult(Result(Pattern));
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001244 }
1245 }
1246 // Fall through
1247
1248 case Action::CCC_Template:
1249 case Action::CCC_MemberTemplate:
Douglas Gregorf64acca2010-05-25 21:41:55 +00001250 if (SemaRef.getLangOptions().CPlusPlus && Results.includeCodePatterns()) {
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001251 // template < parameters >
1252 CodeCompletionString *Pattern = new CodeCompletionString;
1253 Pattern->AddTypedTextChunk("template");
1254 Pattern->AddChunk(CodeCompletionString::CK_LeftAngle);
1255 Pattern->AddPlaceholderChunk("parameters");
1256 Pattern->AddChunk(CodeCompletionString::CK_RightAngle);
Douglas Gregor78a21012010-01-14 16:01:26 +00001257 Results.AddResult(Result(Pattern));
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001258 }
1259
Douglas Gregorf98e6a22010-01-13 23:51:12 +00001260 AddStorageSpecifiers(CCC, SemaRef.getLangOptions(), Results);
1261 AddFunctionSpecifiers(CCC, SemaRef.getLangOptions(), Results);
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001262 break;
1263
Douglas Gregorf1934162010-01-13 21:24:21 +00001264 case Action::CCC_ObjCInterface:
Douglas Gregorf98e6a22010-01-13 23:51:12 +00001265 AddObjCInterfaceResults(SemaRef.getLangOptions(), Results, true);
1266 AddStorageSpecifiers(CCC, SemaRef.getLangOptions(), Results);
1267 AddFunctionSpecifiers(CCC, SemaRef.getLangOptions(), Results);
Douglas Gregorf1934162010-01-13 21:24:21 +00001268 break;
1269
1270 case Action::CCC_ObjCImplementation:
Douglas Gregorf98e6a22010-01-13 23:51:12 +00001271 AddObjCImplementationResults(SemaRef.getLangOptions(), Results, true);
1272 AddStorageSpecifiers(CCC, SemaRef.getLangOptions(), Results);
1273 AddFunctionSpecifiers(CCC, SemaRef.getLangOptions(), Results);
Douglas Gregorf1934162010-01-13 21:24:21 +00001274 break;
1275
Douglas Gregor48d46252010-01-13 21:54:15 +00001276 case Action::CCC_ObjCInstanceVariableList:
Douglas Gregorf98e6a22010-01-13 23:51:12 +00001277 AddObjCVisibilityResults(SemaRef.getLangOptions(), Results, true);
Douglas Gregor48d46252010-01-13 21:54:15 +00001278 break;
1279
Douglas Gregor6da3db42010-05-25 05:58:43 +00001280 case Action::CCC_RecoveryInFunction:
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001281 case Action::CCC_Statement: {
Douglas Gregorf4c33342010-05-28 00:22:41 +00001282 AddTypedefResult(Results);
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001283
1284 CodeCompletionString *Pattern = 0;
Douglas Gregorf64acca2010-05-25 21:41:55 +00001285 if (SemaRef.getLangOptions().CPlusPlus && Results.includeCodePatterns()) {
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001286 Pattern = new CodeCompletionString;
1287 Pattern->AddTypedTextChunk("try");
1288 Pattern->AddChunk(CodeCompletionString::CK_LeftBrace);
1289 Pattern->AddPlaceholderChunk("statements");
1290 Pattern->AddChunk(CodeCompletionString::CK_VerticalSpace);
1291 Pattern->AddChunk(CodeCompletionString::CK_RightBrace);
1292 Pattern->AddTextChunk("catch");
1293 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
1294 Pattern->AddPlaceholderChunk("declaration");
1295 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
1296 Pattern->AddChunk(CodeCompletionString::CK_LeftBrace);
1297 Pattern->AddPlaceholderChunk("statements");
1298 Pattern->AddChunk(CodeCompletionString::CK_VerticalSpace);
1299 Pattern->AddChunk(CodeCompletionString::CK_RightBrace);
Douglas Gregor78a21012010-01-14 16:01:26 +00001300 Results.AddResult(Result(Pattern));
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001301 }
Douglas Gregorf1934162010-01-13 21:24:21 +00001302 if (SemaRef.getLangOptions().ObjC1)
Douglas Gregorf98e6a22010-01-13 23:51:12 +00001303 AddObjCStatementResults(Results, true);
Douglas Gregorf1934162010-01-13 21:24:21 +00001304
Douglas Gregorf64acca2010-05-25 21:41:55 +00001305 if (Results.includeCodePatterns()) {
1306 // if (condition) { statements }
1307 Pattern = new CodeCompletionString;
1308 Pattern->AddTypedTextChunk("if");
1309 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
1310 if (SemaRef.getLangOptions().CPlusPlus)
1311 Pattern->AddPlaceholderChunk("condition");
1312 else
1313 Pattern->AddPlaceholderChunk("expression");
1314 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
1315 Pattern->AddChunk(CodeCompletionString::CK_LeftBrace);
1316 Pattern->AddPlaceholderChunk("statements");
1317 Pattern->AddChunk(CodeCompletionString::CK_VerticalSpace);
1318 Pattern->AddChunk(CodeCompletionString::CK_RightBrace);
1319 Results.AddResult(Result(Pattern));
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001320
Douglas Gregorf64acca2010-05-25 21:41:55 +00001321 // switch (condition) { }
1322 Pattern = new CodeCompletionString;
1323 Pattern->AddTypedTextChunk("switch");
1324 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
1325 if (SemaRef.getLangOptions().CPlusPlus)
1326 Pattern->AddPlaceholderChunk("condition");
1327 else
1328 Pattern->AddPlaceholderChunk("expression");
1329 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
1330 Pattern->AddChunk(CodeCompletionString::CK_LeftBrace);
1331 Pattern->AddChunk(CodeCompletionString::CK_VerticalSpace);
1332 Pattern->AddChunk(CodeCompletionString::CK_RightBrace);
1333 Results.AddResult(Result(Pattern));
1334 }
1335
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001336 // Switch-specific statements.
Douglas Gregorf4c33342010-05-28 00:22:41 +00001337 if (!SemaRef.getSwitchStack().empty()) {
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001338 // case expression:
1339 Pattern = new CodeCompletionString;
1340 Pattern->AddTypedTextChunk("case");
Douglas Gregorf4c33342010-05-28 00:22:41 +00001341 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001342 Pattern->AddPlaceholderChunk("expression");
1343 Pattern->AddChunk(CodeCompletionString::CK_Colon);
Douglas Gregor78a21012010-01-14 16:01:26 +00001344 Results.AddResult(Result(Pattern));
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001345
1346 // default:
1347 Pattern = new CodeCompletionString;
1348 Pattern->AddTypedTextChunk("default");
1349 Pattern->AddChunk(CodeCompletionString::CK_Colon);
Douglas Gregor78a21012010-01-14 16:01:26 +00001350 Results.AddResult(Result(Pattern));
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001351 }
1352
Douglas Gregorf64acca2010-05-25 21:41:55 +00001353 if (Results.includeCodePatterns()) {
1354 /// while (condition) { statements }
1355 Pattern = new CodeCompletionString;
1356 Pattern->AddTypedTextChunk("while");
1357 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
1358 if (SemaRef.getLangOptions().CPlusPlus)
1359 Pattern->AddPlaceholderChunk("condition");
1360 else
1361 Pattern->AddPlaceholderChunk("expression");
1362 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
1363 Pattern->AddChunk(CodeCompletionString::CK_LeftBrace);
1364 Pattern->AddPlaceholderChunk("statements");
1365 Pattern->AddChunk(CodeCompletionString::CK_VerticalSpace);
1366 Pattern->AddChunk(CodeCompletionString::CK_RightBrace);
1367 Results.AddResult(Result(Pattern));
1368
1369 // do { statements } while ( expression );
1370 Pattern = new CodeCompletionString;
1371 Pattern->AddTypedTextChunk("do");
1372 Pattern->AddChunk(CodeCompletionString::CK_LeftBrace);
1373 Pattern->AddPlaceholderChunk("statements");
1374 Pattern->AddChunk(CodeCompletionString::CK_VerticalSpace);
1375 Pattern->AddChunk(CodeCompletionString::CK_RightBrace);
1376 Pattern->AddTextChunk("while");
1377 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001378 Pattern->AddPlaceholderChunk("expression");
Douglas Gregorf64acca2010-05-25 21:41:55 +00001379 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
1380 Results.AddResult(Result(Pattern));
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001381
Douglas Gregorf64acca2010-05-25 21:41:55 +00001382 // for ( for-init-statement ; condition ; expression ) { statements }
1383 Pattern = new CodeCompletionString;
1384 Pattern->AddTypedTextChunk("for");
1385 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
1386 if (SemaRef.getLangOptions().CPlusPlus || SemaRef.getLangOptions().C99)
1387 Pattern->AddPlaceholderChunk("init-statement");
1388 else
1389 Pattern->AddPlaceholderChunk("init-expression");
1390 Pattern->AddChunk(CodeCompletionString::CK_SemiColon);
1391 Pattern->AddPlaceholderChunk("condition");
1392 Pattern->AddChunk(CodeCompletionString::CK_SemiColon);
1393 Pattern->AddPlaceholderChunk("inc-expression");
1394 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
1395 Pattern->AddChunk(CodeCompletionString::CK_LeftBrace);
1396 Pattern->AddPlaceholderChunk("statements");
1397 Pattern->AddChunk(CodeCompletionString::CK_VerticalSpace);
1398 Pattern->AddChunk(CodeCompletionString::CK_RightBrace);
1399 Results.AddResult(Result(Pattern));
1400 }
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001401
1402 if (S->getContinueParent()) {
1403 // continue ;
1404 Pattern = new CodeCompletionString;
1405 Pattern->AddTypedTextChunk("continue");
Douglas Gregor78a21012010-01-14 16:01:26 +00001406 Results.AddResult(Result(Pattern));
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001407 }
1408
1409 if (S->getBreakParent()) {
1410 // break ;
1411 Pattern = new CodeCompletionString;
1412 Pattern->AddTypedTextChunk("break");
Douglas Gregor78a21012010-01-14 16:01:26 +00001413 Results.AddResult(Result(Pattern));
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001414 }
1415
1416 // "return expression ;" or "return ;", depending on whether we
1417 // know the function is void or not.
1418 bool isVoid = false;
1419 if (FunctionDecl *Function = dyn_cast<FunctionDecl>(SemaRef.CurContext))
1420 isVoid = Function->getResultType()->isVoidType();
1421 else if (ObjCMethodDecl *Method
1422 = dyn_cast<ObjCMethodDecl>(SemaRef.CurContext))
1423 isVoid = Method->getResultType()->isVoidType();
Douglas Gregor9a28e842010-03-01 23:15:13 +00001424 else if (SemaRef.getCurBlock() &&
1425 !SemaRef.getCurBlock()->ReturnType.isNull())
1426 isVoid = SemaRef.getCurBlock()->ReturnType->isVoidType();
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001427 Pattern = new CodeCompletionString;
1428 Pattern->AddTypedTextChunk("return");
Douglas Gregor44272ca2010-02-18 04:06:48 +00001429 if (!isVoid) {
1430 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001431 Pattern->AddPlaceholderChunk("expression");
Douglas Gregor44272ca2010-02-18 04:06:48 +00001432 }
Douglas Gregor78a21012010-01-14 16:01:26 +00001433 Results.AddResult(Result(Pattern));
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001434
Douglas Gregorf4c33342010-05-28 00:22:41 +00001435 // goto identifier ;
1436 Pattern = new CodeCompletionString;
1437 Pattern->AddTypedTextChunk("goto");
1438 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
1439 Pattern->AddPlaceholderChunk("label");
1440 Results.AddResult(Result(Pattern));
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001441
Douglas Gregorf4c33342010-05-28 00:22:41 +00001442 // Using directives
1443 Pattern = new CodeCompletionString;
1444 Pattern->AddTypedTextChunk("using");
1445 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
1446 Pattern->AddTextChunk("namespace");
1447 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
1448 Pattern->AddPlaceholderChunk("identifier");
1449 Results.AddResult(Result(Pattern));
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001450 }
1451
1452 // Fall through (for statement expressions).
1453 case Action::CCC_ForInit:
1454 case Action::CCC_Condition:
Douglas Gregorf98e6a22010-01-13 23:51:12 +00001455 AddStorageSpecifiers(CCC, SemaRef.getLangOptions(), Results);
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001456 // Fall through: conditions and statements can have expressions.
1457
1458 case Action::CCC_Expression: {
1459 CodeCompletionString *Pattern = 0;
1460 if (SemaRef.getLangOptions().CPlusPlus) {
1461 // 'this', if we're in a non-static member function.
1462 if (CXXMethodDecl *Method = dyn_cast<CXXMethodDecl>(SemaRef.CurContext))
1463 if (!Method->isStatic())
Douglas Gregor78a21012010-01-14 16:01:26 +00001464 Results.AddResult(Result("this"));
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001465
1466 // true, false
Douglas Gregor78a21012010-01-14 16:01:26 +00001467 Results.AddResult(Result("true"));
1468 Results.AddResult(Result("false"));
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001469
Douglas Gregorf4c33342010-05-28 00:22:41 +00001470 // dynamic_cast < type-id > ( expression )
1471 Pattern = new CodeCompletionString;
1472 Pattern->AddTypedTextChunk("dynamic_cast");
1473 Pattern->AddChunk(CodeCompletionString::CK_LeftAngle);
1474 Pattern->AddPlaceholderChunk("type");
1475 Pattern->AddChunk(CodeCompletionString::CK_RightAngle);
1476 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
1477 Pattern->AddPlaceholderChunk("expression");
1478 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
1479 Results.AddResult(Result(Pattern));
1480
1481 // static_cast < type-id > ( expression )
1482 Pattern = new CodeCompletionString;
1483 Pattern->AddTypedTextChunk("static_cast");
1484 Pattern->AddChunk(CodeCompletionString::CK_LeftAngle);
1485 Pattern->AddPlaceholderChunk("type");
1486 Pattern->AddChunk(CodeCompletionString::CK_RightAngle);
1487 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
1488 Pattern->AddPlaceholderChunk("expression");
1489 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
1490 Results.AddResult(Result(Pattern));
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001491
Douglas Gregorf4c33342010-05-28 00:22:41 +00001492 // reinterpret_cast < type-id > ( expression )
1493 Pattern = new CodeCompletionString;
1494 Pattern->AddTypedTextChunk("reinterpret_cast");
1495 Pattern->AddChunk(CodeCompletionString::CK_LeftAngle);
1496 Pattern->AddPlaceholderChunk("type");
1497 Pattern->AddChunk(CodeCompletionString::CK_RightAngle);
1498 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
1499 Pattern->AddPlaceholderChunk("expression");
1500 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
1501 Results.AddResult(Result(Pattern));
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001502
Douglas Gregorf4c33342010-05-28 00:22:41 +00001503 // const_cast < type-id > ( expression )
1504 Pattern = new CodeCompletionString;
1505 Pattern->AddTypedTextChunk("const_cast");
1506 Pattern->AddChunk(CodeCompletionString::CK_LeftAngle);
1507 Pattern->AddPlaceholderChunk("type");
1508 Pattern->AddChunk(CodeCompletionString::CK_RightAngle);
1509 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
1510 Pattern->AddPlaceholderChunk("expression");
1511 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
1512 Results.AddResult(Result(Pattern));
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001513
Douglas Gregorf4c33342010-05-28 00:22:41 +00001514 // typeid ( expression-or-type )
1515 Pattern = new CodeCompletionString;
1516 Pattern->AddTypedTextChunk("typeid");
1517 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
1518 Pattern->AddPlaceholderChunk("expression-or-type");
1519 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
1520 Results.AddResult(Result(Pattern));
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001521
Douglas Gregorf4c33342010-05-28 00:22:41 +00001522 // new T ( ... )
1523 Pattern = new CodeCompletionString;
1524 Pattern->AddTypedTextChunk("new");
1525 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
1526 Pattern->AddPlaceholderChunk("type");
1527 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
1528 Pattern->AddPlaceholderChunk("expressions");
1529 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
1530 Results.AddResult(Result(Pattern));
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001531
Douglas Gregorf4c33342010-05-28 00:22:41 +00001532 // new T [ ] ( ... )
1533 Pattern = new CodeCompletionString;
1534 Pattern->AddTypedTextChunk("new");
1535 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
1536 Pattern->AddPlaceholderChunk("type");
1537 Pattern->AddChunk(CodeCompletionString::CK_LeftBracket);
1538 Pattern->AddPlaceholderChunk("size");
1539 Pattern->AddChunk(CodeCompletionString::CK_RightBracket);
1540 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
1541 Pattern->AddPlaceholderChunk("expressions");
1542 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
1543 Results.AddResult(Result(Pattern));
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001544
Douglas Gregorf4c33342010-05-28 00:22:41 +00001545 // delete expression
1546 Pattern = new CodeCompletionString;
1547 Pattern->AddTypedTextChunk("delete");
1548 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
1549 Pattern->AddPlaceholderChunk("expression");
1550 Results.AddResult(Result(Pattern));
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001551
Douglas Gregorf4c33342010-05-28 00:22:41 +00001552 // delete [] expression
1553 Pattern = new CodeCompletionString;
1554 Pattern->AddTypedTextChunk("delete");
1555 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
1556 Pattern->AddChunk(CodeCompletionString::CK_LeftBracket);
1557 Pattern->AddChunk(CodeCompletionString::CK_RightBracket);
1558 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
1559 Pattern->AddPlaceholderChunk("expression");
1560 Results.AddResult(Result(Pattern));
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001561
Douglas Gregorf4c33342010-05-28 00:22:41 +00001562 // throw expression
1563 Pattern = new CodeCompletionString;
1564 Pattern->AddTypedTextChunk("throw");
1565 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
1566 Pattern->AddPlaceholderChunk("expression");
1567 Results.AddResult(Result(Pattern));
Douglas Gregora2db7932010-05-26 22:00:08 +00001568
1569 // FIXME: Rethrow?
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001570 }
1571
1572 if (SemaRef.getLangOptions().ObjC1) {
1573 // Add "super", if we're in an Objective-C class with a superclass.
Ted Kremenek305a0a72010-05-31 21:43:10 +00001574 if (ObjCMethodDecl *Method = SemaRef.getCurMethodDecl()) {
1575 // The interface can be NULL.
1576 if (ObjCInterfaceDecl *ID = Method->getClassInterface())
1577 if (ID->getSuperClass())
1578 Results.AddResult(Result("super"));
1579 }
1580
Douglas Gregorf98e6a22010-01-13 23:51:12 +00001581 AddObjCExpressionResults(Results, true);
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001582 }
1583
Douglas Gregorf4c33342010-05-28 00:22:41 +00001584 // sizeof expression
1585 Pattern = new CodeCompletionString;
1586 Pattern->AddTypedTextChunk("sizeof");
1587 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
1588 Pattern->AddPlaceholderChunk("expression-or-type");
1589 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
1590 Results.AddResult(Result(Pattern));
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001591 break;
1592 }
1593 }
1594
Douglas Gregor70febae2010-05-28 00:49:12 +00001595 if (WantTypesInContext(CCC, SemaRef.getLangOptions()))
1596 AddTypeSpecifierResults(SemaRef.getLangOptions(), Results);
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001597
1598 if (SemaRef.getLangOptions().CPlusPlus)
Douglas Gregor78a21012010-01-14 16:01:26 +00001599 Results.AddResult(Result("operator"));
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001600}
1601
Douglas Gregorb3fa9192009-12-18 18:53:37 +00001602/// \brief If the given declaration has an associated type, add it as a result
1603/// type chunk.
1604static void AddResultTypeChunk(ASTContext &Context,
1605 NamedDecl *ND,
1606 CodeCompletionString *Result) {
1607 if (!ND)
1608 return;
1609
1610 // Determine the type of the declaration (if it has a type).
1611 QualType T;
1612 if (FunctionDecl *Function = dyn_cast<FunctionDecl>(ND))
1613 T = Function->getResultType();
1614 else if (ObjCMethodDecl *Method = dyn_cast<ObjCMethodDecl>(ND))
1615 T = Method->getResultType();
1616 else if (FunctionTemplateDecl *FunTmpl = dyn_cast<FunctionTemplateDecl>(ND))
1617 T = FunTmpl->getTemplatedDecl()->getResultType();
1618 else if (EnumConstantDecl *Enumerator = dyn_cast<EnumConstantDecl>(ND))
1619 T = Context.getTypeDeclType(cast<TypeDecl>(Enumerator->getDeclContext()));
1620 else if (isa<UnresolvedUsingValueDecl>(ND)) {
1621 /* Do nothing: ignore unresolved using declarations*/
1622 } else if (ValueDecl *Value = dyn_cast<ValueDecl>(ND))
1623 T = Value->getType();
1624 else if (ObjCPropertyDecl *Property = dyn_cast<ObjCPropertyDecl>(ND))
1625 T = Property->getType();
1626
1627 if (T.isNull() || Context.hasSameType(T, Context.DependentTy))
1628 return;
1629
Douglas Gregorcf04b022010-04-05 21:25:31 +00001630 PrintingPolicy Policy(Context.PrintingPolicy);
1631 Policy.AnonymousTagLocations = false;
1632
Douglas Gregorb3fa9192009-12-18 18:53:37 +00001633 std::string TypeStr;
Douglas Gregorcf04b022010-04-05 21:25:31 +00001634 T.getAsStringInternal(TypeStr, Policy);
Douglas Gregorb3fa9192009-12-18 18:53:37 +00001635 Result->AddResultTypeChunk(TypeStr);
1636}
1637
Douglas Gregor3545ff42009-09-21 16:56:56 +00001638/// \brief Add function parameter chunks to the given code completion string.
1639static void AddFunctionParameterChunks(ASTContext &Context,
1640 FunctionDecl *Function,
1641 CodeCompletionString *Result) {
Douglas Gregor9eb77012009-11-07 00:00:49 +00001642 typedef CodeCompletionString::Chunk Chunk;
1643
Douglas Gregor3545ff42009-09-21 16:56:56 +00001644 CodeCompletionString *CCStr = Result;
1645
1646 for (unsigned P = 0, N = Function->getNumParams(); P != N; ++P) {
1647 ParmVarDecl *Param = Function->getParamDecl(P);
1648
1649 if (Param->hasDefaultArg()) {
1650 // When we see an optional default argument, put that argument and
1651 // the remaining default arguments into a new, optional string.
1652 CodeCompletionString *Opt = new CodeCompletionString;
1653 CCStr->AddOptionalChunk(std::auto_ptr<CodeCompletionString>(Opt));
1654 CCStr = Opt;
1655 }
1656
1657 if (P != 0)
Douglas Gregor9eb77012009-11-07 00:00:49 +00001658 CCStr->AddChunk(Chunk(CodeCompletionString::CK_Comma));
Douglas Gregor3545ff42009-09-21 16:56:56 +00001659
1660 // Format the placeholder string.
1661 std::string PlaceholderStr;
1662 if (Param->getIdentifier())
1663 PlaceholderStr = Param->getIdentifier()->getName();
1664
1665 Param->getType().getAsStringInternal(PlaceholderStr,
1666 Context.PrintingPolicy);
1667
1668 // Add the placeholder string.
Benjamin Kramerb33a97c2009-11-29 20:18:50 +00001669 CCStr->AddPlaceholderChunk(PlaceholderStr);
Douglas Gregor3545ff42009-09-21 16:56:56 +00001670 }
Douglas Gregorba449032009-09-22 21:42:17 +00001671
1672 if (const FunctionProtoType *Proto
1673 = Function->getType()->getAs<FunctionProtoType>())
1674 if (Proto->isVariadic())
1675 CCStr->AddPlaceholderChunk(", ...");
Douglas Gregor3545ff42009-09-21 16:56:56 +00001676}
1677
1678/// \brief Add template parameter chunks to the given code completion string.
1679static void AddTemplateParameterChunks(ASTContext &Context,
1680 TemplateDecl *Template,
1681 CodeCompletionString *Result,
1682 unsigned MaxParameters = 0) {
Douglas Gregor9eb77012009-11-07 00:00:49 +00001683 typedef CodeCompletionString::Chunk Chunk;
1684
Douglas Gregor3545ff42009-09-21 16:56:56 +00001685 CodeCompletionString *CCStr = Result;
1686 bool FirstParameter = true;
1687
1688 TemplateParameterList *Params = Template->getTemplateParameters();
1689 TemplateParameterList::iterator PEnd = Params->end();
1690 if (MaxParameters)
1691 PEnd = Params->begin() + MaxParameters;
1692 for (TemplateParameterList::iterator P = Params->begin(); P != PEnd; ++P) {
1693 bool HasDefaultArg = false;
1694 std::string PlaceholderStr;
1695 if (TemplateTypeParmDecl *TTP = dyn_cast<TemplateTypeParmDecl>(*P)) {
1696 if (TTP->wasDeclaredWithTypename())
1697 PlaceholderStr = "typename";
1698 else
1699 PlaceholderStr = "class";
1700
1701 if (TTP->getIdentifier()) {
1702 PlaceholderStr += ' ';
1703 PlaceholderStr += TTP->getIdentifier()->getName();
1704 }
1705
1706 HasDefaultArg = TTP->hasDefaultArgument();
1707 } else if (NonTypeTemplateParmDecl *NTTP
1708 = dyn_cast<NonTypeTemplateParmDecl>(*P)) {
1709 if (NTTP->getIdentifier())
1710 PlaceholderStr = NTTP->getIdentifier()->getName();
1711 NTTP->getType().getAsStringInternal(PlaceholderStr,
1712 Context.PrintingPolicy);
1713 HasDefaultArg = NTTP->hasDefaultArgument();
1714 } else {
1715 assert(isa<TemplateTemplateParmDecl>(*P));
1716 TemplateTemplateParmDecl *TTP = cast<TemplateTemplateParmDecl>(*P);
1717
1718 // Since putting the template argument list into the placeholder would
1719 // be very, very long, we just use an abbreviation.
1720 PlaceholderStr = "template<...> class";
1721 if (TTP->getIdentifier()) {
1722 PlaceholderStr += ' ';
1723 PlaceholderStr += TTP->getIdentifier()->getName();
1724 }
1725
1726 HasDefaultArg = TTP->hasDefaultArgument();
1727 }
1728
1729 if (HasDefaultArg) {
1730 // When we see an optional default argument, put that argument and
1731 // the remaining default arguments into a new, optional string.
1732 CodeCompletionString *Opt = new CodeCompletionString;
1733 CCStr->AddOptionalChunk(std::auto_ptr<CodeCompletionString>(Opt));
1734 CCStr = Opt;
1735 }
1736
1737 if (FirstParameter)
1738 FirstParameter = false;
1739 else
Douglas Gregor9eb77012009-11-07 00:00:49 +00001740 CCStr->AddChunk(Chunk(CodeCompletionString::CK_Comma));
Douglas Gregor3545ff42009-09-21 16:56:56 +00001741
1742 // Add the placeholder string.
Benjamin Kramerb33a97c2009-11-29 20:18:50 +00001743 CCStr->AddPlaceholderChunk(PlaceholderStr);
Douglas Gregor3545ff42009-09-21 16:56:56 +00001744 }
1745}
1746
Douglas Gregorf2510672009-09-21 19:57:38 +00001747/// \brief Add a qualifier to the given code-completion string, if the
1748/// provided nested-name-specifier is non-NULL.
Douglas Gregor0f622362009-12-11 18:44:16 +00001749static void
1750AddQualifierToCompletionString(CodeCompletionString *Result,
1751 NestedNameSpecifier *Qualifier,
1752 bool QualifierIsInformative,
1753 ASTContext &Context) {
Douglas Gregorf2510672009-09-21 19:57:38 +00001754 if (!Qualifier)
1755 return;
1756
1757 std::string PrintedNNS;
1758 {
1759 llvm::raw_string_ostream OS(PrintedNNS);
1760 Qualifier->print(OS, Context.PrintingPolicy);
1761 }
Douglas Gregor5bf52692009-09-22 23:15:58 +00001762 if (QualifierIsInformative)
Benjamin Kramerb33a97c2009-11-29 20:18:50 +00001763 Result->AddInformativeChunk(PrintedNNS);
Douglas Gregor5bf52692009-09-22 23:15:58 +00001764 else
Benjamin Kramerb33a97c2009-11-29 20:18:50 +00001765 Result->AddTextChunk(PrintedNNS);
Douglas Gregorf2510672009-09-21 19:57:38 +00001766}
1767
Douglas Gregor0f622362009-12-11 18:44:16 +00001768static void AddFunctionTypeQualsToCompletionString(CodeCompletionString *Result,
1769 FunctionDecl *Function) {
1770 const FunctionProtoType *Proto
1771 = Function->getType()->getAs<FunctionProtoType>();
1772 if (!Proto || !Proto->getTypeQuals())
1773 return;
1774
1775 std::string QualsStr;
1776 if (Proto->getTypeQuals() & Qualifiers::Const)
1777 QualsStr += " const";
1778 if (Proto->getTypeQuals() & Qualifiers::Volatile)
1779 QualsStr += " volatile";
1780 if (Proto->getTypeQuals() & Qualifiers::Restrict)
1781 QualsStr += " restrict";
1782 Result->AddInformativeChunk(QualsStr);
1783}
1784
Douglas Gregor3545ff42009-09-21 16:56:56 +00001785/// \brief If possible, create a new code completion string for the given
1786/// result.
1787///
1788/// \returns Either a new, heap-allocated code completion string describing
1789/// how to use this result, or NULL to indicate that the string or name of the
1790/// result is all that is needed.
1791CodeCompletionString *
1792CodeCompleteConsumer::Result::CreateCodeCompletionString(Sema &S) {
Douglas Gregor9eb77012009-11-07 00:00:49 +00001793 typedef CodeCompletionString::Chunk Chunk;
1794
Douglas Gregorf09935f2009-12-01 05:55:20 +00001795 if (Kind == RK_Pattern)
1796 return Pattern->Clone();
1797
1798 CodeCompletionString *Result = new CodeCompletionString;
1799
1800 if (Kind == RK_Keyword) {
1801 Result->AddTypedTextChunk(Keyword);
1802 return Result;
1803 }
Douglas Gregor3545ff42009-09-21 16:56:56 +00001804
Douglas Gregorf329c7c2009-10-30 16:50:04 +00001805 if (Kind == RK_Macro) {
1806 MacroInfo *MI = S.PP.getMacroInfo(Macro);
Douglas Gregorf09935f2009-12-01 05:55:20 +00001807 assert(MI && "Not a macro?");
1808
1809 Result->AddTypedTextChunk(Macro->getName());
1810
1811 if (!MI->isFunctionLike())
1812 return Result;
Douglas Gregorf329c7c2009-10-30 16:50:04 +00001813
1814 // Format a function-like macro with placeholders for the arguments.
Douglas Gregor9eb77012009-11-07 00:00:49 +00001815 Result->AddChunk(Chunk(CodeCompletionString::CK_LeftParen));
Douglas Gregorf329c7c2009-10-30 16:50:04 +00001816 for (MacroInfo::arg_iterator A = MI->arg_begin(), AEnd = MI->arg_end();
1817 A != AEnd; ++A) {
1818 if (A != MI->arg_begin())
Douglas Gregor9eb77012009-11-07 00:00:49 +00001819 Result->AddChunk(Chunk(CodeCompletionString::CK_Comma));
Douglas Gregorf329c7c2009-10-30 16:50:04 +00001820
1821 if (!MI->isVariadic() || A != AEnd - 1) {
1822 // Non-variadic argument.
Benjamin Kramerb33a97c2009-11-29 20:18:50 +00001823 Result->AddPlaceholderChunk((*A)->getName());
Douglas Gregorf329c7c2009-10-30 16:50:04 +00001824 continue;
1825 }
1826
1827 // Variadic argument; cope with the different between GNU and C99
1828 // variadic macros, providing a single placeholder for the rest of the
1829 // arguments.
1830 if ((*A)->isStr("__VA_ARGS__"))
1831 Result->AddPlaceholderChunk("...");
1832 else {
1833 std::string Arg = (*A)->getName();
1834 Arg += "...";
Benjamin Kramerb33a97c2009-11-29 20:18:50 +00001835 Result->AddPlaceholderChunk(Arg);
Douglas Gregorf329c7c2009-10-30 16:50:04 +00001836 }
1837 }
Douglas Gregor9eb77012009-11-07 00:00:49 +00001838 Result->AddChunk(Chunk(CodeCompletionString::CK_RightParen));
Douglas Gregorf329c7c2009-10-30 16:50:04 +00001839 return Result;
1840 }
1841
Douglas Gregorf64acca2010-05-25 21:41:55 +00001842 assert(Kind == RK_Declaration && "Missed a result kind?");
Douglas Gregor3545ff42009-09-21 16:56:56 +00001843 NamedDecl *ND = Declaration;
1844
Douglas Gregor9eb77012009-11-07 00:00:49 +00001845 if (StartsNestedNameSpecifier) {
Benjamin Kramerb33a97c2009-11-29 20:18:50 +00001846 Result->AddTypedTextChunk(ND->getNameAsString());
Douglas Gregor9eb77012009-11-07 00:00:49 +00001847 Result->AddTextChunk("::");
1848 return Result;
1849 }
1850
Douglas Gregorb3fa9192009-12-18 18:53:37 +00001851 AddResultTypeChunk(S.Context, ND, Result);
1852
Douglas Gregor3545ff42009-09-21 16:56:56 +00001853 if (FunctionDecl *Function = dyn_cast<FunctionDecl>(ND)) {
Douglas Gregor5bf52692009-09-22 23:15:58 +00001854 AddQualifierToCompletionString(Result, Qualifier, QualifierIsInformative,
1855 S.Context);
Benjamin Kramerb33a97c2009-11-29 20:18:50 +00001856 Result->AddTypedTextChunk(Function->getNameAsString());
Douglas Gregor9eb77012009-11-07 00:00:49 +00001857 Result->AddChunk(Chunk(CodeCompletionString::CK_LeftParen));
Douglas Gregor3545ff42009-09-21 16:56:56 +00001858 AddFunctionParameterChunks(S.Context, Function, Result);
Douglas Gregor9eb77012009-11-07 00:00:49 +00001859 Result->AddChunk(Chunk(CodeCompletionString::CK_RightParen));
Douglas Gregor0f622362009-12-11 18:44:16 +00001860 AddFunctionTypeQualsToCompletionString(Result, Function);
Douglas Gregor3545ff42009-09-21 16:56:56 +00001861 return Result;
1862 }
1863
1864 if (FunctionTemplateDecl *FunTmpl = dyn_cast<FunctionTemplateDecl>(ND)) {
Douglas Gregor5bf52692009-09-22 23:15:58 +00001865 AddQualifierToCompletionString(Result, Qualifier, QualifierIsInformative,
1866 S.Context);
Douglas Gregor3545ff42009-09-21 16:56:56 +00001867 FunctionDecl *Function = FunTmpl->getTemplatedDecl();
Benjamin Kramerb33a97c2009-11-29 20:18:50 +00001868 Result->AddTypedTextChunk(Function->getNameAsString());
Douglas Gregor3545ff42009-09-21 16:56:56 +00001869
1870 // Figure out which template parameters are deduced (or have default
1871 // arguments).
1872 llvm::SmallVector<bool, 16> Deduced;
1873 S.MarkDeducedTemplateParameters(FunTmpl, Deduced);
1874 unsigned LastDeducibleArgument;
1875 for (LastDeducibleArgument = Deduced.size(); LastDeducibleArgument > 0;
1876 --LastDeducibleArgument) {
1877 if (!Deduced[LastDeducibleArgument - 1]) {
1878 // C++0x: Figure out if the template argument has a default. If so,
1879 // the user doesn't need to type this argument.
1880 // FIXME: We need to abstract template parameters better!
1881 bool HasDefaultArg = false;
1882 NamedDecl *Param = FunTmpl->getTemplateParameters()->getParam(
1883 LastDeducibleArgument - 1);
1884 if (TemplateTypeParmDecl *TTP = dyn_cast<TemplateTypeParmDecl>(Param))
1885 HasDefaultArg = TTP->hasDefaultArgument();
1886 else if (NonTypeTemplateParmDecl *NTTP
1887 = dyn_cast<NonTypeTemplateParmDecl>(Param))
1888 HasDefaultArg = NTTP->hasDefaultArgument();
1889 else {
1890 assert(isa<TemplateTemplateParmDecl>(Param));
1891 HasDefaultArg
Douglas Gregor9eb77012009-11-07 00:00:49 +00001892 = cast<TemplateTemplateParmDecl>(Param)->hasDefaultArgument();
Douglas Gregor3545ff42009-09-21 16:56:56 +00001893 }
1894
1895 if (!HasDefaultArg)
1896 break;
1897 }
1898 }
1899
1900 if (LastDeducibleArgument) {
1901 // Some of the function template arguments cannot be deduced from a
1902 // function call, so we introduce an explicit template argument list
1903 // containing all of the arguments up to the first deducible argument.
Douglas Gregor9eb77012009-11-07 00:00:49 +00001904 Result->AddChunk(Chunk(CodeCompletionString::CK_LeftAngle));
Douglas Gregor3545ff42009-09-21 16:56:56 +00001905 AddTemplateParameterChunks(S.Context, FunTmpl, Result,
1906 LastDeducibleArgument);
Douglas Gregor9eb77012009-11-07 00:00:49 +00001907 Result->AddChunk(Chunk(CodeCompletionString::CK_RightAngle));
Douglas Gregor3545ff42009-09-21 16:56:56 +00001908 }
1909
1910 // Add the function parameters
Douglas Gregor9eb77012009-11-07 00:00:49 +00001911 Result->AddChunk(Chunk(CodeCompletionString::CK_LeftParen));
Douglas Gregor3545ff42009-09-21 16:56:56 +00001912 AddFunctionParameterChunks(S.Context, Function, Result);
Douglas Gregor9eb77012009-11-07 00:00:49 +00001913 Result->AddChunk(Chunk(CodeCompletionString::CK_RightParen));
Douglas Gregor0f622362009-12-11 18:44:16 +00001914 AddFunctionTypeQualsToCompletionString(Result, Function);
Douglas Gregor3545ff42009-09-21 16:56:56 +00001915 return Result;
1916 }
1917
1918 if (TemplateDecl *Template = dyn_cast<TemplateDecl>(ND)) {
Douglas Gregor5bf52692009-09-22 23:15:58 +00001919 AddQualifierToCompletionString(Result, Qualifier, QualifierIsInformative,
1920 S.Context);
Benjamin Kramerb33a97c2009-11-29 20:18:50 +00001921 Result->AddTypedTextChunk(Template->getNameAsString());
Douglas Gregor9eb77012009-11-07 00:00:49 +00001922 Result->AddChunk(Chunk(CodeCompletionString::CK_LeftAngle));
Douglas Gregor3545ff42009-09-21 16:56:56 +00001923 AddTemplateParameterChunks(S.Context, Template, Result);
Douglas Gregor9eb77012009-11-07 00:00:49 +00001924 Result->AddChunk(Chunk(CodeCompletionString::CK_RightAngle));
Douglas Gregor3545ff42009-09-21 16:56:56 +00001925 return Result;
1926 }
1927
Douglas Gregord3c5d792009-11-17 16:44:22 +00001928 if (ObjCMethodDecl *Method = dyn_cast<ObjCMethodDecl>(ND)) {
Douglas Gregord3c5d792009-11-17 16:44:22 +00001929 Selector Sel = Method->getSelector();
1930 if (Sel.isUnarySelector()) {
1931 Result->AddTypedTextChunk(Sel.getIdentifierInfoForSlot(0)->getName());
1932 return Result;
1933 }
1934
Douglas Gregor1b605f72009-11-19 01:08:35 +00001935 std::string SelName = Sel.getIdentifierInfoForSlot(0)->getName().str();
1936 SelName += ':';
1937 if (StartParameter == 0)
1938 Result->AddTypedTextChunk(SelName);
1939 else {
1940 Result->AddInformativeChunk(SelName);
1941
1942 // If there is only one parameter, and we're past it, add an empty
1943 // typed-text chunk since there is nothing to type.
1944 if (Method->param_size() == 1)
1945 Result->AddTypedTextChunk("");
1946 }
Douglas Gregord3c5d792009-11-17 16:44:22 +00001947 unsigned Idx = 0;
1948 for (ObjCMethodDecl::param_iterator P = Method->param_begin(),
1949 PEnd = Method->param_end();
1950 P != PEnd; (void)++P, ++Idx) {
1951 if (Idx > 0) {
Douglas Gregor1b605f72009-11-19 01:08:35 +00001952 std::string Keyword;
1953 if (Idx > StartParameter)
Douglas Gregor6a803932010-01-12 06:38:28 +00001954 Result->AddChunk(CodeCompletionString::CK_HorizontalSpace);
Douglas Gregord3c5d792009-11-17 16:44:22 +00001955 if (IdentifierInfo *II = Sel.getIdentifierInfoForSlot(Idx))
1956 Keyword += II->getName().str();
1957 Keyword += ":";
Douglas Gregorc8537c52009-11-19 07:41:15 +00001958 if (Idx < StartParameter || AllParametersAreInformative) {
Douglas Gregor1b605f72009-11-19 01:08:35 +00001959 Result->AddInformativeChunk(Keyword);
1960 } else if (Idx == StartParameter)
1961 Result->AddTypedTextChunk(Keyword);
1962 else
1963 Result->AddTextChunk(Keyword);
Douglas Gregord3c5d792009-11-17 16:44:22 +00001964 }
Douglas Gregor1b605f72009-11-19 01:08:35 +00001965
1966 // If we're before the starting parameter, skip the placeholder.
1967 if (Idx < StartParameter)
1968 continue;
Douglas Gregord3c5d792009-11-17 16:44:22 +00001969
1970 std::string Arg;
1971 (*P)->getType().getAsStringInternal(Arg, S.Context.PrintingPolicy);
1972 Arg = "(" + Arg + ")";
1973 if (IdentifierInfo *II = (*P)->getIdentifier())
1974 Arg += II->getName().str();
Douglas Gregorc8537c52009-11-19 07:41:15 +00001975 if (AllParametersAreInformative)
1976 Result->AddInformativeChunk(Arg);
1977 else
1978 Result->AddPlaceholderChunk(Arg);
Douglas Gregord3c5d792009-11-17 16:44:22 +00001979 }
1980
Douglas Gregor04c5f972009-12-23 00:21:46 +00001981 if (Method->isVariadic()) {
1982 if (AllParametersAreInformative)
1983 Result->AddInformativeChunk(", ...");
1984 else
1985 Result->AddPlaceholderChunk(", ...");
1986 }
1987
Douglas Gregord3c5d792009-11-17 16:44:22 +00001988 return Result;
1989 }
1990
Douglas Gregorf09935f2009-12-01 05:55:20 +00001991 if (Qualifier)
Douglas Gregor5bf52692009-09-22 23:15:58 +00001992 AddQualifierToCompletionString(Result, Qualifier, QualifierIsInformative,
1993 S.Context);
Douglas Gregorf09935f2009-12-01 05:55:20 +00001994
1995 Result->AddTypedTextChunk(ND->getNameAsString());
1996 return Result;
Douglas Gregor3545ff42009-09-21 16:56:56 +00001997}
1998
Douglas Gregorf0f51982009-09-23 00:34:09 +00001999CodeCompletionString *
2000CodeCompleteConsumer::OverloadCandidate::CreateSignatureString(
2001 unsigned CurrentArg,
2002 Sema &S) const {
Douglas Gregor9eb77012009-11-07 00:00:49 +00002003 typedef CodeCompletionString::Chunk Chunk;
2004
Douglas Gregorf0f51982009-09-23 00:34:09 +00002005 CodeCompletionString *Result = new CodeCompletionString;
2006 FunctionDecl *FDecl = getFunction();
Douglas Gregorb3fa9192009-12-18 18:53:37 +00002007 AddResultTypeChunk(S.Context, FDecl, Result);
Douglas Gregorf0f51982009-09-23 00:34:09 +00002008 const FunctionProtoType *Proto
2009 = dyn_cast<FunctionProtoType>(getFunctionType());
2010 if (!FDecl && !Proto) {
2011 // Function without a prototype. Just give the return type and a
2012 // highlighted ellipsis.
2013 const FunctionType *FT = getFunctionType();
2014 Result->AddTextChunk(
Benjamin Kramerb33a97c2009-11-29 20:18:50 +00002015 FT->getResultType().getAsString(S.Context.PrintingPolicy));
Douglas Gregor9eb77012009-11-07 00:00:49 +00002016 Result->AddChunk(Chunk(CodeCompletionString::CK_LeftParen));
2017 Result->AddChunk(Chunk(CodeCompletionString::CK_CurrentParameter, "..."));
2018 Result->AddChunk(Chunk(CodeCompletionString::CK_RightParen));
Douglas Gregorf0f51982009-09-23 00:34:09 +00002019 return Result;
2020 }
2021
2022 if (FDecl)
Benjamin Kramerb33a97c2009-11-29 20:18:50 +00002023 Result->AddTextChunk(FDecl->getNameAsString());
Douglas Gregorf0f51982009-09-23 00:34:09 +00002024 else
2025 Result->AddTextChunk(
Benjamin Kramerb33a97c2009-11-29 20:18:50 +00002026 Proto->getResultType().getAsString(S.Context.PrintingPolicy));
Douglas Gregorf0f51982009-09-23 00:34:09 +00002027
Douglas Gregor9eb77012009-11-07 00:00:49 +00002028 Result->AddChunk(Chunk(CodeCompletionString::CK_LeftParen));
Douglas Gregorf0f51982009-09-23 00:34:09 +00002029 unsigned NumParams = FDecl? FDecl->getNumParams() : Proto->getNumArgs();
2030 for (unsigned I = 0; I != NumParams; ++I) {
2031 if (I)
Douglas Gregor9eb77012009-11-07 00:00:49 +00002032 Result->AddChunk(Chunk(CodeCompletionString::CK_Comma));
Douglas Gregorf0f51982009-09-23 00:34:09 +00002033
2034 std::string ArgString;
2035 QualType ArgType;
2036
2037 if (FDecl) {
2038 ArgString = FDecl->getParamDecl(I)->getNameAsString();
2039 ArgType = FDecl->getParamDecl(I)->getOriginalType();
2040 } else {
2041 ArgType = Proto->getArgType(I);
2042 }
2043
2044 ArgType.getAsStringInternal(ArgString, S.Context.PrintingPolicy);
2045
2046 if (I == CurrentArg)
Douglas Gregor9eb77012009-11-07 00:00:49 +00002047 Result->AddChunk(Chunk(CodeCompletionString::CK_CurrentParameter,
Benjamin Kramerb33a97c2009-11-29 20:18:50 +00002048 ArgString));
Douglas Gregorf0f51982009-09-23 00:34:09 +00002049 else
Benjamin Kramerb33a97c2009-11-29 20:18:50 +00002050 Result->AddTextChunk(ArgString);
Douglas Gregorf0f51982009-09-23 00:34:09 +00002051 }
2052
2053 if (Proto && Proto->isVariadic()) {
Douglas Gregor9eb77012009-11-07 00:00:49 +00002054 Result->AddChunk(Chunk(CodeCompletionString::CK_Comma));
Douglas Gregorf0f51982009-09-23 00:34:09 +00002055 if (CurrentArg < NumParams)
2056 Result->AddTextChunk("...");
2057 else
Douglas Gregor9eb77012009-11-07 00:00:49 +00002058 Result->AddChunk(Chunk(CodeCompletionString::CK_CurrentParameter, "..."));
Douglas Gregorf0f51982009-09-23 00:34:09 +00002059 }
Douglas Gregor9eb77012009-11-07 00:00:49 +00002060 Result->AddChunk(Chunk(CodeCompletionString::CK_RightParen));
Douglas Gregorf0f51982009-09-23 00:34:09 +00002061
2062 return Result;
2063}
2064
Douglas Gregor3545ff42009-09-21 16:56:56 +00002065namespace {
2066 struct SortCodeCompleteResult {
2067 typedef CodeCompleteConsumer::Result Result;
2068
Douglas Gregore6688e62009-09-28 03:51:44 +00002069 bool isEarlierDeclarationName(DeclarationName X, DeclarationName Y) const {
Douglas Gregor249d6822009-12-05 09:08:56 +00002070 Selector XSel = X.getObjCSelector();
2071 Selector YSel = Y.getObjCSelector();
2072 if (!XSel.isNull() && !YSel.isNull()) {
2073 // We are comparing two selectors.
2074 unsigned N = std::min(XSel.getNumArgs(), YSel.getNumArgs());
2075 if (N == 0)
2076 ++N;
2077 for (unsigned I = 0; I != N; ++I) {
2078 IdentifierInfo *XId = XSel.getIdentifierInfoForSlot(I);
2079 IdentifierInfo *YId = YSel.getIdentifierInfoForSlot(I);
2080 if (!XId || !YId)
2081 return XId && !YId;
2082
2083 switch (XId->getName().compare_lower(YId->getName())) {
2084 case -1: return true;
2085 case 1: return false;
2086 default: break;
2087 }
2088 }
2089
2090 return XSel.getNumArgs() < YSel.getNumArgs();
2091 }
2092
2093 // For non-selectors, order by kind.
2094 if (X.getNameKind() != Y.getNameKind())
Douglas Gregore6688e62009-09-28 03:51:44 +00002095 return X.getNameKind() < Y.getNameKind();
2096
Douglas Gregor249d6822009-12-05 09:08:56 +00002097 // Order identifiers by comparison of their lowercased names.
2098 if (IdentifierInfo *XId = X.getAsIdentifierInfo())
2099 return XId->getName().compare_lower(
2100 Y.getAsIdentifierInfo()->getName()) < 0;
2101
2102 // Order overloaded operators by the order in which they appear
2103 // in our list of operators.
2104 if (OverloadedOperatorKind XOp = X.getCXXOverloadedOperator())
2105 return XOp < Y.getCXXOverloadedOperator();
2106
2107 // Order C++0x user-defined literal operators lexically by their
2108 // lowercased suffixes.
2109 if (IdentifierInfo *XLit = X.getCXXLiteralIdentifier())
2110 return XLit->getName().compare_lower(
2111 Y.getCXXLiteralIdentifier()->getName()) < 0;
2112
2113 // The only stable ordering we have is to turn the name into a
2114 // string and then compare the lower-case strings. This is
2115 // inefficient, but thankfully does not happen too often.
Benjamin Kramer4053e5d2009-12-05 10:22:15 +00002116 return llvm::StringRef(X.getAsString()).compare_lower(
2117 Y.getAsString()) < 0;
Douglas Gregore6688e62009-09-28 03:51:44 +00002118 }
2119
Douglas Gregor52ce62f2010-01-13 23:24:38 +00002120 /// \brief Retrieve the name that should be used to order a result.
2121 ///
2122 /// If the name needs to be constructed as a string, that string will be
2123 /// saved into Saved and the returned StringRef will refer to it.
2124 static llvm::StringRef getOrderedName(const Result &R,
2125 std::string &Saved) {
2126 switch (R.Kind) {
2127 case Result::RK_Keyword:
2128 return R.Keyword;
2129
2130 case Result::RK_Pattern:
2131 return R.Pattern->getTypedText();
2132
2133 case Result::RK_Macro:
2134 return R.Macro->getName();
2135
2136 case Result::RK_Declaration:
2137 // Handle declarations below.
2138 break;
Douglas Gregor45f83ee2009-11-19 00:01:57 +00002139 }
Douglas Gregor52ce62f2010-01-13 23:24:38 +00002140
2141 DeclarationName Name = R.Declaration->getDeclName();
Douglas Gregor45f83ee2009-11-19 00:01:57 +00002142
Douglas Gregor52ce62f2010-01-13 23:24:38 +00002143 // If the name is a simple identifier (by far the common case), or a
2144 // zero-argument selector, just return a reference to that identifier.
2145 if (IdentifierInfo *Id = Name.getAsIdentifierInfo())
2146 return Id->getName();
2147 if (Name.isObjCZeroArgSelector())
2148 if (IdentifierInfo *Id
2149 = Name.getObjCSelector().getIdentifierInfoForSlot(0))
2150 return Id->getName();
2151
2152 Saved = Name.getAsString();
2153 return Saved;
2154 }
2155
2156 bool operator()(const Result &X, const Result &Y) const {
2157 std::string XSaved, YSaved;
2158 llvm::StringRef XStr = getOrderedName(X, XSaved);
2159 llvm::StringRef YStr = getOrderedName(Y, YSaved);
2160 int cmp = XStr.compare_lower(YStr);
2161 if (cmp)
2162 return cmp < 0;
Douglas Gregor3545ff42009-09-21 16:56:56 +00002163
2164 // Non-hidden names precede hidden names.
2165 if (X.Hidden != Y.Hidden)
2166 return !X.Hidden;
2167
Douglas Gregore412a5a2009-09-23 22:26:46 +00002168 // Non-nested-name-specifiers precede nested-name-specifiers.
2169 if (X.StartsNestedNameSpecifier != Y.StartsNestedNameSpecifier)
2170 return !X.StartsNestedNameSpecifier;
2171
Douglas Gregor3545ff42009-09-21 16:56:56 +00002172 return false;
2173 }
2174 };
2175}
2176
Douglas Gregor55b037b2010-07-08 20:55:51 +00002177static void AddMacroResults(Preprocessor &PP, ResultBuilder &Results,
2178 bool TargetTypeIsPointer = false) {
2179 typedef CodeCompleteConsumer::Result Result;
2180
Douglas Gregorf329c7c2009-10-30 16:50:04 +00002181 Results.EnterNewScope();
Douglas Gregor9eb77012009-11-07 00:00:49 +00002182 for (Preprocessor::macro_iterator M = PP.macro_begin(),
2183 MEnd = PP.macro_end();
Douglas Gregor55b037b2010-07-08 20:55:51 +00002184 M != MEnd; ++M) {
2185 unsigned Priority = CCP_Macro;
2186
2187 // Treat the "nil" and "NULL" macros as null pointer constants.
2188 if (M->first->isStr("nil") || M->first->isStr("NULL")) {
2189 Priority = CCP_Constant;
2190 if (TargetTypeIsPointer)
2191 Priority = Priority / CCF_SimilarTypeMatch;
2192 }
2193
2194 Results.AddResult(Result(M->first, Priority));
2195 }
Douglas Gregorf329c7c2009-10-30 16:50:04 +00002196 Results.ExitScope();
2197}
2198
Daniel Dunbar242ea9a2009-11-13 08:58:20 +00002199static void HandleCodeCompleteResults(Sema *S,
2200 CodeCompleteConsumer *CodeCompleter,
2201 CodeCompleteConsumer::Result *Results,
2202 unsigned NumResults) {
Douglas Gregor3545ff42009-09-21 16:56:56 +00002203 std::stable_sort(Results, Results + NumResults, SortCodeCompleteResult());
2204
2205 if (CodeCompleter)
Daniel Dunbar242ea9a2009-11-13 08:58:20 +00002206 CodeCompleter->ProcessCodeCompleteResults(*S, Results, NumResults);
Douglas Gregor45f83ee2009-11-19 00:01:57 +00002207
2208 for (unsigned I = 0; I != NumResults; ++I)
2209 Results[I].Destroy();
Douglas Gregor3545ff42009-09-21 16:56:56 +00002210}
2211
Douglas Gregor504a6ae2010-01-10 23:08:15 +00002212void Sema::CodeCompleteOrdinaryName(Scope *S,
2213 CodeCompletionContext CompletionContext) {
Douglas Gregor92253692009-12-07 09:54:55 +00002214 typedef CodeCompleteConsumer::Result Result;
Douglas Gregor504a6ae2010-01-10 23:08:15 +00002215 ResultBuilder Results(*this);
2216
2217 // Determine how to filter results, e.g., so that the names of
2218 // values (functions, enumerators, function templates, etc.) are
2219 // only allowed where we can have an expression.
2220 switch (CompletionContext) {
2221 case CCC_Namespace:
2222 case CCC_Class:
Douglas Gregorf1934162010-01-13 21:24:21 +00002223 case CCC_ObjCInterface:
2224 case CCC_ObjCImplementation:
Douglas Gregor48d46252010-01-13 21:54:15 +00002225 case CCC_ObjCInstanceVariableList:
Douglas Gregor504a6ae2010-01-10 23:08:15 +00002226 case CCC_Template:
2227 case CCC_MemberTemplate:
2228 Results.setFilter(&ResultBuilder::IsOrdinaryNonValueName);
2229 break;
2230
2231 case CCC_Expression:
2232 case CCC_Statement:
2233 case CCC_ForInit:
2234 case CCC_Condition:
Douglas Gregor70febae2010-05-28 00:49:12 +00002235 if (WantTypesInContext(CompletionContext, getLangOptions()))
2236 Results.setFilter(&ResultBuilder::IsOrdinaryName);
2237 else
2238 Results.setFilter(&ResultBuilder::IsOrdinaryNonTypeName);
Douglas Gregor504a6ae2010-01-10 23:08:15 +00002239 break;
Douglas Gregor6da3db42010-05-25 05:58:43 +00002240
2241 case CCC_RecoveryInFunction:
2242 // Unfiltered
2243 break;
Douglas Gregor504a6ae2010-01-10 23:08:15 +00002244 }
2245
Douglas Gregorc580c522010-01-14 01:09:38 +00002246 CodeCompletionDeclConsumer Consumer(Results, CurContext);
2247 LookupVisibleDecls(S, LookupOrdinaryName, Consumer);
Douglas Gregor92253692009-12-07 09:54:55 +00002248
2249 Results.EnterNewScope();
Douglas Gregorf98e6a22010-01-13 23:51:12 +00002250 AddOrdinaryNameResults(CompletionContext, S, *this, Results);
Douglas Gregor92253692009-12-07 09:54:55 +00002251 Results.ExitScope();
2252
Douglas Gregor9eb77012009-11-07 00:00:49 +00002253 if (CodeCompleter->includeMacros())
Douglas Gregorf98e6a22010-01-13 23:51:12 +00002254 AddMacroResults(PP, Results);
Daniel Dunbar242ea9a2009-11-13 08:58:20 +00002255 HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
Douglas Gregor9d64c5e2009-09-21 20:51:25 +00002256}
2257
Douglas Gregor7aa6b222010-05-30 01:49:25 +00002258/// \brief Perform code-completion in an expression context when we know what
2259/// type we're looking for.
2260void Sema::CodeCompleteExpression(Scope *S, QualType T) {
2261 typedef CodeCompleteConsumer::Result Result;
2262 ResultBuilder Results(*this);
2263
2264 if (WantTypesInContext(CCC_Expression, getLangOptions()))
2265 Results.setFilter(&ResultBuilder::IsOrdinaryName);
2266 else
2267 Results.setFilter(&ResultBuilder::IsOrdinaryNonTypeName);
2268 Results.setPreferredType(T.getNonReferenceType());
2269
2270 CodeCompletionDeclConsumer Consumer(Results, CurContext);
2271 LookupVisibleDecls(S, LookupOrdinaryName, Consumer);
2272
2273 Results.EnterNewScope();
2274 AddOrdinaryNameResults(CCC_Expression, S, *this, Results);
2275 Results.ExitScope();
2276
Douglas Gregor55b037b2010-07-08 20:55:51 +00002277 bool PreferredTypeIsPointer = false;
2278 if (!T.isNull())
2279 PreferredTypeIsPointer = T->isAnyPointerType() ||
2280 T->isMemberPointerType() || T->isBlockPointerType();
2281
Douglas Gregor7aa6b222010-05-30 01:49:25 +00002282 if (CodeCompleter->includeMacros())
Douglas Gregor55b037b2010-07-08 20:55:51 +00002283 AddMacroResults(PP, Results, PreferredTypeIsPointer);
Douglas Gregor7aa6b222010-05-30 01:49:25 +00002284 HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
2285}
2286
2287
Douglas Gregor9291bad2009-11-18 01:29:26 +00002288static void AddObjCProperties(ObjCContainerDecl *Container,
Douglas Gregor5d649882009-11-18 22:32:06 +00002289 bool AllowCategories,
Douglas Gregor9291bad2009-11-18 01:29:26 +00002290 DeclContext *CurContext,
2291 ResultBuilder &Results) {
2292 typedef CodeCompleteConsumer::Result Result;
2293
2294 // Add properties in this container.
2295 for (ObjCContainerDecl::prop_iterator P = Container->prop_begin(),
2296 PEnd = Container->prop_end();
2297 P != PEnd;
2298 ++P)
2299 Results.MaybeAddResult(Result(*P, 0), CurContext);
2300
2301 // Add properties in referenced protocols.
2302 if (ObjCProtocolDecl *Protocol = dyn_cast<ObjCProtocolDecl>(Container)) {
2303 for (ObjCProtocolDecl::protocol_iterator P = Protocol->protocol_begin(),
2304 PEnd = Protocol->protocol_end();
2305 P != PEnd; ++P)
Douglas Gregor5d649882009-11-18 22:32:06 +00002306 AddObjCProperties(*P, AllowCategories, CurContext, Results);
Douglas Gregor9291bad2009-11-18 01:29:26 +00002307 } else if (ObjCInterfaceDecl *IFace = dyn_cast<ObjCInterfaceDecl>(Container)){
Douglas Gregor5d649882009-11-18 22:32:06 +00002308 if (AllowCategories) {
2309 // Look through categories.
2310 for (ObjCCategoryDecl *Category = IFace->getCategoryList();
2311 Category; Category = Category->getNextClassCategory())
2312 AddObjCProperties(Category, AllowCategories, CurContext, Results);
2313 }
Douglas Gregor9291bad2009-11-18 01:29:26 +00002314
2315 // Look through protocols.
2316 for (ObjCInterfaceDecl::protocol_iterator I = IFace->protocol_begin(),
2317 E = IFace->protocol_end();
2318 I != E; ++I)
Douglas Gregor5d649882009-11-18 22:32:06 +00002319 AddObjCProperties(*I, AllowCategories, CurContext, Results);
Douglas Gregor9291bad2009-11-18 01:29:26 +00002320
2321 // Look in the superclass.
2322 if (IFace->getSuperClass())
Douglas Gregor5d649882009-11-18 22:32:06 +00002323 AddObjCProperties(IFace->getSuperClass(), AllowCategories, CurContext,
2324 Results);
Douglas Gregor9291bad2009-11-18 01:29:26 +00002325 } else if (const ObjCCategoryDecl *Category
2326 = dyn_cast<ObjCCategoryDecl>(Container)) {
2327 // Look through protocols.
2328 for (ObjCInterfaceDecl::protocol_iterator P = Category->protocol_begin(),
2329 PEnd = Category->protocol_end();
2330 P != PEnd; ++P)
Douglas Gregor5d649882009-11-18 22:32:06 +00002331 AddObjCProperties(*P, AllowCategories, CurContext, Results);
Douglas Gregor9291bad2009-11-18 01:29:26 +00002332 }
2333}
2334
Douglas Gregor2436e712009-09-17 21:32:03 +00002335void Sema::CodeCompleteMemberReferenceExpr(Scope *S, ExprTy *BaseE,
2336 SourceLocation OpLoc,
2337 bool IsArrow) {
2338 if (!BaseE || !CodeCompleter)
2339 return;
2340
Douglas Gregor3545ff42009-09-21 16:56:56 +00002341 typedef CodeCompleteConsumer::Result Result;
2342
Douglas Gregor2436e712009-09-17 21:32:03 +00002343 Expr *Base = static_cast<Expr *>(BaseE);
2344 QualType BaseType = Base->getType();
Douglas Gregor3545ff42009-09-21 16:56:56 +00002345
2346 if (IsArrow) {
2347 if (const PointerType *Ptr = BaseType->getAs<PointerType>())
2348 BaseType = Ptr->getPointeeType();
2349 else if (BaseType->isObjCObjectPointerType())
2350 /*Do nothing*/ ;
2351 else
2352 return;
2353 }
2354
Douglas Gregore412a5a2009-09-23 22:26:46 +00002355 ResultBuilder Results(*this, &ResultBuilder::IsMember);
Douglas Gregor9291bad2009-11-18 01:29:26 +00002356 Results.EnterNewScope();
2357 if (const RecordType *Record = BaseType->getAs<RecordType>()) {
2358 // Access to a C/C++ class, struct, or union.
Douglas Gregor6ae4c522010-01-14 03:21:49 +00002359 Results.allowNestedNameSpecifiers();
Douglas Gregor09bbc652010-01-14 15:47:35 +00002360 CodeCompletionDeclConsumer Consumer(Results, CurContext);
2361 LookupVisibleDecls(Record->getDecl(), LookupMemberName, Consumer);
Daniel Dunbar242ea9a2009-11-13 08:58:20 +00002362
Douglas Gregor9291bad2009-11-18 01:29:26 +00002363 if (getLangOptions().CPlusPlus) {
2364 if (!Results.empty()) {
2365 // The "template" keyword can follow "->" or "." in the grammar.
2366 // However, we only want to suggest the template keyword if something
2367 // is dependent.
2368 bool IsDependent = BaseType->isDependentType();
2369 if (!IsDependent) {
2370 for (Scope *DepScope = S; DepScope; DepScope = DepScope->getParent())
2371 if (DeclContext *Ctx = (DeclContext *)DepScope->getEntity()) {
2372 IsDependent = Ctx->isDependentContext();
2373 break;
2374 }
2375 }
Daniel Dunbar242ea9a2009-11-13 08:58:20 +00002376
Douglas Gregor9291bad2009-11-18 01:29:26 +00002377 if (IsDependent)
Douglas Gregor78a21012010-01-14 16:01:26 +00002378 Results.AddResult(Result("template"));
Daniel Dunbar242ea9a2009-11-13 08:58:20 +00002379 }
Daniel Dunbar242ea9a2009-11-13 08:58:20 +00002380 }
Douglas Gregor9291bad2009-11-18 01:29:26 +00002381 } else if (!IsArrow && BaseType->getAsObjCInterfacePointerType()) {
2382 // Objective-C property reference.
2383
2384 // Add property results based on our interface.
2385 const ObjCObjectPointerType *ObjCPtr
2386 = BaseType->getAsObjCInterfacePointerType();
2387 assert(ObjCPtr && "Non-NULL pointer guaranteed above!");
Douglas Gregor5d649882009-11-18 22:32:06 +00002388 AddObjCProperties(ObjCPtr->getInterfaceDecl(), true, CurContext, Results);
Douglas Gregor9291bad2009-11-18 01:29:26 +00002389
2390 // Add properties from the protocols in a qualified interface.
2391 for (ObjCObjectPointerType::qual_iterator I = ObjCPtr->qual_begin(),
2392 E = ObjCPtr->qual_end();
2393 I != E; ++I)
Douglas Gregor5d649882009-11-18 22:32:06 +00002394 AddObjCProperties(*I, true, CurContext, Results);
Douglas Gregor9291bad2009-11-18 01:29:26 +00002395 } else if ((IsArrow && BaseType->isObjCObjectPointerType()) ||
John McCall8b07ec22010-05-15 11:32:37 +00002396 (!IsArrow && BaseType->isObjCObjectType())) {
Douglas Gregor9291bad2009-11-18 01:29:26 +00002397 // Objective-C instance variable access.
2398 ObjCInterfaceDecl *Class = 0;
2399 if (const ObjCObjectPointerType *ObjCPtr
2400 = BaseType->getAs<ObjCObjectPointerType>())
2401 Class = ObjCPtr->getInterfaceDecl();
2402 else
John McCall8b07ec22010-05-15 11:32:37 +00002403 Class = BaseType->getAs<ObjCObjectType>()->getInterface();
Douglas Gregor9291bad2009-11-18 01:29:26 +00002404
2405 // Add all ivars from this class and its superclasses.
Douglas Gregor2b8162b2010-01-14 16:08:12 +00002406 if (Class) {
2407 CodeCompletionDeclConsumer Consumer(Results, CurContext);
2408 Results.setFilter(&ResultBuilder::IsObjCIvar);
2409 LookupVisibleDecls(Class, LookupMemberName, Consumer);
Douglas Gregor9291bad2009-11-18 01:29:26 +00002410 }
Douglas Gregor3545ff42009-09-21 16:56:56 +00002411 }
Douglas Gregor9291bad2009-11-18 01:29:26 +00002412
2413 // FIXME: How do we cope with isa?
2414
2415 Results.ExitScope();
Daniel Dunbar242ea9a2009-11-13 08:58:20 +00002416
Daniel Dunbar242ea9a2009-11-13 08:58:20 +00002417 // Hand off the results found for code completion.
2418 HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
Douglas Gregor2436e712009-09-17 21:32:03 +00002419}
2420
Douglas Gregorf45b0cf2009-09-18 15:37:17 +00002421void Sema::CodeCompleteTag(Scope *S, unsigned TagSpec) {
2422 if (!CodeCompleter)
2423 return;
2424
Douglas Gregor3545ff42009-09-21 16:56:56 +00002425 typedef CodeCompleteConsumer::Result Result;
2426 ResultBuilder::LookupFilter Filter = 0;
Douglas Gregorf45b0cf2009-09-18 15:37:17 +00002427 switch ((DeclSpec::TST)TagSpec) {
2428 case DeclSpec::TST_enum:
Douglas Gregor3545ff42009-09-21 16:56:56 +00002429 Filter = &ResultBuilder::IsEnum;
Douglas Gregorf45b0cf2009-09-18 15:37:17 +00002430 break;
2431
2432 case DeclSpec::TST_union:
Douglas Gregor3545ff42009-09-21 16:56:56 +00002433 Filter = &ResultBuilder::IsUnion;
Douglas Gregorf45b0cf2009-09-18 15:37:17 +00002434 break;
2435
2436 case DeclSpec::TST_struct:
Douglas Gregorf45b0cf2009-09-18 15:37:17 +00002437 case DeclSpec::TST_class:
Douglas Gregor3545ff42009-09-21 16:56:56 +00002438 Filter = &ResultBuilder::IsClassOrStruct;
Douglas Gregorf45b0cf2009-09-18 15:37:17 +00002439 break;
2440
2441 default:
2442 assert(false && "Unknown type specifier kind in CodeCompleteTag");
2443 return;
2444 }
Douglas Gregor3545ff42009-09-21 16:56:56 +00002445
John McCalle87beb22010-04-23 18:46:30 +00002446 ResultBuilder Results(*this);
Douglas Gregora6e2edc2010-01-14 03:27:13 +00002447 CodeCompletionDeclConsumer Consumer(Results, CurContext);
John McCalle87beb22010-04-23 18:46:30 +00002448
2449 // First pass: look for tags.
2450 Results.setFilter(Filter);
Douglas Gregora6e2edc2010-01-14 03:27:13 +00002451 LookupVisibleDecls(S, LookupTagName, Consumer);
John McCalle87beb22010-04-23 18:46:30 +00002452
2453 // Second pass: look for nested name specifiers.
2454 Results.setFilter(&ResultBuilder::IsNestedNameSpecifier);
2455 LookupVisibleDecls(S, LookupNestedNameSpecifierName, Consumer);
Douglas Gregor3545ff42009-09-21 16:56:56 +00002456
Daniel Dunbar242ea9a2009-11-13 08:58:20 +00002457 HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
Douglas Gregorf45b0cf2009-09-18 15:37:17 +00002458}
2459
Douglas Gregord328d572009-09-21 18:10:23 +00002460void Sema::CodeCompleteCase(Scope *S) {
2461 if (getSwitchStack().empty() || !CodeCompleter)
2462 return;
2463
2464 SwitchStmt *Switch = getSwitchStack().back();
2465 if (!Switch->getCond()->getType()->isEnumeralType())
2466 return;
2467
2468 // Code-complete the cases of a switch statement over an enumeration type
2469 // by providing the list of
2470 EnumDecl *Enum = Switch->getCond()->getType()->getAs<EnumType>()->getDecl();
2471
2472 // Determine which enumerators we have already seen in the switch statement.
2473 // FIXME: Ideally, we would also be able to look *past* the code-completion
2474 // token, in case we are code-completing in the middle of the switch and not
2475 // at the end. However, we aren't able to do so at the moment.
2476 llvm::SmallPtrSet<EnumConstantDecl *, 8> EnumeratorsSeen;
Douglas Gregorf2510672009-09-21 19:57:38 +00002477 NestedNameSpecifier *Qualifier = 0;
Douglas Gregord328d572009-09-21 18:10:23 +00002478 for (SwitchCase *SC = Switch->getSwitchCaseList(); SC;
2479 SC = SC->getNextSwitchCase()) {
2480 CaseStmt *Case = dyn_cast<CaseStmt>(SC);
2481 if (!Case)
2482 continue;
2483
2484 Expr *CaseVal = Case->getLHS()->IgnoreParenCasts();
2485 if (DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(CaseVal))
2486 if (EnumConstantDecl *Enumerator
2487 = dyn_cast<EnumConstantDecl>(DRE->getDecl())) {
2488 // We look into the AST of the case statement to determine which
2489 // enumerator was named. Alternatively, we could compute the value of
2490 // the integral constant expression, then compare it against the
2491 // values of each enumerator. However, value-based approach would not
2492 // work as well with C++ templates where enumerators declared within a
2493 // template are type- and value-dependent.
2494 EnumeratorsSeen.insert(Enumerator);
2495
Douglas Gregorf2510672009-09-21 19:57:38 +00002496 // If this is a qualified-id, keep track of the nested-name-specifier
2497 // so that we can reproduce it as part of code completion, e.g.,
Douglas Gregord328d572009-09-21 18:10:23 +00002498 //
2499 // switch (TagD.getKind()) {
2500 // case TagDecl::TK_enum:
2501 // break;
2502 // case XXX
2503 //
Douglas Gregorf2510672009-09-21 19:57:38 +00002504 // At the XXX, our completions are TagDecl::TK_union,
Douglas Gregord328d572009-09-21 18:10:23 +00002505 // TagDecl::TK_struct, and TagDecl::TK_class, rather than TK_union,
2506 // TK_struct, and TK_class.
Douglas Gregor4bd90e52009-10-23 18:54:35 +00002507 Qualifier = DRE->getQualifier();
Douglas Gregord328d572009-09-21 18:10:23 +00002508 }
2509 }
2510
Douglas Gregorf2510672009-09-21 19:57:38 +00002511 if (getLangOptions().CPlusPlus && !Qualifier && EnumeratorsSeen.empty()) {
2512 // If there are no prior enumerators in C++, check whether we have to
2513 // qualify the names of the enumerators that we suggest, because they
2514 // may not be visible in this scope.
2515 Qualifier = getRequiredQualification(Context, CurContext,
2516 Enum->getDeclContext());
2517
2518 // FIXME: Scoped enums need to start with "EnumDecl" as the context!
2519 }
2520
Douglas Gregord328d572009-09-21 18:10:23 +00002521 // Add any enumerators that have not yet been mentioned.
2522 ResultBuilder Results(*this);
2523 Results.EnterNewScope();
2524 for (EnumDecl::enumerator_iterator E = Enum->enumerator_begin(),
2525 EEnd = Enum->enumerator_end();
2526 E != EEnd; ++E) {
2527 if (EnumeratorsSeen.count(*E))
2528 continue;
2529
Douglas Gregorfc59ce12010-01-14 16:14:35 +00002530 Results.AddResult(CodeCompleteConsumer::Result(*E, Qualifier),
2531 CurContext, 0, false);
Douglas Gregord328d572009-09-21 18:10:23 +00002532 }
2533 Results.ExitScope();
Douglas Gregor285560922010-04-06 20:02:15 +00002534
Douglas Gregor9eb77012009-11-07 00:00:49 +00002535 if (CodeCompleter->includeMacros())
Douglas Gregorf98e6a22010-01-13 23:51:12 +00002536 AddMacroResults(PP, Results);
Daniel Dunbar242ea9a2009-11-13 08:58:20 +00002537 HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
Douglas Gregord328d572009-09-21 18:10:23 +00002538}
2539
Douglas Gregorcabea402009-09-22 15:41:20 +00002540namespace {
2541 struct IsBetterOverloadCandidate {
2542 Sema &S;
John McCallbc077cf2010-02-08 23:07:23 +00002543 SourceLocation Loc;
Douglas Gregorcabea402009-09-22 15:41:20 +00002544
2545 public:
John McCallbc077cf2010-02-08 23:07:23 +00002546 explicit IsBetterOverloadCandidate(Sema &S, SourceLocation Loc)
2547 : S(S), Loc(Loc) { }
Douglas Gregorcabea402009-09-22 15:41:20 +00002548
2549 bool
2550 operator()(const OverloadCandidate &X, const OverloadCandidate &Y) const {
John McCallbc077cf2010-02-08 23:07:23 +00002551 return S.isBetterOverloadCandidate(X, Y, Loc);
Douglas Gregorcabea402009-09-22 15:41:20 +00002552 }
2553 };
2554}
2555
Douglas Gregor6ed3eb82010-05-30 06:10:08 +00002556static bool anyNullArguments(Expr **Args, unsigned NumArgs) {
2557 if (NumArgs && !Args)
2558 return true;
2559
2560 for (unsigned I = 0; I != NumArgs; ++I)
2561 if (!Args[I])
2562 return true;
2563
2564 return false;
2565}
2566
Douglas Gregorcabea402009-09-22 15:41:20 +00002567void Sema::CodeCompleteCall(Scope *S, ExprTy *FnIn,
2568 ExprTy **ArgsIn, unsigned NumArgs) {
2569 if (!CodeCompleter)
2570 return;
Douglas Gregor3ef59522009-12-11 19:06:04 +00002571
2572 // When we're code-completing for a call, we fall back to ordinary
2573 // name code-completion whenever we can't produce specific
2574 // results. We may want to revisit this strategy in the future,
2575 // e.g., by merging the two kinds of results.
2576
Douglas Gregorcabea402009-09-22 15:41:20 +00002577 Expr *Fn = (Expr *)FnIn;
2578 Expr **Args = (Expr **)ArgsIn;
Douglas Gregor3ef59522009-12-11 19:06:04 +00002579
Douglas Gregorcabea402009-09-22 15:41:20 +00002580 // Ignore type-dependent call expressions entirely.
Douglas Gregor6ed3eb82010-05-30 06:10:08 +00002581 if (!Fn || Fn->isTypeDependent() || anyNullArguments(Args, NumArgs) ||
Douglas Gregor3ef59522009-12-11 19:06:04 +00002582 Expr::hasAnyTypeDependentArguments(Args, NumArgs)) {
Douglas Gregor504a6ae2010-01-10 23:08:15 +00002583 CodeCompleteOrdinaryName(S, CCC_Expression);
Douglas Gregorcabea402009-09-22 15:41:20 +00002584 return;
Douglas Gregor3ef59522009-12-11 19:06:04 +00002585 }
Douglas Gregorcabea402009-09-22 15:41:20 +00002586
John McCall57500772009-12-16 12:17:52 +00002587 // Build an overload candidate set based on the functions we find.
John McCallbc077cf2010-02-08 23:07:23 +00002588 SourceLocation Loc = Fn->getExprLoc();
2589 OverloadCandidateSet CandidateSet(Loc);
John McCall57500772009-12-16 12:17:52 +00002590
Douglas Gregorcabea402009-09-22 15:41:20 +00002591 // FIXME: What if we're calling something that isn't a function declaration?
2592 // FIXME: What if we're calling a pseudo-destructor?
2593 // FIXME: What if we're calling a member function?
2594
Douglas Gregorff59f672010-01-21 15:46:19 +00002595 typedef CodeCompleteConsumer::OverloadCandidate ResultCandidate;
2596 llvm::SmallVector<ResultCandidate, 8> Results;
2597
John McCall57500772009-12-16 12:17:52 +00002598 Expr *NakedFn = Fn->IgnoreParenCasts();
2599 if (UnresolvedLookupExpr *ULE = dyn_cast<UnresolvedLookupExpr>(NakedFn))
2600 AddOverloadedCallCandidates(ULE, Args, NumArgs, CandidateSet,
2601 /*PartialOverloading=*/ true);
2602 else if (DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(NakedFn)) {
2603 FunctionDecl *FDecl = dyn_cast<FunctionDecl>(DRE->getDecl());
Douglas Gregorff59f672010-01-21 15:46:19 +00002604 if (FDecl) {
Douglas Gregor6ed3eb82010-05-30 06:10:08 +00002605 if (!getLangOptions().CPlusPlus ||
2606 !FDecl->getType()->getAs<FunctionProtoType>())
Douglas Gregorff59f672010-01-21 15:46:19 +00002607 Results.push_back(ResultCandidate(FDecl));
2608 else
John McCallb89836b2010-01-26 01:37:31 +00002609 // FIXME: access?
John McCalla0296f72010-03-19 07:35:19 +00002610 AddOverloadCandidate(FDecl, DeclAccessPair::make(FDecl, AS_none),
2611 Args, NumArgs, CandidateSet,
Douglas Gregorb05275a2010-04-16 17:41:49 +00002612 false, /*PartialOverloading*/true);
Douglas Gregorff59f672010-01-21 15:46:19 +00002613 }
John McCall57500772009-12-16 12:17:52 +00002614 }
Douglas Gregorcabea402009-09-22 15:41:20 +00002615
Douglas Gregor7aa6b222010-05-30 01:49:25 +00002616 QualType ParamType;
2617
Douglas Gregorff59f672010-01-21 15:46:19 +00002618 if (!CandidateSet.empty()) {
2619 // Sort the overload candidate set by placing the best overloads first.
2620 std::stable_sort(CandidateSet.begin(), CandidateSet.end(),
John McCallbc077cf2010-02-08 23:07:23 +00002621 IsBetterOverloadCandidate(*this, Loc));
Douglas Gregorcabea402009-09-22 15:41:20 +00002622
Douglas Gregorff59f672010-01-21 15:46:19 +00002623 // Add the remaining viable overload candidates as code-completion reslults.
2624 for (OverloadCandidateSet::iterator Cand = CandidateSet.begin(),
2625 CandEnd = CandidateSet.end();
2626 Cand != CandEnd; ++Cand) {
2627 if (Cand->Viable)
2628 Results.push_back(ResultCandidate(Cand->Function));
2629 }
Douglas Gregor7aa6b222010-05-30 01:49:25 +00002630
2631 // From the viable candidates, try to determine the type of this parameter.
2632 for (unsigned I = 0, N = Results.size(); I != N; ++I) {
2633 if (const FunctionType *FType = Results[I].getFunctionType())
2634 if (const FunctionProtoType *Proto = dyn_cast<FunctionProtoType>(FType))
2635 if (NumArgs < Proto->getNumArgs()) {
2636 if (ParamType.isNull())
2637 ParamType = Proto->getArgType(NumArgs);
2638 else if (!Context.hasSameUnqualifiedType(
2639 ParamType.getNonReferenceType(),
2640 Proto->getArgType(NumArgs).getNonReferenceType())) {
2641 ParamType = QualType();
2642 break;
2643 }
2644 }
2645 }
2646 } else {
2647 // Try to determine the parameter type from the type of the expression
2648 // being called.
2649 QualType FunctionType = Fn->getType();
2650 if (const PointerType *Ptr = FunctionType->getAs<PointerType>())
2651 FunctionType = Ptr->getPointeeType();
2652 else if (const BlockPointerType *BlockPtr
2653 = FunctionType->getAs<BlockPointerType>())
2654 FunctionType = BlockPtr->getPointeeType();
2655 else if (const MemberPointerType *MemPtr
2656 = FunctionType->getAs<MemberPointerType>())
2657 FunctionType = MemPtr->getPointeeType();
2658
2659 if (const FunctionProtoType *Proto
2660 = FunctionType->getAs<FunctionProtoType>()) {
2661 if (NumArgs < Proto->getNumArgs())
2662 ParamType = Proto->getArgType(NumArgs);
2663 }
Douglas Gregorcabea402009-09-22 15:41:20 +00002664 }
Douglas Gregor3ef59522009-12-11 19:06:04 +00002665
Douglas Gregor7aa6b222010-05-30 01:49:25 +00002666 if (ParamType.isNull())
2667 CodeCompleteOrdinaryName(S, CCC_Expression);
2668 else
2669 CodeCompleteExpression(S, ParamType);
2670
Douglas Gregorc01890e2010-04-06 20:19:47 +00002671 if (!Results.empty())
Douglas Gregor3ef59522009-12-11 19:06:04 +00002672 CodeCompleter->ProcessOverloadCandidates(*this, NumArgs, Results.data(),
2673 Results.size());
Douglas Gregorcabea402009-09-22 15:41:20 +00002674}
2675
Douglas Gregor7aa6b222010-05-30 01:49:25 +00002676void Sema::CodeCompleteInitializer(Scope *S, DeclPtrTy D) {
2677 ValueDecl *VD = dyn_cast_or_null<ValueDecl>(D.getAs<Decl>());
2678 if (!VD) {
2679 CodeCompleteOrdinaryName(S, CCC_Expression);
2680 return;
2681 }
2682
2683 CodeCompleteExpression(S, VD->getType());
2684}
2685
2686void Sema::CodeCompleteReturn(Scope *S) {
2687 QualType ResultType;
2688 if (isa<BlockDecl>(CurContext)) {
2689 if (BlockScopeInfo *BSI = getCurBlock())
2690 ResultType = BSI->ReturnType;
2691 } else if (FunctionDecl *Function = dyn_cast<FunctionDecl>(CurContext))
2692 ResultType = Function->getResultType();
2693 else if (ObjCMethodDecl *Method = dyn_cast<ObjCMethodDecl>(CurContext))
2694 ResultType = Method->getResultType();
2695
2696 if (ResultType.isNull())
2697 CodeCompleteOrdinaryName(S, CCC_Expression);
2698 else
2699 CodeCompleteExpression(S, ResultType);
2700}
2701
2702void Sema::CodeCompleteAssignmentRHS(Scope *S, ExprTy *LHS) {
2703 if (LHS)
2704 CodeCompleteExpression(S, static_cast<Expr *>(LHS)->getType());
2705 else
2706 CodeCompleteOrdinaryName(S, CCC_Expression);
2707}
2708
Jeffrey Yasskinc76498d2010-04-08 16:38:48 +00002709void Sema::CodeCompleteQualifiedId(Scope *S, CXXScopeSpec &SS,
Douglas Gregor2436e712009-09-17 21:32:03 +00002710 bool EnteringContext) {
2711 if (!SS.getScopeRep() || !CodeCompleter)
2712 return;
2713
Douglas Gregor3545ff42009-09-21 16:56:56 +00002714 DeclContext *Ctx = computeDeclContext(SS, EnteringContext);
2715 if (!Ctx)
2716 return;
Douglas Gregor800f2f02009-12-11 18:28:39 +00002717
2718 // Try to instantiate any non-dependent declaration contexts before
2719 // we look in them.
John McCall0b66eb32010-05-01 00:40:08 +00002720 if (!isDependentScopeSpecifier(SS) && RequireCompleteDeclContext(SS, Ctx))
Douglas Gregor800f2f02009-12-11 18:28:39 +00002721 return;
2722
Douglas Gregor3545ff42009-09-21 16:56:56 +00002723 ResultBuilder Results(*this);
Douglas Gregor200c99d2010-01-14 03:35:48 +00002724 CodeCompletionDeclConsumer Consumer(Results, CurContext);
2725 LookupVisibleDecls(Ctx, LookupOrdinaryName, Consumer);
Douglas Gregor3545ff42009-09-21 16:56:56 +00002726
2727 // The "template" keyword can follow "::" in the grammar, but only
2728 // put it into the grammar if the nested-name-specifier is dependent.
2729 NestedNameSpecifier *NNS = (NestedNameSpecifier *)SS.getScopeRep();
2730 if (!Results.empty() && NNS->isDependent())
Douglas Gregor78a21012010-01-14 16:01:26 +00002731 Results.AddResult("template");
Douglas Gregor3545ff42009-09-21 16:56:56 +00002732
Daniel Dunbar242ea9a2009-11-13 08:58:20 +00002733 HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
Douglas Gregor2436e712009-09-17 21:32:03 +00002734}
Douglas Gregor7e90c6d2009-09-18 19:03:04 +00002735
2736void Sema::CodeCompleteUsing(Scope *S) {
2737 if (!CodeCompleter)
2738 return;
2739
Douglas Gregor3545ff42009-09-21 16:56:56 +00002740 ResultBuilder Results(*this, &ResultBuilder::IsNestedNameSpecifier);
Douglas Gregor64b12b52009-09-22 23:31:26 +00002741 Results.EnterNewScope();
Douglas Gregor3545ff42009-09-21 16:56:56 +00002742
2743 // If we aren't in class scope, we could see the "namespace" keyword.
2744 if (!S->isClassScope())
Douglas Gregor78a21012010-01-14 16:01:26 +00002745 Results.AddResult(CodeCompleteConsumer::Result("namespace"));
Douglas Gregor3545ff42009-09-21 16:56:56 +00002746
2747 // After "using", we can see anything that would start a
2748 // nested-name-specifier.
Douglas Gregora6e2edc2010-01-14 03:27:13 +00002749 CodeCompletionDeclConsumer Consumer(Results, CurContext);
2750 LookupVisibleDecls(S, LookupOrdinaryName, Consumer);
Douglas Gregor64b12b52009-09-22 23:31:26 +00002751 Results.ExitScope();
Douglas Gregor3545ff42009-09-21 16:56:56 +00002752
Daniel Dunbar242ea9a2009-11-13 08:58:20 +00002753 HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
Douglas Gregor7e90c6d2009-09-18 19:03:04 +00002754}
2755
2756void Sema::CodeCompleteUsingDirective(Scope *S) {
2757 if (!CodeCompleter)
2758 return;
2759
Douglas Gregor3545ff42009-09-21 16:56:56 +00002760 // After "using namespace", we expect to see a namespace name or namespace
2761 // alias.
2762 ResultBuilder Results(*this, &ResultBuilder::IsNamespaceOrAlias);
Douglas Gregor64b12b52009-09-22 23:31:26 +00002763 Results.EnterNewScope();
Douglas Gregora6e2edc2010-01-14 03:27:13 +00002764 CodeCompletionDeclConsumer Consumer(Results, CurContext);
2765 LookupVisibleDecls(S, LookupOrdinaryName, Consumer);
Douglas Gregor64b12b52009-09-22 23:31:26 +00002766 Results.ExitScope();
Daniel Dunbar242ea9a2009-11-13 08:58:20 +00002767 HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
Douglas Gregor7e90c6d2009-09-18 19:03:04 +00002768}
2769
2770void Sema::CodeCompleteNamespaceDecl(Scope *S) {
2771 if (!CodeCompleter)
2772 return;
2773
Douglas Gregor3545ff42009-09-21 16:56:56 +00002774 ResultBuilder Results(*this, &ResultBuilder::IsNamespace);
2775 DeclContext *Ctx = (DeclContext *)S->getEntity();
2776 if (!S->getParent())
2777 Ctx = Context.getTranslationUnitDecl();
2778
2779 if (Ctx && Ctx->isFileContext()) {
2780 // We only want to see those namespaces that have already been defined
2781 // within this scope, because its likely that the user is creating an
2782 // extended namespace declaration. Keep track of the most recent
2783 // definition of each namespace.
2784 std::map<NamespaceDecl *, NamespaceDecl *> OrigToLatest;
2785 for (DeclContext::specific_decl_iterator<NamespaceDecl>
2786 NS(Ctx->decls_begin()), NSEnd(Ctx->decls_end());
2787 NS != NSEnd; ++NS)
2788 OrigToLatest[NS->getOriginalNamespace()] = *NS;
2789
2790 // Add the most recent definition (or extended definition) of each
2791 // namespace to the list of results.
Douglas Gregor64b12b52009-09-22 23:31:26 +00002792 Results.EnterNewScope();
Douglas Gregor3545ff42009-09-21 16:56:56 +00002793 for (std::map<NamespaceDecl *, NamespaceDecl *>::iterator
2794 NS = OrigToLatest.begin(), NSEnd = OrigToLatest.end();
2795 NS != NSEnd; ++NS)
Douglas Gregorfc59ce12010-01-14 16:14:35 +00002796 Results.AddResult(CodeCompleteConsumer::Result(NS->second, 0),
2797 CurContext, 0, false);
Douglas Gregor64b12b52009-09-22 23:31:26 +00002798 Results.ExitScope();
Douglas Gregor3545ff42009-09-21 16:56:56 +00002799 }
2800
Daniel Dunbar242ea9a2009-11-13 08:58:20 +00002801 HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
Douglas Gregor7e90c6d2009-09-18 19:03:04 +00002802}
2803
2804void Sema::CodeCompleteNamespaceAliasDecl(Scope *S) {
2805 if (!CodeCompleter)
2806 return;
2807
Douglas Gregor3545ff42009-09-21 16:56:56 +00002808 // After "namespace", we expect to see a namespace or alias.
2809 ResultBuilder Results(*this, &ResultBuilder::IsNamespaceOrAlias);
Douglas Gregora6e2edc2010-01-14 03:27:13 +00002810 CodeCompletionDeclConsumer Consumer(Results, CurContext);
2811 LookupVisibleDecls(S, LookupOrdinaryName, Consumer);
Daniel Dunbar242ea9a2009-11-13 08:58:20 +00002812 HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
Douglas Gregor7e90c6d2009-09-18 19:03:04 +00002813}
2814
Douglas Gregorc811ede2009-09-18 20:05:18 +00002815void Sema::CodeCompleteOperatorName(Scope *S) {
2816 if (!CodeCompleter)
2817 return;
Douglas Gregor3545ff42009-09-21 16:56:56 +00002818
2819 typedef CodeCompleteConsumer::Result Result;
2820 ResultBuilder Results(*this, &ResultBuilder::IsType);
Douglas Gregor64b12b52009-09-22 23:31:26 +00002821 Results.EnterNewScope();
Douglas Gregorc811ede2009-09-18 20:05:18 +00002822
Douglas Gregor3545ff42009-09-21 16:56:56 +00002823 // Add the names of overloadable operators.
2824#define OVERLOADED_OPERATOR(Name,Spelling,Token,Unary,Binary,MemberOnly) \
2825 if (std::strcmp(Spelling, "?")) \
Douglas Gregor78a21012010-01-14 16:01:26 +00002826 Results.AddResult(Result(Spelling));
Douglas Gregor3545ff42009-09-21 16:56:56 +00002827#include "clang/Basic/OperatorKinds.def"
2828
2829 // Add any type names visible from the current scope
Douglas Gregor6ae4c522010-01-14 03:21:49 +00002830 Results.allowNestedNameSpecifiers();
Douglas Gregora6e2edc2010-01-14 03:27:13 +00002831 CodeCompletionDeclConsumer Consumer(Results, CurContext);
2832 LookupVisibleDecls(S, LookupOrdinaryName, Consumer);
Douglas Gregor3545ff42009-09-21 16:56:56 +00002833
2834 // Add any type specifiers
Douglas Gregorf98e6a22010-01-13 23:51:12 +00002835 AddTypeSpecifierResults(getLangOptions(), Results);
Douglas Gregor64b12b52009-09-22 23:31:26 +00002836 Results.ExitScope();
Douglas Gregor3545ff42009-09-21 16:56:56 +00002837
Daniel Dunbar242ea9a2009-11-13 08:58:20 +00002838 HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
Douglas Gregorc811ede2009-09-18 20:05:18 +00002839}
Douglas Gregor7e90c6d2009-09-18 19:03:04 +00002840
Douglas Gregorf1934162010-01-13 21:24:21 +00002841// Macro that expands to @Keyword or Keyword, depending on whether NeedAt is
2842// true or false.
2843#define OBJC_AT_KEYWORD_NAME(NeedAt,Keyword) NeedAt? "@" #Keyword : #Keyword
Douglas Gregorf98e6a22010-01-13 23:51:12 +00002844static void AddObjCImplementationResults(const LangOptions &LangOpts,
Douglas Gregorf1934162010-01-13 21:24:21 +00002845 ResultBuilder &Results,
2846 bool NeedAt) {
2847 typedef CodeCompleteConsumer::Result Result;
2848 // Since we have an implementation, we can end it.
Douglas Gregor78a21012010-01-14 16:01:26 +00002849 Results.AddResult(Result(OBJC_AT_KEYWORD_NAME(NeedAt,end)));
Douglas Gregorf1934162010-01-13 21:24:21 +00002850
2851 CodeCompletionString *Pattern = 0;
2852 if (LangOpts.ObjC2) {
2853 // @dynamic
2854 Pattern = new CodeCompletionString;
2855 Pattern->AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt,dynamic));
2856 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
2857 Pattern->AddPlaceholderChunk("property");
Douglas Gregor78a21012010-01-14 16:01:26 +00002858 Results.AddResult(Result(Pattern));
Douglas Gregorf1934162010-01-13 21:24:21 +00002859
2860 // @synthesize
2861 Pattern = new CodeCompletionString;
2862 Pattern->AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt,synthesize));
2863 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
2864 Pattern->AddPlaceholderChunk("property");
Douglas Gregor78a21012010-01-14 16:01:26 +00002865 Results.AddResult(Result(Pattern));
Douglas Gregorf1934162010-01-13 21:24:21 +00002866 }
2867}
2868
Douglas Gregorf98e6a22010-01-13 23:51:12 +00002869static void AddObjCInterfaceResults(const LangOptions &LangOpts,
Douglas Gregorf1934162010-01-13 21:24:21 +00002870 ResultBuilder &Results,
2871 bool NeedAt) {
2872 typedef CodeCompleteConsumer::Result Result;
2873
2874 // Since we have an interface or protocol, we can end it.
Douglas Gregor78a21012010-01-14 16:01:26 +00002875 Results.AddResult(Result(OBJC_AT_KEYWORD_NAME(NeedAt,end)));
Douglas Gregorf1934162010-01-13 21:24:21 +00002876
2877 if (LangOpts.ObjC2) {
2878 // @property
Douglas Gregor78a21012010-01-14 16:01:26 +00002879 Results.AddResult(Result(OBJC_AT_KEYWORD_NAME(NeedAt,property)));
Douglas Gregorf1934162010-01-13 21:24:21 +00002880
2881 // @required
Douglas Gregor78a21012010-01-14 16:01:26 +00002882 Results.AddResult(Result(OBJC_AT_KEYWORD_NAME(NeedAt,required)));
Douglas Gregorf1934162010-01-13 21:24:21 +00002883
2884 // @optional
Douglas Gregor78a21012010-01-14 16:01:26 +00002885 Results.AddResult(Result(OBJC_AT_KEYWORD_NAME(NeedAt,optional)));
Douglas Gregorf1934162010-01-13 21:24:21 +00002886 }
2887}
2888
Douglas Gregorf98e6a22010-01-13 23:51:12 +00002889static void AddObjCTopLevelResults(ResultBuilder &Results, bool NeedAt) {
Douglas Gregorf1934162010-01-13 21:24:21 +00002890 typedef CodeCompleteConsumer::Result Result;
2891 CodeCompletionString *Pattern = 0;
2892
2893 // @class name ;
2894 Pattern = new CodeCompletionString;
2895 Pattern->AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt,class));
2896 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
Douglas Gregorf4c33342010-05-28 00:22:41 +00002897 Pattern->AddPlaceholderChunk("name");
Douglas Gregor78a21012010-01-14 16:01:26 +00002898 Results.AddResult(Result(Pattern));
Douglas Gregorf1934162010-01-13 21:24:21 +00002899
Douglas Gregorf4c33342010-05-28 00:22:41 +00002900 if (Results.includeCodePatterns()) {
2901 // @interface name
2902 // FIXME: Could introduce the whole pattern, including superclasses and
2903 // such.
2904 Pattern = new CodeCompletionString;
2905 Pattern->AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt,interface));
2906 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
2907 Pattern->AddPlaceholderChunk("class");
2908 Results.AddResult(Result(Pattern));
Douglas Gregorf1934162010-01-13 21:24:21 +00002909
Douglas Gregorf4c33342010-05-28 00:22:41 +00002910 // @protocol name
2911 Pattern = new CodeCompletionString;
2912 Pattern->AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt,protocol));
2913 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
2914 Pattern->AddPlaceholderChunk("protocol");
2915 Results.AddResult(Result(Pattern));
2916
2917 // @implementation name
2918 Pattern = new CodeCompletionString;
2919 Pattern->AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt,implementation));
2920 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
2921 Pattern->AddPlaceholderChunk("class");
2922 Results.AddResult(Result(Pattern));
2923 }
Douglas Gregorf1934162010-01-13 21:24:21 +00002924
2925 // @compatibility_alias name
2926 Pattern = new CodeCompletionString;
2927 Pattern->AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt,compatibility_alias));
2928 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
2929 Pattern->AddPlaceholderChunk("alias");
2930 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
2931 Pattern->AddPlaceholderChunk("class");
Douglas Gregor78a21012010-01-14 16:01:26 +00002932 Results.AddResult(Result(Pattern));
Douglas Gregorf1934162010-01-13 21:24:21 +00002933}
2934
Douglas Gregorf48706c2009-12-07 09:27:33 +00002935void Sema::CodeCompleteObjCAtDirective(Scope *S, DeclPtrTy ObjCImpDecl,
2936 bool InInterface) {
2937 typedef CodeCompleteConsumer::Result Result;
2938 ResultBuilder Results(*this);
2939 Results.EnterNewScope();
Douglas Gregorf1934162010-01-13 21:24:21 +00002940 if (ObjCImpDecl)
Douglas Gregorf98e6a22010-01-13 23:51:12 +00002941 AddObjCImplementationResults(getLangOptions(), Results, false);
Douglas Gregorf1934162010-01-13 21:24:21 +00002942 else if (InInterface)
Douglas Gregorf98e6a22010-01-13 23:51:12 +00002943 AddObjCInterfaceResults(getLangOptions(), Results, false);
Douglas Gregorf1934162010-01-13 21:24:21 +00002944 else
Douglas Gregorf98e6a22010-01-13 23:51:12 +00002945 AddObjCTopLevelResults(Results, false);
Douglas Gregorf48706c2009-12-07 09:27:33 +00002946 Results.ExitScope();
2947 HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
2948}
2949
Douglas Gregorf98e6a22010-01-13 23:51:12 +00002950static void AddObjCExpressionResults(ResultBuilder &Results, bool NeedAt) {
Douglas Gregorbc7c5e42009-12-07 09:51:25 +00002951 typedef CodeCompleteConsumer::Result Result;
2952 CodeCompletionString *Pattern = 0;
2953
2954 // @encode ( type-name )
2955 Pattern = new CodeCompletionString;
Douglas Gregorf1934162010-01-13 21:24:21 +00002956 Pattern->AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt,encode));
Douglas Gregorbc7c5e42009-12-07 09:51:25 +00002957 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
2958 Pattern->AddPlaceholderChunk("type-name");
2959 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
Douglas Gregor78a21012010-01-14 16:01:26 +00002960 Results.AddResult(Result(Pattern));
Douglas Gregorbc7c5e42009-12-07 09:51:25 +00002961
2962 // @protocol ( protocol-name )
2963 Pattern = new CodeCompletionString;
Douglas Gregorf1934162010-01-13 21:24:21 +00002964 Pattern->AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt,protocol));
Douglas Gregorbc7c5e42009-12-07 09:51:25 +00002965 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
2966 Pattern->AddPlaceholderChunk("protocol-name");
2967 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
Douglas Gregor78a21012010-01-14 16:01:26 +00002968 Results.AddResult(Result(Pattern));
Douglas Gregorbc7c5e42009-12-07 09:51:25 +00002969
2970 // @selector ( selector )
2971 Pattern = new CodeCompletionString;
Douglas Gregorf1934162010-01-13 21:24:21 +00002972 Pattern->AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt,selector));
Douglas Gregorbc7c5e42009-12-07 09:51:25 +00002973 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
2974 Pattern->AddPlaceholderChunk("selector");
2975 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
Douglas Gregor78a21012010-01-14 16:01:26 +00002976 Results.AddResult(Result(Pattern));
Douglas Gregorbc7c5e42009-12-07 09:51:25 +00002977}
2978
Douglas Gregorf98e6a22010-01-13 23:51:12 +00002979static void AddObjCStatementResults(ResultBuilder &Results, bool NeedAt) {
Douglas Gregorbc7c5e42009-12-07 09:51:25 +00002980 typedef CodeCompleteConsumer::Result Result;
Douglas Gregorbc7c5e42009-12-07 09:51:25 +00002981 CodeCompletionString *Pattern = 0;
Douglas Gregorf1934162010-01-13 21:24:21 +00002982
Douglas Gregorf4c33342010-05-28 00:22:41 +00002983 if (Results.includeCodePatterns()) {
2984 // @try { statements } @catch ( declaration ) { statements } @finally
2985 // { statements }
2986 Pattern = new CodeCompletionString;
2987 Pattern->AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt,try));
2988 Pattern->AddChunk(CodeCompletionString::CK_LeftBrace);
2989 Pattern->AddPlaceholderChunk("statements");
2990 Pattern->AddChunk(CodeCompletionString::CK_RightBrace);
2991 Pattern->AddTextChunk("@catch");
2992 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
2993 Pattern->AddPlaceholderChunk("parameter");
2994 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
2995 Pattern->AddChunk(CodeCompletionString::CK_LeftBrace);
2996 Pattern->AddPlaceholderChunk("statements");
2997 Pattern->AddChunk(CodeCompletionString::CK_RightBrace);
2998 Pattern->AddTextChunk("@finally");
2999 Pattern->AddChunk(CodeCompletionString::CK_LeftBrace);
3000 Pattern->AddPlaceholderChunk("statements");
3001 Pattern->AddChunk(CodeCompletionString::CK_RightBrace);
3002 Results.AddResult(Result(Pattern));
3003 }
Douglas Gregorf1934162010-01-13 21:24:21 +00003004
Douglas Gregorbc7c5e42009-12-07 09:51:25 +00003005 // @throw
3006 Pattern = new CodeCompletionString;
Douglas Gregorf1934162010-01-13 21:24:21 +00003007 Pattern->AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt,throw));
Douglas Gregor6a803932010-01-12 06:38:28 +00003008 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
Douglas Gregorbc7c5e42009-12-07 09:51:25 +00003009 Pattern->AddPlaceholderChunk("expression");
Douglas Gregor78a21012010-01-14 16:01:26 +00003010 Results.AddResult(Result(Pattern));
Douglas Gregorf1934162010-01-13 21:24:21 +00003011
Douglas Gregorf4c33342010-05-28 00:22:41 +00003012 if (Results.includeCodePatterns()) {
3013 // @synchronized ( expression ) { statements }
3014 Pattern = new CodeCompletionString;
3015 Pattern->AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt,synchronized));
3016 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
3017 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
3018 Pattern->AddPlaceholderChunk("expression");
3019 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
3020 Pattern->AddChunk(CodeCompletionString::CK_LeftBrace);
3021 Pattern->AddPlaceholderChunk("statements");
3022 Pattern->AddChunk(CodeCompletionString::CK_RightBrace);
3023 Results.AddResult(Result(Pattern));
3024 }
Douglas Gregorf1934162010-01-13 21:24:21 +00003025}
Douglas Gregorbc7c5e42009-12-07 09:51:25 +00003026
Douglas Gregorf98e6a22010-01-13 23:51:12 +00003027static void AddObjCVisibilityResults(const LangOptions &LangOpts,
Douglas Gregor48d46252010-01-13 21:54:15 +00003028 ResultBuilder &Results,
3029 bool NeedAt) {
Douglas Gregorf1934162010-01-13 21:24:21 +00003030 typedef CodeCompleteConsumer::Result Result;
Douglas Gregor78a21012010-01-14 16:01:26 +00003031 Results.AddResult(Result(OBJC_AT_KEYWORD_NAME(NeedAt,private)));
3032 Results.AddResult(Result(OBJC_AT_KEYWORD_NAME(NeedAt,protected)));
3033 Results.AddResult(Result(OBJC_AT_KEYWORD_NAME(NeedAt,public)));
Douglas Gregor48d46252010-01-13 21:54:15 +00003034 if (LangOpts.ObjC2)
Douglas Gregor78a21012010-01-14 16:01:26 +00003035 Results.AddResult(Result(OBJC_AT_KEYWORD_NAME(NeedAt,package)));
Douglas Gregor48d46252010-01-13 21:54:15 +00003036}
3037
3038void Sema::CodeCompleteObjCAtVisibility(Scope *S) {
3039 ResultBuilder Results(*this);
3040 Results.EnterNewScope();
Douglas Gregorf98e6a22010-01-13 23:51:12 +00003041 AddObjCVisibilityResults(getLangOptions(), Results, false);
Douglas Gregor48d46252010-01-13 21:54:15 +00003042 Results.ExitScope();
3043 HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
3044}
3045
3046void Sema::CodeCompleteObjCAtStatement(Scope *S) {
Douglas Gregorf1934162010-01-13 21:24:21 +00003047 ResultBuilder Results(*this);
3048 Results.EnterNewScope();
Douglas Gregorf98e6a22010-01-13 23:51:12 +00003049 AddObjCStatementResults(Results, false);
3050 AddObjCExpressionResults(Results, false);
Douglas Gregorbc7c5e42009-12-07 09:51:25 +00003051 Results.ExitScope();
3052 HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
3053}
3054
3055void Sema::CodeCompleteObjCAtExpression(Scope *S) {
3056 ResultBuilder Results(*this);
3057 Results.EnterNewScope();
Douglas Gregorf98e6a22010-01-13 23:51:12 +00003058 AddObjCExpressionResults(Results, false);
Douglas Gregorbc7c5e42009-12-07 09:51:25 +00003059 Results.ExitScope();
3060 HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
3061}
3062
Douglas Gregore6078da2009-11-19 00:14:45 +00003063/// \brief Determine whether the addition of the given flag to an Objective-C
3064/// property's attributes will cause a conflict.
3065static bool ObjCPropertyFlagConflicts(unsigned Attributes, unsigned NewFlag) {
3066 // Check if we've already added this flag.
3067 if (Attributes & NewFlag)
3068 return true;
3069
3070 Attributes |= NewFlag;
3071
3072 // Check for collisions with "readonly".
3073 if ((Attributes & ObjCDeclSpec::DQ_PR_readonly) &&
3074 (Attributes & (ObjCDeclSpec::DQ_PR_readwrite |
3075 ObjCDeclSpec::DQ_PR_assign |
3076 ObjCDeclSpec::DQ_PR_copy |
3077 ObjCDeclSpec::DQ_PR_retain)))
3078 return true;
3079
3080 // Check for more than one of { assign, copy, retain }.
3081 unsigned AssignCopyRetMask = Attributes & (ObjCDeclSpec::DQ_PR_assign |
3082 ObjCDeclSpec::DQ_PR_copy |
3083 ObjCDeclSpec::DQ_PR_retain);
3084 if (AssignCopyRetMask &&
3085 AssignCopyRetMask != ObjCDeclSpec::DQ_PR_assign &&
3086 AssignCopyRetMask != ObjCDeclSpec::DQ_PR_copy &&
3087 AssignCopyRetMask != ObjCDeclSpec::DQ_PR_retain)
3088 return true;
3089
3090 return false;
3091}
3092
Douglas Gregor36029f42009-11-18 23:08:07 +00003093void Sema::CodeCompleteObjCPropertyFlags(Scope *S, ObjCDeclSpec &ODS) {
Steve Naroff936354c2009-10-08 21:55:05 +00003094 if (!CodeCompleter)
3095 return;
Douglas Gregor1b605f72009-11-19 01:08:35 +00003096
Steve Naroff936354c2009-10-08 21:55:05 +00003097 unsigned Attributes = ODS.getPropertyAttributes();
3098
3099 typedef CodeCompleteConsumer::Result Result;
3100 ResultBuilder Results(*this);
3101 Results.EnterNewScope();
Douglas Gregore6078da2009-11-19 00:14:45 +00003102 if (!ObjCPropertyFlagConflicts(Attributes, ObjCDeclSpec::DQ_PR_readonly))
Douglas Gregor78a21012010-01-14 16:01:26 +00003103 Results.AddResult(CodeCompleteConsumer::Result("readonly"));
Douglas Gregore6078da2009-11-19 00:14:45 +00003104 if (!ObjCPropertyFlagConflicts(Attributes, ObjCDeclSpec::DQ_PR_assign))
Douglas Gregor78a21012010-01-14 16:01:26 +00003105 Results.AddResult(CodeCompleteConsumer::Result("assign"));
Douglas Gregore6078da2009-11-19 00:14:45 +00003106 if (!ObjCPropertyFlagConflicts(Attributes, ObjCDeclSpec::DQ_PR_readwrite))
Douglas Gregor78a21012010-01-14 16:01:26 +00003107 Results.AddResult(CodeCompleteConsumer::Result("readwrite"));
Douglas Gregore6078da2009-11-19 00:14:45 +00003108 if (!ObjCPropertyFlagConflicts(Attributes, ObjCDeclSpec::DQ_PR_retain))
Douglas Gregor78a21012010-01-14 16:01:26 +00003109 Results.AddResult(CodeCompleteConsumer::Result("retain"));
Douglas Gregore6078da2009-11-19 00:14:45 +00003110 if (!ObjCPropertyFlagConflicts(Attributes, ObjCDeclSpec::DQ_PR_copy))
Douglas Gregor78a21012010-01-14 16:01:26 +00003111 Results.AddResult(CodeCompleteConsumer::Result("copy"));
Douglas Gregore6078da2009-11-19 00:14:45 +00003112 if (!ObjCPropertyFlagConflicts(Attributes, ObjCDeclSpec::DQ_PR_nonatomic))
Douglas Gregor78a21012010-01-14 16:01:26 +00003113 Results.AddResult(CodeCompleteConsumer::Result("nonatomic"));
Douglas Gregore6078da2009-11-19 00:14:45 +00003114 if (!ObjCPropertyFlagConflicts(Attributes, ObjCDeclSpec::DQ_PR_setter)) {
Douglas Gregor45f83ee2009-11-19 00:01:57 +00003115 CodeCompletionString *Setter = new CodeCompletionString;
3116 Setter->AddTypedTextChunk("setter");
3117 Setter->AddTextChunk(" = ");
3118 Setter->AddPlaceholderChunk("method");
Douglas Gregor78a21012010-01-14 16:01:26 +00003119 Results.AddResult(CodeCompleteConsumer::Result(Setter));
Douglas Gregor45f83ee2009-11-19 00:01:57 +00003120 }
Douglas Gregore6078da2009-11-19 00:14:45 +00003121 if (!ObjCPropertyFlagConflicts(Attributes, ObjCDeclSpec::DQ_PR_getter)) {
Douglas Gregor45f83ee2009-11-19 00:01:57 +00003122 CodeCompletionString *Getter = new CodeCompletionString;
3123 Getter->AddTypedTextChunk("getter");
3124 Getter->AddTextChunk(" = ");
3125 Getter->AddPlaceholderChunk("method");
Douglas Gregor78a21012010-01-14 16:01:26 +00003126 Results.AddResult(CodeCompleteConsumer::Result(Getter));
Douglas Gregor45f83ee2009-11-19 00:01:57 +00003127 }
Steve Naroff936354c2009-10-08 21:55:05 +00003128 Results.ExitScope();
Daniel Dunbar242ea9a2009-11-13 08:58:20 +00003129 HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
Steve Naroff936354c2009-10-08 21:55:05 +00003130}
Steve Naroffeae65032009-11-07 02:08:14 +00003131
Douglas Gregorc8537c52009-11-19 07:41:15 +00003132/// \brief Descripts the kind of Objective-C method that we want to find
3133/// via code completion.
3134enum ObjCMethodKind {
3135 MK_Any, //< Any kind of method, provided it means other specified criteria.
3136 MK_ZeroArgSelector, //< Zero-argument (unary) selector.
3137 MK_OneArgSelector //< One-argument selector.
3138};
3139
3140static bool isAcceptableObjCMethod(ObjCMethodDecl *Method,
3141 ObjCMethodKind WantKind,
3142 IdentifierInfo **SelIdents,
3143 unsigned NumSelIdents) {
3144 Selector Sel = Method->getSelector();
3145 if (NumSelIdents > Sel.getNumArgs())
3146 return false;
3147
3148 switch (WantKind) {
3149 case MK_Any: break;
3150 case MK_ZeroArgSelector: return Sel.isUnarySelector();
3151 case MK_OneArgSelector: return Sel.getNumArgs() == 1;
3152 }
3153
3154 for (unsigned I = 0; I != NumSelIdents; ++I)
3155 if (SelIdents[I] != Sel.getIdentifierInfoForSlot(I))
3156 return false;
3157
3158 return true;
3159}
3160
Douglas Gregorbab2b3c2009-11-17 23:22:23 +00003161/// \brief Add all of the Objective-C methods in the given Objective-C
3162/// container to the set of results.
3163///
3164/// The container will be a class, protocol, category, or implementation of
3165/// any of the above. This mether will recurse to include methods from
3166/// the superclasses of classes along with their categories, protocols, and
3167/// implementations.
3168///
3169/// \param Container the container in which we'll look to find methods.
3170///
3171/// \param WantInstance whether to add instance methods (only); if false, this
3172/// routine will add factory methods (only).
3173///
3174/// \param CurContext the context in which we're performing the lookup that
3175/// finds methods.
3176///
3177/// \param Results the structure into which we'll add results.
3178static void AddObjCMethods(ObjCContainerDecl *Container,
3179 bool WantInstanceMethods,
Douglas Gregorc8537c52009-11-19 07:41:15 +00003180 ObjCMethodKind WantKind,
Douglas Gregor1b605f72009-11-19 01:08:35 +00003181 IdentifierInfo **SelIdents,
3182 unsigned NumSelIdents,
Douglas Gregorbab2b3c2009-11-17 23:22:23 +00003183 DeclContext *CurContext,
3184 ResultBuilder &Results) {
3185 typedef CodeCompleteConsumer::Result Result;
3186 for (ObjCContainerDecl::method_iterator M = Container->meth_begin(),
3187 MEnd = Container->meth_end();
3188 M != MEnd; ++M) {
Douglas Gregor1b605f72009-11-19 01:08:35 +00003189 if ((*M)->isInstanceMethod() == WantInstanceMethods) {
3190 // Check whether the selector identifiers we've been given are a
3191 // subset of the identifiers for this particular method.
Douglas Gregorc8537c52009-11-19 07:41:15 +00003192 if (!isAcceptableObjCMethod(*M, WantKind, SelIdents, NumSelIdents))
Douglas Gregor1b605f72009-11-19 01:08:35 +00003193 continue;
Douglas Gregorc8537c52009-11-19 07:41:15 +00003194
Douglas Gregor1b605f72009-11-19 01:08:35 +00003195 Result R = Result(*M, 0);
3196 R.StartParameter = NumSelIdents;
Douglas Gregorc8537c52009-11-19 07:41:15 +00003197 R.AllParametersAreInformative = (WantKind != MK_Any);
Douglas Gregor1b605f72009-11-19 01:08:35 +00003198 Results.MaybeAddResult(R, CurContext);
3199 }
Douglas Gregorbab2b3c2009-11-17 23:22:23 +00003200 }
3201
3202 ObjCInterfaceDecl *IFace = dyn_cast<ObjCInterfaceDecl>(Container);
3203 if (!IFace)
3204 return;
3205
3206 // Add methods in protocols.
3207 const ObjCList<ObjCProtocolDecl> &Protocols= IFace->getReferencedProtocols();
3208 for (ObjCList<ObjCProtocolDecl>::iterator I = Protocols.begin(),
3209 E = Protocols.end();
3210 I != E; ++I)
Douglas Gregorc8537c52009-11-19 07:41:15 +00003211 AddObjCMethods(*I, WantInstanceMethods, WantKind, SelIdents, NumSelIdents,
Douglas Gregor1b605f72009-11-19 01:08:35 +00003212 CurContext, Results);
Douglas Gregorbab2b3c2009-11-17 23:22:23 +00003213
3214 // Add methods in categories.
3215 for (ObjCCategoryDecl *CatDecl = IFace->getCategoryList(); CatDecl;
3216 CatDecl = CatDecl->getNextClassCategory()) {
Douglas Gregorc8537c52009-11-19 07:41:15 +00003217 AddObjCMethods(CatDecl, WantInstanceMethods, WantKind, SelIdents,
3218 NumSelIdents, CurContext, Results);
Douglas Gregorbab2b3c2009-11-17 23:22:23 +00003219
3220 // Add a categories protocol methods.
3221 const ObjCList<ObjCProtocolDecl> &Protocols
3222 = CatDecl->getReferencedProtocols();
3223 for (ObjCList<ObjCProtocolDecl>::iterator I = Protocols.begin(),
3224 E = Protocols.end();
3225 I != E; ++I)
Douglas Gregorc8537c52009-11-19 07:41:15 +00003226 AddObjCMethods(*I, WantInstanceMethods, WantKind, SelIdents,
3227 NumSelIdents, CurContext, Results);
Douglas Gregorbab2b3c2009-11-17 23:22:23 +00003228
3229 // Add methods in category implementations.
3230 if (ObjCCategoryImplDecl *Impl = CatDecl->getImplementation())
Douglas Gregorc8537c52009-11-19 07:41:15 +00003231 AddObjCMethods(Impl, WantInstanceMethods, WantKind, SelIdents,
3232 NumSelIdents, CurContext, Results);
Douglas Gregorbab2b3c2009-11-17 23:22:23 +00003233 }
3234
3235 // Add methods in superclass.
3236 if (IFace->getSuperClass())
Douglas Gregorc8537c52009-11-19 07:41:15 +00003237 AddObjCMethods(IFace->getSuperClass(), WantInstanceMethods, WantKind,
3238 SelIdents, NumSelIdents, CurContext, Results);
Douglas Gregorbab2b3c2009-11-17 23:22:23 +00003239
3240 // Add methods in our implementation, if any.
3241 if (ObjCImplementationDecl *Impl = IFace->getImplementation())
Douglas Gregorc8537c52009-11-19 07:41:15 +00003242 AddObjCMethods(Impl, WantInstanceMethods, WantKind, SelIdents,
3243 NumSelIdents, CurContext, Results);
3244}
3245
3246
3247void Sema::CodeCompleteObjCPropertyGetter(Scope *S, DeclPtrTy ClassDecl,
3248 DeclPtrTy *Methods,
3249 unsigned NumMethods) {
3250 typedef CodeCompleteConsumer::Result Result;
3251
3252 // Try to find the interface where getters might live.
3253 ObjCInterfaceDecl *Class
3254 = dyn_cast_or_null<ObjCInterfaceDecl>(ClassDecl.getAs<Decl>());
3255 if (!Class) {
3256 if (ObjCCategoryDecl *Category
3257 = dyn_cast_or_null<ObjCCategoryDecl>(ClassDecl.getAs<Decl>()))
3258 Class = Category->getClassInterface();
3259
3260 if (!Class)
3261 return;
3262 }
3263
3264 // Find all of the potential getters.
3265 ResultBuilder Results(*this);
3266 Results.EnterNewScope();
3267
3268 // FIXME: We need to do this because Objective-C methods don't get
3269 // pushed into DeclContexts early enough. Argh!
3270 for (unsigned I = 0; I != NumMethods; ++I) {
3271 if (ObjCMethodDecl *Method
3272 = dyn_cast_or_null<ObjCMethodDecl>(Methods[I].getAs<Decl>()))
3273 if (Method->isInstanceMethod() &&
3274 isAcceptableObjCMethod(Method, MK_ZeroArgSelector, 0, 0)) {
3275 Result R = Result(Method, 0);
3276 R.AllParametersAreInformative = true;
3277 Results.MaybeAddResult(R, CurContext);
3278 }
3279 }
3280
3281 AddObjCMethods(Class, true, MK_ZeroArgSelector, 0, 0, CurContext, Results);
3282 Results.ExitScope();
3283 HandleCodeCompleteResults(this, CodeCompleter,Results.data(),Results.size());
3284}
3285
3286void Sema::CodeCompleteObjCPropertySetter(Scope *S, DeclPtrTy ObjCImplDecl,
3287 DeclPtrTy *Methods,
3288 unsigned NumMethods) {
3289 typedef CodeCompleteConsumer::Result Result;
3290
3291 // Try to find the interface where setters might live.
3292 ObjCInterfaceDecl *Class
3293 = dyn_cast_or_null<ObjCInterfaceDecl>(ObjCImplDecl.getAs<Decl>());
3294 if (!Class) {
3295 if (ObjCCategoryDecl *Category
3296 = dyn_cast_or_null<ObjCCategoryDecl>(ObjCImplDecl.getAs<Decl>()))
3297 Class = Category->getClassInterface();
3298
3299 if (!Class)
3300 return;
3301 }
3302
3303 // Find all of the potential getters.
3304 ResultBuilder Results(*this);
3305 Results.EnterNewScope();
3306
3307 // FIXME: We need to do this because Objective-C methods don't get
3308 // pushed into DeclContexts early enough. Argh!
3309 for (unsigned I = 0; I != NumMethods; ++I) {
3310 if (ObjCMethodDecl *Method
3311 = dyn_cast_or_null<ObjCMethodDecl>(Methods[I].getAs<Decl>()))
3312 if (Method->isInstanceMethod() &&
3313 isAcceptableObjCMethod(Method, MK_OneArgSelector, 0, 0)) {
3314 Result R = Result(Method, 0);
3315 R.AllParametersAreInformative = true;
3316 Results.MaybeAddResult(R, CurContext);
3317 }
3318 }
3319
3320 AddObjCMethods(Class, true, MK_OneArgSelector, 0, 0, CurContext, Results);
3321
3322 Results.ExitScope();
3323 HandleCodeCompleteResults(this, CodeCompleter,Results.data(),Results.size());
Douglas Gregorbab2b3c2009-11-17 23:22:23 +00003324}
3325
Douglas Gregor9d2ddb22010-04-06 19:22:33 +00003326/// \brief When we have an expression with type "id", we may assume
3327/// that it has some more-specific class type based on knowledge of
3328/// common uses of Objective-C. This routine returns that class type,
3329/// or NULL if no better result could be determined.
3330static ObjCInterfaceDecl *GetAssumedMessageSendExprType(Expr *E) {
3331 ObjCMessageExpr *Msg = dyn_cast<ObjCMessageExpr>(E);
3332 if (!Msg)
3333 return 0;
3334
3335 Selector Sel = Msg->getSelector();
3336 if (Sel.isNull())
3337 return 0;
3338
3339 IdentifierInfo *Id = Sel.getIdentifierInfoForSlot(0);
3340 if (!Id)
3341 return 0;
3342
3343 ObjCMethodDecl *Method = Msg->getMethodDecl();
3344 if (!Method)
3345 return 0;
3346
3347 // Determine the class that we're sending the message to.
Douglas Gregor9a129192010-04-21 00:45:42 +00003348 ObjCInterfaceDecl *IFace = 0;
3349 switch (Msg->getReceiverKind()) {
3350 case ObjCMessageExpr::Class:
John McCall8b07ec22010-05-15 11:32:37 +00003351 if (const ObjCObjectType *ObjType
3352 = Msg->getClassReceiver()->getAs<ObjCObjectType>())
3353 IFace = ObjType->getInterface();
Douglas Gregor9a129192010-04-21 00:45:42 +00003354 break;
3355
3356 case ObjCMessageExpr::Instance: {
3357 QualType T = Msg->getInstanceReceiver()->getType();
3358 if (const ObjCObjectPointerType *Ptr = T->getAs<ObjCObjectPointerType>())
3359 IFace = Ptr->getInterfaceDecl();
3360 break;
3361 }
3362
3363 case ObjCMessageExpr::SuperInstance:
3364 case ObjCMessageExpr::SuperClass:
3365 break;
Douglas Gregor9d2ddb22010-04-06 19:22:33 +00003366 }
3367
3368 if (!IFace)
3369 return 0;
3370
3371 ObjCInterfaceDecl *Super = IFace->getSuperClass();
3372 if (Method->isInstanceMethod())
3373 return llvm::StringSwitch<ObjCInterfaceDecl *>(Id->getName())
3374 .Case("retain", IFace)
3375 .Case("autorelease", IFace)
3376 .Case("copy", IFace)
3377 .Case("copyWithZone", IFace)
3378 .Case("mutableCopy", IFace)
3379 .Case("mutableCopyWithZone", IFace)
3380 .Case("awakeFromCoder", IFace)
3381 .Case("replacementObjectFromCoder", IFace)
3382 .Case("class", IFace)
3383 .Case("classForCoder", IFace)
3384 .Case("superclass", Super)
3385 .Default(0);
3386
3387 return llvm::StringSwitch<ObjCInterfaceDecl *>(Id->getName())
3388 .Case("new", IFace)
3389 .Case("alloc", IFace)
3390 .Case("allocWithZone", IFace)
3391 .Case("class", IFace)
3392 .Case("superclass", Super)
3393 .Default(0);
3394}
3395
Douglas Gregora817a192010-05-27 23:06:34 +00003396void Sema::CodeCompleteObjCMessageReceiver(Scope *S) {
3397 typedef CodeCompleteConsumer::Result Result;
3398 ResultBuilder Results(*this);
3399
3400 // Find anything that looks like it could be a message receiver.
3401 Results.setFilter(&ResultBuilder::IsObjCMessageReceiver);
3402 CodeCompletionDeclConsumer Consumer(Results, CurContext);
3403 Results.EnterNewScope();
3404 LookupVisibleDecls(S, LookupOrdinaryName, Consumer);
3405
3406 // If we are in an Objective-C method inside a class that has a superclass,
3407 // add "super" as an option.
3408 if (ObjCMethodDecl *Method = getCurMethodDecl())
3409 if (ObjCInterfaceDecl *Iface = Method->getClassInterface())
3410 if (Iface->getSuperClass())
3411 Results.AddResult(Result("super"));
3412
3413 Results.ExitScope();
3414
3415 if (CodeCompleter->includeMacros())
3416 AddMacroResults(PP, Results);
3417 HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
3418
3419}
3420
Douglas Gregor0c78ad92010-04-21 19:57:20 +00003421void Sema::CodeCompleteObjCSuperMessage(Scope *S, SourceLocation SuperLoc,
3422 IdentifierInfo **SelIdents,
3423 unsigned NumSelIdents) {
3424 ObjCInterfaceDecl *CDecl = 0;
3425 if (ObjCMethodDecl *CurMethod = getCurMethodDecl()) {
3426 // Figure out which interface we're in.
3427 CDecl = CurMethod->getClassInterface();
3428 if (!CDecl)
3429 return;
3430
3431 // Find the superclass of this class.
3432 CDecl = CDecl->getSuperClass();
3433 if (!CDecl)
3434 return;
3435
3436 if (CurMethod->isInstanceMethod()) {
3437 // We are inside an instance method, which means that the message
3438 // send [super ...] is actually calling an instance method on the
3439 // current object. Build the super expression and handle this like
3440 // an instance method.
3441 QualType SuperTy = Context.getObjCInterfaceType(CDecl);
3442 SuperTy = Context.getObjCObjectPointerType(SuperTy);
3443 OwningExprResult Super
3444 = Owned(new (Context) ObjCSuperExpr(SuperLoc, SuperTy));
3445 return CodeCompleteObjCInstanceMessage(S, (Expr *)Super.get(),
3446 SelIdents, NumSelIdents);
3447 }
3448
3449 // Fall through to send to the superclass in CDecl.
3450 } else {
3451 // "super" may be the name of a type or variable. Figure out which
3452 // it is.
3453 IdentifierInfo *Super = &Context.Idents.get("super");
3454 NamedDecl *ND = LookupSingleName(S, Super, SuperLoc,
3455 LookupOrdinaryName);
3456 if ((CDecl = dyn_cast_or_null<ObjCInterfaceDecl>(ND))) {
3457 // "super" names an interface. Use it.
3458 } else if (TypeDecl *TD = dyn_cast_or_null<TypeDecl>(ND)) {
John McCall8b07ec22010-05-15 11:32:37 +00003459 if (const ObjCObjectType *Iface
3460 = Context.getTypeDeclType(TD)->getAs<ObjCObjectType>())
3461 CDecl = Iface->getInterface();
Douglas Gregor0c78ad92010-04-21 19:57:20 +00003462 } else if (ND && isa<UnresolvedUsingTypenameDecl>(ND)) {
3463 // "super" names an unresolved type; we can't be more specific.
3464 } else {
3465 // Assume that "super" names some kind of value and parse that way.
3466 CXXScopeSpec SS;
3467 UnqualifiedId id;
3468 id.setIdentifier(Super, SuperLoc);
3469 OwningExprResult SuperExpr = ActOnIdExpression(S, SS, id, false, false);
3470 return CodeCompleteObjCInstanceMessage(S, (Expr *)SuperExpr.get(),
3471 SelIdents, NumSelIdents);
3472 }
3473
3474 // Fall through
3475 }
3476
3477 TypeTy *Receiver = 0;
3478 if (CDecl)
3479 Receiver = Context.getObjCInterfaceType(CDecl).getAsOpaquePtr();
3480 return CodeCompleteObjCClassMessage(S, Receiver, SelIdents,
3481 NumSelIdents);
3482}
3483
3484void Sema::CodeCompleteObjCClassMessage(Scope *S, TypeTy *Receiver,
Douglas Gregor1b605f72009-11-19 01:08:35 +00003485 IdentifierInfo **SelIdents,
3486 unsigned NumSelIdents) {
Steve Naroffeae65032009-11-07 02:08:14 +00003487 typedef CodeCompleteConsumer::Result Result;
Douglas Gregor8ce33212009-11-17 17:59:40 +00003488 ObjCInterfaceDecl *CDecl = 0;
3489
Douglas Gregor8ce33212009-11-17 17:59:40 +00003490 // If the given name refers to an interface type, retrieve the
3491 // corresponding declaration.
Douglas Gregor0c78ad92010-04-21 19:57:20 +00003492 if (Receiver) {
3493 QualType T = GetTypeFromParser(Receiver, 0);
3494 if (!T.isNull())
John McCall8b07ec22010-05-15 11:32:37 +00003495 if (const ObjCObjectType *Interface = T->getAs<ObjCObjectType>())
3496 CDecl = Interface->getInterface();
Douglas Gregor8ce33212009-11-17 17:59:40 +00003497 }
3498
Douglas Gregorbab2b3c2009-11-17 23:22:23 +00003499 // Add all of the factory methods in this Objective-C class, its protocols,
3500 // superclasses, categories, implementation, etc.
Steve Naroffeae65032009-11-07 02:08:14 +00003501 ResultBuilder Results(*this);
3502 Results.EnterNewScope();
Douglas Gregor6285f752010-04-06 16:40:00 +00003503
3504 if (CDecl)
3505 AddObjCMethods(CDecl, false, MK_Any, SelIdents, NumSelIdents, CurContext,
3506 Results);
Douglas Gregor0c78ad92010-04-21 19:57:20 +00003507 else {
Douglas Gregor6285f752010-04-06 16:40:00 +00003508 // We're messaging "id" as a type; provide all class/factory methods.
3509
Douglas Gregord720daf2010-04-06 17:30:22 +00003510 // If we have an external source, load the entire class method
3511 // pool from the PCH file.
3512 if (ExternalSource) {
John McCall75b960e2010-06-01 09:23:16 +00003513 for (uint32_t I = 0, N = ExternalSource->GetNumExternalSelectors();
3514 I != N; ++I) {
3515 Selector Sel = ExternalSource->GetExternalSelector(I);
Douglas Gregord720daf2010-04-06 17:30:22 +00003516 if (Sel.isNull() || FactoryMethodPool.count(Sel) ||
3517 InstanceMethodPool.count(Sel))
3518 continue;
3519
3520 ReadMethodPool(Sel, /*isInstance=*/false);
3521 }
3522 }
3523
Douglas Gregor6285f752010-04-06 16:40:00 +00003524 for (llvm::DenseMap<Selector, ObjCMethodList>::iterator
3525 M = FactoryMethodPool.begin(),
3526 MEnd = FactoryMethodPool.end();
3527 M != MEnd;
3528 ++M) {
Douglas Gregord720daf2010-04-06 17:30:22 +00003529 for (ObjCMethodList *MethList = &M->second; MethList && MethList->Method;
Douglas Gregor6285f752010-04-06 16:40:00 +00003530 MethList = MethList->Next) {
3531 if (!isAcceptableObjCMethod(MethList->Method, MK_Any, SelIdents,
3532 NumSelIdents))
3533 continue;
3534
3535 Result R(MethList->Method, 0);
3536 R.StartParameter = NumSelIdents;
3537 R.AllParametersAreInformative = false;
3538 Results.MaybeAddResult(R, CurContext);
3539 }
3540 }
3541 }
3542
Steve Naroffeae65032009-11-07 02:08:14 +00003543 Results.ExitScope();
Daniel Dunbar242ea9a2009-11-13 08:58:20 +00003544 HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
Steve Naroffeae65032009-11-07 02:08:14 +00003545}
3546
Douglas Gregor1b605f72009-11-19 01:08:35 +00003547void Sema::CodeCompleteObjCInstanceMessage(Scope *S, ExprTy *Receiver,
3548 IdentifierInfo **SelIdents,
3549 unsigned NumSelIdents) {
Steve Naroffeae65032009-11-07 02:08:14 +00003550 typedef CodeCompleteConsumer::Result Result;
Steve Naroffeae65032009-11-07 02:08:14 +00003551
3552 Expr *RecExpr = static_cast<Expr *>(Receiver);
Steve Naroffeae65032009-11-07 02:08:14 +00003553
Douglas Gregorbab2b3c2009-11-17 23:22:23 +00003554 // If necessary, apply function/array conversion to the receiver.
3555 // C99 6.7.5.3p[7,8].
Douglas Gregorb92a1562010-02-03 00:27:59 +00003556 DefaultFunctionArrayLvalueConversion(RecExpr);
Douglas Gregorbab2b3c2009-11-17 23:22:23 +00003557 QualType ReceiverType = RecExpr->getType();
Steve Naroffeae65032009-11-07 02:08:14 +00003558
Douglas Gregorbab2b3c2009-11-17 23:22:23 +00003559 // Build the set of methods we can see.
3560 ResultBuilder Results(*this);
3561 Results.EnterNewScope();
Douglas Gregor9d2ddb22010-04-06 19:22:33 +00003562
3563 // If we're messaging an expression with type "id" or "Class", check
3564 // whether we know something special about the receiver that allows
3565 // us to assume a more-specific receiver type.
3566 if (ReceiverType->isObjCIdType() || ReceiverType->isObjCClassType())
3567 if (ObjCInterfaceDecl *IFace = GetAssumedMessageSendExprType(RecExpr))
3568 ReceiverType = Context.getObjCObjectPointerType(
3569 Context.getObjCInterfaceType(IFace));
Douglas Gregorbab2b3c2009-11-17 23:22:23 +00003570
Douglas Gregora3329fa2009-11-18 00:06:18 +00003571 // Handle messages to Class. This really isn't a message to an instance
3572 // method, so we treat it the same way we would treat a message send to a
3573 // class method.
3574 if (ReceiverType->isObjCClassType() ||
3575 ReceiverType->isObjCQualifiedClassType()) {
3576 if (ObjCMethodDecl *CurMethod = getCurMethodDecl()) {
3577 if (ObjCInterfaceDecl *ClassDecl = CurMethod->getClassInterface())
Douglas Gregorc8537c52009-11-19 07:41:15 +00003578 AddObjCMethods(ClassDecl, false, MK_Any, SelIdents, NumSelIdents,
3579 CurContext, Results);
Douglas Gregora3329fa2009-11-18 00:06:18 +00003580 }
3581 }
3582 // Handle messages to a qualified ID ("id<foo>").
3583 else if (const ObjCObjectPointerType *QualID
3584 = ReceiverType->getAsObjCQualifiedIdType()) {
3585 // Search protocols for instance methods.
3586 for (ObjCObjectPointerType::qual_iterator I = QualID->qual_begin(),
3587 E = QualID->qual_end();
3588 I != E; ++I)
Douglas Gregorc8537c52009-11-19 07:41:15 +00003589 AddObjCMethods(*I, true, MK_Any, SelIdents, NumSelIdents, CurContext,
3590 Results);
Douglas Gregora3329fa2009-11-18 00:06:18 +00003591 }
3592 // Handle messages to a pointer to interface type.
3593 else if (const ObjCObjectPointerType *IFacePtr
3594 = ReceiverType->getAsObjCInterfacePointerType()) {
3595 // Search the class, its superclasses, etc., for instance methods.
Douglas Gregorc8537c52009-11-19 07:41:15 +00003596 AddObjCMethods(IFacePtr->getInterfaceDecl(), true, MK_Any, SelIdents,
3597 NumSelIdents, CurContext, Results);
Douglas Gregora3329fa2009-11-18 00:06:18 +00003598
3599 // Search protocols for instance methods.
3600 for (ObjCObjectPointerType::qual_iterator I = IFacePtr->qual_begin(),
3601 E = IFacePtr->qual_end();
3602 I != E; ++I)
Douglas Gregorc8537c52009-11-19 07:41:15 +00003603 AddObjCMethods(*I, true, MK_Any, SelIdents, NumSelIdents, CurContext,
3604 Results);
Douglas Gregora3329fa2009-11-18 00:06:18 +00003605 }
Douglas Gregor6285f752010-04-06 16:40:00 +00003606 // Handle messages to "id".
3607 else if (ReceiverType->isObjCIdType()) {
Douglas Gregord720daf2010-04-06 17:30:22 +00003608 // We're messaging "id", so provide all instance methods we know
3609 // about as code-completion results.
3610
3611 // If we have an external source, load the entire class method
3612 // pool from the PCH file.
3613 if (ExternalSource) {
John McCall75b960e2010-06-01 09:23:16 +00003614 for (uint32_t I = 0, N = ExternalSource->GetNumExternalSelectors();
3615 I != N; ++I) {
3616 Selector Sel = ExternalSource->GetExternalSelector(I);
Douglas Gregord720daf2010-04-06 17:30:22 +00003617 if (Sel.isNull() || InstanceMethodPool.count(Sel) ||
3618 FactoryMethodPool.count(Sel))
3619 continue;
3620
3621 ReadMethodPool(Sel, /*isInstance=*/true);
3622 }
3623 }
3624
Douglas Gregor6285f752010-04-06 16:40:00 +00003625 for (llvm::DenseMap<Selector, ObjCMethodList>::iterator
3626 M = InstanceMethodPool.begin(),
3627 MEnd = InstanceMethodPool.end();
3628 M != MEnd;
3629 ++M) {
Douglas Gregord720daf2010-04-06 17:30:22 +00003630 for (ObjCMethodList *MethList = &M->second; MethList && MethList->Method;
Douglas Gregor6285f752010-04-06 16:40:00 +00003631 MethList = MethList->Next) {
3632 if (!isAcceptableObjCMethod(MethList->Method, MK_Any, SelIdents,
3633 NumSelIdents))
3634 continue;
3635
3636 Result R(MethList->Method, 0);
3637 R.StartParameter = NumSelIdents;
3638 R.AllParametersAreInformative = false;
3639 Results.MaybeAddResult(R, CurContext);
3640 }
3641 }
3642 }
3643
Steve Naroffeae65032009-11-07 02:08:14 +00003644 Results.ExitScope();
Daniel Dunbar242ea9a2009-11-13 08:58:20 +00003645 HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
Steve Naroffeae65032009-11-07 02:08:14 +00003646}
Douglas Gregorbaf69612009-11-18 04:19:12 +00003647
3648/// \brief Add all of the protocol declarations that we find in the given
3649/// (translation unit) context.
3650static void AddProtocolResults(DeclContext *Ctx, DeclContext *CurContext,
Douglas Gregor5b4671c2009-11-18 04:49:41 +00003651 bool OnlyForwardDeclarations,
Douglas Gregorbaf69612009-11-18 04:19:12 +00003652 ResultBuilder &Results) {
3653 typedef CodeCompleteConsumer::Result Result;
3654
3655 for (DeclContext::decl_iterator D = Ctx->decls_begin(),
3656 DEnd = Ctx->decls_end();
3657 D != DEnd; ++D) {
3658 // Record any protocols we find.
3659 if (ObjCProtocolDecl *Proto = dyn_cast<ObjCProtocolDecl>(*D))
Douglas Gregor5b4671c2009-11-18 04:49:41 +00003660 if (!OnlyForwardDeclarations || Proto->isForwardDecl())
Douglas Gregorfc59ce12010-01-14 16:14:35 +00003661 Results.AddResult(Result(Proto, 0), CurContext, 0, false);
Douglas Gregorbaf69612009-11-18 04:19:12 +00003662
3663 // Record any forward-declared protocols we find.
3664 if (ObjCForwardProtocolDecl *Forward
3665 = dyn_cast<ObjCForwardProtocolDecl>(*D)) {
3666 for (ObjCForwardProtocolDecl::protocol_iterator
3667 P = Forward->protocol_begin(),
3668 PEnd = Forward->protocol_end();
3669 P != PEnd; ++P)
Douglas Gregor5b4671c2009-11-18 04:49:41 +00003670 if (!OnlyForwardDeclarations || (*P)->isForwardDecl())
Douglas Gregorfc59ce12010-01-14 16:14:35 +00003671 Results.AddResult(Result(*P, 0), CurContext, 0, false);
Douglas Gregorbaf69612009-11-18 04:19:12 +00003672 }
3673 }
3674}
3675
3676void Sema::CodeCompleteObjCProtocolReferences(IdentifierLocPair *Protocols,
3677 unsigned NumProtocols) {
3678 ResultBuilder Results(*this);
3679 Results.EnterNewScope();
3680
3681 // Tell the result set to ignore all of the protocols we have
3682 // already seen.
3683 for (unsigned I = 0; I != NumProtocols; ++I)
Douglas Gregorb2ccf012010-04-15 22:33:43 +00003684 if (ObjCProtocolDecl *Protocol = LookupProtocol(Protocols[I].first,
3685 Protocols[I].second))
Douglas Gregorbaf69612009-11-18 04:19:12 +00003686 Results.Ignore(Protocol);
3687
3688 // Add all protocols.
Douglas Gregor5b4671c2009-11-18 04:49:41 +00003689 AddProtocolResults(Context.getTranslationUnitDecl(), CurContext, false,
3690 Results);
3691
3692 Results.ExitScope();
3693 HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
3694}
3695
3696void Sema::CodeCompleteObjCProtocolDecl(Scope *) {
3697 ResultBuilder Results(*this);
3698 Results.EnterNewScope();
3699
3700 // Add all protocols.
3701 AddProtocolResults(Context.getTranslationUnitDecl(), CurContext, true,
3702 Results);
Douglas Gregorbaf69612009-11-18 04:19:12 +00003703
3704 Results.ExitScope();
3705 HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
3706}
Douglas Gregor49c22a72009-11-18 16:26:39 +00003707
3708/// \brief Add all of the Objective-C interface declarations that we find in
3709/// the given (translation unit) context.
3710static void AddInterfaceResults(DeclContext *Ctx, DeclContext *CurContext,
3711 bool OnlyForwardDeclarations,
3712 bool OnlyUnimplemented,
3713 ResultBuilder &Results) {
3714 typedef CodeCompleteConsumer::Result Result;
3715
3716 for (DeclContext::decl_iterator D = Ctx->decls_begin(),
3717 DEnd = Ctx->decls_end();
3718 D != DEnd; ++D) {
3719 // Record any interfaces we find.
3720 if (ObjCInterfaceDecl *Class = dyn_cast<ObjCInterfaceDecl>(*D))
3721 if ((!OnlyForwardDeclarations || Class->isForwardDecl()) &&
3722 (!OnlyUnimplemented || !Class->getImplementation()))
Douglas Gregorfc59ce12010-01-14 16:14:35 +00003723 Results.AddResult(Result(Class, 0), CurContext, 0, false);
Douglas Gregor49c22a72009-11-18 16:26:39 +00003724
3725 // Record any forward-declared interfaces we find.
3726 if (ObjCClassDecl *Forward = dyn_cast<ObjCClassDecl>(*D)) {
3727 for (ObjCClassDecl::iterator C = Forward->begin(), CEnd = Forward->end();
3728 C != CEnd; ++C)
3729 if ((!OnlyForwardDeclarations || C->getInterface()->isForwardDecl()) &&
3730 (!OnlyUnimplemented || !C->getInterface()->getImplementation()))
Douglas Gregorfc59ce12010-01-14 16:14:35 +00003731 Results.AddResult(Result(C->getInterface(), 0), CurContext,
3732 0, false);
Douglas Gregor49c22a72009-11-18 16:26:39 +00003733 }
3734 }
3735}
3736
3737void Sema::CodeCompleteObjCInterfaceDecl(Scope *S) {
3738 ResultBuilder Results(*this);
3739 Results.EnterNewScope();
3740
3741 // Add all classes.
3742 AddInterfaceResults(Context.getTranslationUnitDecl(), CurContext, true,
3743 false, Results);
3744
3745 Results.ExitScope();
3746 HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
3747}
3748
Douglas Gregorb2ccf012010-04-15 22:33:43 +00003749void Sema::CodeCompleteObjCSuperclass(Scope *S, IdentifierInfo *ClassName,
3750 SourceLocation ClassNameLoc) {
Douglas Gregor49c22a72009-11-18 16:26:39 +00003751 ResultBuilder Results(*this);
3752 Results.EnterNewScope();
3753
3754 // Make sure that we ignore the class we're currently defining.
3755 NamedDecl *CurClass
Douglas Gregorb2ccf012010-04-15 22:33:43 +00003756 = LookupSingleName(TUScope, ClassName, ClassNameLoc, LookupOrdinaryName);
Douglas Gregor5d34fd32009-11-18 19:08:43 +00003757 if (CurClass && isa<ObjCInterfaceDecl>(CurClass))
Douglas Gregor49c22a72009-11-18 16:26:39 +00003758 Results.Ignore(CurClass);
3759
3760 // Add all classes.
3761 AddInterfaceResults(Context.getTranslationUnitDecl(), CurContext, false,
3762 false, Results);
3763
3764 Results.ExitScope();
3765 HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
3766}
3767
3768void Sema::CodeCompleteObjCImplementationDecl(Scope *S) {
3769 ResultBuilder Results(*this);
3770 Results.EnterNewScope();
3771
3772 // Add all unimplemented classes.
3773 AddInterfaceResults(Context.getTranslationUnitDecl(), CurContext, false,
3774 true, Results);
3775
3776 Results.ExitScope();
3777 HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
3778}
Douglas Gregor5d34fd32009-11-18 19:08:43 +00003779
3780void Sema::CodeCompleteObjCInterfaceCategory(Scope *S,
Douglas Gregorb2ccf012010-04-15 22:33:43 +00003781 IdentifierInfo *ClassName,
3782 SourceLocation ClassNameLoc) {
Douglas Gregor5d34fd32009-11-18 19:08:43 +00003783 typedef CodeCompleteConsumer::Result Result;
3784
3785 ResultBuilder Results(*this);
3786
3787 // Ignore any categories we find that have already been implemented by this
3788 // interface.
3789 llvm::SmallPtrSet<IdentifierInfo *, 16> CategoryNames;
3790 NamedDecl *CurClass
Douglas Gregorb2ccf012010-04-15 22:33:43 +00003791 = LookupSingleName(TUScope, ClassName, ClassNameLoc, LookupOrdinaryName);
Douglas Gregor5d34fd32009-11-18 19:08:43 +00003792 if (ObjCInterfaceDecl *Class = dyn_cast_or_null<ObjCInterfaceDecl>(CurClass))
3793 for (ObjCCategoryDecl *Category = Class->getCategoryList(); Category;
3794 Category = Category->getNextClassCategory())
3795 CategoryNames.insert(Category->getIdentifier());
3796
3797 // Add all of the categories we know about.
3798 Results.EnterNewScope();
3799 TranslationUnitDecl *TU = Context.getTranslationUnitDecl();
3800 for (DeclContext::decl_iterator D = TU->decls_begin(),
3801 DEnd = TU->decls_end();
3802 D != DEnd; ++D)
3803 if (ObjCCategoryDecl *Category = dyn_cast<ObjCCategoryDecl>(*D))
3804 if (CategoryNames.insert(Category->getIdentifier()))
Douglas Gregorfc59ce12010-01-14 16:14:35 +00003805 Results.AddResult(Result(Category, 0), CurContext, 0, false);
Douglas Gregor5d34fd32009-11-18 19:08:43 +00003806 Results.ExitScope();
3807
3808 HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
3809}
3810
3811void Sema::CodeCompleteObjCImplementationCategory(Scope *S,
Douglas Gregorb2ccf012010-04-15 22:33:43 +00003812 IdentifierInfo *ClassName,
3813 SourceLocation ClassNameLoc) {
Douglas Gregor5d34fd32009-11-18 19:08:43 +00003814 typedef CodeCompleteConsumer::Result Result;
3815
3816 // Find the corresponding interface. If we couldn't find the interface, the
3817 // program itself is ill-formed. However, we'll try to be helpful still by
3818 // providing the list of all of the categories we know about.
3819 NamedDecl *CurClass
Douglas Gregorb2ccf012010-04-15 22:33:43 +00003820 = LookupSingleName(TUScope, ClassName, ClassNameLoc, LookupOrdinaryName);
Douglas Gregor5d34fd32009-11-18 19:08:43 +00003821 ObjCInterfaceDecl *Class = dyn_cast_or_null<ObjCInterfaceDecl>(CurClass);
3822 if (!Class)
Douglas Gregorb2ccf012010-04-15 22:33:43 +00003823 return CodeCompleteObjCInterfaceCategory(S, ClassName, ClassNameLoc);
Douglas Gregor5d34fd32009-11-18 19:08:43 +00003824
3825 ResultBuilder Results(*this);
3826
3827 // Add all of the categories that have have corresponding interface
3828 // declarations in this class and any of its superclasses, except for
3829 // already-implemented categories in the class itself.
3830 llvm::SmallPtrSet<IdentifierInfo *, 16> CategoryNames;
3831 Results.EnterNewScope();
3832 bool IgnoreImplemented = true;
3833 while (Class) {
3834 for (ObjCCategoryDecl *Category = Class->getCategoryList(); Category;
3835 Category = Category->getNextClassCategory())
3836 if ((!IgnoreImplemented || !Category->getImplementation()) &&
3837 CategoryNames.insert(Category->getIdentifier()))
Douglas Gregorfc59ce12010-01-14 16:14:35 +00003838 Results.AddResult(Result(Category, 0), CurContext, 0, false);
Douglas Gregor5d34fd32009-11-18 19:08:43 +00003839
3840 Class = Class->getSuperClass();
3841 IgnoreImplemented = false;
3842 }
3843 Results.ExitScope();
3844
3845 HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
3846}
Douglas Gregor5d649882009-11-18 22:32:06 +00003847
Douglas Gregor52e78bd2009-11-18 22:56:13 +00003848void Sema::CodeCompleteObjCPropertyDefinition(Scope *S, DeclPtrTy ObjCImpDecl) {
Douglas Gregor5d649882009-11-18 22:32:06 +00003849 typedef CodeCompleteConsumer::Result Result;
3850 ResultBuilder Results(*this);
3851
3852 // Figure out where this @synthesize lives.
3853 ObjCContainerDecl *Container
3854 = dyn_cast_or_null<ObjCContainerDecl>(ObjCImpDecl.getAs<Decl>());
3855 if (!Container ||
3856 (!isa<ObjCImplementationDecl>(Container) &&
3857 !isa<ObjCCategoryImplDecl>(Container)))
3858 return;
3859
3860 // Ignore any properties that have already been implemented.
3861 for (DeclContext::decl_iterator D = Container->decls_begin(),
3862 DEnd = Container->decls_end();
3863 D != DEnd; ++D)
3864 if (ObjCPropertyImplDecl *PropertyImpl = dyn_cast<ObjCPropertyImplDecl>(*D))
3865 Results.Ignore(PropertyImpl->getPropertyDecl());
3866
3867 // Add any properties that we find.
3868 Results.EnterNewScope();
3869 if (ObjCImplementationDecl *ClassImpl
3870 = dyn_cast<ObjCImplementationDecl>(Container))
3871 AddObjCProperties(ClassImpl->getClassInterface(), false, CurContext,
3872 Results);
3873 else
3874 AddObjCProperties(cast<ObjCCategoryImplDecl>(Container)->getCategoryDecl(),
3875 false, CurContext, Results);
3876 Results.ExitScope();
3877
3878 HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
3879}
3880
3881void Sema::CodeCompleteObjCPropertySynthesizeIvar(Scope *S,
3882 IdentifierInfo *PropertyName,
3883 DeclPtrTy ObjCImpDecl) {
3884 typedef CodeCompleteConsumer::Result Result;
3885 ResultBuilder Results(*this);
3886
3887 // Figure out where this @synthesize lives.
3888 ObjCContainerDecl *Container
3889 = dyn_cast_or_null<ObjCContainerDecl>(ObjCImpDecl.getAs<Decl>());
3890 if (!Container ||
3891 (!isa<ObjCImplementationDecl>(Container) &&
3892 !isa<ObjCCategoryImplDecl>(Container)))
3893 return;
3894
3895 // Figure out which interface we're looking into.
3896 ObjCInterfaceDecl *Class = 0;
3897 if (ObjCImplementationDecl *ClassImpl
3898 = dyn_cast<ObjCImplementationDecl>(Container))
3899 Class = ClassImpl->getClassInterface();
3900 else
3901 Class = cast<ObjCCategoryImplDecl>(Container)->getCategoryDecl()
3902 ->getClassInterface();
3903
3904 // Add all of the instance variables in this class and its superclasses.
3905 Results.EnterNewScope();
3906 for(; Class; Class = Class->getSuperClass()) {
3907 // FIXME: We could screen the type of each ivar for compatibility with
3908 // the property, but is that being too paternal?
3909 for (ObjCInterfaceDecl::ivar_iterator IVar = Class->ivar_begin(),
3910 IVarEnd = Class->ivar_end();
3911 IVar != IVarEnd; ++IVar)
Douglas Gregorfc59ce12010-01-14 16:14:35 +00003912 Results.AddResult(Result(*IVar, 0), CurContext, 0, false);
Douglas Gregor5d649882009-11-18 22:32:06 +00003913 }
3914 Results.ExitScope();
3915
3916 HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
3917}
Douglas Gregor636a61e2010-04-07 00:21:17 +00003918
3919typedef llvm::DenseMap<Selector, ObjCMethodDecl *> KnownMethodsMap;
3920
3921/// \brief Find all of the methods that reside in the given container
3922/// (and its superclasses, protocols, etc.) that meet the given
3923/// criteria. Insert those methods into the map of known methods,
3924/// indexed by selector so they can be easily found.
3925static void FindImplementableMethods(ASTContext &Context,
3926 ObjCContainerDecl *Container,
3927 bool WantInstanceMethods,
3928 QualType ReturnType,
3929 bool IsInImplementation,
3930 KnownMethodsMap &KnownMethods) {
3931 if (ObjCInterfaceDecl *IFace = dyn_cast<ObjCInterfaceDecl>(Container)) {
3932 // Recurse into protocols.
3933 const ObjCList<ObjCProtocolDecl> &Protocols
3934 = IFace->getReferencedProtocols();
3935 for (ObjCList<ObjCProtocolDecl>::iterator I = Protocols.begin(),
3936 E = Protocols.end();
3937 I != E; ++I)
3938 FindImplementableMethods(Context, *I, WantInstanceMethods, ReturnType,
3939 IsInImplementation, KnownMethods);
3940
3941 // If we're not in the implementation of a class, also visit the
3942 // superclass.
3943 if (!IsInImplementation && IFace->getSuperClass())
3944 FindImplementableMethods(Context, IFace->getSuperClass(),
3945 WantInstanceMethods, ReturnType,
3946 IsInImplementation, KnownMethods);
3947
3948 // Add methods from any class extensions (but not from categories;
3949 // those should go into category implementations).
Fariborz Jahanian3bf0ded2010-06-22 23:20:40 +00003950 for (const ObjCCategoryDecl *Cat = IFace->getFirstClassExtension(); Cat;
3951 Cat = Cat->getNextClassExtension())
3952 FindImplementableMethods(Context, const_cast<ObjCCategoryDecl*>(Cat),
3953 WantInstanceMethods, ReturnType,
Douglas Gregor636a61e2010-04-07 00:21:17 +00003954 IsInImplementation, KnownMethods);
Douglas Gregor636a61e2010-04-07 00:21:17 +00003955 }
3956
3957 if (ObjCCategoryDecl *Category = dyn_cast<ObjCCategoryDecl>(Container)) {
3958 // Recurse into protocols.
3959 const ObjCList<ObjCProtocolDecl> &Protocols
3960 = Category->getReferencedProtocols();
3961 for (ObjCList<ObjCProtocolDecl>::iterator I = Protocols.begin(),
3962 E = Protocols.end();
3963 I != E; ++I)
3964 FindImplementableMethods(Context, *I, WantInstanceMethods, ReturnType,
3965 IsInImplementation, KnownMethods);
3966 }
3967
3968 if (ObjCProtocolDecl *Protocol = dyn_cast<ObjCProtocolDecl>(Container)) {
3969 // Recurse into protocols.
3970 const ObjCList<ObjCProtocolDecl> &Protocols
3971 = Protocol->getReferencedProtocols();
3972 for (ObjCList<ObjCProtocolDecl>::iterator I = Protocols.begin(),
3973 E = Protocols.end();
3974 I != E; ++I)
3975 FindImplementableMethods(Context, *I, WantInstanceMethods, ReturnType,
3976 IsInImplementation, KnownMethods);
3977 }
3978
3979 // Add methods in this container. This operation occurs last because
3980 // we want the methods from this container to override any methods
3981 // we've previously seen with the same selector.
3982 for (ObjCContainerDecl::method_iterator M = Container->meth_begin(),
3983 MEnd = Container->meth_end();
3984 M != MEnd; ++M) {
3985 if ((*M)->isInstanceMethod() == WantInstanceMethods) {
3986 if (!ReturnType.isNull() &&
3987 !Context.hasSameUnqualifiedType(ReturnType, (*M)->getResultType()))
3988 continue;
3989
3990 KnownMethods[(*M)->getSelector()] = *M;
3991 }
3992 }
3993}
3994
3995void Sema::CodeCompleteObjCMethodDecl(Scope *S,
3996 bool IsInstanceMethod,
3997 TypeTy *ReturnTy,
3998 DeclPtrTy IDecl) {
3999 // Determine the return type of the method we're declaring, if
4000 // provided.
4001 QualType ReturnType = GetTypeFromParser(ReturnTy);
4002
4003 // Determine where we should start searching for methods, and where we
4004 ObjCContainerDecl *SearchDecl = 0, *CurrentDecl = 0;
4005 bool IsInImplementation = false;
4006 if (Decl *D = IDecl.getAs<Decl>()) {
4007 if (ObjCImplementationDecl *Impl = dyn_cast<ObjCImplementationDecl>(D)) {
4008 SearchDecl = Impl->getClassInterface();
4009 CurrentDecl = Impl;
4010 IsInImplementation = true;
4011 } else if (ObjCCategoryImplDecl *CatImpl
4012 = dyn_cast<ObjCCategoryImplDecl>(D)) {
4013 SearchDecl = CatImpl->getCategoryDecl();
4014 CurrentDecl = CatImpl;
4015 IsInImplementation = true;
4016 } else {
4017 SearchDecl = dyn_cast<ObjCContainerDecl>(D);
4018 CurrentDecl = SearchDecl;
4019 }
4020 }
4021
4022 if (!SearchDecl && S) {
4023 if (DeclContext *DC = static_cast<DeclContext *>(S->getEntity())) {
4024 SearchDecl = dyn_cast<ObjCContainerDecl>(DC);
4025 CurrentDecl = SearchDecl;
4026 }
4027 }
4028
4029 if (!SearchDecl || !CurrentDecl) {
4030 HandleCodeCompleteResults(this, CodeCompleter, 0, 0);
4031 return;
4032 }
4033
4034 // Find all of the methods that we could declare/implement here.
4035 KnownMethodsMap KnownMethods;
4036 FindImplementableMethods(Context, SearchDecl, IsInstanceMethod,
4037 ReturnType, IsInImplementation, KnownMethods);
4038
4039 // Erase any methods that have already been declared or
4040 // implemented here.
4041 for (ObjCContainerDecl::method_iterator M = CurrentDecl->meth_begin(),
4042 MEnd = CurrentDecl->meth_end();
4043 M != MEnd; ++M) {
4044 if ((*M)->isInstanceMethod() != IsInstanceMethod)
4045 continue;
4046
4047 KnownMethodsMap::iterator Pos = KnownMethods.find((*M)->getSelector());
4048 if (Pos != KnownMethods.end())
4049 KnownMethods.erase(Pos);
4050 }
4051
4052 // Add declarations or definitions for each of the known methods.
4053 typedef CodeCompleteConsumer::Result Result;
4054 ResultBuilder Results(*this);
4055 Results.EnterNewScope();
4056 PrintingPolicy Policy(Context.PrintingPolicy);
4057 Policy.AnonymousTagLocations = false;
4058 for (KnownMethodsMap::iterator M = KnownMethods.begin(),
4059 MEnd = KnownMethods.end();
4060 M != MEnd; ++M) {
4061 ObjCMethodDecl *Method = M->second;
4062 CodeCompletionString *Pattern = new CodeCompletionString;
4063
4064 // If the result type was not already provided, add it to the
4065 // pattern as (type).
4066 if (ReturnType.isNull()) {
4067 std::string TypeStr;
4068 Method->getResultType().getAsStringInternal(TypeStr, Policy);
4069 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
4070 Pattern->AddTextChunk(TypeStr);
4071 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
4072 }
4073
4074 Selector Sel = Method->getSelector();
4075
4076 // Add the first part of the selector to the pattern.
4077 Pattern->AddTypedTextChunk(Sel.getIdentifierInfoForSlot(0)->getName());
4078
4079 // Add parameters to the pattern.
4080 unsigned I = 0;
4081 for (ObjCMethodDecl::param_iterator P = Method->param_begin(),
4082 PEnd = Method->param_end();
4083 P != PEnd; (void)++P, ++I) {
4084 // Add the part of the selector name.
4085 if (I == 0)
4086 Pattern->AddChunk(CodeCompletionString::CK_Colon);
4087 else if (I < Sel.getNumArgs()) {
4088 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
4089 Pattern->AddTextChunk(Sel.getIdentifierInfoForSlot(1)->getName());
4090 Pattern->AddChunk(CodeCompletionString::CK_Colon);
4091 } else
4092 break;
4093
4094 // Add the parameter type.
4095 std::string TypeStr;
4096 (*P)->getOriginalType().getAsStringInternal(TypeStr, Policy);
4097 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
4098 Pattern->AddTextChunk(TypeStr);
4099 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
4100
4101 if (IdentifierInfo *Id = (*P)->getIdentifier())
4102 Pattern->AddTextChunk(Id->getName());
4103 }
4104
4105 if (Method->isVariadic()) {
4106 if (Method->param_size() > 0)
4107 Pattern->AddChunk(CodeCompletionString::CK_Comma);
4108 Pattern->AddTextChunk("...");
4109 }
4110
Douglas Gregord37c59d2010-05-28 00:57:46 +00004111 if (IsInImplementation && Results.includeCodePatterns()) {
Douglas Gregor636a61e2010-04-07 00:21:17 +00004112 // We will be defining the method here, so add a compound statement.
4113 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
4114 Pattern->AddChunk(CodeCompletionString::CK_LeftBrace);
4115 Pattern->AddChunk(CodeCompletionString::CK_VerticalSpace);
4116 if (!Method->getResultType()->isVoidType()) {
4117 // If the result type is not void, add a return clause.
4118 Pattern->AddTextChunk("return");
4119 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
4120 Pattern->AddPlaceholderChunk("expression");
4121 Pattern->AddChunk(CodeCompletionString::CK_SemiColon);
4122 } else
4123 Pattern->AddPlaceholderChunk("statements");
4124
4125 Pattern->AddChunk(CodeCompletionString::CK_VerticalSpace);
4126 Pattern->AddChunk(CodeCompletionString::CK_RightBrace);
4127 }
4128
4129 Results.AddResult(Result(Pattern));
4130 }
4131
4132 Results.ExitScope();
4133
4134 HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
4135}