blob: e305172e5114abd6e777b8e2a9941085ba567270 [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//===----------------------------------------------------------------------===//
John McCall83024632010-08-25 22:03:47 +000013#include "clang/Sema/SemaInternal.h"
Douglas Gregorc3a6ade2010-08-12 20:07:10 +000014#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 McCallaab3e412010-08-25 08:40:02 +000019#include "clang/Sema/ScopeInfo.h"
John McCallde6836a2010-08-24 07:21:54 +000020#include "clang/AST/DeclObjC.h"
Douglas Gregorf2510672009-09-21 19:57:38 +000021#include "clang/AST/ExprCXX.h"
Douglas Gregor8ce33212009-11-17 17:59:40 +000022#include "clang/AST/ExprObjC.h"
Douglas Gregorf329c7c2009-10-30 16:50:04 +000023#include "clang/Lex/MacroInfo.h"
24#include "clang/Lex/Preprocessor.h"
Douglas Gregor1154e272010-09-16 16:06:31 +000025#include "llvm/ADT/DenseSet.h"
Douglas Gregor3545ff42009-09-21 16:56:56 +000026#include "llvm/ADT/SmallPtrSet.h"
Douglas Gregore6688e62009-09-28 03:51:44 +000027#include "llvm/ADT/StringExtras.h"
Douglas Gregor9d2ddb22010-04-06 19:22:33 +000028#include "llvm/ADT/StringSwitch.h"
Douglas Gregor67c692c2010-08-26 15:07:07 +000029#include "llvm/ADT/Twine.h"
Douglas Gregor3545ff42009-09-21 16:56:56 +000030#include <list>
31#include <map>
32#include <vector>
Douglas Gregor2436e712009-09-17 21:32:03 +000033
34using namespace clang;
John McCallaab3e412010-08-25 08:40:02 +000035using namespace sema;
Douglas Gregor2436e712009-09-17 21:32:03 +000036
Douglas Gregor3545ff42009-09-21 16:56:56 +000037namespace {
38 /// \brief A container of code-completion results.
39 class ResultBuilder {
40 public:
41 /// \brief The type of a name-lookup filter, which can be provided to the
42 /// name-lookup routines to specify which declarations should be included in
43 /// the result set (when it returns true) and which declarations should be
44 /// filtered out (returns false).
45 typedef bool (ResultBuilder::*LookupFilter)(NamedDecl *) const;
46
John McCall276321a2010-08-25 06:19:51 +000047 typedef CodeCompletionResult Result;
Douglas Gregor3545ff42009-09-21 16:56:56 +000048
49 private:
50 /// \brief The actual results we have found.
51 std::vector<Result> Results;
52
53 /// \brief A record of all of the declarations we have found and placed
54 /// into the result set, used to ensure that no declaration ever gets into
55 /// the result set twice.
56 llvm::SmallPtrSet<Decl*, 16> AllDeclsFound;
57
Douglas Gregor05e7ca32009-12-06 20:23:50 +000058 typedef std::pair<NamedDecl *, unsigned> DeclIndexPair;
59
60 /// \brief An entry in the shadow map, which is optimized to store
61 /// a single (declaration, index) mapping (the common case) but
62 /// can also store a list of (declaration, index) mappings.
63 class ShadowMapEntry {
64 typedef llvm::SmallVector<DeclIndexPair, 4> DeclIndexPairVector;
65
66 /// \brief Contains either the solitary NamedDecl * or a vector
67 /// of (declaration, index) pairs.
68 llvm::PointerUnion<NamedDecl *, DeclIndexPairVector*> DeclOrVector;
69
70 /// \brief When the entry contains a single declaration, this is
71 /// the index associated with that entry.
72 unsigned SingleDeclIndex;
73
74 public:
75 ShadowMapEntry() : DeclOrVector(), SingleDeclIndex(0) { }
76
77 void Add(NamedDecl *ND, unsigned Index) {
78 if (DeclOrVector.isNull()) {
79 // 0 - > 1 elements: just set the single element information.
80 DeclOrVector = ND;
81 SingleDeclIndex = Index;
82 return;
83 }
84
85 if (NamedDecl *PrevND = DeclOrVector.dyn_cast<NamedDecl *>()) {
86 // 1 -> 2 elements: create the vector of results and push in the
87 // existing declaration.
88 DeclIndexPairVector *Vec = new DeclIndexPairVector;
89 Vec->push_back(DeclIndexPair(PrevND, SingleDeclIndex));
90 DeclOrVector = Vec;
91 }
92
93 // Add the new element to the end of the vector.
94 DeclOrVector.get<DeclIndexPairVector*>()->push_back(
95 DeclIndexPair(ND, Index));
96 }
97
98 void Destroy() {
99 if (DeclIndexPairVector *Vec
100 = DeclOrVector.dyn_cast<DeclIndexPairVector *>()) {
101 delete Vec;
102 DeclOrVector = ((NamedDecl *)0);
103 }
104 }
105
106 // Iteration.
107 class iterator;
108 iterator begin() const;
109 iterator end() const;
110 };
111
Douglas Gregor3545ff42009-09-21 16:56:56 +0000112 /// \brief A mapping from declaration names to the declarations that have
113 /// this name within a particular scope and their index within the list of
114 /// results.
Douglas Gregor05e7ca32009-12-06 20:23:50 +0000115 typedef llvm::DenseMap<DeclarationName, ShadowMapEntry> ShadowMap;
Douglas Gregor3545ff42009-09-21 16:56:56 +0000116
117 /// \brief The semantic analysis object for which results are being
118 /// produced.
119 Sema &SemaRef;
120
121 /// \brief If non-NULL, a filter function used to remove any code-completion
122 /// results that are not desirable.
123 LookupFilter Filter;
Douglas Gregor6ae4c522010-01-14 03:21:49 +0000124
125 /// \brief Whether we should allow declarations as
126 /// nested-name-specifiers that would otherwise be filtered out.
127 bool AllowNestedNameSpecifiers;
128
Douglas Gregor7aa6b222010-05-30 01:49:25 +0000129 /// \brief If set, the type that we would prefer our resulting value
130 /// declarations to have.
131 ///
132 /// Closely matching the preferred type gives a boost to a result's
133 /// priority.
134 CanQualType PreferredType;
135
Douglas Gregor3545ff42009-09-21 16:56:56 +0000136 /// \brief A list of shadow maps, which is used to model name hiding at
137 /// different levels of, e.g., the inheritance hierarchy.
138 std::list<ShadowMap> ShadowMaps;
139
Douglas Gregor9be0ed42010-08-26 16:36:48 +0000140 /// \brief If we're potentially referring to a C++ member function, the set
141 /// of qualifiers applied to the object type.
142 Qualifiers ObjectTypeQualifiers;
143
144 /// \brief Whether the \p ObjectTypeQualifiers field is active.
145 bool HasObjectTypeQualifiers;
146
Douglas Gregorc2cb2e22010-08-27 15:29:55 +0000147 /// \brief The selector that we prefer.
148 Selector PreferredSelector;
149
Douglas Gregor95887f92010-07-08 23:20:03 +0000150 void AdjustResultPriorityForPreferredType(Result &R);
151
Douglas Gregor3545ff42009-09-21 16:56:56 +0000152 public:
153 explicit ResultBuilder(Sema &SemaRef, LookupFilter Filter = 0)
Douglas Gregor9be0ed42010-08-26 16:36:48 +0000154 : SemaRef(SemaRef), Filter(Filter), AllowNestedNameSpecifiers(false),
155 HasObjectTypeQualifiers(false) { }
Douglas Gregor3545ff42009-09-21 16:56:56 +0000156
Douglas Gregorf64acca2010-05-25 21:41:55 +0000157 /// \brief Whether we should include code patterns in the completion
158 /// results.
159 bool includeCodePatterns() const {
160 return SemaRef.CodeCompleter &&
Douglas Gregorac322ec2010-08-27 21:18:54 +0000161 SemaRef.CodeCompleter->includeCodePatterns();
Douglas Gregorf64acca2010-05-25 21:41:55 +0000162 }
163
Douglas Gregor3545ff42009-09-21 16:56:56 +0000164 /// \brief Set the filter used for code-completion results.
165 void setFilter(LookupFilter Filter) {
166 this->Filter = Filter;
167 }
168
Douglas Gregor3545ff42009-09-21 16:56:56 +0000169 Result *data() { return Results.empty()? 0 : &Results.front(); }
170 unsigned size() const { return Results.size(); }
171 bool empty() const { return Results.empty(); }
172
Douglas Gregor7aa6b222010-05-30 01:49:25 +0000173 /// \brief Specify the preferred type.
174 void setPreferredType(QualType T) {
175 PreferredType = SemaRef.Context.getCanonicalType(T);
176 }
177
Douglas Gregor9be0ed42010-08-26 16:36:48 +0000178 /// \brief Set the cv-qualifiers on the object type, for us in filtering
179 /// calls to member functions.
180 ///
181 /// When there are qualifiers in this set, they will be used to filter
182 /// out member functions that aren't available (because there will be a
183 /// cv-qualifier mismatch) or prefer functions with an exact qualifier
184 /// match.
185 void setObjectTypeQualifiers(Qualifiers Quals) {
186 ObjectTypeQualifiers = Quals;
187 HasObjectTypeQualifiers = true;
188 }
189
Douglas Gregorc2cb2e22010-08-27 15:29:55 +0000190 /// \brief Set the preferred selector.
191 ///
192 /// When an Objective-C method declaration result is added, and that
193 /// method's selector matches this preferred selector, we give that method
194 /// a slight priority boost.
195 void setPreferredSelector(Selector Sel) {
196 PreferredSelector = Sel;
197 }
198
Douglas Gregor6ae4c522010-01-14 03:21:49 +0000199 /// \brief Specify whether nested-name-specifiers are allowed.
200 void allowNestedNameSpecifiers(bool Allow = true) {
201 AllowNestedNameSpecifiers = Allow;
202 }
203
Douglas Gregor7c208612010-01-14 00:20:49 +0000204 /// \brief Determine whether the given declaration is at all interesting
205 /// as a code-completion result.
Douglas Gregor6ae4c522010-01-14 03:21:49 +0000206 ///
207 /// \param ND the declaration that we are inspecting.
208 ///
209 /// \param AsNestedNameSpecifier will be set true if this declaration is
210 /// only interesting when it is a nested-name-specifier.
211 bool isInterestingDecl(NamedDecl *ND, bool &AsNestedNameSpecifier) const;
Douglas Gregore0717ab2010-01-14 00:41:07 +0000212
213 /// \brief Check whether the result is hidden by the Hiding declaration.
214 ///
215 /// \returns true if the result is hidden and cannot be found, false if
216 /// the hidden result could still be found. When false, \p R may be
217 /// modified to describe how the result can be found (e.g., via extra
218 /// qualification).
219 bool CheckHiddenResult(Result &R, DeclContext *CurContext,
220 NamedDecl *Hiding);
221
Douglas Gregor3545ff42009-09-21 16:56:56 +0000222 /// \brief Add a new result to this result set (if it isn't already in one
223 /// of the shadow maps), or replace an existing result (for, e.g., a
224 /// redeclaration).
Douglas Gregor2af2f672009-09-21 20:12:40 +0000225 ///
Douglas Gregorc580c522010-01-14 01:09:38 +0000226 /// \param CurContext the result to add (if it is unique).
Douglas Gregor2af2f672009-09-21 20:12:40 +0000227 ///
228 /// \param R the context in which this result will be named.
229 void MaybeAddResult(Result R, DeclContext *CurContext = 0);
Douglas Gregor3545ff42009-09-21 16:56:56 +0000230
Douglas Gregorc580c522010-01-14 01:09:38 +0000231 /// \brief Add a new result to this result set, where we already know
232 /// the hiding declation (if any).
233 ///
234 /// \param R the result to add (if it is unique).
235 ///
236 /// \param CurContext the context in which this result will be named.
237 ///
238 /// \param Hiding the declaration that hides the result.
Douglas Gregor09bbc652010-01-14 15:47:35 +0000239 ///
240 /// \param InBaseClass whether the result was found in a base
241 /// class of the searched context.
242 void AddResult(Result R, DeclContext *CurContext, NamedDecl *Hiding,
243 bool InBaseClass);
Douglas Gregorc580c522010-01-14 01:09:38 +0000244
Douglas Gregor78a21012010-01-14 16:01:26 +0000245 /// \brief Add a new non-declaration result to this result set.
246 void AddResult(Result R);
247
Douglas Gregor3545ff42009-09-21 16:56:56 +0000248 /// \brief Enter into a new scope.
249 void EnterNewScope();
250
251 /// \brief Exit from the current scope.
252 void ExitScope();
253
Douglas Gregorbaf69612009-11-18 04:19:12 +0000254 /// \brief Ignore this declaration, if it is seen again.
255 void Ignore(Decl *D) { AllDeclsFound.insert(D->getCanonicalDecl()); }
256
Douglas Gregor3545ff42009-09-21 16:56:56 +0000257 /// \name Name lookup predicates
258 ///
259 /// These predicates can be passed to the name lookup functions to filter the
260 /// results of name lookup. All of the predicates have the same type, so that
261 ///
262 //@{
Douglas Gregor9d64c5e2009-09-21 20:51:25 +0000263 bool IsOrdinaryName(NamedDecl *ND) const;
Douglas Gregor70febae2010-05-28 00:49:12 +0000264 bool IsOrdinaryNonTypeName(NamedDecl *ND) const;
Douglas Gregor85b50632010-07-28 21:50:18 +0000265 bool IsIntegralConstantValue(NamedDecl *ND) const;
Douglas Gregor504a6ae2010-01-10 23:08:15 +0000266 bool IsOrdinaryNonValueName(NamedDecl *ND) const;
Douglas Gregor3545ff42009-09-21 16:56:56 +0000267 bool IsNestedNameSpecifier(NamedDecl *ND) const;
268 bool IsEnum(NamedDecl *ND) const;
269 bool IsClassOrStruct(NamedDecl *ND) const;
270 bool IsUnion(NamedDecl *ND) const;
271 bool IsNamespace(NamedDecl *ND) const;
272 bool IsNamespaceOrAlias(NamedDecl *ND) const;
273 bool IsType(NamedDecl *ND) const;
Douglas Gregore412a5a2009-09-23 22:26:46 +0000274 bool IsMember(NamedDecl *ND) const;
Douglas Gregor2b8162b2010-01-14 16:08:12 +0000275 bool IsObjCIvar(NamedDecl *ND) const;
Douglas Gregora817a192010-05-27 23:06:34 +0000276 bool IsObjCMessageReceiver(NamedDecl *ND) const;
Douglas Gregor68762e72010-08-23 21:17:50 +0000277 bool IsObjCCollection(NamedDecl *ND) const;
Douglas Gregor3545ff42009-09-21 16:56:56 +0000278 //@}
279 };
280}
281
Douglas Gregor05e7ca32009-12-06 20:23:50 +0000282class ResultBuilder::ShadowMapEntry::iterator {
283 llvm::PointerUnion<NamedDecl*, const DeclIndexPair*> DeclOrIterator;
284 unsigned SingleDeclIndex;
285
286public:
287 typedef DeclIndexPair value_type;
288 typedef value_type reference;
289 typedef std::ptrdiff_t difference_type;
290 typedef std::input_iterator_tag iterator_category;
291
292 class pointer {
293 DeclIndexPair Value;
294
295 public:
296 pointer(const DeclIndexPair &Value) : Value(Value) { }
297
298 const DeclIndexPair *operator->() const {
299 return &Value;
300 }
301 };
302
303 iterator() : DeclOrIterator((NamedDecl *)0), SingleDeclIndex(0) { }
304
305 iterator(NamedDecl *SingleDecl, unsigned Index)
306 : DeclOrIterator(SingleDecl), SingleDeclIndex(Index) { }
307
308 iterator(const DeclIndexPair *Iterator)
309 : DeclOrIterator(Iterator), SingleDeclIndex(0) { }
310
311 iterator &operator++() {
312 if (DeclOrIterator.is<NamedDecl *>()) {
313 DeclOrIterator = (NamedDecl *)0;
314 SingleDeclIndex = 0;
315 return *this;
316 }
317
318 const DeclIndexPair *I = DeclOrIterator.get<const DeclIndexPair*>();
319 ++I;
320 DeclOrIterator = I;
321 return *this;
322 }
323
Chris Lattner9795b392010-09-04 18:12:20 +0000324 /*iterator operator++(int) {
Douglas Gregor05e7ca32009-12-06 20:23:50 +0000325 iterator tmp(*this);
326 ++(*this);
327 return tmp;
Chris Lattner9795b392010-09-04 18:12:20 +0000328 }*/
Douglas Gregor05e7ca32009-12-06 20:23:50 +0000329
330 reference operator*() const {
331 if (NamedDecl *ND = DeclOrIterator.dyn_cast<NamedDecl *>())
332 return reference(ND, SingleDeclIndex);
333
Douglas Gregor94bb5e82009-12-06 21:27:58 +0000334 return *DeclOrIterator.get<const DeclIndexPair*>();
Douglas Gregor05e7ca32009-12-06 20:23:50 +0000335 }
336
337 pointer operator->() const {
338 return pointer(**this);
339 }
340
341 friend bool operator==(const iterator &X, const iterator &Y) {
Douglas Gregor94bb5e82009-12-06 21:27:58 +0000342 return X.DeclOrIterator.getOpaqueValue()
343 == Y.DeclOrIterator.getOpaqueValue() &&
Douglas Gregor05e7ca32009-12-06 20:23:50 +0000344 X.SingleDeclIndex == Y.SingleDeclIndex;
345 }
346
347 friend bool operator!=(const iterator &X, const iterator &Y) {
Douglas Gregor94bb5e82009-12-06 21:27:58 +0000348 return !(X == Y);
Douglas Gregor05e7ca32009-12-06 20:23:50 +0000349 }
350};
351
Douglas Gregor05e7ca32009-12-06 20:23:50 +0000352ResultBuilder::ShadowMapEntry::iterator
353ResultBuilder::ShadowMapEntry::begin() const {
354 if (DeclOrVector.isNull())
355 return iterator();
356
357 if (NamedDecl *ND = DeclOrVector.dyn_cast<NamedDecl *>())
358 return iterator(ND, SingleDeclIndex);
359
360 return iterator(DeclOrVector.get<DeclIndexPairVector *>()->begin());
361}
362
363ResultBuilder::ShadowMapEntry::iterator
364ResultBuilder::ShadowMapEntry::end() const {
365 if (DeclOrVector.is<NamedDecl *>() || DeclOrVector.isNull())
366 return iterator();
367
368 return iterator(DeclOrVector.get<DeclIndexPairVector *>()->end());
369}
370
Douglas Gregor2af2f672009-09-21 20:12:40 +0000371/// \brief Compute the qualification required to get from the current context
372/// (\p CurContext) to the target context (\p TargetContext).
373///
374/// \param Context the AST context in which the qualification will be used.
375///
376/// \param CurContext the context where an entity is being named, which is
377/// typically based on the current scope.
378///
379/// \param TargetContext the context in which the named entity actually
380/// resides.
381///
382/// \returns a nested name specifier that refers into the target context, or
383/// NULL if no qualification is needed.
384static NestedNameSpecifier *
385getRequiredQualification(ASTContext &Context,
386 DeclContext *CurContext,
387 DeclContext *TargetContext) {
388 llvm::SmallVector<DeclContext *, 4> TargetParents;
389
390 for (DeclContext *CommonAncestor = TargetContext;
391 CommonAncestor && !CommonAncestor->Encloses(CurContext);
392 CommonAncestor = CommonAncestor->getLookupParent()) {
393 if (CommonAncestor->isTransparentContext() ||
394 CommonAncestor->isFunctionOrMethod())
395 continue;
396
397 TargetParents.push_back(CommonAncestor);
398 }
399
400 NestedNameSpecifier *Result = 0;
401 while (!TargetParents.empty()) {
402 DeclContext *Parent = TargetParents.back();
403 TargetParents.pop_back();
404
Douglas Gregor68762e72010-08-23 21:17:50 +0000405 if (NamespaceDecl *Namespace = dyn_cast<NamespaceDecl>(Parent)) {
406 if (!Namespace->getIdentifier())
407 continue;
408
Douglas Gregor2af2f672009-09-21 20:12:40 +0000409 Result = NestedNameSpecifier::Create(Context, Result, Namespace);
Douglas Gregor68762e72010-08-23 21:17:50 +0000410 }
Douglas Gregor2af2f672009-09-21 20:12:40 +0000411 else if (TagDecl *TD = dyn_cast<TagDecl>(Parent))
412 Result = NestedNameSpecifier::Create(Context, Result,
413 false,
414 Context.getTypeDeclType(TD).getTypePtr());
Douglas Gregor9eb77012009-11-07 00:00:49 +0000415 }
Douglas Gregor2af2f672009-09-21 20:12:40 +0000416 return Result;
417}
418
Douglas Gregor6ae4c522010-01-14 03:21:49 +0000419bool ResultBuilder::isInterestingDecl(NamedDecl *ND,
420 bool &AsNestedNameSpecifier) const {
421 AsNestedNameSpecifier = false;
422
Douglas Gregor7c208612010-01-14 00:20:49 +0000423 ND = ND->getUnderlyingDecl();
424 unsigned IDNS = ND->getIdentifierNamespace();
Douglas Gregor58acf322009-10-09 22:16:47 +0000425
426 // Skip unnamed entities.
Douglas Gregor7c208612010-01-14 00:20:49 +0000427 if (!ND->getDeclName())
428 return false;
Douglas Gregor3545ff42009-09-21 16:56:56 +0000429
430 // Friend declarations and declarations introduced due to friends are never
431 // added as results.
John McCallbbbbe4e2010-03-11 07:50:04 +0000432 if (IDNS & (Decl::IDNS_OrdinaryFriend | Decl::IDNS_TagFriend))
Douglas Gregor7c208612010-01-14 00:20:49 +0000433 return false;
434
Douglas Gregor99fe2ad2009-12-11 17:31:05 +0000435 // Class template (partial) specializations are never added as results.
Douglas Gregor7c208612010-01-14 00:20:49 +0000436 if (isa<ClassTemplateSpecializationDecl>(ND) ||
437 isa<ClassTemplatePartialSpecializationDecl>(ND))
438 return false;
Douglas Gregor3545ff42009-09-21 16:56:56 +0000439
Douglas Gregor99fe2ad2009-12-11 17:31:05 +0000440 // Using declarations themselves are never added as results.
Douglas Gregor7c208612010-01-14 00:20:49 +0000441 if (isa<UsingDecl>(ND))
442 return false;
443
444 // Some declarations have reserved names that we don't want to ever show.
445 if (const IdentifierInfo *Id = ND->getIdentifier()) {
Douglas Gregor3545ff42009-09-21 16:56:56 +0000446 // __va_list_tag is a freak of nature. Find it and skip it.
447 if (Id->isStr("__va_list_tag") || Id->isStr("__builtin_va_list"))
Douglas Gregor7c208612010-01-14 00:20:49 +0000448 return false;
Douglas Gregor3545ff42009-09-21 16:56:56 +0000449
Douglas Gregor58acf322009-10-09 22:16:47 +0000450 // Filter out names reserved for the implementation (C99 7.1.3,
Douglas Gregor9f1570d2010-07-14 17:44:04 +0000451 // C++ [lib.global.names]) if they come from a system header.
Daniel Dunbar2c422dc92009-10-18 20:26:12 +0000452 //
453 // FIXME: Add predicate for this.
Douglas Gregor58acf322009-10-09 22:16:47 +0000454 if (Id->getLength() >= 2) {
Daniel Dunbar2c422dc92009-10-18 20:26:12 +0000455 const char *Name = Id->getNameStart();
Douglas Gregor58acf322009-10-09 22:16:47 +0000456 if (Name[0] == '_' &&
Douglas Gregor9f1570d2010-07-14 17:44:04 +0000457 (Name[1] == '_' || (Name[1] >= 'A' && Name[1] <= 'Z')) &&
458 (ND->getLocation().isInvalid() ||
459 SemaRef.SourceMgr.isInSystemHeader(
460 SemaRef.SourceMgr.getSpellingLoc(ND->getLocation()))))
Douglas Gregor7c208612010-01-14 00:20:49 +0000461 return false;
Douglas Gregor58acf322009-10-09 22:16:47 +0000462 }
Douglas Gregor3545ff42009-09-21 16:56:56 +0000463 }
Douglas Gregor7c208612010-01-14 00:20:49 +0000464
Douglas Gregor3545ff42009-09-21 16:56:56 +0000465 // C++ constructors are never found by name lookup.
Douglas Gregor7c208612010-01-14 00:20:49 +0000466 if (isa<CXXConstructorDecl>(ND))
467 return false;
Douglas Gregor3545ff42009-09-21 16:56:56 +0000468
Douglas Gregor59cab552010-08-16 23:05:20 +0000469 if (Filter == &ResultBuilder::IsNestedNameSpecifier ||
470 ((isa<NamespaceDecl>(ND) || isa<NamespaceAliasDecl>(ND)) &&
471 Filter != &ResultBuilder::IsNamespace &&
472 Filter != &ResultBuilder::IsNamespaceOrAlias))
473 AsNestedNameSpecifier = true;
474
Douglas Gregor3545ff42009-09-21 16:56:56 +0000475 // Filter out any unwanted results.
Douglas Gregor6ae4c522010-01-14 03:21:49 +0000476 if (Filter && !(this->*Filter)(ND)) {
477 // Check whether it is interesting as a nested-name-specifier.
478 if (AllowNestedNameSpecifiers && SemaRef.getLangOptions().CPlusPlus &&
479 IsNestedNameSpecifier(ND) &&
480 (Filter != &ResultBuilder::IsMember ||
481 (isa<CXXRecordDecl>(ND) &&
482 cast<CXXRecordDecl>(ND)->isInjectedClassName()))) {
483 AsNestedNameSpecifier = true;
484 return true;
485 }
486
Douglas Gregor7c208612010-01-14 00:20:49 +0000487 return false;
Douglas Gregor59cab552010-08-16 23:05:20 +0000488 }
Douglas Gregor7c208612010-01-14 00:20:49 +0000489 // ... then it must be interesting!
490 return true;
491}
492
Douglas Gregore0717ab2010-01-14 00:41:07 +0000493bool ResultBuilder::CheckHiddenResult(Result &R, DeclContext *CurContext,
494 NamedDecl *Hiding) {
495 // In C, there is no way to refer to a hidden name.
496 // FIXME: This isn't true; we can find a tag name hidden by an ordinary
497 // name if we introduce the tag type.
498 if (!SemaRef.getLangOptions().CPlusPlus)
499 return true;
500
Sebastian Redl50c68252010-08-31 00:36:30 +0000501 DeclContext *HiddenCtx = R.Declaration->getDeclContext()->getRedeclContext();
Douglas Gregore0717ab2010-01-14 00:41:07 +0000502
503 // There is no way to qualify a name declared in a function or method.
504 if (HiddenCtx->isFunctionOrMethod())
505 return true;
506
Sebastian Redl50c68252010-08-31 00:36:30 +0000507 if (HiddenCtx == Hiding->getDeclContext()->getRedeclContext())
Douglas Gregore0717ab2010-01-14 00:41:07 +0000508 return true;
509
510 // We can refer to the result with the appropriate qualification. Do it.
511 R.Hidden = true;
512 R.QualifierIsInformative = false;
513
514 if (!R.Qualifier)
515 R.Qualifier = getRequiredQualification(SemaRef.Context,
516 CurContext,
517 R.Declaration->getDeclContext());
518 return false;
519}
520
Douglas Gregor95887f92010-07-08 23:20:03 +0000521/// \brief A simplified classification of types used to determine whether two
522/// types are "similar enough" when adjusting priorities.
Douglas Gregor6e240332010-08-16 16:18:59 +0000523SimplifiedTypeClass clang::getSimplifiedTypeClass(CanQualType T) {
Douglas Gregor95887f92010-07-08 23:20:03 +0000524 switch (T->getTypeClass()) {
525 case Type::Builtin:
526 switch (cast<BuiltinType>(T)->getKind()) {
527 case BuiltinType::Void:
528 return STC_Void;
529
530 case BuiltinType::NullPtr:
531 return STC_Pointer;
532
533 case BuiltinType::Overload:
534 case BuiltinType::Dependent:
535 case BuiltinType::UndeducedAuto:
536 return STC_Other;
537
538 case BuiltinType::ObjCId:
539 case BuiltinType::ObjCClass:
540 case BuiltinType::ObjCSel:
541 return STC_ObjectiveC;
542
543 default:
544 return STC_Arithmetic;
545 }
546 return STC_Other;
547
548 case Type::Complex:
549 return STC_Arithmetic;
550
551 case Type::Pointer:
552 return STC_Pointer;
553
554 case Type::BlockPointer:
555 return STC_Block;
556
557 case Type::LValueReference:
558 case Type::RValueReference:
559 return getSimplifiedTypeClass(T->getAs<ReferenceType>()->getPointeeType());
560
561 case Type::ConstantArray:
562 case Type::IncompleteArray:
563 case Type::VariableArray:
564 case Type::DependentSizedArray:
565 return STC_Array;
566
567 case Type::DependentSizedExtVector:
568 case Type::Vector:
569 case Type::ExtVector:
570 return STC_Arithmetic;
571
572 case Type::FunctionProto:
573 case Type::FunctionNoProto:
574 return STC_Function;
575
576 case Type::Record:
577 return STC_Record;
578
579 case Type::Enum:
580 return STC_Arithmetic;
581
582 case Type::ObjCObject:
583 case Type::ObjCInterface:
584 case Type::ObjCObjectPointer:
585 return STC_ObjectiveC;
586
587 default:
588 return STC_Other;
589 }
590}
591
592/// \brief Get the type that a given expression will have if this declaration
593/// is used as an expression in its "typical" code-completion form.
Douglas Gregor6e240332010-08-16 16:18:59 +0000594QualType clang::getDeclUsageType(ASTContext &C, NamedDecl *ND) {
Douglas Gregor95887f92010-07-08 23:20:03 +0000595 ND = cast<NamedDecl>(ND->getUnderlyingDecl());
596
597 if (TypeDecl *Type = dyn_cast<TypeDecl>(ND))
598 return C.getTypeDeclType(Type);
599 if (ObjCInterfaceDecl *Iface = dyn_cast<ObjCInterfaceDecl>(ND))
600 return C.getObjCInterfaceType(Iface);
601
602 QualType T;
603 if (FunctionDecl *Function = dyn_cast<FunctionDecl>(ND))
Douglas Gregor603d81b2010-07-13 08:18:22 +0000604 T = Function->getCallResultType();
Douglas Gregor95887f92010-07-08 23:20:03 +0000605 else if (ObjCMethodDecl *Method = dyn_cast<ObjCMethodDecl>(ND))
Douglas Gregor603d81b2010-07-13 08:18:22 +0000606 T = Method->getSendResultType();
Douglas Gregor95887f92010-07-08 23:20:03 +0000607 else if (FunctionTemplateDecl *FunTmpl = dyn_cast<FunctionTemplateDecl>(ND))
Douglas Gregor603d81b2010-07-13 08:18:22 +0000608 T = FunTmpl->getTemplatedDecl()->getCallResultType();
Douglas Gregor95887f92010-07-08 23:20:03 +0000609 else if (EnumConstantDecl *Enumerator = dyn_cast<EnumConstantDecl>(ND))
610 T = C.getTypeDeclType(cast<EnumDecl>(Enumerator->getDeclContext()));
611 else if (ObjCPropertyDecl *Property = dyn_cast<ObjCPropertyDecl>(ND))
612 T = Property->getType();
613 else if (ValueDecl *Value = dyn_cast<ValueDecl>(ND))
614 T = Value->getType();
615 else
616 return QualType();
617
618 return T.getNonReferenceType();
619}
620
621void ResultBuilder::AdjustResultPriorityForPreferredType(Result &R) {
622 QualType T = getDeclUsageType(SemaRef.Context, R.Declaration);
623 if (T.isNull())
624 return;
625
626 CanQualType TC = SemaRef.Context.getCanonicalType(T);
627 // Check for exactly-matching types (modulo qualifiers).
Douglas Gregor4d755e82010-08-24 23:58:17 +0000628 if (SemaRef.Context.hasSameUnqualifiedType(PreferredType, TC)) {
629 if (PreferredType->isVoidType())
630 R.Priority += CCD_VoidMatch;
631 else
632 R.Priority /= CCF_ExactTypeMatch;
633 } // Check for nearly-matching types, based on classification of each.
Douglas Gregor95887f92010-07-08 23:20:03 +0000634 else if ((getSimplifiedTypeClass(PreferredType)
635 == getSimplifiedTypeClass(TC)) &&
636 !(PreferredType->isEnumeralType() && TC->isEnumeralType()))
637 R.Priority /= CCF_SimilarTypeMatch;
638}
639
Douglas Gregor7c208612010-01-14 00:20:49 +0000640void ResultBuilder::MaybeAddResult(Result R, DeclContext *CurContext) {
641 assert(!ShadowMaps.empty() && "Must enter into a results scope");
642
643 if (R.Kind != Result::RK_Declaration) {
644 // For non-declaration results, just add the result.
645 Results.push_back(R);
646 return;
647 }
648
649 // Look through using declarations.
650 if (UsingShadowDecl *Using = dyn_cast<UsingShadowDecl>(R.Declaration)) {
651 MaybeAddResult(Result(Using->getTargetDecl(), R.Qualifier), CurContext);
652 return;
653 }
654
655 Decl *CanonDecl = R.Declaration->getCanonicalDecl();
656 unsigned IDNS = CanonDecl->getIdentifierNamespace();
657
Douglas Gregor6ae4c522010-01-14 03:21:49 +0000658 bool AsNestedNameSpecifier = false;
659 if (!isInterestingDecl(R.Declaration, AsNestedNameSpecifier))
Douglas Gregor7c208612010-01-14 00:20:49 +0000660 return;
661
Douglas Gregor3545ff42009-09-21 16:56:56 +0000662 ShadowMap &SMap = ShadowMaps.back();
Douglas Gregor05e7ca32009-12-06 20:23:50 +0000663 ShadowMapEntry::iterator I, IEnd;
664 ShadowMap::iterator NamePos = SMap.find(R.Declaration->getDeclName());
665 if (NamePos != SMap.end()) {
666 I = NamePos->second.begin();
667 IEnd = NamePos->second.end();
668 }
669
670 for (; I != IEnd; ++I) {
671 NamedDecl *ND = I->first;
672 unsigned Index = I->second;
Douglas Gregor3545ff42009-09-21 16:56:56 +0000673 if (ND->getCanonicalDecl() == CanonDecl) {
674 // This is a redeclaration. Always pick the newer declaration.
Douglas Gregor3545ff42009-09-21 16:56:56 +0000675 Results[Index].Declaration = R.Declaration;
676
Douglas Gregor3545ff42009-09-21 16:56:56 +0000677 // We're done.
678 return;
679 }
680 }
681
682 // This is a new declaration in this scope. However, check whether this
683 // declaration name is hidden by a similarly-named declaration in an outer
684 // scope.
685 std::list<ShadowMap>::iterator SM, SMEnd = ShadowMaps.end();
686 --SMEnd;
687 for (SM = ShadowMaps.begin(); SM != SMEnd; ++SM) {
Douglas Gregor05e7ca32009-12-06 20:23:50 +0000688 ShadowMapEntry::iterator I, IEnd;
689 ShadowMap::iterator NamePos = SM->find(R.Declaration->getDeclName());
690 if (NamePos != SM->end()) {
691 I = NamePos->second.begin();
692 IEnd = NamePos->second.end();
693 }
694 for (; I != IEnd; ++I) {
Douglas Gregor3545ff42009-09-21 16:56:56 +0000695 // A tag declaration does not hide a non-tag declaration.
John McCalle87beb22010-04-23 18:46:30 +0000696 if (I->first->hasTagIdentifierNamespace() &&
Douglas Gregor3545ff42009-09-21 16:56:56 +0000697 (IDNS & (Decl::IDNS_Member | Decl::IDNS_Ordinary |
698 Decl::IDNS_ObjCProtocol)))
699 continue;
700
701 // Protocols are in distinct namespaces from everything else.
Douglas Gregor05e7ca32009-12-06 20:23:50 +0000702 if (((I->first->getIdentifierNamespace() & Decl::IDNS_ObjCProtocol)
Douglas Gregor3545ff42009-09-21 16:56:56 +0000703 || (IDNS & Decl::IDNS_ObjCProtocol)) &&
Douglas Gregor05e7ca32009-12-06 20:23:50 +0000704 I->first->getIdentifierNamespace() != IDNS)
Douglas Gregor3545ff42009-09-21 16:56:56 +0000705 continue;
706
707 // The newly-added result is hidden by an entry in the shadow map.
Douglas Gregore0717ab2010-01-14 00:41:07 +0000708 if (CheckHiddenResult(R, CurContext, I->first))
Douglas Gregor3545ff42009-09-21 16:56:56 +0000709 return;
Douglas Gregor3545ff42009-09-21 16:56:56 +0000710
711 break;
712 }
713 }
714
715 // Make sure that any given declaration only shows up in the result set once.
716 if (!AllDeclsFound.insert(CanonDecl))
717 return;
Douglas Gregorc2cb2e22010-08-27 15:29:55 +0000718
719 // If this is an Objective-C method declaration whose selector matches our
720 // preferred selector, give it a priority boost.
721 if (!PreferredSelector.isNull())
722 if (ObjCMethodDecl *Method = dyn_cast<ObjCMethodDecl>(R.Declaration))
723 if (PreferredSelector == Method->getSelector())
724 R.Priority += CCD_SelectorMatch;
725
Douglas Gregore412a5a2009-09-23 22:26:46 +0000726 // If the filter is for nested-name-specifiers, then this result starts a
727 // nested-name-specifier.
Douglas Gregora2db7932010-05-26 22:00:08 +0000728 if (AsNestedNameSpecifier) {
Douglas Gregore412a5a2009-09-23 22:26:46 +0000729 R.StartsNestedNameSpecifier = true;
Douglas Gregora2db7932010-05-26 22:00:08 +0000730 R.Priority = CCP_NestedNameSpecifier;
Douglas Gregor95887f92010-07-08 23:20:03 +0000731 } else if (!PreferredType.isNull())
732 AdjustResultPriorityForPreferredType(R);
Douglas Gregorc2cb2e22010-08-27 15:29:55 +0000733
Douglas Gregor5bf52692009-09-22 23:15:58 +0000734 // If this result is supposed to have an informative qualifier, add one.
Douglas Gregore412a5a2009-09-23 22:26:46 +0000735 if (R.QualifierIsInformative && !R.Qualifier &&
736 !R.StartsNestedNameSpecifier) {
Douglas Gregor5bf52692009-09-22 23:15:58 +0000737 DeclContext *Ctx = R.Declaration->getDeclContext();
738 if (NamespaceDecl *Namespace = dyn_cast<NamespaceDecl>(Ctx))
739 R.Qualifier = NestedNameSpecifier::Create(SemaRef.Context, 0, Namespace);
740 else if (TagDecl *Tag = dyn_cast<TagDecl>(Ctx))
741 R.Qualifier = NestedNameSpecifier::Create(SemaRef.Context, 0, false,
742 SemaRef.Context.getTypeDeclType(Tag).getTypePtr());
743 else
744 R.QualifierIsInformative = false;
745 }
Douglas Gregore412a5a2009-09-23 22:26:46 +0000746
Douglas Gregor3545ff42009-09-21 16:56:56 +0000747 // Insert this result into the set of results and into the current shadow
748 // map.
Douglas Gregor05e7ca32009-12-06 20:23:50 +0000749 SMap[R.Declaration->getDeclName()].Add(R.Declaration, Results.size());
Douglas Gregor3545ff42009-09-21 16:56:56 +0000750 Results.push_back(R);
751}
752
Douglas Gregorc580c522010-01-14 01:09:38 +0000753void ResultBuilder::AddResult(Result R, DeclContext *CurContext,
Douglas Gregor09bbc652010-01-14 15:47:35 +0000754 NamedDecl *Hiding, bool InBaseClass = false) {
Douglas Gregor78a21012010-01-14 16:01:26 +0000755 if (R.Kind != Result::RK_Declaration) {
756 // For non-declaration results, just add the result.
757 Results.push_back(R);
758 return;
759 }
760
Douglas Gregorc580c522010-01-14 01:09:38 +0000761 // Look through using declarations.
762 if (UsingShadowDecl *Using = dyn_cast<UsingShadowDecl>(R.Declaration)) {
763 AddResult(Result(Using->getTargetDecl(), R.Qualifier), CurContext, Hiding);
764 return;
765 }
766
Douglas Gregor6ae4c522010-01-14 03:21:49 +0000767 bool AsNestedNameSpecifier = false;
768 if (!isInterestingDecl(R.Declaration, AsNestedNameSpecifier))
Douglas Gregorc580c522010-01-14 01:09:38 +0000769 return;
770
771 if (Hiding && CheckHiddenResult(R, CurContext, Hiding))
772 return;
773
774 // Make sure that any given declaration only shows up in the result set once.
775 if (!AllDeclsFound.insert(R.Declaration->getCanonicalDecl()))
776 return;
777
778 // If the filter is for nested-name-specifiers, then this result starts a
779 // nested-name-specifier.
Douglas Gregora2db7932010-05-26 22:00:08 +0000780 if (AsNestedNameSpecifier) {
Douglas Gregorc580c522010-01-14 01:09:38 +0000781 R.StartsNestedNameSpecifier = true;
Douglas Gregora2db7932010-05-26 22:00:08 +0000782 R.Priority = CCP_NestedNameSpecifier;
783 }
Douglas Gregor09bbc652010-01-14 15:47:35 +0000784 else if (Filter == &ResultBuilder::IsMember && !R.Qualifier && InBaseClass &&
785 isa<CXXRecordDecl>(R.Declaration->getDeclContext()
Sebastian Redl50c68252010-08-31 00:36:30 +0000786 ->getRedeclContext()))
Douglas Gregor09bbc652010-01-14 15:47:35 +0000787 R.QualifierIsInformative = true;
788
Douglas Gregorc580c522010-01-14 01:09:38 +0000789 // If this result is supposed to have an informative qualifier, add one.
790 if (R.QualifierIsInformative && !R.Qualifier &&
791 !R.StartsNestedNameSpecifier) {
792 DeclContext *Ctx = R.Declaration->getDeclContext();
793 if (NamespaceDecl *Namespace = dyn_cast<NamespaceDecl>(Ctx))
794 R.Qualifier = NestedNameSpecifier::Create(SemaRef.Context, 0, Namespace);
795 else if (TagDecl *Tag = dyn_cast<TagDecl>(Ctx))
796 R.Qualifier = NestedNameSpecifier::Create(SemaRef.Context, 0, false,
Douglas Gregor6ae4c522010-01-14 03:21:49 +0000797 SemaRef.Context.getTypeDeclType(Tag).getTypePtr());
Douglas Gregorc580c522010-01-14 01:09:38 +0000798 else
799 R.QualifierIsInformative = false;
800 }
801
Douglas Gregora2db7932010-05-26 22:00:08 +0000802 // Adjust the priority if this result comes from a base class.
803 if (InBaseClass)
804 R.Priority += CCD_InBaseClass;
805
Douglas Gregorc2cb2e22010-08-27 15:29:55 +0000806 // If this is an Objective-C method declaration whose selector matches our
807 // preferred selector, give it a priority boost.
808 if (!PreferredSelector.isNull())
809 if (ObjCMethodDecl *Method = dyn_cast<ObjCMethodDecl>(R.Declaration))
810 if (PreferredSelector == Method->getSelector())
811 R.Priority += CCD_SelectorMatch;
812
Douglas Gregor95887f92010-07-08 23:20:03 +0000813 if (!PreferredType.isNull())
814 AdjustResultPriorityForPreferredType(R);
Douglas Gregor7aa6b222010-05-30 01:49:25 +0000815
Douglas Gregor9be0ed42010-08-26 16:36:48 +0000816 if (HasObjectTypeQualifiers)
817 if (CXXMethodDecl *Method = dyn_cast<CXXMethodDecl>(R.Declaration))
818 if (Method->isInstance()) {
819 Qualifiers MethodQuals
820 = Qualifiers::fromCVRMask(Method->getTypeQualifiers());
821 if (ObjectTypeQualifiers == MethodQuals)
822 R.Priority += CCD_ObjectQualifierMatch;
823 else if (ObjectTypeQualifiers - MethodQuals) {
824 // The method cannot be invoked, because doing so would drop
825 // qualifiers.
826 return;
827 }
828 }
829
Douglas Gregorc580c522010-01-14 01:09:38 +0000830 // Insert this result into the set of results.
831 Results.push_back(R);
832}
833
Douglas Gregor78a21012010-01-14 16:01:26 +0000834void ResultBuilder::AddResult(Result R) {
835 assert(R.Kind != Result::RK_Declaration &&
836 "Declaration results need more context");
837 Results.push_back(R);
838}
839
Douglas Gregor3545ff42009-09-21 16:56:56 +0000840/// \brief Enter into a new scope.
841void ResultBuilder::EnterNewScope() {
842 ShadowMaps.push_back(ShadowMap());
843}
844
845/// \brief Exit from the current scope.
846void ResultBuilder::ExitScope() {
Douglas Gregor05e7ca32009-12-06 20:23:50 +0000847 for (ShadowMap::iterator E = ShadowMaps.back().begin(),
848 EEnd = ShadowMaps.back().end();
849 E != EEnd;
850 ++E)
851 E->second.Destroy();
852
Douglas Gregor3545ff42009-09-21 16:56:56 +0000853 ShadowMaps.pop_back();
854}
855
Douglas Gregor9d64c5e2009-09-21 20:51:25 +0000856/// \brief Determines whether this given declaration will be found by
857/// ordinary name lookup.
858bool ResultBuilder::IsOrdinaryName(NamedDecl *ND) const {
Douglas Gregor70febae2010-05-28 00:49:12 +0000859 ND = cast<NamedDecl>(ND->getUnderlyingDecl());
860
Douglas Gregor9d64c5e2009-09-21 20:51:25 +0000861 unsigned IDNS = Decl::IDNS_Ordinary;
862 if (SemaRef.getLangOptions().CPlusPlus)
Douglas Gregor9858ed52010-06-15 20:26:51 +0000863 IDNS |= Decl::IDNS_Tag | Decl::IDNS_Namespace | Decl::IDNS_Member;
Douglas Gregorc580c522010-01-14 01:09:38 +0000864 else if (SemaRef.getLangOptions().ObjC1 && isa<ObjCIvarDecl>(ND))
865 return true;
866
Douglas Gregor9d64c5e2009-09-21 20:51:25 +0000867 return ND->getIdentifierNamespace() & IDNS;
868}
869
Douglas Gregor504a6ae2010-01-10 23:08:15 +0000870/// \brief Determines whether this given declaration will be found by
Douglas Gregor70febae2010-05-28 00:49:12 +0000871/// ordinary name lookup but is not a type name.
872bool ResultBuilder::IsOrdinaryNonTypeName(NamedDecl *ND) const {
873 ND = cast<NamedDecl>(ND->getUnderlyingDecl());
874 if (isa<TypeDecl>(ND) || isa<ObjCInterfaceDecl>(ND))
875 return false;
876
877 unsigned IDNS = Decl::IDNS_Ordinary;
878 if (SemaRef.getLangOptions().CPlusPlus)
Douglas Gregor9858ed52010-06-15 20:26:51 +0000879 IDNS |= Decl::IDNS_Tag | Decl::IDNS_Namespace | Decl::IDNS_Member;
Douglas Gregor70febae2010-05-28 00:49:12 +0000880 else if (SemaRef.getLangOptions().ObjC1 && isa<ObjCIvarDecl>(ND))
881 return true;
882
883 return ND->getIdentifierNamespace() & IDNS;
884}
885
Douglas Gregor85b50632010-07-28 21:50:18 +0000886bool ResultBuilder::IsIntegralConstantValue(NamedDecl *ND) const {
887 if (!IsOrdinaryNonTypeName(ND))
888 return 0;
889
890 if (ValueDecl *VD = dyn_cast<ValueDecl>(ND->getUnderlyingDecl()))
891 if (VD->getType()->isIntegralOrEnumerationType())
892 return true;
893
894 return false;
895}
896
Douglas Gregor70febae2010-05-28 00:49:12 +0000897/// \brief Determines whether this given declaration will be found by
Douglas Gregor504a6ae2010-01-10 23:08:15 +0000898/// ordinary name lookup.
899bool ResultBuilder::IsOrdinaryNonValueName(NamedDecl *ND) const {
Douglas Gregor70febae2010-05-28 00:49:12 +0000900 ND = cast<NamedDecl>(ND->getUnderlyingDecl());
901
Douglas Gregor504a6ae2010-01-10 23:08:15 +0000902 unsigned IDNS = Decl::IDNS_Ordinary;
903 if (SemaRef.getLangOptions().CPlusPlus)
John McCalle87beb22010-04-23 18:46:30 +0000904 IDNS |= Decl::IDNS_Tag | Decl::IDNS_Namespace;
Douglas Gregor504a6ae2010-01-10 23:08:15 +0000905
906 return (ND->getIdentifierNamespace() & IDNS) &&
Douglas Gregor70febae2010-05-28 00:49:12 +0000907 !isa<ValueDecl>(ND) && !isa<FunctionTemplateDecl>(ND) &&
908 !isa<ObjCPropertyDecl>(ND);
Douglas Gregor504a6ae2010-01-10 23:08:15 +0000909}
910
Douglas Gregor3545ff42009-09-21 16:56:56 +0000911/// \brief Determines whether the given declaration is suitable as the
912/// start of a C++ nested-name-specifier, e.g., a class or namespace.
913bool ResultBuilder::IsNestedNameSpecifier(NamedDecl *ND) const {
914 // Allow us to find class templates, too.
915 if (ClassTemplateDecl *ClassTemplate = dyn_cast<ClassTemplateDecl>(ND))
916 ND = ClassTemplate->getTemplatedDecl();
917
918 return SemaRef.isAcceptableNestedNameSpecifier(ND);
919}
920
921/// \brief Determines whether the given declaration is an enumeration.
922bool ResultBuilder::IsEnum(NamedDecl *ND) const {
923 return isa<EnumDecl>(ND);
924}
925
926/// \brief Determines whether the given declaration is a class or struct.
927bool ResultBuilder::IsClassOrStruct(NamedDecl *ND) const {
928 // Allow us to find class templates, too.
929 if (ClassTemplateDecl *ClassTemplate = dyn_cast<ClassTemplateDecl>(ND))
930 ND = ClassTemplate->getTemplatedDecl();
931
932 if (RecordDecl *RD = dyn_cast<RecordDecl>(ND))
Abramo Bagnara6150c882010-05-11 21:36:43 +0000933 return RD->getTagKind() == TTK_Class ||
934 RD->getTagKind() == TTK_Struct;
Douglas Gregor3545ff42009-09-21 16:56:56 +0000935
936 return false;
937}
938
939/// \brief Determines whether the given declaration is a union.
940bool ResultBuilder::IsUnion(NamedDecl *ND) const {
941 // Allow us to find class templates, too.
942 if (ClassTemplateDecl *ClassTemplate = dyn_cast<ClassTemplateDecl>(ND))
943 ND = ClassTemplate->getTemplatedDecl();
944
945 if (RecordDecl *RD = dyn_cast<RecordDecl>(ND))
Abramo Bagnara6150c882010-05-11 21:36:43 +0000946 return RD->getTagKind() == TTK_Union;
Douglas Gregor3545ff42009-09-21 16:56:56 +0000947
948 return false;
949}
950
951/// \brief Determines whether the given declaration is a namespace.
952bool ResultBuilder::IsNamespace(NamedDecl *ND) const {
953 return isa<NamespaceDecl>(ND);
954}
955
956/// \brief Determines whether the given declaration is a namespace or
957/// namespace alias.
958bool ResultBuilder::IsNamespaceOrAlias(NamedDecl *ND) const {
959 return isa<NamespaceDecl>(ND) || isa<NamespaceAliasDecl>(ND);
960}
961
Douglas Gregor99fe2ad2009-12-11 17:31:05 +0000962/// \brief Determines whether the given declaration is a type.
Douglas Gregor3545ff42009-09-21 16:56:56 +0000963bool ResultBuilder::IsType(NamedDecl *ND) const {
Douglas Gregor99fa2642010-08-24 01:06:58 +0000964 if (UsingShadowDecl *Using = dyn_cast<UsingShadowDecl>(ND))
965 ND = Using->getTargetDecl();
966
967 return isa<TypeDecl>(ND) || isa<ObjCInterfaceDecl>(ND);
Douglas Gregor3545ff42009-09-21 16:56:56 +0000968}
969
Douglas Gregor99fe2ad2009-12-11 17:31:05 +0000970/// \brief Determines which members of a class should be visible via
971/// "." or "->". Only value declarations, nested name specifiers, and
972/// using declarations thereof should show up.
Douglas Gregore412a5a2009-09-23 22:26:46 +0000973bool ResultBuilder::IsMember(NamedDecl *ND) const {
Douglas Gregor99fe2ad2009-12-11 17:31:05 +0000974 if (UsingShadowDecl *Using = dyn_cast<UsingShadowDecl>(ND))
975 ND = Using->getTargetDecl();
976
Douglas Gregor70788392009-12-11 18:14:22 +0000977 return isa<ValueDecl>(ND) || isa<FunctionTemplateDecl>(ND) ||
978 isa<ObjCPropertyDecl>(ND);
Douglas Gregore412a5a2009-09-23 22:26:46 +0000979}
980
Douglas Gregora817a192010-05-27 23:06:34 +0000981static bool isObjCReceiverType(ASTContext &C, QualType T) {
982 T = C.getCanonicalType(T);
983 switch (T->getTypeClass()) {
984 case Type::ObjCObject:
985 case Type::ObjCInterface:
986 case Type::ObjCObjectPointer:
987 return true;
988
989 case Type::Builtin:
990 switch (cast<BuiltinType>(T)->getKind()) {
991 case BuiltinType::ObjCId:
992 case BuiltinType::ObjCClass:
993 case BuiltinType::ObjCSel:
994 return true;
995
996 default:
997 break;
998 }
999 return false;
1000
1001 default:
1002 break;
1003 }
1004
1005 if (!C.getLangOptions().CPlusPlus)
1006 return false;
1007
1008 // FIXME: We could perform more analysis here to determine whether a
1009 // particular class type has any conversions to Objective-C types. For now,
1010 // just accept all class types.
1011 return T->isDependentType() || T->isRecordType();
1012}
1013
1014bool ResultBuilder::IsObjCMessageReceiver(NamedDecl *ND) const {
1015 QualType T = getDeclUsageType(SemaRef.Context, ND);
1016 if (T.isNull())
1017 return false;
1018
1019 T = SemaRef.Context.getBaseElementType(T);
1020 return isObjCReceiverType(SemaRef.Context, T);
1021}
1022
Douglas Gregor68762e72010-08-23 21:17:50 +00001023bool ResultBuilder::IsObjCCollection(NamedDecl *ND) const {
1024 if ((SemaRef.getLangOptions().CPlusPlus && !IsOrdinaryName(ND)) ||
1025 (!SemaRef.getLangOptions().CPlusPlus && !IsOrdinaryNonTypeName(ND)))
1026 return false;
1027
1028 QualType T = getDeclUsageType(SemaRef.Context, ND);
1029 if (T.isNull())
1030 return false;
1031
1032 T = SemaRef.Context.getBaseElementType(T);
1033 return T->isObjCObjectType() || T->isObjCObjectPointerType() ||
1034 T->isObjCIdType() ||
1035 (SemaRef.getLangOptions().CPlusPlus && T->isRecordType());
1036}
Douglas Gregora817a192010-05-27 23:06:34 +00001037
Douglas Gregor2b8162b2010-01-14 16:08:12 +00001038/// \rief Determines whether the given declaration is an Objective-C
1039/// instance variable.
1040bool ResultBuilder::IsObjCIvar(NamedDecl *ND) const {
1041 return isa<ObjCIvarDecl>(ND);
1042}
1043
Douglas Gregorc580c522010-01-14 01:09:38 +00001044namespace {
1045 /// \brief Visible declaration consumer that adds a code-completion result
1046 /// for each visible declaration.
1047 class CodeCompletionDeclConsumer : public VisibleDeclConsumer {
1048 ResultBuilder &Results;
1049 DeclContext *CurContext;
1050
1051 public:
1052 CodeCompletionDeclConsumer(ResultBuilder &Results, DeclContext *CurContext)
1053 : Results(Results), CurContext(CurContext) { }
1054
Douglas Gregor09bbc652010-01-14 15:47:35 +00001055 virtual void FoundDecl(NamedDecl *ND, NamedDecl *Hiding, bool InBaseClass) {
1056 Results.AddResult(ND, CurContext, Hiding, InBaseClass);
Douglas Gregorc580c522010-01-14 01:09:38 +00001057 }
1058 };
1059}
1060
Douglas Gregor3545ff42009-09-21 16:56:56 +00001061/// \brief Add type specifiers for the current language as keyword results.
Douglas Gregorf98e6a22010-01-13 23:51:12 +00001062static void AddTypeSpecifierResults(const LangOptions &LangOpts,
Douglas Gregor3545ff42009-09-21 16:56:56 +00001063 ResultBuilder &Results) {
John McCall276321a2010-08-25 06:19:51 +00001064 typedef CodeCompletionResult Result;
Douglas Gregora2db7932010-05-26 22:00:08 +00001065 Results.AddResult(Result("short", CCP_Type));
1066 Results.AddResult(Result("long", CCP_Type));
1067 Results.AddResult(Result("signed", CCP_Type));
1068 Results.AddResult(Result("unsigned", CCP_Type));
1069 Results.AddResult(Result("void", CCP_Type));
1070 Results.AddResult(Result("char", CCP_Type));
1071 Results.AddResult(Result("int", CCP_Type));
1072 Results.AddResult(Result("float", CCP_Type));
1073 Results.AddResult(Result("double", CCP_Type));
1074 Results.AddResult(Result("enum", CCP_Type));
1075 Results.AddResult(Result("struct", CCP_Type));
1076 Results.AddResult(Result("union", CCP_Type));
1077 Results.AddResult(Result("const", CCP_Type));
1078 Results.AddResult(Result("volatile", CCP_Type));
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001079
Douglas Gregor3545ff42009-09-21 16:56:56 +00001080 if (LangOpts.C99) {
1081 // C99-specific
Douglas Gregora2db7932010-05-26 22:00:08 +00001082 Results.AddResult(Result("_Complex", CCP_Type));
1083 Results.AddResult(Result("_Imaginary", CCP_Type));
1084 Results.AddResult(Result("_Bool", CCP_Type));
1085 Results.AddResult(Result("restrict", CCP_Type));
Douglas Gregor3545ff42009-09-21 16:56:56 +00001086 }
1087
1088 if (LangOpts.CPlusPlus) {
1089 // C++-specific
Douglas Gregora2db7932010-05-26 22:00:08 +00001090 Results.AddResult(Result("bool", CCP_Type));
1091 Results.AddResult(Result("class", CCP_Type));
1092 Results.AddResult(Result("wchar_t", CCP_Type));
Douglas Gregor3545ff42009-09-21 16:56:56 +00001093
Douglas Gregorf4c33342010-05-28 00:22:41 +00001094 // typename qualified-id
1095 CodeCompletionString *Pattern = new CodeCompletionString;
1096 Pattern->AddTypedTextChunk("typename");
1097 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
1098 Pattern->AddPlaceholderChunk("qualifier");
1099 Pattern->AddTextChunk("::");
1100 Pattern->AddPlaceholderChunk("name");
1101 Results.AddResult(Result(Pattern));
Douglas Gregorf64acca2010-05-25 21:41:55 +00001102
Douglas Gregor3545ff42009-09-21 16:56:56 +00001103 if (LangOpts.CPlusPlus0x) {
Douglas Gregora2db7932010-05-26 22:00:08 +00001104 Results.AddResult(Result("auto", CCP_Type));
1105 Results.AddResult(Result("char16_t", CCP_Type));
1106 Results.AddResult(Result("char32_t", CCP_Type));
Douglas Gregorf4c33342010-05-28 00:22:41 +00001107
1108 CodeCompletionString *Pattern = new CodeCompletionString;
1109 Pattern->AddTypedTextChunk("decltype");
1110 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
1111 Pattern->AddPlaceholderChunk("expression");
1112 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
1113 Results.AddResult(Result(Pattern));
Douglas Gregor3545ff42009-09-21 16:56:56 +00001114 }
1115 }
1116
1117 // GNU extensions
1118 if (LangOpts.GNUMode) {
1119 // FIXME: Enable when we actually support decimal floating point.
Douglas Gregor78a21012010-01-14 16:01:26 +00001120 // Results.AddResult(Result("_Decimal32"));
1121 // Results.AddResult(Result("_Decimal64"));
1122 // Results.AddResult(Result("_Decimal128"));
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001123
Douglas Gregorf4c33342010-05-28 00:22:41 +00001124 CodeCompletionString *Pattern = new CodeCompletionString;
1125 Pattern->AddTypedTextChunk("typeof");
1126 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
1127 Pattern->AddPlaceholderChunk("expression");
1128 Results.AddResult(Result(Pattern));
1129
1130 Pattern = new CodeCompletionString;
1131 Pattern->AddTypedTextChunk("typeof");
1132 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
1133 Pattern->AddPlaceholderChunk("type");
1134 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
1135 Results.AddResult(Result(Pattern));
Douglas Gregor3545ff42009-09-21 16:56:56 +00001136 }
1137}
1138
John McCallfaf5fb42010-08-26 23:41:50 +00001139static void AddStorageSpecifiers(Sema::ParserCompletionContext CCC,
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001140 const LangOptions &LangOpts,
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001141 ResultBuilder &Results) {
John McCall276321a2010-08-25 06:19:51 +00001142 typedef CodeCompletionResult Result;
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001143 // Note: we don't suggest either "auto" or "register", because both
1144 // are pointless as storage specifiers. Elsewhere, we suggest "auto"
1145 // in C++0x as a type specifier.
Douglas Gregor78a21012010-01-14 16:01:26 +00001146 Results.AddResult(Result("extern"));
1147 Results.AddResult(Result("static"));
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001148}
1149
John McCallfaf5fb42010-08-26 23:41:50 +00001150static void AddFunctionSpecifiers(Sema::ParserCompletionContext CCC,
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001151 const LangOptions &LangOpts,
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001152 ResultBuilder &Results) {
John McCall276321a2010-08-25 06:19:51 +00001153 typedef CodeCompletionResult Result;
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001154 switch (CCC) {
John McCallfaf5fb42010-08-26 23:41:50 +00001155 case Sema::PCC_Class:
1156 case Sema::PCC_MemberTemplate:
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001157 if (LangOpts.CPlusPlus) {
Douglas Gregor78a21012010-01-14 16:01:26 +00001158 Results.AddResult(Result("explicit"));
1159 Results.AddResult(Result("friend"));
1160 Results.AddResult(Result("mutable"));
1161 Results.AddResult(Result("virtual"));
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001162 }
1163 // Fall through
1164
John McCallfaf5fb42010-08-26 23:41:50 +00001165 case Sema::PCC_ObjCInterface:
1166 case Sema::PCC_ObjCImplementation:
1167 case Sema::PCC_Namespace:
1168 case Sema::PCC_Template:
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001169 if (LangOpts.CPlusPlus || LangOpts.C99)
Douglas Gregor78a21012010-01-14 16:01:26 +00001170 Results.AddResult(Result("inline"));
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001171 break;
1172
John McCallfaf5fb42010-08-26 23:41:50 +00001173 case Sema::PCC_ObjCInstanceVariableList:
1174 case Sema::PCC_Expression:
1175 case Sema::PCC_Statement:
1176 case Sema::PCC_ForInit:
1177 case Sema::PCC_Condition:
1178 case Sema::PCC_RecoveryInFunction:
1179 case Sema::PCC_Type:
Douglas Gregor5e35d592010-09-14 23:59:36 +00001180 case Sema::PCC_ParenthesizedExpression:
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001181 break;
1182 }
1183}
1184
Douglas Gregorf98e6a22010-01-13 23:51:12 +00001185static void AddObjCExpressionResults(ResultBuilder &Results, bool NeedAt);
1186static void AddObjCStatementResults(ResultBuilder &Results, bool NeedAt);
1187static void AddObjCVisibilityResults(const LangOptions &LangOpts,
Douglas Gregor48d46252010-01-13 21:54:15 +00001188 ResultBuilder &Results,
1189 bool NeedAt);
Douglas Gregorf98e6a22010-01-13 23:51:12 +00001190static void AddObjCImplementationResults(const LangOptions &LangOpts,
Douglas Gregorf1934162010-01-13 21:24:21 +00001191 ResultBuilder &Results,
1192 bool NeedAt);
Douglas Gregorf98e6a22010-01-13 23:51:12 +00001193static void AddObjCInterfaceResults(const LangOptions &LangOpts,
Douglas Gregorf1934162010-01-13 21:24:21 +00001194 ResultBuilder &Results,
1195 bool NeedAt);
Douglas Gregorf98e6a22010-01-13 23:51:12 +00001196static void AddObjCTopLevelResults(ResultBuilder &Results, bool NeedAt);
Douglas Gregorf1934162010-01-13 21:24:21 +00001197
Douglas Gregorf4c33342010-05-28 00:22:41 +00001198static void AddTypedefResult(ResultBuilder &Results) {
1199 CodeCompletionString *Pattern = new CodeCompletionString;
1200 Pattern->AddTypedTextChunk("typedef");
1201 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
1202 Pattern->AddPlaceholderChunk("type");
1203 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
1204 Pattern->AddPlaceholderChunk("name");
John McCall276321a2010-08-25 06:19:51 +00001205 Results.AddResult(CodeCompletionResult(Pattern));
Douglas Gregorf4c33342010-05-28 00:22:41 +00001206}
1207
John McCallfaf5fb42010-08-26 23:41:50 +00001208static bool WantTypesInContext(Sema::ParserCompletionContext CCC,
Douglas Gregor70febae2010-05-28 00:49:12 +00001209 const LangOptions &LangOpts) {
Douglas Gregor70febae2010-05-28 00:49:12 +00001210 switch (CCC) {
John McCallfaf5fb42010-08-26 23:41:50 +00001211 case Sema::PCC_Namespace:
1212 case Sema::PCC_Class:
1213 case Sema::PCC_ObjCInstanceVariableList:
1214 case Sema::PCC_Template:
1215 case Sema::PCC_MemberTemplate:
1216 case Sema::PCC_Statement:
1217 case Sema::PCC_RecoveryInFunction:
1218 case Sema::PCC_Type:
Douglas Gregor5e35d592010-09-14 23:59:36 +00001219 case Sema::PCC_ParenthesizedExpression:
Douglas Gregor70febae2010-05-28 00:49:12 +00001220 return true;
1221
John McCallfaf5fb42010-08-26 23:41:50 +00001222 case Sema::PCC_Expression:
1223 case Sema::PCC_Condition:
Douglas Gregor5e35d592010-09-14 23:59:36 +00001224 return LangOpts.CPlusPlus;
1225
1226 case Sema::PCC_ObjCInterface:
1227 case Sema::PCC_ObjCImplementation:
Douglas Gregor70febae2010-05-28 00:49:12 +00001228 return false;
1229
John McCallfaf5fb42010-08-26 23:41:50 +00001230 case Sema::PCC_ForInit:
Douglas Gregor5e35d592010-09-14 23:59:36 +00001231 return LangOpts.CPlusPlus || LangOpts.ObjC1 || LangOpts.C99;
Douglas Gregor70febae2010-05-28 00:49:12 +00001232 }
1233
1234 return false;
1235}
1236
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001237/// \brief Add language constructs that show up for "ordinary" names.
John McCallfaf5fb42010-08-26 23:41:50 +00001238static void AddOrdinaryNameResults(Sema::ParserCompletionContext CCC,
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001239 Scope *S,
1240 Sema &SemaRef,
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001241 ResultBuilder &Results) {
John McCall276321a2010-08-25 06:19:51 +00001242 typedef CodeCompletionResult Result;
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001243 switch (CCC) {
John McCallfaf5fb42010-08-26 23:41:50 +00001244 case Sema::PCC_Namespace:
Douglas Gregorf4c33342010-05-28 00:22:41 +00001245 if (SemaRef.getLangOptions().CPlusPlus) {
1246 CodeCompletionString *Pattern = 0;
1247
1248 if (Results.includeCodePatterns()) {
1249 // namespace <identifier> { declarations }
1250 CodeCompletionString *Pattern = new CodeCompletionString;
1251 Pattern->AddTypedTextChunk("namespace");
1252 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
1253 Pattern->AddPlaceholderChunk("identifier");
1254 Pattern->AddChunk(CodeCompletionString::CK_LeftBrace);
1255 Pattern->AddPlaceholderChunk("declarations");
1256 Pattern->AddChunk(CodeCompletionString::CK_VerticalSpace);
1257 Pattern->AddChunk(CodeCompletionString::CK_RightBrace);
1258 Results.AddResult(Result(Pattern));
1259 }
1260
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001261 // namespace identifier = identifier ;
1262 Pattern = new CodeCompletionString;
1263 Pattern->AddTypedTextChunk("namespace");
1264 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
Douglas Gregorf4c33342010-05-28 00:22:41 +00001265 Pattern->AddPlaceholderChunk("name");
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001266 Pattern->AddChunk(CodeCompletionString::CK_Equal);
Douglas Gregorf4c33342010-05-28 00:22:41 +00001267 Pattern->AddPlaceholderChunk("namespace");
Douglas Gregor78a21012010-01-14 16:01:26 +00001268 Results.AddResult(Result(Pattern));
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001269
1270 // Using directives
1271 Pattern = new CodeCompletionString;
1272 Pattern->AddTypedTextChunk("using");
1273 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
1274 Pattern->AddTextChunk("namespace");
1275 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
1276 Pattern->AddPlaceholderChunk("identifier");
Douglas Gregor78a21012010-01-14 16:01:26 +00001277 Results.AddResult(Result(Pattern));
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001278
1279 // asm(string-literal)
1280 Pattern = new CodeCompletionString;
1281 Pattern->AddTypedTextChunk("asm");
1282 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
1283 Pattern->AddPlaceholderChunk("string-literal");
1284 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
Douglas Gregor78a21012010-01-14 16:01:26 +00001285 Results.AddResult(Result(Pattern));
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001286
Douglas Gregorf4c33342010-05-28 00:22:41 +00001287 if (Results.includeCodePatterns()) {
1288 // Explicit template instantiation
1289 Pattern = new CodeCompletionString;
1290 Pattern->AddTypedTextChunk("template");
1291 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
1292 Pattern->AddPlaceholderChunk("declaration");
1293 Results.AddResult(Result(Pattern));
1294 }
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001295 }
Douglas Gregorf1934162010-01-13 21:24:21 +00001296
1297 if (SemaRef.getLangOptions().ObjC1)
Douglas Gregorf98e6a22010-01-13 23:51:12 +00001298 AddObjCTopLevelResults(Results, true);
Douglas Gregorf1934162010-01-13 21:24:21 +00001299
Douglas Gregorf4c33342010-05-28 00:22:41 +00001300 AddTypedefResult(Results);
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001301 // Fall through
1302
John McCallfaf5fb42010-08-26 23:41:50 +00001303 case Sema::PCC_Class:
Douglas Gregorf4c33342010-05-28 00:22:41 +00001304 if (SemaRef.getLangOptions().CPlusPlus) {
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001305 // Using declaration
1306 CodeCompletionString *Pattern = new CodeCompletionString;
1307 Pattern->AddTypedTextChunk("using");
1308 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
Douglas Gregorf4c33342010-05-28 00:22:41 +00001309 Pattern->AddPlaceholderChunk("qualifier");
1310 Pattern->AddTextChunk("::");
1311 Pattern->AddPlaceholderChunk("name");
Douglas Gregor78a21012010-01-14 16:01:26 +00001312 Results.AddResult(Result(Pattern));
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001313
Douglas Gregorf4c33342010-05-28 00:22:41 +00001314 // using typename qualifier::name (only in a dependent context)
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001315 if (SemaRef.CurContext->isDependentContext()) {
1316 Pattern = new CodeCompletionString;
1317 Pattern->AddTypedTextChunk("using");
1318 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
1319 Pattern->AddTextChunk("typename");
1320 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
Douglas Gregorf4c33342010-05-28 00:22:41 +00001321 Pattern->AddPlaceholderChunk("qualifier");
1322 Pattern->AddTextChunk("::");
1323 Pattern->AddPlaceholderChunk("name");
Douglas Gregor78a21012010-01-14 16:01:26 +00001324 Results.AddResult(Result(Pattern));
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001325 }
1326
John McCallfaf5fb42010-08-26 23:41:50 +00001327 if (CCC == Sema::PCC_Class) {
Douglas Gregorf4c33342010-05-28 00:22:41 +00001328 AddTypedefResult(Results);
1329
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001330 // public:
1331 Pattern = new CodeCompletionString;
1332 Pattern->AddTypedTextChunk("public");
1333 Pattern->AddChunk(CodeCompletionString::CK_Colon);
Douglas Gregor78a21012010-01-14 16:01:26 +00001334 Results.AddResult(Result(Pattern));
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001335
1336 // protected:
1337 Pattern = new CodeCompletionString;
1338 Pattern->AddTypedTextChunk("protected");
1339 Pattern->AddChunk(CodeCompletionString::CK_Colon);
Douglas Gregor78a21012010-01-14 16:01:26 +00001340 Results.AddResult(Result(Pattern));
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001341
1342 // private:
1343 Pattern = new CodeCompletionString;
1344 Pattern->AddTypedTextChunk("private");
1345 Pattern->AddChunk(CodeCompletionString::CK_Colon);
Douglas Gregor78a21012010-01-14 16:01:26 +00001346 Results.AddResult(Result(Pattern));
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001347 }
1348 }
1349 // Fall through
1350
John McCallfaf5fb42010-08-26 23:41:50 +00001351 case Sema::PCC_Template:
1352 case Sema::PCC_MemberTemplate:
Douglas Gregorf64acca2010-05-25 21:41:55 +00001353 if (SemaRef.getLangOptions().CPlusPlus && Results.includeCodePatterns()) {
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001354 // template < parameters >
1355 CodeCompletionString *Pattern = new CodeCompletionString;
1356 Pattern->AddTypedTextChunk("template");
1357 Pattern->AddChunk(CodeCompletionString::CK_LeftAngle);
1358 Pattern->AddPlaceholderChunk("parameters");
1359 Pattern->AddChunk(CodeCompletionString::CK_RightAngle);
Douglas Gregor78a21012010-01-14 16:01:26 +00001360 Results.AddResult(Result(Pattern));
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001361 }
1362
Douglas Gregorf98e6a22010-01-13 23:51:12 +00001363 AddStorageSpecifiers(CCC, SemaRef.getLangOptions(), Results);
1364 AddFunctionSpecifiers(CCC, SemaRef.getLangOptions(), Results);
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001365 break;
1366
John McCallfaf5fb42010-08-26 23:41:50 +00001367 case Sema::PCC_ObjCInterface:
Douglas Gregorf98e6a22010-01-13 23:51:12 +00001368 AddObjCInterfaceResults(SemaRef.getLangOptions(), Results, true);
1369 AddStorageSpecifiers(CCC, SemaRef.getLangOptions(), Results);
1370 AddFunctionSpecifiers(CCC, SemaRef.getLangOptions(), Results);
Douglas Gregorf1934162010-01-13 21:24:21 +00001371 break;
1372
John McCallfaf5fb42010-08-26 23:41:50 +00001373 case Sema::PCC_ObjCImplementation:
Douglas Gregorf98e6a22010-01-13 23:51:12 +00001374 AddObjCImplementationResults(SemaRef.getLangOptions(), Results, true);
1375 AddStorageSpecifiers(CCC, SemaRef.getLangOptions(), Results);
1376 AddFunctionSpecifiers(CCC, SemaRef.getLangOptions(), Results);
Douglas Gregorf1934162010-01-13 21:24:21 +00001377 break;
1378
John McCallfaf5fb42010-08-26 23:41:50 +00001379 case Sema::PCC_ObjCInstanceVariableList:
Douglas Gregorf98e6a22010-01-13 23:51:12 +00001380 AddObjCVisibilityResults(SemaRef.getLangOptions(), Results, true);
Douglas Gregor48d46252010-01-13 21:54:15 +00001381 break;
1382
John McCallfaf5fb42010-08-26 23:41:50 +00001383 case Sema::PCC_RecoveryInFunction:
1384 case Sema::PCC_Statement: {
Douglas Gregorf4c33342010-05-28 00:22:41 +00001385 AddTypedefResult(Results);
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001386
1387 CodeCompletionString *Pattern = 0;
Douglas Gregorf64acca2010-05-25 21:41:55 +00001388 if (SemaRef.getLangOptions().CPlusPlus && Results.includeCodePatterns()) {
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001389 Pattern = new CodeCompletionString;
1390 Pattern->AddTypedTextChunk("try");
1391 Pattern->AddChunk(CodeCompletionString::CK_LeftBrace);
1392 Pattern->AddPlaceholderChunk("statements");
1393 Pattern->AddChunk(CodeCompletionString::CK_VerticalSpace);
1394 Pattern->AddChunk(CodeCompletionString::CK_RightBrace);
1395 Pattern->AddTextChunk("catch");
1396 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
1397 Pattern->AddPlaceholderChunk("declaration");
1398 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
1399 Pattern->AddChunk(CodeCompletionString::CK_LeftBrace);
1400 Pattern->AddPlaceholderChunk("statements");
1401 Pattern->AddChunk(CodeCompletionString::CK_VerticalSpace);
1402 Pattern->AddChunk(CodeCompletionString::CK_RightBrace);
Douglas Gregor78a21012010-01-14 16:01:26 +00001403 Results.AddResult(Result(Pattern));
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001404 }
Douglas Gregorf1934162010-01-13 21:24:21 +00001405 if (SemaRef.getLangOptions().ObjC1)
Douglas Gregorf98e6a22010-01-13 23:51:12 +00001406 AddObjCStatementResults(Results, true);
Douglas Gregorf1934162010-01-13 21:24:21 +00001407
Douglas Gregorf64acca2010-05-25 21:41:55 +00001408 if (Results.includeCodePatterns()) {
1409 // if (condition) { statements }
1410 Pattern = new CodeCompletionString;
1411 Pattern->AddTypedTextChunk("if");
1412 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
1413 if (SemaRef.getLangOptions().CPlusPlus)
1414 Pattern->AddPlaceholderChunk("condition");
1415 else
1416 Pattern->AddPlaceholderChunk("expression");
1417 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
1418 Pattern->AddChunk(CodeCompletionString::CK_LeftBrace);
1419 Pattern->AddPlaceholderChunk("statements");
1420 Pattern->AddChunk(CodeCompletionString::CK_VerticalSpace);
1421 Pattern->AddChunk(CodeCompletionString::CK_RightBrace);
1422 Results.AddResult(Result(Pattern));
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001423
Douglas Gregorf64acca2010-05-25 21:41:55 +00001424 // switch (condition) { }
1425 Pattern = new CodeCompletionString;
1426 Pattern->AddTypedTextChunk("switch");
1427 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
1428 if (SemaRef.getLangOptions().CPlusPlus)
1429 Pattern->AddPlaceholderChunk("condition");
1430 else
1431 Pattern->AddPlaceholderChunk("expression");
1432 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
1433 Pattern->AddChunk(CodeCompletionString::CK_LeftBrace);
1434 Pattern->AddChunk(CodeCompletionString::CK_VerticalSpace);
1435 Pattern->AddChunk(CodeCompletionString::CK_RightBrace);
1436 Results.AddResult(Result(Pattern));
1437 }
1438
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001439 // Switch-specific statements.
John McCallaab3e412010-08-25 08:40:02 +00001440 if (!SemaRef.getCurFunction()->SwitchStack.empty()) {
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001441 // case expression:
1442 Pattern = new CodeCompletionString;
1443 Pattern->AddTypedTextChunk("case");
Douglas Gregorf4c33342010-05-28 00:22:41 +00001444 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001445 Pattern->AddPlaceholderChunk("expression");
1446 Pattern->AddChunk(CodeCompletionString::CK_Colon);
Douglas Gregor78a21012010-01-14 16:01:26 +00001447 Results.AddResult(Result(Pattern));
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001448
1449 // default:
1450 Pattern = new CodeCompletionString;
1451 Pattern->AddTypedTextChunk("default");
1452 Pattern->AddChunk(CodeCompletionString::CK_Colon);
Douglas Gregor78a21012010-01-14 16:01:26 +00001453 Results.AddResult(Result(Pattern));
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001454 }
1455
Douglas Gregorf64acca2010-05-25 21:41:55 +00001456 if (Results.includeCodePatterns()) {
1457 /// while (condition) { statements }
1458 Pattern = new CodeCompletionString;
1459 Pattern->AddTypedTextChunk("while");
1460 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
1461 if (SemaRef.getLangOptions().CPlusPlus)
1462 Pattern->AddPlaceholderChunk("condition");
1463 else
1464 Pattern->AddPlaceholderChunk("expression");
1465 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
1466 Pattern->AddChunk(CodeCompletionString::CK_LeftBrace);
1467 Pattern->AddPlaceholderChunk("statements");
1468 Pattern->AddChunk(CodeCompletionString::CK_VerticalSpace);
1469 Pattern->AddChunk(CodeCompletionString::CK_RightBrace);
1470 Results.AddResult(Result(Pattern));
1471
1472 // do { statements } while ( expression );
1473 Pattern = new CodeCompletionString;
1474 Pattern->AddTypedTextChunk("do");
1475 Pattern->AddChunk(CodeCompletionString::CK_LeftBrace);
1476 Pattern->AddPlaceholderChunk("statements");
1477 Pattern->AddChunk(CodeCompletionString::CK_VerticalSpace);
1478 Pattern->AddChunk(CodeCompletionString::CK_RightBrace);
1479 Pattern->AddTextChunk("while");
1480 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001481 Pattern->AddPlaceholderChunk("expression");
Douglas Gregorf64acca2010-05-25 21:41:55 +00001482 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
1483 Results.AddResult(Result(Pattern));
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001484
Douglas Gregorf64acca2010-05-25 21:41:55 +00001485 // for ( for-init-statement ; condition ; expression ) { statements }
1486 Pattern = new CodeCompletionString;
1487 Pattern->AddTypedTextChunk("for");
1488 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
1489 if (SemaRef.getLangOptions().CPlusPlus || SemaRef.getLangOptions().C99)
1490 Pattern->AddPlaceholderChunk("init-statement");
1491 else
1492 Pattern->AddPlaceholderChunk("init-expression");
1493 Pattern->AddChunk(CodeCompletionString::CK_SemiColon);
1494 Pattern->AddPlaceholderChunk("condition");
1495 Pattern->AddChunk(CodeCompletionString::CK_SemiColon);
1496 Pattern->AddPlaceholderChunk("inc-expression");
1497 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
1498 Pattern->AddChunk(CodeCompletionString::CK_LeftBrace);
1499 Pattern->AddPlaceholderChunk("statements");
1500 Pattern->AddChunk(CodeCompletionString::CK_VerticalSpace);
1501 Pattern->AddChunk(CodeCompletionString::CK_RightBrace);
1502 Results.AddResult(Result(Pattern));
1503 }
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001504
1505 if (S->getContinueParent()) {
1506 // continue ;
1507 Pattern = new CodeCompletionString;
1508 Pattern->AddTypedTextChunk("continue");
Douglas Gregor78a21012010-01-14 16:01:26 +00001509 Results.AddResult(Result(Pattern));
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001510 }
1511
1512 if (S->getBreakParent()) {
1513 // break ;
1514 Pattern = new CodeCompletionString;
1515 Pattern->AddTypedTextChunk("break");
Douglas Gregor78a21012010-01-14 16:01:26 +00001516 Results.AddResult(Result(Pattern));
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001517 }
1518
1519 // "return expression ;" or "return ;", depending on whether we
1520 // know the function is void or not.
1521 bool isVoid = false;
1522 if (FunctionDecl *Function = dyn_cast<FunctionDecl>(SemaRef.CurContext))
1523 isVoid = Function->getResultType()->isVoidType();
1524 else if (ObjCMethodDecl *Method
1525 = dyn_cast<ObjCMethodDecl>(SemaRef.CurContext))
1526 isVoid = Method->getResultType()->isVoidType();
Douglas Gregor9a28e842010-03-01 23:15:13 +00001527 else if (SemaRef.getCurBlock() &&
1528 !SemaRef.getCurBlock()->ReturnType.isNull())
1529 isVoid = SemaRef.getCurBlock()->ReturnType->isVoidType();
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001530 Pattern = new CodeCompletionString;
1531 Pattern->AddTypedTextChunk("return");
Douglas Gregor44272ca2010-02-18 04:06:48 +00001532 if (!isVoid) {
1533 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001534 Pattern->AddPlaceholderChunk("expression");
Douglas Gregor44272ca2010-02-18 04:06:48 +00001535 }
Douglas Gregor78a21012010-01-14 16:01:26 +00001536 Results.AddResult(Result(Pattern));
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001537
Douglas Gregorf4c33342010-05-28 00:22:41 +00001538 // goto identifier ;
1539 Pattern = new CodeCompletionString;
1540 Pattern->AddTypedTextChunk("goto");
1541 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
1542 Pattern->AddPlaceholderChunk("label");
1543 Results.AddResult(Result(Pattern));
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001544
Douglas Gregorf4c33342010-05-28 00:22:41 +00001545 // Using directives
1546 Pattern = new CodeCompletionString;
1547 Pattern->AddTypedTextChunk("using");
1548 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
1549 Pattern->AddTextChunk("namespace");
1550 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
1551 Pattern->AddPlaceholderChunk("identifier");
1552 Results.AddResult(Result(Pattern));
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001553 }
1554
1555 // Fall through (for statement expressions).
John McCallfaf5fb42010-08-26 23:41:50 +00001556 case Sema::PCC_ForInit:
1557 case Sema::PCC_Condition:
Douglas Gregorf98e6a22010-01-13 23:51:12 +00001558 AddStorageSpecifiers(CCC, SemaRef.getLangOptions(), Results);
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001559 // Fall through: conditions and statements can have expressions.
1560
Douglas Gregor5e35d592010-09-14 23:59:36 +00001561 case Sema::PCC_ParenthesizedExpression:
John McCallfaf5fb42010-08-26 23:41:50 +00001562 case Sema::PCC_Expression: {
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001563 CodeCompletionString *Pattern = 0;
1564 if (SemaRef.getLangOptions().CPlusPlus) {
1565 // 'this', if we're in a non-static member function.
1566 if (CXXMethodDecl *Method = dyn_cast<CXXMethodDecl>(SemaRef.CurContext))
1567 if (!Method->isStatic())
Douglas Gregor78a21012010-01-14 16:01:26 +00001568 Results.AddResult(Result("this"));
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001569
1570 // true, false
Douglas Gregor78a21012010-01-14 16:01:26 +00001571 Results.AddResult(Result("true"));
1572 Results.AddResult(Result("false"));
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001573
Douglas Gregorf4c33342010-05-28 00:22:41 +00001574 // dynamic_cast < type-id > ( expression )
1575 Pattern = new CodeCompletionString;
1576 Pattern->AddTypedTextChunk("dynamic_cast");
1577 Pattern->AddChunk(CodeCompletionString::CK_LeftAngle);
1578 Pattern->AddPlaceholderChunk("type");
1579 Pattern->AddChunk(CodeCompletionString::CK_RightAngle);
1580 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
1581 Pattern->AddPlaceholderChunk("expression");
1582 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
1583 Results.AddResult(Result(Pattern));
1584
1585 // static_cast < type-id > ( expression )
1586 Pattern = new CodeCompletionString;
1587 Pattern->AddTypedTextChunk("static_cast");
1588 Pattern->AddChunk(CodeCompletionString::CK_LeftAngle);
1589 Pattern->AddPlaceholderChunk("type");
1590 Pattern->AddChunk(CodeCompletionString::CK_RightAngle);
1591 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
1592 Pattern->AddPlaceholderChunk("expression");
1593 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
1594 Results.AddResult(Result(Pattern));
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001595
Douglas Gregorf4c33342010-05-28 00:22:41 +00001596 // reinterpret_cast < type-id > ( expression )
1597 Pattern = new CodeCompletionString;
1598 Pattern->AddTypedTextChunk("reinterpret_cast");
1599 Pattern->AddChunk(CodeCompletionString::CK_LeftAngle);
1600 Pattern->AddPlaceholderChunk("type");
1601 Pattern->AddChunk(CodeCompletionString::CK_RightAngle);
1602 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
1603 Pattern->AddPlaceholderChunk("expression");
1604 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
1605 Results.AddResult(Result(Pattern));
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001606
Douglas Gregorf4c33342010-05-28 00:22:41 +00001607 // const_cast < type-id > ( expression )
1608 Pattern = new CodeCompletionString;
1609 Pattern->AddTypedTextChunk("const_cast");
1610 Pattern->AddChunk(CodeCompletionString::CK_LeftAngle);
1611 Pattern->AddPlaceholderChunk("type");
1612 Pattern->AddChunk(CodeCompletionString::CK_RightAngle);
1613 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
1614 Pattern->AddPlaceholderChunk("expression");
1615 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
1616 Results.AddResult(Result(Pattern));
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001617
Douglas Gregorf4c33342010-05-28 00:22:41 +00001618 // typeid ( expression-or-type )
1619 Pattern = new CodeCompletionString;
1620 Pattern->AddTypedTextChunk("typeid");
1621 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
1622 Pattern->AddPlaceholderChunk("expression-or-type");
1623 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
1624 Results.AddResult(Result(Pattern));
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001625
Douglas Gregorf4c33342010-05-28 00:22:41 +00001626 // new T ( ... )
1627 Pattern = new CodeCompletionString;
1628 Pattern->AddTypedTextChunk("new");
1629 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
1630 Pattern->AddPlaceholderChunk("type");
1631 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
1632 Pattern->AddPlaceholderChunk("expressions");
1633 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
1634 Results.AddResult(Result(Pattern));
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001635
Douglas Gregorf4c33342010-05-28 00:22:41 +00001636 // new T [ ] ( ... )
1637 Pattern = new CodeCompletionString;
1638 Pattern->AddTypedTextChunk("new");
1639 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
1640 Pattern->AddPlaceholderChunk("type");
1641 Pattern->AddChunk(CodeCompletionString::CK_LeftBracket);
1642 Pattern->AddPlaceholderChunk("size");
1643 Pattern->AddChunk(CodeCompletionString::CK_RightBracket);
1644 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
1645 Pattern->AddPlaceholderChunk("expressions");
1646 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
1647 Results.AddResult(Result(Pattern));
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001648
Douglas Gregorf4c33342010-05-28 00:22:41 +00001649 // delete expression
1650 Pattern = new CodeCompletionString;
1651 Pattern->AddTypedTextChunk("delete");
1652 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
1653 Pattern->AddPlaceholderChunk("expression");
1654 Results.AddResult(Result(Pattern));
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001655
Douglas Gregorf4c33342010-05-28 00:22:41 +00001656 // delete [] expression
1657 Pattern = new CodeCompletionString;
1658 Pattern->AddTypedTextChunk("delete");
1659 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
1660 Pattern->AddChunk(CodeCompletionString::CK_LeftBracket);
1661 Pattern->AddChunk(CodeCompletionString::CK_RightBracket);
1662 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
1663 Pattern->AddPlaceholderChunk("expression");
1664 Results.AddResult(Result(Pattern));
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001665
Douglas Gregorf4c33342010-05-28 00:22:41 +00001666 // throw expression
1667 Pattern = new CodeCompletionString;
1668 Pattern->AddTypedTextChunk("throw");
1669 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
1670 Pattern->AddPlaceholderChunk("expression");
1671 Results.AddResult(Result(Pattern));
Douglas Gregora2db7932010-05-26 22:00:08 +00001672
1673 // FIXME: Rethrow?
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001674 }
1675
1676 if (SemaRef.getLangOptions().ObjC1) {
1677 // Add "super", if we're in an Objective-C class with a superclass.
Ted Kremenek305a0a72010-05-31 21:43:10 +00001678 if (ObjCMethodDecl *Method = SemaRef.getCurMethodDecl()) {
1679 // The interface can be NULL.
1680 if (ObjCInterfaceDecl *ID = Method->getClassInterface())
1681 if (ID->getSuperClass())
1682 Results.AddResult(Result("super"));
1683 }
1684
Douglas Gregorf98e6a22010-01-13 23:51:12 +00001685 AddObjCExpressionResults(Results, true);
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001686 }
1687
Douglas Gregorf4c33342010-05-28 00:22:41 +00001688 // sizeof expression
1689 Pattern = new CodeCompletionString;
1690 Pattern->AddTypedTextChunk("sizeof");
1691 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
1692 Pattern->AddPlaceholderChunk("expression-or-type");
1693 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
1694 Results.AddResult(Result(Pattern));
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001695 break;
1696 }
Douglas Gregor99fa2642010-08-24 01:06:58 +00001697
John McCallfaf5fb42010-08-26 23:41:50 +00001698 case Sema::PCC_Type:
Douglas Gregor99fa2642010-08-24 01:06:58 +00001699 break;
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001700 }
1701
Douglas Gregor70febae2010-05-28 00:49:12 +00001702 if (WantTypesInContext(CCC, SemaRef.getLangOptions()))
1703 AddTypeSpecifierResults(SemaRef.getLangOptions(), Results);
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001704
John McCallfaf5fb42010-08-26 23:41:50 +00001705 if (SemaRef.getLangOptions().CPlusPlus && CCC != Sema::PCC_Type)
Douglas Gregor78a21012010-01-14 16:01:26 +00001706 Results.AddResult(Result("operator"));
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001707}
1708
Douglas Gregorb3fa9192009-12-18 18:53:37 +00001709/// \brief If the given declaration has an associated type, add it as a result
1710/// type chunk.
1711static void AddResultTypeChunk(ASTContext &Context,
1712 NamedDecl *ND,
1713 CodeCompletionString *Result) {
1714 if (!ND)
1715 return;
1716
1717 // Determine the type of the declaration (if it has a type).
1718 QualType T;
1719 if (FunctionDecl *Function = dyn_cast<FunctionDecl>(ND))
1720 T = Function->getResultType();
1721 else if (ObjCMethodDecl *Method = dyn_cast<ObjCMethodDecl>(ND))
1722 T = Method->getResultType();
1723 else if (FunctionTemplateDecl *FunTmpl = dyn_cast<FunctionTemplateDecl>(ND))
1724 T = FunTmpl->getTemplatedDecl()->getResultType();
1725 else if (EnumConstantDecl *Enumerator = dyn_cast<EnumConstantDecl>(ND))
1726 T = Context.getTypeDeclType(cast<TypeDecl>(Enumerator->getDeclContext()));
1727 else if (isa<UnresolvedUsingValueDecl>(ND)) {
1728 /* Do nothing: ignore unresolved using declarations*/
1729 } else if (ValueDecl *Value = dyn_cast<ValueDecl>(ND))
1730 T = Value->getType();
1731 else if (ObjCPropertyDecl *Property = dyn_cast<ObjCPropertyDecl>(ND))
1732 T = Property->getType();
1733
1734 if (T.isNull() || Context.hasSameType(T, Context.DependentTy))
1735 return;
1736
Douglas Gregorcf04b022010-04-05 21:25:31 +00001737 PrintingPolicy Policy(Context.PrintingPolicy);
1738 Policy.AnonymousTagLocations = false;
1739
Douglas Gregorb3fa9192009-12-18 18:53:37 +00001740 std::string TypeStr;
Douglas Gregorcf04b022010-04-05 21:25:31 +00001741 T.getAsStringInternal(TypeStr, Policy);
Douglas Gregorb3fa9192009-12-18 18:53:37 +00001742 Result->AddResultTypeChunk(TypeStr);
1743}
1744
Douglas Gregordbb71db2010-08-23 23:51:41 +00001745static void MaybeAddSentinel(ASTContext &Context, NamedDecl *FunctionOrMethod,
1746 CodeCompletionString *Result) {
1747 if (SentinelAttr *Sentinel = FunctionOrMethod->getAttr<SentinelAttr>())
1748 if (Sentinel->getSentinel() == 0) {
1749 if (Context.getLangOptions().ObjC1 &&
1750 Context.Idents.get("nil").hasMacroDefinition())
1751 Result->AddTextChunk(", nil");
1752 else if (Context.Idents.get("NULL").hasMacroDefinition())
1753 Result->AddTextChunk(", NULL");
1754 else
1755 Result->AddTextChunk(", (void*)0");
1756 }
1757}
1758
Douglas Gregore90dd002010-08-24 16:15:59 +00001759static std::string FormatFunctionParameter(ASTContext &Context,
Douglas Gregor981a0c42010-08-29 19:47:46 +00001760 ParmVarDecl *Param,
1761 bool SuppressName = false) {
Douglas Gregore90dd002010-08-24 16:15:59 +00001762 bool ObjCMethodParam = isa<ObjCMethodDecl>(Param->getDeclContext());
1763 if (Param->getType()->isDependentType() ||
1764 !Param->getType()->isBlockPointerType()) {
1765 // The argument for a dependent or non-block parameter is a placeholder
1766 // containing that parameter's type.
1767 std::string Result;
1768
Douglas Gregor981a0c42010-08-29 19:47:46 +00001769 if (Param->getIdentifier() && !ObjCMethodParam && !SuppressName)
Douglas Gregore90dd002010-08-24 16:15:59 +00001770 Result = Param->getIdentifier()->getName();
1771
1772 Param->getType().getAsStringInternal(Result,
1773 Context.PrintingPolicy);
1774
1775 if (ObjCMethodParam) {
1776 Result = "(" + Result;
1777 Result += ")";
Douglas Gregor981a0c42010-08-29 19:47:46 +00001778 if (Param->getIdentifier() && !SuppressName)
Douglas Gregore90dd002010-08-24 16:15:59 +00001779 Result += Param->getIdentifier()->getName();
1780 }
1781 return Result;
1782 }
1783
1784 // The argument for a block pointer parameter is a block literal with
1785 // the appropriate type.
1786 FunctionProtoTypeLoc *Block = 0;
1787 TypeLoc TL;
1788 if (TypeSourceInfo *TSInfo = Param->getTypeSourceInfo()) {
1789 TL = TSInfo->getTypeLoc().getUnqualifiedLoc();
1790 while (true) {
1791 // Look through typedefs.
1792 if (TypedefTypeLoc *TypedefTL = dyn_cast<TypedefTypeLoc>(&TL)) {
1793 if (TypeSourceInfo *InnerTSInfo
1794 = TypedefTL->getTypedefDecl()->getTypeSourceInfo()) {
1795 TL = InnerTSInfo->getTypeLoc().getUnqualifiedLoc();
1796 continue;
1797 }
1798 }
1799
1800 // Look through qualified types
1801 if (QualifiedTypeLoc *QualifiedTL = dyn_cast<QualifiedTypeLoc>(&TL)) {
1802 TL = QualifiedTL->getUnqualifiedLoc();
1803 continue;
1804 }
1805
1806 // Try to get the function prototype behind the block pointer type,
1807 // then we're done.
1808 if (BlockPointerTypeLoc *BlockPtr
1809 = dyn_cast<BlockPointerTypeLoc>(&TL)) {
1810 TL = BlockPtr->getPointeeLoc();
1811 Block = dyn_cast<FunctionProtoTypeLoc>(&TL);
1812 }
1813 break;
1814 }
1815 }
1816
1817 if (!Block) {
1818 // We were unable to find a FunctionProtoTypeLoc with parameter names
1819 // for the block; just use the parameter type as a placeholder.
1820 std::string Result;
1821 Param->getType().getUnqualifiedType().
1822 getAsStringInternal(Result, Context.PrintingPolicy);
1823
1824 if (ObjCMethodParam) {
1825 Result = "(" + Result;
1826 Result += ")";
1827 if (Param->getIdentifier())
1828 Result += Param->getIdentifier()->getName();
1829 }
1830
1831 return Result;
1832 }
1833
1834 // We have the function prototype behind the block pointer type, as it was
1835 // written in the source.
Douglas Gregor67da50e2010-09-08 22:47:51 +00001836 std::string Result;
1837 QualType ResultType = Block->getTypePtr()->getResultType();
1838 if (!ResultType->isVoidType())
1839 ResultType.getAsStringInternal(Result, Context.PrintingPolicy);
1840
1841 Result = '^' + Result;
1842 if (Block->getNumArgs() == 0) {
1843 if (Block->getTypePtr()->isVariadic())
1844 Result += "(...)";
1845 } else {
1846 Result += "(";
1847 for (unsigned I = 0, N = Block->getNumArgs(); I != N; ++I) {
1848 if (I)
1849 Result += ", ";
1850 Result += FormatFunctionParameter(Context, Block->getArg(I));
1851
1852 if (I == N - 1 && Block->getTypePtr()->isVariadic())
1853 Result += ", ...";
1854 }
1855 Result += ")";
Douglas Gregor400f5972010-08-31 05:13:43 +00001856 }
Douglas Gregor67da50e2010-09-08 22:47:51 +00001857
Douglas Gregore90dd002010-08-24 16:15:59 +00001858 return Result;
1859}
1860
Douglas Gregor3545ff42009-09-21 16:56:56 +00001861/// \brief Add function parameter chunks to the given code completion string.
1862static void AddFunctionParameterChunks(ASTContext &Context,
1863 FunctionDecl *Function,
1864 CodeCompletionString *Result) {
Douglas Gregor9eb77012009-11-07 00:00:49 +00001865 typedef CodeCompletionString::Chunk Chunk;
1866
Douglas Gregor3545ff42009-09-21 16:56:56 +00001867 CodeCompletionString *CCStr = Result;
1868
1869 for (unsigned P = 0, N = Function->getNumParams(); P != N; ++P) {
1870 ParmVarDecl *Param = Function->getParamDecl(P);
1871
1872 if (Param->hasDefaultArg()) {
1873 // When we see an optional default argument, put that argument and
1874 // the remaining default arguments into a new, optional string.
1875 CodeCompletionString *Opt = new CodeCompletionString;
1876 CCStr->AddOptionalChunk(std::auto_ptr<CodeCompletionString>(Opt));
1877 CCStr = Opt;
1878 }
1879
1880 if (P != 0)
Douglas Gregor9eb77012009-11-07 00:00:49 +00001881 CCStr->AddChunk(Chunk(CodeCompletionString::CK_Comma));
Douglas Gregor3545ff42009-09-21 16:56:56 +00001882
1883 // Format the placeholder string.
Douglas Gregore90dd002010-08-24 16:15:59 +00001884 std::string PlaceholderStr = FormatFunctionParameter(Context, Param);
1885
Douglas Gregor400f5972010-08-31 05:13:43 +00001886 if (Function->isVariadic() && P == N - 1)
1887 PlaceholderStr += ", ...";
1888
Douglas Gregor3545ff42009-09-21 16:56:56 +00001889 // Add the placeholder string.
Benjamin Kramerb33a97c2009-11-29 20:18:50 +00001890 CCStr->AddPlaceholderChunk(PlaceholderStr);
Douglas Gregor3545ff42009-09-21 16:56:56 +00001891 }
Douglas Gregorba449032009-09-22 21:42:17 +00001892
1893 if (const FunctionProtoType *Proto
1894 = Function->getType()->getAs<FunctionProtoType>())
Douglas Gregordbb71db2010-08-23 23:51:41 +00001895 if (Proto->isVariadic()) {
Douglas Gregor400f5972010-08-31 05:13:43 +00001896 if (Proto->getNumArgs() == 0)
1897 CCStr->AddPlaceholderChunk("...");
Douglas Gregordbb71db2010-08-23 23:51:41 +00001898
1899 MaybeAddSentinel(Context, Function, CCStr);
1900 }
Douglas Gregor3545ff42009-09-21 16:56:56 +00001901}
1902
1903/// \brief Add template parameter chunks to the given code completion string.
1904static void AddTemplateParameterChunks(ASTContext &Context,
1905 TemplateDecl *Template,
1906 CodeCompletionString *Result,
1907 unsigned MaxParameters = 0) {
Douglas Gregor9eb77012009-11-07 00:00:49 +00001908 typedef CodeCompletionString::Chunk Chunk;
1909
Douglas Gregor3545ff42009-09-21 16:56:56 +00001910 CodeCompletionString *CCStr = Result;
1911 bool FirstParameter = true;
1912
1913 TemplateParameterList *Params = Template->getTemplateParameters();
1914 TemplateParameterList::iterator PEnd = Params->end();
1915 if (MaxParameters)
1916 PEnd = Params->begin() + MaxParameters;
1917 for (TemplateParameterList::iterator P = Params->begin(); P != PEnd; ++P) {
1918 bool HasDefaultArg = false;
1919 std::string PlaceholderStr;
1920 if (TemplateTypeParmDecl *TTP = dyn_cast<TemplateTypeParmDecl>(*P)) {
1921 if (TTP->wasDeclaredWithTypename())
1922 PlaceholderStr = "typename";
1923 else
1924 PlaceholderStr = "class";
1925
1926 if (TTP->getIdentifier()) {
1927 PlaceholderStr += ' ';
1928 PlaceholderStr += TTP->getIdentifier()->getName();
1929 }
1930
1931 HasDefaultArg = TTP->hasDefaultArgument();
1932 } else if (NonTypeTemplateParmDecl *NTTP
1933 = dyn_cast<NonTypeTemplateParmDecl>(*P)) {
1934 if (NTTP->getIdentifier())
1935 PlaceholderStr = NTTP->getIdentifier()->getName();
1936 NTTP->getType().getAsStringInternal(PlaceholderStr,
1937 Context.PrintingPolicy);
1938 HasDefaultArg = NTTP->hasDefaultArgument();
1939 } else {
1940 assert(isa<TemplateTemplateParmDecl>(*P));
1941 TemplateTemplateParmDecl *TTP = cast<TemplateTemplateParmDecl>(*P);
1942
1943 // Since putting the template argument list into the placeholder would
1944 // be very, very long, we just use an abbreviation.
1945 PlaceholderStr = "template<...> class";
1946 if (TTP->getIdentifier()) {
1947 PlaceholderStr += ' ';
1948 PlaceholderStr += TTP->getIdentifier()->getName();
1949 }
1950
1951 HasDefaultArg = TTP->hasDefaultArgument();
1952 }
1953
1954 if (HasDefaultArg) {
1955 // When we see an optional default argument, put that argument and
1956 // the remaining default arguments into a new, optional string.
1957 CodeCompletionString *Opt = new CodeCompletionString;
1958 CCStr->AddOptionalChunk(std::auto_ptr<CodeCompletionString>(Opt));
1959 CCStr = Opt;
1960 }
1961
1962 if (FirstParameter)
1963 FirstParameter = false;
1964 else
Douglas Gregor9eb77012009-11-07 00:00:49 +00001965 CCStr->AddChunk(Chunk(CodeCompletionString::CK_Comma));
Douglas Gregor3545ff42009-09-21 16:56:56 +00001966
1967 // Add the placeholder string.
Benjamin Kramerb33a97c2009-11-29 20:18:50 +00001968 CCStr->AddPlaceholderChunk(PlaceholderStr);
Douglas Gregor3545ff42009-09-21 16:56:56 +00001969 }
1970}
1971
Douglas Gregorf2510672009-09-21 19:57:38 +00001972/// \brief Add a qualifier to the given code-completion string, if the
1973/// provided nested-name-specifier is non-NULL.
Douglas Gregor0f622362009-12-11 18:44:16 +00001974static void
1975AddQualifierToCompletionString(CodeCompletionString *Result,
1976 NestedNameSpecifier *Qualifier,
1977 bool QualifierIsInformative,
1978 ASTContext &Context) {
Douglas Gregorf2510672009-09-21 19:57:38 +00001979 if (!Qualifier)
1980 return;
1981
1982 std::string PrintedNNS;
1983 {
1984 llvm::raw_string_ostream OS(PrintedNNS);
1985 Qualifier->print(OS, Context.PrintingPolicy);
1986 }
Douglas Gregor5bf52692009-09-22 23:15:58 +00001987 if (QualifierIsInformative)
Benjamin Kramerb33a97c2009-11-29 20:18:50 +00001988 Result->AddInformativeChunk(PrintedNNS);
Douglas Gregor5bf52692009-09-22 23:15:58 +00001989 else
Benjamin Kramerb33a97c2009-11-29 20:18:50 +00001990 Result->AddTextChunk(PrintedNNS);
Douglas Gregorf2510672009-09-21 19:57:38 +00001991}
1992
Douglas Gregor0f622362009-12-11 18:44:16 +00001993static void AddFunctionTypeQualsToCompletionString(CodeCompletionString *Result,
1994 FunctionDecl *Function) {
1995 const FunctionProtoType *Proto
1996 = Function->getType()->getAs<FunctionProtoType>();
1997 if (!Proto || !Proto->getTypeQuals())
1998 return;
1999
2000 std::string QualsStr;
2001 if (Proto->getTypeQuals() & Qualifiers::Const)
2002 QualsStr += " const";
2003 if (Proto->getTypeQuals() & Qualifiers::Volatile)
2004 QualsStr += " volatile";
2005 if (Proto->getTypeQuals() & Qualifiers::Restrict)
2006 QualsStr += " restrict";
2007 Result->AddInformativeChunk(QualsStr);
2008}
2009
Douglas Gregor3545ff42009-09-21 16:56:56 +00002010/// \brief If possible, create a new code completion string for the given
2011/// result.
2012///
2013/// \returns Either a new, heap-allocated code completion string describing
2014/// how to use this result, or NULL to indicate that the string or name of the
2015/// result is all that is needed.
2016CodeCompletionString *
John McCall276321a2010-08-25 06:19:51 +00002017CodeCompletionResult::CreateCodeCompletionString(Sema &S,
Douglas Gregor8e984da2010-08-04 16:47:14 +00002018 CodeCompletionString *Result) {
Douglas Gregor9eb77012009-11-07 00:00:49 +00002019 typedef CodeCompletionString::Chunk Chunk;
2020
Douglas Gregorf09935f2009-12-01 05:55:20 +00002021 if (Kind == RK_Pattern)
Douglas Gregor8e984da2010-08-04 16:47:14 +00002022 return Pattern->Clone(Result);
Douglas Gregorf09935f2009-12-01 05:55:20 +00002023
Douglas Gregor8e984da2010-08-04 16:47:14 +00002024 if (!Result)
2025 Result = new CodeCompletionString;
Douglas Gregorf09935f2009-12-01 05:55:20 +00002026
2027 if (Kind == RK_Keyword) {
2028 Result->AddTypedTextChunk(Keyword);
2029 return Result;
2030 }
Douglas Gregor3545ff42009-09-21 16:56:56 +00002031
Douglas Gregorf329c7c2009-10-30 16:50:04 +00002032 if (Kind == RK_Macro) {
2033 MacroInfo *MI = S.PP.getMacroInfo(Macro);
Douglas Gregorf09935f2009-12-01 05:55:20 +00002034 assert(MI && "Not a macro?");
2035
2036 Result->AddTypedTextChunk(Macro->getName());
2037
2038 if (!MI->isFunctionLike())
2039 return Result;
Douglas Gregorf329c7c2009-10-30 16:50:04 +00002040
2041 // Format a function-like macro with placeholders for the arguments.
Douglas Gregor9eb77012009-11-07 00:00:49 +00002042 Result->AddChunk(Chunk(CodeCompletionString::CK_LeftParen));
Douglas Gregorf329c7c2009-10-30 16:50:04 +00002043 for (MacroInfo::arg_iterator A = MI->arg_begin(), AEnd = MI->arg_end();
2044 A != AEnd; ++A) {
2045 if (A != MI->arg_begin())
Douglas Gregor9eb77012009-11-07 00:00:49 +00002046 Result->AddChunk(Chunk(CodeCompletionString::CK_Comma));
Douglas Gregorf329c7c2009-10-30 16:50:04 +00002047
2048 if (!MI->isVariadic() || A != AEnd - 1) {
2049 // Non-variadic argument.
Benjamin Kramerb33a97c2009-11-29 20:18:50 +00002050 Result->AddPlaceholderChunk((*A)->getName());
Douglas Gregorf329c7c2009-10-30 16:50:04 +00002051 continue;
2052 }
2053
2054 // Variadic argument; cope with the different between GNU and C99
2055 // variadic macros, providing a single placeholder for the rest of the
2056 // arguments.
2057 if ((*A)->isStr("__VA_ARGS__"))
2058 Result->AddPlaceholderChunk("...");
2059 else {
2060 std::string Arg = (*A)->getName();
2061 Arg += "...";
Benjamin Kramerb33a97c2009-11-29 20:18:50 +00002062 Result->AddPlaceholderChunk(Arg);
Douglas Gregorf329c7c2009-10-30 16:50:04 +00002063 }
2064 }
Douglas Gregor9eb77012009-11-07 00:00:49 +00002065 Result->AddChunk(Chunk(CodeCompletionString::CK_RightParen));
Douglas Gregorf329c7c2009-10-30 16:50:04 +00002066 return Result;
2067 }
2068
Douglas Gregorf64acca2010-05-25 21:41:55 +00002069 assert(Kind == RK_Declaration && "Missed a result kind?");
Douglas Gregor3545ff42009-09-21 16:56:56 +00002070 NamedDecl *ND = Declaration;
2071
Douglas Gregor9eb77012009-11-07 00:00:49 +00002072 if (StartsNestedNameSpecifier) {
Benjamin Kramerb33a97c2009-11-29 20:18:50 +00002073 Result->AddTypedTextChunk(ND->getNameAsString());
Douglas Gregor9eb77012009-11-07 00:00:49 +00002074 Result->AddTextChunk("::");
2075 return Result;
2076 }
2077
Douglas Gregorb3fa9192009-12-18 18:53:37 +00002078 AddResultTypeChunk(S.Context, ND, Result);
2079
Douglas Gregor3545ff42009-09-21 16:56:56 +00002080 if (FunctionDecl *Function = dyn_cast<FunctionDecl>(ND)) {
Douglas Gregor5bf52692009-09-22 23:15:58 +00002081 AddQualifierToCompletionString(Result, Qualifier, QualifierIsInformative,
2082 S.Context);
Benjamin Kramerb33a97c2009-11-29 20:18:50 +00002083 Result->AddTypedTextChunk(Function->getNameAsString());
Douglas Gregor9eb77012009-11-07 00:00:49 +00002084 Result->AddChunk(Chunk(CodeCompletionString::CK_LeftParen));
Douglas Gregor3545ff42009-09-21 16:56:56 +00002085 AddFunctionParameterChunks(S.Context, Function, Result);
Douglas Gregor9eb77012009-11-07 00:00:49 +00002086 Result->AddChunk(Chunk(CodeCompletionString::CK_RightParen));
Douglas Gregor0f622362009-12-11 18:44:16 +00002087 AddFunctionTypeQualsToCompletionString(Result, Function);
Douglas Gregor3545ff42009-09-21 16:56:56 +00002088 return Result;
2089 }
2090
2091 if (FunctionTemplateDecl *FunTmpl = dyn_cast<FunctionTemplateDecl>(ND)) {
Douglas Gregor5bf52692009-09-22 23:15:58 +00002092 AddQualifierToCompletionString(Result, Qualifier, QualifierIsInformative,
2093 S.Context);
Douglas Gregor3545ff42009-09-21 16:56:56 +00002094 FunctionDecl *Function = FunTmpl->getTemplatedDecl();
Benjamin Kramerb33a97c2009-11-29 20:18:50 +00002095 Result->AddTypedTextChunk(Function->getNameAsString());
Douglas Gregor3545ff42009-09-21 16:56:56 +00002096
2097 // Figure out which template parameters are deduced (or have default
2098 // arguments).
2099 llvm::SmallVector<bool, 16> Deduced;
2100 S.MarkDeducedTemplateParameters(FunTmpl, Deduced);
2101 unsigned LastDeducibleArgument;
2102 for (LastDeducibleArgument = Deduced.size(); LastDeducibleArgument > 0;
2103 --LastDeducibleArgument) {
2104 if (!Deduced[LastDeducibleArgument - 1]) {
2105 // C++0x: Figure out if the template argument has a default. If so,
2106 // the user doesn't need to type this argument.
2107 // FIXME: We need to abstract template parameters better!
2108 bool HasDefaultArg = false;
2109 NamedDecl *Param = FunTmpl->getTemplateParameters()->getParam(
2110 LastDeducibleArgument - 1);
2111 if (TemplateTypeParmDecl *TTP = dyn_cast<TemplateTypeParmDecl>(Param))
2112 HasDefaultArg = TTP->hasDefaultArgument();
2113 else if (NonTypeTemplateParmDecl *NTTP
2114 = dyn_cast<NonTypeTemplateParmDecl>(Param))
2115 HasDefaultArg = NTTP->hasDefaultArgument();
2116 else {
2117 assert(isa<TemplateTemplateParmDecl>(Param));
2118 HasDefaultArg
Douglas Gregor9eb77012009-11-07 00:00:49 +00002119 = cast<TemplateTemplateParmDecl>(Param)->hasDefaultArgument();
Douglas Gregor3545ff42009-09-21 16:56:56 +00002120 }
2121
2122 if (!HasDefaultArg)
2123 break;
2124 }
2125 }
2126
2127 if (LastDeducibleArgument) {
2128 // Some of the function template arguments cannot be deduced from a
2129 // function call, so we introduce an explicit template argument list
2130 // containing all of the arguments up to the first deducible argument.
Douglas Gregor9eb77012009-11-07 00:00:49 +00002131 Result->AddChunk(Chunk(CodeCompletionString::CK_LeftAngle));
Douglas Gregor3545ff42009-09-21 16:56:56 +00002132 AddTemplateParameterChunks(S.Context, FunTmpl, Result,
2133 LastDeducibleArgument);
Douglas Gregor9eb77012009-11-07 00:00:49 +00002134 Result->AddChunk(Chunk(CodeCompletionString::CK_RightAngle));
Douglas Gregor3545ff42009-09-21 16:56:56 +00002135 }
2136
2137 // Add the function parameters
Douglas Gregor9eb77012009-11-07 00:00:49 +00002138 Result->AddChunk(Chunk(CodeCompletionString::CK_LeftParen));
Douglas Gregor3545ff42009-09-21 16:56:56 +00002139 AddFunctionParameterChunks(S.Context, Function, Result);
Douglas Gregor9eb77012009-11-07 00:00:49 +00002140 Result->AddChunk(Chunk(CodeCompletionString::CK_RightParen));
Douglas Gregor0f622362009-12-11 18:44:16 +00002141 AddFunctionTypeQualsToCompletionString(Result, Function);
Douglas Gregor3545ff42009-09-21 16:56:56 +00002142 return Result;
2143 }
2144
2145 if (TemplateDecl *Template = dyn_cast<TemplateDecl>(ND)) {
Douglas Gregor5bf52692009-09-22 23:15:58 +00002146 AddQualifierToCompletionString(Result, Qualifier, QualifierIsInformative,
2147 S.Context);
Benjamin Kramerb33a97c2009-11-29 20:18:50 +00002148 Result->AddTypedTextChunk(Template->getNameAsString());
Douglas Gregor9eb77012009-11-07 00:00:49 +00002149 Result->AddChunk(Chunk(CodeCompletionString::CK_LeftAngle));
Douglas Gregor3545ff42009-09-21 16:56:56 +00002150 AddTemplateParameterChunks(S.Context, Template, Result);
Douglas Gregor9eb77012009-11-07 00:00:49 +00002151 Result->AddChunk(Chunk(CodeCompletionString::CK_RightAngle));
Douglas Gregor3545ff42009-09-21 16:56:56 +00002152 return Result;
2153 }
2154
Douglas Gregord3c5d792009-11-17 16:44:22 +00002155 if (ObjCMethodDecl *Method = dyn_cast<ObjCMethodDecl>(ND)) {
Douglas Gregord3c5d792009-11-17 16:44:22 +00002156 Selector Sel = Method->getSelector();
2157 if (Sel.isUnarySelector()) {
2158 Result->AddTypedTextChunk(Sel.getIdentifierInfoForSlot(0)->getName());
2159 return Result;
2160 }
2161
Douglas Gregor1b605f72009-11-19 01:08:35 +00002162 std::string SelName = Sel.getIdentifierInfoForSlot(0)->getName().str();
2163 SelName += ':';
2164 if (StartParameter == 0)
2165 Result->AddTypedTextChunk(SelName);
2166 else {
2167 Result->AddInformativeChunk(SelName);
2168
2169 // If there is only one parameter, and we're past it, add an empty
2170 // typed-text chunk since there is nothing to type.
2171 if (Method->param_size() == 1)
2172 Result->AddTypedTextChunk("");
2173 }
Douglas Gregord3c5d792009-11-17 16:44:22 +00002174 unsigned Idx = 0;
2175 for (ObjCMethodDecl::param_iterator P = Method->param_begin(),
2176 PEnd = Method->param_end();
2177 P != PEnd; (void)++P, ++Idx) {
2178 if (Idx > 0) {
Douglas Gregor1b605f72009-11-19 01:08:35 +00002179 std::string Keyword;
2180 if (Idx > StartParameter)
Douglas Gregor6a803932010-01-12 06:38:28 +00002181 Result->AddChunk(CodeCompletionString::CK_HorizontalSpace);
Douglas Gregord3c5d792009-11-17 16:44:22 +00002182 if (IdentifierInfo *II = Sel.getIdentifierInfoForSlot(Idx))
2183 Keyword += II->getName().str();
2184 Keyword += ":";
Douglas Gregor95887f92010-07-08 23:20:03 +00002185 if (Idx < StartParameter || AllParametersAreInformative)
Douglas Gregor1b605f72009-11-19 01:08:35 +00002186 Result->AddInformativeChunk(Keyword);
Douglas Gregor95887f92010-07-08 23:20:03 +00002187 else if (Idx == StartParameter)
Douglas Gregor1b605f72009-11-19 01:08:35 +00002188 Result->AddTypedTextChunk(Keyword);
2189 else
2190 Result->AddTextChunk(Keyword);
Douglas Gregord3c5d792009-11-17 16:44:22 +00002191 }
Douglas Gregor1b605f72009-11-19 01:08:35 +00002192
2193 // If we're before the starting parameter, skip the placeholder.
2194 if (Idx < StartParameter)
2195 continue;
Douglas Gregord3c5d792009-11-17 16:44:22 +00002196
2197 std::string Arg;
Douglas Gregore90dd002010-08-24 16:15:59 +00002198
2199 if ((*P)->getType()->isBlockPointerType() && !DeclaringEntity)
Douglas Gregor981a0c42010-08-29 19:47:46 +00002200 Arg = FormatFunctionParameter(S.Context, *P, true);
Douglas Gregore90dd002010-08-24 16:15:59 +00002201 else {
2202 (*P)->getType().getAsStringInternal(Arg, S.Context.PrintingPolicy);
2203 Arg = "(" + Arg + ")";
2204 if (IdentifierInfo *II = (*P)->getIdentifier())
Douglas Gregor981a0c42010-08-29 19:47:46 +00002205 if (DeclaringEntity || AllParametersAreInformative)
2206 Arg += II->getName().str();
Douglas Gregore90dd002010-08-24 16:15:59 +00002207 }
2208
Douglas Gregor400f5972010-08-31 05:13:43 +00002209 if (Method->isVariadic() && (P + 1) == PEnd)
2210 Arg += ", ...";
2211
Douglas Gregor95887f92010-07-08 23:20:03 +00002212 if (DeclaringEntity)
2213 Result->AddTextChunk(Arg);
2214 else if (AllParametersAreInformative)
Douglas Gregorc8537c52009-11-19 07:41:15 +00002215 Result->AddInformativeChunk(Arg);
2216 else
2217 Result->AddPlaceholderChunk(Arg);
Douglas Gregord3c5d792009-11-17 16:44:22 +00002218 }
2219
Douglas Gregor04c5f972009-12-23 00:21:46 +00002220 if (Method->isVariadic()) {
Douglas Gregor400f5972010-08-31 05:13:43 +00002221 if (Method->param_size() == 0) {
2222 if (DeclaringEntity)
2223 Result->AddTextChunk(", ...");
2224 else if (AllParametersAreInformative)
2225 Result->AddInformativeChunk(", ...");
2226 else
2227 Result->AddPlaceholderChunk(", ...");
2228 }
Douglas Gregordbb71db2010-08-23 23:51:41 +00002229
2230 MaybeAddSentinel(S.Context, Method, Result);
Douglas Gregor04c5f972009-12-23 00:21:46 +00002231 }
2232
Douglas Gregord3c5d792009-11-17 16:44:22 +00002233 return Result;
2234 }
2235
Douglas Gregorf09935f2009-12-01 05:55:20 +00002236 if (Qualifier)
Douglas Gregor5bf52692009-09-22 23:15:58 +00002237 AddQualifierToCompletionString(Result, Qualifier, QualifierIsInformative,
2238 S.Context);
Douglas Gregorf09935f2009-12-01 05:55:20 +00002239
2240 Result->AddTypedTextChunk(ND->getNameAsString());
2241 return Result;
Douglas Gregor3545ff42009-09-21 16:56:56 +00002242}
2243
Douglas Gregorf0f51982009-09-23 00:34:09 +00002244CodeCompletionString *
2245CodeCompleteConsumer::OverloadCandidate::CreateSignatureString(
2246 unsigned CurrentArg,
2247 Sema &S) const {
Douglas Gregor9eb77012009-11-07 00:00:49 +00002248 typedef CodeCompletionString::Chunk Chunk;
2249
Douglas Gregorf0f51982009-09-23 00:34:09 +00002250 CodeCompletionString *Result = new CodeCompletionString;
2251 FunctionDecl *FDecl = getFunction();
Douglas Gregorb3fa9192009-12-18 18:53:37 +00002252 AddResultTypeChunk(S.Context, FDecl, Result);
Douglas Gregorf0f51982009-09-23 00:34:09 +00002253 const FunctionProtoType *Proto
2254 = dyn_cast<FunctionProtoType>(getFunctionType());
2255 if (!FDecl && !Proto) {
2256 // Function without a prototype. Just give the return type and a
2257 // highlighted ellipsis.
2258 const FunctionType *FT = getFunctionType();
2259 Result->AddTextChunk(
Benjamin Kramerb33a97c2009-11-29 20:18:50 +00002260 FT->getResultType().getAsString(S.Context.PrintingPolicy));
Douglas Gregor9eb77012009-11-07 00:00:49 +00002261 Result->AddChunk(Chunk(CodeCompletionString::CK_LeftParen));
2262 Result->AddChunk(Chunk(CodeCompletionString::CK_CurrentParameter, "..."));
2263 Result->AddChunk(Chunk(CodeCompletionString::CK_RightParen));
Douglas Gregorf0f51982009-09-23 00:34:09 +00002264 return Result;
2265 }
2266
2267 if (FDecl)
Benjamin Kramerb33a97c2009-11-29 20:18:50 +00002268 Result->AddTextChunk(FDecl->getNameAsString());
Douglas Gregorf0f51982009-09-23 00:34:09 +00002269 else
2270 Result->AddTextChunk(
Benjamin Kramerb33a97c2009-11-29 20:18:50 +00002271 Proto->getResultType().getAsString(S.Context.PrintingPolicy));
Douglas Gregorf0f51982009-09-23 00:34:09 +00002272
Douglas Gregor9eb77012009-11-07 00:00:49 +00002273 Result->AddChunk(Chunk(CodeCompletionString::CK_LeftParen));
Douglas Gregorf0f51982009-09-23 00:34:09 +00002274 unsigned NumParams = FDecl? FDecl->getNumParams() : Proto->getNumArgs();
2275 for (unsigned I = 0; I != NumParams; ++I) {
2276 if (I)
Douglas Gregor9eb77012009-11-07 00:00:49 +00002277 Result->AddChunk(Chunk(CodeCompletionString::CK_Comma));
Douglas Gregorf0f51982009-09-23 00:34:09 +00002278
2279 std::string ArgString;
2280 QualType ArgType;
2281
2282 if (FDecl) {
2283 ArgString = FDecl->getParamDecl(I)->getNameAsString();
2284 ArgType = FDecl->getParamDecl(I)->getOriginalType();
2285 } else {
2286 ArgType = Proto->getArgType(I);
2287 }
2288
2289 ArgType.getAsStringInternal(ArgString, S.Context.PrintingPolicy);
2290
2291 if (I == CurrentArg)
Douglas Gregor9eb77012009-11-07 00:00:49 +00002292 Result->AddChunk(Chunk(CodeCompletionString::CK_CurrentParameter,
Benjamin Kramerb33a97c2009-11-29 20:18:50 +00002293 ArgString));
Douglas Gregorf0f51982009-09-23 00:34:09 +00002294 else
Benjamin Kramerb33a97c2009-11-29 20:18:50 +00002295 Result->AddTextChunk(ArgString);
Douglas Gregorf0f51982009-09-23 00:34:09 +00002296 }
2297
2298 if (Proto && Proto->isVariadic()) {
Douglas Gregor9eb77012009-11-07 00:00:49 +00002299 Result->AddChunk(Chunk(CodeCompletionString::CK_Comma));
Douglas Gregorf0f51982009-09-23 00:34:09 +00002300 if (CurrentArg < NumParams)
2301 Result->AddTextChunk("...");
2302 else
Douglas Gregor9eb77012009-11-07 00:00:49 +00002303 Result->AddChunk(Chunk(CodeCompletionString::CK_CurrentParameter, "..."));
Douglas Gregorf0f51982009-09-23 00:34:09 +00002304 }
Douglas Gregor9eb77012009-11-07 00:00:49 +00002305 Result->AddChunk(Chunk(CodeCompletionString::CK_RightParen));
Douglas Gregorf0f51982009-09-23 00:34:09 +00002306
2307 return Result;
2308}
2309
Douglas Gregor6e240332010-08-16 16:18:59 +00002310unsigned clang::getMacroUsagePriority(llvm::StringRef MacroName,
2311 bool PreferredTypeIsPointer) {
2312 unsigned Priority = CCP_Macro;
2313
2314 // Treat the "nil" and "NULL" macros as null pointer constants.
2315 if (MacroName.equals("nil") || MacroName.equals("NULL")) {
2316 Priority = CCP_Constant;
2317 if (PreferredTypeIsPointer)
2318 Priority = Priority / CCF_SimilarTypeMatch;
2319 }
2320
2321 return Priority;
2322}
2323
Douglas Gregor09c0eb12010-09-03 23:30:36 +00002324CXCursorKind clang::getCursorKindForDecl(Decl *D) {
2325 if (!D)
2326 return CXCursor_UnexposedDecl;
2327
2328 switch (D->getKind()) {
2329 case Decl::Enum: return CXCursor_EnumDecl;
2330 case Decl::EnumConstant: return CXCursor_EnumConstantDecl;
2331 case Decl::Field: return CXCursor_FieldDecl;
2332 case Decl::Function:
2333 return CXCursor_FunctionDecl;
2334 case Decl::ObjCCategory: return CXCursor_ObjCCategoryDecl;
2335 case Decl::ObjCCategoryImpl: return CXCursor_ObjCCategoryImplDecl;
2336 case Decl::ObjCClass:
2337 // FIXME
2338 return CXCursor_UnexposedDecl;
2339 case Decl::ObjCForwardProtocol:
2340 // FIXME
2341 return CXCursor_UnexposedDecl;
2342 case Decl::ObjCImplementation: return CXCursor_ObjCImplementationDecl;
2343 case Decl::ObjCInterface: return CXCursor_ObjCInterfaceDecl;
2344 case Decl::ObjCIvar: return CXCursor_ObjCIvarDecl;
2345 case Decl::ObjCMethod:
2346 return cast<ObjCMethodDecl>(D)->isInstanceMethod()
2347 ? CXCursor_ObjCInstanceMethodDecl : CXCursor_ObjCClassMethodDecl;
2348 case Decl::CXXMethod: return CXCursor_CXXMethod;
2349 case Decl::CXXConstructor: return CXCursor_Constructor;
2350 case Decl::CXXDestructor: return CXCursor_Destructor;
2351 case Decl::CXXConversion: return CXCursor_ConversionFunction;
2352 case Decl::ObjCProperty: return CXCursor_ObjCPropertyDecl;
2353 case Decl::ObjCProtocol: return CXCursor_ObjCProtocolDecl;
2354 case Decl::ParmVar: return CXCursor_ParmDecl;
2355 case Decl::Typedef: return CXCursor_TypedefDecl;
2356 case Decl::Var: return CXCursor_VarDecl;
2357 case Decl::Namespace: return CXCursor_Namespace;
2358 case Decl::NamespaceAlias: return CXCursor_NamespaceAlias;
2359 case Decl::TemplateTypeParm: return CXCursor_TemplateTypeParameter;
2360 case Decl::NonTypeTemplateParm:return CXCursor_NonTypeTemplateParameter;
2361 case Decl::TemplateTemplateParm:return CXCursor_TemplateTemplateParameter;
2362 case Decl::FunctionTemplate: return CXCursor_FunctionTemplate;
2363 case Decl::ClassTemplate: return CXCursor_ClassTemplate;
2364 case Decl::ClassTemplatePartialSpecialization:
2365 return CXCursor_ClassTemplatePartialSpecialization;
2366 case Decl::UsingDirective: return CXCursor_UsingDirective;
2367
2368 case Decl::Using:
2369 case Decl::UnresolvedUsingValue:
2370 case Decl::UnresolvedUsingTypename:
2371 return CXCursor_UsingDeclaration;
2372
2373 default:
2374 if (TagDecl *TD = dyn_cast<TagDecl>(D)) {
2375 switch (TD->getTagKind()) {
2376 case TTK_Struct: return CXCursor_StructDecl;
2377 case TTK_Class: return CXCursor_ClassDecl;
2378 case TTK_Union: return CXCursor_UnionDecl;
2379 case TTK_Enum: return CXCursor_EnumDecl;
2380 }
2381 }
2382 }
2383
2384 return CXCursor_UnexposedDecl;
2385}
2386
Douglas Gregor55b037b2010-07-08 20:55:51 +00002387static void AddMacroResults(Preprocessor &PP, ResultBuilder &Results,
2388 bool TargetTypeIsPointer = false) {
John McCall276321a2010-08-25 06:19:51 +00002389 typedef CodeCompletionResult Result;
Douglas Gregor55b037b2010-07-08 20:55:51 +00002390
Douglas Gregorf329c7c2009-10-30 16:50:04 +00002391 Results.EnterNewScope();
Douglas Gregor9eb77012009-11-07 00:00:49 +00002392 for (Preprocessor::macro_iterator M = PP.macro_begin(),
2393 MEnd = PP.macro_end();
Douglas Gregor55b037b2010-07-08 20:55:51 +00002394 M != MEnd; ++M) {
Douglas Gregor6e240332010-08-16 16:18:59 +00002395 Results.AddResult(Result(M->first,
2396 getMacroUsagePriority(M->first->getName(),
2397 TargetTypeIsPointer)));
Douglas Gregor55b037b2010-07-08 20:55:51 +00002398 }
Douglas Gregorf329c7c2009-10-30 16:50:04 +00002399 Results.ExitScope();
2400}
2401
Douglas Gregorce0e8562010-08-23 21:54:33 +00002402static void AddPrettyFunctionResults(const LangOptions &LangOpts,
2403 ResultBuilder &Results) {
John McCall276321a2010-08-25 06:19:51 +00002404 typedef CodeCompletionResult Result;
Douglas Gregorce0e8562010-08-23 21:54:33 +00002405
2406 Results.EnterNewScope();
2407 Results.AddResult(Result("__PRETTY_FUNCTION__", CCP_Constant));
2408 Results.AddResult(Result("__FUNCTION__", CCP_Constant));
2409 if (LangOpts.C99 || LangOpts.CPlusPlus0x)
2410 Results.AddResult(Result("__func__", CCP_Constant));
2411 Results.ExitScope();
2412}
2413
Daniel Dunbar242ea9a2009-11-13 08:58:20 +00002414static void HandleCodeCompleteResults(Sema *S,
2415 CodeCompleteConsumer *CodeCompleter,
Douglas Gregor00c37ef2010-08-11 21:23:17 +00002416 CodeCompletionContext Context,
John McCall276321a2010-08-25 06:19:51 +00002417 CodeCompletionResult *Results,
Douglas Gregor00c37ef2010-08-11 21:23:17 +00002418 unsigned NumResults) {
Douglas Gregor3545ff42009-09-21 16:56:56 +00002419 if (CodeCompleter)
Douglas Gregor00c37ef2010-08-11 21:23:17 +00002420 CodeCompleter->ProcessCodeCompleteResults(*S, Context, Results, NumResults);
Douglas Gregor45f83ee2009-11-19 00:01:57 +00002421
2422 for (unsigned I = 0; I != NumResults; ++I)
2423 Results[I].Destroy();
Douglas Gregor3545ff42009-09-21 16:56:56 +00002424}
2425
Douglas Gregor00c37ef2010-08-11 21:23:17 +00002426static enum CodeCompletionContext::Kind mapCodeCompletionContext(Sema &S,
2427 Sema::ParserCompletionContext PCC) {
2428 switch (PCC) {
John McCallfaf5fb42010-08-26 23:41:50 +00002429 case Sema::PCC_Namespace:
Douglas Gregor00c37ef2010-08-11 21:23:17 +00002430 return CodeCompletionContext::CCC_TopLevel;
2431
John McCallfaf5fb42010-08-26 23:41:50 +00002432 case Sema::PCC_Class:
Douglas Gregor00c37ef2010-08-11 21:23:17 +00002433 return CodeCompletionContext::CCC_ClassStructUnion;
2434
John McCallfaf5fb42010-08-26 23:41:50 +00002435 case Sema::PCC_ObjCInterface:
Douglas Gregor00c37ef2010-08-11 21:23:17 +00002436 return CodeCompletionContext::CCC_ObjCInterface;
2437
John McCallfaf5fb42010-08-26 23:41:50 +00002438 case Sema::PCC_ObjCImplementation:
Douglas Gregor00c37ef2010-08-11 21:23:17 +00002439 return CodeCompletionContext::CCC_ObjCImplementation;
2440
John McCallfaf5fb42010-08-26 23:41:50 +00002441 case Sema::PCC_ObjCInstanceVariableList:
Douglas Gregor00c37ef2010-08-11 21:23:17 +00002442 return CodeCompletionContext::CCC_ObjCIvarList;
2443
John McCallfaf5fb42010-08-26 23:41:50 +00002444 case Sema::PCC_Template:
2445 case Sema::PCC_MemberTemplate:
2446 case Sema::PCC_RecoveryInFunction:
Douglas Gregor00c37ef2010-08-11 21:23:17 +00002447 return CodeCompletionContext::CCC_Other;
2448
John McCallfaf5fb42010-08-26 23:41:50 +00002449 case Sema::PCC_Expression:
2450 case Sema::PCC_ForInit:
2451 case Sema::PCC_Condition:
Douglas Gregor00c37ef2010-08-11 21:23:17 +00002452 return CodeCompletionContext::CCC_Expression;
2453
John McCallfaf5fb42010-08-26 23:41:50 +00002454 case Sema::PCC_Statement:
Douglas Gregor00c37ef2010-08-11 21:23:17 +00002455 return CodeCompletionContext::CCC_Statement;
Douglas Gregorf02e5f32010-08-24 01:11:00 +00002456
John McCallfaf5fb42010-08-26 23:41:50 +00002457 case Sema::PCC_Type:
Douglas Gregorf02e5f32010-08-24 01:11:00 +00002458 return CodeCompletionContext::CCC_Type;
Douglas Gregor5e35d592010-09-14 23:59:36 +00002459
2460 case Sema::PCC_ParenthesizedExpression:
2461 return CodeCompletionContext::CCC_ParenthesizedExpression;
Douglas Gregor00c37ef2010-08-11 21:23:17 +00002462 }
2463
2464 return CodeCompletionContext::CCC_Other;
2465}
2466
Douglas Gregorac322ec2010-08-27 21:18:54 +00002467/// \brief If we're in a C++ virtual member function, add completion results
2468/// that invoke the functions we override, since it's common to invoke the
2469/// overridden function as well as adding new functionality.
2470///
2471/// \param S The semantic analysis object for which we are generating results.
2472///
2473/// \param InContext This context in which the nested-name-specifier preceding
2474/// the code-completion point
2475static void MaybeAddOverrideCalls(Sema &S, DeclContext *InContext,
2476 ResultBuilder &Results) {
2477 // Look through blocks.
2478 DeclContext *CurContext = S.CurContext;
2479 while (isa<BlockDecl>(CurContext))
2480 CurContext = CurContext->getParent();
2481
2482
2483 CXXMethodDecl *Method = dyn_cast<CXXMethodDecl>(CurContext);
2484 if (!Method || !Method->isVirtual())
2485 return;
2486
2487 // We need to have names for all of the parameters, if we're going to
2488 // generate a forwarding call.
2489 for (CXXMethodDecl::param_iterator P = Method->param_begin(),
2490 PEnd = Method->param_end();
2491 P != PEnd;
2492 ++P) {
2493 if (!(*P)->getDeclName())
2494 return;
2495 }
2496
2497 for (CXXMethodDecl::method_iterator M = Method->begin_overridden_methods(),
2498 MEnd = Method->end_overridden_methods();
2499 M != MEnd; ++M) {
2500 CodeCompletionString *Pattern = new CodeCompletionString;
2501 CXXMethodDecl *Overridden = const_cast<CXXMethodDecl *>(*M);
2502 if (Overridden->getCanonicalDecl() == Method->getCanonicalDecl())
2503 continue;
2504
2505 // If we need a nested-name-specifier, add one now.
2506 if (!InContext) {
2507 NestedNameSpecifier *NNS
2508 = getRequiredQualification(S.Context, CurContext,
2509 Overridden->getDeclContext());
2510 if (NNS) {
2511 std::string Str;
2512 llvm::raw_string_ostream OS(Str);
2513 NNS->print(OS, S.Context.PrintingPolicy);
2514 Pattern->AddTextChunk(OS.str());
2515 }
2516 } else if (!InContext->Equals(Overridden->getDeclContext()))
2517 continue;
2518
2519 Pattern->AddTypedTextChunk(Overridden->getNameAsString());
2520 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
2521 bool FirstParam = true;
2522 for (CXXMethodDecl::param_iterator P = Method->param_begin(),
2523 PEnd = Method->param_end();
2524 P != PEnd; ++P) {
2525 if (FirstParam)
2526 FirstParam = false;
2527 else
2528 Pattern->AddChunk(CodeCompletionString::CK_Comma);
2529
2530 Pattern->AddPlaceholderChunk((*P)->getIdentifier()->getName());
2531 }
2532 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
2533 Results.AddResult(CodeCompletionResult(Pattern,
2534 CCP_SuperCompletion,
2535 CXCursor_CXXMethod));
2536 Results.Ignore(Overridden);
2537 }
2538}
2539
Douglas Gregor504a6ae2010-01-10 23:08:15 +00002540void Sema::CodeCompleteOrdinaryName(Scope *S,
Douglas Gregor00c37ef2010-08-11 21:23:17 +00002541 ParserCompletionContext CompletionContext) {
John McCall276321a2010-08-25 06:19:51 +00002542 typedef CodeCompletionResult Result;
Douglas Gregorc49f5b22010-08-23 18:23:48 +00002543 ResultBuilder Results(*this);
Douglas Gregorac322ec2010-08-27 21:18:54 +00002544 Results.EnterNewScope();
Douglas Gregor504a6ae2010-01-10 23:08:15 +00002545
2546 // Determine how to filter results, e.g., so that the names of
2547 // values (functions, enumerators, function templates, etc.) are
2548 // only allowed where we can have an expression.
2549 switch (CompletionContext) {
Douglas Gregor00c37ef2010-08-11 21:23:17 +00002550 case PCC_Namespace:
2551 case PCC_Class:
2552 case PCC_ObjCInterface:
2553 case PCC_ObjCImplementation:
2554 case PCC_ObjCInstanceVariableList:
2555 case PCC_Template:
2556 case PCC_MemberTemplate:
Douglas Gregorf02e5f32010-08-24 01:11:00 +00002557 case PCC_Type:
Douglas Gregor504a6ae2010-01-10 23:08:15 +00002558 Results.setFilter(&ResultBuilder::IsOrdinaryNonValueName);
2559 break;
2560
Douglas Gregor00c37ef2010-08-11 21:23:17 +00002561 case PCC_Statement:
Douglas Gregor4d755e82010-08-24 23:58:17 +00002562 // For statements that are expressions, we prefer to call 'void' functions
2563 // rather than functions that return a result, since then the result would
2564 // be ignored.
2565 Results.setPreferredType(Context.VoidTy);
2566 // Fall through
2567
Douglas Gregor5e35d592010-09-14 23:59:36 +00002568 case PCC_ParenthesizedExpression:
Douglas Gregor4d755e82010-08-24 23:58:17 +00002569 case PCC_Expression:
Douglas Gregor00c37ef2010-08-11 21:23:17 +00002570 case PCC_ForInit:
2571 case PCC_Condition:
Douglas Gregor70febae2010-05-28 00:49:12 +00002572 if (WantTypesInContext(CompletionContext, getLangOptions()))
2573 Results.setFilter(&ResultBuilder::IsOrdinaryName);
2574 else
2575 Results.setFilter(&ResultBuilder::IsOrdinaryNonTypeName);
Douglas Gregorac322ec2010-08-27 21:18:54 +00002576
2577 if (getLangOptions().CPlusPlus)
2578 MaybeAddOverrideCalls(*this, /*InContext=*/0, Results);
Douglas Gregor504a6ae2010-01-10 23:08:15 +00002579 break;
Douglas Gregor6da3db42010-05-25 05:58:43 +00002580
Douglas Gregor00c37ef2010-08-11 21:23:17 +00002581 case PCC_RecoveryInFunction:
Douglas Gregor6da3db42010-05-25 05:58:43 +00002582 // Unfiltered
2583 break;
Douglas Gregor504a6ae2010-01-10 23:08:15 +00002584 }
2585
Douglas Gregor9be0ed42010-08-26 16:36:48 +00002586 // If we are in a C++ non-static member function, check the qualifiers on
2587 // the member function to filter/prioritize the results list.
2588 if (CXXMethodDecl *CurMethod = dyn_cast<CXXMethodDecl>(CurContext))
2589 if (CurMethod->isInstance())
2590 Results.setObjectTypeQualifiers(
2591 Qualifiers::fromCVRMask(CurMethod->getTypeQualifiers()));
2592
Douglas Gregorc580c522010-01-14 01:09:38 +00002593 CodeCompletionDeclConsumer Consumer(Results, CurContext);
Douglas Gregor39982192010-08-15 06:18:01 +00002594 LookupVisibleDecls(S, LookupOrdinaryName, Consumer,
2595 CodeCompleter->includeGlobals());
Douglas Gregor92253692009-12-07 09:54:55 +00002596
Douglas Gregorf98e6a22010-01-13 23:51:12 +00002597 AddOrdinaryNameResults(CompletionContext, S, *this, Results);
Douglas Gregor92253692009-12-07 09:54:55 +00002598 Results.ExitScope();
2599
Douglas Gregorce0e8562010-08-23 21:54:33 +00002600 switch (CompletionContext) {
Douglas Gregor5e35d592010-09-14 23:59:36 +00002601 case PCC_ParenthesizedExpression:
Douglas Gregorf02e5f32010-08-24 01:11:00 +00002602 case PCC_Expression:
2603 case PCC_Statement:
2604 case PCC_RecoveryInFunction:
2605 if (S->getFnParent())
2606 AddPrettyFunctionResults(PP.getLangOptions(), Results);
2607 break;
2608
2609 case PCC_Namespace:
2610 case PCC_Class:
2611 case PCC_ObjCInterface:
2612 case PCC_ObjCImplementation:
2613 case PCC_ObjCInstanceVariableList:
2614 case PCC_Template:
2615 case PCC_MemberTemplate:
2616 case PCC_ForInit:
2617 case PCC_Condition:
2618 case PCC_Type:
2619 break;
Douglas Gregorce0e8562010-08-23 21:54:33 +00002620 }
2621
Douglas Gregor9eb77012009-11-07 00:00:49 +00002622 if (CodeCompleter->includeMacros())
Douglas Gregorf98e6a22010-01-13 23:51:12 +00002623 AddMacroResults(PP, Results);
Douglas Gregorce0e8562010-08-23 21:54:33 +00002624
Douglas Gregor00c37ef2010-08-11 21:23:17 +00002625 HandleCodeCompleteResults(this, CodeCompleter,
2626 mapCodeCompletionContext(*this, CompletionContext),
2627 Results.data(),Results.size());
Douglas Gregor9d64c5e2009-09-21 20:51:25 +00002628}
2629
Douglas Gregorbfcea8b2010-09-16 15:14:18 +00002630static void AddClassMessageCompletions(Sema &SemaRef, Scope *S,
2631 ParsedType Receiver,
2632 IdentifierInfo **SelIdents,
2633 unsigned NumSelIdents,
2634 bool IsSuper,
2635 ResultBuilder &Results);
2636
2637void Sema::CodeCompleteDeclSpec(Scope *S, DeclSpec &DS,
2638 bool AllowNonIdentifiers,
2639 bool AllowNestedNameSpecifiers) {
John McCall276321a2010-08-25 06:19:51 +00002640 typedef CodeCompletionResult Result;
Douglas Gregorc49f5b22010-08-23 18:23:48 +00002641 ResultBuilder Results(*this);
2642 Results.EnterNewScope();
2643
2644 // Type qualifiers can come after names.
2645 Results.AddResult(Result("const"));
2646 Results.AddResult(Result("volatile"));
2647 if (getLangOptions().C99)
2648 Results.AddResult(Result("restrict"));
2649
2650 if (getLangOptions().CPlusPlus) {
2651 if (AllowNonIdentifiers) {
2652 Results.AddResult(Result("operator"));
2653 }
2654
2655 // Add nested-name-specifiers.
2656 if (AllowNestedNameSpecifiers) {
2657 Results.allowNestedNameSpecifiers();
2658 CodeCompletionDeclConsumer Consumer(Results, CurContext);
2659 LookupVisibleDecls(S, LookupNestedNameSpecifierName, Consumer,
2660 CodeCompleter->includeGlobals());
2661 }
2662 }
2663 Results.ExitScope();
2664
Douglas Gregorbfcea8b2010-09-16 15:14:18 +00002665 // If we're in a context where we might have an expression (rather than a
2666 // declaration), and what we've seen so far is an Objective-C type that could
2667 // be a receiver of a class message, this may be a class message send with
2668 // the initial opening bracket '[' missing. Add appropriate completions.
2669 if (AllowNonIdentifiers && !AllowNestedNameSpecifiers &&
2670 DS.getTypeSpecType() == DeclSpec::TST_typename &&
2671 DS.getStorageClassSpecAsWritten() == DeclSpec::SCS_unspecified &&
2672 !DS.isThreadSpecified() && !DS.isExternInLinkageSpec() &&
2673 DS.getTypeSpecComplex() == DeclSpec::TSC_unspecified &&
2674 DS.getTypeSpecSign() == DeclSpec::TSS_unspecified &&
2675 DS.getTypeQualifiers() == 0 &&
2676 S &&
2677 (S->getFlags() & Scope::DeclScope) != 0 &&
2678 (S->getFlags() & (Scope::ClassScope | Scope::TemplateParamScope |
2679 Scope::FunctionPrototypeScope |
2680 Scope::AtCatchScope)) == 0) {
2681 ParsedType T = DS.getRepAsType();
2682 if (!T.get().isNull() && T.get()->isObjCObjectOrInterfaceType())
2683 AddClassMessageCompletions(*this, S, T, 0, 0, false, Results);
2684 }
2685
Douglas Gregor56ccce02010-08-24 04:59:56 +00002686 // Note that we intentionally suppress macro results here, since we do not
2687 // encourage using macros to produce the names of entities.
2688
Douglas Gregorc49f5b22010-08-23 18:23:48 +00002689 HandleCodeCompleteResults(this, CodeCompleter,
2690 AllowNestedNameSpecifiers
2691 ? CodeCompletionContext::CCC_PotentiallyQualifiedName
2692 : CodeCompletionContext::CCC_Name,
2693 Results.data(), Results.size());
2694}
2695
Douglas Gregor68762e72010-08-23 21:17:50 +00002696struct Sema::CodeCompleteExpressionData {
2697 CodeCompleteExpressionData(QualType PreferredType = QualType())
2698 : PreferredType(PreferredType), IntegralConstantExpression(false),
2699 ObjCCollection(false) { }
2700
2701 QualType PreferredType;
2702 bool IntegralConstantExpression;
2703 bool ObjCCollection;
2704 llvm::SmallVector<Decl *, 4> IgnoreDecls;
2705};
2706
Douglas Gregor7aa6b222010-05-30 01:49:25 +00002707/// \brief Perform code-completion in an expression context when we know what
2708/// type we're looking for.
Douglas Gregor85b50632010-07-28 21:50:18 +00002709///
2710/// \param IntegralConstantExpression Only permit integral constant
2711/// expressions.
Douglas Gregor68762e72010-08-23 21:17:50 +00002712void Sema::CodeCompleteExpression(Scope *S,
2713 const CodeCompleteExpressionData &Data) {
John McCall276321a2010-08-25 06:19:51 +00002714 typedef CodeCompletionResult Result;
Douglas Gregor7aa6b222010-05-30 01:49:25 +00002715 ResultBuilder Results(*this);
2716
Douglas Gregor68762e72010-08-23 21:17:50 +00002717 if (Data.ObjCCollection)
2718 Results.setFilter(&ResultBuilder::IsObjCCollection);
2719 else if (Data.IntegralConstantExpression)
Douglas Gregor85b50632010-07-28 21:50:18 +00002720 Results.setFilter(&ResultBuilder::IsIntegralConstantValue);
Douglas Gregor00c37ef2010-08-11 21:23:17 +00002721 else if (WantTypesInContext(PCC_Expression, getLangOptions()))
Douglas Gregor7aa6b222010-05-30 01:49:25 +00002722 Results.setFilter(&ResultBuilder::IsOrdinaryName);
2723 else
2724 Results.setFilter(&ResultBuilder::IsOrdinaryNonTypeName);
Douglas Gregor68762e72010-08-23 21:17:50 +00002725
2726 if (!Data.PreferredType.isNull())
2727 Results.setPreferredType(Data.PreferredType.getNonReferenceType());
2728
2729 // Ignore any declarations that we were told that we don't care about.
2730 for (unsigned I = 0, N = Data.IgnoreDecls.size(); I != N; ++I)
2731 Results.Ignore(Data.IgnoreDecls[I]);
Douglas Gregor7aa6b222010-05-30 01:49:25 +00002732
2733 CodeCompletionDeclConsumer Consumer(Results, CurContext);
Douglas Gregor39982192010-08-15 06:18:01 +00002734 LookupVisibleDecls(S, LookupOrdinaryName, Consumer,
2735 CodeCompleter->includeGlobals());
Douglas Gregor7aa6b222010-05-30 01:49:25 +00002736
2737 Results.EnterNewScope();
Douglas Gregor00c37ef2010-08-11 21:23:17 +00002738 AddOrdinaryNameResults(PCC_Expression, S, *this, Results);
Douglas Gregor7aa6b222010-05-30 01:49:25 +00002739 Results.ExitScope();
2740
Douglas Gregor55b037b2010-07-08 20:55:51 +00002741 bool PreferredTypeIsPointer = false;
Douglas Gregor68762e72010-08-23 21:17:50 +00002742 if (!Data.PreferredType.isNull())
2743 PreferredTypeIsPointer = Data.PreferredType->isAnyPointerType()
2744 || Data.PreferredType->isMemberPointerType()
2745 || Data.PreferredType->isBlockPointerType();
Douglas Gregor55b037b2010-07-08 20:55:51 +00002746
Douglas Gregorce0e8562010-08-23 21:54:33 +00002747 if (S->getFnParent() &&
2748 !Data.ObjCCollection &&
2749 !Data.IntegralConstantExpression)
2750 AddPrettyFunctionResults(PP.getLangOptions(), Results);
2751
Douglas Gregor7aa6b222010-05-30 01:49:25 +00002752 if (CodeCompleter->includeMacros())
Douglas Gregor55b037b2010-07-08 20:55:51 +00002753 AddMacroResults(PP, Results, PreferredTypeIsPointer);
Douglas Gregor00c37ef2010-08-11 21:23:17 +00002754 HandleCodeCompleteResults(this, CodeCompleter,
Douglas Gregor68762e72010-08-23 21:17:50 +00002755 CodeCompletionContext(CodeCompletionContext::CCC_Expression,
2756 Data.PreferredType),
Douglas Gregor00c37ef2010-08-11 21:23:17 +00002757 Results.data(),Results.size());
Douglas Gregor7aa6b222010-05-30 01:49:25 +00002758}
2759
Douglas Gregored0b69d2010-09-15 16:23:04 +00002760void Sema::CodeCompletePostfixExpression(Scope *S, Expr *E) {
2761 if (getLangOptions().ObjC1)
2762 CodeCompleteObjCInstanceMessage(S, E, 0, 0, false);
2763}
Douglas Gregor7aa6b222010-05-30 01:49:25 +00002764
Douglas Gregor9291bad2009-11-18 01:29:26 +00002765static void AddObjCProperties(ObjCContainerDecl *Container,
Douglas Gregor5d649882009-11-18 22:32:06 +00002766 bool AllowCategories,
Douglas Gregor9291bad2009-11-18 01:29:26 +00002767 DeclContext *CurContext,
2768 ResultBuilder &Results) {
John McCall276321a2010-08-25 06:19:51 +00002769 typedef CodeCompletionResult Result;
Douglas Gregor9291bad2009-11-18 01:29:26 +00002770
2771 // Add properties in this container.
2772 for (ObjCContainerDecl::prop_iterator P = Container->prop_begin(),
2773 PEnd = Container->prop_end();
2774 P != PEnd;
2775 ++P)
2776 Results.MaybeAddResult(Result(*P, 0), CurContext);
2777
2778 // Add properties in referenced protocols.
2779 if (ObjCProtocolDecl *Protocol = dyn_cast<ObjCProtocolDecl>(Container)) {
2780 for (ObjCProtocolDecl::protocol_iterator P = Protocol->protocol_begin(),
2781 PEnd = Protocol->protocol_end();
2782 P != PEnd; ++P)
Douglas Gregor5d649882009-11-18 22:32:06 +00002783 AddObjCProperties(*P, AllowCategories, CurContext, Results);
Douglas Gregor9291bad2009-11-18 01:29:26 +00002784 } else if (ObjCInterfaceDecl *IFace = dyn_cast<ObjCInterfaceDecl>(Container)){
Douglas Gregor5d649882009-11-18 22:32:06 +00002785 if (AllowCategories) {
2786 // Look through categories.
2787 for (ObjCCategoryDecl *Category = IFace->getCategoryList();
2788 Category; Category = Category->getNextClassCategory())
2789 AddObjCProperties(Category, AllowCategories, CurContext, Results);
2790 }
Douglas Gregor9291bad2009-11-18 01:29:26 +00002791
2792 // Look through protocols.
Ted Kremenek0ef508d2010-09-01 01:21:15 +00002793 for (ObjCInterfaceDecl::all_protocol_iterator
2794 I = IFace->all_referenced_protocol_begin(),
2795 E = IFace->all_referenced_protocol_end(); I != E; ++I)
Douglas Gregor5d649882009-11-18 22:32:06 +00002796 AddObjCProperties(*I, AllowCategories, CurContext, Results);
Douglas Gregor9291bad2009-11-18 01:29:26 +00002797
2798 // Look in the superclass.
2799 if (IFace->getSuperClass())
Douglas Gregor5d649882009-11-18 22:32:06 +00002800 AddObjCProperties(IFace->getSuperClass(), AllowCategories, CurContext,
2801 Results);
Douglas Gregor9291bad2009-11-18 01:29:26 +00002802 } else if (const ObjCCategoryDecl *Category
2803 = dyn_cast<ObjCCategoryDecl>(Container)) {
2804 // Look through protocols.
Ted Kremenek0ef508d2010-09-01 01:21:15 +00002805 for (ObjCCategoryDecl::protocol_iterator P = Category->protocol_begin(),
2806 PEnd = Category->protocol_end();
Douglas Gregor9291bad2009-11-18 01:29:26 +00002807 P != PEnd; ++P)
Douglas Gregor5d649882009-11-18 22:32:06 +00002808 AddObjCProperties(*P, AllowCategories, CurContext, Results);
Douglas Gregor9291bad2009-11-18 01:29:26 +00002809 }
2810}
2811
Douglas Gregor2436e712009-09-17 21:32:03 +00002812void Sema::CodeCompleteMemberReferenceExpr(Scope *S, ExprTy *BaseE,
2813 SourceLocation OpLoc,
2814 bool IsArrow) {
2815 if (!BaseE || !CodeCompleter)
2816 return;
2817
John McCall276321a2010-08-25 06:19:51 +00002818 typedef CodeCompletionResult Result;
Douglas Gregor3545ff42009-09-21 16:56:56 +00002819
Douglas Gregor2436e712009-09-17 21:32:03 +00002820 Expr *Base = static_cast<Expr *>(BaseE);
2821 QualType BaseType = Base->getType();
Douglas Gregor3545ff42009-09-21 16:56:56 +00002822
2823 if (IsArrow) {
2824 if (const PointerType *Ptr = BaseType->getAs<PointerType>())
2825 BaseType = Ptr->getPointeeType();
2826 else if (BaseType->isObjCObjectPointerType())
Douglas Gregor9be0ed42010-08-26 16:36:48 +00002827 /*Do nothing*/ ;
Douglas Gregor3545ff42009-09-21 16:56:56 +00002828 else
2829 return;
2830 }
2831
Douglas Gregore412a5a2009-09-23 22:26:46 +00002832 ResultBuilder Results(*this, &ResultBuilder::IsMember);
Douglas Gregor9291bad2009-11-18 01:29:26 +00002833 Results.EnterNewScope();
2834 if (const RecordType *Record = BaseType->getAs<RecordType>()) {
Douglas Gregor9be0ed42010-08-26 16:36:48 +00002835 // Indicate that we are performing a member access, and the cv-qualifiers
2836 // for the base object type.
2837 Results.setObjectTypeQualifiers(BaseType.getQualifiers());
2838
Douglas Gregor9291bad2009-11-18 01:29:26 +00002839 // Access to a C/C++ class, struct, or union.
Douglas Gregor6ae4c522010-01-14 03:21:49 +00002840 Results.allowNestedNameSpecifiers();
Douglas Gregor09bbc652010-01-14 15:47:35 +00002841 CodeCompletionDeclConsumer Consumer(Results, CurContext);
Douglas Gregor39982192010-08-15 06:18:01 +00002842 LookupVisibleDecls(Record->getDecl(), LookupMemberName, Consumer,
2843 CodeCompleter->includeGlobals());
Daniel Dunbar242ea9a2009-11-13 08:58:20 +00002844
Douglas Gregor9291bad2009-11-18 01:29:26 +00002845 if (getLangOptions().CPlusPlus) {
2846 if (!Results.empty()) {
2847 // The "template" keyword can follow "->" or "." in the grammar.
2848 // However, we only want to suggest the template keyword if something
2849 // is dependent.
2850 bool IsDependent = BaseType->isDependentType();
2851 if (!IsDependent) {
2852 for (Scope *DepScope = S; DepScope; DepScope = DepScope->getParent())
2853 if (DeclContext *Ctx = (DeclContext *)DepScope->getEntity()) {
2854 IsDependent = Ctx->isDependentContext();
2855 break;
2856 }
2857 }
Daniel Dunbar242ea9a2009-11-13 08:58:20 +00002858
Douglas Gregor9291bad2009-11-18 01:29:26 +00002859 if (IsDependent)
Douglas Gregor78a21012010-01-14 16:01:26 +00002860 Results.AddResult(Result("template"));
Daniel Dunbar242ea9a2009-11-13 08:58:20 +00002861 }
Daniel Dunbar242ea9a2009-11-13 08:58:20 +00002862 }
Douglas Gregor9291bad2009-11-18 01:29:26 +00002863 } else if (!IsArrow && BaseType->getAsObjCInterfacePointerType()) {
2864 // Objective-C property reference.
2865
2866 // Add property results based on our interface.
2867 const ObjCObjectPointerType *ObjCPtr
2868 = BaseType->getAsObjCInterfacePointerType();
2869 assert(ObjCPtr && "Non-NULL pointer guaranteed above!");
Douglas Gregor5d649882009-11-18 22:32:06 +00002870 AddObjCProperties(ObjCPtr->getInterfaceDecl(), true, CurContext, Results);
Douglas Gregor9291bad2009-11-18 01:29:26 +00002871
2872 // Add properties from the protocols in a qualified interface.
2873 for (ObjCObjectPointerType::qual_iterator I = ObjCPtr->qual_begin(),
2874 E = ObjCPtr->qual_end();
2875 I != E; ++I)
Douglas Gregor5d649882009-11-18 22:32:06 +00002876 AddObjCProperties(*I, true, CurContext, Results);
Douglas Gregor9291bad2009-11-18 01:29:26 +00002877 } else if ((IsArrow && BaseType->isObjCObjectPointerType()) ||
John McCall8b07ec22010-05-15 11:32:37 +00002878 (!IsArrow && BaseType->isObjCObjectType())) {
Douglas Gregor9291bad2009-11-18 01:29:26 +00002879 // Objective-C instance variable access.
2880 ObjCInterfaceDecl *Class = 0;
2881 if (const ObjCObjectPointerType *ObjCPtr
2882 = BaseType->getAs<ObjCObjectPointerType>())
2883 Class = ObjCPtr->getInterfaceDecl();
2884 else
John McCall8b07ec22010-05-15 11:32:37 +00002885 Class = BaseType->getAs<ObjCObjectType>()->getInterface();
Douglas Gregor9291bad2009-11-18 01:29:26 +00002886
2887 // Add all ivars from this class and its superclasses.
Douglas Gregor2b8162b2010-01-14 16:08:12 +00002888 if (Class) {
2889 CodeCompletionDeclConsumer Consumer(Results, CurContext);
2890 Results.setFilter(&ResultBuilder::IsObjCIvar);
Douglas Gregor39982192010-08-15 06:18:01 +00002891 LookupVisibleDecls(Class, LookupMemberName, Consumer,
2892 CodeCompleter->includeGlobals());
Douglas Gregor9291bad2009-11-18 01:29:26 +00002893 }
Douglas Gregor3545ff42009-09-21 16:56:56 +00002894 }
Douglas Gregor9291bad2009-11-18 01:29:26 +00002895
2896 // FIXME: How do we cope with isa?
2897
2898 Results.ExitScope();
Daniel Dunbar242ea9a2009-11-13 08:58:20 +00002899
Daniel Dunbar242ea9a2009-11-13 08:58:20 +00002900 // Hand off the results found for code completion.
Douglas Gregor00c37ef2010-08-11 21:23:17 +00002901 HandleCodeCompleteResults(this, CodeCompleter,
2902 CodeCompletionContext(CodeCompletionContext::CCC_MemberAccess,
2903 BaseType),
2904 Results.data(),Results.size());
Douglas Gregor2436e712009-09-17 21:32:03 +00002905}
2906
Douglas Gregorf45b0cf2009-09-18 15:37:17 +00002907void Sema::CodeCompleteTag(Scope *S, unsigned TagSpec) {
2908 if (!CodeCompleter)
2909 return;
2910
John McCall276321a2010-08-25 06:19:51 +00002911 typedef CodeCompletionResult Result;
Douglas Gregor3545ff42009-09-21 16:56:56 +00002912 ResultBuilder::LookupFilter Filter = 0;
Douglas Gregor00c37ef2010-08-11 21:23:17 +00002913 enum CodeCompletionContext::Kind ContextKind
2914 = CodeCompletionContext::CCC_Other;
Douglas Gregorf45b0cf2009-09-18 15:37:17 +00002915 switch ((DeclSpec::TST)TagSpec) {
2916 case DeclSpec::TST_enum:
Douglas Gregor3545ff42009-09-21 16:56:56 +00002917 Filter = &ResultBuilder::IsEnum;
Douglas Gregor00c37ef2010-08-11 21:23:17 +00002918 ContextKind = CodeCompletionContext::CCC_EnumTag;
Douglas Gregorf45b0cf2009-09-18 15:37:17 +00002919 break;
2920
2921 case DeclSpec::TST_union:
Douglas Gregor3545ff42009-09-21 16:56:56 +00002922 Filter = &ResultBuilder::IsUnion;
Douglas Gregor00c37ef2010-08-11 21:23:17 +00002923 ContextKind = CodeCompletionContext::CCC_UnionTag;
Douglas Gregorf45b0cf2009-09-18 15:37:17 +00002924 break;
2925
2926 case DeclSpec::TST_struct:
Douglas Gregorf45b0cf2009-09-18 15:37:17 +00002927 case DeclSpec::TST_class:
Douglas Gregor3545ff42009-09-21 16:56:56 +00002928 Filter = &ResultBuilder::IsClassOrStruct;
Douglas Gregor00c37ef2010-08-11 21:23:17 +00002929 ContextKind = CodeCompletionContext::CCC_ClassOrStructTag;
Douglas Gregorf45b0cf2009-09-18 15:37:17 +00002930 break;
2931
2932 default:
2933 assert(false && "Unknown type specifier kind in CodeCompleteTag");
2934 return;
2935 }
Douglas Gregor3545ff42009-09-21 16:56:56 +00002936
John McCalle87beb22010-04-23 18:46:30 +00002937 ResultBuilder Results(*this);
Douglas Gregora6e2edc2010-01-14 03:27:13 +00002938 CodeCompletionDeclConsumer Consumer(Results, CurContext);
John McCalle87beb22010-04-23 18:46:30 +00002939
2940 // First pass: look for tags.
2941 Results.setFilter(Filter);
Douglas Gregor39982192010-08-15 06:18:01 +00002942 LookupVisibleDecls(S, LookupTagName, Consumer,
2943 CodeCompleter->includeGlobals());
John McCalle87beb22010-04-23 18:46:30 +00002944
Douglas Gregor39982192010-08-15 06:18:01 +00002945 if (CodeCompleter->includeGlobals()) {
2946 // Second pass: look for nested name specifiers.
2947 Results.setFilter(&ResultBuilder::IsNestedNameSpecifier);
2948 LookupVisibleDecls(S, LookupNestedNameSpecifierName, Consumer);
2949 }
Douglas Gregor3545ff42009-09-21 16:56:56 +00002950
Douglas Gregor00c37ef2010-08-11 21:23:17 +00002951 HandleCodeCompleteResults(this, CodeCompleter, ContextKind,
2952 Results.data(),Results.size());
Douglas Gregorf45b0cf2009-09-18 15:37:17 +00002953}
2954
Douglas Gregor28c78432010-08-27 17:35:51 +00002955void Sema::CodeCompleteTypeQualifiers(DeclSpec &DS) {
2956 ResultBuilder Results(*this);
2957 Results.EnterNewScope();
2958 if (!(DS.getTypeQualifiers() & DeclSpec::TQ_const))
2959 Results.AddResult("const");
2960 if (!(DS.getTypeQualifiers() & DeclSpec::TQ_volatile))
2961 Results.AddResult("volatile");
2962 if (getLangOptions().C99 &&
2963 !(DS.getTypeQualifiers() & DeclSpec::TQ_restrict))
2964 Results.AddResult("restrict");
2965 Results.ExitScope();
2966 HandleCodeCompleteResults(this, CodeCompleter,
2967 CodeCompletionContext::CCC_TypeQualifiers,
2968 Results.data(), Results.size());
2969}
2970
Douglas Gregord328d572009-09-21 18:10:23 +00002971void Sema::CodeCompleteCase(Scope *S) {
John McCallaab3e412010-08-25 08:40:02 +00002972 if (getCurFunction()->SwitchStack.empty() || !CodeCompleter)
Douglas Gregord328d572009-09-21 18:10:23 +00002973 return;
2974
John McCallaab3e412010-08-25 08:40:02 +00002975 SwitchStmt *Switch = getCurFunction()->SwitchStack.back();
Douglas Gregor85b50632010-07-28 21:50:18 +00002976 if (!Switch->getCond()->getType()->isEnumeralType()) {
Douglas Gregor68762e72010-08-23 21:17:50 +00002977 CodeCompleteExpressionData Data(Switch->getCond()->getType());
2978 Data.IntegralConstantExpression = true;
2979 CodeCompleteExpression(S, Data);
Douglas Gregord328d572009-09-21 18:10:23 +00002980 return;
Douglas Gregor85b50632010-07-28 21:50:18 +00002981 }
Douglas Gregord328d572009-09-21 18:10:23 +00002982
2983 // Code-complete the cases of a switch statement over an enumeration type
2984 // by providing the list of
2985 EnumDecl *Enum = Switch->getCond()->getType()->getAs<EnumType>()->getDecl();
2986
2987 // Determine which enumerators we have already seen in the switch statement.
2988 // FIXME: Ideally, we would also be able to look *past* the code-completion
2989 // token, in case we are code-completing in the middle of the switch and not
2990 // at the end. However, we aren't able to do so at the moment.
2991 llvm::SmallPtrSet<EnumConstantDecl *, 8> EnumeratorsSeen;
Douglas Gregorf2510672009-09-21 19:57:38 +00002992 NestedNameSpecifier *Qualifier = 0;
Douglas Gregord328d572009-09-21 18:10:23 +00002993 for (SwitchCase *SC = Switch->getSwitchCaseList(); SC;
2994 SC = SC->getNextSwitchCase()) {
2995 CaseStmt *Case = dyn_cast<CaseStmt>(SC);
2996 if (!Case)
2997 continue;
2998
2999 Expr *CaseVal = Case->getLHS()->IgnoreParenCasts();
3000 if (DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(CaseVal))
3001 if (EnumConstantDecl *Enumerator
3002 = dyn_cast<EnumConstantDecl>(DRE->getDecl())) {
3003 // We look into the AST of the case statement to determine which
3004 // enumerator was named. Alternatively, we could compute the value of
3005 // the integral constant expression, then compare it against the
3006 // values of each enumerator. However, value-based approach would not
3007 // work as well with C++ templates where enumerators declared within a
3008 // template are type- and value-dependent.
3009 EnumeratorsSeen.insert(Enumerator);
3010
Douglas Gregorf2510672009-09-21 19:57:38 +00003011 // If this is a qualified-id, keep track of the nested-name-specifier
3012 // so that we can reproduce it as part of code completion, e.g.,
Douglas Gregord328d572009-09-21 18:10:23 +00003013 //
3014 // switch (TagD.getKind()) {
3015 // case TagDecl::TK_enum:
3016 // break;
3017 // case XXX
3018 //
Douglas Gregorf2510672009-09-21 19:57:38 +00003019 // At the XXX, our completions are TagDecl::TK_union,
Douglas Gregord328d572009-09-21 18:10:23 +00003020 // TagDecl::TK_struct, and TagDecl::TK_class, rather than TK_union,
3021 // TK_struct, and TK_class.
Douglas Gregor4bd90e52009-10-23 18:54:35 +00003022 Qualifier = DRE->getQualifier();
Douglas Gregord328d572009-09-21 18:10:23 +00003023 }
3024 }
3025
Douglas Gregorf2510672009-09-21 19:57:38 +00003026 if (getLangOptions().CPlusPlus && !Qualifier && EnumeratorsSeen.empty()) {
3027 // If there are no prior enumerators in C++, check whether we have to
3028 // qualify the names of the enumerators that we suggest, because they
3029 // may not be visible in this scope.
3030 Qualifier = getRequiredQualification(Context, CurContext,
3031 Enum->getDeclContext());
3032
3033 // FIXME: Scoped enums need to start with "EnumDecl" as the context!
3034 }
3035
Douglas Gregord328d572009-09-21 18:10:23 +00003036 // Add any enumerators that have not yet been mentioned.
3037 ResultBuilder Results(*this);
3038 Results.EnterNewScope();
3039 for (EnumDecl::enumerator_iterator E = Enum->enumerator_begin(),
3040 EEnd = Enum->enumerator_end();
3041 E != EEnd; ++E) {
3042 if (EnumeratorsSeen.count(*E))
3043 continue;
3044
John McCall276321a2010-08-25 06:19:51 +00003045 Results.AddResult(CodeCompletionResult(*E, Qualifier),
Douglas Gregorfc59ce12010-01-14 16:14:35 +00003046 CurContext, 0, false);
Douglas Gregord328d572009-09-21 18:10:23 +00003047 }
3048 Results.ExitScope();
Douglas Gregor285560922010-04-06 20:02:15 +00003049
Douglas Gregor9eb77012009-11-07 00:00:49 +00003050 if (CodeCompleter->includeMacros())
Douglas Gregorf98e6a22010-01-13 23:51:12 +00003051 AddMacroResults(PP, Results);
Douglas Gregor00c37ef2010-08-11 21:23:17 +00003052 HandleCodeCompleteResults(this, CodeCompleter,
3053 CodeCompletionContext::CCC_Expression,
3054 Results.data(),Results.size());
Douglas Gregord328d572009-09-21 18:10:23 +00003055}
3056
Douglas Gregorcabea402009-09-22 15:41:20 +00003057namespace {
3058 struct IsBetterOverloadCandidate {
3059 Sema &S;
John McCallbc077cf2010-02-08 23:07:23 +00003060 SourceLocation Loc;
Douglas Gregorcabea402009-09-22 15:41:20 +00003061
3062 public:
John McCallbc077cf2010-02-08 23:07:23 +00003063 explicit IsBetterOverloadCandidate(Sema &S, SourceLocation Loc)
3064 : S(S), Loc(Loc) { }
Douglas Gregorcabea402009-09-22 15:41:20 +00003065
3066 bool
3067 operator()(const OverloadCandidate &X, const OverloadCandidate &Y) const {
John McCall5c32be02010-08-24 20:38:10 +00003068 return isBetterOverloadCandidate(S, X, Y, Loc);
Douglas Gregorcabea402009-09-22 15:41:20 +00003069 }
3070 };
3071}
3072
Douglas Gregor6ed3eb82010-05-30 06:10:08 +00003073static bool anyNullArguments(Expr **Args, unsigned NumArgs) {
3074 if (NumArgs && !Args)
3075 return true;
3076
3077 for (unsigned I = 0; I != NumArgs; ++I)
3078 if (!Args[I])
3079 return true;
3080
3081 return false;
3082}
3083
Douglas Gregorcabea402009-09-22 15:41:20 +00003084void Sema::CodeCompleteCall(Scope *S, ExprTy *FnIn,
3085 ExprTy **ArgsIn, unsigned NumArgs) {
3086 if (!CodeCompleter)
3087 return;
Douglas Gregor3ef59522009-12-11 19:06:04 +00003088
3089 // When we're code-completing for a call, we fall back to ordinary
3090 // name code-completion whenever we can't produce specific
3091 // results. We may want to revisit this strategy in the future,
3092 // e.g., by merging the two kinds of results.
3093
Douglas Gregorcabea402009-09-22 15:41:20 +00003094 Expr *Fn = (Expr *)FnIn;
3095 Expr **Args = (Expr **)ArgsIn;
Douglas Gregor3ef59522009-12-11 19:06:04 +00003096
Douglas Gregorcabea402009-09-22 15:41:20 +00003097 // Ignore type-dependent call expressions entirely.
Douglas Gregor6ed3eb82010-05-30 06:10:08 +00003098 if (!Fn || Fn->isTypeDependent() || anyNullArguments(Args, NumArgs) ||
Douglas Gregor3ef59522009-12-11 19:06:04 +00003099 Expr::hasAnyTypeDependentArguments(Args, NumArgs)) {
Douglas Gregor00c37ef2010-08-11 21:23:17 +00003100 CodeCompleteOrdinaryName(S, PCC_Expression);
Douglas Gregorcabea402009-09-22 15:41:20 +00003101 return;
Douglas Gregor3ef59522009-12-11 19:06:04 +00003102 }
Douglas Gregorcabea402009-09-22 15:41:20 +00003103
John McCall57500772009-12-16 12:17:52 +00003104 // Build an overload candidate set based on the functions we find.
John McCallbc077cf2010-02-08 23:07:23 +00003105 SourceLocation Loc = Fn->getExprLoc();
3106 OverloadCandidateSet CandidateSet(Loc);
John McCall57500772009-12-16 12:17:52 +00003107
Douglas Gregorcabea402009-09-22 15:41:20 +00003108 // FIXME: What if we're calling something that isn't a function declaration?
3109 // FIXME: What if we're calling a pseudo-destructor?
3110 // FIXME: What if we're calling a member function?
3111
Douglas Gregorff59f672010-01-21 15:46:19 +00003112 typedef CodeCompleteConsumer::OverloadCandidate ResultCandidate;
3113 llvm::SmallVector<ResultCandidate, 8> Results;
3114
John McCall57500772009-12-16 12:17:52 +00003115 Expr *NakedFn = Fn->IgnoreParenCasts();
3116 if (UnresolvedLookupExpr *ULE = dyn_cast<UnresolvedLookupExpr>(NakedFn))
3117 AddOverloadedCallCandidates(ULE, Args, NumArgs, CandidateSet,
3118 /*PartialOverloading=*/ true);
3119 else if (DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(NakedFn)) {
3120 FunctionDecl *FDecl = dyn_cast<FunctionDecl>(DRE->getDecl());
Douglas Gregorff59f672010-01-21 15:46:19 +00003121 if (FDecl) {
Douglas Gregor6ed3eb82010-05-30 06:10:08 +00003122 if (!getLangOptions().CPlusPlus ||
3123 !FDecl->getType()->getAs<FunctionProtoType>())
Douglas Gregorff59f672010-01-21 15:46:19 +00003124 Results.push_back(ResultCandidate(FDecl));
3125 else
John McCallb89836b2010-01-26 01:37:31 +00003126 // FIXME: access?
John McCalla0296f72010-03-19 07:35:19 +00003127 AddOverloadCandidate(FDecl, DeclAccessPair::make(FDecl, AS_none),
3128 Args, NumArgs, CandidateSet,
Douglas Gregorb05275a2010-04-16 17:41:49 +00003129 false, /*PartialOverloading*/true);
Douglas Gregorff59f672010-01-21 15:46:19 +00003130 }
John McCall57500772009-12-16 12:17:52 +00003131 }
Douglas Gregorcabea402009-09-22 15:41:20 +00003132
Douglas Gregor7aa6b222010-05-30 01:49:25 +00003133 QualType ParamType;
3134
Douglas Gregorff59f672010-01-21 15:46:19 +00003135 if (!CandidateSet.empty()) {
3136 // Sort the overload candidate set by placing the best overloads first.
3137 std::stable_sort(CandidateSet.begin(), CandidateSet.end(),
John McCallbc077cf2010-02-08 23:07:23 +00003138 IsBetterOverloadCandidate(*this, Loc));
Douglas Gregorcabea402009-09-22 15:41:20 +00003139
Douglas Gregorff59f672010-01-21 15:46:19 +00003140 // Add the remaining viable overload candidates as code-completion reslults.
3141 for (OverloadCandidateSet::iterator Cand = CandidateSet.begin(),
3142 CandEnd = CandidateSet.end();
3143 Cand != CandEnd; ++Cand) {
3144 if (Cand->Viable)
3145 Results.push_back(ResultCandidate(Cand->Function));
3146 }
Douglas Gregor7aa6b222010-05-30 01:49:25 +00003147
3148 // From the viable candidates, try to determine the type of this parameter.
3149 for (unsigned I = 0, N = Results.size(); I != N; ++I) {
3150 if (const FunctionType *FType = Results[I].getFunctionType())
3151 if (const FunctionProtoType *Proto = dyn_cast<FunctionProtoType>(FType))
3152 if (NumArgs < Proto->getNumArgs()) {
3153 if (ParamType.isNull())
3154 ParamType = Proto->getArgType(NumArgs);
3155 else if (!Context.hasSameUnqualifiedType(
3156 ParamType.getNonReferenceType(),
3157 Proto->getArgType(NumArgs).getNonReferenceType())) {
3158 ParamType = QualType();
3159 break;
3160 }
3161 }
3162 }
3163 } else {
3164 // Try to determine the parameter type from the type of the expression
3165 // being called.
3166 QualType FunctionType = Fn->getType();
3167 if (const PointerType *Ptr = FunctionType->getAs<PointerType>())
3168 FunctionType = Ptr->getPointeeType();
3169 else if (const BlockPointerType *BlockPtr
3170 = FunctionType->getAs<BlockPointerType>())
3171 FunctionType = BlockPtr->getPointeeType();
3172 else if (const MemberPointerType *MemPtr
3173 = FunctionType->getAs<MemberPointerType>())
3174 FunctionType = MemPtr->getPointeeType();
3175
3176 if (const FunctionProtoType *Proto
3177 = FunctionType->getAs<FunctionProtoType>()) {
3178 if (NumArgs < Proto->getNumArgs())
3179 ParamType = Proto->getArgType(NumArgs);
3180 }
Douglas Gregorcabea402009-09-22 15:41:20 +00003181 }
Douglas Gregor3ef59522009-12-11 19:06:04 +00003182
Douglas Gregor7aa6b222010-05-30 01:49:25 +00003183 if (ParamType.isNull())
Douglas Gregor00c37ef2010-08-11 21:23:17 +00003184 CodeCompleteOrdinaryName(S, PCC_Expression);
Douglas Gregor7aa6b222010-05-30 01:49:25 +00003185 else
3186 CodeCompleteExpression(S, ParamType);
3187
Douglas Gregorc01890e2010-04-06 20:19:47 +00003188 if (!Results.empty())
Douglas Gregor3ef59522009-12-11 19:06:04 +00003189 CodeCompleter->ProcessOverloadCandidates(*this, NumArgs, Results.data(),
3190 Results.size());
Douglas Gregorcabea402009-09-22 15:41:20 +00003191}
3192
John McCall48871652010-08-21 09:40:31 +00003193void Sema::CodeCompleteInitializer(Scope *S, Decl *D) {
3194 ValueDecl *VD = dyn_cast_or_null<ValueDecl>(D);
Douglas Gregor7aa6b222010-05-30 01:49:25 +00003195 if (!VD) {
Douglas Gregor00c37ef2010-08-11 21:23:17 +00003196 CodeCompleteOrdinaryName(S, PCC_Expression);
Douglas Gregor7aa6b222010-05-30 01:49:25 +00003197 return;
3198 }
3199
3200 CodeCompleteExpression(S, VD->getType());
3201}
3202
3203void Sema::CodeCompleteReturn(Scope *S) {
3204 QualType ResultType;
3205 if (isa<BlockDecl>(CurContext)) {
3206 if (BlockScopeInfo *BSI = getCurBlock())
3207 ResultType = BSI->ReturnType;
3208 } else if (FunctionDecl *Function = dyn_cast<FunctionDecl>(CurContext))
3209 ResultType = Function->getResultType();
3210 else if (ObjCMethodDecl *Method = dyn_cast<ObjCMethodDecl>(CurContext))
3211 ResultType = Method->getResultType();
3212
3213 if (ResultType.isNull())
Douglas Gregor00c37ef2010-08-11 21:23:17 +00003214 CodeCompleteOrdinaryName(S, PCC_Expression);
Douglas Gregor7aa6b222010-05-30 01:49:25 +00003215 else
3216 CodeCompleteExpression(S, ResultType);
3217}
3218
3219void Sema::CodeCompleteAssignmentRHS(Scope *S, ExprTy *LHS) {
3220 if (LHS)
3221 CodeCompleteExpression(S, static_cast<Expr *>(LHS)->getType());
3222 else
Douglas Gregor00c37ef2010-08-11 21:23:17 +00003223 CodeCompleteOrdinaryName(S, PCC_Expression);
Douglas Gregor7aa6b222010-05-30 01:49:25 +00003224}
3225
Jeffrey Yasskinc76498d2010-04-08 16:38:48 +00003226void Sema::CodeCompleteQualifiedId(Scope *S, CXXScopeSpec &SS,
Douglas Gregor2436e712009-09-17 21:32:03 +00003227 bool EnteringContext) {
3228 if (!SS.getScopeRep() || !CodeCompleter)
3229 return;
3230
Douglas Gregor3545ff42009-09-21 16:56:56 +00003231 DeclContext *Ctx = computeDeclContext(SS, EnteringContext);
3232 if (!Ctx)
3233 return;
Douglas Gregor800f2f02009-12-11 18:28:39 +00003234
3235 // Try to instantiate any non-dependent declaration contexts before
3236 // we look in them.
John McCall0b66eb32010-05-01 00:40:08 +00003237 if (!isDependentScopeSpecifier(SS) && RequireCompleteDeclContext(SS, Ctx))
Douglas Gregor800f2f02009-12-11 18:28:39 +00003238 return;
3239
Douglas Gregor3545ff42009-09-21 16:56:56 +00003240 ResultBuilder Results(*this);
Douglas Gregor3545ff42009-09-21 16:56:56 +00003241
Douglas Gregorac322ec2010-08-27 21:18:54 +00003242 Results.EnterNewScope();
Douglas Gregor3545ff42009-09-21 16:56:56 +00003243 // The "template" keyword can follow "::" in the grammar, but only
3244 // put it into the grammar if the nested-name-specifier is dependent.
3245 NestedNameSpecifier *NNS = (NestedNameSpecifier *)SS.getScopeRep();
3246 if (!Results.empty() && NNS->isDependent())
Douglas Gregor78a21012010-01-14 16:01:26 +00003247 Results.AddResult("template");
Douglas Gregorac322ec2010-08-27 21:18:54 +00003248
3249 // Add calls to overridden virtual functions, if there are any.
3250 //
3251 // FIXME: This isn't wonderful, because we don't know whether we're actually
3252 // in a context that permits expressions. This is a general issue with
3253 // qualified-id completions.
3254 if (!EnteringContext)
3255 MaybeAddOverrideCalls(*this, Ctx, Results);
3256 Results.ExitScope();
Douglas Gregor3545ff42009-09-21 16:56:56 +00003257
Douglas Gregorac322ec2010-08-27 21:18:54 +00003258 CodeCompletionDeclConsumer Consumer(Results, CurContext);
3259 LookupVisibleDecls(Ctx, LookupOrdinaryName, Consumer);
3260
Douglas Gregor00c37ef2010-08-11 21:23:17 +00003261 HandleCodeCompleteResults(this, CodeCompleter,
Douglas Gregorac322ec2010-08-27 21:18:54 +00003262 CodeCompletionContext::CCC_Name,
Douglas Gregor00c37ef2010-08-11 21:23:17 +00003263 Results.data(),Results.size());
Douglas Gregor2436e712009-09-17 21:32:03 +00003264}
Douglas Gregor7e90c6d2009-09-18 19:03:04 +00003265
3266void Sema::CodeCompleteUsing(Scope *S) {
3267 if (!CodeCompleter)
3268 return;
3269
Douglas Gregor3545ff42009-09-21 16:56:56 +00003270 ResultBuilder Results(*this, &ResultBuilder::IsNestedNameSpecifier);
Douglas Gregor64b12b52009-09-22 23:31:26 +00003271 Results.EnterNewScope();
Douglas Gregor3545ff42009-09-21 16:56:56 +00003272
3273 // If we aren't in class scope, we could see the "namespace" keyword.
3274 if (!S->isClassScope())
John McCall276321a2010-08-25 06:19:51 +00003275 Results.AddResult(CodeCompletionResult("namespace"));
Douglas Gregor3545ff42009-09-21 16:56:56 +00003276
3277 // After "using", we can see anything that would start a
3278 // nested-name-specifier.
Douglas Gregora6e2edc2010-01-14 03:27:13 +00003279 CodeCompletionDeclConsumer Consumer(Results, CurContext);
Douglas Gregor39982192010-08-15 06:18:01 +00003280 LookupVisibleDecls(S, LookupOrdinaryName, Consumer,
3281 CodeCompleter->includeGlobals());
Douglas Gregor64b12b52009-09-22 23:31:26 +00003282 Results.ExitScope();
Douglas Gregor3545ff42009-09-21 16:56:56 +00003283
Douglas Gregor00c37ef2010-08-11 21:23:17 +00003284 HandleCodeCompleteResults(this, CodeCompleter,
3285 CodeCompletionContext::CCC_Other,
3286 Results.data(),Results.size());
Douglas Gregor7e90c6d2009-09-18 19:03:04 +00003287}
3288
3289void Sema::CodeCompleteUsingDirective(Scope *S) {
3290 if (!CodeCompleter)
3291 return;
3292
Douglas Gregor3545ff42009-09-21 16:56:56 +00003293 // After "using namespace", we expect to see a namespace name or namespace
3294 // alias.
3295 ResultBuilder Results(*this, &ResultBuilder::IsNamespaceOrAlias);
Douglas Gregor64b12b52009-09-22 23:31:26 +00003296 Results.EnterNewScope();
Douglas Gregora6e2edc2010-01-14 03:27:13 +00003297 CodeCompletionDeclConsumer Consumer(Results, CurContext);
Douglas Gregor39982192010-08-15 06:18:01 +00003298 LookupVisibleDecls(S, LookupOrdinaryName, Consumer,
3299 CodeCompleter->includeGlobals());
Douglas Gregor64b12b52009-09-22 23:31:26 +00003300 Results.ExitScope();
Douglas Gregor00c37ef2010-08-11 21:23:17 +00003301 HandleCodeCompleteResults(this, CodeCompleter,
Douglas Gregor39982192010-08-15 06:18:01 +00003302 CodeCompletionContext::CCC_Namespace,
Douglas Gregor00c37ef2010-08-11 21:23:17 +00003303 Results.data(),Results.size());
Douglas Gregor7e90c6d2009-09-18 19:03:04 +00003304}
3305
3306void Sema::CodeCompleteNamespaceDecl(Scope *S) {
3307 if (!CodeCompleter)
3308 return;
3309
Douglas Gregor3545ff42009-09-21 16:56:56 +00003310 ResultBuilder Results(*this, &ResultBuilder::IsNamespace);
3311 DeclContext *Ctx = (DeclContext *)S->getEntity();
3312 if (!S->getParent())
3313 Ctx = Context.getTranslationUnitDecl();
3314
3315 if (Ctx && Ctx->isFileContext()) {
3316 // We only want to see those namespaces that have already been defined
3317 // within this scope, because its likely that the user is creating an
3318 // extended namespace declaration. Keep track of the most recent
3319 // definition of each namespace.
3320 std::map<NamespaceDecl *, NamespaceDecl *> OrigToLatest;
3321 for (DeclContext::specific_decl_iterator<NamespaceDecl>
3322 NS(Ctx->decls_begin()), NSEnd(Ctx->decls_end());
3323 NS != NSEnd; ++NS)
3324 OrigToLatest[NS->getOriginalNamespace()] = *NS;
3325
3326 // Add the most recent definition (or extended definition) of each
3327 // namespace to the list of results.
Douglas Gregor64b12b52009-09-22 23:31:26 +00003328 Results.EnterNewScope();
Douglas Gregor3545ff42009-09-21 16:56:56 +00003329 for (std::map<NamespaceDecl *, NamespaceDecl *>::iterator
3330 NS = OrigToLatest.begin(), NSEnd = OrigToLatest.end();
3331 NS != NSEnd; ++NS)
John McCall276321a2010-08-25 06:19:51 +00003332 Results.AddResult(CodeCompletionResult(NS->second, 0),
Douglas Gregorfc59ce12010-01-14 16:14:35 +00003333 CurContext, 0, false);
Douglas Gregor64b12b52009-09-22 23:31:26 +00003334 Results.ExitScope();
Douglas Gregor3545ff42009-09-21 16:56:56 +00003335 }
3336
Douglas Gregor00c37ef2010-08-11 21:23:17 +00003337 HandleCodeCompleteResults(this, CodeCompleter,
3338 CodeCompletionContext::CCC_Other,
3339 Results.data(),Results.size());
Douglas Gregor7e90c6d2009-09-18 19:03:04 +00003340}
3341
3342void Sema::CodeCompleteNamespaceAliasDecl(Scope *S) {
3343 if (!CodeCompleter)
3344 return;
3345
Douglas Gregor3545ff42009-09-21 16:56:56 +00003346 // After "namespace", we expect to see a namespace or alias.
3347 ResultBuilder Results(*this, &ResultBuilder::IsNamespaceOrAlias);
Douglas Gregora6e2edc2010-01-14 03:27:13 +00003348 CodeCompletionDeclConsumer Consumer(Results, CurContext);
Douglas Gregor39982192010-08-15 06:18:01 +00003349 LookupVisibleDecls(S, LookupOrdinaryName, Consumer,
3350 CodeCompleter->includeGlobals());
Douglas Gregor00c37ef2010-08-11 21:23:17 +00003351 HandleCodeCompleteResults(this, CodeCompleter,
Douglas Gregor39982192010-08-15 06:18:01 +00003352 CodeCompletionContext::CCC_Namespace,
Douglas Gregor00c37ef2010-08-11 21:23:17 +00003353 Results.data(),Results.size());
Douglas Gregor7e90c6d2009-09-18 19:03:04 +00003354}
3355
Douglas Gregorc811ede2009-09-18 20:05:18 +00003356void Sema::CodeCompleteOperatorName(Scope *S) {
3357 if (!CodeCompleter)
3358 return;
Douglas Gregor3545ff42009-09-21 16:56:56 +00003359
John McCall276321a2010-08-25 06:19:51 +00003360 typedef CodeCompletionResult Result;
Douglas Gregor3545ff42009-09-21 16:56:56 +00003361 ResultBuilder Results(*this, &ResultBuilder::IsType);
Douglas Gregor64b12b52009-09-22 23:31:26 +00003362 Results.EnterNewScope();
Douglas Gregorc811ede2009-09-18 20:05:18 +00003363
Douglas Gregor3545ff42009-09-21 16:56:56 +00003364 // Add the names of overloadable operators.
3365#define OVERLOADED_OPERATOR(Name,Spelling,Token,Unary,Binary,MemberOnly) \
3366 if (std::strcmp(Spelling, "?")) \
Douglas Gregor78a21012010-01-14 16:01:26 +00003367 Results.AddResult(Result(Spelling));
Douglas Gregor3545ff42009-09-21 16:56:56 +00003368#include "clang/Basic/OperatorKinds.def"
3369
3370 // Add any type names visible from the current scope
Douglas Gregor6ae4c522010-01-14 03:21:49 +00003371 Results.allowNestedNameSpecifiers();
Douglas Gregora6e2edc2010-01-14 03:27:13 +00003372 CodeCompletionDeclConsumer Consumer(Results, CurContext);
Douglas Gregor39982192010-08-15 06:18:01 +00003373 LookupVisibleDecls(S, LookupOrdinaryName, Consumer,
3374 CodeCompleter->includeGlobals());
Douglas Gregor3545ff42009-09-21 16:56:56 +00003375
3376 // Add any type specifiers
Douglas Gregorf98e6a22010-01-13 23:51:12 +00003377 AddTypeSpecifierResults(getLangOptions(), Results);
Douglas Gregor64b12b52009-09-22 23:31:26 +00003378 Results.ExitScope();
Douglas Gregor3545ff42009-09-21 16:56:56 +00003379
Douglas Gregor00c37ef2010-08-11 21:23:17 +00003380 HandleCodeCompleteResults(this, CodeCompleter,
Douglas Gregor39982192010-08-15 06:18:01 +00003381 CodeCompletionContext::CCC_Type,
Douglas Gregor00c37ef2010-08-11 21:23:17 +00003382 Results.data(),Results.size());
Douglas Gregorc811ede2009-09-18 20:05:18 +00003383}
Douglas Gregor7e90c6d2009-09-18 19:03:04 +00003384
Douglas Gregoreaeeca92010-08-28 00:00:50 +00003385void Sema::CodeCompleteConstructorInitializer(Decl *ConstructorD,
3386 CXXBaseOrMemberInitializer** Initializers,
3387 unsigned NumInitializers) {
3388 CXXConstructorDecl *Constructor
3389 = static_cast<CXXConstructorDecl *>(ConstructorD);
3390 if (!Constructor)
3391 return;
3392
3393 ResultBuilder Results(*this);
3394 Results.EnterNewScope();
3395
3396 // Fill in any already-initialized fields or base classes.
3397 llvm::SmallPtrSet<FieldDecl *, 4> InitializedFields;
3398 llvm::SmallPtrSet<CanQualType, 4> InitializedBases;
3399 for (unsigned I = 0; I != NumInitializers; ++I) {
3400 if (Initializers[I]->isBaseInitializer())
3401 InitializedBases.insert(
3402 Context.getCanonicalType(QualType(Initializers[I]->getBaseClass(), 0)));
3403 else
3404 InitializedFields.insert(cast<FieldDecl>(Initializers[I]->getMember()));
3405 }
3406
3407 // Add completions for base classes.
Douglas Gregor99129ef2010-08-29 19:27:27 +00003408 bool SawLastInitializer = (NumInitializers == 0);
Douglas Gregoreaeeca92010-08-28 00:00:50 +00003409 CXXRecordDecl *ClassDecl = Constructor->getParent();
3410 for (CXXRecordDecl::base_class_iterator Base = ClassDecl->bases_begin(),
3411 BaseEnd = ClassDecl->bases_end();
3412 Base != BaseEnd; ++Base) {
Douglas Gregor99129ef2010-08-29 19:27:27 +00003413 if (!InitializedBases.insert(Context.getCanonicalType(Base->getType()))) {
3414 SawLastInitializer
3415 = NumInitializers > 0 &&
3416 Initializers[NumInitializers - 1]->isBaseInitializer() &&
3417 Context.hasSameUnqualifiedType(Base->getType(),
3418 QualType(Initializers[NumInitializers - 1]->getBaseClass(), 0));
Douglas Gregoreaeeca92010-08-28 00:00:50 +00003419 continue;
Douglas Gregor99129ef2010-08-29 19:27:27 +00003420 }
Douglas Gregoreaeeca92010-08-28 00:00:50 +00003421
3422 CodeCompletionString *Pattern = new CodeCompletionString;
3423 Pattern->AddTypedTextChunk(
3424 Base->getType().getAsString(Context.PrintingPolicy));
3425 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
3426 Pattern->AddPlaceholderChunk("args");
3427 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
Douglas Gregor99129ef2010-08-29 19:27:27 +00003428 Results.AddResult(CodeCompletionResult(Pattern,
3429 SawLastInitializer? CCP_NextInitializer
3430 : CCP_MemberDeclaration));
3431 SawLastInitializer = false;
Douglas Gregoreaeeca92010-08-28 00:00:50 +00003432 }
3433
3434 // Add completions for virtual base classes.
3435 for (CXXRecordDecl::base_class_iterator Base = ClassDecl->vbases_begin(),
3436 BaseEnd = ClassDecl->vbases_end();
3437 Base != BaseEnd; ++Base) {
Douglas Gregor99129ef2010-08-29 19:27:27 +00003438 if (!InitializedBases.insert(Context.getCanonicalType(Base->getType()))) {
3439 SawLastInitializer
3440 = NumInitializers > 0 &&
3441 Initializers[NumInitializers - 1]->isBaseInitializer() &&
3442 Context.hasSameUnqualifiedType(Base->getType(),
3443 QualType(Initializers[NumInitializers - 1]->getBaseClass(), 0));
Douglas Gregoreaeeca92010-08-28 00:00:50 +00003444 continue;
Douglas Gregor99129ef2010-08-29 19:27:27 +00003445 }
Douglas Gregoreaeeca92010-08-28 00:00:50 +00003446
3447 CodeCompletionString *Pattern = new CodeCompletionString;
3448 Pattern->AddTypedTextChunk(
3449 Base->getType().getAsString(Context.PrintingPolicy));
3450 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
3451 Pattern->AddPlaceholderChunk("args");
3452 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
Douglas Gregor99129ef2010-08-29 19:27:27 +00003453 Results.AddResult(CodeCompletionResult(Pattern,
3454 SawLastInitializer? CCP_NextInitializer
3455 : CCP_MemberDeclaration));
3456 SawLastInitializer = false;
Douglas Gregoreaeeca92010-08-28 00:00:50 +00003457 }
3458
3459 // Add completions for members.
3460 for (CXXRecordDecl::field_iterator Field = ClassDecl->field_begin(),
3461 FieldEnd = ClassDecl->field_end();
3462 Field != FieldEnd; ++Field) {
Douglas Gregor99129ef2010-08-29 19:27:27 +00003463 if (!InitializedFields.insert(cast<FieldDecl>(Field->getCanonicalDecl()))) {
3464 SawLastInitializer
3465 = NumInitializers > 0 &&
3466 Initializers[NumInitializers - 1]->isMemberInitializer() &&
3467 Initializers[NumInitializers - 1]->getMember() == *Field;
Douglas Gregoreaeeca92010-08-28 00:00:50 +00003468 continue;
Douglas Gregor99129ef2010-08-29 19:27:27 +00003469 }
Douglas Gregoreaeeca92010-08-28 00:00:50 +00003470
3471 if (!Field->getDeclName())
3472 continue;
3473
3474 CodeCompletionString *Pattern = new CodeCompletionString;
3475 Pattern->AddTypedTextChunk(Field->getIdentifier()->getName());
3476 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
3477 Pattern->AddPlaceholderChunk("args");
3478 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
Douglas Gregor99129ef2010-08-29 19:27:27 +00003479 Results.AddResult(CodeCompletionResult(Pattern,
3480 SawLastInitializer? CCP_NextInitializer
Douglas Gregorf3af3112010-09-09 21:42:20 +00003481 : CCP_MemberDeclaration,
3482 CXCursor_MemberRef));
Douglas Gregor99129ef2010-08-29 19:27:27 +00003483 SawLastInitializer = false;
Douglas Gregoreaeeca92010-08-28 00:00:50 +00003484 }
3485 Results.ExitScope();
3486
3487 HandleCodeCompleteResults(this, CodeCompleter,
3488 CodeCompletionContext::CCC_Name,
3489 Results.data(), Results.size());
3490}
3491
Douglas Gregorf1934162010-01-13 21:24:21 +00003492// Macro that expands to @Keyword or Keyword, depending on whether NeedAt is
3493// true or false.
3494#define OBJC_AT_KEYWORD_NAME(NeedAt,Keyword) NeedAt? "@" #Keyword : #Keyword
Douglas Gregorf98e6a22010-01-13 23:51:12 +00003495static void AddObjCImplementationResults(const LangOptions &LangOpts,
Douglas Gregorf1934162010-01-13 21:24:21 +00003496 ResultBuilder &Results,
3497 bool NeedAt) {
John McCall276321a2010-08-25 06:19:51 +00003498 typedef CodeCompletionResult Result;
Douglas Gregorf1934162010-01-13 21:24:21 +00003499 // Since we have an implementation, we can end it.
Douglas Gregor78a21012010-01-14 16:01:26 +00003500 Results.AddResult(Result(OBJC_AT_KEYWORD_NAME(NeedAt,end)));
Douglas Gregorf1934162010-01-13 21:24:21 +00003501
3502 CodeCompletionString *Pattern = 0;
3503 if (LangOpts.ObjC2) {
3504 // @dynamic
3505 Pattern = new CodeCompletionString;
3506 Pattern->AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt,dynamic));
3507 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
3508 Pattern->AddPlaceholderChunk("property");
Douglas Gregor78a21012010-01-14 16:01:26 +00003509 Results.AddResult(Result(Pattern));
Douglas Gregorf1934162010-01-13 21:24:21 +00003510
3511 // @synthesize
3512 Pattern = new CodeCompletionString;
3513 Pattern->AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt,synthesize));
3514 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
3515 Pattern->AddPlaceholderChunk("property");
Douglas Gregor78a21012010-01-14 16:01:26 +00003516 Results.AddResult(Result(Pattern));
Douglas Gregorf1934162010-01-13 21:24:21 +00003517 }
3518}
3519
Douglas Gregorf98e6a22010-01-13 23:51:12 +00003520static void AddObjCInterfaceResults(const LangOptions &LangOpts,
Douglas Gregorf1934162010-01-13 21:24:21 +00003521 ResultBuilder &Results,
3522 bool NeedAt) {
John McCall276321a2010-08-25 06:19:51 +00003523 typedef CodeCompletionResult Result;
Douglas Gregorf1934162010-01-13 21:24:21 +00003524
3525 // Since we have an interface or protocol, we can end it.
Douglas Gregor78a21012010-01-14 16:01:26 +00003526 Results.AddResult(Result(OBJC_AT_KEYWORD_NAME(NeedAt,end)));
Douglas Gregorf1934162010-01-13 21:24:21 +00003527
3528 if (LangOpts.ObjC2) {
3529 // @property
Douglas Gregor78a21012010-01-14 16:01:26 +00003530 Results.AddResult(Result(OBJC_AT_KEYWORD_NAME(NeedAt,property)));
Douglas Gregorf1934162010-01-13 21:24:21 +00003531
3532 // @required
Douglas Gregor78a21012010-01-14 16:01:26 +00003533 Results.AddResult(Result(OBJC_AT_KEYWORD_NAME(NeedAt,required)));
Douglas Gregorf1934162010-01-13 21:24:21 +00003534
3535 // @optional
Douglas Gregor78a21012010-01-14 16:01:26 +00003536 Results.AddResult(Result(OBJC_AT_KEYWORD_NAME(NeedAt,optional)));
Douglas Gregorf1934162010-01-13 21:24:21 +00003537 }
3538}
3539
Douglas Gregorf98e6a22010-01-13 23:51:12 +00003540static void AddObjCTopLevelResults(ResultBuilder &Results, bool NeedAt) {
John McCall276321a2010-08-25 06:19:51 +00003541 typedef CodeCompletionResult Result;
Douglas Gregorf1934162010-01-13 21:24:21 +00003542 CodeCompletionString *Pattern = 0;
3543
3544 // @class name ;
3545 Pattern = new CodeCompletionString;
3546 Pattern->AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt,class));
3547 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
Douglas Gregorf4c33342010-05-28 00:22:41 +00003548 Pattern->AddPlaceholderChunk("name");
Douglas Gregor78a21012010-01-14 16:01:26 +00003549 Results.AddResult(Result(Pattern));
Douglas Gregorf1934162010-01-13 21:24:21 +00003550
Douglas Gregorf4c33342010-05-28 00:22:41 +00003551 if (Results.includeCodePatterns()) {
3552 // @interface name
3553 // FIXME: Could introduce the whole pattern, including superclasses and
3554 // such.
3555 Pattern = new CodeCompletionString;
3556 Pattern->AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt,interface));
3557 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
3558 Pattern->AddPlaceholderChunk("class");
3559 Results.AddResult(Result(Pattern));
Douglas Gregorf1934162010-01-13 21:24:21 +00003560
Douglas Gregorf4c33342010-05-28 00:22:41 +00003561 // @protocol name
3562 Pattern = new CodeCompletionString;
3563 Pattern->AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt,protocol));
3564 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
3565 Pattern->AddPlaceholderChunk("protocol");
3566 Results.AddResult(Result(Pattern));
3567
3568 // @implementation name
3569 Pattern = new CodeCompletionString;
3570 Pattern->AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt,implementation));
3571 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
3572 Pattern->AddPlaceholderChunk("class");
3573 Results.AddResult(Result(Pattern));
3574 }
Douglas Gregorf1934162010-01-13 21:24:21 +00003575
3576 // @compatibility_alias name
3577 Pattern = new CodeCompletionString;
3578 Pattern->AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt,compatibility_alias));
3579 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
3580 Pattern->AddPlaceholderChunk("alias");
3581 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
3582 Pattern->AddPlaceholderChunk("class");
Douglas Gregor78a21012010-01-14 16:01:26 +00003583 Results.AddResult(Result(Pattern));
Douglas Gregorf1934162010-01-13 21:24:21 +00003584}
3585
John McCall48871652010-08-21 09:40:31 +00003586void Sema::CodeCompleteObjCAtDirective(Scope *S, Decl *ObjCImpDecl,
Douglas Gregorf48706c2009-12-07 09:27:33 +00003587 bool InInterface) {
John McCall276321a2010-08-25 06:19:51 +00003588 typedef CodeCompletionResult Result;
Douglas Gregorf48706c2009-12-07 09:27:33 +00003589 ResultBuilder Results(*this);
3590 Results.EnterNewScope();
Douglas Gregorf1934162010-01-13 21:24:21 +00003591 if (ObjCImpDecl)
Douglas Gregorf98e6a22010-01-13 23:51:12 +00003592 AddObjCImplementationResults(getLangOptions(), Results, false);
Douglas Gregorf1934162010-01-13 21:24:21 +00003593 else if (InInterface)
Douglas Gregorf98e6a22010-01-13 23:51:12 +00003594 AddObjCInterfaceResults(getLangOptions(), Results, false);
Douglas Gregorf1934162010-01-13 21:24:21 +00003595 else
Douglas Gregorf98e6a22010-01-13 23:51:12 +00003596 AddObjCTopLevelResults(Results, false);
Douglas Gregorf48706c2009-12-07 09:27:33 +00003597 Results.ExitScope();
Douglas Gregor00c37ef2010-08-11 21:23:17 +00003598 HandleCodeCompleteResults(this, CodeCompleter,
3599 CodeCompletionContext::CCC_Other,
3600 Results.data(),Results.size());
Douglas Gregorf48706c2009-12-07 09:27:33 +00003601}
3602
Douglas Gregorf98e6a22010-01-13 23:51:12 +00003603static void AddObjCExpressionResults(ResultBuilder &Results, bool NeedAt) {
John McCall276321a2010-08-25 06:19:51 +00003604 typedef CodeCompletionResult Result;
Douglas Gregorbc7c5e42009-12-07 09:51:25 +00003605 CodeCompletionString *Pattern = 0;
3606
3607 // @encode ( type-name )
3608 Pattern = new CodeCompletionString;
Douglas Gregorf1934162010-01-13 21:24:21 +00003609 Pattern->AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt,encode));
Douglas Gregorbc7c5e42009-12-07 09:51:25 +00003610 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
3611 Pattern->AddPlaceholderChunk("type-name");
3612 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
Douglas Gregor78a21012010-01-14 16:01:26 +00003613 Results.AddResult(Result(Pattern));
Douglas Gregorbc7c5e42009-12-07 09:51:25 +00003614
3615 // @protocol ( protocol-name )
3616 Pattern = new CodeCompletionString;
Douglas Gregorf1934162010-01-13 21:24:21 +00003617 Pattern->AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt,protocol));
Douglas Gregorbc7c5e42009-12-07 09:51:25 +00003618 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
3619 Pattern->AddPlaceholderChunk("protocol-name");
3620 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
Douglas Gregor78a21012010-01-14 16:01:26 +00003621 Results.AddResult(Result(Pattern));
Douglas Gregorbc7c5e42009-12-07 09:51:25 +00003622
3623 // @selector ( selector )
3624 Pattern = new CodeCompletionString;
Douglas Gregorf1934162010-01-13 21:24:21 +00003625 Pattern->AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt,selector));
Douglas Gregorbc7c5e42009-12-07 09:51:25 +00003626 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
3627 Pattern->AddPlaceholderChunk("selector");
3628 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
Douglas Gregor78a21012010-01-14 16:01:26 +00003629 Results.AddResult(Result(Pattern));
Douglas Gregorbc7c5e42009-12-07 09:51:25 +00003630}
3631
Douglas Gregorf98e6a22010-01-13 23:51:12 +00003632static void AddObjCStatementResults(ResultBuilder &Results, bool NeedAt) {
John McCall276321a2010-08-25 06:19:51 +00003633 typedef CodeCompletionResult Result;
Douglas Gregorbc7c5e42009-12-07 09:51:25 +00003634 CodeCompletionString *Pattern = 0;
Douglas Gregorf1934162010-01-13 21:24:21 +00003635
Douglas Gregorf4c33342010-05-28 00:22:41 +00003636 if (Results.includeCodePatterns()) {
3637 // @try { statements } @catch ( declaration ) { statements } @finally
3638 // { statements }
3639 Pattern = new CodeCompletionString;
3640 Pattern->AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt,try));
3641 Pattern->AddChunk(CodeCompletionString::CK_LeftBrace);
3642 Pattern->AddPlaceholderChunk("statements");
3643 Pattern->AddChunk(CodeCompletionString::CK_RightBrace);
3644 Pattern->AddTextChunk("@catch");
3645 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
3646 Pattern->AddPlaceholderChunk("parameter");
3647 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
3648 Pattern->AddChunk(CodeCompletionString::CK_LeftBrace);
3649 Pattern->AddPlaceholderChunk("statements");
3650 Pattern->AddChunk(CodeCompletionString::CK_RightBrace);
3651 Pattern->AddTextChunk("@finally");
3652 Pattern->AddChunk(CodeCompletionString::CK_LeftBrace);
3653 Pattern->AddPlaceholderChunk("statements");
3654 Pattern->AddChunk(CodeCompletionString::CK_RightBrace);
3655 Results.AddResult(Result(Pattern));
3656 }
Douglas Gregorf1934162010-01-13 21:24:21 +00003657
Douglas Gregorbc7c5e42009-12-07 09:51:25 +00003658 // @throw
3659 Pattern = new CodeCompletionString;
Douglas Gregorf1934162010-01-13 21:24:21 +00003660 Pattern->AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt,throw));
Douglas Gregor6a803932010-01-12 06:38:28 +00003661 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
Douglas Gregorbc7c5e42009-12-07 09:51:25 +00003662 Pattern->AddPlaceholderChunk("expression");
Douglas Gregor78a21012010-01-14 16:01:26 +00003663 Results.AddResult(Result(Pattern));
Douglas Gregorf1934162010-01-13 21:24:21 +00003664
Douglas Gregorf4c33342010-05-28 00:22:41 +00003665 if (Results.includeCodePatterns()) {
3666 // @synchronized ( expression ) { statements }
3667 Pattern = new CodeCompletionString;
3668 Pattern->AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt,synchronized));
3669 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
3670 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
3671 Pattern->AddPlaceholderChunk("expression");
3672 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
3673 Pattern->AddChunk(CodeCompletionString::CK_LeftBrace);
3674 Pattern->AddPlaceholderChunk("statements");
3675 Pattern->AddChunk(CodeCompletionString::CK_RightBrace);
3676 Results.AddResult(Result(Pattern));
3677 }
Douglas Gregorf1934162010-01-13 21:24:21 +00003678}
Douglas Gregorbc7c5e42009-12-07 09:51:25 +00003679
Douglas Gregorf98e6a22010-01-13 23:51:12 +00003680static void AddObjCVisibilityResults(const LangOptions &LangOpts,
Douglas Gregor48d46252010-01-13 21:54:15 +00003681 ResultBuilder &Results,
3682 bool NeedAt) {
John McCall276321a2010-08-25 06:19:51 +00003683 typedef CodeCompletionResult Result;
Douglas Gregor78a21012010-01-14 16:01:26 +00003684 Results.AddResult(Result(OBJC_AT_KEYWORD_NAME(NeedAt,private)));
3685 Results.AddResult(Result(OBJC_AT_KEYWORD_NAME(NeedAt,protected)));
3686 Results.AddResult(Result(OBJC_AT_KEYWORD_NAME(NeedAt,public)));
Douglas Gregor48d46252010-01-13 21:54:15 +00003687 if (LangOpts.ObjC2)
Douglas Gregor78a21012010-01-14 16:01:26 +00003688 Results.AddResult(Result(OBJC_AT_KEYWORD_NAME(NeedAt,package)));
Douglas Gregor48d46252010-01-13 21:54:15 +00003689}
3690
3691void Sema::CodeCompleteObjCAtVisibility(Scope *S) {
3692 ResultBuilder Results(*this);
3693 Results.EnterNewScope();
Douglas Gregorf98e6a22010-01-13 23:51:12 +00003694 AddObjCVisibilityResults(getLangOptions(), Results, false);
Douglas Gregor48d46252010-01-13 21:54:15 +00003695 Results.ExitScope();
Douglas Gregor00c37ef2010-08-11 21:23:17 +00003696 HandleCodeCompleteResults(this, CodeCompleter,
3697 CodeCompletionContext::CCC_Other,
3698 Results.data(),Results.size());
Douglas Gregor48d46252010-01-13 21:54:15 +00003699}
3700
3701void Sema::CodeCompleteObjCAtStatement(Scope *S) {
Douglas Gregorf1934162010-01-13 21:24:21 +00003702 ResultBuilder Results(*this);
3703 Results.EnterNewScope();
Douglas Gregorf98e6a22010-01-13 23:51:12 +00003704 AddObjCStatementResults(Results, false);
3705 AddObjCExpressionResults(Results, false);
Douglas Gregorbc7c5e42009-12-07 09:51:25 +00003706 Results.ExitScope();
Douglas Gregor00c37ef2010-08-11 21:23:17 +00003707 HandleCodeCompleteResults(this, CodeCompleter,
3708 CodeCompletionContext::CCC_Other,
3709 Results.data(),Results.size());
Douglas Gregorbc7c5e42009-12-07 09:51:25 +00003710}
3711
3712void Sema::CodeCompleteObjCAtExpression(Scope *S) {
3713 ResultBuilder Results(*this);
3714 Results.EnterNewScope();
Douglas Gregorf98e6a22010-01-13 23:51:12 +00003715 AddObjCExpressionResults(Results, false);
Douglas Gregorbc7c5e42009-12-07 09:51:25 +00003716 Results.ExitScope();
Douglas Gregor00c37ef2010-08-11 21:23:17 +00003717 HandleCodeCompleteResults(this, CodeCompleter,
3718 CodeCompletionContext::CCC_Other,
3719 Results.data(),Results.size());
Douglas Gregorbc7c5e42009-12-07 09:51:25 +00003720}
3721
Douglas Gregore6078da2009-11-19 00:14:45 +00003722/// \brief Determine whether the addition of the given flag to an Objective-C
3723/// property's attributes will cause a conflict.
3724static bool ObjCPropertyFlagConflicts(unsigned Attributes, unsigned NewFlag) {
3725 // Check if we've already added this flag.
3726 if (Attributes & NewFlag)
3727 return true;
3728
3729 Attributes |= NewFlag;
3730
3731 // Check for collisions with "readonly".
3732 if ((Attributes & ObjCDeclSpec::DQ_PR_readonly) &&
3733 (Attributes & (ObjCDeclSpec::DQ_PR_readwrite |
3734 ObjCDeclSpec::DQ_PR_assign |
3735 ObjCDeclSpec::DQ_PR_copy |
3736 ObjCDeclSpec::DQ_PR_retain)))
3737 return true;
3738
3739 // Check for more than one of { assign, copy, retain }.
3740 unsigned AssignCopyRetMask = Attributes & (ObjCDeclSpec::DQ_PR_assign |
3741 ObjCDeclSpec::DQ_PR_copy |
3742 ObjCDeclSpec::DQ_PR_retain);
3743 if (AssignCopyRetMask &&
3744 AssignCopyRetMask != ObjCDeclSpec::DQ_PR_assign &&
3745 AssignCopyRetMask != ObjCDeclSpec::DQ_PR_copy &&
3746 AssignCopyRetMask != ObjCDeclSpec::DQ_PR_retain)
3747 return true;
3748
3749 return false;
3750}
3751
Douglas Gregor36029f42009-11-18 23:08:07 +00003752void Sema::CodeCompleteObjCPropertyFlags(Scope *S, ObjCDeclSpec &ODS) {
Steve Naroff936354c2009-10-08 21:55:05 +00003753 if (!CodeCompleter)
3754 return;
Douglas Gregor1b605f72009-11-19 01:08:35 +00003755
Steve Naroff936354c2009-10-08 21:55:05 +00003756 unsigned Attributes = ODS.getPropertyAttributes();
3757
John McCall276321a2010-08-25 06:19:51 +00003758 typedef CodeCompletionResult Result;
Steve Naroff936354c2009-10-08 21:55:05 +00003759 ResultBuilder Results(*this);
3760 Results.EnterNewScope();
Douglas Gregore6078da2009-11-19 00:14:45 +00003761 if (!ObjCPropertyFlagConflicts(Attributes, ObjCDeclSpec::DQ_PR_readonly))
John McCall276321a2010-08-25 06:19:51 +00003762 Results.AddResult(CodeCompletionResult("readonly"));
Douglas Gregore6078da2009-11-19 00:14:45 +00003763 if (!ObjCPropertyFlagConflicts(Attributes, ObjCDeclSpec::DQ_PR_assign))
John McCall276321a2010-08-25 06:19:51 +00003764 Results.AddResult(CodeCompletionResult("assign"));
Douglas Gregore6078da2009-11-19 00:14:45 +00003765 if (!ObjCPropertyFlagConflicts(Attributes, ObjCDeclSpec::DQ_PR_readwrite))
John McCall276321a2010-08-25 06:19:51 +00003766 Results.AddResult(CodeCompletionResult("readwrite"));
Douglas Gregore6078da2009-11-19 00:14:45 +00003767 if (!ObjCPropertyFlagConflicts(Attributes, ObjCDeclSpec::DQ_PR_retain))
John McCall276321a2010-08-25 06:19:51 +00003768 Results.AddResult(CodeCompletionResult("retain"));
Douglas Gregore6078da2009-11-19 00:14:45 +00003769 if (!ObjCPropertyFlagConflicts(Attributes, ObjCDeclSpec::DQ_PR_copy))
John McCall276321a2010-08-25 06:19:51 +00003770 Results.AddResult(CodeCompletionResult("copy"));
Douglas Gregore6078da2009-11-19 00:14:45 +00003771 if (!ObjCPropertyFlagConflicts(Attributes, ObjCDeclSpec::DQ_PR_nonatomic))
John McCall276321a2010-08-25 06:19:51 +00003772 Results.AddResult(CodeCompletionResult("nonatomic"));
Douglas Gregore6078da2009-11-19 00:14:45 +00003773 if (!ObjCPropertyFlagConflicts(Attributes, ObjCDeclSpec::DQ_PR_setter)) {
Douglas Gregor45f83ee2009-11-19 00:01:57 +00003774 CodeCompletionString *Setter = new CodeCompletionString;
3775 Setter->AddTypedTextChunk("setter");
3776 Setter->AddTextChunk(" = ");
3777 Setter->AddPlaceholderChunk("method");
John McCall276321a2010-08-25 06:19:51 +00003778 Results.AddResult(CodeCompletionResult(Setter));
Douglas Gregor45f83ee2009-11-19 00:01:57 +00003779 }
Douglas Gregore6078da2009-11-19 00:14:45 +00003780 if (!ObjCPropertyFlagConflicts(Attributes, ObjCDeclSpec::DQ_PR_getter)) {
Douglas Gregor45f83ee2009-11-19 00:01:57 +00003781 CodeCompletionString *Getter = new CodeCompletionString;
3782 Getter->AddTypedTextChunk("getter");
3783 Getter->AddTextChunk(" = ");
3784 Getter->AddPlaceholderChunk("method");
John McCall276321a2010-08-25 06:19:51 +00003785 Results.AddResult(CodeCompletionResult(Getter));
Douglas Gregor45f83ee2009-11-19 00:01:57 +00003786 }
Steve Naroff936354c2009-10-08 21:55:05 +00003787 Results.ExitScope();
Douglas Gregor00c37ef2010-08-11 21:23:17 +00003788 HandleCodeCompleteResults(this, CodeCompleter,
3789 CodeCompletionContext::CCC_Other,
3790 Results.data(),Results.size());
Steve Naroff936354c2009-10-08 21:55:05 +00003791}
Steve Naroffeae65032009-11-07 02:08:14 +00003792
Douglas Gregorc8537c52009-11-19 07:41:15 +00003793/// \brief Descripts the kind of Objective-C method that we want to find
3794/// via code completion.
3795enum ObjCMethodKind {
3796 MK_Any, //< Any kind of method, provided it means other specified criteria.
3797 MK_ZeroArgSelector, //< Zero-argument (unary) selector.
3798 MK_OneArgSelector //< One-argument selector.
3799};
3800
Douglas Gregor67c692c2010-08-26 15:07:07 +00003801static bool isAcceptableObjCSelector(Selector Sel,
3802 ObjCMethodKind WantKind,
3803 IdentifierInfo **SelIdents,
3804 unsigned NumSelIdents) {
3805 if (NumSelIdents > Sel.getNumArgs())
3806 return false;
3807
3808 switch (WantKind) {
3809 case MK_Any: break;
3810 case MK_ZeroArgSelector: return Sel.isUnarySelector();
3811 case MK_OneArgSelector: return Sel.getNumArgs() == 1;
3812 }
3813
3814 for (unsigned I = 0; I != NumSelIdents; ++I)
3815 if (SelIdents[I] != Sel.getIdentifierInfoForSlot(I))
3816 return false;
3817
3818 return true;
3819}
3820
Douglas Gregorc8537c52009-11-19 07:41:15 +00003821static bool isAcceptableObjCMethod(ObjCMethodDecl *Method,
3822 ObjCMethodKind WantKind,
3823 IdentifierInfo **SelIdents,
3824 unsigned NumSelIdents) {
Douglas Gregor67c692c2010-08-26 15:07:07 +00003825 return isAcceptableObjCSelector(Method->getSelector(), WantKind, SelIdents,
3826 NumSelIdents);
Douglas Gregorc8537c52009-11-19 07:41:15 +00003827}
Douglas Gregor1154e272010-09-16 16:06:31 +00003828
3829namespace {
3830 /// \brief A set of selectors, which is used to avoid introducing multiple
3831 /// completions with the same selector into the result set.
3832 typedef llvm::SmallPtrSet<Selector, 16> VisitedSelectorSet;
3833}
3834
Douglas Gregorbab2b3c2009-11-17 23:22:23 +00003835/// \brief Add all of the Objective-C methods in the given Objective-C
3836/// container to the set of results.
3837///
3838/// The container will be a class, protocol, category, or implementation of
3839/// any of the above. This mether will recurse to include methods from
3840/// the superclasses of classes along with their categories, protocols, and
3841/// implementations.
3842///
3843/// \param Container the container in which we'll look to find methods.
3844///
3845/// \param WantInstance whether to add instance methods (only); if false, this
3846/// routine will add factory methods (only).
3847///
3848/// \param CurContext the context in which we're performing the lookup that
3849/// finds methods.
3850///
3851/// \param Results the structure into which we'll add results.
3852static void AddObjCMethods(ObjCContainerDecl *Container,
3853 bool WantInstanceMethods,
Douglas Gregorc8537c52009-11-19 07:41:15 +00003854 ObjCMethodKind WantKind,
Douglas Gregor1b605f72009-11-19 01:08:35 +00003855 IdentifierInfo **SelIdents,
3856 unsigned NumSelIdents,
Douglas Gregorbab2b3c2009-11-17 23:22:23 +00003857 DeclContext *CurContext,
Douglas Gregor1154e272010-09-16 16:06:31 +00003858 VisitedSelectorSet &Selectors,
Douglas Gregor416b5752010-08-25 01:08:01 +00003859 ResultBuilder &Results,
3860 bool InOriginalClass = true) {
John McCall276321a2010-08-25 06:19:51 +00003861 typedef CodeCompletionResult Result;
Douglas Gregorbab2b3c2009-11-17 23:22:23 +00003862 for (ObjCContainerDecl::method_iterator M = Container->meth_begin(),
3863 MEnd = Container->meth_end();
3864 M != MEnd; ++M) {
Douglas Gregor1b605f72009-11-19 01:08:35 +00003865 if ((*M)->isInstanceMethod() == WantInstanceMethods) {
3866 // Check whether the selector identifiers we've been given are a
3867 // subset of the identifiers for this particular method.
Douglas Gregorc8537c52009-11-19 07:41:15 +00003868 if (!isAcceptableObjCMethod(*M, WantKind, SelIdents, NumSelIdents))
Douglas Gregor1b605f72009-11-19 01:08:35 +00003869 continue;
Douglas Gregorc8537c52009-11-19 07:41:15 +00003870
Douglas Gregor1154e272010-09-16 16:06:31 +00003871 if (!Selectors.insert((*M)->getSelector()))
3872 continue;
3873
Douglas Gregor1b605f72009-11-19 01:08:35 +00003874 Result R = Result(*M, 0);
3875 R.StartParameter = NumSelIdents;
Douglas Gregorc8537c52009-11-19 07:41:15 +00003876 R.AllParametersAreInformative = (WantKind != MK_Any);
Douglas Gregor416b5752010-08-25 01:08:01 +00003877 if (!InOriginalClass)
3878 R.Priority += CCD_InBaseClass;
Douglas Gregor1b605f72009-11-19 01:08:35 +00003879 Results.MaybeAddResult(R, CurContext);
3880 }
Douglas Gregorbab2b3c2009-11-17 23:22:23 +00003881 }
3882
Douglas Gregorf37c9492010-09-16 15:34:59 +00003883 // Visit the protocols of protocols.
3884 if (ObjCProtocolDecl *Protocol = dyn_cast<ObjCProtocolDecl>(Container)) {
3885 const ObjCList<ObjCProtocolDecl> &Protocols
3886 = Protocol->getReferencedProtocols();
3887 for (ObjCList<ObjCProtocolDecl>::iterator I = Protocols.begin(),
3888 E = Protocols.end();
3889 I != E; ++I)
3890 AddObjCMethods(*I, WantInstanceMethods, WantKind, SelIdents, NumSelIdents,
Douglas Gregor1154e272010-09-16 16:06:31 +00003891 CurContext, Selectors, Results, false);
Douglas Gregorf37c9492010-09-16 15:34:59 +00003892 }
3893
Douglas Gregorbab2b3c2009-11-17 23:22:23 +00003894 ObjCInterfaceDecl *IFace = dyn_cast<ObjCInterfaceDecl>(Container);
3895 if (!IFace)
3896 return;
3897
3898 // Add methods in protocols.
3899 const ObjCList<ObjCProtocolDecl> &Protocols= IFace->getReferencedProtocols();
3900 for (ObjCList<ObjCProtocolDecl>::iterator I = Protocols.begin(),
3901 E = Protocols.end();
3902 I != E; ++I)
Douglas Gregorc8537c52009-11-19 07:41:15 +00003903 AddObjCMethods(*I, WantInstanceMethods, WantKind, SelIdents, NumSelIdents,
Douglas Gregor1154e272010-09-16 16:06:31 +00003904 CurContext, Selectors, Results, false);
Douglas Gregorbab2b3c2009-11-17 23:22:23 +00003905
3906 // Add methods in categories.
3907 for (ObjCCategoryDecl *CatDecl = IFace->getCategoryList(); CatDecl;
3908 CatDecl = CatDecl->getNextClassCategory()) {
Douglas Gregorc8537c52009-11-19 07:41:15 +00003909 AddObjCMethods(CatDecl, WantInstanceMethods, WantKind, SelIdents,
Douglas Gregor1154e272010-09-16 16:06:31 +00003910 NumSelIdents, CurContext, Selectors, Results,
3911 InOriginalClass);
Douglas Gregorbab2b3c2009-11-17 23:22:23 +00003912
3913 // Add a categories protocol methods.
3914 const ObjCList<ObjCProtocolDecl> &Protocols
3915 = CatDecl->getReferencedProtocols();
3916 for (ObjCList<ObjCProtocolDecl>::iterator I = Protocols.begin(),
3917 E = Protocols.end();
3918 I != E; ++I)
Douglas Gregorc8537c52009-11-19 07:41:15 +00003919 AddObjCMethods(*I, WantInstanceMethods, WantKind, SelIdents,
Douglas Gregor1154e272010-09-16 16:06:31 +00003920 NumSelIdents, CurContext, Selectors, Results, false);
Douglas Gregorbab2b3c2009-11-17 23:22:23 +00003921
3922 // Add methods in category implementations.
3923 if (ObjCCategoryImplDecl *Impl = CatDecl->getImplementation())
Douglas Gregorc8537c52009-11-19 07:41:15 +00003924 AddObjCMethods(Impl, WantInstanceMethods, WantKind, SelIdents,
Douglas Gregor1154e272010-09-16 16:06:31 +00003925 NumSelIdents, CurContext, Selectors, Results,
3926 InOriginalClass);
Douglas Gregorbab2b3c2009-11-17 23:22:23 +00003927 }
3928
3929 // Add methods in superclass.
3930 if (IFace->getSuperClass())
Douglas Gregorc8537c52009-11-19 07:41:15 +00003931 AddObjCMethods(IFace->getSuperClass(), WantInstanceMethods, WantKind,
Douglas Gregor1154e272010-09-16 16:06:31 +00003932 SelIdents, NumSelIdents, CurContext, Selectors, Results,
3933 false);
Douglas Gregorbab2b3c2009-11-17 23:22:23 +00003934
3935 // Add methods in our implementation, if any.
3936 if (ObjCImplementationDecl *Impl = IFace->getImplementation())
Douglas Gregorc8537c52009-11-19 07:41:15 +00003937 AddObjCMethods(Impl, WantInstanceMethods, WantKind, SelIdents,
Douglas Gregor1154e272010-09-16 16:06:31 +00003938 NumSelIdents, CurContext, Selectors, Results,
3939 InOriginalClass);
Douglas Gregorc8537c52009-11-19 07:41:15 +00003940}
3941
3942
John McCall48871652010-08-21 09:40:31 +00003943void Sema::CodeCompleteObjCPropertyGetter(Scope *S, Decl *ClassDecl,
3944 Decl **Methods,
Douglas Gregorc8537c52009-11-19 07:41:15 +00003945 unsigned NumMethods) {
John McCall276321a2010-08-25 06:19:51 +00003946 typedef CodeCompletionResult Result;
Douglas Gregorc8537c52009-11-19 07:41:15 +00003947
3948 // Try to find the interface where getters might live.
John McCall48871652010-08-21 09:40:31 +00003949 ObjCInterfaceDecl *Class = dyn_cast_or_null<ObjCInterfaceDecl>(ClassDecl);
Douglas Gregorc8537c52009-11-19 07:41:15 +00003950 if (!Class) {
3951 if (ObjCCategoryDecl *Category
John McCall48871652010-08-21 09:40:31 +00003952 = dyn_cast_or_null<ObjCCategoryDecl>(ClassDecl))
Douglas Gregorc8537c52009-11-19 07:41:15 +00003953 Class = Category->getClassInterface();
3954
3955 if (!Class)
3956 return;
3957 }
3958
3959 // Find all of the potential getters.
3960 ResultBuilder Results(*this);
3961 Results.EnterNewScope();
3962
3963 // FIXME: We need to do this because Objective-C methods don't get
3964 // pushed into DeclContexts early enough. Argh!
3965 for (unsigned I = 0; I != NumMethods; ++I) {
3966 if (ObjCMethodDecl *Method
John McCall48871652010-08-21 09:40:31 +00003967 = dyn_cast_or_null<ObjCMethodDecl>(Methods[I]))
Douglas Gregorc8537c52009-11-19 07:41:15 +00003968 if (Method->isInstanceMethod() &&
3969 isAcceptableObjCMethod(Method, MK_ZeroArgSelector, 0, 0)) {
3970 Result R = Result(Method, 0);
3971 R.AllParametersAreInformative = true;
3972 Results.MaybeAddResult(R, CurContext);
3973 }
3974 }
3975
Douglas Gregor1154e272010-09-16 16:06:31 +00003976 VisitedSelectorSet Selectors;
3977 AddObjCMethods(Class, true, MK_ZeroArgSelector, 0, 0, CurContext, Selectors,
3978 Results);
Douglas Gregorc8537c52009-11-19 07:41:15 +00003979 Results.ExitScope();
Douglas Gregor00c37ef2010-08-11 21:23:17 +00003980 HandleCodeCompleteResults(this, CodeCompleter,
3981 CodeCompletionContext::CCC_Other,
3982 Results.data(),Results.size());
Douglas Gregorc8537c52009-11-19 07:41:15 +00003983}
3984
John McCall48871652010-08-21 09:40:31 +00003985void Sema::CodeCompleteObjCPropertySetter(Scope *S, Decl *ObjCImplDecl,
3986 Decl **Methods,
Douglas Gregorc8537c52009-11-19 07:41:15 +00003987 unsigned NumMethods) {
John McCall276321a2010-08-25 06:19:51 +00003988 typedef CodeCompletionResult Result;
Douglas Gregorc8537c52009-11-19 07:41:15 +00003989
3990 // Try to find the interface where setters might live.
3991 ObjCInterfaceDecl *Class
John McCall48871652010-08-21 09:40:31 +00003992 = dyn_cast_or_null<ObjCInterfaceDecl>(ObjCImplDecl);
Douglas Gregorc8537c52009-11-19 07:41:15 +00003993 if (!Class) {
3994 if (ObjCCategoryDecl *Category
John McCall48871652010-08-21 09:40:31 +00003995 = dyn_cast_or_null<ObjCCategoryDecl>(ObjCImplDecl))
Douglas Gregorc8537c52009-11-19 07:41:15 +00003996 Class = Category->getClassInterface();
3997
3998 if (!Class)
3999 return;
4000 }
4001
4002 // Find all of the potential getters.
4003 ResultBuilder Results(*this);
4004 Results.EnterNewScope();
4005
4006 // FIXME: We need to do this because Objective-C methods don't get
4007 // pushed into DeclContexts early enough. Argh!
4008 for (unsigned I = 0; I != NumMethods; ++I) {
4009 if (ObjCMethodDecl *Method
John McCall48871652010-08-21 09:40:31 +00004010 = dyn_cast_or_null<ObjCMethodDecl>(Methods[I]))
Douglas Gregorc8537c52009-11-19 07:41:15 +00004011 if (Method->isInstanceMethod() &&
4012 isAcceptableObjCMethod(Method, MK_OneArgSelector, 0, 0)) {
4013 Result R = Result(Method, 0);
4014 R.AllParametersAreInformative = true;
4015 Results.MaybeAddResult(R, CurContext);
4016 }
4017 }
4018
Douglas Gregor1154e272010-09-16 16:06:31 +00004019 VisitedSelectorSet Selectors;
4020 AddObjCMethods(Class, true, MK_OneArgSelector, 0, 0, CurContext,
4021 Selectors, Results);
Douglas Gregorc8537c52009-11-19 07:41:15 +00004022
4023 Results.ExitScope();
Douglas Gregor00c37ef2010-08-11 21:23:17 +00004024 HandleCodeCompleteResults(this, CodeCompleter,
4025 CodeCompletionContext::CCC_Other,
4026 Results.data(),Results.size());
Douglas Gregorbab2b3c2009-11-17 23:22:23 +00004027}
4028
Douglas Gregor99fa2642010-08-24 01:06:58 +00004029void Sema::CodeCompleteObjCPassingType(Scope *S, ObjCDeclSpec &DS) {
John McCall276321a2010-08-25 06:19:51 +00004030 typedef CodeCompletionResult Result;
Douglas Gregor99fa2642010-08-24 01:06:58 +00004031 ResultBuilder Results(*this);
4032 Results.EnterNewScope();
4033
4034 // Add context-sensitive, Objective-C parameter-passing keywords.
4035 bool AddedInOut = false;
4036 if ((DS.getObjCDeclQualifier() &
4037 (ObjCDeclSpec::DQ_In | ObjCDeclSpec::DQ_Inout)) == 0) {
4038 Results.AddResult("in");
4039 Results.AddResult("inout");
4040 AddedInOut = true;
4041 }
4042 if ((DS.getObjCDeclQualifier() &
4043 (ObjCDeclSpec::DQ_Out | ObjCDeclSpec::DQ_Inout)) == 0) {
4044 Results.AddResult("out");
4045 if (!AddedInOut)
4046 Results.AddResult("inout");
4047 }
4048 if ((DS.getObjCDeclQualifier() &
4049 (ObjCDeclSpec::DQ_Bycopy | ObjCDeclSpec::DQ_Byref |
4050 ObjCDeclSpec::DQ_Oneway)) == 0) {
4051 Results.AddResult("bycopy");
4052 Results.AddResult("byref");
4053 Results.AddResult("oneway");
4054 }
4055
4056 // Add various builtin type names and specifiers.
4057 AddOrdinaryNameResults(PCC_Type, S, *this, Results);
4058 Results.ExitScope();
4059
4060 // Add the various type names
4061 Results.setFilter(&ResultBuilder::IsOrdinaryNonValueName);
4062 CodeCompletionDeclConsumer Consumer(Results, CurContext);
4063 LookupVisibleDecls(S, LookupOrdinaryName, Consumer,
4064 CodeCompleter->includeGlobals());
4065
4066 if (CodeCompleter->includeMacros())
4067 AddMacroResults(PP, Results);
4068
4069 HandleCodeCompleteResults(this, CodeCompleter,
4070 CodeCompletionContext::CCC_Type,
4071 Results.data(), Results.size());
4072}
4073
Douglas Gregor9d2ddb22010-04-06 19:22:33 +00004074/// \brief When we have an expression with type "id", we may assume
4075/// that it has some more-specific class type based on knowledge of
4076/// common uses of Objective-C. This routine returns that class type,
4077/// or NULL if no better result could be determined.
4078static ObjCInterfaceDecl *GetAssumedMessageSendExprType(Expr *E) {
Douglas Gregored0b69d2010-09-15 16:23:04 +00004079 ObjCMessageExpr *Msg = dyn_cast_or_null<ObjCMessageExpr>(E);
Douglas Gregor9d2ddb22010-04-06 19:22:33 +00004080 if (!Msg)
4081 return 0;
4082
4083 Selector Sel = Msg->getSelector();
4084 if (Sel.isNull())
4085 return 0;
4086
4087 IdentifierInfo *Id = Sel.getIdentifierInfoForSlot(0);
4088 if (!Id)
4089 return 0;
4090
4091 ObjCMethodDecl *Method = Msg->getMethodDecl();
4092 if (!Method)
4093 return 0;
4094
4095 // Determine the class that we're sending the message to.
Douglas Gregor9a129192010-04-21 00:45:42 +00004096 ObjCInterfaceDecl *IFace = 0;
4097 switch (Msg->getReceiverKind()) {
4098 case ObjCMessageExpr::Class:
John McCall8b07ec22010-05-15 11:32:37 +00004099 if (const ObjCObjectType *ObjType
4100 = Msg->getClassReceiver()->getAs<ObjCObjectType>())
4101 IFace = ObjType->getInterface();
Douglas Gregor9a129192010-04-21 00:45:42 +00004102 break;
4103
4104 case ObjCMessageExpr::Instance: {
4105 QualType T = Msg->getInstanceReceiver()->getType();
4106 if (const ObjCObjectPointerType *Ptr = T->getAs<ObjCObjectPointerType>())
4107 IFace = Ptr->getInterfaceDecl();
4108 break;
4109 }
4110
4111 case ObjCMessageExpr::SuperInstance:
4112 case ObjCMessageExpr::SuperClass:
4113 break;
Douglas Gregor9d2ddb22010-04-06 19:22:33 +00004114 }
4115
4116 if (!IFace)
4117 return 0;
4118
4119 ObjCInterfaceDecl *Super = IFace->getSuperClass();
4120 if (Method->isInstanceMethod())
4121 return llvm::StringSwitch<ObjCInterfaceDecl *>(Id->getName())
4122 .Case("retain", IFace)
4123 .Case("autorelease", IFace)
4124 .Case("copy", IFace)
4125 .Case("copyWithZone", IFace)
4126 .Case("mutableCopy", IFace)
4127 .Case("mutableCopyWithZone", IFace)
4128 .Case("awakeFromCoder", IFace)
4129 .Case("replacementObjectFromCoder", IFace)
4130 .Case("class", IFace)
4131 .Case("classForCoder", IFace)
4132 .Case("superclass", Super)
4133 .Default(0);
4134
4135 return llvm::StringSwitch<ObjCInterfaceDecl *>(Id->getName())
4136 .Case("new", IFace)
4137 .Case("alloc", IFace)
4138 .Case("allocWithZone", IFace)
4139 .Case("class", IFace)
4140 .Case("superclass", Super)
4141 .Default(0);
4142}
4143
Douglas Gregor6fc04132010-08-27 15:10:57 +00004144// Add a special completion for a message send to "super", which fills in the
4145// most likely case of forwarding all of our arguments to the superclass
4146// function.
4147///
4148/// \param S The semantic analysis object.
4149///
4150/// \param S NeedSuperKeyword Whether we need to prefix this completion with
4151/// the "super" keyword. Otherwise, we just need to provide the arguments.
4152///
4153/// \param SelIdents The identifiers in the selector that have already been
4154/// provided as arguments for a send to "super".
4155///
4156/// \param NumSelIdents The number of identifiers in \p SelIdents.
4157///
4158/// \param Results The set of results to augment.
4159///
4160/// \returns the Objective-C method declaration that would be invoked by
4161/// this "super" completion. If NULL, no completion was added.
4162static ObjCMethodDecl *AddSuperSendCompletion(Sema &S, bool NeedSuperKeyword,
4163 IdentifierInfo **SelIdents,
4164 unsigned NumSelIdents,
4165 ResultBuilder &Results) {
4166 ObjCMethodDecl *CurMethod = S.getCurMethodDecl();
4167 if (!CurMethod)
4168 return 0;
4169
4170 ObjCInterfaceDecl *Class = CurMethod->getClassInterface();
4171 if (!Class)
4172 return 0;
4173
4174 // Try to find a superclass method with the same selector.
4175 ObjCMethodDecl *SuperMethod = 0;
4176 while ((Class = Class->getSuperClass()) && !SuperMethod)
4177 SuperMethod = Class->getMethod(CurMethod->getSelector(),
4178 CurMethod->isInstanceMethod());
4179
4180 if (!SuperMethod)
4181 return 0;
4182
4183 // Check whether the superclass method has the same signature.
4184 if (CurMethod->param_size() != SuperMethod->param_size() ||
4185 CurMethod->isVariadic() != SuperMethod->isVariadic())
4186 return 0;
4187
4188 for (ObjCMethodDecl::param_iterator CurP = CurMethod->param_begin(),
4189 CurPEnd = CurMethod->param_end(),
4190 SuperP = SuperMethod->param_begin();
4191 CurP != CurPEnd; ++CurP, ++SuperP) {
4192 // Make sure the parameter types are compatible.
4193 if (!S.Context.hasSameUnqualifiedType((*CurP)->getType(),
4194 (*SuperP)->getType()))
4195 return 0;
4196
4197 // Make sure we have a parameter name to forward!
4198 if (!(*CurP)->getIdentifier())
4199 return 0;
4200 }
4201
4202 // We have a superclass method. Now, form the send-to-super completion.
4203 CodeCompletionString *Pattern = new CodeCompletionString;
4204
4205 // Give this completion a return type.
4206 AddResultTypeChunk(S.Context, SuperMethod, Pattern);
4207
4208 // If we need the "super" keyword, add it (plus some spacing).
4209 if (NeedSuperKeyword) {
4210 Pattern->AddTypedTextChunk("super");
4211 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
4212 }
4213
4214 Selector Sel = CurMethod->getSelector();
4215 if (Sel.isUnarySelector()) {
4216 if (NeedSuperKeyword)
4217 Pattern->AddTextChunk(Sel.getIdentifierInfoForSlot(0)->getName());
4218 else
4219 Pattern->AddTypedTextChunk(Sel.getIdentifierInfoForSlot(0)->getName());
4220 } else {
4221 ObjCMethodDecl::param_iterator CurP = CurMethod->param_begin();
4222 for (unsigned I = 0, N = Sel.getNumArgs(); I != N; ++I, ++CurP) {
4223 if (I > NumSelIdents)
4224 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
4225
4226 if (I < NumSelIdents)
4227 Pattern->AddInformativeChunk(
4228 Sel.getIdentifierInfoForSlot(I)->getName().str() + ":");
4229 else if (NeedSuperKeyword || I > NumSelIdents) {
4230 Pattern->AddTextChunk(
4231 Sel.getIdentifierInfoForSlot(I)->getName().str() + ":");
4232 Pattern->AddPlaceholderChunk((*CurP)->getIdentifier()->getName());
4233 } else {
4234 Pattern->AddTypedTextChunk(
4235 Sel.getIdentifierInfoForSlot(I)->getName().str() + ":");
4236 Pattern->AddPlaceholderChunk((*CurP)->getIdentifier()->getName());
4237 }
4238 }
4239 }
4240
4241 Results.AddResult(CodeCompletionResult(Pattern, CCP_SuperCompletion,
4242 SuperMethod->isInstanceMethod()
4243 ? CXCursor_ObjCInstanceMethodDecl
4244 : CXCursor_ObjCClassMethodDecl));
4245 return SuperMethod;
4246}
4247
Douglas Gregora817a192010-05-27 23:06:34 +00004248void Sema::CodeCompleteObjCMessageReceiver(Scope *S) {
John McCall276321a2010-08-25 06:19:51 +00004249 typedef CodeCompletionResult Result;
Douglas Gregora817a192010-05-27 23:06:34 +00004250 ResultBuilder Results(*this);
4251
4252 // Find anything that looks like it could be a message receiver.
4253 Results.setFilter(&ResultBuilder::IsObjCMessageReceiver);
4254 CodeCompletionDeclConsumer Consumer(Results, CurContext);
4255 Results.EnterNewScope();
Douglas Gregor39982192010-08-15 06:18:01 +00004256 LookupVisibleDecls(S, LookupOrdinaryName, Consumer,
4257 CodeCompleter->includeGlobals());
Douglas Gregora817a192010-05-27 23:06:34 +00004258
4259 // If we are in an Objective-C method inside a class that has a superclass,
4260 // add "super" as an option.
4261 if (ObjCMethodDecl *Method = getCurMethodDecl())
4262 if (ObjCInterfaceDecl *Iface = Method->getClassInterface())
Douglas Gregor6fc04132010-08-27 15:10:57 +00004263 if (Iface->getSuperClass()) {
Douglas Gregora817a192010-05-27 23:06:34 +00004264 Results.AddResult(Result("super"));
Douglas Gregor6fc04132010-08-27 15:10:57 +00004265
4266 AddSuperSendCompletion(*this, /*NeedSuperKeyword=*/true, 0, 0, Results);
4267 }
Douglas Gregora817a192010-05-27 23:06:34 +00004268
4269 Results.ExitScope();
4270
4271 if (CodeCompleter->includeMacros())
4272 AddMacroResults(PP, Results);
Douglas Gregor00c37ef2010-08-11 21:23:17 +00004273 HandleCodeCompleteResults(this, CodeCompleter,
4274 CodeCompletionContext::CCC_ObjCMessageReceiver,
4275 Results.data(), Results.size());
Douglas Gregora817a192010-05-27 23:06:34 +00004276
4277}
4278
Douglas Gregor0c78ad92010-04-21 19:57:20 +00004279void Sema::CodeCompleteObjCSuperMessage(Scope *S, SourceLocation SuperLoc,
4280 IdentifierInfo **SelIdents,
4281 unsigned NumSelIdents) {
4282 ObjCInterfaceDecl *CDecl = 0;
4283 if (ObjCMethodDecl *CurMethod = getCurMethodDecl()) {
4284 // Figure out which interface we're in.
4285 CDecl = CurMethod->getClassInterface();
4286 if (!CDecl)
4287 return;
4288
4289 // Find the superclass of this class.
4290 CDecl = CDecl->getSuperClass();
4291 if (!CDecl)
4292 return;
4293
4294 if (CurMethod->isInstanceMethod()) {
4295 // We are inside an instance method, which means that the message
4296 // send [super ...] is actually calling an instance method on the
4297 // current object. Build the super expression and handle this like
4298 // an instance method.
4299 QualType SuperTy = Context.getObjCInterfaceType(CDecl);
4300 SuperTy = Context.getObjCObjectPointerType(SuperTy);
John McCalldadc5752010-08-24 06:29:42 +00004301 ExprResult Super
Douglas Gregor0c78ad92010-04-21 19:57:20 +00004302 = Owned(new (Context) ObjCSuperExpr(SuperLoc, SuperTy));
4303 return CodeCompleteObjCInstanceMessage(S, (Expr *)Super.get(),
Douglas Gregor6fc04132010-08-27 15:10:57 +00004304 SelIdents, NumSelIdents,
4305 /*IsSuper=*/true);
Douglas Gregor0c78ad92010-04-21 19:57:20 +00004306 }
4307
4308 // Fall through to send to the superclass in CDecl.
4309 } else {
4310 // "super" may be the name of a type or variable. Figure out which
4311 // it is.
4312 IdentifierInfo *Super = &Context.Idents.get("super");
4313 NamedDecl *ND = LookupSingleName(S, Super, SuperLoc,
4314 LookupOrdinaryName);
4315 if ((CDecl = dyn_cast_or_null<ObjCInterfaceDecl>(ND))) {
4316 // "super" names an interface. Use it.
4317 } else if (TypeDecl *TD = dyn_cast_or_null<TypeDecl>(ND)) {
John McCall8b07ec22010-05-15 11:32:37 +00004318 if (const ObjCObjectType *Iface
4319 = Context.getTypeDeclType(TD)->getAs<ObjCObjectType>())
4320 CDecl = Iface->getInterface();
Douglas Gregor0c78ad92010-04-21 19:57:20 +00004321 } else if (ND && isa<UnresolvedUsingTypenameDecl>(ND)) {
4322 // "super" names an unresolved type; we can't be more specific.
4323 } else {
4324 // Assume that "super" names some kind of value and parse that way.
4325 CXXScopeSpec SS;
4326 UnqualifiedId id;
4327 id.setIdentifier(Super, SuperLoc);
John McCalldadc5752010-08-24 06:29:42 +00004328 ExprResult SuperExpr = ActOnIdExpression(S, SS, id, false, false);
Douglas Gregor0c78ad92010-04-21 19:57:20 +00004329 return CodeCompleteObjCInstanceMessage(S, (Expr *)SuperExpr.get(),
4330 SelIdents, NumSelIdents);
4331 }
4332
4333 // Fall through
4334 }
4335
John McCallba7bf592010-08-24 05:47:05 +00004336 ParsedType Receiver;
Douglas Gregor0c78ad92010-04-21 19:57:20 +00004337 if (CDecl)
John McCallba7bf592010-08-24 05:47:05 +00004338 Receiver = ParsedType::make(Context.getObjCInterfaceType(CDecl));
Douglas Gregor0c78ad92010-04-21 19:57:20 +00004339 return CodeCompleteObjCClassMessage(S, Receiver, SelIdents,
Douglas Gregor6fc04132010-08-27 15:10:57 +00004340 NumSelIdents, /*IsSuper=*/true);
Douglas Gregor0c78ad92010-04-21 19:57:20 +00004341}
4342
Douglas Gregorbfcea8b2010-09-16 15:14:18 +00004343static void AddClassMessageCompletions(Sema &SemaRef, Scope *S,
4344 ParsedType Receiver,
4345 IdentifierInfo **SelIdents,
4346 unsigned NumSelIdents,
4347 bool IsSuper,
4348 ResultBuilder &Results) {
John McCall276321a2010-08-25 06:19:51 +00004349 typedef CodeCompletionResult Result;
Douglas Gregor8ce33212009-11-17 17:59:40 +00004350 ObjCInterfaceDecl *CDecl = 0;
Douglas Gregorbfcea8b2010-09-16 15:14:18 +00004351
Douglas Gregor8ce33212009-11-17 17:59:40 +00004352 // If the given name refers to an interface type, retrieve the
4353 // corresponding declaration.
Douglas Gregor0c78ad92010-04-21 19:57:20 +00004354 if (Receiver) {
Douglas Gregorbfcea8b2010-09-16 15:14:18 +00004355 QualType T = SemaRef.GetTypeFromParser(Receiver, 0);
Douglas Gregor0c78ad92010-04-21 19:57:20 +00004356 if (!T.isNull())
John McCall8b07ec22010-05-15 11:32:37 +00004357 if (const ObjCObjectType *Interface = T->getAs<ObjCObjectType>())
4358 CDecl = Interface->getInterface();
Douglas Gregor8ce33212009-11-17 17:59:40 +00004359 }
Douglas Gregorbfcea8b2010-09-16 15:14:18 +00004360
Douglas Gregorbab2b3c2009-11-17 23:22:23 +00004361 // Add all of the factory methods in this Objective-C class, its protocols,
4362 // superclasses, categories, implementation, etc.
Steve Naroffeae65032009-11-07 02:08:14 +00004363 Results.EnterNewScope();
Douglas Gregorbfcea8b2010-09-16 15:14:18 +00004364
Douglas Gregor6fc04132010-08-27 15:10:57 +00004365 // If this is a send-to-super, try to add the special "super" send
4366 // completion.
4367 if (IsSuper) {
4368 if (ObjCMethodDecl *SuperMethod
Douglas Gregorbfcea8b2010-09-16 15:14:18 +00004369 = AddSuperSendCompletion(SemaRef, false, SelIdents, NumSelIdents,
4370 Results))
Douglas Gregor6fc04132010-08-27 15:10:57 +00004371 Results.Ignore(SuperMethod);
4372 }
Douglas Gregorbfcea8b2010-09-16 15:14:18 +00004373
Douglas Gregorc2cb2e22010-08-27 15:29:55 +00004374 // If we're inside an Objective-C method definition, prefer its selector to
4375 // others.
Douglas Gregorbfcea8b2010-09-16 15:14:18 +00004376 if (ObjCMethodDecl *CurMethod = SemaRef.getCurMethodDecl())
Douglas Gregorc2cb2e22010-08-27 15:29:55 +00004377 Results.setPreferredSelector(CurMethod->getSelector());
Douglas Gregorbfcea8b2010-09-16 15:14:18 +00004378
Douglas Gregor1154e272010-09-16 16:06:31 +00004379 VisitedSelectorSet Selectors;
Douglas Gregor6285f752010-04-06 16:40:00 +00004380 if (CDecl)
Douglas Gregorbfcea8b2010-09-16 15:14:18 +00004381 AddObjCMethods(CDecl, false, MK_Any, SelIdents, NumSelIdents,
Douglas Gregor1154e272010-09-16 16:06:31 +00004382 SemaRef.CurContext, Selectors, Results);
Douglas Gregor0c78ad92010-04-21 19:57:20 +00004383 else {
Douglas Gregor6285f752010-04-06 16:40:00 +00004384 // We're messaging "id" as a type; provide all class/factory methods.
Douglas Gregorbfcea8b2010-09-16 15:14:18 +00004385
Douglas Gregord720daf2010-04-06 17:30:22 +00004386 // If we have an external source, load the entire class method
Sebastian Redld44cd6a2010-08-18 23:57:06 +00004387 // pool from the AST file.
Douglas Gregorbfcea8b2010-09-16 15:14:18 +00004388 if (SemaRef.ExternalSource) {
4389 for (uint32_t I = 0,
4390 N = SemaRef.ExternalSource->GetNumExternalSelectors();
John McCall75b960e2010-06-01 09:23:16 +00004391 I != N; ++I) {
Douglas Gregorbfcea8b2010-09-16 15:14:18 +00004392 Selector Sel = SemaRef.ExternalSource->GetExternalSelector(I);
4393 if (Sel.isNull() || SemaRef.MethodPool.count(Sel))
Douglas Gregord720daf2010-04-06 17:30:22 +00004394 continue;
Douglas Gregorbfcea8b2010-09-16 15:14:18 +00004395
4396 SemaRef.ReadMethodPool(Sel);
Douglas Gregord720daf2010-04-06 17:30:22 +00004397 }
4398 }
Douglas Gregorbfcea8b2010-09-16 15:14:18 +00004399
4400 for (Sema::GlobalMethodPool::iterator M = SemaRef.MethodPool.begin(),
4401 MEnd = SemaRef.MethodPool.end();
Sebastian Redl75d8a322010-08-02 23:18:59 +00004402 M != MEnd; ++M) {
4403 for (ObjCMethodList *MethList = &M->second.second;
4404 MethList && MethList->Method;
Douglas Gregor6285f752010-04-06 16:40:00 +00004405 MethList = MethList->Next) {
4406 if (!isAcceptableObjCMethod(MethList->Method, MK_Any, SelIdents,
4407 NumSelIdents))
4408 continue;
Douglas Gregorbfcea8b2010-09-16 15:14:18 +00004409
Douglas Gregor6285f752010-04-06 16:40:00 +00004410 Result R(MethList->Method, 0);
4411 R.StartParameter = NumSelIdents;
4412 R.AllParametersAreInformative = false;
Douglas Gregorbfcea8b2010-09-16 15:14:18 +00004413 Results.MaybeAddResult(R, SemaRef.CurContext);
Douglas Gregor6285f752010-04-06 16:40:00 +00004414 }
4415 }
4416 }
Douglas Gregorbfcea8b2010-09-16 15:14:18 +00004417
4418 Results.ExitScope();
4419}
Douglas Gregor6285f752010-04-06 16:40:00 +00004420
Douglas Gregorbfcea8b2010-09-16 15:14:18 +00004421void Sema::CodeCompleteObjCClassMessage(Scope *S, ParsedType Receiver,
4422 IdentifierInfo **SelIdents,
4423 unsigned NumSelIdents,
4424 bool IsSuper) {
4425 ResultBuilder Results(*this);
4426 AddClassMessageCompletions(*this, S, Receiver, SelIdents, NumSelIdents, IsSuper,
4427 Results);
Douglas Gregor00c37ef2010-08-11 21:23:17 +00004428 HandleCodeCompleteResults(this, CodeCompleter,
4429 CodeCompletionContext::CCC_Other,
Douglas Gregor6fc04132010-08-27 15:10:57 +00004430 Results.data(), Results.size());
Steve Naroffeae65032009-11-07 02:08:14 +00004431}
4432
Douglas Gregor1b605f72009-11-19 01:08:35 +00004433void Sema::CodeCompleteObjCInstanceMessage(Scope *S, ExprTy *Receiver,
4434 IdentifierInfo **SelIdents,
Douglas Gregor6fc04132010-08-27 15:10:57 +00004435 unsigned NumSelIdents,
4436 bool IsSuper) {
John McCall276321a2010-08-25 06:19:51 +00004437 typedef CodeCompletionResult Result;
Steve Naroffeae65032009-11-07 02:08:14 +00004438
4439 Expr *RecExpr = static_cast<Expr *>(Receiver);
Steve Naroffeae65032009-11-07 02:08:14 +00004440
Douglas Gregorbab2b3c2009-11-17 23:22:23 +00004441 // If necessary, apply function/array conversion to the receiver.
4442 // C99 6.7.5.3p[7,8].
Douglas Gregored0b69d2010-09-15 16:23:04 +00004443 if (RecExpr)
4444 DefaultFunctionArrayLvalueConversion(RecExpr);
4445 QualType ReceiverType = RecExpr? RecExpr->getType() : Context.getObjCIdType();
Steve Naroffeae65032009-11-07 02:08:14 +00004446
Douglas Gregorbab2b3c2009-11-17 23:22:23 +00004447 // Build the set of methods we can see.
4448 ResultBuilder Results(*this);
4449 Results.EnterNewScope();
Douglas Gregor9d2ddb22010-04-06 19:22:33 +00004450
Douglas Gregor6fc04132010-08-27 15:10:57 +00004451 // If this is a send-to-super, try to add the special "super" send
4452 // completion.
4453 if (IsSuper) {
4454 if (ObjCMethodDecl *SuperMethod
4455 = AddSuperSendCompletion(*this, false, SelIdents, NumSelIdents,
4456 Results))
4457 Results.Ignore(SuperMethod);
4458 }
4459
Douglas Gregorc2cb2e22010-08-27 15:29:55 +00004460 // If we're inside an Objective-C method definition, prefer its selector to
4461 // others.
4462 if (ObjCMethodDecl *CurMethod = getCurMethodDecl())
4463 Results.setPreferredSelector(CurMethod->getSelector());
4464
Douglas Gregor9d2ddb22010-04-06 19:22:33 +00004465 // If we're messaging an expression with type "id" or "Class", check
4466 // whether we know something special about the receiver that allows
4467 // us to assume a more-specific receiver type.
4468 if (ReceiverType->isObjCIdType() || ReceiverType->isObjCClassType())
4469 if (ObjCInterfaceDecl *IFace = GetAssumedMessageSendExprType(RecExpr))
4470 ReceiverType = Context.getObjCObjectPointerType(
4471 Context.getObjCInterfaceType(IFace));
Douglas Gregorbab2b3c2009-11-17 23:22:23 +00004472
Douglas Gregor1154e272010-09-16 16:06:31 +00004473 // Keep track of the selectors we've already added.
4474 VisitedSelectorSet Selectors;
4475
Douglas Gregora3329fa2009-11-18 00:06:18 +00004476 // Handle messages to Class. This really isn't a message to an instance
4477 // method, so we treat it the same way we would treat a message send to a
4478 // class method.
4479 if (ReceiverType->isObjCClassType() ||
4480 ReceiverType->isObjCQualifiedClassType()) {
4481 if (ObjCMethodDecl *CurMethod = getCurMethodDecl()) {
4482 if (ObjCInterfaceDecl *ClassDecl = CurMethod->getClassInterface())
Douglas Gregorc8537c52009-11-19 07:41:15 +00004483 AddObjCMethods(ClassDecl, false, MK_Any, SelIdents, NumSelIdents,
Douglas Gregor1154e272010-09-16 16:06:31 +00004484 CurContext, Selectors, Results);
Douglas Gregora3329fa2009-11-18 00:06:18 +00004485 }
4486 }
4487 // Handle messages to a qualified ID ("id<foo>").
4488 else if (const ObjCObjectPointerType *QualID
4489 = ReceiverType->getAsObjCQualifiedIdType()) {
4490 // Search protocols for instance methods.
4491 for (ObjCObjectPointerType::qual_iterator I = QualID->qual_begin(),
4492 E = QualID->qual_end();
4493 I != E; ++I)
Douglas Gregorc8537c52009-11-19 07:41:15 +00004494 AddObjCMethods(*I, true, MK_Any, SelIdents, NumSelIdents, CurContext,
Douglas Gregor1154e272010-09-16 16:06:31 +00004495 Selectors, Results);
Douglas Gregora3329fa2009-11-18 00:06:18 +00004496 }
4497 // Handle messages to a pointer to interface type.
4498 else if (const ObjCObjectPointerType *IFacePtr
4499 = ReceiverType->getAsObjCInterfacePointerType()) {
4500 // Search the class, its superclasses, etc., for instance methods.
Douglas Gregorc8537c52009-11-19 07:41:15 +00004501 AddObjCMethods(IFacePtr->getInterfaceDecl(), true, MK_Any, SelIdents,
Douglas Gregor1154e272010-09-16 16:06:31 +00004502 NumSelIdents, CurContext, Selectors, Results);
Douglas Gregora3329fa2009-11-18 00:06:18 +00004503
4504 // Search protocols for instance methods.
4505 for (ObjCObjectPointerType::qual_iterator I = IFacePtr->qual_begin(),
4506 E = IFacePtr->qual_end();
4507 I != E; ++I)
Douglas Gregorc8537c52009-11-19 07:41:15 +00004508 AddObjCMethods(*I, true, MK_Any, SelIdents, NumSelIdents, CurContext,
Douglas Gregor1154e272010-09-16 16:06:31 +00004509 Selectors, Results);
Douglas Gregora3329fa2009-11-18 00:06:18 +00004510 }
Douglas Gregor6285f752010-04-06 16:40:00 +00004511 // Handle messages to "id".
4512 else if (ReceiverType->isObjCIdType()) {
Douglas Gregord720daf2010-04-06 17:30:22 +00004513 // We're messaging "id", so provide all instance methods we know
4514 // about as code-completion results.
4515
4516 // If we have an external source, load the entire class method
Sebastian Redld44cd6a2010-08-18 23:57:06 +00004517 // pool from the AST file.
Douglas Gregord720daf2010-04-06 17:30:22 +00004518 if (ExternalSource) {
John McCall75b960e2010-06-01 09:23:16 +00004519 for (uint32_t I = 0, N = ExternalSource->GetNumExternalSelectors();
4520 I != N; ++I) {
4521 Selector Sel = ExternalSource->GetExternalSelector(I);
Sebastian Redl75d8a322010-08-02 23:18:59 +00004522 if (Sel.isNull() || MethodPool.count(Sel))
Douglas Gregord720daf2010-04-06 17:30:22 +00004523 continue;
4524
Sebastian Redl75d8a322010-08-02 23:18:59 +00004525 ReadMethodPool(Sel);
Douglas Gregord720daf2010-04-06 17:30:22 +00004526 }
4527 }
4528
Sebastian Redl75d8a322010-08-02 23:18:59 +00004529 for (GlobalMethodPool::iterator M = MethodPool.begin(),
4530 MEnd = MethodPool.end();
4531 M != MEnd; ++M) {
4532 for (ObjCMethodList *MethList = &M->second.first;
4533 MethList && MethList->Method;
Douglas Gregor6285f752010-04-06 16:40:00 +00004534 MethList = MethList->Next) {
4535 if (!isAcceptableObjCMethod(MethList->Method, MK_Any, SelIdents,
4536 NumSelIdents))
4537 continue;
Douglas Gregor1154e272010-09-16 16:06:31 +00004538
4539 if (!Selectors.insert(MethList->Method->getSelector()))
4540 continue;
4541
Douglas Gregor6285f752010-04-06 16:40:00 +00004542 Result R(MethList->Method, 0);
4543 R.StartParameter = NumSelIdents;
4544 R.AllParametersAreInformative = false;
4545 Results.MaybeAddResult(R, CurContext);
4546 }
4547 }
4548 }
4549
Steve Naroffeae65032009-11-07 02:08:14 +00004550 Results.ExitScope();
Douglas Gregor00c37ef2010-08-11 21:23:17 +00004551 HandleCodeCompleteResults(this, CodeCompleter,
4552 CodeCompletionContext::CCC_Other,
4553 Results.data(),Results.size());
Steve Naroffeae65032009-11-07 02:08:14 +00004554}
Douglas Gregorbaf69612009-11-18 04:19:12 +00004555
Douglas Gregor68762e72010-08-23 21:17:50 +00004556void Sema::CodeCompleteObjCForCollection(Scope *S,
4557 DeclGroupPtrTy IterationVar) {
4558 CodeCompleteExpressionData Data;
4559 Data.ObjCCollection = true;
4560
4561 if (IterationVar.getAsOpaquePtr()) {
4562 DeclGroupRef DG = IterationVar.getAsVal<DeclGroupRef>();
4563 for (DeclGroupRef::iterator I = DG.begin(), End = DG.end(); I != End; ++I) {
4564 if (*I)
4565 Data.IgnoreDecls.push_back(*I);
4566 }
4567 }
4568
4569 CodeCompleteExpression(S, Data);
4570}
4571
Douglas Gregor67c692c2010-08-26 15:07:07 +00004572void Sema::CodeCompleteObjCSelector(Scope *S, IdentifierInfo **SelIdents,
4573 unsigned NumSelIdents) {
4574 // If we have an external source, load the entire class method
4575 // pool from the AST file.
4576 if (ExternalSource) {
4577 for (uint32_t I = 0, N = ExternalSource->GetNumExternalSelectors();
4578 I != N; ++I) {
4579 Selector Sel = ExternalSource->GetExternalSelector(I);
4580 if (Sel.isNull() || MethodPool.count(Sel))
4581 continue;
4582
4583 ReadMethodPool(Sel);
4584 }
4585 }
4586
4587 ResultBuilder Results(*this);
4588 Results.EnterNewScope();
4589 for (GlobalMethodPool::iterator M = MethodPool.begin(),
4590 MEnd = MethodPool.end();
4591 M != MEnd; ++M) {
4592
4593 Selector Sel = M->first;
4594 if (!isAcceptableObjCSelector(Sel, MK_Any, SelIdents, NumSelIdents))
4595 continue;
4596
4597 CodeCompletionString *Pattern = new CodeCompletionString;
4598 if (Sel.isUnarySelector()) {
4599 Pattern->AddTypedTextChunk(Sel.getIdentifierInfoForSlot(0)->getName());
4600 Results.AddResult(Pattern);
4601 continue;
4602 }
4603
Douglas Gregor9ac1ad12010-08-26 16:46:39 +00004604 std::string Accumulator;
Douglas Gregor67c692c2010-08-26 15:07:07 +00004605 for (unsigned I = 0, N = Sel.getNumArgs(); I != N; ++I) {
Douglas Gregor9ac1ad12010-08-26 16:46:39 +00004606 if (I == NumSelIdents) {
4607 if (!Accumulator.empty()) {
4608 Pattern->AddInformativeChunk(Accumulator);
4609 Accumulator.clear();
4610 }
4611 }
4612
4613 Accumulator += Sel.getIdentifierInfoForSlot(I)->getName().str();
4614 Accumulator += ':';
Douglas Gregor67c692c2010-08-26 15:07:07 +00004615 }
Douglas Gregor9ac1ad12010-08-26 16:46:39 +00004616 Pattern->AddTypedTextChunk(Accumulator);
Douglas Gregor67c692c2010-08-26 15:07:07 +00004617 Results.AddResult(Pattern);
4618 }
4619 Results.ExitScope();
4620
4621 HandleCodeCompleteResults(this, CodeCompleter,
4622 CodeCompletionContext::CCC_SelectorName,
4623 Results.data(), Results.size());
4624}
4625
Douglas Gregorbaf69612009-11-18 04:19:12 +00004626/// \brief Add all of the protocol declarations that we find in the given
4627/// (translation unit) context.
4628static void AddProtocolResults(DeclContext *Ctx, DeclContext *CurContext,
Douglas Gregor5b4671c2009-11-18 04:49:41 +00004629 bool OnlyForwardDeclarations,
Douglas Gregorbaf69612009-11-18 04:19:12 +00004630 ResultBuilder &Results) {
John McCall276321a2010-08-25 06:19:51 +00004631 typedef CodeCompletionResult Result;
Douglas Gregorbaf69612009-11-18 04:19:12 +00004632
4633 for (DeclContext::decl_iterator D = Ctx->decls_begin(),
4634 DEnd = Ctx->decls_end();
4635 D != DEnd; ++D) {
4636 // Record any protocols we find.
4637 if (ObjCProtocolDecl *Proto = dyn_cast<ObjCProtocolDecl>(*D))
Douglas Gregor5b4671c2009-11-18 04:49:41 +00004638 if (!OnlyForwardDeclarations || Proto->isForwardDecl())
Douglas Gregorfc59ce12010-01-14 16:14:35 +00004639 Results.AddResult(Result(Proto, 0), CurContext, 0, false);
Douglas Gregorbaf69612009-11-18 04:19:12 +00004640
4641 // Record any forward-declared protocols we find.
4642 if (ObjCForwardProtocolDecl *Forward
4643 = dyn_cast<ObjCForwardProtocolDecl>(*D)) {
4644 for (ObjCForwardProtocolDecl::protocol_iterator
4645 P = Forward->protocol_begin(),
4646 PEnd = Forward->protocol_end();
4647 P != PEnd; ++P)
Douglas Gregor5b4671c2009-11-18 04:49:41 +00004648 if (!OnlyForwardDeclarations || (*P)->isForwardDecl())
Douglas Gregorfc59ce12010-01-14 16:14:35 +00004649 Results.AddResult(Result(*P, 0), CurContext, 0, false);
Douglas Gregorbaf69612009-11-18 04:19:12 +00004650 }
4651 }
4652}
4653
4654void Sema::CodeCompleteObjCProtocolReferences(IdentifierLocPair *Protocols,
4655 unsigned NumProtocols) {
4656 ResultBuilder Results(*this);
4657 Results.EnterNewScope();
4658
4659 // Tell the result set to ignore all of the protocols we have
4660 // already seen.
4661 for (unsigned I = 0; I != NumProtocols; ++I)
Douglas Gregorb2ccf012010-04-15 22:33:43 +00004662 if (ObjCProtocolDecl *Protocol = LookupProtocol(Protocols[I].first,
4663 Protocols[I].second))
Douglas Gregorbaf69612009-11-18 04:19:12 +00004664 Results.Ignore(Protocol);
4665
4666 // Add all protocols.
Douglas Gregor5b4671c2009-11-18 04:49:41 +00004667 AddProtocolResults(Context.getTranslationUnitDecl(), CurContext, false,
4668 Results);
4669
4670 Results.ExitScope();
Douglas Gregor00c37ef2010-08-11 21:23:17 +00004671 HandleCodeCompleteResults(this, CodeCompleter,
4672 CodeCompletionContext::CCC_ObjCProtocolName,
4673 Results.data(),Results.size());
Douglas Gregor5b4671c2009-11-18 04:49:41 +00004674}
4675
4676void Sema::CodeCompleteObjCProtocolDecl(Scope *) {
4677 ResultBuilder Results(*this);
4678 Results.EnterNewScope();
4679
4680 // Add all protocols.
4681 AddProtocolResults(Context.getTranslationUnitDecl(), CurContext, true,
4682 Results);
Douglas Gregorbaf69612009-11-18 04:19:12 +00004683
4684 Results.ExitScope();
Douglas Gregor00c37ef2010-08-11 21:23:17 +00004685 HandleCodeCompleteResults(this, CodeCompleter,
4686 CodeCompletionContext::CCC_ObjCProtocolName,
4687 Results.data(),Results.size());
Douglas Gregorbaf69612009-11-18 04:19:12 +00004688}
Douglas Gregor49c22a72009-11-18 16:26:39 +00004689
4690/// \brief Add all of the Objective-C interface declarations that we find in
4691/// the given (translation unit) context.
4692static void AddInterfaceResults(DeclContext *Ctx, DeclContext *CurContext,
4693 bool OnlyForwardDeclarations,
4694 bool OnlyUnimplemented,
4695 ResultBuilder &Results) {
John McCall276321a2010-08-25 06:19:51 +00004696 typedef CodeCompletionResult Result;
Douglas Gregor49c22a72009-11-18 16:26:39 +00004697
4698 for (DeclContext::decl_iterator D = Ctx->decls_begin(),
4699 DEnd = Ctx->decls_end();
4700 D != DEnd; ++D) {
Douglas Gregor1c283312010-08-11 12:19:30 +00004701 // Record any interfaces we find.
4702 if (ObjCInterfaceDecl *Class = dyn_cast<ObjCInterfaceDecl>(*D))
4703 if ((!OnlyForwardDeclarations || Class->isForwardDecl()) &&
4704 (!OnlyUnimplemented || !Class->getImplementation()))
4705 Results.AddResult(Result(Class, 0), CurContext, 0, false);
Douglas Gregor49c22a72009-11-18 16:26:39 +00004706
4707 // Record any forward-declared interfaces we find.
4708 if (ObjCClassDecl *Forward = dyn_cast<ObjCClassDecl>(*D)) {
4709 for (ObjCClassDecl::iterator C = Forward->begin(), CEnd = Forward->end();
Douglas Gregor1c283312010-08-11 12:19:30 +00004710 C != CEnd; ++C)
4711 if ((!OnlyForwardDeclarations || C->getInterface()->isForwardDecl()) &&
4712 (!OnlyUnimplemented || !C->getInterface()->getImplementation()))
4713 Results.AddResult(Result(C->getInterface(), 0), CurContext,
Douglas Gregorfc59ce12010-01-14 16:14:35 +00004714 0, false);
Douglas Gregor49c22a72009-11-18 16:26:39 +00004715 }
4716 }
4717}
4718
4719void Sema::CodeCompleteObjCInterfaceDecl(Scope *S) {
4720 ResultBuilder Results(*this);
4721 Results.EnterNewScope();
4722
4723 // Add all classes.
4724 AddInterfaceResults(Context.getTranslationUnitDecl(), CurContext, true,
4725 false, Results);
4726
4727 Results.ExitScope();
Douglas Gregor00c37ef2010-08-11 21:23:17 +00004728 HandleCodeCompleteResults(this, CodeCompleter,
4729 CodeCompletionContext::CCC_Other,
4730 Results.data(),Results.size());
Douglas Gregor49c22a72009-11-18 16:26:39 +00004731}
4732
Douglas Gregorb2ccf012010-04-15 22:33:43 +00004733void Sema::CodeCompleteObjCSuperclass(Scope *S, IdentifierInfo *ClassName,
4734 SourceLocation ClassNameLoc) {
Douglas Gregor49c22a72009-11-18 16:26:39 +00004735 ResultBuilder Results(*this);
4736 Results.EnterNewScope();
4737
4738 // Make sure that we ignore the class we're currently defining.
4739 NamedDecl *CurClass
Douglas Gregorb2ccf012010-04-15 22:33:43 +00004740 = LookupSingleName(TUScope, ClassName, ClassNameLoc, LookupOrdinaryName);
Douglas Gregor5d34fd32009-11-18 19:08:43 +00004741 if (CurClass && isa<ObjCInterfaceDecl>(CurClass))
Douglas Gregor49c22a72009-11-18 16:26:39 +00004742 Results.Ignore(CurClass);
4743
4744 // Add all classes.
4745 AddInterfaceResults(Context.getTranslationUnitDecl(), CurContext, false,
4746 false, Results);
4747
4748 Results.ExitScope();
Douglas Gregor00c37ef2010-08-11 21:23:17 +00004749 HandleCodeCompleteResults(this, CodeCompleter,
4750 CodeCompletionContext::CCC_Other,
4751 Results.data(),Results.size());
Douglas Gregor49c22a72009-11-18 16:26:39 +00004752}
4753
4754void Sema::CodeCompleteObjCImplementationDecl(Scope *S) {
4755 ResultBuilder Results(*this);
4756 Results.EnterNewScope();
4757
4758 // Add all unimplemented classes.
4759 AddInterfaceResults(Context.getTranslationUnitDecl(), CurContext, false,
4760 true, Results);
4761
4762 Results.ExitScope();
Douglas Gregor00c37ef2010-08-11 21:23:17 +00004763 HandleCodeCompleteResults(this, CodeCompleter,
4764 CodeCompletionContext::CCC_Other,
4765 Results.data(),Results.size());
Douglas Gregor49c22a72009-11-18 16:26:39 +00004766}
Douglas Gregor5d34fd32009-11-18 19:08:43 +00004767
4768void Sema::CodeCompleteObjCInterfaceCategory(Scope *S,
Douglas Gregorb2ccf012010-04-15 22:33:43 +00004769 IdentifierInfo *ClassName,
4770 SourceLocation ClassNameLoc) {
John McCall276321a2010-08-25 06:19:51 +00004771 typedef CodeCompletionResult Result;
Douglas Gregor5d34fd32009-11-18 19:08:43 +00004772
4773 ResultBuilder Results(*this);
4774
4775 // Ignore any categories we find that have already been implemented by this
4776 // interface.
4777 llvm::SmallPtrSet<IdentifierInfo *, 16> CategoryNames;
4778 NamedDecl *CurClass
Douglas Gregorb2ccf012010-04-15 22:33:43 +00004779 = LookupSingleName(TUScope, ClassName, ClassNameLoc, LookupOrdinaryName);
Douglas Gregor5d34fd32009-11-18 19:08:43 +00004780 if (ObjCInterfaceDecl *Class = dyn_cast_or_null<ObjCInterfaceDecl>(CurClass))
4781 for (ObjCCategoryDecl *Category = Class->getCategoryList(); Category;
4782 Category = Category->getNextClassCategory())
4783 CategoryNames.insert(Category->getIdentifier());
4784
4785 // Add all of the categories we know about.
4786 Results.EnterNewScope();
4787 TranslationUnitDecl *TU = Context.getTranslationUnitDecl();
4788 for (DeclContext::decl_iterator D = TU->decls_begin(),
4789 DEnd = TU->decls_end();
4790 D != DEnd; ++D)
4791 if (ObjCCategoryDecl *Category = dyn_cast<ObjCCategoryDecl>(*D))
4792 if (CategoryNames.insert(Category->getIdentifier()))
Douglas Gregorfc59ce12010-01-14 16:14:35 +00004793 Results.AddResult(Result(Category, 0), CurContext, 0, false);
Douglas Gregor5d34fd32009-11-18 19:08:43 +00004794 Results.ExitScope();
4795
Douglas Gregor00c37ef2010-08-11 21:23:17 +00004796 HandleCodeCompleteResults(this, CodeCompleter,
4797 CodeCompletionContext::CCC_Other,
4798 Results.data(),Results.size());
Douglas Gregor5d34fd32009-11-18 19:08:43 +00004799}
4800
4801void Sema::CodeCompleteObjCImplementationCategory(Scope *S,
Douglas Gregorb2ccf012010-04-15 22:33:43 +00004802 IdentifierInfo *ClassName,
4803 SourceLocation ClassNameLoc) {
John McCall276321a2010-08-25 06:19:51 +00004804 typedef CodeCompletionResult Result;
Douglas Gregor5d34fd32009-11-18 19:08:43 +00004805
4806 // Find the corresponding interface. If we couldn't find the interface, the
4807 // program itself is ill-formed. However, we'll try to be helpful still by
4808 // providing the list of all of the categories we know about.
4809 NamedDecl *CurClass
Douglas Gregorb2ccf012010-04-15 22:33:43 +00004810 = LookupSingleName(TUScope, ClassName, ClassNameLoc, LookupOrdinaryName);
Douglas Gregor5d34fd32009-11-18 19:08:43 +00004811 ObjCInterfaceDecl *Class = dyn_cast_or_null<ObjCInterfaceDecl>(CurClass);
4812 if (!Class)
Douglas Gregorb2ccf012010-04-15 22:33:43 +00004813 return CodeCompleteObjCInterfaceCategory(S, ClassName, ClassNameLoc);
Douglas Gregor5d34fd32009-11-18 19:08:43 +00004814
4815 ResultBuilder Results(*this);
4816
4817 // Add all of the categories that have have corresponding interface
4818 // declarations in this class and any of its superclasses, except for
4819 // already-implemented categories in the class itself.
4820 llvm::SmallPtrSet<IdentifierInfo *, 16> CategoryNames;
4821 Results.EnterNewScope();
4822 bool IgnoreImplemented = true;
4823 while (Class) {
4824 for (ObjCCategoryDecl *Category = Class->getCategoryList(); Category;
4825 Category = Category->getNextClassCategory())
4826 if ((!IgnoreImplemented || !Category->getImplementation()) &&
4827 CategoryNames.insert(Category->getIdentifier()))
Douglas Gregorfc59ce12010-01-14 16:14:35 +00004828 Results.AddResult(Result(Category, 0), CurContext, 0, false);
Douglas Gregor5d34fd32009-11-18 19:08:43 +00004829
4830 Class = Class->getSuperClass();
4831 IgnoreImplemented = false;
4832 }
4833 Results.ExitScope();
4834
Douglas Gregor00c37ef2010-08-11 21:23:17 +00004835 HandleCodeCompleteResults(this, CodeCompleter,
4836 CodeCompletionContext::CCC_Other,
4837 Results.data(),Results.size());
Douglas Gregor5d34fd32009-11-18 19:08:43 +00004838}
Douglas Gregor5d649882009-11-18 22:32:06 +00004839
John McCall48871652010-08-21 09:40:31 +00004840void Sema::CodeCompleteObjCPropertyDefinition(Scope *S, Decl *ObjCImpDecl) {
John McCall276321a2010-08-25 06:19:51 +00004841 typedef CodeCompletionResult Result;
Douglas Gregor5d649882009-11-18 22:32:06 +00004842 ResultBuilder Results(*this);
4843
4844 // Figure out where this @synthesize lives.
4845 ObjCContainerDecl *Container
John McCall48871652010-08-21 09:40:31 +00004846 = dyn_cast_or_null<ObjCContainerDecl>(ObjCImpDecl);
Douglas Gregor5d649882009-11-18 22:32:06 +00004847 if (!Container ||
4848 (!isa<ObjCImplementationDecl>(Container) &&
4849 !isa<ObjCCategoryImplDecl>(Container)))
4850 return;
4851
4852 // Ignore any properties that have already been implemented.
4853 for (DeclContext::decl_iterator D = Container->decls_begin(),
4854 DEnd = Container->decls_end();
4855 D != DEnd; ++D)
4856 if (ObjCPropertyImplDecl *PropertyImpl = dyn_cast<ObjCPropertyImplDecl>(*D))
4857 Results.Ignore(PropertyImpl->getPropertyDecl());
4858
4859 // Add any properties that we find.
4860 Results.EnterNewScope();
4861 if (ObjCImplementationDecl *ClassImpl
4862 = dyn_cast<ObjCImplementationDecl>(Container))
4863 AddObjCProperties(ClassImpl->getClassInterface(), false, CurContext,
4864 Results);
4865 else
4866 AddObjCProperties(cast<ObjCCategoryImplDecl>(Container)->getCategoryDecl(),
4867 false, CurContext, Results);
4868 Results.ExitScope();
4869
Douglas Gregor00c37ef2010-08-11 21:23:17 +00004870 HandleCodeCompleteResults(this, CodeCompleter,
4871 CodeCompletionContext::CCC_Other,
4872 Results.data(),Results.size());
Douglas Gregor5d649882009-11-18 22:32:06 +00004873}
4874
4875void Sema::CodeCompleteObjCPropertySynthesizeIvar(Scope *S,
4876 IdentifierInfo *PropertyName,
John McCall48871652010-08-21 09:40:31 +00004877 Decl *ObjCImpDecl) {
John McCall276321a2010-08-25 06:19:51 +00004878 typedef CodeCompletionResult Result;
Douglas Gregor5d649882009-11-18 22:32:06 +00004879 ResultBuilder Results(*this);
4880
4881 // Figure out where this @synthesize lives.
4882 ObjCContainerDecl *Container
John McCall48871652010-08-21 09:40:31 +00004883 = dyn_cast_or_null<ObjCContainerDecl>(ObjCImpDecl);
Douglas Gregor5d649882009-11-18 22:32:06 +00004884 if (!Container ||
4885 (!isa<ObjCImplementationDecl>(Container) &&
4886 !isa<ObjCCategoryImplDecl>(Container)))
4887 return;
4888
4889 // Figure out which interface we're looking into.
4890 ObjCInterfaceDecl *Class = 0;
4891 if (ObjCImplementationDecl *ClassImpl
4892 = dyn_cast<ObjCImplementationDecl>(Container))
4893 Class = ClassImpl->getClassInterface();
4894 else
4895 Class = cast<ObjCCategoryImplDecl>(Container)->getCategoryDecl()
4896 ->getClassInterface();
4897
4898 // Add all of the instance variables in this class and its superclasses.
4899 Results.EnterNewScope();
4900 for(; Class; Class = Class->getSuperClass()) {
4901 // FIXME: We could screen the type of each ivar for compatibility with
4902 // the property, but is that being too paternal?
4903 for (ObjCInterfaceDecl::ivar_iterator IVar = Class->ivar_begin(),
4904 IVarEnd = Class->ivar_end();
4905 IVar != IVarEnd; ++IVar)
Douglas Gregorfc59ce12010-01-14 16:14:35 +00004906 Results.AddResult(Result(*IVar, 0), CurContext, 0, false);
Douglas Gregor5d649882009-11-18 22:32:06 +00004907 }
4908 Results.ExitScope();
4909
Douglas Gregor00c37ef2010-08-11 21:23:17 +00004910 HandleCodeCompleteResults(this, CodeCompleter,
4911 CodeCompletionContext::CCC_Other,
4912 Results.data(),Results.size());
Douglas Gregor5d649882009-11-18 22:32:06 +00004913}
Douglas Gregor636a61e2010-04-07 00:21:17 +00004914
Douglas Gregor416b5752010-08-25 01:08:01 +00004915// Mapping from selectors to the methods that implement that selector, along
4916// with the "in original class" flag.
4917typedef llvm::DenseMap<Selector, std::pair<ObjCMethodDecl *, bool> >
4918 KnownMethodsMap;
Douglas Gregor636a61e2010-04-07 00:21:17 +00004919
4920/// \brief Find all of the methods that reside in the given container
4921/// (and its superclasses, protocols, etc.) that meet the given
4922/// criteria. Insert those methods into the map of known methods,
4923/// indexed by selector so they can be easily found.
4924static void FindImplementableMethods(ASTContext &Context,
4925 ObjCContainerDecl *Container,
4926 bool WantInstanceMethods,
4927 QualType ReturnType,
4928 bool IsInImplementation,
Douglas Gregor416b5752010-08-25 01:08:01 +00004929 KnownMethodsMap &KnownMethods,
4930 bool InOriginalClass = true) {
Douglas Gregor636a61e2010-04-07 00:21:17 +00004931 if (ObjCInterfaceDecl *IFace = dyn_cast<ObjCInterfaceDecl>(Container)) {
4932 // Recurse into protocols.
4933 const ObjCList<ObjCProtocolDecl> &Protocols
4934 = IFace->getReferencedProtocols();
4935 for (ObjCList<ObjCProtocolDecl>::iterator I = Protocols.begin(),
4936 E = Protocols.end();
4937 I != E; ++I)
4938 FindImplementableMethods(Context, *I, WantInstanceMethods, ReturnType,
Douglas Gregor416b5752010-08-25 01:08:01 +00004939 IsInImplementation, KnownMethods,
4940 InOriginalClass);
Douglas Gregor636a61e2010-04-07 00:21:17 +00004941
4942 // If we're not in the implementation of a class, also visit the
4943 // superclass.
4944 if (!IsInImplementation && IFace->getSuperClass())
4945 FindImplementableMethods(Context, IFace->getSuperClass(),
4946 WantInstanceMethods, ReturnType,
Douglas Gregor416b5752010-08-25 01:08:01 +00004947 IsInImplementation, KnownMethods,
4948 false);
Douglas Gregor636a61e2010-04-07 00:21:17 +00004949
4950 // Add methods from any class extensions (but not from categories;
4951 // those should go into category implementations).
Fariborz Jahanian3bf0ded2010-06-22 23:20:40 +00004952 for (const ObjCCategoryDecl *Cat = IFace->getFirstClassExtension(); Cat;
4953 Cat = Cat->getNextClassExtension())
4954 FindImplementableMethods(Context, const_cast<ObjCCategoryDecl*>(Cat),
4955 WantInstanceMethods, ReturnType,
Douglas Gregor416b5752010-08-25 01:08:01 +00004956 IsInImplementation, KnownMethods,
4957 InOriginalClass);
Douglas Gregor636a61e2010-04-07 00:21:17 +00004958 }
4959
4960 if (ObjCCategoryDecl *Category = dyn_cast<ObjCCategoryDecl>(Container)) {
4961 // Recurse into protocols.
4962 const ObjCList<ObjCProtocolDecl> &Protocols
4963 = Category->getReferencedProtocols();
4964 for (ObjCList<ObjCProtocolDecl>::iterator I = Protocols.begin(),
4965 E = Protocols.end();
4966 I != E; ++I)
4967 FindImplementableMethods(Context, *I, WantInstanceMethods, ReturnType,
Douglas Gregor416b5752010-08-25 01:08:01 +00004968 IsInImplementation, KnownMethods,
4969 InOriginalClass);
Douglas Gregor636a61e2010-04-07 00:21:17 +00004970 }
4971
4972 if (ObjCProtocolDecl *Protocol = dyn_cast<ObjCProtocolDecl>(Container)) {
4973 // Recurse into protocols.
4974 const ObjCList<ObjCProtocolDecl> &Protocols
4975 = Protocol->getReferencedProtocols();
4976 for (ObjCList<ObjCProtocolDecl>::iterator I = Protocols.begin(),
4977 E = Protocols.end();
4978 I != E; ++I)
4979 FindImplementableMethods(Context, *I, WantInstanceMethods, ReturnType,
Douglas Gregor416b5752010-08-25 01:08:01 +00004980 IsInImplementation, KnownMethods, false);
Douglas Gregor636a61e2010-04-07 00:21:17 +00004981 }
4982
4983 // Add methods in this container. This operation occurs last because
4984 // we want the methods from this container to override any methods
4985 // we've previously seen with the same selector.
4986 for (ObjCContainerDecl::method_iterator M = Container->meth_begin(),
4987 MEnd = Container->meth_end();
4988 M != MEnd; ++M) {
4989 if ((*M)->isInstanceMethod() == WantInstanceMethods) {
4990 if (!ReturnType.isNull() &&
4991 !Context.hasSameUnqualifiedType(ReturnType, (*M)->getResultType()))
4992 continue;
4993
Douglas Gregor416b5752010-08-25 01:08:01 +00004994 KnownMethods[(*M)->getSelector()] = std::make_pair(*M, InOriginalClass);
Douglas Gregor636a61e2010-04-07 00:21:17 +00004995 }
4996 }
4997}
4998
4999void Sema::CodeCompleteObjCMethodDecl(Scope *S,
5000 bool IsInstanceMethod,
John McCallba7bf592010-08-24 05:47:05 +00005001 ParsedType ReturnTy,
John McCall48871652010-08-21 09:40:31 +00005002 Decl *IDecl) {
Douglas Gregor636a61e2010-04-07 00:21:17 +00005003 // Determine the return type of the method we're declaring, if
5004 // provided.
5005 QualType ReturnType = GetTypeFromParser(ReturnTy);
5006
5007 // Determine where we should start searching for methods, and where we
5008 ObjCContainerDecl *SearchDecl = 0, *CurrentDecl = 0;
5009 bool IsInImplementation = false;
John McCall48871652010-08-21 09:40:31 +00005010 if (Decl *D = IDecl) {
Douglas Gregor636a61e2010-04-07 00:21:17 +00005011 if (ObjCImplementationDecl *Impl = dyn_cast<ObjCImplementationDecl>(D)) {
5012 SearchDecl = Impl->getClassInterface();
5013 CurrentDecl = Impl;
5014 IsInImplementation = true;
5015 } else if (ObjCCategoryImplDecl *CatImpl
5016 = dyn_cast<ObjCCategoryImplDecl>(D)) {
5017 SearchDecl = CatImpl->getCategoryDecl();
5018 CurrentDecl = CatImpl;
5019 IsInImplementation = true;
5020 } else {
5021 SearchDecl = dyn_cast<ObjCContainerDecl>(D);
5022 CurrentDecl = SearchDecl;
5023 }
5024 }
5025
5026 if (!SearchDecl && S) {
5027 if (DeclContext *DC = static_cast<DeclContext *>(S->getEntity())) {
5028 SearchDecl = dyn_cast<ObjCContainerDecl>(DC);
5029 CurrentDecl = SearchDecl;
5030 }
5031 }
5032
5033 if (!SearchDecl || !CurrentDecl) {
Douglas Gregor00c37ef2010-08-11 21:23:17 +00005034 HandleCodeCompleteResults(this, CodeCompleter,
5035 CodeCompletionContext::CCC_Other,
5036 0, 0);
Douglas Gregor636a61e2010-04-07 00:21:17 +00005037 return;
5038 }
5039
5040 // Find all of the methods that we could declare/implement here.
5041 KnownMethodsMap KnownMethods;
5042 FindImplementableMethods(Context, SearchDecl, IsInstanceMethod,
5043 ReturnType, IsInImplementation, KnownMethods);
5044
5045 // Erase any methods that have already been declared or
5046 // implemented here.
5047 for (ObjCContainerDecl::method_iterator M = CurrentDecl->meth_begin(),
5048 MEnd = CurrentDecl->meth_end();
5049 M != MEnd; ++M) {
5050 if ((*M)->isInstanceMethod() != IsInstanceMethod)
5051 continue;
5052
5053 KnownMethodsMap::iterator Pos = KnownMethods.find((*M)->getSelector());
5054 if (Pos != KnownMethods.end())
5055 KnownMethods.erase(Pos);
5056 }
5057
5058 // Add declarations or definitions for each of the known methods.
John McCall276321a2010-08-25 06:19:51 +00005059 typedef CodeCompletionResult Result;
Douglas Gregor636a61e2010-04-07 00:21:17 +00005060 ResultBuilder Results(*this);
5061 Results.EnterNewScope();
5062 PrintingPolicy Policy(Context.PrintingPolicy);
5063 Policy.AnonymousTagLocations = false;
5064 for (KnownMethodsMap::iterator M = KnownMethods.begin(),
5065 MEnd = KnownMethods.end();
5066 M != MEnd; ++M) {
Douglas Gregor416b5752010-08-25 01:08:01 +00005067 ObjCMethodDecl *Method = M->second.first;
Douglas Gregor636a61e2010-04-07 00:21:17 +00005068 CodeCompletionString *Pattern = new CodeCompletionString;
5069
5070 // If the result type was not already provided, add it to the
5071 // pattern as (type).
5072 if (ReturnType.isNull()) {
5073 std::string TypeStr;
5074 Method->getResultType().getAsStringInternal(TypeStr, Policy);
5075 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
5076 Pattern->AddTextChunk(TypeStr);
5077 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
5078 }
5079
5080 Selector Sel = Method->getSelector();
5081
5082 // Add the first part of the selector to the pattern.
5083 Pattern->AddTypedTextChunk(Sel.getIdentifierInfoForSlot(0)->getName());
5084
5085 // Add parameters to the pattern.
5086 unsigned I = 0;
5087 for (ObjCMethodDecl::param_iterator P = Method->param_begin(),
5088 PEnd = Method->param_end();
5089 P != PEnd; (void)++P, ++I) {
5090 // Add the part of the selector name.
5091 if (I == 0)
5092 Pattern->AddChunk(CodeCompletionString::CK_Colon);
5093 else if (I < Sel.getNumArgs()) {
5094 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
Douglas Gregorb0ce9b72010-08-17 15:53:35 +00005095 Pattern->AddTextChunk(Sel.getIdentifierInfoForSlot(I)->getName());
Douglas Gregor636a61e2010-04-07 00:21:17 +00005096 Pattern->AddChunk(CodeCompletionString::CK_Colon);
5097 } else
5098 break;
5099
5100 // Add the parameter type.
5101 std::string TypeStr;
5102 (*P)->getOriginalType().getAsStringInternal(TypeStr, Policy);
5103 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
5104 Pattern->AddTextChunk(TypeStr);
5105 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
5106
5107 if (IdentifierInfo *Id = (*P)->getIdentifier())
Douglas Gregor400f5972010-08-31 05:13:43 +00005108 Pattern->AddTextChunk(Id->getName());
Douglas Gregor636a61e2010-04-07 00:21:17 +00005109 }
5110
5111 if (Method->isVariadic()) {
5112 if (Method->param_size() > 0)
5113 Pattern->AddChunk(CodeCompletionString::CK_Comma);
5114 Pattern->AddTextChunk("...");
Douglas Gregor400f5972010-08-31 05:13:43 +00005115 }
Douglas Gregor636a61e2010-04-07 00:21:17 +00005116
Douglas Gregord37c59d2010-05-28 00:57:46 +00005117 if (IsInImplementation && Results.includeCodePatterns()) {
Douglas Gregor636a61e2010-04-07 00:21:17 +00005118 // We will be defining the method here, so add a compound statement.
5119 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
5120 Pattern->AddChunk(CodeCompletionString::CK_LeftBrace);
5121 Pattern->AddChunk(CodeCompletionString::CK_VerticalSpace);
5122 if (!Method->getResultType()->isVoidType()) {
5123 // If the result type is not void, add a return clause.
5124 Pattern->AddTextChunk("return");
5125 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
5126 Pattern->AddPlaceholderChunk("expression");
5127 Pattern->AddChunk(CodeCompletionString::CK_SemiColon);
5128 } else
5129 Pattern->AddPlaceholderChunk("statements");
5130
5131 Pattern->AddChunk(CodeCompletionString::CK_VerticalSpace);
5132 Pattern->AddChunk(CodeCompletionString::CK_RightBrace);
5133 }
5134
Douglas Gregor416b5752010-08-25 01:08:01 +00005135 unsigned Priority = CCP_CodePattern;
5136 if (!M->second.second)
5137 Priority += CCD_InBaseClass;
5138
5139 Results.AddResult(Result(Pattern, Priority,
Douglas Gregor7116a8c2010-08-17 16:06:07 +00005140 Method->isInstanceMethod()
5141 ? CXCursor_ObjCInstanceMethodDecl
5142 : CXCursor_ObjCClassMethodDecl));
Douglas Gregor636a61e2010-04-07 00:21:17 +00005143 }
5144
5145 Results.ExitScope();
5146
Douglas Gregor00c37ef2010-08-11 21:23:17 +00005147 HandleCodeCompleteResults(this, CodeCompleter,
5148 CodeCompletionContext::CCC_Other,
5149 Results.data(),Results.size());
Douglas Gregor636a61e2010-04-07 00:21:17 +00005150}
Douglas Gregor95887f92010-07-08 23:20:03 +00005151
5152void Sema::CodeCompleteObjCMethodDeclSelector(Scope *S,
5153 bool IsInstanceMethod,
Douglas Gregor45879692010-07-08 23:37:41 +00005154 bool AtParameterName,
John McCallba7bf592010-08-24 05:47:05 +00005155 ParsedType ReturnTy,
Douglas Gregor95887f92010-07-08 23:20:03 +00005156 IdentifierInfo **SelIdents,
5157 unsigned NumSelIdents) {
Douglas Gregor95887f92010-07-08 23:20:03 +00005158 // If we have an external source, load the entire class method
Sebastian Redld44cd6a2010-08-18 23:57:06 +00005159 // pool from the AST file.
Douglas Gregor95887f92010-07-08 23:20:03 +00005160 if (ExternalSource) {
5161 for (uint32_t I = 0, N = ExternalSource->GetNumExternalSelectors();
5162 I != N; ++I) {
5163 Selector Sel = ExternalSource->GetExternalSelector(I);
Sebastian Redl75d8a322010-08-02 23:18:59 +00005164 if (Sel.isNull() || MethodPool.count(Sel))
Douglas Gregor95887f92010-07-08 23:20:03 +00005165 continue;
Sebastian Redl75d8a322010-08-02 23:18:59 +00005166
5167 ReadMethodPool(Sel);
Douglas Gregor95887f92010-07-08 23:20:03 +00005168 }
5169 }
5170
5171 // Build the set of methods we can see.
John McCall276321a2010-08-25 06:19:51 +00005172 typedef CodeCompletionResult Result;
Douglas Gregor95887f92010-07-08 23:20:03 +00005173 ResultBuilder Results(*this);
5174
5175 if (ReturnTy)
5176 Results.setPreferredType(GetTypeFromParser(ReturnTy).getNonReferenceType());
Sebastian Redl75d8a322010-08-02 23:18:59 +00005177
Douglas Gregor95887f92010-07-08 23:20:03 +00005178 Results.EnterNewScope();
Sebastian Redl75d8a322010-08-02 23:18:59 +00005179 for (GlobalMethodPool::iterator M = MethodPool.begin(),
5180 MEnd = MethodPool.end();
5181 M != MEnd; ++M) {
5182 for (ObjCMethodList *MethList = IsInstanceMethod ? &M->second.first :
5183 &M->second.second;
5184 MethList && MethList->Method;
Douglas Gregor95887f92010-07-08 23:20:03 +00005185 MethList = MethList->Next) {
5186 if (!isAcceptableObjCMethod(MethList->Method, MK_Any, SelIdents,
5187 NumSelIdents))
5188 continue;
5189
Douglas Gregor45879692010-07-08 23:37:41 +00005190 if (AtParameterName) {
5191 // Suggest parameter names we've seen before.
5192 if (NumSelIdents && NumSelIdents <= MethList->Method->param_size()) {
5193 ParmVarDecl *Param = MethList->Method->param_begin()[NumSelIdents-1];
5194 if (Param->getIdentifier()) {
5195 CodeCompletionString *Pattern = new CodeCompletionString;
5196 Pattern->AddTypedTextChunk(Param->getIdentifier()->getName());
5197 Results.AddResult(Pattern);
5198 }
5199 }
5200
5201 continue;
5202 }
5203
Douglas Gregor95887f92010-07-08 23:20:03 +00005204 Result R(MethList->Method, 0);
5205 R.StartParameter = NumSelIdents;
5206 R.AllParametersAreInformative = false;
5207 R.DeclaringEntity = true;
5208 Results.MaybeAddResult(R, CurContext);
5209 }
5210 }
5211
5212 Results.ExitScope();
Douglas Gregor00c37ef2010-08-11 21:23:17 +00005213 HandleCodeCompleteResults(this, CodeCompleter,
5214 CodeCompletionContext::CCC_Other,
5215 Results.data(),Results.size());
Douglas Gregor95887f92010-07-08 23:20:03 +00005216}
Douglas Gregorb14904c2010-08-13 22:48:40 +00005217
Douglas Gregorec00a262010-08-24 22:20:20 +00005218void Sema::CodeCompletePreprocessorDirective(bool InConditional) {
Douglas Gregor3a7ad252010-08-24 19:08:16 +00005219 ResultBuilder Results(*this);
5220 Results.EnterNewScope();
5221
5222 // #if <condition>
5223 CodeCompletionString *Pattern = new CodeCompletionString;
5224 Pattern->AddTypedTextChunk("if");
5225 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
5226 Pattern->AddPlaceholderChunk("condition");
5227 Results.AddResult(Pattern);
5228
5229 // #ifdef <macro>
5230 Pattern = new CodeCompletionString;
5231 Pattern->AddTypedTextChunk("ifdef");
5232 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
5233 Pattern->AddPlaceholderChunk("macro");
5234 Results.AddResult(Pattern);
5235
5236 // #ifndef <macro>
5237 Pattern = new CodeCompletionString;
5238 Pattern->AddTypedTextChunk("ifndef");
5239 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
5240 Pattern->AddPlaceholderChunk("macro");
5241 Results.AddResult(Pattern);
5242
5243 if (InConditional) {
5244 // #elif <condition>
5245 Pattern = new CodeCompletionString;
5246 Pattern->AddTypedTextChunk("elif");
5247 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
5248 Pattern->AddPlaceholderChunk("condition");
5249 Results.AddResult(Pattern);
5250
5251 // #else
5252 Pattern = new CodeCompletionString;
5253 Pattern->AddTypedTextChunk("else");
5254 Results.AddResult(Pattern);
5255
5256 // #endif
5257 Pattern = new CodeCompletionString;
5258 Pattern->AddTypedTextChunk("endif");
5259 Results.AddResult(Pattern);
5260 }
5261
5262 // #include "header"
5263 Pattern = new CodeCompletionString;
5264 Pattern->AddTypedTextChunk("include");
5265 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
5266 Pattern->AddTextChunk("\"");
5267 Pattern->AddPlaceholderChunk("header");
5268 Pattern->AddTextChunk("\"");
5269 Results.AddResult(Pattern);
5270
5271 // #include <header>
5272 Pattern = new CodeCompletionString;
5273 Pattern->AddTypedTextChunk("include");
5274 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
5275 Pattern->AddTextChunk("<");
5276 Pattern->AddPlaceholderChunk("header");
5277 Pattern->AddTextChunk(">");
5278 Results.AddResult(Pattern);
5279
5280 // #define <macro>
5281 Pattern = new CodeCompletionString;
5282 Pattern->AddTypedTextChunk("define");
5283 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
5284 Pattern->AddPlaceholderChunk("macro");
5285 Results.AddResult(Pattern);
5286
5287 // #define <macro>(<args>)
5288 Pattern = new CodeCompletionString;
5289 Pattern->AddTypedTextChunk("define");
5290 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
5291 Pattern->AddPlaceholderChunk("macro");
5292 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
5293 Pattern->AddPlaceholderChunk("args");
5294 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
5295 Results.AddResult(Pattern);
5296
5297 // #undef <macro>
5298 Pattern = new CodeCompletionString;
5299 Pattern->AddTypedTextChunk("undef");
5300 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
5301 Pattern->AddPlaceholderChunk("macro");
5302 Results.AddResult(Pattern);
5303
5304 // #line <number>
5305 Pattern = new CodeCompletionString;
5306 Pattern->AddTypedTextChunk("line");
5307 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
5308 Pattern->AddPlaceholderChunk("number");
5309 Results.AddResult(Pattern);
5310
5311 // #line <number> "filename"
5312 Pattern = new CodeCompletionString;
5313 Pattern->AddTypedTextChunk("line");
5314 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
5315 Pattern->AddPlaceholderChunk("number");
5316 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
5317 Pattern->AddTextChunk("\"");
5318 Pattern->AddPlaceholderChunk("filename");
5319 Pattern->AddTextChunk("\"");
5320 Results.AddResult(Pattern);
5321
5322 // #error <message>
5323 Pattern = new CodeCompletionString;
5324 Pattern->AddTypedTextChunk("error");
5325 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
5326 Pattern->AddPlaceholderChunk("message");
5327 Results.AddResult(Pattern);
5328
5329 // #pragma <arguments>
5330 Pattern = new CodeCompletionString;
5331 Pattern->AddTypedTextChunk("pragma");
5332 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
5333 Pattern->AddPlaceholderChunk("arguments");
5334 Results.AddResult(Pattern);
5335
5336 if (getLangOptions().ObjC1) {
5337 // #import "header"
5338 Pattern = new CodeCompletionString;
5339 Pattern->AddTypedTextChunk("import");
5340 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
5341 Pattern->AddTextChunk("\"");
5342 Pattern->AddPlaceholderChunk("header");
5343 Pattern->AddTextChunk("\"");
5344 Results.AddResult(Pattern);
5345
5346 // #import <header>
5347 Pattern = new CodeCompletionString;
5348 Pattern->AddTypedTextChunk("import");
5349 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
5350 Pattern->AddTextChunk("<");
5351 Pattern->AddPlaceholderChunk("header");
5352 Pattern->AddTextChunk(">");
5353 Results.AddResult(Pattern);
5354 }
5355
5356 // #include_next "header"
5357 Pattern = new CodeCompletionString;
5358 Pattern->AddTypedTextChunk("include_next");
5359 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
5360 Pattern->AddTextChunk("\"");
5361 Pattern->AddPlaceholderChunk("header");
5362 Pattern->AddTextChunk("\"");
5363 Results.AddResult(Pattern);
5364
5365 // #include_next <header>
5366 Pattern = new CodeCompletionString;
5367 Pattern->AddTypedTextChunk("include_next");
5368 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
5369 Pattern->AddTextChunk("<");
5370 Pattern->AddPlaceholderChunk("header");
5371 Pattern->AddTextChunk(">");
5372 Results.AddResult(Pattern);
5373
5374 // #warning <message>
5375 Pattern = new CodeCompletionString;
5376 Pattern->AddTypedTextChunk("warning");
5377 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
5378 Pattern->AddPlaceholderChunk("message");
5379 Results.AddResult(Pattern);
5380
5381 // Note: #ident and #sccs are such crazy anachronisms that we don't provide
5382 // completions for them. And __include_macros is a Clang-internal extension
5383 // that we don't want to encourage anyone to use.
5384
5385 // FIXME: we don't support #assert or #unassert, so don't suggest them.
5386 Results.ExitScope();
5387
Douglas Gregor3a7ad252010-08-24 19:08:16 +00005388 HandleCodeCompleteResults(this, CodeCompleter,
Douglas Gregor0de55ce2010-08-25 18:41:16 +00005389 CodeCompletionContext::CCC_PreprocessorDirective,
Douglas Gregor3a7ad252010-08-24 19:08:16 +00005390 Results.data(), Results.size());
5391}
5392
5393void Sema::CodeCompleteInPreprocessorConditionalExclusion(Scope *S) {
Douglas Gregorec00a262010-08-24 22:20:20 +00005394 CodeCompleteOrdinaryName(S,
John McCallfaf5fb42010-08-26 23:41:50 +00005395 S->getFnParent()? Sema::PCC_RecoveryInFunction
5396 : Sema::PCC_Namespace);
Douglas Gregor3a7ad252010-08-24 19:08:16 +00005397}
5398
Douglas Gregorec00a262010-08-24 22:20:20 +00005399void Sema::CodeCompletePreprocessorMacroName(bool IsDefinition) {
Douglas Gregor12785102010-08-24 20:21:13 +00005400 ResultBuilder Results(*this);
5401 if (!IsDefinition && (!CodeCompleter || CodeCompleter->includeMacros())) {
5402 // Add just the names of macros, not their arguments.
5403 Results.EnterNewScope();
5404 for (Preprocessor::macro_iterator M = PP.macro_begin(),
5405 MEnd = PP.macro_end();
5406 M != MEnd; ++M) {
5407 CodeCompletionString *Pattern = new CodeCompletionString;
5408 Pattern->AddTypedTextChunk(M->first->getName());
5409 Results.AddResult(Pattern);
5410 }
5411 Results.ExitScope();
5412 } else if (IsDefinition) {
5413 // FIXME: Can we detect when the user just wrote an include guard above?
5414 }
5415
5416 HandleCodeCompleteResults(this, CodeCompleter,
5417 IsDefinition? CodeCompletionContext::CCC_MacroName
5418 : CodeCompletionContext::CCC_MacroNameUse,
5419 Results.data(), Results.size());
5420}
5421
Douglas Gregorec00a262010-08-24 22:20:20 +00005422void Sema::CodeCompletePreprocessorExpression() {
5423 ResultBuilder Results(*this);
5424
5425 if (!CodeCompleter || CodeCompleter->includeMacros())
5426 AddMacroResults(PP, Results);
5427
5428 // defined (<macro>)
5429 Results.EnterNewScope();
5430 CodeCompletionString *Pattern = new CodeCompletionString;
5431 Pattern->AddTypedTextChunk("defined");
5432 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
5433 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
5434 Pattern->AddPlaceholderChunk("macro");
5435 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
5436 Results.AddResult(Pattern);
5437 Results.ExitScope();
5438
5439 HandleCodeCompleteResults(this, CodeCompleter,
5440 CodeCompletionContext::CCC_PreprocessorExpression,
5441 Results.data(), Results.size());
5442}
5443
5444void Sema::CodeCompletePreprocessorMacroArgument(Scope *S,
5445 IdentifierInfo *Macro,
5446 MacroInfo *MacroInfo,
5447 unsigned Argument) {
5448 // FIXME: In the future, we could provide "overload" results, much like we
5449 // do for function calls.
5450
5451 CodeCompleteOrdinaryName(S,
John McCallfaf5fb42010-08-26 23:41:50 +00005452 S->getFnParent()? Sema::PCC_RecoveryInFunction
5453 : Sema::PCC_Namespace);
Douglas Gregorec00a262010-08-24 22:20:20 +00005454}
5455
Douglas Gregor11583702010-08-25 17:04:25 +00005456void Sema::CodeCompleteNaturalLanguage() {
Douglas Gregor11583702010-08-25 17:04:25 +00005457 HandleCodeCompleteResults(this, CodeCompleter,
Douglas Gregorea736372010-08-25 17:10:00 +00005458 CodeCompletionContext::CCC_NaturalLanguage,
Douglas Gregor11583702010-08-25 17:04:25 +00005459 0, 0);
5460}
5461
Douglas Gregorb14904c2010-08-13 22:48:40 +00005462void Sema::GatherGlobalCodeCompletions(
John McCall276321a2010-08-25 06:19:51 +00005463 llvm::SmallVectorImpl<CodeCompletionResult> &Results) {
Douglas Gregorb14904c2010-08-13 22:48:40 +00005464 ResultBuilder Builder(*this);
5465
Douglas Gregor39982192010-08-15 06:18:01 +00005466 if (!CodeCompleter || CodeCompleter->includeGlobals()) {
5467 CodeCompletionDeclConsumer Consumer(Builder,
5468 Context.getTranslationUnitDecl());
5469 LookupVisibleDecls(Context.getTranslationUnitDecl(), LookupAnyName,
5470 Consumer);
5471 }
Douglas Gregorb14904c2010-08-13 22:48:40 +00005472
5473 if (!CodeCompleter || CodeCompleter->includeMacros())
5474 AddMacroResults(PP, Builder);
5475
5476 Results.clear();
5477 Results.insert(Results.end(),
5478 Builder.data(), Builder.data() + Builder.size());
5479}