blob: 4228bed9ee0f4b694b92aa641fe2864daf4b3ef6 [file] [log] [blame]
Douglas Gregor2436e712009-09-17 21:32:03 +00001//===---------------- SemaCodeComplete.cpp - Code Completion ----*- C++ -*-===//
2//
3// The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9//
10// This file defines the code-completion semantic actions.
11//
12//===----------------------------------------------------------------------===//
Douglas Gregorc3a6ade2010-08-12 20:07:10 +000013#include "clang/Sema/Sema.h"
14#include "clang/Sema/Lookup.h"
John McCall5c32be02010-08-24 20:38:10 +000015#include "clang/Sema/Overload.h"
Douglas Gregor2436e712009-09-17 21:32:03 +000016#include "clang/Sema/CodeCompleteConsumer.h"
Douglas Gregord720daf2010-04-06 17:30:22 +000017#include "clang/Sema/ExternalSemaSource.h"
John McCallcc14d1f2010-08-24 08:50:51 +000018#include "clang/Sema/Scope.h"
John McCallde6836a2010-08-24 07:21:54 +000019#include "clang/AST/DeclObjC.h"
Douglas Gregorf2510672009-09-21 19:57:38 +000020#include "clang/AST/ExprCXX.h"
Douglas Gregor8ce33212009-11-17 17:59:40 +000021#include "clang/AST/ExprObjC.h"
Douglas Gregorf329c7c2009-10-30 16:50:04 +000022#include "clang/Lex/MacroInfo.h"
23#include "clang/Lex/Preprocessor.h"
Douglas Gregor3545ff42009-09-21 16:56:56 +000024#include "llvm/ADT/SmallPtrSet.h"
Douglas Gregore6688e62009-09-28 03:51:44 +000025#include "llvm/ADT/StringExtras.h"
Douglas Gregor9d2ddb22010-04-06 19:22:33 +000026#include "llvm/ADT/StringSwitch.h"
Douglas Gregor3545ff42009-09-21 16:56:56 +000027#include <list>
28#include <map>
29#include <vector>
Douglas Gregor2436e712009-09-17 21:32:03 +000030
31using namespace clang;
32
Douglas Gregor3545ff42009-09-21 16:56:56 +000033namespace {
34 /// \brief A container of code-completion results.
35 class ResultBuilder {
36 public:
37 /// \brief The type of a name-lookup filter, which can be provided to the
38 /// name-lookup routines to specify which declarations should be included in
39 /// the result set (when it returns true) and which declarations should be
40 /// filtered out (returns false).
41 typedef bool (ResultBuilder::*LookupFilter)(NamedDecl *) const;
42
John McCall276321a2010-08-25 06:19:51 +000043 typedef CodeCompletionResult Result;
Douglas Gregor3545ff42009-09-21 16:56:56 +000044
45 private:
46 /// \brief The actual results we have found.
47 std::vector<Result> Results;
48
49 /// \brief A record of all of the declarations we have found and placed
50 /// into the result set, used to ensure that no declaration ever gets into
51 /// the result set twice.
52 llvm::SmallPtrSet<Decl*, 16> AllDeclsFound;
53
Douglas Gregor05e7ca32009-12-06 20:23:50 +000054 typedef std::pair<NamedDecl *, unsigned> DeclIndexPair;
55
56 /// \brief An entry in the shadow map, which is optimized to store
57 /// a single (declaration, index) mapping (the common case) but
58 /// can also store a list of (declaration, index) mappings.
59 class ShadowMapEntry {
60 typedef llvm::SmallVector<DeclIndexPair, 4> DeclIndexPairVector;
61
62 /// \brief Contains either the solitary NamedDecl * or a vector
63 /// of (declaration, index) pairs.
64 llvm::PointerUnion<NamedDecl *, DeclIndexPairVector*> DeclOrVector;
65
66 /// \brief When the entry contains a single declaration, this is
67 /// the index associated with that entry.
68 unsigned SingleDeclIndex;
69
70 public:
71 ShadowMapEntry() : DeclOrVector(), SingleDeclIndex(0) { }
72
73 void Add(NamedDecl *ND, unsigned Index) {
74 if (DeclOrVector.isNull()) {
75 // 0 - > 1 elements: just set the single element information.
76 DeclOrVector = ND;
77 SingleDeclIndex = Index;
78 return;
79 }
80
81 if (NamedDecl *PrevND = DeclOrVector.dyn_cast<NamedDecl *>()) {
82 // 1 -> 2 elements: create the vector of results and push in the
83 // existing declaration.
84 DeclIndexPairVector *Vec = new DeclIndexPairVector;
85 Vec->push_back(DeclIndexPair(PrevND, SingleDeclIndex));
86 DeclOrVector = Vec;
87 }
88
89 // Add the new element to the end of the vector.
90 DeclOrVector.get<DeclIndexPairVector*>()->push_back(
91 DeclIndexPair(ND, Index));
92 }
93
94 void Destroy() {
95 if (DeclIndexPairVector *Vec
96 = DeclOrVector.dyn_cast<DeclIndexPairVector *>()) {
97 delete Vec;
98 DeclOrVector = ((NamedDecl *)0);
99 }
100 }
101
102 // Iteration.
103 class iterator;
104 iterator begin() const;
105 iterator end() const;
106 };
107
Douglas Gregor3545ff42009-09-21 16:56:56 +0000108 /// \brief A mapping from declaration names to the declarations that have
109 /// this name within a particular scope and their index within the list of
110 /// results.
Douglas Gregor05e7ca32009-12-06 20:23:50 +0000111 typedef llvm::DenseMap<DeclarationName, ShadowMapEntry> ShadowMap;
Douglas Gregor3545ff42009-09-21 16:56:56 +0000112
113 /// \brief The semantic analysis object for which results are being
114 /// produced.
115 Sema &SemaRef;
116
117 /// \brief If non-NULL, a filter function used to remove any code-completion
118 /// results that are not desirable.
119 LookupFilter Filter;
Douglas Gregor6ae4c522010-01-14 03:21:49 +0000120
121 /// \brief Whether we should allow declarations as
122 /// nested-name-specifiers that would otherwise be filtered out.
123 bool AllowNestedNameSpecifiers;
124
Douglas Gregor7aa6b222010-05-30 01:49:25 +0000125 /// \brief If set, the type that we would prefer our resulting value
126 /// declarations to have.
127 ///
128 /// Closely matching the preferred type gives a boost to a result's
129 /// priority.
130 CanQualType PreferredType;
131
Douglas Gregor3545ff42009-09-21 16:56:56 +0000132 /// \brief A list of shadow maps, which is used to model name hiding at
133 /// different levels of, e.g., the inheritance hierarchy.
134 std::list<ShadowMap> ShadowMaps;
135
Douglas Gregor95887f92010-07-08 23:20:03 +0000136 void AdjustResultPriorityForPreferredType(Result &R);
137
Douglas Gregor3545ff42009-09-21 16:56:56 +0000138 public:
139 explicit ResultBuilder(Sema &SemaRef, LookupFilter Filter = 0)
Douglas Gregor6ae4c522010-01-14 03:21:49 +0000140 : SemaRef(SemaRef), Filter(Filter), AllowNestedNameSpecifiers(false) { }
Douglas Gregor3545ff42009-09-21 16:56:56 +0000141
Douglas Gregorf64acca2010-05-25 21:41:55 +0000142 /// \brief Whether we should include code patterns in the completion
143 /// results.
144 bool includeCodePatterns() const {
145 return SemaRef.CodeCompleter &&
146 SemaRef.CodeCompleter->includeCodePatterns();
147 }
148
Douglas Gregor3545ff42009-09-21 16:56:56 +0000149 /// \brief Set the filter used for code-completion results.
150 void setFilter(LookupFilter Filter) {
151 this->Filter = Filter;
152 }
153
154 typedef std::vector<Result>::iterator iterator;
155 iterator begin() { return Results.begin(); }
156 iterator end() { return Results.end(); }
157
158 Result *data() { return Results.empty()? 0 : &Results.front(); }
159 unsigned size() const { return Results.size(); }
160 bool empty() const { return Results.empty(); }
161
Douglas Gregor7aa6b222010-05-30 01:49:25 +0000162 /// \brief Specify the preferred type.
163 void setPreferredType(QualType T) {
164 PreferredType = SemaRef.Context.getCanonicalType(T);
165 }
166
Douglas Gregor6ae4c522010-01-14 03:21:49 +0000167 /// \brief Specify whether nested-name-specifiers are allowed.
168 void allowNestedNameSpecifiers(bool Allow = true) {
169 AllowNestedNameSpecifiers = Allow;
170 }
171
Douglas Gregor7c208612010-01-14 00:20:49 +0000172 /// \brief Determine whether the given declaration is at all interesting
173 /// as a code-completion result.
Douglas Gregor6ae4c522010-01-14 03:21:49 +0000174 ///
175 /// \param ND the declaration that we are inspecting.
176 ///
177 /// \param AsNestedNameSpecifier will be set true if this declaration is
178 /// only interesting when it is a nested-name-specifier.
179 bool isInterestingDecl(NamedDecl *ND, bool &AsNestedNameSpecifier) const;
Douglas Gregore0717ab2010-01-14 00:41:07 +0000180
181 /// \brief Check whether the result is hidden by the Hiding declaration.
182 ///
183 /// \returns true if the result is hidden and cannot be found, false if
184 /// the hidden result could still be found. When false, \p R may be
185 /// modified to describe how the result can be found (e.g., via extra
186 /// qualification).
187 bool CheckHiddenResult(Result &R, DeclContext *CurContext,
188 NamedDecl *Hiding);
189
Douglas Gregor3545ff42009-09-21 16:56:56 +0000190 /// \brief Add a new result to this result set (if it isn't already in one
191 /// of the shadow maps), or replace an existing result (for, e.g., a
192 /// redeclaration).
Douglas Gregor2af2f672009-09-21 20:12:40 +0000193 ///
Douglas Gregorc580c522010-01-14 01:09:38 +0000194 /// \param CurContext the result to add (if it is unique).
Douglas Gregor2af2f672009-09-21 20:12:40 +0000195 ///
196 /// \param R the context in which this result will be named.
197 void MaybeAddResult(Result R, DeclContext *CurContext = 0);
Douglas Gregor3545ff42009-09-21 16:56:56 +0000198
Douglas Gregorc580c522010-01-14 01:09:38 +0000199 /// \brief Add a new result to this result set, where we already know
200 /// the hiding declation (if any).
201 ///
202 /// \param R the result to add (if it is unique).
203 ///
204 /// \param CurContext the context in which this result will be named.
205 ///
206 /// \param Hiding the declaration that hides the result.
Douglas Gregor09bbc652010-01-14 15:47:35 +0000207 ///
208 /// \param InBaseClass whether the result was found in a base
209 /// class of the searched context.
210 void AddResult(Result R, DeclContext *CurContext, NamedDecl *Hiding,
211 bool InBaseClass);
Douglas Gregorc580c522010-01-14 01:09:38 +0000212
Douglas Gregor78a21012010-01-14 16:01:26 +0000213 /// \brief Add a new non-declaration result to this result set.
214 void AddResult(Result R);
215
Douglas Gregor3545ff42009-09-21 16:56:56 +0000216 /// \brief Enter into a new scope.
217 void EnterNewScope();
218
219 /// \brief Exit from the current scope.
220 void ExitScope();
221
Douglas Gregorbaf69612009-11-18 04:19:12 +0000222 /// \brief Ignore this declaration, if it is seen again.
223 void Ignore(Decl *D) { AllDeclsFound.insert(D->getCanonicalDecl()); }
224
Douglas Gregor3545ff42009-09-21 16:56:56 +0000225 /// \name Name lookup predicates
226 ///
227 /// These predicates can be passed to the name lookup functions to filter the
228 /// results of name lookup. All of the predicates have the same type, so that
229 ///
230 //@{
Douglas Gregor9d64c5e2009-09-21 20:51:25 +0000231 bool IsOrdinaryName(NamedDecl *ND) const;
Douglas Gregor70febae2010-05-28 00:49:12 +0000232 bool IsOrdinaryNonTypeName(NamedDecl *ND) const;
Douglas Gregor85b50632010-07-28 21:50:18 +0000233 bool IsIntegralConstantValue(NamedDecl *ND) const;
Douglas Gregor504a6ae2010-01-10 23:08:15 +0000234 bool IsOrdinaryNonValueName(NamedDecl *ND) const;
Douglas Gregor3545ff42009-09-21 16:56:56 +0000235 bool IsNestedNameSpecifier(NamedDecl *ND) const;
236 bool IsEnum(NamedDecl *ND) const;
237 bool IsClassOrStruct(NamedDecl *ND) const;
238 bool IsUnion(NamedDecl *ND) const;
239 bool IsNamespace(NamedDecl *ND) const;
240 bool IsNamespaceOrAlias(NamedDecl *ND) const;
241 bool IsType(NamedDecl *ND) const;
Douglas Gregore412a5a2009-09-23 22:26:46 +0000242 bool IsMember(NamedDecl *ND) const;
Douglas Gregor2b8162b2010-01-14 16:08:12 +0000243 bool IsObjCIvar(NamedDecl *ND) const;
Douglas Gregora817a192010-05-27 23:06:34 +0000244 bool IsObjCMessageReceiver(NamedDecl *ND) const;
Douglas Gregor68762e72010-08-23 21:17:50 +0000245 bool IsObjCCollection(NamedDecl *ND) const;
Douglas Gregor3545ff42009-09-21 16:56:56 +0000246 //@}
247 };
248}
249
Douglas Gregor05e7ca32009-12-06 20:23:50 +0000250class ResultBuilder::ShadowMapEntry::iterator {
251 llvm::PointerUnion<NamedDecl*, const DeclIndexPair*> DeclOrIterator;
252 unsigned SingleDeclIndex;
253
254public:
255 typedef DeclIndexPair value_type;
256 typedef value_type reference;
257 typedef std::ptrdiff_t difference_type;
258 typedef std::input_iterator_tag iterator_category;
259
260 class pointer {
261 DeclIndexPair Value;
262
263 public:
264 pointer(const DeclIndexPair &Value) : Value(Value) { }
265
266 const DeclIndexPair *operator->() const {
267 return &Value;
268 }
269 };
270
271 iterator() : DeclOrIterator((NamedDecl *)0), SingleDeclIndex(0) { }
272
273 iterator(NamedDecl *SingleDecl, unsigned Index)
274 : DeclOrIterator(SingleDecl), SingleDeclIndex(Index) { }
275
276 iterator(const DeclIndexPair *Iterator)
277 : DeclOrIterator(Iterator), SingleDeclIndex(0) { }
278
279 iterator &operator++() {
280 if (DeclOrIterator.is<NamedDecl *>()) {
281 DeclOrIterator = (NamedDecl *)0;
282 SingleDeclIndex = 0;
283 return *this;
284 }
285
286 const DeclIndexPair *I = DeclOrIterator.get<const DeclIndexPair*>();
287 ++I;
288 DeclOrIterator = I;
289 return *this;
290 }
291
292 iterator operator++(int) {
293 iterator tmp(*this);
294 ++(*this);
295 return tmp;
296 }
297
298 reference operator*() const {
299 if (NamedDecl *ND = DeclOrIterator.dyn_cast<NamedDecl *>())
300 return reference(ND, SingleDeclIndex);
301
Douglas Gregor94bb5e82009-12-06 21:27:58 +0000302 return *DeclOrIterator.get<const DeclIndexPair*>();
Douglas Gregor05e7ca32009-12-06 20:23:50 +0000303 }
304
305 pointer operator->() const {
306 return pointer(**this);
307 }
308
309 friend bool operator==(const iterator &X, const iterator &Y) {
Douglas Gregor94bb5e82009-12-06 21:27:58 +0000310 return X.DeclOrIterator.getOpaqueValue()
311 == Y.DeclOrIterator.getOpaqueValue() &&
Douglas Gregor05e7ca32009-12-06 20:23:50 +0000312 X.SingleDeclIndex == Y.SingleDeclIndex;
313 }
314
315 friend bool operator!=(const iterator &X, const iterator &Y) {
Douglas Gregor94bb5e82009-12-06 21:27:58 +0000316 return !(X == Y);
Douglas Gregor05e7ca32009-12-06 20:23:50 +0000317 }
318};
319
Douglas Gregor05e7ca32009-12-06 20:23:50 +0000320ResultBuilder::ShadowMapEntry::iterator
321ResultBuilder::ShadowMapEntry::begin() const {
322 if (DeclOrVector.isNull())
323 return iterator();
324
325 if (NamedDecl *ND = DeclOrVector.dyn_cast<NamedDecl *>())
326 return iterator(ND, SingleDeclIndex);
327
328 return iterator(DeclOrVector.get<DeclIndexPairVector *>()->begin());
329}
330
331ResultBuilder::ShadowMapEntry::iterator
332ResultBuilder::ShadowMapEntry::end() const {
333 if (DeclOrVector.is<NamedDecl *>() || DeclOrVector.isNull())
334 return iterator();
335
336 return iterator(DeclOrVector.get<DeclIndexPairVector *>()->end());
337}
338
Douglas Gregor2af2f672009-09-21 20:12:40 +0000339/// \brief Compute the qualification required to get from the current context
340/// (\p CurContext) to the target context (\p TargetContext).
341///
342/// \param Context the AST context in which the qualification will be used.
343///
344/// \param CurContext the context where an entity is being named, which is
345/// typically based on the current scope.
346///
347/// \param TargetContext the context in which the named entity actually
348/// resides.
349///
350/// \returns a nested name specifier that refers into the target context, or
351/// NULL if no qualification is needed.
352static NestedNameSpecifier *
353getRequiredQualification(ASTContext &Context,
354 DeclContext *CurContext,
355 DeclContext *TargetContext) {
356 llvm::SmallVector<DeclContext *, 4> TargetParents;
357
358 for (DeclContext *CommonAncestor = TargetContext;
359 CommonAncestor && !CommonAncestor->Encloses(CurContext);
360 CommonAncestor = CommonAncestor->getLookupParent()) {
361 if (CommonAncestor->isTransparentContext() ||
362 CommonAncestor->isFunctionOrMethod())
363 continue;
364
365 TargetParents.push_back(CommonAncestor);
366 }
367
368 NestedNameSpecifier *Result = 0;
369 while (!TargetParents.empty()) {
370 DeclContext *Parent = TargetParents.back();
371 TargetParents.pop_back();
372
Douglas Gregor68762e72010-08-23 21:17:50 +0000373 if (NamespaceDecl *Namespace = dyn_cast<NamespaceDecl>(Parent)) {
374 if (!Namespace->getIdentifier())
375 continue;
376
Douglas Gregor2af2f672009-09-21 20:12:40 +0000377 Result = NestedNameSpecifier::Create(Context, Result, Namespace);
Douglas Gregor68762e72010-08-23 21:17:50 +0000378 }
Douglas Gregor2af2f672009-09-21 20:12:40 +0000379 else if (TagDecl *TD = dyn_cast<TagDecl>(Parent))
380 Result = NestedNameSpecifier::Create(Context, Result,
381 false,
382 Context.getTypeDeclType(TD).getTypePtr());
Douglas Gregor9eb77012009-11-07 00:00:49 +0000383 }
Douglas Gregor2af2f672009-09-21 20:12:40 +0000384 return Result;
385}
386
Douglas Gregor6ae4c522010-01-14 03:21:49 +0000387bool ResultBuilder::isInterestingDecl(NamedDecl *ND,
388 bool &AsNestedNameSpecifier) const {
389 AsNestedNameSpecifier = false;
390
Douglas Gregor7c208612010-01-14 00:20:49 +0000391 ND = ND->getUnderlyingDecl();
392 unsigned IDNS = ND->getIdentifierNamespace();
Douglas Gregor58acf322009-10-09 22:16:47 +0000393
394 // Skip unnamed entities.
Douglas Gregor7c208612010-01-14 00:20:49 +0000395 if (!ND->getDeclName())
396 return false;
Douglas Gregor3545ff42009-09-21 16:56:56 +0000397
398 // Friend declarations and declarations introduced due to friends are never
399 // added as results.
John McCallbbbbe4e2010-03-11 07:50:04 +0000400 if (IDNS & (Decl::IDNS_OrdinaryFriend | Decl::IDNS_TagFriend))
Douglas Gregor7c208612010-01-14 00:20:49 +0000401 return false;
402
Douglas Gregor99fe2ad2009-12-11 17:31:05 +0000403 // Class template (partial) specializations are never added as results.
Douglas Gregor7c208612010-01-14 00:20:49 +0000404 if (isa<ClassTemplateSpecializationDecl>(ND) ||
405 isa<ClassTemplatePartialSpecializationDecl>(ND))
406 return false;
Douglas Gregor3545ff42009-09-21 16:56:56 +0000407
Douglas Gregor99fe2ad2009-12-11 17:31:05 +0000408 // Using declarations themselves are never added as results.
Douglas Gregor7c208612010-01-14 00:20:49 +0000409 if (isa<UsingDecl>(ND))
410 return false;
411
412 // Some declarations have reserved names that we don't want to ever show.
413 if (const IdentifierInfo *Id = ND->getIdentifier()) {
Douglas Gregor3545ff42009-09-21 16:56:56 +0000414 // __va_list_tag is a freak of nature. Find it and skip it.
415 if (Id->isStr("__va_list_tag") || Id->isStr("__builtin_va_list"))
Douglas Gregor7c208612010-01-14 00:20:49 +0000416 return false;
Douglas Gregor3545ff42009-09-21 16:56:56 +0000417
Douglas Gregor58acf322009-10-09 22:16:47 +0000418 // Filter out names reserved for the implementation (C99 7.1.3,
Douglas Gregor9f1570d2010-07-14 17:44:04 +0000419 // C++ [lib.global.names]) if they come from a system header.
Daniel Dunbar2c422dc92009-10-18 20:26:12 +0000420 //
421 // FIXME: Add predicate for this.
Douglas Gregor58acf322009-10-09 22:16:47 +0000422 if (Id->getLength() >= 2) {
Daniel Dunbar2c422dc92009-10-18 20:26:12 +0000423 const char *Name = Id->getNameStart();
Douglas Gregor58acf322009-10-09 22:16:47 +0000424 if (Name[0] == '_' &&
Douglas Gregor9f1570d2010-07-14 17:44:04 +0000425 (Name[1] == '_' || (Name[1] >= 'A' && Name[1] <= 'Z')) &&
426 (ND->getLocation().isInvalid() ||
427 SemaRef.SourceMgr.isInSystemHeader(
428 SemaRef.SourceMgr.getSpellingLoc(ND->getLocation()))))
Douglas Gregor7c208612010-01-14 00:20:49 +0000429 return false;
Douglas Gregor58acf322009-10-09 22:16:47 +0000430 }
Douglas Gregor3545ff42009-09-21 16:56:56 +0000431 }
Douglas Gregor7c208612010-01-14 00:20:49 +0000432
Douglas Gregor3545ff42009-09-21 16:56:56 +0000433 // C++ constructors are never found by name lookup.
Douglas Gregor7c208612010-01-14 00:20:49 +0000434 if (isa<CXXConstructorDecl>(ND))
435 return false;
Douglas Gregor3545ff42009-09-21 16:56:56 +0000436
Douglas Gregor59cab552010-08-16 23:05:20 +0000437 if (Filter == &ResultBuilder::IsNestedNameSpecifier ||
438 ((isa<NamespaceDecl>(ND) || isa<NamespaceAliasDecl>(ND)) &&
439 Filter != &ResultBuilder::IsNamespace &&
440 Filter != &ResultBuilder::IsNamespaceOrAlias))
441 AsNestedNameSpecifier = true;
442
Douglas Gregor3545ff42009-09-21 16:56:56 +0000443 // Filter out any unwanted results.
Douglas Gregor6ae4c522010-01-14 03:21:49 +0000444 if (Filter && !(this->*Filter)(ND)) {
445 // Check whether it is interesting as a nested-name-specifier.
446 if (AllowNestedNameSpecifiers && SemaRef.getLangOptions().CPlusPlus &&
447 IsNestedNameSpecifier(ND) &&
448 (Filter != &ResultBuilder::IsMember ||
449 (isa<CXXRecordDecl>(ND) &&
450 cast<CXXRecordDecl>(ND)->isInjectedClassName()))) {
451 AsNestedNameSpecifier = true;
452 return true;
453 }
454
Douglas Gregor7c208612010-01-14 00:20:49 +0000455 return false;
Douglas Gregor59cab552010-08-16 23:05:20 +0000456 }
Douglas Gregor7c208612010-01-14 00:20:49 +0000457 // ... then it must be interesting!
458 return true;
459}
460
Douglas Gregore0717ab2010-01-14 00:41:07 +0000461bool ResultBuilder::CheckHiddenResult(Result &R, DeclContext *CurContext,
462 NamedDecl *Hiding) {
463 // In C, there is no way to refer to a hidden name.
464 // FIXME: This isn't true; we can find a tag name hidden by an ordinary
465 // name if we introduce the tag type.
466 if (!SemaRef.getLangOptions().CPlusPlus)
467 return true;
468
469 DeclContext *HiddenCtx = R.Declaration->getDeclContext()->getLookupContext();
470
471 // There is no way to qualify a name declared in a function or method.
472 if (HiddenCtx->isFunctionOrMethod())
473 return true;
474
475 if (HiddenCtx == Hiding->getDeclContext()->getLookupContext())
476 return true;
477
478 // We can refer to the result with the appropriate qualification. Do it.
479 R.Hidden = true;
480 R.QualifierIsInformative = false;
481
482 if (!R.Qualifier)
483 R.Qualifier = getRequiredQualification(SemaRef.Context,
484 CurContext,
485 R.Declaration->getDeclContext());
486 return false;
487}
488
Douglas Gregor95887f92010-07-08 23:20:03 +0000489/// \brief A simplified classification of types used to determine whether two
490/// types are "similar enough" when adjusting priorities.
Douglas Gregor6e240332010-08-16 16:18:59 +0000491SimplifiedTypeClass clang::getSimplifiedTypeClass(CanQualType T) {
Douglas Gregor95887f92010-07-08 23:20:03 +0000492 switch (T->getTypeClass()) {
493 case Type::Builtin:
494 switch (cast<BuiltinType>(T)->getKind()) {
495 case BuiltinType::Void:
496 return STC_Void;
497
498 case BuiltinType::NullPtr:
499 return STC_Pointer;
500
501 case BuiltinType::Overload:
502 case BuiltinType::Dependent:
503 case BuiltinType::UndeducedAuto:
504 return STC_Other;
505
506 case BuiltinType::ObjCId:
507 case BuiltinType::ObjCClass:
508 case BuiltinType::ObjCSel:
509 return STC_ObjectiveC;
510
511 default:
512 return STC_Arithmetic;
513 }
514 return STC_Other;
515
516 case Type::Complex:
517 return STC_Arithmetic;
518
519 case Type::Pointer:
520 return STC_Pointer;
521
522 case Type::BlockPointer:
523 return STC_Block;
524
525 case Type::LValueReference:
526 case Type::RValueReference:
527 return getSimplifiedTypeClass(T->getAs<ReferenceType>()->getPointeeType());
528
529 case Type::ConstantArray:
530 case Type::IncompleteArray:
531 case Type::VariableArray:
532 case Type::DependentSizedArray:
533 return STC_Array;
534
535 case Type::DependentSizedExtVector:
536 case Type::Vector:
537 case Type::ExtVector:
538 return STC_Arithmetic;
539
540 case Type::FunctionProto:
541 case Type::FunctionNoProto:
542 return STC_Function;
543
544 case Type::Record:
545 return STC_Record;
546
547 case Type::Enum:
548 return STC_Arithmetic;
549
550 case Type::ObjCObject:
551 case Type::ObjCInterface:
552 case Type::ObjCObjectPointer:
553 return STC_ObjectiveC;
554
555 default:
556 return STC_Other;
557 }
558}
559
560/// \brief Get the type that a given expression will have if this declaration
561/// is used as an expression in its "typical" code-completion form.
Douglas Gregor6e240332010-08-16 16:18:59 +0000562QualType clang::getDeclUsageType(ASTContext &C, NamedDecl *ND) {
Douglas Gregor95887f92010-07-08 23:20:03 +0000563 ND = cast<NamedDecl>(ND->getUnderlyingDecl());
564
565 if (TypeDecl *Type = dyn_cast<TypeDecl>(ND))
566 return C.getTypeDeclType(Type);
567 if (ObjCInterfaceDecl *Iface = dyn_cast<ObjCInterfaceDecl>(ND))
568 return C.getObjCInterfaceType(Iface);
569
570 QualType T;
571 if (FunctionDecl *Function = dyn_cast<FunctionDecl>(ND))
Douglas Gregor603d81b2010-07-13 08:18:22 +0000572 T = Function->getCallResultType();
Douglas Gregor95887f92010-07-08 23:20:03 +0000573 else if (ObjCMethodDecl *Method = dyn_cast<ObjCMethodDecl>(ND))
Douglas Gregor603d81b2010-07-13 08:18:22 +0000574 T = Method->getSendResultType();
Douglas Gregor95887f92010-07-08 23:20:03 +0000575 else if (FunctionTemplateDecl *FunTmpl = dyn_cast<FunctionTemplateDecl>(ND))
Douglas Gregor603d81b2010-07-13 08:18:22 +0000576 T = FunTmpl->getTemplatedDecl()->getCallResultType();
Douglas Gregor95887f92010-07-08 23:20:03 +0000577 else if (EnumConstantDecl *Enumerator = dyn_cast<EnumConstantDecl>(ND))
578 T = C.getTypeDeclType(cast<EnumDecl>(Enumerator->getDeclContext()));
579 else if (ObjCPropertyDecl *Property = dyn_cast<ObjCPropertyDecl>(ND))
580 T = Property->getType();
581 else if (ValueDecl *Value = dyn_cast<ValueDecl>(ND))
582 T = Value->getType();
583 else
584 return QualType();
585
586 return T.getNonReferenceType();
587}
588
589void ResultBuilder::AdjustResultPriorityForPreferredType(Result &R) {
590 QualType T = getDeclUsageType(SemaRef.Context, R.Declaration);
591 if (T.isNull())
592 return;
593
594 CanQualType TC = SemaRef.Context.getCanonicalType(T);
595 // Check for exactly-matching types (modulo qualifiers).
Douglas Gregor4d755e82010-08-24 23:58:17 +0000596 if (SemaRef.Context.hasSameUnqualifiedType(PreferredType, TC)) {
597 if (PreferredType->isVoidType())
598 R.Priority += CCD_VoidMatch;
599 else
600 R.Priority /= CCF_ExactTypeMatch;
601 } // Check for nearly-matching types, based on classification of each.
Douglas Gregor95887f92010-07-08 23:20:03 +0000602 else if ((getSimplifiedTypeClass(PreferredType)
603 == getSimplifiedTypeClass(TC)) &&
604 !(PreferredType->isEnumeralType() && TC->isEnumeralType()))
605 R.Priority /= CCF_SimilarTypeMatch;
606}
607
Douglas Gregor7c208612010-01-14 00:20:49 +0000608void ResultBuilder::MaybeAddResult(Result R, DeclContext *CurContext) {
609 assert(!ShadowMaps.empty() && "Must enter into a results scope");
610
611 if (R.Kind != Result::RK_Declaration) {
612 // For non-declaration results, just add the result.
613 Results.push_back(R);
614 return;
615 }
616
617 // Look through using declarations.
618 if (UsingShadowDecl *Using = dyn_cast<UsingShadowDecl>(R.Declaration)) {
619 MaybeAddResult(Result(Using->getTargetDecl(), R.Qualifier), CurContext);
620 return;
621 }
622
623 Decl *CanonDecl = R.Declaration->getCanonicalDecl();
624 unsigned IDNS = CanonDecl->getIdentifierNamespace();
625
Douglas Gregor6ae4c522010-01-14 03:21:49 +0000626 bool AsNestedNameSpecifier = false;
627 if (!isInterestingDecl(R.Declaration, AsNestedNameSpecifier))
Douglas Gregor7c208612010-01-14 00:20:49 +0000628 return;
629
Douglas Gregor3545ff42009-09-21 16:56:56 +0000630 ShadowMap &SMap = ShadowMaps.back();
Douglas Gregor05e7ca32009-12-06 20:23:50 +0000631 ShadowMapEntry::iterator I, IEnd;
632 ShadowMap::iterator NamePos = SMap.find(R.Declaration->getDeclName());
633 if (NamePos != SMap.end()) {
634 I = NamePos->second.begin();
635 IEnd = NamePos->second.end();
636 }
637
638 for (; I != IEnd; ++I) {
639 NamedDecl *ND = I->first;
640 unsigned Index = I->second;
Douglas Gregor3545ff42009-09-21 16:56:56 +0000641 if (ND->getCanonicalDecl() == CanonDecl) {
642 // This is a redeclaration. Always pick the newer declaration.
Douglas Gregor3545ff42009-09-21 16:56:56 +0000643 Results[Index].Declaration = R.Declaration;
644
Douglas Gregor3545ff42009-09-21 16:56:56 +0000645 // We're done.
646 return;
647 }
648 }
649
650 // This is a new declaration in this scope. However, check whether this
651 // declaration name is hidden by a similarly-named declaration in an outer
652 // scope.
653 std::list<ShadowMap>::iterator SM, SMEnd = ShadowMaps.end();
654 --SMEnd;
655 for (SM = ShadowMaps.begin(); SM != SMEnd; ++SM) {
Douglas Gregor05e7ca32009-12-06 20:23:50 +0000656 ShadowMapEntry::iterator I, IEnd;
657 ShadowMap::iterator NamePos = SM->find(R.Declaration->getDeclName());
658 if (NamePos != SM->end()) {
659 I = NamePos->second.begin();
660 IEnd = NamePos->second.end();
661 }
662 for (; I != IEnd; ++I) {
Douglas Gregor3545ff42009-09-21 16:56:56 +0000663 // A tag declaration does not hide a non-tag declaration.
John McCalle87beb22010-04-23 18:46:30 +0000664 if (I->first->hasTagIdentifierNamespace() &&
Douglas Gregor3545ff42009-09-21 16:56:56 +0000665 (IDNS & (Decl::IDNS_Member | Decl::IDNS_Ordinary |
666 Decl::IDNS_ObjCProtocol)))
667 continue;
668
669 // Protocols are in distinct namespaces from everything else.
Douglas Gregor05e7ca32009-12-06 20:23:50 +0000670 if (((I->first->getIdentifierNamespace() & Decl::IDNS_ObjCProtocol)
Douglas Gregor3545ff42009-09-21 16:56:56 +0000671 || (IDNS & Decl::IDNS_ObjCProtocol)) &&
Douglas Gregor05e7ca32009-12-06 20:23:50 +0000672 I->first->getIdentifierNamespace() != IDNS)
Douglas Gregor3545ff42009-09-21 16:56:56 +0000673 continue;
674
675 // The newly-added result is hidden by an entry in the shadow map.
Douglas Gregore0717ab2010-01-14 00:41:07 +0000676 if (CheckHiddenResult(R, CurContext, I->first))
Douglas Gregor3545ff42009-09-21 16:56:56 +0000677 return;
Douglas Gregor3545ff42009-09-21 16:56:56 +0000678
679 break;
680 }
681 }
682
683 // Make sure that any given declaration only shows up in the result set once.
684 if (!AllDeclsFound.insert(CanonDecl))
685 return;
686
Douglas Gregore412a5a2009-09-23 22:26:46 +0000687 // If the filter is for nested-name-specifiers, then this result starts a
688 // nested-name-specifier.
Douglas Gregora2db7932010-05-26 22:00:08 +0000689 if (AsNestedNameSpecifier) {
Douglas Gregore412a5a2009-09-23 22:26:46 +0000690 R.StartsNestedNameSpecifier = true;
Douglas Gregora2db7932010-05-26 22:00:08 +0000691 R.Priority = CCP_NestedNameSpecifier;
Douglas Gregor95887f92010-07-08 23:20:03 +0000692 } else if (!PreferredType.isNull())
693 AdjustResultPriorityForPreferredType(R);
694
Douglas Gregor5bf52692009-09-22 23:15:58 +0000695 // If this result is supposed to have an informative qualifier, add one.
Douglas Gregore412a5a2009-09-23 22:26:46 +0000696 if (R.QualifierIsInformative && !R.Qualifier &&
697 !R.StartsNestedNameSpecifier) {
Douglas Gregor5bf52692009-09-22 23:15:58 +0000698 DeclContext *Ctx = R.Declaration->getDeclContext();
699 if (NamespaceDecl *Namespace = dyn_cast<NamespaceDecl>(Ctx))
700 R.Qualifier = NestedNameSpecifier::Create(SemaRef.Context, 0, Namespace);
701 else if (TagDecl *Tag = dyn_cast<TagDecl>(Ctx))
702 R.Qualifier = NestedNameSpecifier::Create(SemaRef.Context, 0, false,
703 SemaRef.Context.getTypeDeclType(Tag).getTypePtr());
704 else
705 R.QualifierIsInformative = false;
706 }
Douglas Gregore412a5a2009-09-23 22:26:46 +0000707
Douglas Gregor3545ff42009-09-21 16:56:56 +0000708 // Insert this result into the set of results and into the current shadow
709 // map.
Douglas Gregor05e7ca32009-12-06 20:23:50 +0000710 SMap[R.Declaration->getDeclName()].Add(R.Declaration, Results.size());
Douglas Gregor3545ff42009-09-21 16:56:56 +0000711 Results.push_back(R);
712}
713
Douglas Gregorc580c522010-01-14 01:09:38 +0000714void ResultBuilder::AddResult(Result R, DeclContext *CurContext,
Douglas Gregor09bbc652010-01-14 15:47:35 +0000715 NamedDecl *Hiding, bool InBaseClass = false) {
Douglas Gregor78a21012010-01-14 16:01:26 +0000716 if (R.Kind != Result::RK_Declaration) {
717 // For non-declaration results, just add the result.
718 Results.push_back(R);
719 return;
720 }
721
Douglas Gregorc580c522010-01-14 01:09:38 +0000722 // Look through using declarations.
723 if (UsingShadowDecl *Using = dyn_cast<UsingShadowDecl>(R.Declaration)) {
724 AddResult(Result(Using->getTargetDecl(), R.Qualifier), CurContext, Hiding);
725 return;
726 }
727
Douglas Gregor6ae4c522010-01-14 03:21:49 +0000728 bool AsNestedNameSpecifier = false;
729 if (!isInterestingDecl(R.Declaration, AsNestedNameSpecifier))
Douglas Gregorc580c522010-01-14 01:09:38 +0000730 return;
731
732 if (Hiding && CheckHiddenResult(R, CurContext, Hiding))
733 return;
734
735 // Make sure that any given declaration only shows up in the result set once.
736 if (!AllDeclsFound.insert(R.Declaration->getCanonicalDecl()))
737 return;
738
739 // If the filter is for nested-name-specifiers, then this result starts a
740 // nested-name-specifier.
Douglas Gregora2db7932010-05-26 22:00:08 +0000741 if (AsNestedNameSpecifier) {
Douglas Gregorc580c522010-01-14 01:09:38 +0000742 R.StartsNestedNameSpecifier = true;
Douglas Gregora2db7932010-05-26 22:00:08 +0000743 R.Priority = CCP_NestedNameSpecifier;
744 }
Douglas Gregor09bbc652010-01-14 15:47:35 +0000745 else if (Filter == &ResultBuilder::IsMember && !R.Qualifier && InBaseClass &&
746 isa<CXXRecordDecl>(R.Declaration->getDeclContext()
747 ->getLookupContext()))
748 R.QualifierIsInformative = true;
749
Douglas Gregorc580c522010-01-14 01:09:38 +0000750 // If this result is supposed to have an informative qualifier, add one.
751 if (R.QualifierIsInformative && !R.Qualifier &&
752 !R.StartsNestedNameSpecifier) {
753 DeclContext *Ctx = R.Declaration->getDeclContext();
754 if (NamespaceDecl *Namespace = dyn_cast<NamespaceDecl>(Ctx))
755 R.Qualifier = NestedNameSpecifier::Create(SemaRef.Context, 0, Namespace);
756 else if (TagDecl *Tag = dyn_cast<TagDecl>(Ctx))
757 R.Qualifier = NestedNameSpecifier::Create(SemaRef.Context, 0, false,
Douglas Gregor6ae4c522010-01-14 03:21:49 +0000758 SemaRef.Context.getTypeDeclType(Tag).getTypePtr());
Douglas Gregorc580c522010-01-14 01:09:38 +0000759 else
760 R.QualifierIsInformative = false;
761 }
762
Douglas Gregora2db7932010-05-26 22:00:08 +0000763 // Adjust the priority if this result comes from a base class.
764 if (InBaseClass)
765 R.Priority += CCD_InBaseClass;
766
Douglas Gregor95887f92010-07-08 23:20:03 +0000767 if (!PreferredType.isNull())
768 AdjustResultPriorityForPreferredType(R);
Douglas Gregor7aa6b222010-05-30 01:49:25 +0000769
Douglas Gregorc580c522010-01-14 01:09:38 +0000770 // Insert this result into the set of results.
771 Results.push_back(R);
772}
773
Douglas Gregor78a21012010-01-14 16:01:26 +0000774void ResultBuilder::AddResult(Result R) {
775 assert(R.Kind != Result::RK_Declaration &&
776 "Declaration results need more context");
777 Results.push_back(R);
778}
779
Douglas Gregor3545ff42009-09-21 16:56:56 +0000780/// \brief Enter into a new scope.
781void ResultBuilder::EnterNewScope() {
782 ShadowMaps.push_back(ShadowMap());
783}
784
785/// \brief Exit from the current scope.
786void ResultBuilder::ExitScope() {
Douglas Gregor05e7ca32009-12-06 20:23:50 +0000787 for (ShadowMap::iterator E = ShadowMaps.back().begin(),
788 EEnd = ShadowMaps.back().end();
789 E != EEnd;
790 ++E)
791 E->second.Destroy();
792
Douglas Gregor3545ff42009-09-21 16:56:56 +0000793 ShadowMaps.pop_back();
794}
795
Douglas Gregor9d64c5e2009-09-21 20:51:25 +0000796/// \brief Determines whether this given declaration will be found by
797/// ordinary name lookup.
798bool ResultBuilder::IsOrdinaryName(NamedDecl *ND) const {
Douglas Gregor70febae2010-05-28 00:49:12 +0000799 ND = cast<NamedDecl>(ND->getUnderlyingDecl());
800
Douglas Gregor9d64c5e2009-09-21 20:51:25 +0000801 unsigned IDNS = Decl::IDNS_Ordinary;
802 if (SemaRef.getLangOptions().CPlusPlus)
Douglas Gregor9858ed52010-06-15 20:26:51 +0000803 IDNS |= Decl::IDNS_Tag | Decl::IDNS_Namespace | Decl::IDNS_Member;
Douglas Gregorc580c522010-01-14 01:09:38 +0000804 else if (SemaRef.getLangOptions().ObjC1 && isa<ObjCIvarDecl>(ND))
805 return true;
806
Douglas Gregor9d64c5e2009-09-21 20:51:25 +0000807 return ND->getIdentifierNamespace() & IDNS;
808}
809
Douglas Gregor504a6ae2010-01-10 23:08:15 +0000810/// \brief Determines whether this given declaration will be found by
Douglas Gregor70febae2010-05-28 00:49:12 +0000811/// ordinary name lookup but is not a type name.
812bool ResultBuilder::IsOrdinaryNonTypeName(NamedDecl *ND) const {
813 ND = cast<NamedDecl>(ND->getUnderlyingDecl());
814 if (isa<TypeDecl>(ND) || isa<ObjCInterfaceDecl>(ND))
815 return false;
816
817 unsigned IDNS = Decl::IDNS_Ordinary;
818 if (SemaRef.getLangOptions().CPlusPlus)
Douglas Gregor9858ed52010-06-15 20:26:51 +0000819 IDNS |= Decl::IDNS_Tag | Decl::IDNS_Namespace | Decl::IDNS_Member;
Douglas Gregor70febae2010-05-28 00:49:12 +0000820 else if (SemaRef.getLangOptions().ObjC1 && isa<ObjCIvarDecl>(ND))
821 return true;
822
823 return ND->getIdentifierNamespace() & IDNS;
824}
825
Douglas Gregor85b50632010-07-28 21:50:18 +0000826bool ResultBuilder::IsIntegralConstantValue(NamedDecl *ND) const {
827 if (!IsOrdinaryNonTypeName(ND))
828 return 0;
829
830 if (ValueDecl *VD = dyn_cast<ValueDecl>(ND->getUnderlyingDecl()))
831 if (VD->getType()->isIntegralOrEnumerationType())
832 return true;
833
834 return false;
835}
836
Douglas Gregor70febae2010-05-28 00:49:12 +0000837/// \brief Determines whether this given declaration will be found by
Douglas Gregor504a6ae2010-01-10 23:08:15 +0000838/// ordinary name lookup.
839bool ResultBuilder::IsOrdinaryNonValueName(NamedDecl *ND) const {
Douglas Gregor70febae2010-05-28 00:49:12 +0000840 ND = cast<NamedDecl>(ND->getUnderlyingDecl());
841
Douglas Gregor504a6ae2010-01-10 23:08:15 +0000842 unsigned IDNS = Decl::IDNS_Ordinary;
843 if (SemaRef.getLangOptions().CPlusPlus)
John McCalle87beb22010-04-23 18:46:30 +0000844 IDNS |= Decl::IDNS_Tag | Decl::IDNS_Namespace;
Douglas Gregor504a6ae2010-01-10 23:08:15 +0000845
846 return (ND->getIdentifierNamespace() & IDNS) &&
Douglas Gregor70febae2010-05-28 00:49:12 +0000847 !isa<ValueDecl>(ND) && !isa<FunctionTemplateDecl>(ND) &&
848 !isa<ObjCPropertyDecl>(ND);
Douglas Gregor504a6ae2010-01-10 23:08:15 +0000849}
850
Douglas Gregor3545ff42009-09-21 16:56:56 +0000851/// \brief Determines whether the given declaration is suitable as the
852/// start of a C++ nested-name-specifier, e.g., a class or namespace.
853bool ResultBuilder::IsNestedNameSpecifier(NamedDecl *ND) const {
854 // Allow us to find class templates, too.
855 if (ClassTemplateDecl *ClassTemplate = dyn_cast<ClassTemplateDecl>(ND))
856 ND = ClassTemplate->getTemplatedDecl();
857
858 return SemaRef.isAcceptableNestedNameSpecifier(ND);
859}
860
861/// \brief Determines whether the given declaration is an enumeration.
862bool ResultBuilder::IsEnum(NamedDecl *ND) const {
863 return isa<EnumDecl>(ND);
864}
865
866/// \brief Determines whether the given declaration is a class or struct.
867bool ResultBuilder::IsClassOrStruct(NamedDecl *ND) const {
868 // Allow us to find class templates, too.
869 if (ClassTemplateDecl *ClassTemplate = dyn_cast<ClassTemplateDecl>(ND))
870 ND = ClassTemplate->getTemplatedDecl();
871
872 if (RecordDecl *RD = dyn_cast<RecordDecl>(ND))
Abramo Bagnara6150c882010-05-11 21:36:43 +0000873 return RD->getTagKind() == TTK_Class ||
874 RD->getTagKind() == TTK_Struct;
Douglas Gregor3545ff42009-09-21 16:56:56 +0000875
876 return false;
877}
878
879/// \brief Determines whether the given declaration is a union.
880bool ResultBuilder::IsUnion(NamedDecl *ND) const {
881 // Allow us to find class templates, too.
882 if (ClassTemplateDecl *ClassTemplate = dyn_cast<ClassTemplateDecl>(ND))
883 ND = ClassTemplate->getTemplatedDecl();
884
885 if (RecordDecl *RD = dyn_cast<RecordDecl>(ND))
Abramo Bagnara6150c882010-05-11 21:36:43 +0000886 return RD->getTagKind() == TTK_Union;
Douglas Gregor3545ff42009-09-21 16:56:56 +0000887
888 return false;
889}
890
891/// \brief Determines whether the given declaration is a namespace.
892bool ResultBuilder::IsNamespace(NamedDecl *ND) const {
893 return isa<NamespaceDecl>(ND);
894}
895
896/// \brief Determines whether the given declaration is a namespace or
897/// namespace alias.
898bool ResultBuilder::IsNamespaceOrAlias(NamedDecl *ND) const {
899 return isa<NamespaceDecl>(ND) || isa<NamespaceAliasDecl>(ND);
900}
901
Douglas Gregor99fe2ad2009-12-11 17:31:05 +0000902/// \brief Determines whether the given declaration is a type.
Douglas Gregor3545ff42009-09-21 16:56:56 +0000903bool ResultBuilder::IsType(NamedDecl *ND) const {
Douglas Gregor99fa2642010-08-24 01:06:58 +0000904 if (UsingShadowDecl *Using = dyn_cast<UsingShadowDecl>(ND))
905 ND = Using->getTargetDecl();
906
907 return isa<TypeDecl>(ND) || isa<ObjCInterfaceDecl>(ND);
Douglas Gregor3545ff42009-09-21 16:56:56 +0000908}
909
Douglas Gregor99fe2ad2009-12-11 17:31:05 +0000910/// \brief Determines which members of a class should be visible via
911/// "." or "->". Only value declarations, nested name specifiers, and
912/// using declarations thereof should show up.
Douglas Gregore412a5a2009-09-23 22:26:46 +0000913bool ResultBuilder::IsMember(NamedDecl *ND) const {
Douglas Gregor99fe2ad2009-12-11 17:31:05 +0000914 if (UsingShadowDecl *Using = dyn_cast<UsingShadowDecl>(ND))
915 ND = Using->getTargetDecl();
916
Douglas Gregor70788392009-12-11 18:14:22 +0000917 return isa<ValueDecl>(ND) || isa<FunctionTemplateDecl>(ND) ||
918 isa<ObjCPropertyDecl>(ND);
Douglas Gregore412a5a2009-09-23 22:26:46 +0000919}
920
Douglas Gregora817a192010-05-27 23:06:34 +0000921static bool isObjCReceiverType(ASTContext &C, QualType T) {
922 T = C.getCanonicalType(T);
923 switch (T->getTypeClass()) {
924 case Type::ObjCObject:
925 case Type::ObjCInterface:
926 case Type::ObjCObjectPointer:
927 return true;
928
929 case Type::Builtin:
930 switch (cast<BuiltinType>(T)->getKind()) {
931 case BuiltinType::ObjCId:
932 case BuiltinType::ObjCClass:
933 case BuiltinType::ObjCSel:
934 return true;
935
936 default:
937 break;
938 }
939 return false;
940
941 default:
942 break;
943 }
944
945 if (!C.getLangOptions().CPlusPlus)
946 return false;
947
948 // FIXME: We could perform more analysis here to determine whether a
949 // particular class type has any conversions to Objective-C types. For now,
950 // just accept all class types.
951 return T->isDependentType() || T->isRecordType();
952}
953
954bool ResultBuilder::IsObjCMessageReceiver(NamedDecl *ND) const {
955 QualType T = getDeclUsageType(SemaRef.Context, ND);
956 if (T.isNull())
957 return false;
958
959 T = SemaRef.Context.getBaseElementType(T);
960 return isObjCReceiverType(SemaRef.Context, T);
961}
962
Douglas Gregor68762e72010-08-23 21:17:50 +0000963bool ResultBuilder::IsObjCCollection(NamedDecl *ND) const {
964 if ((SemaRef.getLangOptions().CPlusPlus && !IsOrdinaryName(ND)) ||
965 (!SemaRef.getLangOptions().CPlusPlus && !IsOrdinaryNonTypeName(ND)))
966 return false;
967
968 QualType T = getDeclUsageType(SemaRef.Context, ND);
969 if (T.isNull())
970 return false;
971
972 T = SemaRef.Context.getBaseElementType(T);
973 return T->isObjCObjectType() || T->isObjCObjectPointerType() ||
974 T->isObjCIdType() ||
975 (SemaRef.getLangOptions().CPlusPlus && T->isRecordType());
976}
Douglas Gregora817a192010-05-27 23:06:34 +0000977
Douglas Gregor2b8162b2010-01-14 16:08:12 +0000978/// \rief Determines whether the given declaration is an Objective-C
979/// instance variable.
980bool ResultBuilder::IsObjCIvar(NamedDecl *ND) const {
981 return isa<ObjCIvarDecl>(ND);
982}
983
Douglas Gregorc580c522010-01-14 01:09:38 +0000984namespace {
985 /// \brief Visible declaration consumer that adds a code-completion result
986 /// for each visible declaration.
987 class CodeCompletionDeclConsumer : public VisibleDeclConsumer {
988 ResultBuilder &Results;
989 DeclContext *CurContext;
990
991 public:
992 CodeCompletionDeclConsumer(ResultBuilder &Results, DeclContext *CurContext)
993 : Results(Results), CurContext(CurContext) { }
994
Douglas Gregor09bbc652010-01-14 15:47:35 +0000995 virtual void FoundDecl(NamedDecl *ND, NamedDecl *Hiding, bool InBaseClass) {
996 Results.AddResult(ND, CurContext, Hiding, InBaseClass);
Douglas Gregorc580c522010-01-14 01:09:38 +0000997 }
998 };
999}
1000
Douglas Gregor3545ff42009-09-21 16:56:56 +00001001/// \brief Add type specifiers for the current language as keyword results.
Douglas Gregorf98e6a22010-01-13 23:51:12 +00001002static void AddTypeSpecifierResults(const LangOptions &LangOpts,
Douglas Gregor3545ff42009-09-21 16:56:56 +00001003 ResultBuilder &Results) {
John McCall276321a2010-08-25 06:19:51 +00001004 typedef CodeCompletionResult Result;
Douglas Gregora2db7932010-05-26 22:00:08 +00001005 Results.AddResult(Result("short", CCP_Type));
1006 Results.AddResult(Result("long", CCP_Type));
1007 Results.AddResult(Result("signed", CCP_Type));
1008 Results.AddResult(Result("unsigned", CCP_Type));
1009 Results.AddResult(Result("void", CCP_Type));
1010 Results.AddResult(Result("char", CCP_Type));
1011 Results.AddResult(Result("int", CCP_Type));
1012 Results.AddResult(Result("float", CCP_Type));
1013 Results.AddResult(Result("double", CCP_Type));
1014 Results.AddResult(Result("enum", CCP_Type));
1015 Results.AddResult(Result("struct", CCP_Type));
1016 Results.AddResult(Result("union", CCP_Type));
1017 Results.AddResult(Result("const", CCP_Type));
1018 Results.AddResult(Result("volatile", CCP_Type));
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001019
Douglas Gregor3545ff42009-09-21 16:56:56 +00001020 if (LangOpts.C99) {
1021 // C99-specific
Douglas Gregora2db7932010-05-26 22:00:08 +00001022 Results.AddResult(Result("_Complex", CCP_Type));
1023 Results.AddResult(Result("_Imaginary", CCP_Type));
1024 Results.AddResult(Result("_Bool", CCP_Type));
1025 Results.AddResult(Result("restrict", CCP_Type));
Douglas Gregor3545ff42009-09-21 16:56:56 +00001026 }
1027
1028 if (LangOpts.CPlusPlus) {
1029 // C++-specific
Douglas Gregora2db7932010-05-26 22:00:08 +00001030 Results.AddResult(Result("bool", CCP_Type));
1031 Results.AddResult(Result("class", CCP_Type));
1032 Results.AddResult(Result("wchar_t", CCP_Type));
Douglas Gregor3545ff42009-09-21 16:56:56 +00001033
Douglas Gregorf4c33342010-05-28 00:22:41 +00001034 // typename qualified-id
1035 CodeCompletionString *Pattern = new CodeCompletionString;
1036 Pattern->AddTypedTextChunk("typename");
1037 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
1038 Pattern->AddPlaceholderChunk("qualifier");
1039 Pattern->AddTextChunk("::");
1040 Pattern->AddPlaceholderChunk("name");
1041 Results.AddResult(Result(Pattern));
Douglas Gregorf64acca2010-05-25 21:41:55 +00001042
Douglas Gregor3545ff42009-09-21 16:56:56 +00001043 if (LangOpts.CPlusPlus0x) {
Douglas Gregora2db7932010-05-26 22:00:08 +00001044 Results.AddResult(Result("auto", CCP_Type));
1045 Results.AddResult(Result("char16_t", CCP_Type));
1046 Results.AddResult(Result("char32_t", CCP_Type));
Douglas Gregorf4c33342010-05-28 00:22:41 +00001047
1048 CodeCompletionString *Pattern = new CodeCompletionString;
1049 Pattern->AddTypedTextChunk("decltype");
1050 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
1051 Pattern->AddPlaceholderChunk("expression");
1052 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
1053 Results.AddResult(Result(Pattern));
Douglas Gregor3545ff42009-09-21 16:56:56 +00001054 }
1055 }
1056
1057 // GNU extensions
1058 if (LangOpts.GNUMode) {
1059 // FIXME: Enable when we actually support decimal floating point.
Douglas Gregor78a21012010-01-14 16:01:26 +00001060 // Results.AddResult(Result("_Decimal32"));
1061 // Results.AddResult(Result("_Decimal64"));
1062 // Results.AddResult(Result("_Decimal128"));
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001063
Douglas Gregorf4c33342010-05-28 00:22:41 +00001064 CodeCompletionString *Pattern = new CodeCompletionString;
1065 Pattern->AddTypedTextChunk("typeof");
1066 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
1067 Pattern->AddPlaceholderChunk("expression");
1068 Results.AddResult(Result(Pattern));
1069
1070 Pattern = new CodeCompletionString;
1071 Pattern->AddTypedTextChunk("typeof");
1072 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
1073 Pattern->AddPlaceholderChunk("type");
1074 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
1075 Results.AddResult(Result(Pattern));
Douglas Gregor3545ff42009-09-21 16:56:56 +00001076 }
1077}
1078
Douglas Gregor00c37ef2010-08-11 21:23:17 +00001079static void AddStorageSpecifiers(Action::ParserCompletionContext CCC,
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001080 const LangOptions &LangOpts,
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001081 ResultBuilder &Results) {
John McCall276321a2010-08-25 06:19:51 +00001082 typedef CodeCompletionResult Result;
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001083 // Note: we don't suggest either "auto" or "register", because both
1084 // are pointless as storage specifiers. Elsewhere, we suggest "auto"
1085 // in C++0x as a type specifier.
Douglas Gregor78a21012010-01-14 16:01:26 +00001086 Results.AddResult(Result("extern"));
1087 Results.AddResult(Result("static"));
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001088}
1089
Douglas Gregor00c37ef2010-08-11 21:23:17 +00001090static void AddFunctionSpecifiers(Action::ParserCompletionContext CCC,
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001091 const LangOptions &LangOpts,
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001092 ResultBuilder &Results) {
John McCall276321a2010-08-25 06:19:51 +00001093 typedef CodeCompletionResult Result;
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001094 switch (CCC) {
Douglas Gregor00c37ef2010-08-11 21:23:17 +00001095 case Action::PCC_Class:
1096 case Action::PCC_MemberTemplate:
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001097 if (LangOpts.CPlusPlus) {
Douglas Gregor78a21012010-01-14 16:01:26 +00001098 Results.AddResult(Result("explicit"));
1099 Results.AddResult(Result("friend"));
1100 Results.AddResult(Result("mutable"));
1101 Results.AddResult(Result("virtual"));
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001102 }
1103 // Fall through
1104
Douglas Gregor00c37ef2010-08-11 21:23:17 +00001105 case Action::PCC_ObjCInterface:
1106 case Action::PCC_ObjCImplementation:
1107 case Action::PCC_Namespace:
1108 case Action::PCC_Template:
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001109 if (LangOpts.CPlusPlus || LangOpts.C99)
Douglas Gregor78a21012010-01-14 16:01:26 +00001110 Results.AddResult(Result("inline"));
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001111 break;
1112
Douglas Gregor00c37ef2010-08-11 21:23:17 +00001113 case Action::PCC_ObjCInstanceVariableList:
1114 case Action::PCC_Expression:
1115 case Action::PCC_Statement:
1116 case Action::PCC_ForInit:
1117 case Action::PCC_Condition:
1118 case Action::PCC_RecoveryInFunction:
Douglas Gregor99fa2642010-08-24 01:06:58 +00001119 case Action::PCC_Type:
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001120 break;
1121 }
1122}
1123
Douglas Gregorf98e6a22010-01-13 23:51:12 +00001124static void AddObjCExpressionResults(ResultBuilder &Results, bool NeedAt);
1125static void AddObjCStatementResults(ResultBuilder &Results, bool NeedAt);
1126static void AddObjCVisibilityResults(const LangOptions &LangOpts,
Douglas Gregor48d46252010-01-13 21:54:15 +00001127 ResultBuilder &Results,
1128 bool NeedAt);
Douglas Gregorf98e6a22010-01-13 23:51:12 +00001129static void AddObjCImplementationResults(const LangOptions &LangOpts,
Douglas Gregorf1934162010-01-13 21:24:21 +00001130 ResultBuilder &Results,
1131 bool NeedAt);
Douglas Gregorf98e6a22010-01-13 23:51:12 +00001132static void AddObjCInterfaceResults(const LangOptions &LangOpts,
Douglas Gregorf1934162010-01-13 21:24:21 +00001133 ResultBuilder &Results,
1134 bool NeedAt);
Douglas Gregorf98e6a22010-01-13 23:51:12 +00001135static void AddObjCTopLevelResults(ResultBuilder &Results, bool NeedAt);
Douglas Gregorf1934162010-01-13 21:24:21 +00001136
Douglas Gregorf4c33342010-05-28 00:22:41 +00001137static void AddTypedefResult(ResultBuilder &Results) {
1138 CodeCompletionString *Pattern = new CodeCompletionString;
1139 Pattern->AddTypedTextChunk("typedef");
1140 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
1141 Pattern->AddPlaceholderChunk("type");
1142 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
1143 Pattern->AddPlaceholderChunk("name");
John McCall276321a2010-08-25 06:19:51 +00001144 Results.AddResult(CodeCompletionResult(Pattern));
Douglas Gregorf4c33342010-05-28 00:22:41 +00001145}
1146
Douglas Gregor00c37ef2010-08-11 21:23:17 +00001147static bool WantTypesInContext(Action::ParserCompletionContext CCC,
Douglas Gregor70febae2010-05-28 00:49:12 +00001148 const LangOptions &LangOpts) {
1149 if (LangOpts.CPlusPlus)
1150 return true;
1151
1152 switch (CCC) {
Douglas Gregor00c37ef2010-08-11 21:23:17 +00001153 case Action::PCC_Namespace:
1154 case Action::PCC_Class:
1155 case Action::PCC_ObjCInstanceVariableList:
1156 case Action::PCC_Template:
1157 case Action::PCC_MemberTemplate:
1158 case Action::PCC_Statement:
1159 case Action::PCC_RecoveryInFunction:
Douglas Gregor99fa2642010-08-24 01:06:58 +00001160 case Action::PCC_Type:
Douglas Gregor70febae2010-05-28 00:49:12 +00001161 return true;
1162
Douglas Gregor00c37ef2010-08-11 21:23:17 +00001163 case Action::PCC_ObjCInterface:
1164 case Action::PCC_ObjCImplementation:
1165 case Action::PCC_Expression:
1166 case Action::PCC_Condition:
Douglas Gregor70febae2010-05-28 00:49:12 +00001167 return false;
1168
Douglas Gregor00c37ef2010-08-11 21:23:17 +00001169 case Action::PCC_ForInit:
Douglas Gregor70febae2010-05-28 00:49:12 +00001170 return LangOpts.ObjC1 || LangOpts.C99;
1171 }
1172
1173 return false;
1174}
1175
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001176/// \brief Add language constructs that show up for "ordinary" names.
Douglas Gregor00c37ef2010-08-11 21:23:17 +00001177static void AddOrdinaryNameResults(Action::ParserCompletionContext CCC,
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001178 Scope *S,
1179 Sema &SemaRef,
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001180 ResultBuilder &Results) {
John McCall276321a2010-08-25 06:19:51 +00001181 typedef CodeCompletionResult Result;
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001182 switch (CCC) {
Douglas Gregor00c37ef2010-08-11 21:23:17 +00001183 case Action::PCC_Namespace:
Douglas Gregorf4c33342010-05-28 00:22:41 +00001184 if (SemaRef.getLangOptions().CPlusPlus) {
1185 CodeCompletionString *Pattern = 0;
1186
1187 if (Results.includeCodePatterns()) {
1188 // namespace <identifier> { declarations }
1189 CodeCompletionString *Pattern = new CodeCompletionString;
1190 Pattern->AddTypedTextChunk("namespace");
1191 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
1192 Pattern->AddPlaceholderChunk("identifier");
1193 Pattern->AddChunk(CodeCompletionString::CK_LeftBrace);
1194 Pattern->AddPlaceholderChunk("declarations");
1195 Pattern->AddChunk(CodeCompletionString::CK_VerticalSpace);
1196 Pattern->AddChunk(CodeCompletionString::CK_RightBrace);
1197 Results.AddResult(Result(Pattern));
1198 }
1199
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001200 // namespace identifier = identifier ;
1201 Pattern = new CodeCompletionString;
1202 Pattern->AddTypedTextChunk("namespace");
1203 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
Douglas Gregorf4c33342010-05-28 00:22:41 +00001204 Pattern->AddPlaceholderChunk("name");
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001205 Pattern->AddChunk(CodeCompletionString::CK_Equal);
Douglas Gregorf4c33342010-05-28 00:22:41 +00001206 Pattern->AddPlaceholderChunk("namespace");
Douglas Gregor78a21012010-01-14 16:01:26 +00001207 Results.AddResult(Result(Pattern));
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001208
1209 // Using directives
1210 Pattern = new CodeCompletionString;
1211 Pattern->AddTypedTextChunk("using");
1212 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
1213 Pattern->AddTextChunk("namespace");
1214 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
1215 Pattern->AddPlaceholderChunk("identifier");
Douglas Gregor78a21012010-01-14 16:01:26 +00001216 Results.AddResult(Result(Pattern));
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001217
1218 // asm(string-literal)
1219 Pattern = new CodeCompletionString;
1220 Pattern->AddTypedTextChunk("asm");
1221 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
1222 Pattern->AddPlaceholderChunk("string-literal");
1223 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
Douglas Gregor78a21012010-01-14 16:01:26 +00001224 Results.AddResult(Result(Pattern));
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001225
Douglas Gregorf4c33342010-05-28 00:22:41 +00001226 if (Results.includeCodePatterns()) {
1227 // Explicit template instantiation
1228 Pattern = new CodeCompletionString;
1229 Pattern->AddTypedTextChunk("template");
1230 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
1231 Pattern->AddPlaceholderChunk("declaration");
1232 Results.AddResult(Result(Pattern));
1233 }
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001234 }
Douglas Gregorf1934162010-01-13 21:24:21 +00001235
1236 if (SemaRef.getLangOptions().ObjC1)
Douglas Gregorf98e6a22010-01-13 23:51:12 +00001237 AddObjCTopLevelResults(Results, true);
Douglas Gregorf1934162010-01-13 21:24:21 +00001238
Douglas Gregorf4c33342010-05-28 00:22:41 +00001239 AddTypedefResult(Results);
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001240 // Fall through
1241
Douglas Gregor00c37ef2010-08-11 21:23:17 +00001242 case Action::PCC_Class:
Douglas Gregorf4c33342010-05-28 00:22:41 +00001243 if (SemaRef.getLangOptions().CPlusPlus) {
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001244 // Using declaration
1245 CodeCompletionString *Pattern = new CodeCompletionString;
1246 Pattern->AddTypedTextChunk("using");
1247 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
Douglas Gregorf4c33342010-05-28 00:22:41 +00001248 Pattern->AddPlaceholderChunk("qualifier");
1249 Pattern->AddTextChunk("::");
1250 Pattern->AddPlaceholderChunk("name");
Douglas Gregor78a21012010-01-14 16:01:26 +00001251 Results.AddResult(Result(Pattern));
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001252
Douglas Gregorf4c33342010-05-28 00:22:41 +00001253 // using typename qualifier::name (only in a dependent context)
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001254 if (SemaRef.CurContext->isDependentContext()) {
1255 Pattern = new CodeCompletionString;
1256 Pattern->AddTypedTextChunk("using");
1257 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
1258 Pattern->AddTextChunk("typename");
1259 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
Douglas Gregorf4c33342010-05-28 00:22:41 +00001260 Pattern->AddPlaceholderChunk("qualifier");
1261 Pattern->AddTextChunk("::");
1262 Pattern->AddPlaceholderChunk("name");
Douglas Gregor78a21012010-01-14 16:01:26 +00001263 Results.AddResult(Result(Pattern));
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001264 }
1265
Douglas Gregor00c37ef2010-08-11 21:23:17 +00001266 if (CCC == Action::PCC_Class) {
Douglas Gregorf4c33342010-05-28 00:22:41 +00001267 AddTypedefResult(Results);
1268
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001269 // public:
1270 Pattern = new CodeCompletionString;
1271 Pattern->AddTypedTextChunk("public");
1272 Pattern->AddChunk(CodeCompletionString::CK_Colon);
Douglas Gregor78a21012010-01-14 16:01:26 +00001273 Results.AddResult(Result(Pattern));
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001274
1275 // protected:
1276 Pattern = new CodeCompletionString;
1277 Pattern->AddTypedTextChunk("protected");
1278 Pattern->AddChunk(CodeCompletionString::CK_Colon);
Douglas Gregor78a21012010-01-14 16:01:26 +00001279 Results.AddResult(Result(Pattern));
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001280
1281 // private:
1282 Pattern = new CodeCompletionString;
1283 Pattern->AddTypedTextChunk("private");
1284 Pattern->AddChunk(CodeCompletionString::CK_Colon);
Douglas Gregor78a21012010-01-14 16:01:26 +00001285 Results.AddResult(Result(Pattern));
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001286 }
1287 }
1288 // Fall through
1289
Douglas Gregor00c37ef2010-08-11 21:23:17 +00001290 case Action::PCC_Template:
1291 case Action::PCC_MemberTemplate:
Douglas Gregorf64acca2010-05-25 21:41:55 +00001292 if (SemaRef.getLangOptions().CPlusPlus && Results.includeCodePatterns()) {
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001293 // template < parameters >
1294 CodeCompletionString *Pattern = new CodeCompletionString;
1295 Pattern->AddTypedTextChunk("template");
1296 Pattern->AddChunk(CodeCompletionString::CK_LeftAngle);
1297 Pattern->AddPlaceholderChunk("parameters");
1298 Pattern->AddChunk(CodeCompletionString::CK_RightAngle);
Douglas Gregor78a21012010-01-14 16:01:26 +00001299 Results.AddResult(Result(Pattern));
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001300 }
1301
Douglas Gregorf98e6a22010-01-13 23:51:12 +00001302 AddStorageSpecifiers(CCC, SemaRef.getLangOptions(), Results);
1303 AddFunctionSpecifiers(CCC, SemaRef.getLangOptions(), Results);
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001304 break;
1305
Douglas Gregor00c37ef2010-08-11 21:23:17 +00001306 case Action::PCC_ObjCInterface:
Douglas Gregorf98e6a22010-01-13 23:51:12 +00001307 AddObjCInterfaceResults(SemaRef.getLangOptions(), Results, true);
1308 AddStorageSpecifiers(CCC, SemaRef.getLangOptions(), Results);
1309 AddFunctionSpecifiers(CCC, SemaRef.getLangOptions(), Results);
Douglas Gregorf1934162010-01-13 21:24:21 +00001310 break;
1311
Douglas Gregor00c37ef2010-08-11 21:23:17 +00001312 case Action::PCC_ObjCImplementation:
Douglas Gregorf98e6a22010-01-13 23:51:12 +00001313 AddObjCImplementationResults(SemaRef.getLangOptions(), Results, true);
1314 AddStorageSpecifiers(CCC, SemaRef.getLangOptions(), Results);
1315 AddFunctionSpecifiers(CCC, SemaRef.getLangOptions(), Results);
Douglas Gregorf1934162010-01-13 21:24:21 +00001316 break;
1317
Douglas Gregor00c37ef2010-08-11 21:23:17 +00001318 case Action::PCC_ObjCInstanceVariableList:
Douglas Gregorf98e6a22010-01-13 23:51:12 +00001319 AddObjCVisibilityResults(SemaRef.getLangOptions(), Results, true);
Douglas Gregor48d46252010-01-13 21:54:15 +00001320 break;
1321
Douglas Gregor00c37ef2010-08-11 21:23:17 +00001322 case Action::PCC_RecoveryInFunction:
1323 case Action::PCC_Statement: {
Douglas Gregorf4c33342010-05-28 00:22:41 +00001324 AddTypedefResult(Results);
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001325
1326 CodeCompletionString *Pattern = 0;
Douglas Gregorf64acca2010-05-25 21:41:55 +00001327 if (SemaRef.getLangOptions().CPlusPlus && Results.includeCodePatterns()) {
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001328 Pattern = new CodeCompletionString;
1329 Pattern->AddTypedTextChunk("try");
1330 Pattern->AddChunk(CodeCompletionString::CK_LeftBrace);
1331 Pattern->AddPlaceholderChunk("statements");
1332 Pattern->AddChunk(CodeCompletionString::CK_VerticalSpace);
1333 Pattern->AddChunk(CodeCompletionString::CK_RightBrace);
1334 Pattern->AddTextChunk("catch");
1335 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
1336 Pattern->AddPlaceholderChunk("declaration");
1337 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
1338 Pattern->AddChunk(CodeCompletionString::CK_LeftBrace);
1339 Pattern->AddPlaceholderChunk("statements");
1340 Pattern->AddChunk(CodeCompletionString::CK_VerticalSpace);
1341 Pattern->AddChunk(CodeCompletionString::CK_RightBrace);
Douglas Gregor78a21012010-01-14 16:01:26 +00001342 Results.AddResult(Result(Pattern));
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001343 }
Douglas Gregorf1934162010-01-13 21:24:21 +00001344 if (SemaRef.getLangOptions().ObjC1)
Douglas Gregorf98e6a22010-01-13 23:51:12 +00001345 AddObjCStatementResults(Results, true);
Douglas Gregorf1934162010-01-13 21:24:21 +00001346
Douglas Gregorf64acca2010-05-25 21:41:55 +00001347 if (Results.includeCodePatterns()) {
1348 // if (condition) { statements }
1349 Pattern = new CodeCompletionString;
1350 Pattern->AddTypedTextChunk("if");
1351 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
1352 if (SemaRef.getLangOptions().CPlusPlus)
1353 Pattern->AddPlaceholderChunk("condition");
1354 else
1355 Pattern->AddPlaceholderChunk("expression");
1356 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
1357 Pattern->AddChunk(CodeCompletionString::CK_LeftBrace);
1358 Pattern->AddPlaceholderChunk("statements");
1359 Pattern->AddChunk(CodeCompletionString::CK_VerticalSpace);
1360 Pattern->AddChunk(CodeCompletionString::CK_RightBrace);
1361 Results.AddResult(Result(Pattern));
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001362
Douglas Gregorf64acca2010-05-25 21:41:55 +00001363 // switch (condition) { }
1364 Pattern = new CodeCompletionString;
1365 Pattern->AddTypedTextChunk("switch");
1366 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
1367 if (SemaRef.getLangOptions().CPlusPlus)
1368 Pattern->AddPlaceholderChunk("condition");
1369 else
1370 Pattern->AddPlaceholderChunk("expression");
1371 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
1372 Pattern->AddChunk(CodeCompletionString::CK_LeftBrace);
1373 Pattern->AddChunk(CodeCompletionString::CK_VerticalSpace);
1374 Pattern->AddChunk(CodeCompletionString::CK_RightBrace);
1375 Results.AddResult(Result(Pattern));
1376 }
1377
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001378 // Switch-specific statements.
Douglas Gregorf4c33342010-05-28 00:22:41 +00001379 if (!SemaRef.getSwitchStack().empty()) {
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001380 // case expression:
1381 Pattern = new CodeCompletionString;
1382 Pattern->AddTypedTextChunk("case");
Douglas Gregorf4c33342010-05-28 00:22:41 +00001383 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001384 Pattern->AddPlaceholderChunk("expression");
1385 Pattern->AddChunk(CodeCompletionString::CK_Colon);
Douglas Gregor78a21012010-01-14 16:01:26 +00001386 Results.AddResult(Result(Pattern));
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001387
1388 // default:
1389 Pattern = new CodeCompletionString;
1390 Pattern->AddTypedTextChunk("default");
1391 Pattern->AddChunk(CodeCompletionString::CK_Colon);
Douglas Gregor78a21012010-01-14 16:01:26 +00001392 Results.AddResult(Result(Pattern));
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001393 }
1394
Douglas Gregorf64acca2010-05-25 21:41:55 +00001395 if (Results.includeCodePatterns()) {
1396 /// while (condition) { statements }
1397 Pattern = new CodeCompletionString;
1398 Pattern->AddTypedTextChunk("while");
1399 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
1400 if (SemaRef.getLangOptions().CPlusPlus)
1401 Pattern->AddPlaceholderChunk("condition");
1402 else
1403 Pattern->AddPlaceholderChunk("expression");
1404 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
1405 Pattern->AddChunk(CodeCompletionString::CK_LeftBrace);
1406 Pattern->AddPlaceholderChunk("statements");
1407 Pattern->AddChunk(CodeCompletionString::CK_VerticalSpace);
1408 Pattern->AddChunk(CodeCompletionString::CK_RightBrace);
1409 Results.AddResult(Result(Pattern));
1410
1411 // do { statements } while ( expression );
1412 Pattern = new CodeCompletionString;
1413 Pattern->AddTypedTextChunk("do");
1414 Pattern->AddChunk(CodeCompletionString::CK_LeftBrace);
1415 Pattern->AddPlaceholderChunk("statements");
1416 Pattern->AddChunk(CodeCompletionString::CK_VerticalSpace);
1417 Pattern->AddChunk(CodeCompletionString::CK_RightBrace);
1418 Pattern->AddTextChunk("while");
1419 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001420 Pattern->AddPlaceholderChunk("expression");
Douglas Gregorf64acca2010-05-25 21:41:55 +00001421 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
1422 Results.AddResult(Result(Pattern));
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001423
Douglas Gregorf64acca2010-05-25 21:41:55 +00001424 // for ( for-init-statement ; condition ; expression ) { statements }
1425 Pattern = new CodeCompletionString;
1426 Pattern->AddTypedTextChunk("for");
1427 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
1428 if (SemaRef.getLangOptions().CPlusPlus || SemaRef.getLangOptions().C99)
1429 Pattern->AddPlaceholderChunk("init-statement");
1430 else
1431 Pattern->AddPlaceholderChunk("init-expression");
1432 Pattern->AddChunk(CodeCompletionString::CK_SemiColon);
1433 Pattern->AddPlaceholderChunk("condition");
1434 Pattern->AddChunk(CodeCompletionString::CK_SemiColon);
1435 Pattern->AddPlaceholderChunk("inc-expression");
1436 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
1437 Pattern->AddChunk(CodeCompletionString::CK_LeftBrace);
1438 Pattern->AddPlaceholderChunk("statements");
1439 Pattern->AddChunk(CodeCompletionString::CK_VerticalSpace);
1440 Pattern->AddChunk(CodeCompletionString::CK_RightBrace);
1441 Results.AddResult(Result(Pattern));
1442 }
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001443
1444 if (S->getContinueParent()) {
1445 // continue ;
1446 Pattern = new CodeCompletionString;
1447 Pattern->AddTypedTextChunk("continue");
Douglas Gregor78a21012010-01-14 16:01:26 +00001448 Results.AddResult(Result(Pattern));
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001449 }
1450
1451 if (S->getBreakParent()) {
1452 // break ;
1453 Pattern = new CodeCompletionString;
1454 Pattern->AddTypedTextChunk("break");
Douglas Gregor78a21012010-01-14 16:01:26 +00001455 Results.AddResult(Result(Pattern));
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001456 }
1457
1458 // "return expression ;" or "return ;", depending on whether we
1459 // know the function is void or not.
1460 bool isVoid = false;
1461 if (FunctionDecl *Function = dyn_cast<FunctionDecl>(SemaRef.CurContext))
1462 isVoid = Function->getResultType()->isVoidType();
1463 else if (ObjCMethodDecl *Method
1464 = dyn_cast<ObjCMethodDecl>(SemaRef.CurContext))
1465 isVoid = Method->getResultType()->isVoidType();
Douglas Gregor9a28e842010-03-01 23:15:13 +00001466 else if (SemaRef.getCurBlock() &&
1467 !SemaRef.getCurBlock()->ReturnType.isNull())
1468 isVoid = SemaRef.getCurBlock()->ReturnType->isVoidType();
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001469 Pattern = new CodeCompletionString;
1470 Pattern->AddTypedTextChunk("return");
Douglas Gregor44272ca2010-02-18 04:06:48 +00001471 if (!isVoid) {
1472 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001473 Pattern->AddPlaceholderChunk("expression");
Douglas Gregor44272ca2010-02-18 04:06:48 +00001474 }
Douglas Gregor78a21012010-01-14 16:01:26 +00001475 Results.AddResult(Result(Pattern));
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001476
Douglas Gregorf4c33342010-05-28 00:22:41 +00001477 // goto identifier ;
1478 Pattern = new CodeCompletionString;
1479 Pattern->AddTypedTextChunk("goto");
1480 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
1481 Pattern->AddPlaceholderChunk("label");
1482 Results.AddResult(Result(Pattern));
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001483
Douglas Gregorf4c33342010-05-28 00:22:41 +00001484 // Using directives
1485 Pattern = new CodeCompletionString;
1486 Pattern->AddTypedTextChunk("using");
1487 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
1488 Pattern->AddTextChunk("namespace");
1489 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
1490 Pattern->AddPlaceholderChunk("identifier");
1491 Results.AddResult(Result(Pattern));
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001492 }
1493
1494 // Fall through (for statement expressions).
Douglas Gregor00c37ef2010-08-11 21:23:17 +00001495 case Action::PCC_ForInit:
1496 case Action::PCC_Condition:
Douglas Gregorf98e6a22010-01-13 23:51:12 +00001497 AddStorageSpecifiers(CCC, SemaRef.getLangOptions(), Results);
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001498 // Fall through: conditions and statements can have expressions.
1499
Douglas Gregor00c37ef2010-08-11 21:23:17 +00001500 case Action::PCC_Expression: {
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001501 CodeCompletionString *Pattern = 0;
1502 if (SemaRef.getLangOptions().CPlusPlus) {
1503 // 'this', if we're in a non-static member function.
1504 if (CXXMethodDecl *Method = dyn_cast<CXXMethodDecl>(SemaRef.CurContext))
1505 if (!Method->isStatic())
Douglas Gregor78a21012010-01-14 16:01:26 +00001506 Results.AddResult(Result("this"));
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001507
1508 // true, false
Douglas Gregor78a21012010-01-14 16:01:26 +00001509 Results.AddResult(Result("true"));
1510 Results.AddResult(Result("false"));
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001511
Douglas Gregorf4c33342010-05-28 00:22:41 +00001512 // dynamic_cast < type-id > ( expression )
1513 Pattern = new CodeCompletionString;
1514 Pattern->AddTypedTextChunk("dynamic_cast");
1515 Pattern->AddChunk(CodeCompletionString::CK_LeftAngle);
1516 Pattern->AddPlaceholderChunk("type");
1517 Pattern->AddChunk(CodeCompletionString::CK_RightAngle);
1518 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
1519 Pattern->AddPlaceholderChunk("expression");
1520 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
1521 Results.AddResult(Result(Pattern));
1522
1523 // static_cast < type-id > ( expression )
1524 Pattern = new CodeCompletionString;
1525 Pattern->AddTypedTextChunk("static_cast");
1526 Pattern->AddChunk(CodeCompletionString::CK_LeftAngle);
1527 Pattern->AddPlaceholderChunk("type");
1528 Pattern->AddChunk(CodeCompletionString::CK_RightAngle);
1529 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
1530 Pattern->AddPlaceholderChunk("expression");
1531 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
1532 Results.AddResult(Result(Pattern));
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001533
Douglas Gregorf4c33342010-05-28 00:22:41 +00001534 // reinterpret_cast < type-id > ( expression )
1535 Pattern = new CodeCompletionString;
1536 Pattern->AddTypedTextChunk("reinterpret_cast");
1537 Pattern->AddChunk(CodeCompletionString::CK_LeftAngle);
1538 Pattern->AddPlaceholderChunk("type");
1539 Pattern->AddChunk(CodeCompletionString::CK_RightAngle);
1540 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
1541 Pattern->AddPlaceholderChunk("expression");
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 // const_cast < type-id > ( expression )
1546 Pattern = new CodeCompletionString;
1547 Pattern->AddTypedTextChunk("const_cast");
1548 Pattern->AddChunk(CodeCompletionString::CK_LeftAngle);
1549 Pattern->AddPlaceholderChunk("type");
1550 Pattern->AddChunk(CodeCompletionString::CK_RightAngle);
1551 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
1552 Pattern->AddPlaceholderChunk("expression");
1553 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
1554 Results.AddResult(Result(Pattern));
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001555
Douglas Gregorf4c33342010-05-28 00:22:41 +00001556 // typeid ( expression-or-type )
1557 Pattern = new CodeCompletionString;
1558 Pattern->AddTypedTextChunk("typeid");
1559 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
1560 Pattern->AddPlaceholderChunk("expression-or-type");
1561 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
1562 Results.AddResult(Result(Pattern));
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001563
Douglas Gregorf4c33342010-05-28 00:22:41 +00001564 // new T ( ... )
1565 Pattern = new CodeCompletionString;
1566 Pattern->AddTypedTextChunk("new");
1567 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
1568 Pattern->AddPlaceholderChunk("type");
1569 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
1570 Pattern->AddPlaceholderChunk("expressions");
1571 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
1572 Results.AddResult(Result(Pattern));
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001573
Douglas Gregorf4c33342010-05-28 00:22:41 +00001574 // new T [ ] ( ... )
1575 Pattern = new CodeCompletionString;
1576 Pattern->AddTypedTextChunk("new");
1577 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
1578 Pattern->AddPlaceholderChunk("type");
1579 Pattern->AddChunk(CodeCompletionString::CK_LeftBracket);
1580 Pattern->AddPlaceholderChunk("size");
1581 Pattern->AddChunk(CodeCompletionString::CK_RightBracket);
1582 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
1583 Pattern->AddPlaceholderChunk("expressions");
1584 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
1585 Results.AddResult(Result(Pattern));
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001586
Douglas Gregorf4c33342010-05-28 00:22:41 +00001587 // delete expression
1588 Pattern = new CodeCompletionString;
1589 Pattern->AddTypedTextChunk("delete");
1590 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
1591 Pattern->AddPlaceholderChunk("expression");
1592 Results.AddResult(Result(Pattern));
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001593
Douglas Gregorf4c33342010-05-28 00:22:41 +00001594 // delete [] expression
1595 Pattern = new CodeCompletionString;
1596 Pattern->AddTypedTextChunk("delete");
1597 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
1598 Pattern->AddChunk(CodeCompletionString::CK_LeftBracket);
1599 Pattern->AddChunk(CodeCompletionString::CK_RightBracket);
1600 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
1601 Pattern->AddPlaceholderChunk("expression");
1602 Results.AddResult(Result(Pattern));
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001603
Douglas Gregorf4c33342010-05-28 00:22:41 +00001604 // throw expression
1605 Pattern = new CodeCompletionString;
1606 Pattern->AddTypedTextChunk("throw");
1607 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
1608 Pattern->AddPlaceholderChunk("expression");
1609 Results.AddResult(Result(Pattern));
Douglas Gregora2db7932010-05-26 22:00:08 +00001610
1611 // FIXME: Rethrow?
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001612 }
1613
1614 if (SemaRef.getLangOptions().ObjC1) {
1615 // Add "super", if we're in an Objective-C class with a superclass.
Ted Kremenek305a0a72010-05-31 21:43:10 +00001616 if (ObjCMethodDecl *Method = SemaRef.getCurMethodDecl()) {
1617 // The interface can be NULL.
1618 if (ObjCInterfaceDecl *ID = Method->getClassInterface())
1619 if (ID->getSuperClass())
1620 Results.AddResult(Result("super"));
1621 }
1622
Douglas Gregorf98e6a22010-01-13 23:51:12 +00001623 AddObjCExpressionResults(Results, true);
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001624 }
1625
Douglas Gregorf4c33342010-05-28 00:22:41 +00001626 // sizeof expression
1627 Pattern = new CodeCompletionString;
1628 Pattern->AddTypedTextChunk("sizeof");
1629 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
1630 Pattern->AddPlaceholderChunk("expression-or-type");
1631 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
1632 Results.AddResult(Result(Pattern));
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001633 break;
1634 }
Douglas Gregor99fa2642010-08-24 01:06:58 +00001635
1636 case Action::PCC_Type:
1637 break;
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001638 }
1639
Douglas Gregor70febae2010-05-28 00:49:12 +00001640 if (WantTypesInContext(CCC, SemaRef.getLangOptions()))
1641 AddTypeSpecifierResults(SemaRef.getLangOptions(), Results);
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001642
Douglas Gregor99fa2642010-08-24 01:06:58 +00001643 if (SemaRef.getLangOptions().CPlusPlus && CCC != Action::PCC_Type)
Douglas Gregor78a21012010-01-14 16:01:26 +00001644 Results.AddResult(Result("operator"));
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001645}
1646
Douglas Gregorb3fa9192009-12-18 18:53:37 +00001647/// \brief If the given declaration has an associated type, add it as a result
1648/// type chunk.
1649static void AddResultTypeChunk(ASTContext &Context,
1650 NamedDecl *ND,
1651 CodeCompletionString *Result) {
1652 if (!ND)
1653 return;
1654
1655 // Determine the type of the declaration (if it has a type).
1656 QualType T;
1657 if (FunctionDecl *Function = dyn_cast<FunctionDecl>(ND))
1658 T = Function->getResultType();
1659 else if (ObjCMethodDecl *Method = dyn_cast<ObjCMethodDecl>(ND))
1660 T = Method->getResultType();
1661 else if (FunctionTemplateDecl *FunTmpl = dyn_cast<FunctionTemplateDecl>(ND))
1662 T = FunTmpl->getTemplatedDecl()->getResultType();
1663 else if (EnumConstantDecl *Enumerator = dyn_cast<EnumConstantDecl>(ND))
1664 T = Context.getTypeDeclType(cast<TypeDecl>(Enumerator->getDeclContext()));
1665 else if (isa<UnresolvedUsingValueDecl>(ND)) {
1666 /* Do nothing: ignore unresolved using declarations*/
1667 } else if (ValueDecl *Value = dyn_cast<ValueDecl>(ND))
1668 T = Value->getType();
1669 else if (ObjCPropertyDecl *Property = dyn_cast<ObjCPropertyDecl>(ND))
1670 T = Property->getType();
1671
1672 if (T.isNull() || Context.hasSameType(T, Context.DependentTy))
1673 return;
1674
Douglas Gregorcf04b022010-04-05 21:25:31 +00001675 PrintingPolicy Policy(Context.PrintingPolicy);
1676 Policy.AnonymousTagLocations = false;
1677
Douglas Gregorb3fa9192009-12-18 18:53:37 +00001678 std::string TypeStr;
Douglas Gregorcf04b022010-04-05 21:25:31 +00001679 T.getAsStringInternal(TypeStr, Policy);
Douglas Gregorb3fa9192009-12-18 18:53:37 +00001680 Result->AddResultTypeChunk(TypeStr);
1681}
1682
Douglas Gregordbb71db2010-08-23 23:51:41 +00001683static void MaybeAddSentinel(ASTContext &Context, NamedDecl *FunctionOrMethod,
1684 CodeCompletionString *Result) {
1685 if (SentinelAttr *Sentinel = FunctionOrMethod->getAttr<SentinelAttr>())
1686 if (Sentinel->getSentinel() == 0) {
1687 if (Context.getLangOptions().ObjC1 &&
1688 Context.Idents.get("nil").hasMacroDefinition())
1689 Result->AddTextChunk(", nil");
1690 else if (Context.Idents.get("NULL").hasMacroDefinition())
1691 Result->AddTextChunk(", NULL");
1692 else
1693 Result->AddTextChunk(", (void*)0");
1694 }
1695}
1696
Douglas Gregore90dd002010-08-24 16:15:59 +00001697static std::string FormatFunctionParameter(ASTContext &Context,
1698 ParmVarDecl *Param) {
1699 bool ObjCMethodParam = isa<ObjCMethodDecl>(Param->getDeclContext());
1700 if (Param->getType()->isDependentType() ||
1701 !Param->getType()->isBlockPointerType()) {
1702 // The argument for a dependent or non-block parameter is a placeholder
1703 // containing that parameter's type.
1704 std::string Result;
1705
1706 if (Param->getIdentifier() && !ObjCMethodParam)
1707 Result = Param->getIdentifier()->getName();
1708
1709 Param->getType().getAsStringInternal(Result,
1710 Context.PrintingPolicy);
1711
1712 if (ObjCMethodParam) {
1713 Result = "(" + Result;
1714 Result += ")";
1715 if (Param->getIdentifier())
1716 Result += Param->getIdentifier()->getName();
1717 }
1718 return Result;
1719 }
1720
1721 // The argument for a block pointer parameter is a block literal with
1722 // the appropriate type.
1723 FunctionProtoTypeLoc *Block = 0;
1724 TypeLoc TL;
1725 if (TypeSourceInfo *TSInfo = Param->getTypeSourceInfo()) {
1726 TL = TSInfo->getTypeLoc().getUnqualifiedLoc();
1727 while (true) {
1728 // Look through typedefs.
1729 if (TypedefTypeLoc *TypedefTL = dyn_cast<TypedefTypeLoc>(&TL)) {
1730 if (TypeSourceInfo *InnerTSInfo
1731 = TypedefTL->getTypedefDecl()->getTypeSourceInfo()) {
1732 TL = InnerTSInfo->getTypeLoc().getUnqualifiedLoc();
1733 continue;
1734 }
1735 }
1736
1737 // Look through qualified types
1738 if (QualifiedTypeLoc *QualifiedTL = dyn_cast<QualifiedTypeLoc>(&TL)) {
1739 TL = QualifiedTL->getUnqualifiedLoc();
1740 continue;
1741 }
1742
1743 // Try to get the function prototype behind the block pointer type,
1744 // then we're done.
1745 if (BlockPointerTypeLoc *BlockPtr
1746 = dyn_cast<BlockPointerTypeLoc>(&TL)) {
1747 TL = BlockPtr->getPointeeLoc();
1748 Block = dyn_cast<FunctionProtoTypeLoc>(&TL);
1749 }
1750 break;
1751 }
1752 }
1753
1754 if (!Block) {
1755 // We were unable to find a FunctionProtoTypeLoc with parameter names
1756 // for the block; just use the parameter type as a placeholder.
1757 std::string Result;
1758 Param->getType().getUnqualifiedType().
1759 getAsStringInternal(Result, Context.PrintingPolicy);
1760
1761 if (ObjCMethodParam) {
1762 Result = "(" + Result;
1763 Result += ")";
1764 if (Param->getIdentifier())
1765 Result += Param->getIdentifier()->getName();
1766 }
1767
1768 return Result;
1769 }
1770
1771 // We have the function prototype behind the block pointer type, as it was
1772 // written in the source.
1773 std::string Result = "(^)(";
1774 for (unsigned I = 0, N = Block->getNumArgs(); I != N; ++I) {
1775 if (I)
1776 Result += ", ";
1777 Result += FormatFunctionParameter(Context, Block->getArg(I));
1778 }
1779 if (Block->getTypePtr()->isVariadic()) {
1780 if (Block->getNumArgs() > 0)
1781 Result += ", ...";
1782 else
1783 Result += "...";
1784 } else if (Block->getNumArgs() == 0 && !Context.getLangOptions().CPlusPlus)
1785 Result += "void";
1786
1787 Result += ")";
1788 Block->getTypePtr()->getResultType().getAsStringInternal(Result,
1789 Context.PrintingPolicy);
1790 return Result;
1791}
1792
Douglas Gregor3545ff42009-09-21 16:56:56 +00001793/// \brief Add function parameter chunks to the given code completion string.
1794static void AddFunctionParameterChunks(ASTContext &Context,
1795 FunctionDecl *Function,
1796 CodeCompletionString *Result) {
Douglas Gregor9eb77012009-11-07 00:00:49 +00001797 typedef CodeCompletionString::Chunk Chunk;
1798
Douglas Gregor3545ff42009-09-21 16:56:56 +00001799 CodeCompletionString *CCStr = Result;
1800
1801 for (unsigned P = 0, N = Function->getNumParams(); P != N; ++P) {
1802 ParmVarDecl *Param = Function->getParamDecl(P);
1803
1804 if (Param->hasDefaultArg()) {
1805 // When we see an optional default argument, put that argument and
1806 // the remaining default arguments into a new, optional string.
1807 CodeCompletionString *Opt = new CodeCompletionString;
1808 CCStr->AddOptionalChunk(std::auto_ptr<CodeCompletionString>(Opt));
1809 CCStr = Opt;
1810 }
1811
1812 if (P != 0)
Douglas Gregor9eb77012009-11-07 00:00:49 +00001813 CCStr->AddChunk(Chunk(CodeCompletionString::CK_Comma));
Douglas Gregor3545ff42009-09-21 16:56:56 +00001814
1815 // Format the placeholder string.
Douglas Gregore90dd002010-08-24 16:15:59 +00001816 std::string PlaceholderStr = FormatFunctionParameter(Context, Param);
1817
Douglas Gregor3545ff42009-09-21 16:56:56 +00001818 // Add the placeholder string.
Benjamin Kramerb33a97c2009-11-29 20:18:50 +00001819 CCStr->AddPlaceholderChunk(PlaceholderStr);
Douglas Gregor3545ff42009-09-21 16:56:56 +00001820 }
Douglas Gregorba449032009-09-22 21:42:17 +00001821
1822 if (const FunctionProtoType *Proto
1823 = Function->getType()->getAs<FunctionProtoType>())
Douglas Gregordbb71db2010-08-23 23:51:41 +00001824 if (Proto->isVariadic()) {
Douglas Gregorba449032009-09-22 21:42:17 +00001825 CCStr->AddPlaceholderChunk(", ...");
Douglas Gregordbb71db2010-08-23 23:51:41 +00001826
1827 MaybeAddSentinel(Context, Function, CCStr);
1828 }
Douglas Gregor3545ff42009-09-21 16:56:56 +00001829}
1830
1831/// \brief Add template parameter chunks to the given code completion string.
1832static void AddTemplateParameterChunks(ASTContext &Context,
1833 TemplateDecl *Template,
1834 CodeCompletionString *Result,
1835 unsigned MaxParameters = 0) {
Douglas Gregor9eb77012009-11-07 00:00:49 +00001836 typedef CodeCompletionString::Chunk Chunk;
1837
Douglas Gregor3545ff42009-09-21 16:56:56 +00001838 CodeCompletionString *CCStr = Result;
1839 bool FirstParameter = true;
1840
1841 TemplateParameterList *Params = Template->getTemplateParameters();
1842 TemplateParameterList::iterator PEnd = Params->end();
1843 if (MaxParameters)
1844 PEnd = Params->begin() + MaxParameters;
1845 for (TemplateParameterList::iterator P = Params->begin(); P != PEnd; ++P) {
1846 bool HasDefaultArg = false;
1847 std::string PlaceholderStr;
1848 if (TemplateTypeParmDecl *TTP = dyn_cast<TemplateTypeParmDecl>(*P)) {
1849 if (TTP->wasDeclaredWithTypename())
1850 PlaceholderStr = "typename";
1851 else
1852 PlaceholderStr = "class";
1853
1854 if (TTP->getIdentifier()) {
1855 PlaceholderStr += ' ';
1856 PlaceholderStr += TTP->getIdentifier()->getName();
1857 }
1858
1859 HasDefaultArg = TTP->hasDefaultArgument();
1860 } else if (NonTypeTemplateParmDecl *NTTP
1861 = dyn_cast<NonTypeTemplateParmDecl>(*P)) {
1862 if (NTTP->getIdentifier())
1863 PlaceholderStr = NTTP->getIdentifier()->getName();
1864 NTTP->getType().getAsStringInternal(PlaceholderStr,
1865 Context.PrintingPolicy);
1866 HasDefaultArg = NTTP->hasDefaultArgument();
1867 } else {
1868 assert(isa<TemplateTemplateParmDecl>(*P));
1869 TemplateTemplateParmDecl *TTP = cast<TemplateTemplateParmDecl>(*P);
1870
1871 // Since putting the template argument list into the placeholder would
1872 // be very, very long, we just use an abbreviation.
1873 PlaceholderStr = "template<...> class";
1874 if (TTP->getIdentifier()) {
1875 PlaceholderStr += ' ';
1876 PlaceholderStr += TTP->getIdentifier()->getName();
1877 }
1878
1879 HasDefaultArg = TTP->hasDefaultArgument();
1880 }
1881
1882 if (HasDefaultArg) {
1883 // When we see an optional default argument, put that argument and
1884 // the remaining default arguments into a new, optional string.
1885 CodeCompletionString *Opt = new CodeCompletionString;
1886 CCStr->AddOptionalChunk(std::auto_ptr<CodeCompletionString>(Opt));
1887 CCStr = Opt;
1888 }
1889
1890 if (FirstParameter)
1891 FirstParameter = false;
1892 else
Douglas Gregor9eb77012009-11-07 00:00:49 +00001893 CCStr->AddChunk(Chunk(CodeCompletionString::CK_Comma));
Douglas Gregor3545ff42009-09-21 16:56:56 +00001894
1895 // Add the placeholder string.
Benjamin Kramerb33a97c2009-11-29 20:18:50 +00001896 CCStr->AddPlaceholderChunk(PlaceholderStr);
Douglas Gregor3545ff42009-09-21 16:56:56 +00001897 }
1898}
1899
Douglas Gregorf2510672009-09-21 19:57:38 +00001900/// \brief Add a qualifier to the given code-completion string, if the
1901/// provided nested-name-specifier is non-NULL.
Douglas Gregor0f622362009-12-11 18:44:16 +00001902static void
1903AddQualifierToCompletionString(CodeCompletionString *Result,
1904 NestedNameSpecifier *Qualifier,
1905 bool QualifierIsInformative,
1906 ASTContext &Context) {
Douglas Gregorf2510672009-09-21 19:57:38 +00001907 if (!Qualifier)
1908 return;
1909
1910 std::string PrintedNNS;
1911 {
1912 llvm::raw_string_ostream OS(PrintedNNS);
1913 Qualifier->print(OS, Context.PrintingPolicy);
1914 }
Douglas Gregor5bf52692009-09-22 23:15:58 +00001915 if (QualifierIsInformative)
Benjamin Kramerb33a97c2009-11-29 20:18:50 +00001916 Result->AddInformativeChunk(PrintedNNS);
Douglas Gregor5bf52692009-09-22 23:15:58 +00001917 else
Benjamin Kramerb33a97c2009-11-29 20:18:50 +00001918 Result->AddTextChunk(PrintedNNS);
Douglas Gregorf2510672009-09-21 19:57:38 +00001919}
1920
Douglas Gregor0f622362009-12-11 18:44:16 +00001921static void AddFunctionTypeQualsToCompletionString(CodeCompletionString *Result,
1922 FunctionDecl *Function) {
1923 const FunctionProtoType *Proto
1924 = Function->getType()->getAs<FunctionProtoType>();
1925 if (!Proto || !Proto->getTypeQuals())
1926 return;
1927
1928 std::string QualsStr;
1929 if (Proto->getTypeQuals() & Qualifiers::Const)
1930 QualsStr += " const";
1931 if (Proto->getTypeQuals() & Qualifiers::Volatile)
1932 QualsStr += " volatile";
1933 if (Proto->getTypeQuals() & Qualifiers::Restrict)
1934 QualsStr += " restrict";
1935 Result->AddInformativeChunk(QualsStr);
1936}
1937
Douglas Gregor3545ff42009-09-21 16:56:56 +00001938/// \brief If possible, create a new code completion string for the given
1939/// result.
1940///
1941/// \returns Either a new, heap-allocated code completion string describing
1942/// how to use this result, or NULL to indicate that the string or name of the
1943/// result is all that is needed.
1944CodeCompletionString *
John McCall276321a2010-08-25 06:19:51 +00001945CodeCompletionResult::CreateCodeCompletionString(Sema &S,
Douglas Gregor8e984da2010-08-04 16:47:14 +00001946 CodeCompletionString *Result) {
Douglas Gregor9eb77012009-11-07 00:00:49 +00001947 typedef CodeCompletionString::Chunk Chunk;
1948
Douglas Gregorf09935f2009-12-01 05:55:20 +00001949 if (Kind == RK_Pattern)
Douglas Gregor8e984da2010-08-04 16:47:14 +00001950 return Pattern->Clone(Result);
Douglas Gregorf09935f2009-12-01 05:55:20 +00001951
Douglas Gregor8e984da2010-08-04 16:47:14 +00001952 if (!Result)
1953 Result = new CodeCompletionString;
Douglas Gregorf09935f2009-12-01 05:55:20 +00001954
1955 if (Kind == RK_Keyword) {
1956 Result->AddTypedTextChunk(Keyword);
1957 return Result;
1958 }
Douglas Gregor3545ff42009-09-21 16:56:56 +00001959
Douglas Gregorf329c7c2009-10-30 16:50:04 +00001960 if (Kind == RK_Macro) {
1961 MacroInfo *MI = S.PP.getMacroInfo(Macro);
Douglas Gregorf09935f2009-12-01 05:55:20 +00001962 assert(MI && "Not a macro?");
1963
1964 Result->AddTypedTextChunk(Macro->getName());
1965
1966 if (!MI->isFunctionLike())
1967 return Result;
Douglas Gregorf329c7c2009-10-30 16:50:04 +00001968
1969 // Format a function-like macro with placeholders for the arguments.
Douglas Gregor9eb77012009-11-07 00:00:49 +00001970 Result->AddChunk(Chunk(CodeCompletionString::CK_LeftParen));
Douglas Gregorf329c7c2009-10-30 16:50:04 +00001971 for (MacroInfo::arg_iterator A = MI->arg_begin(), AEnd = MI->arg_end();
1972 A != AEnd; ++A) {
1973 if (A != MI->arg_begin())
Douglas Gregor9eb77012009-11-07 00:00:49 +00001974 Result->AddChunk(Chunk(CodeCompletionString::CK_Comma));
Douglas Gregorf329c7c2009-10-30 16:50:04 +00001975
1976 if (!MI->isVariadic() || A != AEnd - 1) {
1977 // Non-variadic argument.
Benjamin Kramerb33a97c2009-11-29 20:18:50 +00001978 Result->AddPlaceholderChunk((*A)->getName());
Douglas Gregorf329c7c2009-10-30 16:50:04 +00001979 continue;
1980 }
1981
1982 // Variadic argument; cope with the different between GNU and C99
1983 // variadic macros, providing a single placeholder for the rest of the
1984 // arguments.
1985 if ((*A)->isStr("__VA_ARGS__"))
1986 Result->AddPlaceholderChunk("...");
1987 else {
1988 std::string Arg = (*A)->getName();
1989 Arg += "...";
Benjamin Kramerb33a97c2009-11-29 20:18:50 +00001990 Result->AddPlaceholderChunk(Arg);
Douglas Gregorf329c7c2009-10-30 16:50:04 +00001991 }
1992 }
Douglas Gregor9eb77012009-11-07 00:00:49 +00001993 Result->AddChunk(Chunk(CodeCompletionString::CK_RightParen));
Douglas Gregorf329c7c2009-10-30 16:50:04 +00001994 return Result;
1995 }
1996
Douglas Gregorf64acca2010-05-25 21:41:55 +00001997 assert(Kind == RK_Declaration && "Missed a result kind?");
Douglas Gregor3545ff42009-09-21 16:56:56 +00001998 NamedDecl *ND = Declaration;
1999
Douglas Gregor9eb77012009-11-07 00:00:49 +00002000 if (StartsNestedNameSpecifier) {
Benjamin Kramerb33a97c2009-11-29 20:18:50 +00002001 Result->AddTypedTextChunk(ND->getNameAsString());
Douglas Gregor9eb77012009-11-07 00:00:49 +00002002 Result->AddTextChunk("::");
2003 return Result;
2004 }
2005
Douglas Gregorb3fa9192009-12-18 18:53:37 +00002006 AddResultTypeChunk(S.Context, ND, Result);
2007
Douglas Gregor3545ff42009-09-21 16:56:56 +00002008 if (FunctionDecl *Function = dyn_cast<FunctionDecl>(ND)) {
Douglas Gregor5bf52692009-09-22 23:15:58 +00002009 AddQualifierToCompletionString(Result, Qualifier, QualifierIsInformative,
2010 S.Context);
Benjamin Kramerb33a97c2009-11-29 20:18:50 +00002011 Result->AddTypedTextChunk(Function->getNameAsString());
Douglas Gregor9eb77012009-11-07 00:00:49 +00002012 Result->AddChunk(Chunk(CodeCompletionString::CK_LeftParen));
Douglas Gregor3545ff42009-09-21 16:56:56 +00002013 AddFunctionParameterChunks(S.Context, Function, Result);
Douglas Gregor9eb77012009-11-07 00:00:49 +00002014 Result->AddChunk(Chunk(CodeCompletionString::CK_RightParen));
Douglas Gregor0f622362009-12-11 18:44:16 +00002015 AddFunctionTypeQualsToCompletionString(Result, Function);
Douglas Gregor3545ff42009-09-21 16:56:56 +00002016 return Result;
2017 }
2018
2019 if (FunctionTemplateDecl *FunTmpl = dyn_cast<FunctionTemplateDecl>(ND)) {
Douglas Gregor5bf52692009-09-22 23:15:58 +00002020 AddQualifierToCompletionString(Result, Qualifier, QualifierIsInformative,
2021 S.Context);
Douglas Gregor3545ff42009-09-21 16:56:56 +00002022 FunctionDecl *Function = FunTmpl->getTemplatedDecl();
Benjamin Kramerb33a97c2009-11-29 20:18:50 +00002023 Result->AddTypedTextChunk(Function->getNameAsString());
Douglas Gregor3545ff42009-09-21 16:56:56 +00002024
2025 // Figure out which template parameters are deduced (or have default
2026 // arguments).
2027 llvm::SmallVector<bool, 16> Deduced;
2028 S.MarkDeducedTemplateParameters(FunTmpl, Deduced);
2029 unsigned LastDeducibleArgument;
2030 for (LastDeducibleArgument = Deduced.size(); LastDeducibleArgument > 0;
2031 --LastDeducibleArgument) {
2032 if (!Deduced[LastDeducibleArgument - 1]) {
2033 // C++0x: Figure out if the template argument has a default. If so,
2034 // the user doesn't need to type this argument.
2035 // FIXME: We need to abstract template parameters better!
2036 bool HasDefaultArg = false;
2037 NamedDecl *Param = FunTmpl->getTemplateParameters()->getParam(
2038 LastDeducibleArgument - 1);
2039 if (TemplateTypeParmDecl *TTP = dyn_cast<TemplateTypeParmDecl>(Param))
2040 HasDefaultArg = TTP->hasDefaultArgument();
2041 else if (NonTypeTemplateParmDecl *NTTP
2042 = dyn_cast<NonTypeTemplateParmDecl>(Param))
2043 HasDefaultArg = NTTP->hasDefaultArgument();
2044 else {
2045 assert(isa<TemplateTemplateParmDecl>(Param));
2046 HasDefaultArg
Douglas Gregor9eb77012009-11-07 00:00:49 +00002047 = cast<TemplateTemplateParmDecl>(Param)->hasDefaultArgument();
Douglas Gregor3545ff42009-09-21 16:56:56 +00002048 }
2049
2050 if (!HasDefaultArg)
2051 break;
2052 }
2053 }
2054
2055 if (LastDeducibleArgument) {
2056 // Some of the function template arguments cannot be deduced from a
2057 // function call, so we introduce an explicit template argument list
2058 // containing all of the arguments up to the first deducible argument.
Douglas Gregor9eb77012009-11-07 00:00:49 +00002059 Result->AddChunk(Chunk(CodeCompletionString::CK_LeftAngle));
Douglas Gregor3545ff42009-09-21 16:56:56 +00002060 AddTemplateParameterChunks(S.Context, FunTmpl, Result,
2061 LastDeducibleArgument);
Douglas Gregor9eb77012009-11-07 00:00:49 +00002062 Result->AddChunk(Chunk(CodeCompletionString::CK_RightAngle));
Douglas Gregor3545ff42009-09-21 16:56:56 +00002063 }
2064
2065 // Add the function parameters
Douglas Gregor9eb77012009-11-07 00:00:49 +00002066 Result->AddChunk(Chunk(CodeCompletionString::CK_LeftParen));
Douglas Gregor3545ff42009-09-21 16:56:56 +00002067 AddFunctionParameterChunks(S.Context, Function, Result);
Douglas Gregor9eb77012009-11-07 00:00:49 +00002068 Result->AddChunk(Chunk(CodeCompletionString::CK_RightParen));
Douglas Gregor0f622362009-12-11 18:44:16 +00002069 AddFunctionTypeQualsToCompletionString(Result, Function);
Douglas Gregor3545ff42009-09-21 16:56:56 +00002070 return Result;
2071 }
2072
2073 if (TemplateDecl *Template = dyn_cast<TemplateDecl>(ND)) {
Douglas Gregor5bf52692009-09-22 23:15:58 +00002074 AddQualifierToCompletionString(Result, Qualifier, QualifierIsInformative,
2075 S.Context);
Benjamin Kramerb33a97c2009-11-29 20:18:50 +00002076 Result->AddTypedTextChunk(Template->getNameAsString());
Douglas Gregor9eb77012009-11-07 00:00:49 +00002077 Result->AddChunk(Chunk(CodeCompletionString::CK_LeftAngle));
Douglas Gregor3545ff42009-09-21 16:56:56 +00002078 AddTemplateParameterChunks(S.Context, Template, Result);
Douglas Gregor9eb77012009-11-07 00:00:49 +00002079 Result->AddChunk(Chunk(CodeCompletionString::CK_RightAngle));
Douglas Gregor3545ff42009-09-21 16:56:56 +00002080 return Result;
2081 }
2082
Douglas Gregord3c5d792009-11-17 16:44:22 +00002083 if (ObjCMethodDecl *Method = dyn_cast<ObjCMethodDecl>(ND)) {
Douglas Gregord3c5d792009-11-17 16:44:22 +00002084 Selector Sel = Method->getSelector();
2085 if (Sel.isUnarySelector()) {
2086 Result->AddTypedTextChunk(Sel.getIdentifierInfoForSlot(0)->getName());
2087 return Result;
2088 }
2089
Douglas Gregor1b605f72009-11-19 01:08:35 +00002090 std::string SelName = Sel.getIdentifierInfoForSlot(0)->getName().str();
2091 SelName += ':';
2092 if (StartParameter == 0)
2093 Result->AddTypedTextChunk(SelName);
2094 else {
2095 Result->AddInformativeChunk(SelName);
2096
2097 // If there is only one parameter, and we're past it, add an empty
2098 // typed-text chunk since there is nothing to type.
2099 if (Method->param_size() == 1)
2100 Result->AddTypedTextChunk("");
2101 }
Douglas Gregord3c5d792009-11-17 16:44:22 +00002102 unsigned Idx = 0;
2103 for (ObjCMethodDecl::param_iterator P = Method->param_begin(),
2104 PEnd = Method->param_end();
2105 P != PEnd; (void)++P, ++Idx) {
2106 if (Idx > 0) {
Douglas Gregor1b605f72009-11-19 01:08:35 +00002107 std::string Keyword;
2108 if (Idx > StartParameter)
Douglas Gregor6a803932010-01-12 06:38:28 +00002109 Result->AddChunk(CodeCompletionString::CK_HorizontalSpace);
Douglas Gregord3c5d792009-11-17 16:44:22 +00002110 if (IdentifierInfo *II = Sel.getIdentifierInfoForSlot(Idx))
2111 Keyword += II->getName().str();
2112 Keyword += ":";
Douglas Gregor95887f92010-07-08 23:20:03 +00002113 if (Idx < StartParameter || AllParametersAreInformative)
Douglas Gregor1b605f72009-11-19 01:08:35 +00002114 Result->AddInformativeChunk(Keyword);
Douglas Gregor95887f92010-07-08 23:20:03 +00002115 else if (Idx == StartParameter)
Douglas Gregor1b605f72009-11-19 01:08:35 +00002116 Result->AddTypedTextChunk(Keyword);
2117 else
2118 Result->AddTextChunk(Keyword);
Douglas Gregord3c5d792009-11-17 16:44:22 +00002119 }
Douglas Gregor1b605f72009-11-19 01:08:35 +00002120
2121 // If we're before the starting parameter, skip the placeholder.
2122 if (Idx < StartParameter)
2123 continue;
Douglas Gregord3c5d792009-11-17 16:44:22 +00002124
2125 std::string Arg;
Douglas Gregore90dd002010-08-24 16:15:59 +00002126
2127 if ((*P)->getType()->isBlockPointerType() && !DeclaringEntity)
2128 Arg = FormatFunctionParameter(S.Context, *P);
2129 else {
2130 (*P)->getType().getAsStringInternal(Arg, S.Context.PrintingPolicy);
2131 Arg = "(" + Arg + ")";
2132 if (IdentifierInfo *II = (*P)->getIdentifier())
2133 Arg += II->getName().str();
2134 }
2135
Douglas Gregor95887f92010-07-08 23:20:03 +00002136 if (DeclaringEntity)
2137 Result->AddTextChunk(Arg);
2138 else if (AllParametersAreInformative)
Douglas Gregorc8537c52009-11-19 07:41:15 +00002139 Result->AddInformativeChunk(Arg);
2140 else
2141 Result->AddPlaceholderChunk(Arg);
Douglas Gregord3c5d792009-11-17 16:44:22 +00002142 }
2143
Douglas Gregor04c5f972009-12-23 00:21:46 +00002144 if (Method->isVariadic()) {
Douglas Gregor95887f92010-07-08 23:20:03 +00002145 if (DeclaringEntity)
2146 Result->AddTextChunk(", ...");
2147 else if (AllParametersAreInformative)
Douglas Gregor04c5f972009-12-23 00:21:46 +00002148 Result->AddInformativeChunk(", ...");
2149 else
2150 Result->AddPlaceholderChunk(", ...");
Douglas Gregordbb71db2010-08-23 23:51:41 +00002151
2152 MaybeAddSentinel(S.Context, Method, Result);
Douglas Gregor04c5f972009-12-23 00:21:46 +00002153 }
2154
Douglas Gregord3c5d792009-11-17 16:44:22 +00002155 return Result;
2156 }
2157
Douglas Gregorf09935f2009-12-01 05:55:20 +00002158 if (Qualifier)
Douglas Gregor5bf52692009-09-22 23:15:58 +00002159 AddQualifierToCompletionString(Result, Qualifier, QualifierIsInformative,
2160 S.Context);
Douglas Gregorf09935f2009-12-01 05:55:20 +00002161
2162 Result->AddTypedTextChunk(ND->getNameAsString());
2163 return Result;
Douglas Gregor3545ff42009-09-21 16:56:56 +00002164}
2165
Douglas Gregorf0f51982009-09-23 00:34:09 +00002166CodeCompletionString *
2167CodeCompleteConsumer::OverloadCandidate::CreateSignatureString(
2168 unsigned CurrentArg,
2169 Sema &S) const {
Douglas Gregor9eb77012009-11-07 00:00:49 +00002170 typedef CodeCompletionString::Chunk Chunk;
2171
Douglas Gregorf0f51982009-09-23 00:34:09 +00002172 CodeCompletionString *Result = new CodeCompletionString;
2173 FunctionDecl *FDecl = getFunction();
Douglas Gregorb3fa9192009-12-18 18:53:37 +00002174 AddResultTypeChunk(S.Context, FDecl, Result);
Douglas Gregorf0f51982009-09-23 00:34:09 +00002175 const FunctionProtoType *Proto
2176 = dyn_cast<FunctionProtoType>(getFunctionType());
2177 if (!FDecl && !Proto) {
2178 // Function without a prototype. Just give the return type and a
2179 // highlighted ellipsis.
2180 const FunctionType *FT = getFunctionType();
2181 Result->AddTextChunk(
Benjamin Kramerb33a97c2009-11-29 20:18:50 +00002182 FT->getResultType().getAsString(S.Context.PrintingPolicy));
Douglas Gregor9eb77012009-11-07 00:00:49 +00002183 Result->AddChunk(Chunk(CodeCompletionString::CK_LeftParen));
2184 Result->AddChunk(Chunk(CodeCompletionString::CK_CurrentParameter, "..."));
2185 Result->AddChunk(Chunk(CodeCompletionString::CK_RightParen));
Douglas Gregorf0f51982009-09-23 00:34:09 +00002186 return Result;
2187 }
2188
2189 if (FDecl)
Benjamin Kramerb33a97c2009-11-29 20:18:50 +00002190 Result->AddTextChunk(FDecl->getNameAsString());
Douglas Gregorf0f51982009-09-23 00:34:09 +00002191 else
2192 Result->AddTextChunk(
Benjamin Kramerb33a97c2009-11-29 20:18:50 +00002193 Proto->getResultType().getAsString(S.Context.PrintingPolicy));
Douglas Gregorf0f51982009-09-23 00:34:09 +00002194
Douglas Gregor9eb77012009-11-07 00:00:49 +00002195 Result->AddChunk(Chunk(CodeCompletionString::CK_LeftParen));
Douglas Gregorf0f51982009-09-23 00:34:09 +00002196 unsigned NumParams = FDecl? FDecl->getNumParams() : Proto->getNumArgs();
2197 for (unsigned I = 0; I != NumParams; ++I) {
2198 if (I)
Douglas Gregor9eb77012009-11-07 00:00:49 +00002199 Result->AddChunk(Chunk(CodeCompletionString::CK_Comma));
Douglas Gregorf0f51982009-09-23 00:34:09 +00002200
2201 std::string ArgString;
2202 QualType ArgType;
2203
2204 if (FDecl) {
2205 ArgString = FDecl->getParamDecl(I)->getNameAsString();
2206 ArgType = FDecl->getParamDecl(I)->getOriginalType();
2207 } else {
2208 ArgType = Proto->getArgType(I);
2209 }
2210
2211 ArgType.getAsStringInternal(ArgString, S.Context.PrintingPolicy);
2212
2213 if (I == CurrentArg)
Douglas Gregor9eb77012009-11-07 00:00:49 +00002214 Result->AddChunk(Chunk(CodeCompletionString::CK_CurrentParameter,
Benjamin Kramerb33a97c2009-11-29 20:18:50 +00002215 ArgString));
Douglas Gregorf0f51982009-09-23 00:34:09 +00002216 else
Benjamin Kramerb33a97c2009-11-29 20:18:50 +00002217 Result->AddTextChunk(ArgString);
Douglas Gregorf0f51982009-09-23 00:34:09 +00002218 }
2219
2220 if (Proto && Proto->isVariadic()) {
Douglas Gregor9eb77012009-11-07 00:00:49 +00002221 Result->AddChunk(Chunk(CodeCompletionString::CK_Comma));
Douglas Gregorf0f51982009-09-23 00:34:09 +00002222 if (CurrentArg < NumParams)
2223 Result->AddTextChunk("...");
2224 else
Douglas Gregor9eb77012009-11-07 00:00:49 +00002225 Result->AddChunk(Chunk(CodeCompletionString::CK_CurrentParameter, "..."));
Douglas Gregorf0f51982009-09-23 00:34:09 +00002226 }
Douglas Gregor9eb77012009-11-07 00:00:49 +00002227 Result->AddChunk(Chunk(CodeCompletionString::CK_RightParen));
Douglas Gregorf0f51982009-09-23 00:34:09 +00002228
2229 return Result;
2230}
2231
Douglas Gregor3545ff42009-09-21 16:56:56 +00002232namespace {
2233 struct SortCodeCompleteResult {
John McCall276321a2010-08-25 06:19:51 +00002234 typedef CodeCompletionResult Result;
Douglas Gregor3545ff42009-09-21 16:56:56 +00002235
Douglas Gregor52ce62f2010-01-13 23:24:38 +00002236 /// \brief Retrieve the name that should be used to order a result.
2237 ///
2238 /// If the name needs to be constructed as a string, that string will be
2239 /// saved into Saved and the returned StringRef will refer to it.
2240 static llvm::StringRef getOrderedName(const Result &R,
2241 std::string &Saved) {
2242 switch (R.Kind) {
2243 case Result::RK_Keyword:
2244 return R.Keyword;
2245
2246 case Result::RK_Pattern:
2247 return R.Pattern->getTypedText();
2248
2249 case Result::RK_Macro:
2250 return R.Macro->getName();
2251
2252 case Result::RK_Declaration:
2253 // Handle declarations below.
2254 break;
Douglas Gregor45f83ee2009-11-19 00:01:57 +00002255 }
Douglas Gregor52ce62f2010-01-13 23:24:38 +00002256
2257 DeclarationName Name = R.Declaration->getDeclName();
Douglas Gregor45f83ee2009-11-19 00:01:57 +00002258
Douglas Gregor52ce62f2010-01-13 23:24:38 +00002259 // If the name is a simple identifier (by far the common case), or a
2260 // zero-argument selector, just return a reference to that identifier.
2261 if (IdentifierInfo *Id = Name.getAsIdentifierInfo())
2262 return Id->getName();
2263 if (Name.isObjCZeroArgSelector())
2264 if (IdentifierInfo *Id
2265 = Name.getObjCSelector().getIdentifierInfoForSlot(0))
2266 return Id->getName();
2267
2268 Saved = Name.getAsString();
2269 return Saved;
2270 }
2271
2272 bool operator()(const Result &X, const Result &Y) const {
2273 std::string XSaved, YSaved;
2274 llvm::StringRef XStr = getOrderedName(X, XSaved);
2275 llvm::StringRef YStr = getOrderedName(Y, YSaved);
2276 int cmp = XStr.compare_lower(YStr);
2277 if (cmp)
2278 return cmp < 0;
Douglas Gregor3545ff42009-09-21 16:56:56 +00002279
2280 // Non-hidden names precede hidden names.
2281 if (X.Hidden != Y.Hidden)
2282 return !X.Hidden;
2283
Douglas Gregore412a5a2009-09-23 22:26:46 +00002284 // Non-nested-name-specifiers precede nested-name-specifiers.
2285 if (X.StartsNestedNameSpecifier != Y.StartsNestedNameSpecifier)
2286 return !X.StartsNestedNameSpecifier;
2287
Douglas Gregor3545ff42009-09-21 16:56:56 +00002288 return false;
2289 }
2290 };
2291}
2292
Douglas Gregor6e240332010-08-16 16:18:59 +00002293unsigned clang::getMacroUsagePriority(llvm::StringRef MacroName,
2294 bool PreferredTypeIsPointer) {
2295 unsigned Priority = CCP_Macro;
2296
2297 // Treat the "nil" and "NULL" macros as null pointer constants.
2298 if (MacroName.equals("nil") || MacroName.equals("NULL")) {
2299 Priority = CCP_Constant;
2300 if (PreferredTypeIsPointer)
2301 Priority = Priority / CCF_SimilarTypeMatch;
2302 }
2303
2304 return Priority;
2305}
2306
Douglas Gregor55b037b2010-07-08 20:55:51 +00002307static void AddMacroResults(Preprocessor &PP, ResultBuilder &Results,
2308 bool TargetTypeIsPointer = false) {
John McCall276321a2010-08-25 06:19:51 +00002309 typedef CodeCompletionResult Result;
Douglas Gregor55b037b2010-07-08 20:55:51 +00002310
Douglas Gregorf329c7c2009-10-30 16:50:04 +00002311 Results.EnterNewScope();
Douglas Gregor9eb77012009-11-07 00:00:49 +00002312 for (Preprocessor::macro_iterator M = PP.macro_begin(),
2313 MEnd = PP.macro_end();
Douglas Gregor55b037b2010-07-08 20:55:51 +00002314 M != MEnd; ++M) {
Douglas Gregor6e240332010-08-16 16:18:59 +00002315 Results.AddResult(Result(M->first,
2316 getMacroUsagePriority(M->first->getName(),
2317 TargetTypeIsPointer)));
Douglas Gregor55b037b2010-07-08 20:55:51 +00002318 }
Douglas Gregorf329c7c2009-10-30 16:50:04 +00002319 Results.ExitScope();
2320}
2321
Douglas Gregorce0e8562010-08-23 21:54:33 +00002322static void AddPrettyFunctionResults(const LangOptions &LangOpts,
2323 ResultBuilder &Results) {
John McCall276321a2010-08-25 06:19:51 +00002324 typedef CodeCompletionResult Result;
Douglas Gregorce0e8562010-08-23 21:54:33 +00002325
2326 Results.EnterNewScope();
2327 Results.AddResult(Result("__PRETTY_FUNCTION__", CCP_Constant));
2328 Results.AddResult(Result("__FUNCTION__", CCP_Constant));
2329 if (LangOpts.C99 || LangOpts.CPlusPlus0x)
2330 Results.AddResult(Result("__func__", CCP_Constant));
2331 Results.ExitScope();
2332}
2333
Daniel Dunbar242ea9a2009-11-13 08:58:20 +00002334static void HandleCodeCompleteResults(Sema *S,
2335 CodeCompleteConsumer *CodeCompleter,
Douglas Gregor00c37ef2010-08-11 21:23:17 +00002336 CodeCompletionContext Context,
John McCall276321a2010-08-25 06:19:51 +00002337 CodeCompletionResult *Results,
Douglas Gregor00c37ef2010-08-11 21:23:17 +00002338 unsigned NumResults) {
Douglas Gregor3545ff42009-09-21 16:56:56 +00002339 std::stable_sort(Results, Results + NumResults, SortCodeCompleteResult());
2340
2341 if (CodeCompleter)
Douglas Gregor00c37ef2010-08-11 21:23:17 +00002342 CodeCompleter->ProcessCodeCompleteResults(*S, Context, Results, NumResults);
Douglas Gregor45f83ee2009-11-19 00:01:57 +00002343
2344 for (unsigned I = 0; I != NumResults; ++I)
2345 Results[I].Destroy();
Douglas Gregor3545ff42009-09-21 16:56:56 +00002346}
2347
Douglas Gregor00c37ef2010-08-11 21:23:17 +00002348static enum CodeCompletionContext::Kind mapCodeCompletionContext(Sema &S,
2349 Sema::ParserCompletionContext PCC) {
2350 switch (PCC) {
2351 case Action::PCC_Namespace:
2352 return CodeCompletionContext::CCC_TopLevel;
2353
2354 case Action::PCC_Class:
2355 return CodeCompletionContext::CCC_ClassStructUnion;
2356
2357 case Action::PCC_ObjCInterface:
2358 return CodeCompletionContext::CCC_ObjCInterface;
2359
2360 case Action::PCC_ObjCImplementation:
2361 return CodeCompletionContext::CCC_ObjCImplementation;
2362
2363 case Action::PCC_ObjCInstanceVariableList:
2364 return CodeCompletionContext::CCC_ObjCIvarList;
2365
2366 case Action::PCC_Template:
2367 case Action::PCC_MemberTemplate:
2368 case Action::PCC_RecoveryInFunction:
2369 return CodeCompletionContext::CCC_Other;
2370
2371 case Action::PCC_Expression:
2372 case Action::PCC_ForInit:
2373 case Action::PCC_Condition:
2374 return CodeCompletionContext::CCC_Expression;
2375
2376 case Action::PCC_Statement:
2377 return CodeCompletionContext::CCC_Statement;
Douglas Gregorf02e5f32010-08-24 01:11:00 +00002378
2379 case Action::PCC_Type:
2380 return CodeCompletionContext::CCC_Type;
Douglas Gregor00c37ef2010-08-11 21:23:17 +00002381 }
2382
2383 return CodeCompletionContext::CCC_Other;
2384}
2385
Douglas Gregor504a6ae2010-01-10 23:08:15 +00002386void Sema::CodeCompleteOrdinaryName(Scope *S,
Douglas Gregor00c37ef2010-08-11 21:23:17 +00002387 ParserCompletionContext CompletionContext) {
John McCall276321a2010-08-25 06:19:51 +00002388 typedef CodeCompletionResult Result;
Douglas Gregorc49f5b22010-08-23 18:23:48 +00002389 ResultBuilder Results(*this);
Douglas Gregor504a6ae2010-01-10 23:08:15 +00002390
2391 // Determine how to filter results, e.g., so that the names of
2392 // values (functions, enumerators, function templates, etc.) are
2393 // only allowed where we can have an expression.
2394 switch (CompletionContext) {
Douglas Gregor00c37ef2010-08-11 21:23:17 +00002395 case PCC_Namespace:
2396 case PCC_Class:
2397 case PCC_ObjCInterface:
2398 case PCC_ObjCImplementation:
2399 case PCC_ObjCInstanceVariableList:
2400 case PCC_Template:
2401 case PCC_MemberTemplate:
Douglas Gregorf02e5f32010-08-24 01:11:00 +00002402 case PCC_Type:
Douglas Gregor504a6ae2010-01-10 23:08:15 +00002403 Results.setFilter(&ResultBuilder::IsOrdinaryNonValueName);
2404 break;
2405
Douglas Gregor00c37ef2010-08-11 21:23:17 +00002406 case PCC_Statement:
Douglas Gregor4d755e82010-08-24 23:58:17 +00002407 // For statements that are expressions, we prefer to call 'void' functions
2408 // rather than functions that return a result, since then the result would
2409 // be ignored.
2410 Results.setPreferredType(Context.VoidTy);
2411 // Fall through
2412
2413 case PCC_Expression:
Douglas Gregor00c37ef2010-08-11 21:23:17 +00002414 case PCC_ForInit:
2415 case PCC_Condition:
Douglas Gregor70febae2010-05-28 00:49:12 +00002416 if (WantTypesInContext(CompletionContext, getLangOptions()))
2417 Results.setFilter(&ResultBuilder::IsOrdinaryName);
2418 else
2419 Results.setFilter(&ResultBuilder::IsOrdinaryNonTypeName);
Douglas Gregor504a6ae2010-01-10 23:08:15 +00002420 break;
Douglas Gregor6da3db42010-05-25 05:58:43 +00002421
Douglas Gregor00c37ef2010-08-11 21:23:17 +00002422 case PCC_RecoveryInFunction:
Douglas Gregor6da3db42010-05-25 05:58:43 +00002423 // Unfiltered
2424 break;
Douglas Gregor504a6ae2010-01-10 23:08:15 +00002425 }
2426
Douglas Gregorc580c522010-01-14 01:09:38 +00002427 CodeCompletionDeclConsumer Consumer(Results, CurContext);
Douglas Gregor39982192010-08-15 06:18:01 +00002428 LookupVisibleDecls(S, LookupOrdinaryName, Consumer,
2429 CodeCompleter->includeGlobals());
Douglas Gregor92253692009-12-07 09:54:55 +00002430
2431 Results.EnterNewScope();
Douglas Gregorf98e6a22010-01-13 23:51:12 +00002432 AddOrdinaryNameResults(CompletionContext, S, *this, Results);
Douglas Gregor92253692009-12-07 09:54:55 +00002433 Results.ExitScope();
2434
Douglas Gregorce0e8562010-08-23 21:54:33 +00002435 switch (CompletionContext) {
Douglas Gregorf02e5f32010-08-24 01:11:00 +00002436 case PCC_Expression:
2437 case PCC_Statement:
2438 case PCC_RecoveryInFunction:
2439 if (S->getFnParent())
2440 AddPrettyFunctionResults(PP.getLangOptions(), Results);
2441 break;
2442
2443 case PCC_Namespace:
2444 case PCC_Class:
2445 case PCC_ObjCInterface:
2446 case PCC_ObjCImplementation:
2447 case PCC_ObjCInstanceVariableList:
2448 case PCC_Template:
2449 case PCC_MemberTemplate:
2450 case PCC_ForInit:
2451 case PCC_Condition:
2452 case PCC_Type:
2453 break;
Douglas Gregorce0e8562010-08-23 21:54:33 +00002454 }
2455
Douglas Gregor9eb77012009-11-07 00:00:49 +00002456 if (CodeCompleter->includeMacros())
Douglas Gregorf98e6a22010-01-13 23:51:12 +00002457 AddMacroResults(PP, Results);
Douglas Gregorce0e8562010-08-23 21:54:33 +00002458
Douglas Gregor00c37ef2010-08-11 21:23:17 +00002459 HandleCodeCompleteResults(this, CodeCompleter,
2460 mapCodeCompletionContext(*this, CompletionContext),
2461 Results.data(),Results.size());
Douglas Gregor9d64c5e2009-09-21 20:51:25 +00002462}
2463
Douglas Gregorc49f5b22010-08-23 18:23:48 +00002464void Sema::CodeCompleteDeclarator(Scope *S,
2465 bool AllowNonIdentifiers,
2466 bool AllowNestedNameSpecifiers) {
John McCall276321a2010-08-25 06:19:51 +00002467 typedef CodeCompletionResult Result;
Douglas Gregorc49f5b22010-08-23 18:23:48 +00002468 ResultBuilder Results(*this);
2469 Results.EnterNewScope();
2470
2471 // Type qualifiers can come after names.
2472 Results.AddResult(Result("const"));
2473 Results.AddResult(Result("volatile"));
2474 if (getLangOptions().C99)
2475 Results.AddResult(Result("restrict"));
2476
2477 if (getLangOptions().CPlusPlus) {
2478 if (AllowNonIdentifiers) {
2479 Results.AddResult(Result("operator"));
2480 }
2481
2482 // Add nested-name-specifiers.
2483 if (AllowNestedNameSpecifiers) {
2484 Results.allowNestedNameSpecifiers();
2485 CodeCompletionDeclConsumer Consumer(Results, CurContext);
2486 LookupVisibleDecls(S, LookupNestedNameSpecifierName, Consumer,
2487 CodeCompleter->includeGlobals());
2488 }
2489 }
2490 Results.ExitScope();
2491
Douglas Gregor56ccce02010-08-24 04:59:56 +00002492 // Note that we intentionally suppress macro results here, since we do not
2493 // encourage using macros to produce the names of entities.
2494
Douglas Gregorc49f5b22010-08-23 18:23:48 +00002495 HandleCodeCompleteResults(this, CodeCompleter,
2496 AllowNestedNameSpecifiers
2497 ? CodeCompletionContext::CCC_PotentiallyQualifiedName
2498 : CodeCompletionContext::CCC_Name,
2499 Results.data(), Results.size());
2500}
2501
Douglas Gregor68762e72010-08-23 21:17:50 +00002502struct Sema::CodeCompleteExpressionData {
2503 CodeCompleteExpressionData(QualType PreferredType = QualType())
2504 : PreferredType(PreferredType), IntegralConstantExpression(false),
2505 ObjCCollection(false) { }
2506
2507 QualType PreferredType;
2508 bool IntegralConstantExpression;
2509 bool ObjCCollection;
2510 llvm::SmallVector<Decl *, 4> IgnoreDecls;
2511};
2512
Douglas Gregor7aa6b222010-05-30 01:49:25 +00002513/// \brief Perform code-completion in an expression context when we know what
2514/// type we're looking for.
Douglas Gregor85b50632010-07-28 21:50:18 +00002515///
2516/// \param IntegralConstantExpression Only permit integral constant
2517/// expressions.
Douglas Gregor68762e72010-08-23 21:17:50 +00002518void Sema::CodeCompleteExpression(Scope *S,
2519 const CodeCompleteExpressionData &Data) {
John McCall276321a2010-08-25 06:19:51 +00002520 typedef CodeCompletionResult Result;
Douglas Gregor7aa6b222010-05-30 01:49:25 +00002521 ResultBuilder Results(*this);
2522
Douglas Gregor68762e72010-08-23 21:17:50 +00002523 if (Data.ObjCCollection)
2524 Results.setFilter(&ResultBuilder::IsObjCCollection);
2525 else if (Data.IntegralConstantExpression)
Douglas Gregor85b50632010-07-28 21:50:18 +00002526 Results.setFilter(&ResultBuilder::IsIntegralConstantValue);
Douglas Gregor00c37ef2010-08-11 21:23:17 +00002527 else if (WantTypesInContext(PCC_Expression, getLangOptions()))
Douglas Gregor7aa6b222010-05-30 01:49:25 +00002528 Results.setFilter(&ResultBuilder::IsOrdinaryName);
2529 else
2530 Results.setFilter(&ResultBuilder::IsOrdinaryNonTypeName);
Douglas Gregor68762e72010-08-23 21:17:50 +00002531
2532 if (!Data.PreferredType.isNull())
2533 Results.setPreferredType(Data.PreferredType.getNonReferenceType());
2534
2535 // Ignore any declarations that we were told that we don't care about.
2536 for (unsigned I = 0, N = Data.IgnoreDecls.size(); I != N; ++I)
2537 Results.Ignore(Data.IgnoreDecls[I]);
Douglas Gregor7aa6b222010-05-30 01:49:25 +00002538
2539 CodeCompletionDeclConsumer Consumer(Results, CurContext);
Douglas Gregor39982192010-08-15 06:18:01 +00002540 LookupVisibleDecls(S, LookupOrdinaryName, Consumer,
2541 CodeCompleter->includeGlobals());
Douglas Gregor7aa6b222010-05-30 01:49:25 +00002542
2543 Results.EnterNewScope();
Douglas Gregor00c37ef2010-08-11 21:23:17 +00002544 AddOrdinaryNameResults(PCC_Expression, S, *this, Results);
Douglas Gregor7aa6b222010-05-30 01:49:25 +00002545 Results.ExitScope();
2546
Douglas Gregor55b037b2010-07-08 20:55:51 +00002547 bool PreferredTypeIsPointer = false;
Douglas Gregor68762e72010-08-23 21:17:50 +00002548 if (!Data.PreferredType.isNull())
2549 PreferredTypeIsPointer = Data.PreferredType->isAnyPointerType()
2550 || Data.PreferredType->isMemberPointerType()
2551 || Data.PreferredType->isBlockPointerType();
Douglas Gregor55b037b2010-07-08 20:55:51 +00002552
Douglas Gregorce0e8562010-08-23 21:54:33 +00002553 if (S->getFnParent() &&
2554 !Data.ObjCCollection &&
2555 !Data.IntegralConstantExpression)
2556 AddPrettyFunctionResults(PP.getLangOptions(), Results);
2557
Douglas Gregor7aa6b222010-05-30 01:49:25 +00002558 if (CodeCompleter->includeMacros())
Douglas Gregor55b037b2010-07-08 20:55:51 +00002559 AddMacroResults(PP, Results, PreferredTypeIsPointer);
Douglas Gregor00c37ef2010-08-11 21:23:17 +00002560 HandleCodeCompleteResults(this, CodeCompleter,
Douglas Gregor68762e72010-08-23 21:17:50 +00002561 CodeCompletionContext(CodeCompletionContext::CCC_Expression,
2562 Data.PreferredType),
Douglas Gregor00c37ef2010-08-11 21:23:17 +00002563 Results.data(),Results.size());
Douglas Gregor7aa6b222010-05-30 01:49:25 +00002564}
2565
2566
Douglas Gregor9291bad2009-11-18 01:29:26 +00002567static void AddObjCProperties(ObjCContainerDecl *Container,
Douglas Gregor5d649882009-11-18 22:32:06 +00002568 bool AllowCategories,
Douglas Gregor9291bad2009-11-18 01:29:26 +00002569 DeclContext *CurContext,
2570 ResultBuilder &Results) {
John McCall276321a2010-08-25 06:19:51 +00002571 typedef CodeCompletionResult Result;
Douglas Gregor9291bad2009-11-18 01:29:26 +00002572
2573 // Add properties in this container.
2574 for (ObjCContainerDecl::prop_iterator P = Container->prop_begin(),
2575 PEnd = Container->prop_end();
2576 P != PEnd;
2577 ++P)
2578 Results.MaybeAddResult(Result(*P, 0), CurContext);
2579
2580 // Add properties in referenced protocols.
2581 if (ObjCProtocolDecl *Protocol = dyn_cast<ObjCProtocolDecl>(Container)) {
2582 for (ObjCProtocolDecl::protocol_iterator P = Protocol->protocol_begin(),
2583 PEnd = Protocol->protocol_end();
2584 P != PEnd; ++P)
Douglas Gregor5d649882009-11-18 22:32:06 +00002585 AddObjCProperties(*P, AllowCategories, CurContext, Results);
Douglas Gregor9291bad2009-11-18 01:29:26 +00002586 } else if (ObjCInterfaceDecl *IFace = dyn_cast<ObjCInterfaceDecl>(Container)){
Douglas Gregor5d649882009-11-18 22:32:06 +00002587 if (AllowCategories) {
2588 // Look through categories.
2589 for (ObjCCategoryDecl *Category = IFace->getCategoryList();
2590 Category; Category = Category->getNextClassCategory())
2591 AddObjCProperties(Category, AllowCategories, CurContext, Results);
2592 }
Douglas Gregor9291bad2009-11-18 01:29:26 +00002593
2594 // Look through protocols.
2595 for (ObjCInterfaceDecl::protocol_iterator I = IFace->protocol_begin(),
2596 E = IFace->protocol_end();
2597 I != E; ++I)
Douglas Gregor5d649882009-11-18 22:32:06 +00002598 AddObjCProperties(*I, AllowCategories, CurContext, Results);
Douglas Gregor9291bad2009-11-18 01:29:26 +00002599
2600 // Look in the superclass.
2601 if (IFace->getSuperClass())
Douglas Gregor5d649882009-11-18 22:32:06 +00002602 AddObjCProperties(IFace->getSuperClass(), AllowCategories, CurContext,
2603 Results);
Douglas Gregor9291bad2009-11-18 01:29:26 +00002604 } else if (const ObjCCategoryDecl *Category
2605 = dyn_cast<ObjCCategoryDecl>(Container)) {
2606 // Look through protocols.
2607 for (ObjCInterfaceDecl::protocol_iterator P = Category->protocol_begin(),
2608 PEnd = Category->protocol_end();
2609 P != PEnd; ++P)
Douglas Gregor5d649882009-11-18 22:32:06 +00002610 AddObjCProperties(*P, AllowCategories, CurContext, Results);
Douglas Gregor9291bad2009-11-18 01:29:26 +00002611 }
2612}
2613
Douglas Gregor2436e712009-09-17 21:32:03 +00002614void Sema::CodeCompleteMemberReferenceExpr(Scope *S, ExprTy *BaseE,
2615 SourceLocation OpLoc,
2616 bool IsArrow) {
2617 if (!BaseE || !CodeCompleter)
2618 return;
2619
John McCall276321a2010-08-25 06:19:51 +00002620 typedef CodeCompletionResult Result;
Douglas Gregor3545ff42009-09-21 16:56:56 +00002621
Douglas Gregor2436e712009-09-17 21:32:03 +00002622 Expr *Base = static_cast<Expr *>(BaseE);
2623 QualType BaseType = Base->getType();
Douglas Gregor3545ff42009-09-21 16:56:56 +00002624
2625 if (IsArrow) {
2626 if (const PointerType *Ptr = BaseType->getAs<PointerType>())
2627 BaseType = Ptr->getPointeeType();
2628 else if (BaseType->isObjCObjectPointerType())
2629 /*Do nothing*/ ;
2630 else
2631 return;
2632 }
2633
Douglas Gregore412a5a2009-09-23 22:26:46 +00002634 ResultBuilder Results(*this, &ResultBuilder::IsMember);
Douglas Gregor9291bad2009-11-18 01:29:26 +00002635 Results.EnterNewScope();
2636 if (const RecordType *Record = BaseType->getAs<RecordType>()) {
2637 // Access to a C/C++ class, struct, or union.
Douglas Gregor6ae4c522010-01-14 03:21:49 +00002638 Results.allowNestedNameSpecifiers();
Douglas Gregor09bbc652010-01-14 15:47:35 +00002639 CodeCompletionDeclConsumer Consumer(Results, CurContext);
Douglas Gregor39982192010-08-15 06:18:01 +00002640 LookupVisibleDecls(Record->getDecl(), LookupMemberName, Consumer,
2641 CodeCompleter->includeGlobals());
Daniel Dunbar242ea9a2009-11-13 08:58:20 +00002642
Douglas Gregor9291bad2009-11-18 01:29:26 +00002643 if (getLangOptions().CPlusPlus) {
2644 if (!Results.empty()) {
2645 // The "template" keyword can follow "->" or "." in the grammar.
2646 // However, we only want to suggest the template keyword if something
2647 // is dependent.
2648 bool IsDependent = BaseType->isDependentType();
2649 if (!IsDependent) {
2650 for (Scope *DepScope = S; DepScope; DepScope = DepScope->getParent())
2651 if (DeclContext *Ctx = (DeclContext *)DepScope->getEntity()) {
2652 IsDependent = Ctx->isDependentContext();
2653 break;
2654 }
2655 }
Daniel Dunbar242ea9a2009-11-13 08:58:20 +00002656
Douglas Gregor9291bad2009-11-18 01:29:26 +00002657 if (IsDependent)
Douglas Gregor78a21012010-01-14 16:01:26 +00002658 Results.AddResult(Result("template"));
Daniel Dunbar242ea9a2009-11-13 08:58:20 +00002659 }
Daniel Dunbar242ea9a2009-11-13 08:58:20 +00002660 }
Douglas Gregor9291bad2009-11-18 01:29:26 +00002661 } else if (!IsArrow && BaseType->getAsObjCInterfacePointerType()) {
2662 // Objective-C property reference.
2663
2664 // Add property results based on our interface.
2665 const ObjCObjectPointerType *ObjCPtr
2666 = BaseType->getAsObjCInterfacePointerType();
2667 assert(ObjCPtr && "Non-NULL pointer guaranteed above!");
Douglas Gregor5d649882009-11-18 22:32:06 +00002668 AddObjCProperties(ObjCPtr->getInterfaceDecl(), true, CurContext, Results);
Douglas Gregor9291bad2009-11-18 01:29:26 +00002669
2670 // Add properties from the protocols in a qualified interface.
2671 for (ObjCObjectPointerType::qual_iterator I = ObjCPtr->qual_begin(),
2672 E = ObjCPtr->qual_end();
2673 I != E; ++I)
Douglas Gregor5d649882009-11-18 22:32:06 +00002674 AddObjCProperties(*I, true, CurContext, Results);
Douglas Gregor9291bad2009-11-18 01:29:26 +00002675 } else if ((IsArrow && BaseType->isObjCObjectPointerType()) ||
John McCall8b07ec22010-05-15 11:32:37 +00002676 (!IsArrow && BaseType->isObjCObjectType())) {
Douglas Gregor9291bad2009-11-18 01:29:26 +00002677 // Objective-C instance variable access.
2678 ObjCInterfaceDecl *Class = 0;
2679 if (const ObjCObjectPointerType *ObjCPtr
2680 = BaseType->getAs<ObjCObjectPointerType>())
2681 Class = ObjCPtr->getInterfaceDecl();
2682 else
John McCall8b07ec22010-05-15 11:32:37 +00002683 Class = BaseType->getAs<ObjCObjectType>()->getInterface();
Douglas Gregor9291bad2009-11-18 01:29:26 +00002684
2685 // Add all ivars from this class and its superclasses.
Douglas Gregor2b8162b2010-01-14 16:08:12 +00002686 if (Class) {
2687 CodeCompletionDeclConsumer Consumer(Results, CurContext);
2688 Results.setFilter(&ResultBuilder::IsObjCIvar);
Douglas Gregor39982192010-08-15 06:18:01 +00002689 LookupVisibleDecls(Class, LookupMemberName, Consumer,
2690 CodeCompleter->includeGlobals());
Douglas Gregor9291bad2009-11-18 01:29:26 +00002691 }
Douglas Gregor3545ff42009-09-21 16:56:56 +00002692 }
Douglas Gregor9291bad2009-11-18 01:29:26 +00002693
2694 // FIXME: How do we cope with isa?
2695
2696 Results.ExitScope();
Daniel Dunbar242ea9a2009-11-13 08:58:20 +00002697
Daniel Dunbar242ea9a2009-11-13 08:58:20 +00002698 // Hand off the results found for code completion.
Douglas Gregor00c37ef2010-08-11 21:23:17 +00002699 HandleCodeCompleteResults(this, CodeCompleter,
2700 CodeCompletionContext(CodeCompletionContext::CCC_MemberAccess,
2701 BaseType),
2702 Results.data(),Results.size());
Douglas Gregor2436e712009-09-17 21:32:03 +00002703}
2704
Douglas Gregorf45b0cf2009-09-18 15:37:17 +00002705void Sema::CodeCompleteTag(Scope *S, unsigned TagSpec) {
2706 if (!CodeCompleter)
2707 return;
2708
John McCall276321a2010-08-25 06:19:51 +00002709 typedef CodeCompletionResult Result;
Douglas Gregor3545ff42009-09-21 16:56:56 +00002710 ResultBuilder::LookupFilter Filter = 0;
Douglas Gregor00c37ef2010-08-11 21:23:17 +00002711 enum CodeCompletionContext::Kind ContextKind
2712 = CodeCompletionContext::CCC_Other;
Douglas Gregorf45b0cf2009-09-18 15:37:17 +00002713 switch ((DeclSpec::TST)TagSpec) {
2714 case DeclSpec::TST_enum:
Douglas Gregor3545ff42009-09-21 16:56:56 +00002715 Filter = &ResultBuilder::IsEnum;
Douglas Gregor00c37ef2010-08-11 21:23:17 +00002716 ContextKind = CodeCompletionContext::CCC_EnumTag;
Douglas Gregorf45b0cf2009-09-18 15:37:17 +00002717 break;
2718
2719 case DeclSpec::TST_union:
Douglas Gregor3545ff42009-09-21 16:56:56 +00002720 Filter = &ResultBuilder::IsUnion;
Douglas Gregor00c37ef2010-08-11 21:23:17 +00002721 ContextKind = CodeCompletionContext::CCC_UnionTag;
Douglas Gregorf45b0cf2009-09-18 15:37:17 +00002722 break;
2723
2724 case DeclSpec::TST_struct:
Douglas Gregorf45b0cf2009-09-18 15:37:17 +00002725 case DeclSpec::TST_class:
Douglas Gregor3545ff42009-09-21 16:56:56 +00002726 Filter = &ResultBuilder::IsClassOrStruct;
Douglas Gregor00c37ef2010-08-11 21:23:17 +00002727 ContextKind = CodeCompletionContext::CCC_ClassOrStructTag;
Douglas Gregorf45b0cf2009-09-18 15:37:17 +00002728 break;
2729
2730 default:
2731 assert(false && "Unknown type specifier kind in CodeCompleteTag");
2732 return;
2733 }
Douglas Gregor3545ff42009-09-21 16:56:56 +00002734
John McCalle87beb22010-04-23 18:46:30 +00002735 ResultBuilder Results(*this);
Douglas Gregora6e2edc2010-01-14 03:27:13 +00002736 CodeCompletionDeclConsumer Consumer(Results, CurContext);
John McCalle87beb22010-04-23 18:46:30 +00002737
2738 // First pass: look for tags.
2739 Results.setFilter(Filter);
Douglas Gregor39982192010-08-15 06:18:01 +00002740 LookupVisibleDecls(S, LookupTagName, Consumer,
2741 CodeCompleter->includeGlobals());
John McCalle87beb22010-04-23 18:46:30 +00002742
Douglas Gregor39982192010-08-15 06:18:01 +00002743 if (CodeCompleter->includeGlobals()) {
2744 // Second pass: look for nested name specifiers.
2745 Results.setFilter(&ResultBuilder::IsNestedNameSpecifier);
2746 LookupVisibleDecls(S, LookupNestedNameSpecifierName, Consumer);
2747 }
Douglas Gregor3545ff42009-09-21 16:56:56 +00002748
Douglas Gregor00c37ef2010-08-11 21:23:17 +00002749 HandleCodeCompleteResults(this, CodeCompleter, ContextKind,
2750 Results.data(),Results.size());
Douglas Gregorf45b0cf2009-09-18 15:37:17 +00002751}
2752
Douglas Gregord328d572009-09-21 18:10:23 +00002753void Sema::CodeCompleteCase(Scope *S) {
2754 if (getSwitchStack().empty() || !CodeCompleter)
2755 return;
2756
2757 SwitchStmt *Switch = getSwitchStack().back();
Douglas Gregor85b50632010-07-28 21:50:18 +00002758 if (!Switch->getCond()->getType()->isEnumeralType()) {
Douglas Gregor68762e72010-08-23 21:17:50 +00002759 CodeCompleteExpressionData Data(Switch->getCond()->getType());
2760 Data.IntegralConstantExpression = true;
2761 CodeCompleteExpression(S, Data);
Douglas Gregord328d572009-09-21 18:10:23 +00002762 return;
Douglas Gregor85b50632010-07-28 21:50:18 +00002763 }
Douglas Gregord328d572009-09-21 18:10:23 +00002764
2765 // Code-complete the cases of a switch statement over an enumeration type
2766 // by providing the list of
2767 EnumDecl *Enum = Switch->getCond()->getType()->getAs<EnumType>()->getDecl();
2768
2769 // Determine which enumerators we have already seen in the switch statement.
2770 // FIXME: Ideally, we would also be able to look *past* the code-completion
2771 // token, in case we are code-completing in the middle of the switch and not
2772 // at the end. However, we aren't able to do so at the moment.
2773 llvm::SmallPtrSet<EnumConstantDecl *, 8> EnumeratorsSeen;
Douglas Gregorf2510672009-09-21 19:57:38 +00002774 NestedNameSpecifier *Qualifier = 0;
Douglas Gregord328d572009-09-21 18:10:23 +00002775 for (SwitchCase *SC = Switch->getSwitchCaseList(); SC;
2776 SC = SC->getNextSwitchCase()) {
2777 CaseStmt *Case = dyn_cast<CaseStmt>(SC);
2778 if (!Case)
2779 continue;
2780
2781 Expr *CaseVal = Case->getLHS()->IgnoreParenCasts();
2782 if (DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(CaseVal))
2783 if (EnumConstantDecl *Enumerator
2784 = dyn_cast<EnumConstantDecl>(DRE->getDecl())) {
2785 // We look into the AST of the case statement to determine which
2786 // enumerator was named. Alternatively, we could compute the value of
2787 // the integral constant expression, then compare it against the
2788 // values of each enumerator. However, value-based approach would not
2789 // work as well with C++ templates where enumerators declared within a
2790 // template are type- and value-dependent.
2791 EnumeratorsSeen.insert(Enumerator);
2792
Douglas Gregorf2510672009-09-21 19:57:38 +00002793 // If this is a qualified-id, keep track of the nested-name-specifier
2794 // so that we can reproduce it as part of code completion, e.g.,
Douglas Gregord328d572009-09-21 18:10:23 +00002795 //
2796 // switch (TagD.getKind()) {
2797 // case TagDecl::TK_enum:
2798 // break;
2799 // case XXX
2800 //
Douglas Gregorf2510672009-09-21 19:57:38 +00002801 // At the XXX, our completions are TagDecl::TK_union,
Douglas Gregord328d572009-09-21 18:10:23 +00002802 // TagDecl::TK_struct, and TagDecl::TK_class, rather than TK_union,
2803 // TK_struct, and TK_class.
Douglas Gregor4bd90e52009-10-23 18:54:35 +00002804 Qualifier = DRE->getQualifier();
Douglas Gregord328d572009-09-21 18:10:23 +00002805 }
2806 }
2807
Douglas Gregorf2510672009-09-21 19:57:38 +00002808 if (getLangOptions().CPlusPlus && !Qualifier && EnumeratorsSeen.empty()) {
2809 // If there are no prior enumerators in C++, check whether we have to
2810 // qualify the names of the enumerators that we suggest, because they
2811 // may not be visible in this scope.
2812 Qualifier = getRequiredQualification(Context, CurContext,
2813 Enum->getDeclContext());
2814
2815 // FIXME: Scoped enums need to start with "EnumDecl" as the context!
2816 }
2817
Douglas Gregord328d572009-09-21 18:10:23 +00002818 // Add any enumerators that have not yet been mentioned.
2819 ResultBuilder Results(*this);
2820 Results.EnterNewScope();
2821 for (EnumDecl::enumerator_iterator E = Enum->enumerator_begin(),
2822 EEnd = Enum->enumerator_end();
2823 E != EEnd; ++E) {
2824 if (EnumeratorsSeen.count(*E))
2825 continue;
2826
John McCall276321a2010-08-25 06:19:51 +00002827 Results.AddResult(CodeCompletionResult(*E, Qualifier),
Douglas Gregorfc59ce12010-01-14 16:14:35 +00002828 CurContext, 0, false);
Douglas Gregord328d572009-09-21 18:10:23 +00002829 }
2830 Results.ExitScope();
Douglas Gregor285560922010-04-06 20:02:15 +00002831
Douglas Gregor9eb77012009-11-07 00:00:49 +00002832 if (CodeCompleter->includeMacros())
Douglas Gregorf98e6a22010-01-13 23:51:12 +00002833 AddMacroResults(PP, Results);
Douglas Gregor00c37ef2010-08-11 21:23:17 +00002834 HandleCodeCompleteResults(this, CodeCompleter,
2835 CodeCompletionContext::CCC_Expression,
2836 Results.data(),Results.size());
Douglas Gregord328d572009-09-21 18:10:23 +00002837}
2838
Douglas Gregorcabea402009-09-22 15:41:20 +00002839namespace {
2840 struct IsBetterOverloadCandidate {
2841 Sema &S;
John McCallbc077cf2010-02-08 23:07:23 +00002842 SourceLocation Loc;
Douglas Gregorcabea402009-09-22 15:41:20 +00002843
2844 public:
John McCallbc077cf2010-02-08 23:07:23 +00002845 explicit IsBetterOverloadCandidate(Sema &S, SourceLocation Loc)
2846 : S(S), Loc(Loc) { }
Douglas Gregorcabea402009-09-22 15:41:20 +00002847
2848 bool
2849 operator()(const OverloadCandidate &X, const OverloadCandidate &Y) const {
John McCall5c32be02010-08-24 20:38:10 +00002850 return isBetterOverloadCandidate(S, X, Y, Loc);
Douglas Gregorcabea402009-09-22 15:41:20 +00002851 }
2852 };
2853}
2854
Douglas Gregor6ed3eb82010-05-30 06:10:08 +00002855static bool anyNullArguments(Expr **Args, unsigned NumArgs) {
2856 if (NumArgs && !Args)
2857 return true;
2858
2859 for (unsigned I = 0; I != NumArgs; ++I)
2860 if (!Args[I])
2861 return true;
2862
2863 return false;
2864}
2865
Douglas Gregorcabea402009-09-22 15:41:20 +00002866void Sema::CodeCompleteCall(Scope *S, ExprTy *FnIn,
2867 ExprTy **ArgsIn, unsigned NumArgs) {
2868 if (!CodeCompleter)
2869 return;
Douglas Gregor3ef59522009-12-11 19:06:04 +00002870
2871 // When we're code-completing for a call, we fall back to ordinary
2872 // name code-completion whenever we can't produce specific
2873 // results. We may want to revisit this strategy in the future,
2874 // e.g., by merging the two kinds of results.
2875
Douglas Gregorcabea402009-09-22 15:41:20 +00002876 Expr *Fn = (Expr *)FnIn;
2877 Expr **Args = (Expr **)ArgsIn;
Douglas Gregor3ef59522009-12-11 19:06:04 +00002878
Douglas Gregorcabea402009-09-22 15:41:20 +00002879 // Ignore type-dependent call expressions entirely.
Douglas Gregor6ed3eb82010-05-30 06:10:08 +00002880 if (!Fn || Fn->isTypeDependent() || anyNullArguments(Args, NumArgs) ||
Douglas Gregor3ef59522009-12-11 19:06:04 +00002881 Expr::hasAnyTypeDependentArguments(Args, NumArgs)) {
Douglas Gregor00c37ef2010-08-11 21:23:17 +00002882 CodeCompleteOrdinaryName(S, PCC_Expression);
Douglas Gregorcabea402009-09-22 15:41:20 +00002883 return;
Douglas Gregor3ef59522009-12-11 19:06:04 +00002884 }
Douglas Gregorcabea402009-09-22 15:41:20 +00002885
John McCall57500772009-12-16 12:17:52 +00002886 // Build an overload candidate set based on the functions we find.
John McCallbc077cf2010-02-08 23:07:23 +00002887 SourceLocation Loc = Fn->getExprLoc();
2888 OverloadCandidateSet CandidateSet(Loc);
John McCall57500772009-12-16 12:17:52 +00002889
Douglas Gregorcabea402009-09-22 15:41:20 +00002890 // FIXME: What if we're calling something that isn't a function declaration?
2891 // FIXME: What if we're calling a pseudo-destructor?
2892 // FIXME: What if we're calling a member function?
2893
Douglas Gregorff59f672010-01-21 15:46:19 +00002894 typedef CodeCompleteConsumer::OverloadCandidate ResultCandidate;
2895 llvm::SmallVector<ResultCandidate, 8> Results;
2896
John McCall57500772009-12-16 12:17:52 +00002897 Expr *NakedFn = Fn->IgnoreParenCasts();
2898 if (UnresolvedLookupExpr *ULE = dyn_cast<UnresolvedLookupExpr>(NakedFn))
2899 AddOverloadedCallCandidates(ULE, Args, NumArgs, CandidateSet,
2900 /*PartialOverloading=*/ true);
2901 else if (DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(NakedFn)) {
2902 FunctionDecl *FDecl = dyn_cast<FunctionDecl>(DRE->getDecl());
Douglas Gregorff59f672010-01-21 15:46:19 +00002903 if (FDecl) {
Douglas Gregor6ed3eb82010-05-30 06:10:08 +00002904 if (!getLangOptions().CPlusPlus ||
2905 !FDecl->getType()->getAs<FunctionProtoType>())
Douglas Gregorff59f672010-01-21 15:46:19 +00002906 Results.push_back(ResultCandidate(FDecl));
2907 else
John McCallb89836b2010-01-26 01:37:31 +00002908 // FIXME: access?
John McCalla0296f72010-03-19 07:35:19 +00002909 AddOverloadCandidate(FDecl, DeclAccessPair::make(FDecl, AS_none),
2910 Args, NumArgs, CandidateSet,
Douglas Gregorb05275a2010-04-16 17:41:49 +00002911 false, /*PartialOverloading*/true);
Douglas Gregorff59f672010-01-21 15:46:19 +00002912 }
John McCall57500772009-12-16 12:17:52 +00002913 }
Douglas Gregorcabea402009-09-22 15:41:20 +00002914
Douglas Gregor7aa6b222010-05-30 01:49:25 +00002915 QualType ParamType;
2916
Douglas Gregorff59f672010-01-21 15:46:19 +00002917 if (!CandidateSet.empty()) {
2918 // Sort the overload candidate set by placing the best overloads first.
2919 std::stable_sort(CandidateSet.begin(), CandidateSet.end(),
John McCallbc077cf2010-02-08 23:07:23 +00002920 IsBetterOverloadCandidate(*this, Loc));
Douglas Gregorcabea402009-09-22 15:41:20 +00002921
Douglas Gregorff59f672010-01-21 15:46:19 +00002922 // Add the remaining viable overload candidates as code-completion reslults.
2923 for (OverloadCandidateSet::iterator Cand = CandidateSet.begin(),
2924 CandEnd = CandidateSet.end();
2925 Cand != CandEnd; ++Cand) {
2926 if (Cand->Viable)
2927 Results.push_back(ResultCandidate(Cand->Function));
2928 }
Douglas Gregor7aa6b222010-05-30 01:49:25 +00002929
2930 // From the viable candidates, try to determine the type of this parameter.
2931 for (unsigned I = 0, N = Results.size(); I != N; ++I) {
2932 if (const FunctionType *FType = Results[I].getFunctionType())
2933 if (const FunctionProtoType *Proto = dyn_cast<FunctionProtoType>(FType))
2934 if (NumArgs < Proto->getNumArgs()) {
2935 if (ParamType.isNull())
2936 ParamType = Proto->getArgType(NumArgs);
2937 else if (!Context.hasSameUnqualifiedType(
2938 ParamType.getNonReferenceType(),
2939 Proto->getArgType(NumArgs).getNonReferenceType())) {
2940 ParamType = QualType();
2941 break;
2942 }
2943 }
2944 }
2945 } else {
2946 // Try to determine the parameter type from the type of the expression
2947 // being called.
2948 QualType FunctionType = Fn->getType();
2949 if (const PointerType *Ptr = FunctionType->getAs<PointerType>())
2950 FunctionType = Ptr->getPointeeType();
2951 else if (const BlockPointerType *BlockPtr
2952 = FunctionType->getAs<BlockPointerType>())
2953 FunctionType = BlockPtr->getPointeeType();
2954 else if (const MemberPointerType *MemPtr
2955 = FunctionType->getAs<MemberPointerType>())
2956 FunctionType = MemPtr->getPointeeType();
2957
2958 if (const FunctionProtoType *Proto
2959 = FunctionType->getAs<FunctionProtoType>()) {
2960 if (NumArgs < Proto->getNumArgs())
2961 ParamType = Proto->getArgType(NumArgs);
2962 }
Douglas Gregorcabea402009-09-22 15:41:20 +00002963 }
Douglas Gregor3ef59522009-12-11 19:06:04 +00002964
Douglas Gregor7aa6b222010-05-30 01:49:25 +00002965 if (ParamType.isNull())
Douglas Gregor00c37ef2010-08-11 21:23:17 +00002966 CodeCompleteOrdinaryName(S, PCC_Expression);
Douglas Gregor7aa6b222010-05-30 01:49:25 +00002967 else
2968 CodeCompleteExpression(S, ParamType);
2969
Douglas Gregorc01890e2010-04-06 20:19:47 +00002970 if (!Results.empty())
Douglas Gregor3ef59522009-12-11 19:06:04 +00002971 CodeCompleter->ProcessOverloadCandidates(*this, NumArgs, Results.data(),
2972 Results.size());
Douglas Gregorcabea402009-09-22 15:41:20 +00002973}
2974
John McCall48871652010-08-21 09:40:31 +00002975void Sema::CodeCompleteInitializer(Scope *S, Decl *D) {
2976 ValueDecl *VD = dyn_cast_or_null<ValueDecl>(D);
Douglas Gregor7aa6b222010-05-30 01:49:25 +00002977 if (!VD) {
Douglas Gregor00c37ef2010-08-11 21:23:17 +00002978 CodeCompleteOrdinaryName(S, PCC_Expression);
Douglas Gregor7aa6b222010-05-30 01:49:25 +00002979 return;
2980 }
2981
2982 CodeCompleteExpression(S, VD->getType());
2983}
2984
2985void Sema::CodeCompleteReturn(Scope *S) {
2986 QualType ResultType;
2987 if (isa<BlockDecl>(CurContext)) {
2988 if (BlockScopeInfo *BSI = getCurBlock())
2989 ResultType = BSI->ReturnType;
2990 } else if (FunctionDecl *Function = dyn_cast<FunctionDecl>(CurContext))
2991 ResultType = Function->getResultType();
2992 else if (ObjCMethodDecl *Method = dyn_cast<ObjCMethodDecl>(CurContext))
2993 ResultType = Method->getResultType();
2994
2995 if (ResultType.isNull())
Douglas Gregor00c37ef2010-08-11 21:23:17 +00002996 CodeCompleteOrdinaryName(S, PCC_Expression);
Douglas Gregor7aa6b222010-05-30 01:49:25 +00002997 else
2998 CodeCompleteExpression(S, ResultType);
2999}
3000
3001void Sema::CodeCompleteAssignmentRHS(Scope *S, ExprTy *LHS) {
3002 if (LHS)
3003 CodeCompleteExpression(S, static_cast<Expr *>(LHS)->getType());
3004 else
Douglas Gregor00c37ef2010-08-11 21:23:17 +00003005 CodeCompleteOrdinaryName(S, PCC_Expression);
Douglas Gregor7aa6b222010-05-30 01:49:25 +00003006}
3007
Jeffrey Yasskinc76498d2010-04-08 16:38:48 +00003008void Sema::CodeCompleteQualifiedId(Scope *S, CXXScopeSpec &SS,
Douglas Gregor2436e712009-09-17 21:32:03 +00003009 bool EnteringContext) {
3010 if (!SS.getScopeRep() || !CodeCompleter)
3011 return;
3012
Douglas Gregor3545ff42009-09-21 16:56:56 +00003013 DeclContext *Ctx = computeDeclContext(SS, EnteringContext);
3014 if (!Ctx)
3015 return;
Douglas Gregor800f2f02009-12-11 18:28:39 +00003016
3017 // Try to instantiate any non-dependent declaration contexts before
3018 // we look in them.
John McCall0b66eb32010-05-01 00:40:08 +00003019 if (!isDependentScopeSpecifier(SS) && RequireCompleteDeclContext(SS, Ctx))
Douglas Gregor800f2f02009-12-11 18:28:39 +00003020 return;
3021
Douglas Gregor3545ff42009-09-21 16:56:56 +00003022 ResultBuilder Results(*this);
Douglas Gregor200c99d2010-01-14 03:35:48 +00003023 CodeCompletionDeclConsumer Consumer(Results, CurContext);
3024 LookupVisibleDecls(Ctx, LookupOrdinaryName, Consumer);
Douglas Gregor3545ff42009-09-21 16:56:56 +00003025
3026 // The "template" keyword can follow "::" in the grammar, but only
3027 // put it into the grammar if the nested-name-specifier is dependent.
3028 NestedNameSpecifier *NNS = (NestedNameSpecifier *)SS.getScopeRep();
3029 if (!Results.empty() && NNS->isDependent())
Douglas Gregor78a21012010-01-14 16:01:26 +00003030 Results.AddResult("template");
Douglas Gregor3545ff42009-09-21 16:56:56 +00003031
Douglas Gregor00c37ef2010-08-11 21:23:17 +00003032 HandleCodeCompleteResults(this, CodeCompleter,
3033 CodeCompletionContext::CCC_Other,
3034 Results.data(),Results.size());
Douglas Gregor2436e712009-09-17 21:32:03 +00003035}
Douglas Gregor7e90c6d2009-09-18 19:03:04 +00003036
3037void Sema::CodeCompleteUsing(Scope *S) {
3038 if (!CodeCompleter)
3039 return;
3040
Douglas Gregor3545ff42009-09-21 16:56:56 +00003041 ResultBuilder Results(*this, &ResultBuilder::IsNestedNameSpecifier);
Douglas Gregor64b12b52009-09-22 23:31:26 +00003042 Results.EnterNewScope();
Douglas Gregor3545ff42009-09-21 16:56:56 +00003043
3044 // If we aren't in class scope, we could see the "namespace" keyword.
3045 if (!S->isClassScope())
John McCall276321a2010-08-25 06:19:51 +00003046 Results.AddResult(CodeCompletionResult("namespace"));
Douglas Gregor3545ff42009-09-21 16:56:56 +00003047
3048 // After "using", we can see anything that would start a
3049 // nested-name-specifier.
Douglas Gregora6e2edc2010-01-14 03:27:13 +00003050 CodeCompletionDeclConsumer Consumer(Results, CurContext);
Douglas Gregor39982192010-08-15 06:18:01 +00003051 LookupVisibleDecls(S, LookupOrdinaryName, Consumer,
3052 CodeCompleter->includeGlobals());
Douglas Gregor64b12b52009-09-22 23:31:26 +00003053 Results.ExitScope();
Douglas Gregor3545ff42009-09-21 16:56:56 +00003054
Douglas Gregor00c37ef2010-08-11 21:23:17 +00003055 HandleCodeCompleteResults(this, CodeCompleter,
3056 CodeCompletionContext::CCC_Other,
3057 Results.data(),Results.size());
Douglas Gregor7e90c6d2009-09-18 19:03:04 +00003058}
3059
3060void Sema::CodeCompleteUsingDirective(Scope *S) {
3061 if (!CodeCompleter)
3062 return;
3063
Douglas Gregor3545ff42009-09-21 16:56:56 +00003064 // After "using namespace", we expect to see a namespace name or namespace
3065 // alias.
3066 ResultBuilder Results(*this, &ResultBuilder::IsNamespaceOrAlias);
Douglas Gregor64b12b52009-09-22 23:31:26 +00003067 Results.EnterNewScope();
Douglas Gregora6e2edc2010-01-14 03:27:13 +00003068 CodeCompletionDeclConsumer Consumer(Results, CurContext);
Douglas Gregor39982192010-08-15 06:18:01 +00003069 LookupVisibleDecls(S, LookupOrdinaryName, Consumer,
3070 CodeCompleter->includeGlobals());
Douglas Gregor64b12b52009-09-22 23:31:26 +00003071 Results.ExitScope();
Douglas Gregor00c37ef2010-08-11 21:23:17 +00003072 HandleCodeCompleteResults(this, CodeCompleter,
Douglas Gregor39982192010-08-15 06:18:01 +00003073 CodeCompletionContext::CCC_Namespace,
Douglas Gregor00c37ef2010-08-11 21:23:17 +00003074 Results.data(),Results.size());
Douglas Gregor7e90c6d2009-09-18 19:03:04 +00003075}
3076
3077void Sema::CodeCompleteNamespaceDecl(Scope *S) {
3078 if (!CodeCompleter)
3079 return;
3080
Douglas Gregor3545ff42009-09-21 16:56:56 +00003081 ResultBuilder Results(*this, &ResultBuilder::IsNamespace);
3082 DeclContext *Ctx = (DeclContext *)S->getEntity();
3083 if (!S->getParent())
3084 Ctx = Context.getTranslationUnitDecl();
3085
3086 if (Ctx && Ctx->isFileContext()) {
3087 // We only want to see those namespaces that have already been defined
3088 // within this scope, because its likely that the user is creating an
3089 // extended namespace declaration. Keep track of the most recent
3090 // definition of each namespace.
3091 std::map<NamespaceDecl *, NamespaceDecl *> OrigToLatest;
3092 for (DeclContext::specific_decl_iterator<NamespaceDecl>
3093 NS(Ctx->decls_begin()), NSEnd(Ctx->decls_end());
3094 NS != NSEnd; ++NS)
3095 OrigToLatest[NS->getOriginalNamespace()] = *NS;
3096
3097 // Add the most recent definition (or extended definition) of each
3098 // namespace to the list of results.
Douglas Gregor64b12b52009-09-22 23:31:26 +00003099 Results.EnterNewScope();
Douglas Gregor3545ff42009-09-21 16:56:56 +00003100 for (std::map<NamespaceDecl *, NamespaceDecl *>::iterator
3101 NS = OrigToLatest.begin(), NSEnd = OrigToLatest.end();
3102 NS != NSEnd; ++NS)
John McCall276321a2010-08-25 06:19:51 +00003103 Results.AddResult(CodeCompletionResult(NS->second, 0),
Douglas Gregorfc59ce12010-01-14 16:14:35 +00003104 CurContext, 0, false);
Douglas Gregor64b12b52009-09-22 23:31:26 +00003105 Results.ExitScope();
Douglas Gregor3545ff42009-09-21 16:56:56 +00003106 }
3107
Douglas Gregor00c37ef2010-08-11 21:23:17 +00003108 HandleCodeCompleteResults(this, CodeCompleter,
3109 CodeCompletionContext::CCC_Other,
3110 Results.data(),Results.size());
Douglas Gregor7e90c6d2009-09-18 19:03:04 +00003111}
3112
3113void Sema::CodeCompleteNamespaceAliasDecl(Scope *S) {
3114 if (!CodeCompleter)
3115 return;
3116
Douglas Gregor3545ff42009-09-21 16:56:56 +00003117 // After "namespace", we expect to see a namespace or alias.
3118 ResultBuilder Results(*this, &ResultBuilder::IsNamespaceOrAlias);
Douglas Gregora6e2edc2010-01-14 03:27:13 +00003119 CodeCompletionDeclConsumer Consumer(Results, CurContext);
Douglas Gregor39982192010-08-15 06:18:01 +00003120 LookupVisibleDecls(S, LookupOrdinaryName, Consumer,
3121 CodeCompleter->includeGlobals());
Douglas Gregor00c37ef2010-08-11 21:23:17 +00003122 HandleCodeCompleteResults(this, CodeCompleter,
Douglas Gregor39982192010-08-15 06:18:01 +00003123 CodeCompletionContext::CCC_Namespace,
Douglas Gregor00c37ef2010-08-11 21:23:17 +00003124 Results.data(),Results.size());
Douglas Gregor7e90c6d2009-09-18 19:03:04 +00003125}
3126
Douglas Gregorc811ede2009-09-18 20:05:18 +00003127void Sema::CodeCompleteOperatorName(Scope *S) {
3128 if (!CodeCompleter)
3129 return;
Douglas Gregor3545ff42009-09-21 16:56:56 +00003130
John McCall276321a2010-08-25 06:19:51 +00003131 typedef CodeCompletionResult Result;
Douglas Gregor3545ff42009-09-21 16:56:56 +00003132 ResultBuilder Results(*this, &ResultBuilder::IsType);
Douglas Gregor64b12b52009-09-22 23:31:26 +00003133 Results.EnterNewScope();
Douglas Gregorc811ede2009-09-18 20:05:18 +00003134
Douglas Gregor3545ff42009-09-21 16:56:56 +00003135 // Add the names of overloadable operators.
3136#define OVERLOADED_OPERATOR(Name,Spelling,Token,Unary,Binary,MemberOnly) \
3137 if (std::strcmp(Spelling, "?")) \
Douglas Gregor78a21012010-01-14 16:01:26 +00003138 Results.AddResult(Result(Spelling));
Douglas Gregor3545ff42009-09-21 16:56:56 +00003139#include "clang/Basic/OperatorKinds.def"
3140
3141 // Add any type names visible from the current scope
Douglas Gregor6ae4c522010-01-14 03:21:49 +00003142 Results.allowNestedNameSpecifiers();
Douglas Gregora6e2edc2010-01-14 03:27:13 +00003143 CodeCompletionDeclConsumer Consumer(Results, CurContext);
Douglas Gregor39982192010-08-15 06:18:01 +00003144 LookupVisibleDecls(S, LookupOrdinaryName, Consumer,
3145 CodeCompleter->includeGlobals());
Douglas Gregor3545ff42009-09-21 16:56:56 +00003146
3147 // Add any type specifiers
Douglas Gregorf98e6a22010-01-13 23:51:12 +00003148 AddTypeSpecifierResults(getLangOptions(), Results);
Douglas Gregor64b12b52009-09-22 23:31:26 +00003149 Results.ExitScope();
Douglas Gregor3545ff42009-09-21 16:56:56 +00003150
Douglas Gregor00c37ef2010-08-11 21:23:17 +00003151 HandleCodeCompleteResults(this, CodeCompleter,
Douglas Gregor39982192010-08-15 06:18:01 +00003152 CodeCompletionContext::CCC_Type,
Douglas Gregor00c37ef2010-08-11 21:23:17 +00003153 Results.data(),Results.size());
Douglas Gregorc811ede2009-09-18 20:05:18 +00003154}
Douglas Gregor7e90c6d2009-09-18 19:03:04 +00003155
Douglas Gregorf1934162010-01-13 21:24:21 +00003156// Macro that expands to @Keyword or Keyword, depending on whether NeedAt is
3157// true or false.
3158#define OBJC_AT_KEYWORD_NAME(NeedAt,Keyword) NeedAt? "@" #Keyword : #Keyword
Douglas Gregorf98e6a22010-01-13 23:51:12 +00003159static void AddObjCImplementationResults(const LangOptions &LangOpts,
Douglas Gregorf1934162010-01-13 21:24:21 +00003160 ResultBuilder &Results,
3161 bool NeedAt) {
John McCall276321a2010-08-25 06:19:51 +00003162 typedef CodeCompletionResult Result;
Douglas Gregorf1934162010-01-13 21:24:21 +00003163 // Since we have an implementation, we can end it.
Douglas Gregor78a21012010-01-14 16:01:26 +00003164 Results.AddResult(Result(OBJC_AT_KEYWORD_NAME(NeedAt,end)));
Douglas Gregorf1934162010-01-13 21:24:21 +00003165
3166 CodeCompletionString *Pattern = 0;
3167 if (LangOpts.ObjC2) {
3168 // @dynamic
3169 Pattern = new CodeCompletionString;
3170 Pattern->AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt,dynamic));
3171 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
3172 Pattern->AddPlaceholderChunk("property");
Douglas Gregor78a21012010-01-14 16:01:26 +00003173 Results.AddResult(Result(Pattern));
Douglas Gregorf1934162010-01-13 21:24:21 +00003174
3175 // @synthesize
3176 Pattern = new CodeCompletionString;
3177 Pattern->AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt,synthesize));
3178 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
3179 Pattern->AddPlaceholderChunk("property");
Douglas Gregor78a21012010-01-14 16:01:26 +00003180 Results.AddResult(Result(Pattern));
Douglas Gregorf1934162010-01-13 21:24:21 +00003181 }
3182}
3183
Douglas Gregorf98e6a22010-01-13 23:51:12 +00003184static void AddObjCInterfaceResults(const LangOptions &LangOpts,
Douglas Gregorf1934162010-01-13 21:24:21 +00003185 ResultBuilder &Results,
3186 bool NeedAt) {
John McCall276321a2010-08-25 06:19:51 +00003187 typedef CodeCompletionResult Result;
Douglas Gregorf1934162010-01-13 21:24:21 +00003188
3189 // Since we have an interface or protocol, we can end it.
Douglas Gregor78a21012010-01-14 16:01:26 +00003190 Results.AddResult(Result(OBJC_AT_KEYWORD_NAME(NeedAt,end)));
Douglas Gregorf1934162010-01-13 21:24:21 +00003191
3192 if (LangOpts.ObjC2) {
3193 // @property
Douglas Gregor78a21012010-01-14 16:01:26 +00003194 Results.AddResult(Result(OBJC_AT_KEYWORD_NAME(NeedAt,property)));
Douglas Gregorf1934162010-01-13 21:24:21 +00003195
3196 // @required
Douglas Gregor78a21012010-01-14 16:01:26 +00003197 Results.AddResult(Result(OBJC_AT_KEYWORD_NAME(NeedAt,required)));
Douglas Gregorf1934162010-01-13 21:24:21 +00003198
3199 // @optional
Douglas Gregor78a21012010-01-14 16:01:26 +00003200 Results.AddResult(Result(OBJC_AT_KEYWORD_NAME(NeedAt,optional)));
Douglas Gregorf1934162010-01-13 21:24:21 +00003201 }
3202}
3203
Douglas Gregorf98e6a22010-01-13 23:51:12 +00003204static void AddObjCTopLevelResults(ResultBuilder &Results, bool NeedAt) {
John McCall276321a2010-08-25 06:19:51 +00003205 typedef CodeCompletionResult Result;
Douglas Gregorf1934162010-01-13 21:24:21 +00003206 CodeCompletionString *Pattern = 0;
3207
3208 // @class name ;
3209 Pattern = new CodeCompletionString;
3210 Pattern->AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt,class));
3211 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
Douglas Gregorf4c33342010-05-28 00:22:41 +00003212 Pattern->AddPlaceholderChunk("name");
Douglas Gregor78a21012010-01-14 16:01:26 +00003213 Results.AddResult(Result(Pattern));
Douglas Gregorf1934162010-01-13 21:24:21 +00003214
Douglas Gregorf4c33342010-05-28 00:22:41 +00003215 if (Results.includeCodePatterns()) {
3216 // @interface name
3217 // FIXME: Could introduce the whole pattern, including superclasses and
3218 // such.
3219 Pattern = new CodeCompletionString;
3220 Pattern->AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt,interface));
3221 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
3222 Pattern->AddPlaceholderChunk("class");
3223 Results.AddResult(Result(Pattern));
Douglas Gregorf1934162010-01-13 21:24:21 +00003224
Douglas Gregorf4c33342010-05-28 00:22:41 +00003225 // @protocol name
3226 Pattern = new CodeCompletionString;
3227 Pattern->AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt,protocol));
3228 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
3229 Pattern->AddPlaceholderChunk("protocol");
3230 Results.AddResult(Result(Pattern));
3231
3232 // @implementation name
3233 Pattern = new CodeCompletionString;
3234 Pattern->AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt,implementation));
3235 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
3236 Pattern->AddPlaceholderChunk("class");
3237 Results.AddResult(Result(Pattern));
3238 }
Douglas Gregorf1934162010-01-13 21:24:21 +00003239
3240 // @compatibility_alias name
3241 Pattern = new CodeCompletionString;
3242 Pattern->AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt,compatibility_alias));
3243 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
3244 Pattern->AddPlaceholderChunk("alias");
3245 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
3246 Pattern->AddPlaceholderChunk("class");
Douglas Gregor78a21012010-01-14 16:01:26 +00003247 Results.AddResult(Result(Pattern));
Douglas Gregorf1934162010-01-13 21:24:21 +00003248}
3249
John McCall48871652010-08-21 09:40:31 +00003250void Sema::CodeCompleteObjCAtDirective(Scope *S, Decl *ObjCImpDecl,
Douglas Gregorf48706c2009-12-07 09:27:33 +00003251 bool InInterface) {
John McCall276321a2010-08-25 06:19:51 +00003252 typedef CodeCompletionResult Result;
Douglas Gregorf48706c2009-12-07 09:27:33 +00003253 ResultBuilder Results(*this);
3254 Results.EnterNewScope();
Douglas Gregorf1934162010-01-13 21:24:21 +00003255 if (ObjCImpDecl)
Douglas Gregorf98e6a22010-01-13 23:51:12 +00003256 AddObjCImplementationResults(getLangOptions(), Results, false);
Douglas Gregorf1934162010-01-13 21:24:21 +00003257 else if (InInterface)
Douglas Gregorf98e6a22010-01-13 23:51:12 +00003258 AddObjCInterfaceResults(getLangOptions(), Results, false);
Douglas Gregorf1934162010-01-13 21:24:21 +00003259 else
Douglas Gregorf98e6a22010-01-13 23:51:12 +00003260 AddObjCTopLevelResults(Results, false);
Douglas Gregorf48706c2009-12-07 09:27:33 +00003261 Results.ExitScope();
Douglas Gregor00c37ef2010-08-11 21:23:17 +00003262 HandleCodeCompleteResults(this, CodeCompleter,
3263 CodeCompletionContext::CCC_Other,
3264 Results.data(),Results.size());
Douglas Gregorf48706c2009-12-07 09:27:33 +00003265}
3266
Douglas Gregorf98e6a22010-01-13 23:51:12 +00003267static void AddObjCExpressionResults(ResultBuilder &Results, bool NeedAt) {
John McCall276321a2010-08-25 06:19:51 +00003268 typedef CodeCompletionResult Result;
Douglas Gregorbc7c5e42009-12-07 09:51:25 +00003269 CodeCompletionString *Pattern = 0;
3270
3271 // @encode ( type-name )
3272 Pattern = new CodeCompletionString;
Douglas Gregorf1934162010-01-13 21:24:21 +00003273 Pattern->AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt,encode));
Douglas Gregorbc7c5e42009-12-07 09:51:25 +00003274 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
3275 Pattern->AddPlaceholderChunk("type-name");
3276 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
Douglas Gregor78a21012010-01-14 16:01:26 +00003277 Results.AddResult(Result(Pattern));
Douglas Gregorbc7c5e42009-12-07 09:51:25 +00003278
3279 // @protocol ( protocol-name )
3280 Pattern = new CodeCompletionString;
Douglas Gregorf1934162010-01-13 21:24:21 +00003281 Pattern->AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt,protocol));
Douglas Gregorbc7c5e42009-12-07 09:51:25 +00003282 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
3283 Pattern->AddPlaceholderChunk("protocol-name");
3284 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
Douglas Gregor78a21012010-01-14 16:01:26 +00003285 Results.AddResult(Result(Pattern));
Douglas Gregorbc7c5e42009-12-07 09:51:25 +00003286
3287 // @selector ( selector )
3288 Pattern = new CodeCompletionString;
Douglas Gregorf1934162010-01-13 21:24:21 +00003289 Pattern->AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt,selector));
Douglas Gregorbc7c5e42009-12-07 09:51:25 +00003290 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
3291 Pattern->AddPlaceholderChunk("selector");
3292 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
Douglas Gregor78a21012010-01-14 16:01:26 +00003293 Results.AddResult(Result(Pattern));
Douglas Gregorbc7c5e42009-12-07 09:51:25 +00003294}
3295
Douglas Gregorf98e6a22010-01-13 23:51:12 +00003296static void AddObjCStatementResults(ResultBuilder &Results, bool NeedAt) {
John McCall276321a2010-08-25 06:19:51 +00003297 typedef CodeCompletionResult Result;
Douglas Gregorbc7c5e42009-12-07 09:51:25 +00003298 CodeCompletionString *Pattern = 0;
Douglas Gregorf1934162010-01-13 21:24:21 +00003299
Douglas Gregorf4c33342010-05-28 00:22:41 +00003300 if (Results.includeCodePatterns()) {
3301 // @try { statements } @catch ( declaration ) { statements } @finally
3302 // { statements }
3303 Pattern = new CodeCompletionString;
3304 Pattern->AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt,try));
3305 Pattern->AddChunk(CodeCompletionString::CK_LeftBrace);
3306 Pattern->AddPlaceholderChunk("statements");
3307 Pattern->AddChunk(CodeCompletionString::CK_RightBrace);
3308 Pattern->AddTextChunk("@catch");
3309 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
3310 Pattern->AddPlaceholderChunk("parameter");
3311 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
3312 Pattern->AddChunk(CodeCompletionString::CK_LeftBrace);
3313 Pattern->AddPlaceholderChunk("statements");
3314 Pattern->AddChunk(CodeCompletionString::CK_RightBrace);
3315 Pattern->AddTextChunk("@finally");
3316 Pattern->AddChunk(CodeCompletionString::CK_LeftBrace);
3317 Pattern->AddPlaceholderChunk("statements");
3318 Pattern->AddChunk(CodeCompletionString::CK_RightBrace);
3319 Results.AddResult(Result(Pattern));
3320 }
Douglas Gregorf1934162010-01-13 21:24:21 +00003321
Douglas Gregorbc7c5e42009-12-07 09:51:25 +00003322 // @throw
3323 Pattern = new CodeCompletionString;
Douglas Gregorf1934162010-01-13 21:24:21 +00003324 Pattern->AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt,throw));
Douglas Gregor6a803932010-01-12 06:38:28 +00003325 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
Douglas Gregorbc7c5e42009-12-07 09:51:25 +00003326 Pattern->AddPlaceholderChunk("expression");
Douglas Gregor78a21012010-01-14 16:01:26 +00003327 Results.AddResult(Result(Pattern));
Douglas Gregorf1934162010-01-13 21:24:21 +00003328
Douglas Gregorf4c33342010-05-28 00:22:41 +00003329 if (Results.includeCodePatterns()) {
3330 // @synchronized ( expression ) { statements }
3331 Pattern = new CodeCompletionString;
3332 Pattern->AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt,synchronized));
3333 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
3334 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
3335 Pattern->AddPlaceholderChunk("expression");
3336 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
3337 Pattern->AddChunk(CodeCompletionString::CK_LeftBrace);
3338 Pattern->AddPlaceholderChunk("statements");
3339 Pattern->AddChunk(CodeCompletionString::CK_RightBrace);
3340 Results.AddResult(Result(Pattern));
3341 }
Douglas Gregorf1934162010-01-13 21:24:21 +00003342}
Douglas Gregorbc7c5e42009-12-07 09:51:25 +00003343
Douglas Gregorf98e6a22010-01-13 23:51:12 +00003344static void AddObjCVisibilityResults(const LangOptions &LangOpts,
Douglas Gregor48d46252010-01-13 21:54:15 +00003345 ResultBuilder &Results,
3346 bool NeedAt) {
John McCall276321a2010-08-25 06:19:51 +00003347 typedef CodeCompletionResult Result;
Douglas Gregor78a21012010-01-14 16:01:26 +00003348 Results.AddResult(Result(OBJC_AT_KEYWORD_NAME(NeedAt,private)));
3349 Results.AddResult(Result(OBJC_AT_KEYWORD_NAME(NeedAt,protected)));
3350 Results.AddResult(Result(OBJC_AT_KEYWORD_NAME(NeedAt,public)));
Douglas Gregor48d46252010-01-13 21:54:15 +00003351 if (LangOpts.ObjC2)
Douglas Gregor78a21012010-01-14 16:01:26 +00003352 Results.AddResult(Result(OBJC_AT_KEYWORD_NAME(NeedAt,package)));
Douglas Gregor48d46252010-01-13 21:54:15 +00003353}
3354
3355void Sema::CodeCompleteObjCAtVisibility(Scope *S) {
3356 ResultBuilder Results(*this);
3357 Results.EnterNewScope();
Douglas Gregorf98e6a22010-01-13 23:51:12 +00003358 AddObjCVisibilityResults(getLangOptions(), Results, false);
Douglas Gregor48d46252010-01-13 21:54:15 +00003359 Results.ExitScope();
Douglas Gregor00c37ef2010-08-11 21:23:17 +00003360 HandleCodeCompleteResults(this, CodeCompleter,
3361 CodeCompletionContext::CCC_Other,
3362 Results.data(),Results.size());
Douglas Gregor48d46252010-01-13 21:54:15 +00003363}
3364
3365void Sema::CodeCompleteObjCAtStatement(Scope *S) {
Douglas Gregorf1934162010-01-13 21:24:21 +00003366 ResultBuilder Results(*this);
3367 Results.EnterNewScope();
Douglas Gregorf98e6a22010-01-13 23:51:12 +00003368 AddObjCStatementResults(Results, false);
3369 AddObjCExpressionResults(Results, false);
Douglas Gregorbc7c5e42009-12-07 09:51:25 +00003370 Results.ExitScope();
Douglas Gregor00c37ef2010-08-11 21:23:17 +00003371 HandleCodeCompleteResults(this, CodeCompleter,
3372 CodeCompletionContext::CCC_Other,
3373 Results.data(),Results.size());
Douglas Gregorbc7c5e42009-12-07 09:51:25 +00003374}
3375
3376void Sema::CodeCompleteObjCAtExpression(Scope *S) {
3377 ResultBuilder Results(*this);
3378 Results.EnterNewScope();
Douglas Gregorf98e6a22010-01-13 23:51:12 +00003379 AddObjCExpressionResults(Results, false);
Douglas Gregorbc7c5e42009-12-07 09:51:25 +00003380 Results.ExitScope();
Douglas Gregor00c37ef2010-08-11 21:23:17 +00003381 HandleCodeCompleteResults(this, CodeCompleter,
3382 CodeCompletionContext::CCC_Other,
3383 Results.data(),Results.size());
Douglas Gregorbc7c5e42009-12-07 09:51:25 +00003384}
3385
Douglas Gregore6078da2009-11-19 00:14:45 +00003386/// \brief Determine whether the addition of the given flag to an Objective-C
3387/// property's attributes will cause a conflict.
3388static bool ObjCPropertyFlagConflicts(unsigned Attributes, unsigned NewFlag) {
3389 // Check if we've already added this flag.
3390 if (Attributes & NewFlag)
3391 return true;
3392
3393 Attributes |= NewFlag;
3394
3395 // Check for collisions with "readonly".
3396 if ((Attributes & ObjCDeclSpec::DQ_PR_readonly) &&
3397 (Attributes & (ObjCDeclSpec::DQ_PR_readwrite |
3398 ObjCDeclSpec::DQ_PR_assign |
3399 ObjCDeclSpec::DQ_PR_copy |
3400 ObjCDeclSpec::DQ_PR_retain)))
3401 return true;
3402
3403 // Check for more than one of { assign, copy, retain }.
3404 unsigned AssignCopyRetMask = Attributes & (ObjCDeclSpec::DQ_PR_assign |
3405 ObjCDeclSpec::DQ_PR_copy |
3406 ObjCDeclSpec::DQ_PR_retain);
3407 if (AssignCopyRetMask &&
3408 AssignCopyRetMask != ObjCDeclSpec::DQ_PR_assign &&
3409 AssignCopyRetMask != ObjCDeclSpec::DQ_PR_copy &&
3410 AssignCopyRetMask != ObjCDeclSpec::DQ_PR_retain)
3411 return true;
3412
3413 return false;
3414}
3415
Douglas Gregor36029f42009-11-18 23:08:07 +00003416void Sema::CodeCompleteObjCPropertyFlags(Scope *S, ObjCDeclSpec &ODS) {
Steve Naroff936354c2009-10-08 21:55:05 +00003417 if (!CodeCompleter)
3418 return;
Douglas Gregor1b605f72009-11-19 01:08:35 +00003419
Steve Naroff936354c2009-10-08 21:55:05 +00003420 unsigned Attributes = ODS.getPropertyAttributes();
3421
John McCall276321a2010-08-25 06:19:51 +00003422 typedef CodeCompletionResult Result;
Steve Naroff936354c2009-10-08 21:55:05 +00003423 ResultBuilder Results(*this);
3424 Results.EnterNewScope();
Douglas Gregore6078da2009-11-19 00:14:45 +00003425 if (!ObjCPropertyFlagConflicts(Attributes, ObjCDeclSpec::DQ_PR_readonly))
John McCall276321a2010-08-25 06:19:51 +00003426 Results.AddResult(CodeCompletionResult("readonly"));
Douglas Gregore6078da2009-11-19 00:14:45 +00003427 if (!ObjCPropertyFlagConflicts(Attributes, ObjCDeclSpec::DQ_PR_assign))
John McCall276321a2010-08-25 06:19:51 +00003428 Results.AddResult(CodeCompletionResult("assign"));
Douglas Gregore6078da2009-11-19 00:14:45 +00003429 if (!ObjCPropertyFlagConflicts(Attributes, ObjCDeclSpec::DQ_PR_readwrite))
John McCall276321a2010-08-25 06:19:51 +00003430 Results.AddResult(CodeCompletionResult("readwrite"));
Douglas Gregore6078da2009-11-19 00:14:45 +00003431 if (!ObjCPropertyFlagConflicts(Attributes, ObjCDeclSpec::DQ_PR_retain))
John McCall276321a2010-08-25 06:19:51 +00003432 Results.AddResult(CodeCompletionResult("retain"));
Douglas Gregore6078da2009-11-19 00:14:45 +00003433 if (!ObjCPropertyFlagConflicts(Attributes, ObjCDeclSpec::DQ_PR_copy))
John McCall276321a2010-08-25 06:19:51 +00003434 Results.AddResult(CodeCompletionResult("copy"));
Douglas Gregore6078da2009-11-19 00:14:45 +00003435 if (!ObjCPropertyFlagConflicts(Attributes, ObjCDeclSpec::DQ_PR_nonatomic))
John McCall276321a2010-08-25 06:19:51 +00003436 Results.AddResult(CodeCompletionResult("nonatomic"));
Douglas Gregore6078da2009-11-19 00:14:45 +00003437 if (!ObjCPropertyFlagConflicts(Attributes, ObjCDeclSpec::DQ_PR_setter)) {
Douglas Gregor45f83ee2009-11-19 00:01:57 +00003438 CodeCompletionString *Setter = new CodeCompletionString;
3439 Setter->AddTypedTextChunk("setter");
3440 Setter->AddTextChunk(" = ");
3441 Setter->AddPlaceholderChunk("method");
John McCall276321a2010-08-25 06:19:51 +00003442 Results.AddResult(CodeCompletionResult(Setter));
Douglas Gregor45f83ee2009-11-19 00:01:57 +00003443 }
Douglas Gregore6078da2009-11-19 00:14:45 +00003444 if (!ObjCPropertyFlagConflicts(Attributes, ObjCDeclSpec::DQ_PR_getter)) {
Douglas Gregor45f83ee2009-11-19 00:01:57 +00003445 CodeCompletionString *Getter = new CodeCompletionString;
3446 Getter->AddTypedTextChunk("getter");
3447 Getter->AddTextChunk(" = ");
3448 Getter->AddPlaceholderChunk("method");
John McCall276321a2010-08-25 06:19:51 +00003449 Results.AddResult(CodeCompletionResult(Getter));
Douglas Gregor45f83ee2009-11-19 00:01:57 +00003450 }
Steve Naroff936354c2009-10-08 21:55:05 +00003451 Results.ExitScope();
Douglas Gregor00c37ef2010-08-11 21:23:17 +00003452 HandleCodeCompleteResults(this, CodeCompleter,
3453 CodeCompletionContext::CCC_Other,
3454 Results.data(),Results.size());
Steve Naroff936354c2009-10-08 21:55:05 +00003455}
Steve Naroffeae65032009-11-07 02:08:14 +00003456
Douglas Gregorc8537c52009-11-19 07:41:15 +00003457/// \brief Descripts the kind of Objective-C method that we want to find
3458/// via code completion.
3459enum ObjCMethodKind {
3460 MK_Any, //< Any kind of method, provided it means other specified criteria.
3461 MK_ZeroArgSelector, //< Zero-argument (unary) selector.
3462 MK_OneArgSelector //< One-argument selector.
3463};
3464
3465static bool isAcceptableObjCMethod(ObjCMethodDecl *Method,
3466 ObjCMethodKind WantKind,
3467 IdentifierInfo **SelIdents,
3468 unsigned NumSelIdents) {
3469 Selector Sel = Method->getSelector();
3470 if (NumSelIdents > Sel.getNumArgs())
3471 return false;
3472
3473 switch (WantKind) {
3474 case MK_Any: break;
3475 case MK_ZeroArgSelector: return Sel.isUnarySelector();
3476 case MK_OneArgSelector: return Sel.getNumArgs() == 1;
3477 }
3478
3479 for (unsigned I = 0; I != NumSelIdents; ++I)
3480 if (SelIdents[I] != Sel.getIdentifierInfoForSlot(I))
3481 return false;
3482
3483 return true;
3484}
3485
Douglas Gregorbab2b3c2009-11-17 23:22:23 +00003486/// \brief Add all of the Objective-C methods in the given Objective-C
3487/// container to the set of results.
3488///
3489/// The container will be a class, protocol, category, or implementation of
3490/// any of the above. This mether will recurse to include methods from
3491/// the superclasses of classes along with their categories, protocols, and
3492/// implementations.
3493///
3494/// \param Container the container in which we'll look to find methods.
3495///
3496/// \param WantInstance whether to add instance methods (only); if false, this
3497/// routine will add factory methods (only).
3498///
3499/// \param CurContext the context in which we're performing the lookup that
3500/// finds methods.
3501///
3502/// \param Results the structure into which we'll add results.
3503static void AddObjCMethods(ObjCContainerDecl *Container,
3504 bool WantInstanceMethods,
Douglas Gregorc8537c52009-11-19 07:41:15 +00003505 ObjCMethodKind WantKind,
Douglas Gregor1b605f72009-11-19 01:08:35 +00003506 IdentifierInfo **SelIdents,
3507 unsigned NumSelIdents,
Douglas Gregorbab2b3c2009-11-17 23:22:23 +00003508 DeclContext *CurContext,
Douglas Gregor416b5752010-08-25 01:08:01 +00003509 ResultBuilder &Results,
3510 bool InOriginalClass = true) {
John McCall276321a2010-08-25 06:19:51 +00003511 typedef CodeCompletionResult Result;
Douglas Gregorbab2b3c2009-11-17 23:22:23 +00003512 for (ObjCContainerDecl::method_iterator M = Container->meth_begin(),
3513 MEnd = Container->meth_end();
3514 M != MEnd; ++M) {
Douglas Gregor1b605f72009-11-19 01:08:35 +00003515 if ((*M)->isInstanceMethod() == WantInstanceMethods) {
3516 // Check whether the selector identifiers we've been given are a
3517 // subset of the identifiers for this particular method.
Douglas Gregorc8537c52009-11-19 07:41:15 +00003518 if (!isAcceptableObjCMethod(*M, WantKind, SelIdents, NumSelIdents))
Douglas Gregor1b605f72009-11-19 01:08:35 +00003519 continue;
Douglas Gregorc8537c52009-11-19 07:41:15 +00003520
Douglas Gregor1b605f72009-11-19 01:08:35 +00003521 Result R = Result(*M, 0);
3522 R.StartParameter = NumSelIdents;
Douglas Gregorc8537c52009-11-19 07:41:15 +00003523 R.AllParametersAreInformative = (WantKind != MK_Any);
Douglas Gregor416b5752010-08-25 01:08:01 +00003524 if (!InOriginalClass)
3525 R.Priority += CCD_InBaseClass;
Douglas Gregor1b605f72009-11-19 01:08:35 +00003526 Results.MaybeAddResult(R, CurContext);
3527 }
Douglas Gregorbab2b3c2009-11-17 23:22:23 +00003528 }
3529
3530 ObjCInterfaceDecl *IFace = dyn_cast<ObjCInterfaceDecl>(Container);
3531 if (!IFace)
3532 return;
3533
3534 // Add methods in protocols.
3535 const ObjCList<ObjCProtocolDecl> &Protocols= IFace->getReferencedProtocols();
3536 for (ObjCList<ObjCProtocolDecl>::iterator I = Protocols.begin(),
3537 E = Protocols.end();
3538 I != E; ++I)
Douglas Gregorc8537c52009-11-19 07:41:15 +00003539 AddObjCMethods(*I, WantInstanceMethods, WantKind, SelIdents, NumSelIdents,
Douglas Gregor416b5752010-08-25 01:08:01 +00003540 CurContext, Results, false);
Douglas Gregorbab2b3c2009-11-17 23:22:23 +00003541
3542 // Add methods in categories.
3543 for (ObjCCategoryDecl *CatDecl = IFace->getCategoryList(); CatDecl;
3544 CatDecl = CatDecl->getNextClassCategory()) {
Douglas Gregorc8537c52009-11-19 07:41:15 +00003545 AddObjCMethods(CatDecl, WantInstanceMethods, WantKind, SelIdents,
Douglas Gregor416b5752010-08-25 01:08:01 +00003546 NumSelIdents, CurContext, Results, InOriginalClass);
Douglas Gregorbab2b3c2009-11-17 23:22:23 +00003547
3548 // Add a categories protocol methods.
3549 const ObjCList<ObjCProtocolDecl> &Protocols
3550 = CatDecl->getReferencedProtocols();
3551 for (ObjCList<ObjCProtocolDecl>::iterator I = Protocols.begin(),
3552 E = Protocols.end();
3553 I != E; ++I)
Douglas Gregorc8537c52009-11-19 07:41:15 +00003554 AddObjCMethods(*I, WantInstanceMethods, WantKind, SelIdents,
Douglas Gregor416b5752010-08-25 01:08:01 +00003555 NumSelIdents, CurContext, Results, false);
Douglas Gregorbab2b3c2009-11-17 23:22:23 +00003556
3557 // Add methods in category implementations.
3558 if (ObjCCategoryImplDecl *Impl = CatDecl->getImplementation())
Douglas Gregorc8537c52009-11-19 07:41:15 +00003559 AddObjCMethods(Impl, WantInstanceMethods, WantKind, SelIdents,
Douglas Gregor416b5752010-08-25 01:08:01 +00003560 NumSelIdents, CurContext, Results, InOriginalClass);
Douglas Gregorbab2b3c2009-11-17 23:22:23 +00003561 }
3562
3563 // Add methods in superclass.
3564 if (IFace->getSuperClass())
Douglas Gregorc8537c52009-11-19 07:41:15 +00003565 AddObjCMethods(IFace->getSuperClass(), WantInstanceMethods, WantKind,
Douglas Gregor416b5752010-08-25 01:08:01 +00003566 SelIdents, NumSelIdents, CurContext, Results, false);
Douglas Gregorbab2b3c2009-11-17 23:22:23 +00003567
3568 // Add methods in our implementation, if any.
3569 if (ObjCImplementationDecl *Impl = IFace->getImplementation())
Douglas Gregorc8537c52009-11-19 07:41:15 +00003570 AddObjCMethods(Impl, WantInstanceMethods, WantKind, SelIdents,
Douglas Gregor416b5752010-08-25 01:08:01 +00003571 NumSelIdents, CurContext, Results, InOriginalClass);
Douglas Gregorc8537c52009-11-19 07:41:15 +00003572}
3573
3574
John McCall48871652010-08-21 09:40:31 +00003575void Sema::CodeCompleteObjCPropertyGetter(Scope *S, Decl *ClassDecl,
3576 Decl **Methods,
Douglas Gregorc8537c52009-11-19 07:41:15 +00003577 unsigned NumMethods) {
John McCall276321a2010-08-25 06:19:51 +00003578 typedef CodeCompletionResult Result;
Douglas Gregorc8537c52009-11-19 07:41:15 +00003579
3580 // Try to find the interface where getters might live.
John McCall48871652010-08-21 09:40:31 +00003581 ObjCInterfaceDecl *Class = dyn_cast_or_null<ObjCInterfaceDecl>(ClassDecl);
Douglas Gregorc8537c52009-11-19 07:41:15 +00003582 if (!Class) {
3583 if (ObjCCategoryDecl *Category
John McCall48871652010-08-21 09:40:31 +00003584 = dyn_cast_or_null<ObjCCategoryDecl>(ClassDecl))
Douglas Gregorc8537c52009-11-19 07:41:15 +00003585 Class = Category->getClassInterface();
3586
3587 if (!Class)
3588 return;
3589 }
3590
3591 // Find all of the potential getters.
3592 ResultBuilder Results(*this);
3593 Results.EnterNewScope();
3594
3595 // FIXME: We need to do this because Objective-C methods don't get
3596 // pushed into DeclContexts early enough. Argh!
3597 for (unsigned I = 0; I != NumMethods; ++I) {
3598 if (ObjCMethodDecl *Method
John McCall48871652010-08-21 09:40:31 +00003599 = dyn_cast_or_null<ObjCMethodDecl>(Methods[I]))
Douglas Gregorc8537c52009-11-19 07:41:15 +00003600 if (Method->isInstanceMethod() &&
3601 isAcceptableObjCMethod(Method, MK_ZeroArgSelector, 0, 0)) {
3602 Result R = Result(Method, 0);
3603 R.AllParametersAreInformative = true;
3604 Results.MaybeAddResult(R, CurContext);
3605 }
3606 }
3607
3608 AddObjCMethods(Class, true, MK_ZeroArgSelector, 0, 0, CurContext, Results);
3609 Results.ExitScope();
Douglas Gregor00c37ef2010-08-11 21:23:17 +00003610 HandleCodeCompleteResults(this, CodeCompleter,
3611 CodeCompletionContext::CCC_Other,
3612 Results.data(),Results.size());
Douglas Gregorc8537c52009-11-19 07:41:15 +00003613}
3614
John McCall48871652010-08-21 09:40:31 +00003615void Sema::CodeCompleteObjCPropertySetter(Scope *S, Decl *ObjCImplDecl,
3616 Decl **Methods,
Douglas Gregorc8537c52009-11-19 07:41:15 +00003617 unsigned NumMethods) {
John McCall276321a2010-08-25 06:19:51 +00003618 typedef CodeCompletionResult Result;
Douglas Gregorc8537c52009-11-19 07:41:15 +00003619
3620 // Try to find the interface where setters might live.
3621 ObjCInterfaceDecl *Class
John McCall48871652010-08-21 09:40:31 +00003622 = dyn_cast_or_null<ObjCInterfaceDecl>(ObjCImplDecl);
Douglas Gregorc8537c52009-11-19 07:41:15 +00003623 if (!Class) {
3624 if (ObjCCategoryDecl *Category
John McCall48871652010-08-21 09:40:31 +00003625 = dyn_cast_or_null<ObjCCategoryDecl>(ObjCImplDecl))
Douglas Gregorc8537c52009-11-19 07:41:15 +00003626 Class = Category->getClassInterface();
3627
3628 if (!Class)
3629 return;
3630 }
3631
3632 // Find all of the potential getters.
3633 ResultBuilder Results(*this);
3634 Results.EnterNewScope();
3635
3636 // FIXME: We need to do this because Objective-C methods don't get
3637 // pushed into DeclContexts early enough. Argh!
3638 for (unsigned I = 0; I != NumMethods; ++I) {
3639 if (ObjCMethodDecl *Method
John McCall48871652010-08-21 09:40:31 +00003640 = dyn_cast_or_null<ObjCMethodDecl>(Methods[I]))
Douglas Gregorc8537c52009-11-19 07:41:15 +00003641 if (Method->isInstanceMethod() &&
3642 isAcceptableObjCMethod(Method, MK_OneArgSelector, 0, 0)) {
3643 Result R = Result(Method, 0);
3644 R.AllParametersAreInformative = true;
3645 Results.MaybeAddResult(R, CurContext);
3646 }
3647 }
3648
3649 AddObjCMethods(Class, true, MK_OneArgSelector, 0, 0, CurContext, Results);
3650
3651 Results.ExitScope();
Douglas Gregor00c37ef2010-08-11 21:23:17 +00003652 HandleCodeCompleteResults(this, CodeCompleter,
3653 CodeCompletionContext::CCC_Other,
3654 Results.data(),Results.size());
Douglas Gregorbab2b3c2009-11-17 23:22:23 +00003655}
3656
Douglas Gregor99fa2642010-08-24 01:06:58 +00003657void Sema::CodeCompleteObjCPassingType(Scope *S, ObjCDeclSpec &DS) {
John McCall276321a2010-08-25 06:19:51 +00003658 typedef CodeCompletionResult Result;
Douglas Gregor99fa2642010-08-24 01:06:58 +00003659 ResultBuilder Results(*this);
3660 Results.EnterNewScope();
3661
3662 // Add context-sensitive, Objective-C parameter-passing keywords.
3663 bool AddedInOut = false;
3664 if ((DS.getObjCDeclQualifier() &
3665 (ObjCDeclSpec::DQ_In | ObjCDeclSpec::DQ_Inout)) == 0) {
3666 Results.AddResult("in");
3667 Results.AddResult("inout");
3668 AddedInOut = true;
3669 }
3670 if ((DS.getObjCDeclQualifier() &
3671 (ObjCDeclSpec::DQ_Out | ObjCDeclSpec::DQ_Inout)) == 0) {
3672 Results.AddResult("out");
3673 if (!AddedInOut)
3674 Results.AddResult("inout");
3675 }
3676 if ((DS.getObjCDeclQualifier() &
3677 (ObjCDeclSpec::DQ_Bycopy | ObjCDeclSpec::DQ_Byref |
3678 ObjCDeclSpec::DQ_Oneway)) == 0) {
3679 Results.AddResult("bycopy");
3680 Results.AddResult("byref");
3681 Results.AddResult("oneway");
3682 }
3683
3684 // Add various builtin type names and specifiers.
3685 AddOrdinaryNameResults(PCC_Type, S, *this, Results);
3686 Results.ExitScope();
3687
3688 // Add the various type names
3689 Results.setFilter(&ResultBuilder::IsOrdinaryNonValueName);
3690 CodeCompletionDeclConsumer Consumer(Results, CurContext);
3691 LookupVisibleDecls(S, LookupOrdinaryName, Consumer,
3692 CodeCompleter->includeGlobals());
3693
3694 if (CodeCompleter->includeMacros())
3695 AddMacroResults(PP, Results);
3696
3697 HandleCodeCompleteResults(this, CodeCompleter,
3698 CodeCompletionContext::CCC_Type,
3699 Results.data(), Results.size());
3700}
3701
Douglas Gregor9d2ddb22010-04-06 19:22:33 +00003702/// \brief When we have an expression with type "id", we may assume
3703/// that it has some more-specific class type based on knowledge of
3704/// common uses of Objective-C. This routine returns that class type,
3705/// or NULL if no better result could be determined.
3706static ObjCInterfaceDecl *GetAssumedMessageSendExprType(Expr *E) {
3707 ObjCMessageExpr *Msg = dyn_cast<ObjCMessageExpr>(E);
3708 if (!Msg)
3709 return 0;
3710
3711 Selector Sel = Msg->getSelector();
3712 if (Sel.isNull())
3713 return 0;
3714
3715 IdentifierInfo *Id = Sel.getIdentifierInfoForSlot(0);
3716 if (!Id)
3717 return 0;
3718
3719 ObjCMethodDecl *Method = Msg->getMethodDecl();
3720 if (!Method)
3721 return 0;
3722
3723 // Determine the class that we're sending the message to.
Douglas Gregor9a129192010-04-21 00:45:42 +00003724 ObjCInterfaceDecl *IFace = 0;
3725 switch (Msg->getReceiverKind()) {
3726 case ObjCMessageExpr::Class:
John McCall8b07ec22010-05-15 11:32:37 +00003727 if (const ObjCObjectType *ObjType
3728 = Msg->getClassReceiver()->getAs<ObjCObjectType>())
3729 IFace = ObjType->getInterface();
Douglas Gregor9a129192010-04-21 00:45:42 +00003730 break;
3731
3732 case ObjCMessageExpr::Instance: {
3733 QualType T = Msg->getInstanceReceiver()->getType();
3734 if (const ObjCObjectPointerType *Ptr = T->getAs<ObjCObjectPointerType>())
3735 IFace = Ptr->getInterfaceDecl();
3736 break;
3737 }
3738
3739 case ObjCMessageExpr::SuperInstance:
3740 case ObjCMessageExpr::SuperClass:
3741 break;
Douglas Gregor9d2ddb22010-04-06 19:22:33 +00003742 }
3743
3744 if (!IFace)
3745 return 0;
3746
3747 ObjCInterfaceDecl *Super = IFace->getSuperClass();
3748 if (Method->isInstanceMethod())
3749 return llvm::StringSwitch<ObjCInterfaceDecl *>(Id->getName())
3750 .Case("retain", IFace)
3751 .Case("autorelease", IFace)
3752 .Case("copy", IFace)
3753 .Case("copyWithZone", IFace)
3754 .Case("mutableCopy", IFace)
3755 .Case("mutableCopyWithZone", IFace)
3756 .Case("awakeFromCoder", IFace)
3757 .Case("replacementObjectFromCoder", IFace)
3758 .Case("class", IFace)
3759 .Case("classForCoder", IFace)
3760 .Case("superclass", Super)
3761 .Default(0);
3762
3763 return llvm::StringSwitch<ObjCInterfaceDecl *>(Id->getName())
3764 .Case("new", IFace)
3765 .Case("alloc", IFace)
3766 .Case("allocWithZone", IFace)
3767 .Case("class", IFace)
3768 .Case("superclass", Super)
3769 .Default(0);
3770}
3771
Douglas Gregora817a192010-05-27 23:06:34 +00003772void Sema::CodeCompleteObjCMessageReceiver(Scope *S) {
John McCall276321a2010-08-25 06:19:51 +00003773 typedef CodeCompletionResult Result;
Douglas Gregora817a192010-05-27 23:06:34 +00003774 ResultBuilder Results(*this);
3775
3776 // Find anything that looks like it could be a message receiver.
3777 Results.setFilter(&ResultBuilder::IsObjCMessageReceiver);
3778 CodeCompletionDeclConsumer Consumer(Results, CurContext);
3779 Results.EnterNewScope();
Douglas Gregor39982192010-08-15 06:18:01 +00003780 LookupVisibleDecls(S, LookupOrdinaryName, Consumer,
3781 CodeCompleter->includeGlobals());
Douglas Gregora817a192010-05-27 23:06:34 +00003782
3783 // If we are in an Objective-C method inside a class that has a superclass,
3784 // add "super" as an option.
3785 if (ObjCMethodDecl *Method = getCurMethodDecl())
3786 if (ObjCInterfaceDecl *Iface = Method->getClassInterface())
3787 if (Iface->getSuperClass())
3788 Results.AddResult(Result("super"));
3789
3790 Results.ExitScope();
3791
3792 if (CodeCompleter->includeMacros())
3793 AddMacroResults(PP, Results);
Douglas Gregor00c37ef2010-08-11 21:23:17 +00003794 HandleCodeCompleteResults(this, CodeCompleter,
3795 CodeCompletionContext::CCC_ObjCMessageReceiver,
3796 Results.data(), Results.size());
Douglas Gregora817a192010-05-27 23:06:34 +00003797
3798}
3799
Douglas Gregor0c78ad92010-04-21 19:57:20 +00003800void Sema::CodeCompleteObjCSuperMessage(Scope *S, SourceLocation SuperLoc,
3801 IdentifierInfo **SelIdents,
3802 unsigned NumSelIdents) {
3803 ObjCInterfaceDecl *CDecl = 0;
3804 if (ObjCMethodDecl *CurMethod = getCurMethodDecl()) {
3805 // Figure out which interface we're in.
3806 CDecl = CurMethod->getClassInterface();
3807 if (!CDecl)
3808 return;
3809
3810 // Find the superclass of this class.
3811 CDecl = CDecl->getSuperClass();
3812 if (!CDecl)
3813 return;
3814
3815 if (CurMethod->isInstanceMethod()) {
3816 // We are inside an instance method, which means that the message
3817 // send [super ...] is actually calling an instance method on the
3818 // current object. Build the super expression and handle this like
3819 // an instance method.
3820 QualType SuperTy = Context.getObjCInterfaceType(CDecl);
3821 SuperTy = Context.getObjCObjectPointerType(SuperTy);
John McCalldadc5752010-08-24 06:29:42 +00003822 ExprResult Super
Douglas Gregor0c78ad92010-04-21 19:57:20 +00003823 = Owned(new (Context) ObjCSuperExpr(SuperLoc, SuperTy));
3824 return CodeCompleteObjCInstanceMessage(S, (Expr *)Super.get(),
3825 SelIdents, NumSelIdents);
3826 }
3827
3828 // Fall through to send to the superclass in CDecl.
3829 } else {
3830 // "super" may be the name of a type or variable. Figure out which
3831 // it is.
3832 IdentifierInfo *Super = &Context.Idents.get("super");
3833 NamedDecl *ND = LookupSingleName(S, Super, SuperLoc,
3834 LookupOrdinaryName);
3835 if ((CDecl = dyn_cast_or_null<ObjCInterfaceDecl>(ND))) {
3836 // "super" names an interface. Use it.
3837 } else if (TypeDecl *TD = dyn_cast_or_null<TypeDecl>(ND)) {
John McCall8b07ec22010-05-15 11:32:37 +00003838 if (const ObjCObjectType *Iface
3839 = Context.getTypeDeclType(TD)->getAs<ObjCObjectType>())
3840 CDecl = Iface->getInterface();
Douglas Gregor0c78ad92010-04-21 19:57:20 +00003841 } else if (ND && isa<UnresolvedUsingTypenameDecl>(ND)) {
3842 // "super" names an unresolved type; we can't be more specific.
3843 } else {
3844 // Assume that "super" names some kind of value and parse that way.
3845 CXXScopeSpec SS;
3846 UnqualifiedId id;
3847 id.setIdentifier(Super, SuperLoc);
John McCalldadc5752010-08-24 06:29:42 +00003848 ExprResult SuperExpr = ActOnIdExpression(S, SS, id, false, false);
Douglas Gregor0c78ad92010-04-21 19:57:20 +00003849 return CodeCompleteObjCInstanceMessage(S, (Expr *)SuperExpr.get(),
3850 SelIdents, NumSelIdents);
3851 }
3852
3853 // Fall through
3854 }
3855
John McCallba7bf592010-08-24 05:47:05 +00003856 ParsedType Receiver;
Douglas Gregor0c78ad92010-04-21 19:57:20 +00003857 if (CDecl)
John McCallba7bf592010-08-24 05:47:05 +00003858 Receiver = ParsedType::make(Context.getObjCInterfaceType(CDecl));
Douglas Gregor0c78ad92010-04-21 19:57:20 +00003859 return CodeCompleteObjCClassMessage(S, Receiver, SelIdents,
3860 NumSelIdents);
3861}
3862
John McCallba7bf592010-08-24 05:47:05 +00003863void Sema::CodeCompleteObjCClassMessage(Scope *S, ParsedType Receiver,
Douglas Gregor1b605f72009-11-19 01:08:35 +00003864 IdentifierInfo **SelIdents,
3865 unsigned NumSelIdents) {
John McCall276321a2010-08-25 06:19:51 +00003866 typedef CodeCompletionResult Result;
Douglas Gregor8ce33212009-11-17 17:59:40 +00003867 ObjCInterfaceDecl *CDecl = 0;
3868
Douglas Gregor8ce33212009-11-17 17:59:40 +00003869 // If the given name refers to an interface type, retrieve the
3870 // corresponding declaration.
Douglas Gregor0c78ad92010-04-21 19:57:20 +00003871 if (Receiver) {
3872 QualType T = GetTypeFromParser(Receiver, 0);
3873 if (!T.isNull())
John McCall8b07ec22010-05-15 11:32:37 +00003874 if (const ObjCObjectType *Interface = T->getAs<ObjCObjectType>())
3875 CDecl = Interface->getInterface();
Douglas Gregor8ce33212009-11-17 17:59:40 +00003876 }
3877
Douglas Gregorbab2b3c2009-11-17 23:22:23 +00003878 // Add all of the factory methods in this Objective-C class, its protocols,
3879 // superclasses, categories, implementation, etc.
Steve Naroffeae65032009-11-07 02:08:14 +00003880 ResultBuilder Results(*this);
3881 Results.EnterNewScope();
Douglas Gregor6285f752010-04-06 16:40:00 +00003882
3883 if (CDecl)
3884 AddObjCMethods(CDecl, false, MK_Any, SelIdents, NumSelIdents, CurContext,
3885 Results);
Douglas Gregor0c78ad92010-04-21 19:57:20 +00003886 else {
Douglas Gregor6285f752010-04-06 16:40:00 +00003887 // We're messaging "id" as a type; provide all class/factory methods.
3888
Douglas Gregord720daf2010-04-06 17:30:22 +00003889 // If we have an external source, load the entire class method
Sebastian Redld44cd6a2010-08-18 23:57:06 +00003890 // pool from the AST file.
Douglas Gregord720daf2010-04-06 17:30:22 +00003891 if (ExternalSource) {
John McCall75b960e2010-06-01 09:23:16 +00003892 for (uint32_t I = 0, N = ExternalSource->GetNumExternalSelectors();
3893 I != N; ++I) {
3894 Selector Sel = ExternalSource->GetExternalSelector(I);
Sebastian Redl75d8a322010-08-02 23:18:59 +00003895 if (Sel.isNull() || MethodPool.count(Sel))
Douglas Gregord720daf2010-04-06 17:30:22 +00003896 continue;
3897
Sebastian Redl75d8a322010-08-02 23:18:59 +00003898 ReadMethodPool(Sel);
Douglas Gregord720daf2010-04-06 17:30:22 +00003899 }
3900 }
3901
Sebastian Redl75d8a322010-08-02 23:18:59 +00003902 for (GlobalMethodPool::iterator M = MethodPool.begin(),
3903 MEnd = MethodPool.end();
3904 M != MEnd; ++M) {
3905 for (ObjCMethodList *MethList = &M->second.second;
3906 MethList && MethList->Method;
Douglas Gregor6285f752010-04-06 16:40:00 +00003907 MethList = MethList->Next) {
3908 if (!isAcceptableObjCMethod(MethList->Method, MK_Any, SelIdents,
3909 NumSelIdents))
3910 continue;
3911
3912 Result R(MethList->Method, 0);
3913 R.StartParameter = NumSelIdents;
3914 R.AllParametersAreInformative = false;
3915 Results.MaybeAddResult(R, CurContext);
3916 }
3917 }
3918 }
3919
Steve Naroffeae65032009-11-07 02:08:14 +00003920 Results.ExitScope();
Douglas Gregor00c37ef2010-08-11 21:23:17 +00003921 HandleCodeCompleteResults(this, CodeCompleter,
3922 CodeCompletionContext::CCC_Other,
3923 Results.data(),Results.size());
Steve Naroffeae65032009-11-07 02:08:14 +00003924}
3925
Douglas Gregor1b605f72009-11-19 01:08:35 +00003926void Sema::CodeCompleteObjCInstanceMessage(Scope *S, ExprTy *Receiver,
3927 IdentifierInfo **SelIdents,
3928 unsigned NumSelIdents) {
John McCall276321a2010-08-25 06:19:51 +00003929 typedef CodeCompletionResult Result;
Steve Naroffeae65032009-11-07 02:08:14 +00003930
3931 Expr *RecExpr = static_cast<Expr *>(Receiver);
Steve Naroffeae65032009-11-07 02:08:14 +00003932
Douglas Gregorbab2b3c2009-11-17 23:22:23 +00003933 // If necessary, apply function/array conversion to the receiver.
3934 // C99 6.7.5.3p[7,8].
Douglas Gregorb92a1562010-02-03 00:27:59 +00003935 DefaultFunctionArrayLvalueConversion(RecExpr);
Douglas Gregorbab2b3c2009-11-17 23:22:23 +00003936 QualType ReceiverType = RecExpr->getType();
Steve Naroffeae65032009-11-07 02:08:14 +00003937
Douglas Gregorbab2b3c2009-11-17 23:22:23 +00003938 // Build the set of methods we can see.
3939 ResultBuilder Results(*this);
3940 Results.EnterNewScope();
Douglas Gregor9d2ddb22010-04-06 19:22:33 +00003941
3942 // If we're messaging an expression with type "id" or "Class", check
3943 // whether we know something special about the receiver that allows
3944 // us to assume a more-specific receiver type.
3945 if (ReceiverType->isObjCIdType() || ReceiverType->isObjCClassType())
3946 if (ObjCInterfaceDecl *IFace = GetAssumedMessageSendExprType(RecExpr))
3947 ReceiverType = Context.getObjCObjectPointerType(
3948 Context.getObjCInterfaceType(IFace));
Douglas Gregorbab2b3c2009-11-17 23:22:23 +00003949
Douglas Gregora3329fa2009-11-18 00:06:18 +00003950 // Handle messages to Class. This really isn't a message to an instance
3951 // method, so we treat it the same way we would treat a message send to a
3952 // class method.
3953 if (ReceiverType->isObjCClassType() ||
3954 ReceiverType->isObjCQualifiedClassType()) {
3955 if (ObjCMethodDecl *CurMethod = getCurMethodDecl()) {
3956 if (ObjCInterfaceDecl *ClassDecl = CurMethod->getClassInterface())
Douglas Gregorc8537c52009-11-19 07:41:15 +00003957 AddObjCMethods(ClassDecl, false, MK_Any, SelIdents, NumSelIdents,
3958 CurContext, Results);
Douglas Gregora3329fa2009-11-18 00:06:18 +00003959 }
3960 }
3961 // Handle messages to a qualified ID ("id<foo>").
3962 else if (const ObjCObjectPointerType *QualID
3963 = ReceiverType->getAsObjCQualifiedIdType()) {
3964 // Search protocols for instance methods.
3965 for (ObjCObjectPointerType::qual_iterator I = QualID->qual_begin(),
3966 E = QualID->qual_end();
3967 I != E; ++I)
Douglas Gregorc8537c52009-11-19 07:41:15 +00003968 AddObjCMethods(*I, true, MK_Any, SelIdents, NumSelIdents, CurContext,
3969 Results);
Douglas Gregora3329fa2009-11-18 00:06:18 +00003970 }
3971 // Handle messages to a pointer to interface type.
3972 else if (const ObjCObjectPointerType *IFacePtr
3973 = ReceiverType->getAsObjCInterfacePointerType()) {
3974 // Search the class, its superclasses, etc., for instance methods.
Douglas Gregorc8537c52009-11-19 07:41:15 +00003975 AddObjCMethods(IFacePtr->getInterfaceDecl(), true, MK_Any, SelIdents,
3976 NumSelIdents, CurContext, Results);
Douglas Gregora3329fa2009-11-18 00:06:18 +00003977
3978 // Search protocols for instance methods.
3979 for (ObjCObjectPointerType::qual_iterator I = IFacePtr->qual_begin(),
3980 E = IFacePtr->qual_end();
3981 I != E; ++I)
Douglas Gregorc8537c52009-11-19 07:41:15 +00003982 AddObjCMethods(*I, true, MK_Any, SelIdents, NumSelIdents, CurContext,
3983 Results);
Douglas Gregora3329fa2009-11-18 00:06:18 +00003984 }
Douglas Gregor6285f752010-04-06 16:40:00 +00003985 // Handle messages to "id".
3986 else if (ReceiverType->isObjCIdType()) {
Douglas Gregord720daf2010-04-06 17:30:22 +00003987 // We're messaging "id", so provide all instance methods we know
3988 // about as code-completion results.
3989
3990 // If we have an external source, load the entire class method
Sebastian Redld44cd6a2010-08-18 23:57:06 +00003991 // pool from the AST file.
Douglas Gregord720daf2010-04-06 17:30:22 +00003992 if (ExternalSource) {
John McCall75b960e2010-06-01 09:23:16 +00003993 for (uint32_t I = 0, N = ExternalSource->GetNumExternalSelectors();
3994 I != N; ++I) {
3995 Selector Sel = ExternalSource->GetExternalSelector(I);
Sebastian Redl75d8a322010-08-02 23:18:59 +00003996 if (Sel.isNull() || MethodPool.count(Sel))
Douglas Gregord720daf2010-04-06 17:30:22 +00003997 continue;
3998
Sebastian Redl75d8a322010-08-02 23:18:59 +00003999 ReadMethodPool(Sel);
Douglas Gregord720daf2010-04-06 17:30:22 +00004000 }
4001 }
4002
Sebastian Redl75d8a322010-08-02 23:18:59 +00004003 for (GlobalMethodPool::iterator M = MethodPool.begin(),
4004 MEnd = MethodPool.end();
4005 M != MEnd; ++M) {
4006 for (ObjCMethodList *MethList = &M->second.first;
4007 MethList && MethList->Method;
Douglas Gregor6285f752010-04-06 16:40:00 +00004008 MethList = MethList->Next) {
4009 if (!isAcceptableObjCMethod(MethList->Method, MK_Any, SelIdents,
4010 NumSelIdents))
4011 continue;
4012
4013 Result R(MethList->Method, 0);
4014 R.StartParameter = NumSelIdents;
4015 R.AllParametersAreInformative = false;
4016 Results.MaybeAddResult(R, CurContext);
4017 }
4018 }
4019 }
4020
Steve Naroffeae65032009-11-07 02:08:14 +00004021 Results.ExitScope();
Douglas Gregor00c37ef2010-08-11 21:23:17 +00004022 HandleCodeCompleteResults(this, CodeCompleter,
4023 CodeCompletionContext::CCC_Other,
4024 Results.data(),Results.size());
Steve Naroffeae65032009-11-07 02:08:14 +00004025}
Douglas Gregorbaf69612009-11-18 04:19:12 +00004026
Douglas Gregor68762e72010-08-23 21:17:50 +00004027void Sema::CodeCompleteObjCForCollection(Scope *S,
4028 DeclGroupPtrTy IterationVar) {
4029 CodeCompleteExpressionData Data;
4030 Data.ObjCCollection = true;
4031
4032 if (IterationVar.getAsOpaquePtr()) {
4033 DeclGroupRef DG = IterationVar.getAsVal<DeclGroupRef>();
4034 for (DeclGroupRef::iterator I = DG.begin(), End = DG.end(); I != End; ++I) {
4035 if (*I)
4036 Data.IgnoreDecls.push_back(*I);
4037 }
4038 }
4039
4040 CodeCompleteExpression(S, Data);
4041}
4042
Douglas Gregorbaf69612009-11-18 04:19:12 +00004043/// \brief Add all of the protocol declarations that we find in the given
4044/// (translation unit) context.
4045static void AddProtocolResults(DeclContext *Ctx, DeclContext *CurContext,
Douglas Gregor5b4671c2009-11-18 04:49:41 +00004046 bool OnlyForwardDeclarations,
Douglas Gregorbaf69612009-11-18 04:19:12 +00004047 ResultBuilder &Results) {
John McCall276321a2010-08-25 06:19:51 +00004048 typedef CodeCompletionResult Result;
Douglas Gregorbaf69612009-11-18 04:19:12 +00004049
4050 for (DeclContext::decl_iterator D = Ctx->decls_begin(),
4051 DEnd = Ctx->decls_end();
4052 D != DEnd; ++D) {
4053 // Record any protocols we find.
4054 if (ObjCProtocolDecl *Proto = dyn_cast<ObjCProtocolDecl>(*D))
Douglas Gregor5b4671c2009-11-18 04:49:41 +00004055 if (!OnlyForwardDeclarations || Proto->isForwardDecl())
Douglas Gregorfc59ce12010-01-14 16:14:35 +00004056 Results.AddResult(Result(Proto, 0), CurContext, 0, false);
Douglas Gregorbaf69612009-11-18 04:19:12 +00004057
4058 // Record any forward-declared protocols we find.
4059 if (ObjCForwardProtocolDecl *Forward
4060 = dyn_cast<ObjCForwardProtocolDecl>(*D)) {
4061 for (ObjCForwardProtocolDecl::protocol_iterator
4062 P = Forward->protocol_begin(),
4063 PEnd = Forward->protocol_end();
4064 P != PEnd; ++P)
Douglas Gregor5b4671c2009-11-18 04:49:41 +00004065 if (!OnlyForwardDeclarations || (*P)->isForwardDecl())
Douglas Gregorfc59ce12010-01-14 16:14:35 +00004066 Results.AddResult(Result(*P, 0), CurContext, 0, false);
Douglas Gregorbaf69612009-11-18 04:19:12 +00004067 }
4068 }
4069}
4070
4071void Sema::CodeCompleteObjCProtocolReferences(IdentifierLocPair *Protocols,
4072 unsigned NumProtocols) {
4073 ResultBuilder Results(*this);
4074 Results.EnterNewScope();
4075
4076 // Tell the result set to ignore all of the protocols we have
4077 // already seen.
4078 for (unsigned I = 0; I != NumProtocols; ++I)
Douglas Gregorb2ccf012010-04-15 22:33:43 +00004079 if (ObjCProtocolDecl *Protocol = LookupProtocol(Protocols[I].first,
4080 Protocols[I].second))
Douglas Gregorbaf69612009-11-18 04:19:12 +00004081 Results.Ignore(Protocol);
4082
4083 // Add all protocols.
Douglas Gregor5b4671c2009-11-18 04:49:41 +00004084 AddProtocolResults(Context.getTranslationUnitDecl(), CurContext, false,
4085 Results);
4086
4087 Results.ExitScope();
Douglas Gregor00c37ef2010-08-11 21:23:17 +00004088 HandleCodeCompleteResults(this, CodeCompleter,
4089 CodeCompletionContext::CCC_ObjCProtocolName,
4090 Results.data(),Results.size());
Douglas Gregor5b4671c2009-11-18 04:49:41 +00004091}
4092
4093void Sema::CodeCompleteObjCProtocolDecl(Scope *) {
4094 ResultBuilder Results(*this);
4095 Results.EnterNewScope();
4096
4097 // Add all protocols.
4098 AddProtocolResults(Context.getTranslationUnitDecl(), CurContext, true,
4099 Results);
Douglas Gregorbaf69612009-11-18 04:19:12 +00004100
4101 Results.ExitScope();
Douglas Gregor00c37ef2010-08-11 21:23:17 +00004102 HandleCodeCompleteResults(this, CodeCompleter,
4103 CodeCompletionContext::CCC_ObjCProtocolName,
4104 Results.data(),Results.size());
Douglas Gregorbaf69612009-11-18 04:19:12 +00004105}
Douglas Gregor49c22a72009-11-18 16:26:39 +00004106
4107/// \brief Add all of the Objective-C interface declarations that we find in
4108/// the given (translation unit) context.
4109static void AddInterfaceResults(DeclContext *Ctx, DeclContext *CurContext,
4110 bool OnlyForwardDeclarations,
4111 bool OnlyUnimplemented,
4112 ResultBuilder &Results) {
John McCall276321a2010-08-25 06:19:51 +00004113 typedef CodeCompletionResult Result;
Douglas Gregor49c22a72009-11-18 16:26:39 +00004114
4115 for (DeclContext::decl_iterator D = Ctx->decls_begin(),
4116 DEnd = Ctx->decls_end();
4117 D != DEnd; ++D) {
Douglas Gregor1c283312010-08-11 12:19:30 +00004118 // Record any interfaces we find.
4119 if (ObjCInterfaceDecl *Class = dyn_cast<ObjCInterfaceDecl>(*D))
4120 if ((!OnlyForwardDeclarations || Class->isForwardDecl()) &&
4121 (!OnlyUnimplemented || !Class->getImplementation()))
4122 Results.AddResult(Result(Class, 0), CurContext, 0, false);
Douglas Gregor49c22a72009-11-18 16:26:39 +00004123
4124 // Record any forward-declared interfaces we find.
4125 if (ObjCClassDecl *Forward = dyn_cast<ObjCClassDecl>(*D)) {
4126 for (ObjCClassDecl::iterator C = Forward->begin(), CEnd = Forward->end();
Douglas Gregor1c283312010-08-11 12:19:30 +00004127 C != CEnd; ++C)
4128 if ((!OnlyForwardDeclarations || C->getInterface()->isForwardDecl()) &&
4129 (!OnlyUnimplemented || !C->getInterface()->getImplementation()))
4130 Results.AddResult(Result(C->getInterface(), 0), CurContext,
Douglas Gregorfc59ce12010-01-14 16:14:35 +00004131 0, false);
Douglas Gregor49c22a72009-11-18 16:26:39 +00004132 }
4133 }
4134}
4135
4136void Sema::CodeCompleteObjCInterfaceDecl(Scope *S) {
4137 ResultBuilder Results(*this);
4138 Results.EnterNewScope();
4139
4140 // Add all classes.
4141 AddInterfaceResults(Context.getTranslationUnitDecl(), CurContext, true,
4142 false, Results);
4143
4144 Results.ExitScope();
Douglas Gregor00c37ef2010-08-11 21:23:17 +00004145 HandleCodeCompleteResults(this, CodeCompleter,
4146 CodeCompletionContext::CCC_Other,
4147 Results.data(),Results.size());
Douglas Gregor49c22a72009-11-18 16:26:39 +00004148}
4149
Douglas Gregorb2ccf012010-04-15 22:33:43 +00004150void Sema::CodeCompleteObjCSuperclass(Scope *S, IdentifierInfo *ClassName,
4151 SourceLocation ClassNameLoc) {
Douglas Gregor49c22a72009-11-18 16:26:39 +00004152 ResultBuilder Results(*this);
4153 Results.EnterNewScope();
4154
4155 // Make sure that we ignore the class we're currently defining.
4156 NamedDecl *CurClass
Douglas Gregorb2ccf012010-04-15 22:33:43 +00004157 = LookupSingleName(TUScope, ClassName, ClassNameLoc, LookupOrdinaryName);
Douglas Gregor5d34fd32009-11-18 19:08:43 +00004158 if (CurClass && isa<ObjCInterfaceDecl>(CurClass))
Douglas Gregor49c22a72009-11-18 16:26:39 +00004159 Results.Ignore(CurClass);
4160
4161 // Add all classes.
4162 AddInterfaceResults(Context.getTranslationUnitDecl(), CurContext, false,
4163 false, Results);
4164
4165 Results.ExitScope();
Douglas Gregor00c37ef2010-08-11 21:23:17 +00004166 HandleCodeCompleteResults(this, CodeCompleter,
4167 CodeCompletionContext::CCC_Other,
4168 Results.data(),Results.size());
Douglas Gregor49c22a72009-11-18 16:26:39 +00004169}
4170
4171void Sema::CodeCompleteObjCImplementationDecl(Scope *S) {
4172 ResultBuilder Results(*this);
4173 Results.EnterNewScope();
4174
4175 // Add all unimplemented classes.
4176 AddInterfaceResults(Context.getTranslationUnitDecl(), CurContext, false,
4177 true, Results);
4178
4179 Results.ExitScope();
Douglas Gregor00c37ef2010-08-11 21:23:17 +00004180 HandleCodeCompleteResults(this, CodeCompleter,
4181 CodeCompletionContext::CCC_Other,
4182 Results.data(),Results.size());
Douglas Gregor49c22a72009-11-18 16:26:39 +00004183}
Douglas Gregor5d34fd32009-11-18 19:08:43 +00004184
4185void Sema::CodeCompleteObjCInterfaceCategory(Scope *S,
Douglas Gregorb2ccf012010-04-15 22:33:43 +00004186 IdentifierInfo *ClassName,
4187 SourceLocation ClassNameLoc) {
John McCall276321a2010-08-25 06:19:51 +00004188 typedef CodeCompletionResult Result;
Douglas Gregor5d34fd32009-11-18 19:08:43 +00004189
4190 ResultBuilder Results(*this);
4191
4192 // Ignore any categories we find that have already been implemented by this
4193 // interface.
4194 llvm::SmallPtrSet<IdentifierInfo *, 16> CategoryNames;
4195 NamedDecl *CurClass
Douglas Gregorb2ccf012010-04-15 22:33:43 +00004196 = LookupSingleName(TUScope, ClassName, ClassNameLoc, LookupOrdinaryName);
Douglas Gregor5d34fd32009-11-18 19:08:43 +00004197 if (ObjCInterfaceDecl *Class = dyn_cast_or_null<ObjCInterfaceDecl>(CurClass))
4198 for (ObjCCategoryDecl *Category = Class->getCategoryList(); Category;
4199 Category = Category->getNextClassCategory())
4200 CategoryNames.insert(Category->getIdentifier());
4201
4202 // Add all of the categories we know about.
4203 Results.EnterNewScope();
4204 TranslationUnitDecl *TU = Context.getTranslationUnitDecl();
4205 for (DeclContext::decl_iterator D = TU->decls_begin(),
4206 DEnd = TU->decls_end();
4207 D != DEnd; ++D)
4208 if (ObjCCategoryDecl *Category = dyn_cast<ObjCCategoryDecl>(*D))
4209 if (CategoryNames.insert(Category->getIdentifier()))
Douglas Gregorfc59ce12010-01-14 16:14:35 +00004210 Results.AddResult(Result(Category, 0), CurContext, 0, false);
Douglas Gregor5d34fd32009-11-18 19:08:43 +00004211 Results.ExitScope();
4212
Douglas Gregor00c37ef2010-08-11 21:23:17 +00004213 HandleCodeCompleteResults(this, CodeCompleter,
4214 CodeCompletionContext::CCC_Other,
4215 Results.data(),Results.size());
Douglas Gregor5d34fd32009-11-18 19:08:43 +00004216}
4217
4218void Sema::CodeCompleteObjCImplementationCategory(Scope *S,
Douglas Gregorb2ccf012010-04-15 22:33:43 +00004219 IdentifierInfo *ClassName,
4220 SourceLocation ClassNameLoc) {
John McCall276321a2010-08-25 06:19:51 +00004221 typedef CodeCompletionResult Result;
Douglas Gregor5d34fd32009-11-18 19:08:43 +00004222
4223 // Find the corresponding interface. If we couldn't find the interface, the
4224 // program itself is ill-formed. However, we'll try to be helpful still by
4225 // providing the list of all of the categories we know about.
4226 NamedDecl *CurClass
Douglas Gregorb2ccf012010-04-15 22:33:43 +00004227 = LookupSingleName(TUScope, ClassName, ClassNameLoc, LookupOrdinaryName);
Douglas Gregor5d34fd32009-11-18 19:08:43 +00004228 ObjCInterfaceDecl *Class = dyn_cast_or_null<ObjCInterfaceDecl>(CurClass);
4229 if (!Class)
Douglas Gregorb2ccf012010-04-15 22:33:43 +00004230 return CodeCompleteObjCInterfaceCategory(S, ClassName, ClassNameLoc);
Douglas Gregor5d34fd32009-11-18 19:08:43 +00004231
4232 ResultBuilder Results(*this);
4233
4234 // Add all of the categories that have have corresponding interface
4235 // declarations in this class and any of its superclasses, except for
4236 // already-implemented categories in the class itself.
4237 llvm::SmallPtrSet<IdentifierInfo *, 16> CategoryNames;
4238 Results.EnterNewScope();
4239 bool IgnoreImplemented = true;
4240 while (Class) {
4241 for (ObjCCategoryDecl *Category = Class->getCategoryList(); Category;
4242 Category = Category->getNextClassCategory())
4243 if ((!IgnoreImplemented || !Category->getImplementation()) &&
4244 CategoryNames.insert(Category->getIdentifier()))
Douglas Gregorfc59ce12010-01-14 16:14:35 +00004245 Results.AddResult(Result(Category, 0), CurContext, 0, false);
Douglas Gregor5d34fd32009-11-18 19:08:43 +00004246
4247 Class = Class->getSuperClass();
4248 IgnoreImplemented = false;
4249 }
4250 Results.ExitScope();
4251
Douglas Gregor00c37ef2010-08-11 21:23:17 +00004252 HandleCodeCompleteResults(this, CodeCompleter,
4253 CodeCompletionContext::CCC_Other,
4254 Results.data(),Results.size());
Douglas Gregor5d34fd32009-11-18 19:08:43 +00004255}
Douglas Gregor5d649882009-11-18 22:32:06 +00004256
John McCall48871652010-08-21 09:40:31 +00004257void Sema::CodeCompleteObjCPropertyDefinition(Scope *S, Decl *ObjCImpDecl) {
John McCall276321a2010-08-25 06:19:51 +00004258 typedef CodeCompletionResult Result;
Douglas Gregor5d649882009-11-18 22:32:06 +00004259 ResultBuilder Results(*this);
4260
4261 // Figure out where this @synthesize lives.
4262 ObjCContainerDecl *Container
John McCall48871652010-08-21 09:40:31 +00004263 = dyn_cast_or_null<ObjCContainerDecl>(ObjCImpDecl);
Douglas Gregor5d649882009-11-18 22:32:06 +00004264 if (!Container ||
4265 (!isa<ObjCImplementationDecl>(Container) &&
4266 !isa<ObjCCategoryImplDecl>(Container)))
4267 return;
4268
4269 // Ignore any properties that have already been implemented.
4270 for (DeclContext::decl_iterator D = Container->decls_begin(),
4271 DEnd = Container->decls_end();
4272 D != DEnd; ++D)
4273 if (ObjCPropertyImplDecl *PropertyImpl = dyn_cast<ObjCPropertyImplDecl>(*D))
4274 Results.Ignore(PropertyImpl->getPropertyDecl());
4275
4276 // Add any properties that we find.
4277 Results.EnterNewScope();
4278 if (ObjCImplementationDecl *ClassImpl
4279 = dyn_cast<ObjCImplementationDecl>(Container))
4280 AddObjCProperties(ClassImpl->getClassInterface(), false, CurContext,
4281 Results);
4282 else
4283 AddObjCProperties(cast<ObjCCategoryImplDecl>(Container)->getCategoryDecl(),
4284 false, CurContext, Results);
4285 Results.ExitScope();
4286
Douglas Gregor00c37ef2010-08-11 21:23:17 +00004287 HandleCodeCompleteResults(this, CodeCompleter,
4288 CodeCompletionContext::CCC_Other,
4289 Results.data(),Results.size());
Douglas Gregor5d649882009-11-18 22:32:06 +00004290}
4291
4292void Sema::CodeCompleteObjCPropertySynthesizeIvar(Scope *S,
4293 IdentifierInfo *PropertyName,
John McCall48871652010-08-21 09:40:31 +00004294 Decl *ObjCImpDecl) {
John McCall276321a2010-08-25 06:19:51 +00004295 typedef CodeCompletionResult Result;
Douglas Gregor5d649882009-11-18 22:32:06 +00004296 ResultBuilder Results(*this);
4297
4298 // Figure out where this @synthesize lives.
4299 ObjCContainerDecl *Container
John McCall48871652010-08-21 09:40:31 +00004300 = dyn_cast_or_null<ObjCContainerDecl>(ObjCImpDecl);
Douglas Gregor5d649882009-11-18 22:32:06 +00004301 if (!Container ||
4302 (!isa<ObjCImplementationDecl>(Container) &&
4303 !isa<ObjCCategoryImplDecl>(Container)))
4304 return;
4305
4306 // Figure out which interface we're looking into.
4307 ObjCInterfaceDecl *Class = 0;
4308 if (ObjCImplementationDecl *ClassImpl
4309 = dyn_cast<ObjCImplementationDecl>(Container))
4310 Class = ClassImpl->getClassInterface();
4311 else
4312 Class = cast<ObjCCategoryImplDecl>(Container)->getCategoryDecl()
4313 ->getClassInterface();
4314
4315 // Add all of the instance variables in this class and its superclasses.
4316 Results.EnterNewScope();
4317 for(; Class; Class = Class->getSuperClass()) {
4318 // FIXME: We could screen the type of each ivar for compatibility with
4319 // the property, but is that being too paternal?
4320 for (ObjCInterfaceDecl::ivar_iterator IVar = Class->ivar_begin(),
4321 IVarEnd = Class->ivar_end();
4322 IVar != IVarEnd; ++IVar)
Douglas Gregorfc59ce12010-01-14 16:14:35 +00004323 Results.AddResult(Result(*IVar, 0), CurContext, 0, false);
Douglas Gregor5d649882009-11-18 22:32:06 +00004324 }
4325 Results.ExitScope();
4326
Douglas Gregor00c37ef2010-08-11 21:23:17 +00004327 HandleCodeCompleteResults(this, CodeCompleter,
4328 CodeCompletionContext::CCC_Other,
4329 Results.data(),Results.size());
Douglas Gregor5d649882009-11-18 22:32:06 +00004330}
Douglas Gregor636a61e2010-04-07 00:21:17 +00004331
Douglas Gregor416b5752010-08-25 01:08:01 +00004332// Mapping from selectors to the methods that implement that selector, along
4333// with the "in original class" flag.
4334typedef llvm::DenseMap<Selector, std::pair<ObjCMethodDecl *, bool> >
4335 KnownMethodsMap;
Douglas Gregor636a61e2010-04-07 00:21:17 +00004336
4337/// \brief Find all of the methods that reside in the given container
4338/// (and its superclasses, protocols, etc.) that meet the given
4339/// criteria. Insert those methods into the map of known methods,
4340/// indexed by selector so they can be easily found.
4341static void FindImplementableMethods(ASTContext &Context,
4342 ObjCContainerDecl *Container,
4343 bool WantInstanceMethods,
4344 QualType ReturnType,
4345 bool IsInImplementation,
Douglas Gregor416b5752010-08-25 01:08:01 +00004346 KnownMethodsMap &KnownMethods,
4347 bool InOriginalClass = true) {
Douglas Gregor636a61e2010-04-07 00:21:17 +00004348 if (ObjCInterfaceDecl *IFace = dyn_cast<ObjCInterfaceDecl>(Container)) {
4349 // Recurse into protocols.
4350 const ObjCList<ObjCProtocolDecl> &Protocols
4351 = IFace->getReferencedProtocols();
4352 for (ObjCList<ObjCProtocolDecl>::iterator I = Protocols.begin(),
4353 E = Protocols.end();
4354 I != E; ++I)
4355 FindImplementableMethods(Context, *I, WantInstanceMethods, ReturnType,
Douglas Gregor416b5752010-08-25 01:08:01 +00004356 IsInImplementation, KnownMethods,
4357 InOriginalClass);
Douglas Gregor636a61e2010-04-07 00:21:17 +00004358
4359 // If we're not in the implementation of a class, also visit the
4360 // superclass.
4361 if (!IsInImplementation && IFace->getSuperClass())
4362 FindImplementableMethods(Context, IFace->getSuperClass(),
4363 WantInstanceMethods, ReturnType,
Douglas Gregor416b5752010-08-25 01:08:01 +00004364 IsInImplementation, KnownMethods,
4365 false);
Douglas Gregor636a61e2010-04-07 00:21:17 +00004366
4367 // Add methods from any class extensions (but not from categories;
4368 // those should go into category implementations).
Fariborz Jahanian3bf0ded2010-06-22 23:20:40 +00004369 for (const ObjCCategoryDecl *Cat = IFace->getFirstClassExtension(); Cat;
4370 Cat = Cat->getNextClassExtension())
4371 FindImplementableMethods(Context, const_cast<ObjCCategoryDecl*>(Cat),
4372 WantInstanceMethods, ReturnType,
Douglas Gregor416b5752010-08-25 01:08:01 +00004373 IsInImplementation, KnownMethods,
4374 InOriginalClass);
Douglas Gregor636a61e2010-04-07 00:21:17 +00004375 }
4376
4377 if (ObjCCategoryDecl *Category = dyn_cast<ObjCCategoryDecl>(Container)) {
4378 // Recurse into protocols.
4379 const ObjCList<ObjCProtocolDecl> &Protocols
4380 = Category->getReferencedProtocols();
4381 for (ObjCList<ObjCProtocolDecl>::iterator I = Protocols.begin(),
4382 E = Protocols.end();
4383 I != E; ++I)
4384 FindImplementableMethods(Context, *I, WantInstanceMethods, ReturnType,
Douglas Gregor416b5752010-08-25 01:08:01 +00004385 IsInImplementation, KnownMethods,
4386 InOriginalClass);
Douglas Gregor636a61e2010-04-07 00:21:17 +00004387 }
4388
4389 if (ObjCProtocolDecl *Protocol = dyn_cast<ObjCProtocolDecl>(Container)) {
4390 // Recurse into protocols.
4391 const ObjCList<ObjCProtocolDecl> &Protocols
4392 = Protocol->getReferencedProtocols();
4393 for (ObjCList<ObjCProtocolDecl>::iterator I = Protocols.begin(),
4394 E = Protocols.end();
4395 I != E; ++I)
4396 FindImplementableMethods(Context, *I, WantInstanceMethods, ReturnType,
Douglas Gregor416b5752010-08-25 01:08:01 +00004397 IsInImplementation, KnownMethods, false);
Douglas Gregor636a61e2010-04-07 00:21:17 +00004398 }
4399
4400 // Add methods in this container. This operation occurs last because
4401 // we want the methods from this container to override any methods
4402 // we've previously seen with the same selector.
4403 for (ObjCContainerDecl::method_iterator M = Container->meth_begin(),
4404 MEnd = Container->meth_end();
4405 M != MEnd; ++M) {
4406 if ((*M)->isInstanceMethod() == WantInstanceMethods) {
4407 if (!ReturnType.isNull() &&
4408 !Context.hasSameUnqualifiedType(ReturnType, (*M)->getResultType()))
4409 continue;
4410
Douglas Gregor416b5752010-08-25 01:08:01 +00004411 KnownMethods[(*M)->getSelector()] = std::make_pair(*M, InOriginalClass);
Douglas Gregor636a61e2010-04-07 00:21:17 +00004412 }
4413 }
4414}
4415
4416void Sema::CodeCompleteObjCMethodDecl(Scope *S,
4417 bool IsInstanceMethod,
John McCallba7bf592010-08-24 05:47:05 +00004418 ParsedType ReturnTy,
John McCall48871652010-08-21 09:40:31 +00004419 Decl *IDecl) {
Douglas Gregor636a61e2010-04-07 00:21:17 +00004420 // Determine the return type of the method we're declaring, if
4421 // provided.
4422 QualType ReturnType = GetTypeFromParser(ReturnTy);
4423
4424 // Determine where we should start searching for methods, and where we
4425 ObjCContainerDecl *SearchDecl = 0, *CurrentDecl = 0;
4426 bool IsInImplementation = false;
John McCall48871652010-08-21 09:40:31 +00004427 if (Decl *D = IDecl) {
Douglas Gregor636a61e2010-04-07 00:21:17 +00004428 if (ObjCImplementationDecl *Impl = dyn_cast<ObjCImplementationDecl>(D)) {
4429 SearchDecl = Impl->getClassInterface();
4430 CurrentDecl = Impl;
4431 IsInImplementation = true;
4432 } else if (ObjCCategoryImplDecl *CatImpl
4433 = dyn_cast<ObjCCategoryImplDecl>(D)) {
4434 SearchDecl = CatImpl->getCategoryDecl();
4435 CurrentDecl = CatImpl;
4436 IsInImplementation = true;
4437 } else {
4438 SearchDecl = dyn_cast<ObjCContainerDecl>(D);
4439 CurrentDecl = SearchDecl;
4440 }
4441 }
4442
4443 if (!SearchDecl && S) {
4444 if (DeclContext *DC = static_cast<DeclContext *>(S->getEntity())) {
4445 SearchDecl = dyn_cast<ObjCContainerDecl>(DC);
4446 CurrentDecl = SearchDecl;
4447 }
4448 }
4449
4450 if (!SearchDecl || !CurrentDecl) {
Douglas Gregor00c37ef2010-08-11 21:23:17 +00004451 HandleCodeCompleteResults(this, CodeCompleter,
4452 CodeCompletionContext::CCC_Other,
4453 0, 0);
Douglas Gregor636a61e2010-04-07 00:21:17 +00004454 return;
4455 }
4456
4457 // Find all of the methods that we could declare/implement here.
4458 KnownMethodsMap KnownMethods;
4459 FindImplementableMethods(Context, SearchDecl, IsInstanceMethod,
4460 ReturnType, IsInImplementation, KnownMethods);
4461
4462 // Erase any methods that have already been declared or
4463 // implemented here.
4464 for (ObjCContainerDecl::method_iterator M = CurrentDecl->meth_begin(),
4465 MEnd = CurrentDecl->meth_end();
4466 M != MEnd; ++M) {
4467 if ((*M)->isInstanceMethod() != IsInstanceMethod)
4468 continue;
4469
4470 KnownMethodsMap::iterator Pos = KnownMethods.find((*M)->getSelector());
4471 if (Pos != KnownMethods.end())
4472 KnownMethods.erase(Pos);
4473 }
4474
4475 // Add declarations or definitions for each of the known methods.
John McCall276321a2010-08-25 06:19:51 +00004476 typedef CodeCompletionResult Result;
Douglas Gregor636a61e2010-04-07 00:21:17 +00004477 ResultBuilder Results(*this);
4478 Results.EnterNewScope();
4479 PrintingPolicy Policy(Context.PrintingPolicy);
4480 Policy.AnonymousTagLocations = false;
4481 for (KnownMethodsMap::iterator M = KnownMethods.begin(),
4482 MEnd = KnownMethods.end();
4483 M != MEnd; ++M) {
Douglas Gregor416b5752010-08-25 01:08:01 +00004484 ObjCMethodDecl *Method = M->second.first;
Douglas Gregor636a61e2010-04-07 00:21:17 +00004485 CodeCompletionString *Pattern = new CodeCompletionString;
4486
4487 // If the result type was not already provided, add it to the
4488 // pattern as (type).
4489 if (ReturnType.isNull()) {
4490 std::string TypeStr;
4491 Method->getResultType().getAsStringInternal(TypeStr, Policy);
4492 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
4493 Pattern->AddTextChunk(TypeStr);
4494 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
4495 }
4496
4497 Selector Sel = Method->getSelector();
4498
4499 // Add the first part of the selector to the pattern.
4500 Pattern->AddTypedTextChunk(Sel.getIdentifierInfoForSlot(0)->getName());
4501
4502 // Add parameters to the pattern.
4503 unsigned I = 0;
4504 for (ObjCMethodDecl::param_iterator P = Method->param_begin(),
4505 PEnd = Method->param_end();
4506 P != PEnd; (void)++P, ++I) {
4507 // Add the part of the selector name.
4508 if (I == 0)
4509 Pattern->AddChunk(CodeCompletionString::CK_Colon);
4510 else if (I < Sel.getNumArgs()) {
4511 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
Douglas Gregorb0ce9b72010-08-17 15:53:35 +00004512 Pattern->AddTextChunk(Sel.getIdentifierInfoForSlot(I)->getName());
Douglas Gregor636a61e2010-04-07 00:21:17 +00004513 Pattern->AddChunk(CodeCompletionString::CK_Colon);
4514 } else
4515 break;
4516
4517 // Add the parameter type.
4518 std::string TypeStr;
4519 (*P)->getOriginalType().getAsStringInternal(TypeStr, Policy);
4520 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
4521 Pattern->AddTextChunk(TypeStr);
4522 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
4523
4524 if (IdentifierInfo *Id = (*P)->getIdentifier())
4525 Pattern->AddTextChunk(Id->getName());
4526 }
4527
4528 if (Method->isVariadic()) {
4529 if (Method->param_size() > 0)
4530 Pattern->AddChunk(CodeCompletionString::CK_Comma);
4531 Pattern->AddTextChunk("...");
4532 }
4533
Douglas Gregord37c59d2010-05-28 00:57:46 +00004534 if (IsInImplementation && Results.includeCodePatterns()) {
Douglas Gregor636a61e2010-04-07 00:21:17 +00004535 // We will be defining the method here, so add a compound statement.
4536 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
4537 Pattern->AddChunk(CodeCompletionString::CK_LeftBrace);
4538 Pattern->AddChunk(CodeCompletionString::CK_VerticalSpace);
4539 if (!Method->getResultType()->isVoidType()) {
4540 // If the result type is not void, add a return clause.
4541 Pattern->AddTextChunk("return");
4542 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
4543 Pattern->AddPlaceholderChunk("expression");
4544 Pattern->AddChunk(CodeCompletionString::CK_SemiColon);
4545 } else
4546 Pattern->AddPlaceholderChunk("statements");
4547
4548 Pattern->AddChunk(CodeCompletionString::CK_VerticalSpace);
4549 Pattern->AddChunk(CodeCompletionString::CK_RightBrace);
4550 }
4551
Douglas Gregor416b5752010-08-25 01:08:01 +00004552 unsigned Priority = CCP_CodePattern;
4553 if (!M->second.second)
4554 Priority += CCD_InBaseClass;
4555
4556 Results.AddResult(Result(Pattern, Priority,
Douglas Gregor7116a8c2010-08-17 16:06:07 +00004557 Method->isInstanceMethod()
4558 ? CXCursor_ObjCInstanceMethodDecl
4559 : CXCursor_ObjCClassMethodDecl));
Douglas Gregor636a61e2010-04-07 00:21:17 +00004560 }
4561
4562 Results.ExitScope();
4563
Douglas Gregor00c37ef2010-08-11 21:23:17 +00004564 HandleCodeCompleteResults(this, CodeCompleter,
4565 CodeCompletionContext::CCC_Other,
4566 Results.data(),Results.size());
Douglas Gregor636a61e2010-04-07 00:21:17 +00004567}
Douglas Gregor95887f92010-07-08 23:20:03 +00004568
4569void Sema::CodeCompleteObjCMethodDeclSelector(Scope *S,
4570 bool IsInstanceMethod,
Douglas Gregor45879692010-07-08 23:37:41 +00004571 bool AtParameterName,
John McCallba7bf592010-08-24 05:47:05 +00004572 ParsedType ReturnTy,
Douglas Gregor95887f92010-07-08 23:20:03 +00004573 IdentifierInfo **SelIdents,
4574 unsigned NumSelIdents) {
Douglas Gregor95887f92010-07-08 23:20:03 +00004575 // If we have an external source, load the entire class method
Sebastian Redld44cd6a2010-08-18 23:57:06 +00004576 // pool from the AST file.
Douglas Gregor95887f92010-07-08 23:20:03 +00004577 if (ExternalSource) {
4578 for (uint32_t I = 0, N = ExternalSource->GetNumExternalSelectors();
4579 I != N; ++I) {
4580 Selector Sel = ExternalSource->GetExternalSelector(I);
Sebastian Redl75d8a322010-08-02 23:18:59 +00004581 if (Sel.isNull() || MethodPool.count(Sel))
Douglas Gregor95887f92010-07-08 23:20:03 +00004582 continue;
Sebastian Redl75d8a322010-08-02 23:18:59 +00004583
4584 ReadMethodPool(Sel);
Douglas Gregor95887f92010-07-08 23:20:03 +00004585 }
4586 }
4587
4588 // Build the set of methods we can see.
John McCall276321a2010-08-25 06:19:51 +00004589 typedef CodeCompletionResult Result;
Douglas Gregor95887f92010-07-08 23:20:03 +00004590 ResultBuilder Results(*this);
4591
4592 if (ReturnTy)
4593 Results.setPreferredType(GetTypeFromParser(ReturnTy).getNonReferenceType());
Sebastian Redl75d8a322010-08-02 23:18:59 +00004594
Douglas Gregor95887f92010-07-08 23:20:03 +00004595 Results.EnterNewScope();
Sebastian Redl75d8a322010-08-02 23:18:59 +00004596 for (GlobalMethodPool::iterator M = MethodPool.begin(),
4597 MEnd = MethodPool.end();
4598 M != MEnd; ++M) {
4599 for (ObjCMethodList *MethList = IsInstanceMethod ? &M->second.first :
4600 &M->second.second;
4601 MethList && MethList->Method;
Douglas Gregor95887f92010-07-08 23:20:03 +00004602 MethList = MethList->Next) {
4603 if (!isAcceptableObjCMethod(MethList->Method, MK_Any, SelIdents,
4604 NumSelIdents))
4605 continue;
4606
Douglas Gregor45879692010-07-08 23:37:41 +00004607 if (AtParameterName) {
4608 // Suggest parameter names we've seen before.
4609 if (NumSelIdents && NumSelIdents <= MethList->Method->param_size()) {
4610 ParmVarDecl *Param = MethList->Method->param_begin()[NumSelIdents-1];
4611 if (Param->getIdentifier()) {
4612 CodeCompletionString *Pattern = new CodeCompletionString;
4613 Pattern->AddTypedTextChunk(Param->getIdentifier()->getName());
4614 Results.AddResult(Pattern);
4615 }
4616 }
4617
4618 continue;
4619 }
4620
Douglas Gregor95887f92010-07-08 23:20:03 +00004621 Result R(MethList->Method, 0);
4622 R.StartParameter = NumSelIdents;
4623 R.AllParametersAreInformative = false;
4624 R.DeclaringEntity = true;
4625 Results.MaybeAddResult(R, CurContext);
4626 }
4627 }
4628
4629 Results.ExitScope();
Douglas Gregor00c37ef2010-08-11 21:23:17 +00004630 HandleCodeCompleteResults(this, CodeCompleter,
4631 CodeCompletionContext::CCC_Other,
4632 Results.data(),Results.size());
Douglas Gregor95887f92010-07-08 23:20:03 +00004633}
Douglas Gregorb14904c2010-08-13 22:48:40 +00004634
Douglas Gregorec00a262010-08-24 22:20:20 +00004635void Sema::CodeCompletePreprocessorDirective(bool InConditional) {
Douglas Gregor3a7ad252010-08-24 19:08:16 +00004636 ResultBuilder Results(*this);
4637 Results.EnterNewScope();
4638
4639 // #if <condition>
4640 CodeCompletionString *Pattern = new CodeCompletionString;
4641 Pattern->AddTypedTextChunk("if");
4642 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
4643 Pattern->AddPlaceholderChunk("condition");
4644 Results.AddResult(Pattern);
4645
4646 // #ifdef <macro>
4647 Pattern = new CodeCompletionString;
4648 Pattern->AddTypedTextChunk("ifdef");
4649 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
4650 Pattern->AddPlaceholderChunk("macro");
4651 Results.AddResult(Pattern);
4652
4653 // #ifndef <macro>
4654 Pattern = new CodeCompletionString;
4655 Pattern->AddTypedTextChunk("ifndef");
4656 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
4657 Pattern->AddPlaceholderChunk("macro");
4658 Results.AddResult(Pattern);
4659
4660 if (InConditional) {
4661 // #elif <condition>
4662 Pattern = new CodeCompletionString;
4663 Pattern->AddTypedTextChunk("elif");
4664 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
4665 Pattern->AddPlaceholderChunk("condition");
4666 Results.AddResult(Pattern);
4667
4668 // #else
4669 Pattern = new CodeCompletionString;
4670 Pattern->AddTypedTextChunk("else");
4671 Results.AddResult(Pattern);
4672
4673 // #endif
4674 Pattern = new CodeCompletionString;
4675 Pattern->AddTypedTextChunk("endif");
4676 Results.AddResult(Pattern);
4677 }
4678
4679 // #include "header"
4680 Pattern = new CodeCompletionString;
4681 Pattern->AddTypedTextChunk("include");
4682 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
4683 Pattern->AddTextChunk("\"");
4684 Pattern->AddPlaceholderChunk("header");
4685 Pattern->AddTextChunk("\"");
4686 Results.AddResult(Pattern);
4687
4688 // #include <header>
4689 Pattern = new CodeCompletionString;
4690 Pattern->AddTypedTextChunk("include");
4691 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
4692 Pattern->AddTextChunk("<");
4693 Pattern->AddPlaceholderChunk("header");
4694 Pattern->AddTextChunk(">");
4695 Results.AddResult(Pattern);
4696
4697 // #define <macro>
4698 Pattern = new CodeCompletionString;
4699 Pattern->AddTypedTextChunk("define");
4700 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
4701 Pattern->AddPlaceholderChunk("macro");
4702 Results.AddResult(Pattern);
4703
4704 // #define <macro>(<args>)
4705 Pattern = new CodeCompletionString;
4706 Pattern->AddTypedTextChunk("define");
4707 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
4708 Pattern->AddPlaceholderChunk("macro");
4709 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
4710 Pattern->AddPlaceholderChunk("args");
4711 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
4712 Results.AddResult(Pattern);
4713
4714 // #undef <macro>
4715 Pattern = new CodeCompletionString;
4716 Pattern->AddTypedTextChunk("undef");
4717 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
4718 Pattern->AddPlaceholderChunk("macro");
4719 Results.AddResult(Pattern);
4720
4721 // #line <number>
4722 Pattern = new CodeCompletionString;
4723 Pattern->AddTypedTextChunk("line");
4724 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
4725 Pattern->AddPlaceholderChunk("number");
4726 Results.AddResult(Pattern);
4727
4728 // #line <number> "filename"
4729 Pattern = new CodeCompletionString;
4730 Pattern->AddTypedTextChunk("line");
4731 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
4732 Pattern->AddPlaceholderChunk("number");
4733 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
4734 Pattern->AddTextChunk("\"");
4735 Pattern->AddPlaceholderChunk("filename");
4736 Pattern->AddTextChunk("\"");
4737 Results.AddResult(Pattern);
4738
4739 // #error <message>
4740 Pattern = new CodeCompletionString;
4741 Pattern->AddTypedTextChunk("error");
4742 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
4743 Pattern->AddPlaceholderChunk("message");
4744 Results.AddResult(Pattern);
4745
4746 // #pragma <arguments>
4747 Pattern = new CodeCompletionString;
4748 Pattern->AddTypedTextChunk("pragma");
4749 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
4750 Pattern->AddPlaceholderChunk("arguments");
4751 Results.AddResult(Pattern);
4752
4753 if (getLangOptions().ObjC1) {
4754 // #import "header"
4755 Pattern = new CodeCompletionString;
4756 Pattern->AddTypedTextChunk("import");
4757 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
4758 Pattern->AddTextChunk("\"");
4759 Pattern->AddPlaceholderChunk("header");
4760 Pattern->AddTextChunk("\"");
4761 Results.AddResult(Pattern);
4762
4763 // #import <header>
4764 Pattern = new CodeCompletionString;
4765 Pattern->AddTypedTextChunk("import");
4766 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
4767 Pattern->AddTextChunk("<");
4768 Pattern->AddPlaceholderChunk("header");
4769 Pattern->AddTextChunk(">");
4770 Results.AddResult(Pattern);
4771 }
4772
4773 // #include_next "header"
4774 Pattern = new CodeCompletionString;
4775 Pattern->AddTypedTextChunk("include_next");
4776 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
4777 Pattern->AddTextChunk("\"");
4778 Pattern->AddPlaceholderChunk("header");
4779 Pattern->AddTextChunk("\"");
4780 Results.AddResult(Pattern);
4781
4782 // #include_next <header>
4783 Pattern = new CodeCompletionString;
4784 Pattern->AddTypedTextChunk("include_next");
4785 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
4786 Pattern->AddTextChunk("<");
4787 Pattern->AddPlaceholderChunk("header");
4788 Pattern->AddTextChunk(">");
4789 Results.AddResult(Pattern);
4790
4791 // #warning <message>
4792 Pattern = new CodeCompletionString;
4793 Pattern->AddTypedTextChunk("warning");
4794 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
4795 Pattern->AddPlaceholderChunk("message");
4796 Results.AddResult(Pattern);
4797
4798 // Note: #ident and #sccs are such crazy anachronisms that we don't provide
4799 // completions for them. And __include_macros is a Clang-internal extension
4800 // that we don't want to encourage anyone to use.
4801
4802 // FIXME: we don't support #assert or #unassert, so don't suggest them.
4803 Results.ExitScope();
4804
4805 // FIXME: Create a new code-completion context for this?
4806 HandleCodeCompleteResults(this, CodeCompleter,
4807 CodeCompletionContext::CCC_Other,
4808 Results.data(), Results.size());
4809}
4810
4811void Sema::CodeCompleteInPreprocessorConditionalExclusion(Scope *S) {
Douglas Gregorec00a262010-08-24 22:20:20 +00004812 CodeCompleteOrdinaryName(S,
4813 S->getFnParent()? Action::PCC_RecoveryInFunction
4814 : Action::PCC_Namespace);
Douglas Gregor3a7ad252010-08-24 19:08:16 +00004815}
4816
Douglas Gregorec00a262010-08-24 22:20:20 +00004817void Sema::CodeCompletePreprocessorMacroName(bool IsDefinition) {
Douglas Gregor12785102010-08-24 20:21:13 +00004818 ResultBuilder Results(*this);
4819 if (!IsDefinition && (!CodeCompleter || CodeCompleter->includeMacros())) {
4820 // Add just the names of macros, not their arguments.
4821 Results.EnterNewScope();
4822 for (Preprocessor::macro_iterator M = PP.macro_begin(),
4823 MEnd = PP.macro_end();
4824 M != MEnd; ++M) {
4825 CodeCompletionString *Pattern = new CodeCompletionString;
4826 Pattern->AddTypedTextChunk(M->first->getName());
4827 Results.AddResult(Pattern);
4828 }
4829 Results.ExitScope();
4830 } else if (IsDefinition) {
4831 // FIXME: Can we detect when the user just wrote an include guard above?
4832 }
4833
4834 HandleCodeCompleteResults(this, CodeCompleter,
4835 IsDefinition? CodeCompletionContext::CCC_MacroName
4836 : CodeCompletionContext::CCC_MacroNameUse,
4837 Results.data(), Results.size());
4838}
4839
Douglas Gregorec00a262010-08-24 22:20:20 +00004840void Sema::CodeCompletePreprocessorExpression() {
4841 ResultBuilder Results(*this);
4842
4843 if (!CodeCompleter || CodeCompleter->includeMacros())
4844 AddMacroResults(PP, Results);
4845
4846 // defined (<macro>)
4847 Results.EnterNewScope();
4848 CodeCompletionString *Pattern = new CodeCompletionString;
4849 Pattern->AddTypedTextChunk("defined");
4850 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
4851 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
4852 Pattern->AddPlaceholderChunk("macro");
4853 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
4854 Results.AddResult(Pattern);
4855 Results.ExitScope();
4856
4857 HandleCodeCompleteResults(this, CodeCompleter,
4858 CodeCompletionContext::CCC_PreprocessorExpression,
4859 Results.data(), Results.size());
4860}
4861
4862void Sema::CodeCompletePreprocessorMacroArgument(Scope *S,
4863 IdentifierInfo *Macro,
4864 MacroInfo *MacroInfo,
4865 unsigned Argument) {
4866 // FIXME: In the future, we could provide "overload" results, much like we
4867 // do for function calls.
4868
4869 CodeCompleteOrdinaryName(S,
4870 S->getFnParent()? Action::PCC_RecoveryInFunction
4871 : Action::PCC_Namespace);
4872}
4873
Douglas Gregorb14904c2010-08-13 22:48:40 +00004874void Sema::GatherGlobalCodeCompletions(
John McCall276321a2010-08-25 06:19:51 +00004875 llvm::SmallVectorImpl<CodeCompletionResult> &Results) {
Douglas Gregorb14904c2010-08-13 22:48:40 +00004876 ResultBuilder Builder(*this);
4877
Douglas Gregor39982192010-08-15 06:18:01 +00004878 if (!CodeCompleter || CodeCompleter->includeGlobals()) {
4879 CodeCompletionDeclConsumer Consumer(Builder,
4880 Context.getTranslationUnitDecl());
4881 LookupVisibleDecls(Context.getTranslationUnitDecl(), LookupAnyName,
4882 Consumer);
4883 }
Douglas Gregorb14904c2010-08-13 22:48:40 +00004884
4885 if (!CodeCompleter || CodeCompleter->includeMacros())
4886 AddMacroResults(PP, Builder);
4887
4888 Results.clear();
4889 Results.insert(Results.end(),
4890 Builder.data(), Builder.data() + Builder.size());
4891}