blob: 8e1e6914c669479ff333e318e9928872fbf1cd02 [file] [log] [blame]
Douglas Gregor81b747b2009-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 McCall2d887082010-08-25 22:03:47 +000013#include "clang/Sema/SemaInternal.h"
Douglas Gregore737f502010-08-12 20:07:10 +000014#include "clang/Sema/Lookup.h"
John McCall120d63c2010-08-24 20:38:10 +000015#include "clang/Sema/Overload.h"
Douglas Gregor81b747b2009-09-17 21:32:03 +000016#include "clang/Sema/CodeCompleteConsumer.h"
Douglas Gregor719770d2010-04-06 17:30:22 +000017#include "clang/Sema/ExternalSemaSource.h"
John McCall5f1e0942010-08-24 08:50:51 +000018#include "clang/Sema/Scope.h"
John McCall781472f2010-08-25 08:40:02 +000019#include "clang/Sema/ScopeInfo.h"
John McCall7cd088e2010-08-24 07:21:54 +000020#include "clang/AST/DeclObjC.h"
Douglas Gregorb9d0ef72009-09-21 19:57:38 +000021#include "clang/AST/ExprCXX.h"
Douglas Gregor24a069f2009-11-17 17:59:40 +000022#include "clang/AST/ExprObjC.h"
Douglas Gregor3f7c7f42009-10-30 16:50:04 +000023#include "clang/Lex/MacroInfo.h"
24#include "clang/Lex/Preprocessor.h"
Douglas Gregor86d9a522009-09-21 16:56:56 +000025#include "llvm/ADT/SmallPtrSet.h"
Douglas Gregor6a684032009-09-28 03:51:44 +000026#include "llvm/ADT/StringExtras.h"
Douglas Gregor22f56992010-04-06 19:22:33 +000027#include "llvm/ADT/StringSwitch.h"
Douglas Gregor458433d2010-08-26 15:07:07 +000028#include "llvm/ADT/Twine.h"
Douglas Gregor86d9a522009-09-21 16:56:56 +000029#include <list>
30#include <map>
31#include <vector>
Douglas Gregor81b747b2009-09-17 21:32:03 +000032
33using namespace clang;
John McCall781472f2010-08-25 08:40:02 +000034using namespace sema;
Douglas Gregor81b747b2009-09-17 21:32:03 +000035
Douglas Gregor86d9a522009-09-21 16:56:56 +000036namespace {
37 /// \brief A container of code-completion results.
38 class ResultBuilder {
39 public:
40 /// \brief The type of a name-lookup filter, which can be provided to the
41 /// name-lookup routines to specify which declarations should be included in
42 /// the result set (when it returns true) and which declarations should be
43 /// filtered out (returns false).
44 typedef bool (ResultBuilder::*LookupFilter)(NamedDecl *) const;
45
John McCall0a2c5e22010-08-25 06:19:51 +000046 typedef CodeCompletionResult Result;
Douglas Gregor86d9a522009-09-21 16:56:56 +000047
48 private:
49 /// \brief The actual results we have found.
50 std::vector<Result> Results;
51
52 /// \brief A record of all of the declarations we have found and placed
53 /// into the result set, used to ensure that no declaration ever gets into
54 /// the result set twice.
55 llvm::SmallPtrSet<Decl*, 16> AllDeclsFound;
56
Douglas Gregorfbcb5d62009-12-06 20:23:50 +000057 typedef std::pair<NamedDecl *, unsigned> DeclIndexPair;
58
59 /// \brief An entry in the shadow map, which is optimized to store
60 /// a single (declaration, index) mapping (the common case) but
61 /// can also store a list of (declaration, index) mappings.
62 class ShadowMapEntry {
63 typedef llvm::SmallVector<DeclIndexPair, 4> DeclIndexPairVector;
64
65 /// \brief Contains either the solitary NamedDecl * or a vector
66 /// of (declaration, index) pairs.
67 llvm::PointerUnion<NamedDecl *, DeclIndexPairVector*> DeclOrVector;
68
69 /// \brief When the entry contains a single declaration, this is
70 /// the index associated with that entry.
71 unsigned SingleDeclIndex;
72
73 public:
74 ShadowMapEntry() : DeclOrVector(), SingleDeclIndex(0) { }
75
76 void Add(NamedDecl *ND, unsigned Index) {
77 if (DeclOrVector.isNull()) {
78 // 0 - > 1 elements: just set the single element information.
79 DeclOrVector = ND;
80 SingleDeclIndex = Index;
81 return;
82 }
83
84 if (NamedDecl *PrevND = DeclOrVector.dyn_cast<NamedDecl *>()) {
85 // 1 -> 2 elements: create the vector of results and push in the
86 // existing declaration.
87 DeclIndexPairVector *Vec = new DeclIndexPairVector;
88 Vec->push_back(DeclIndexPair(PrevND, SingleDeclIndex));
89 DeclOrVector = Vec;
90 }
91
92 // Add the new element to the end of the vector.
93 DeclOrVector.get<DeclIndexPairVector*>()->push_back(
94 DeclIndexPair(ND, Index));
95 }
96
97 void Destroy() {
98 if (DeclIndexPairVector *Vec
99 = DeclOrVector.dyn_cast<DeclIndexPairVector *>()) {
100 delete Vec;
101 DeclOrVector = ((NamedDecl *)0);
102 }
103 }
104
105 // Iteration.
106 class iterator;
107 iterator begin() const;
108 iterator end() const;
109 };
110
Douglas Gregor86d9a522009-09-21 16:56:56 +0000111 /// \brief A mapping from declaration names to the declarations that have
112 /// this name within a particular scope and their index within the list of
113 /// results.
Douglas Gregorfbcb5d62009-12-06 20:23:50 +0000114 typedef llvm::DenseMap<DeclarationName, ShadowMapEntry> ShadowMap;
Douglas Gregor86d9a522009-09-21 16:56:56 +0000115
116 /// \brief The semantic analysis object for which results are being
117 /// produced.
118 Sema &SemaRef;
119
120 /// \brief If non-NULL, a filter function used to remove any code-completion
121 /// results that are not desirable.
122 LookupFilter Filter;
Douglas Gregor45bcd432010-01-14 03:21:49 +0000123
124 /// \brief Whether we should allow declarations as
125 /// nested-name-specifiers that would otherwise be filtered out.
126 bool AllowNestedNameSpecifiers;
127
Douglas Gregor5ac3bdb2010-05-30 01:49:25 +0000128 /// \brief If set, the type that we would prefer our resulting value
129 /// declarations to have.
130 ///
131 /// Closely matching the preferred type gives a boost to a result's
132 /// priority.
133 CanQualType PreferredType;
134
Douglas Gregor86d9a522009-09-21 16:56:56 +0000135 /// \brief A list of shadow maps, which is used to model name hiding at
136 /// different levels of, e.g., the inheritance hierarchy.
137 std::list<ShadowMap> ShadowMaps;
138
Douglas Gregor3cdee122010-08-26 16:36:48 +0000139 /// \brief If we're potentially referring to a C++ member function, the set
140 /// of qualifiers applied to the object type.
141 Qualifiers ObjectTypeQualifiers;
142
143 /// \brief Whether the \p ObjectTypeQualifiers field is active.
144 bool HasObjectTypeQualifiers;
145
Douglas Gregor1f5537a2010-07-08 23:20:03 +0000146 void AdjustResultPriorityForPreferredType(Result &R);
147
Douglas Gregor86d9a522009-09-21 16:56:56 +0000148 public:
149 explicit ResultBuilder(Sema &SemaRef, LookupFilter Filter = 0)
Douglas Gregor3cdee122010-08-26 16:36:48 +0000150 : SemaRef(SemaRef), Filter(Filter), AllowNestedNameSpecifiers(false),
151 HasObjectTypeQualifiers(false) { }
Douglas Gregor86d9a522009-09-21 16:56:56 +0000152
Douglas Gregord8e8a582010-05-25 21:41:55 +0000153 /// \brief Whether we should include code patterns in the completion
154 /// results.
155 bool includeCodePatterns() const {
156 return SemaRef.CodeCompleter &&
157 SemaRef.CodeCompleter->includeCodePatterns();
158 }
159
Douglas Gregor86d9a522009-09-21 16:56:56 +0000160 /// \brief Set the filter used for code-completion results.
161 void setFilter(LookupFilter Filter) {
162 this->Filter = Filter;
163 }
164
165 typedef std::vector<Result>::iterator iterator;
166 iterator begin() { return Results.begin(); }
167 iterator end() { return Results.end(); }
168
169 Result *data() { return Results.empty()? 0 : &Results.front(); }
170 unsigned size() const { return Results.size(); }
171 bool empty() const { return Results.empty(); }
172
Douglas Gregor5ac3bdb2010-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 Gregor3cdee122010-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 Gregor45bcd432010-01-14 03:21:49 +0000190 /// \brief Specify whether nested-name-specifiers are allowed.
191 void allowNestedNameSpecifiers(bool Allow = true) {
192 AllowNestedNameSpecifiers = Allow;
193 }
194
Douglas Gregore495b7f2010-01-14 00:20:49 +0000195 /// \brief Determine whether the given declaration is at all interesting
196 /// as a code-completion result.
Douglas Gregor45bcd432010-01-14 03:21:49 +0000197 ///
198 /// \param ND the declaration that we are inspecting.
199 ///
200 /// \param AsNestedNameSpecifier will be set true if this declaration is
201 /// only interesting when it is a nested-name-specifier.
202 bool isInterestingDecl(NamedDecl *ND, bool &AsNestedNameSpecifier) const;
Douglas Gregor6660d842010-01-14 00:41:07 +0000203
204 /// \brief Check whether the result is hidden by the Hiding declaration.
205 ///
206 /// \returns true if the result is hidden and cannot be found, false if
207 /// the hidden result could still be found. When false, \p R may be
208 /// modified to describe how the result can be found (e.g., via extra
209 /// qualification).
210 bool CheckHiddenResult(Result &R, DeclContext *CurContext,
211 NamedDecl *Hiding);
212
Douglas Gregor86d9a522009-09-21 16:56:56 +0000213 /// \brief Add a new result to this result set (if it isn't already in one
214 /// of the shadow maps), or replace an existing result (for, e.g., a
215 /// redeclaration).
Douglas Gregor456c4a12009-09-21 20:12:40 +0000216 ///
Douglas Gregor1ca6ae82010-01-14 01:09:38 +0000217 /// \param CurContext the result to add (if it is unique).
Douglas Gregor456c4a12009-09-21 20:12:40 +0000218 ///
219 /// \param R the context in which this result will be named.
220 void MaybeAddResult(Result R, DeclContext *CurContext = 0);
Douglas Gregor86d9a522009-09-21 16:56:56 +0000221
Douglas Gregor1ca6ae82010-01-14 01:09:38 +0000222 /// \brief Add a new result to this result set, where we already know
223 /// the hiding declation (if any).
224 ///
225 /// \param R the result to add (if it is unique).
226 ///
227 /// \param CurContext the context in which this result will be named.
228 ///
229 /// \param Hiding the declaration that hides the result.
Douglas Gregor0cc84042010-01-14 15:47:35 +0000230 ///
231 /// \param InBaseClass whether the result was found in a base
232 /// class of the searched context.
233 void AddResult(Result R, DeclContext *CurContext, NamedDecl *Hiding,
234 bool InBaseClass);
Douglas Gregor1ca6ae82010-01-14 01:09:38 +0000235
Douglas Gregora4477812010-01-14 16:01:26 +0000236 /// \brief Add a new non-declaration result to this result set.
237 void AddResult(Result R);
238
Douglas Gregor86d9a522009-09-21 16:56:56 +0000239 /// \brief Enter into a new scope.
240 void EnterNewScope();
241
242 /// \brief Exit from the current scope.
243 void ExitScope();
244
Douglas Gregor55385fe2009-11-18 04:19:12 +0000245 /// \brief Ignore this declaration, if it is seen again.
246 void Ignore(Decl *D) { AllDeclsFound.insert(D->getCanonicalDecl()); }
247
Douglas Gregor86d9a522009-09-21 16:56:56 +0000248 /// \name Name lookup predicates
249 ///
250 /// These predicates can be passed to the name lookup functions to filter the
251 /// results of name lookup. All of the predicates have the same type, so that
252 ///
253 //@{
Douglas Gregor791215b2009-09-21 20:51:25 +0000254 bool IsOrdinaryName(NamedDecl *ND) const;
Douglas Gregor4710e5b2010-05-28 00:49:12 +0000255 bool IsOrdinaryNonTypeName(NamedDecl *ND) const;
Douglas Gregorf9578432010-07-28 21:50:18 +0000256 bool IsIntegralConstantValue(NamedDecl *ND) const;
Douglas Gregor01dfea02010-01-10 23:08:15 +0000257 bool IsOrdinaryNonValueName(NamedDecl *ND) const;
Douglas Gregor86d9a522009-09-21 16:56:56 +0000258 bool IsNestedNameSpecifier(NamedDecl *ND) const;
259 bool IsEnum(NamedDecl *ND) const;
260 bool IsClassOrStruct(NamedDecl *ND) const;
261 bool IsUnion(NamedDecl *ND) const;
262 bool IsNamespace(NamedDecl *ND) const;
263 bool IsNamespaceOrAlias(NamedDecl *ND) const;
264 bool IsType(NamedDecl *ND) const;
Douglas Gregoreb5758b2009-09-23 22:26:46 +0000265 bool IsMember(NamedDecl *ND) const;
Douglas Gregor80f4f4c2010-01-14 16:08:12 +0000266 bool IsObjCIvar(NamedDecl *ND) const;
Douglas Gregor8e254cf2010-05-27 23:06:34 +0000267 bool IsObjCMessageReceiver(NamedDecl *ND) const;
Douglas Gregorfb629412010-08-23 21:17:50 +0000268 bool IsObjCCollection(NamedDecl *ND) const;
Douglas Gregor86d9a522009-09-21 16:56:56 +0000269 //@}
270 };
271}
272
Douglas Gregorfbcb5d62009-12-06 20:23:50 +0000273class ResultBuilder::ShadowMapEntry::iterator {
274 llvm::PointerUnion<NamedDecl*, const DeclIndexPair*> DeclOrIterator;
275 unsigned SingleDeclIndex;
276
277public:
278 typedef DeclIndexPair value_type;
279 typedef value_type reference;
280 typedef std::ptrdiff_t difference_type;
281 typedef std::input_iterator_tag iterator_category;
282
283 class pointer {
284 DeclIndexPair Value;
285
286 public:
287 pointer(const DeclIndexPair &Value) : Value(Value) { }
288
289 const DeclIndexPair *operator->() const {
290 return &Value;
291 }
292 };
293
294 iterator() : DeclOrIterator((NamedDecl *)0), SingleDeclIndex(0) { }
295
296 iterator(NamedDecl *SingleDecl, unsigned Index)
297 : DeclOrIterator(SingleDecl), SingleDeclIndex(Index) { }
298
299 iterator(const DeclIndexPair *Iterator)
300 : DeclOrIterator(Iterator), SingleDeclIndex(0) { }
301
302 iterator &operator++() {
303 if (DeclOrIterator.is<NamedDecl *>()) {
304 DeclOrIterator = (NamedDecl *)0;
305 SingleDeclIndex = 0;
306 return *this;
307 }
308
309 const DeclIndexPair *I = DeclOrIterator.get<const DeclIndexPair*>();
310 ++I;
311 DeclOrIterator = I;
312 return *this;
313 }
314
315 iterator operator++(int) {
316 iterator tmp(*this);
317 ++(*this);
318 return tmp;
319 }
320
321 reference operator*() const {
322 if (NamedDecl *ND = DeclOrIterator.dyn_cast<NamedDecl *>())
323 return reference(ND, SingleDeclIndex);
324
Douglas Gregord490f952009-12-06 21:27:58 +0000325 return *DeclOrIterator.get<const DeclIndexPair*>();
Douglas Gregorfbcb5d62009-12-06 20:23:50 +0000326 }
327
328 pointer operator->() const {
329 return pointer(**this);
330 }
331
332 friend bool operator==(const iterator &X, const iterator &Y) {
Douglas Gregord490f952009-12-06 21:27:58 +0000333 return X.DeclOrIterator.getOpaqueValue()
334 == Y.DeclOrIterator.getOpaqueValue() &&
Douglas Gregorfbcb5d62009-12-06 20:23:50 +0000335 X.SingleDeclIndex == Y.SingleDeclIndex;
336 }
337
338 friend bool operator!=(const iterator &X, const iterator &Y) {
Douglas Gregord490f952009-12-06 21:27:58 +0000339 return !(X == Y);
Douglas Gregorfbcb5d62009-12-06 20:23:50 +0000340 }
341};
342
Douglas Gregorfbcb5d62009-12-06 20:23:50 +0000343ResultBuilder::ShadowMapEntry::iterator
344ResultBuilder::ShadowMapEntry::begin() const {
345 if (DeclOrVector.isNull())
346 return iterator();
347
348 if (NamedDecl *ND = DeclOrVector.dyn_cast<NamedDecl *>())
349 return iterator(ND, SingleDeclIndex);
350
351 return iterator(DeclOrVector.get<DeclIndexPairVector *>()->begin());
352}
353
354ResultBuilder::ShadowMapEntry::iterator
355ResultBuilder::ShadowMapEntry::end() const {
356 if (DeclOrVector.is<NamedDecl *>() || DeclOrVector.isNull())
357 return iterator();
358
359 return iterator(DeclOrVector.get<DeclIndexPairVector *>()->end());
360}
361
Douglas Gregor456c4a12009-09-21 20:12:40 +0000362/// \brief Compute the qualification required to get from the current context
363/// (\p CurContext) to the target context (\p TargetContext).
364///
365/// \param Context the AST context in which the qualification will be used.
366///
367/// \param CurContext the context where an entity is being named, which is
368/// typically based on the current scope.
369///
370/// \param TargetContext the context in which the named entity actually
371/// resides.
372///
373/// \returns a nested name specifier that refers into the target context, or
374/// NULL if no qualification is needed.
375static NestedNameSpecifier *
376getRequiredQualification(ASTContext &Context,
377 DeclContext *CurContext,
378 DeclContext *TargetContext) {
379 llvm::SmallVector<DeclContext *, 4> TargetParents;
380
381 for (DeclContext *CommonAncestor = TargetContext;
382 CommonAncestor && !CommonAncestor->Encloses(CurContext);
383 CommonAncestor = CommonAncestor->getLookupParent()) {
384 if (CommonAncestor->isTransparentContext() ||
385 CommonAncestor->isFunctionOrMethod())
386 continue;
387
388 TargetParents.push_back(CommonAncestor);
389 }
390
391 NestedNameSpecifier *Result = 0;
392 while (!TargetParents.empty()) {
393 DeclContext *Parent = TargetParents.back();
394 TargetParents.pop_back();
395
Douglas Gregorfb629412010-08-23 21:17:50 +0000396 if (NamespaceDecl *Namespace = dyn_cast<NamespaceDecl>(Parent)) {
397 if (!Namespace->getIdentifier())
398 continue;
399
Douglas Gregor456c4a12009-09-21 20:12:40 +0000400 Result = NestedNameSpecifier::Create(Context, Result, Namespace);
Douglas Gregorfb629412010-08-23 21:17:50 +0000401 }
Douglas Gregor456c4a12009-09-21 20:12:40 +0000402 else if (TagDecl *TD = dyn_cast<TagDecl>(Parent))
403 Result = NestedNameSpecifier::Create(Context, Result,
404 false,
405 Context.getTypeDeclType(TD).getTypePtr());
Douglas Gregor0c8296d2009-11-07 00:00:49 +0000406 }
Douglas Gregor456c4a12009-09-21 20:12:40 +0000407 return Result;
408}
409
Douglas Gregor45bcd432010-01-14 03:21:49 +0000410bool ResultBuilder::isInterestingDecl(NamedDecl *ND,
411 bool &AsNestedNameSpecifier) const {
412 AsNestedNameSpecifier = false;
413
Douglas Gregore495b7f2010-01-14 00:20:49 +0000414 ND = ND->getUnderlyingDecl();
415 unsigned IDNS = ND->getIdentifierNamespace();
Douglas Gregorf52cede2009-10-09 22:16:47 +0000416
417 // Skip unnamed entities.
Douglas Gregore495b7f2010-01-14 00:20:49 +0000418 if (!ND->getDeclName())
419 return false;
Douglas Gregor86d9a522009-09-21 16:56:56 +0000420
421 // Friend declarations and declarations introduced due to friends are never
422 // added as results.
John McCall92b7f702010-03-11 07:50:04 +0000423 if (IDNS & (Decl::IDNS_OrdinaryFriend | Decl::IDNS_TagFriend))
Douglas Gregore495b7f2010-01-14 00:20:49 +0000424 return false;
425
Douglas Gregor76282942009-12-11 17:31:05 +0000426 // Class template (partial) specializations are never added as results.
Douglas Gregore495b7f2010-01-14 00:20:49 +0000427 if (isa<ClassTemplateSpecializationDecl>(ND) ||
428 isa<ClassTemplatePartialSpecializationDecl>(ND))
429 return false;
Douglas Gregor86d9a522009-09-21 16:56:56 +0000430
Douglas Gregor76282942009-12-11 17:31:05 +0000431 // Using declarations themselves are never added as results.
Douglas Gregore495b7f2010-01-14 00:20:49 +0000432 if (isa<UsingDecl>(ND))
433 return false;
434
435 // Some declarations have reserved names that we don't want to ever show.
436 if (const IdentifierInfo *Id = ND->getIdentifier()) {
Douglas Gregor86d9a522009-09-21 16:56:56 +0000437 // __va_list_tag is a freak of nature. Find it and skip it.
438 if (Id->isStr("__va_list_tag") || Id->isStr("__builtin_va_list"))
Douglas Gregore495b7f2010-01-14 00:20:49 +0000439 return false;
Douglas Gregor86d9a522009-09-21 16:56:56 +0000440
Douglas Gregorf52cede2009-10-09 22:16:47 +0000441 // Filter out names reserved for the implementation (C99 7.1.3,
Douglas Gregor797efb52010-07-14 17:44:04 +0000442 // C++ [lib.global.names]) if they come from a system header.
Daniel Dunbare013d682009-10-18 20:26:12 +0000443 //
444 // FIXME: Add predicate for this.
Douglas Gregorf52cede2009-10-09 22:16:47 +0000445 if (Id->getLength() >= 2) {
Daniel Dunbare013d682009-10-18 20:26:12 +0000446 const char *Name = Id->getNameStart();
Douglas Gregorf52cede2009-10-09 22:16:47 +0000447 if (Name[0] == '_' &&
Douglas Gregor797efb52010-07-14 17:44:04 +0000448 (Name[1] == '_' || (Name[1] >= 'A' && Name[1] <= 'Z')) &&
449 (ND->getLocation().isInvalid() ||
450 SemaRef.SourceMgr.isInSystemHeader(
451 SemaRef.SourceMgr.getSpellingLoc(ND->getLocation()))))
Douglas Gregore495b7f2010-01-14 00:20:49 +0000452 return false;
Douglas Gregorf52cede2009-10-09 22:16:47 +0000453 }
Douglas Gregor86d9a522009-09-21 16:56:56 +0000454 }
Douglas Gregore495b7f2010-01-14 00:20:49 +0000455
Douglas Gregor86d9a522009-09-21 16:56:56 +0000456 // C++ constructors are never found by name lookup.
Douglas Gregore495b7f2010-01-14 00:20:49 +0000457 if (isa<CXXConstructorDecl>(ND))
458 return false;
Douglas Gregor86d9a522009-09-21 16:56:56 +0000459
Douglas Gregora5fb7c32010-08-16 23:05:20 +0000460 if (Filter == &ResultBuilder::IsNestedNameSpecifier ||
461 ((isa<NamespaceDecl>(ND) || isa<NamespaceAliasDecl>(ND)) &&
462 Filter != &ResultBuilder::IsNamespace &&
463 Filter != &ResultBuilder::IsNamespaceOrAlias))
464 AsNestedNameSpecifier = true;
465
Douglas Gregor86d9a522009-09-21 16:56:56 +0000466 // Filter out any unwanted results.
Douglas Gregor45bcd432010-01-14 03:21:49 +0000467 if (Filter && !(this->*Filter)(ND)) {
468 // Check whether it is interesting as a nested-name-specifier.
469 if (AllowNestedNameSpecifiers && SemaRef.getLangOptions().CPlusPlus &&
470 IsNestedNameSpecifier(ND) &&
471 (Filter != &ResultBuilder::IsMember ||
472 (isa<CXXRecordDecl>(ND) &&
473 cast<CXXRecordDecl>(ND)->isInjectedClassName()))) {
474 AsNestedNameSpecifier = true;
475 return true;
476 }
477
Douglas Gregore495b7f2010-01-14 00:20:49 +0000478 return false;
Douglas Gregora5fb7c32010-08-16 23:05:20 +0000479 }
Douglas Gregore495b7f2010-01-14 00:20:49 +0000480 // ... then it must be interesting!
481 return true;
482}
483
Douglas Gregor6660d842010-01-14 00:41:07 +0000484bool ResultBuilder::CheckHiddenResult(Result &R, DeclContext *CurContext,
485 NamedDecl *Hiding) {
486 // In C, there is no way to refer to a hidden name.
487 // FIXME: This isn't true; we can find a tag name hidden by an ordinary
488 // name if we introduce the tag type.
489 if (!SemaRef.getLangOptions().CPlusPlus)
490 return true;
491
492 DeclContext *HiddenCtx = R.Declaration->getDeclContext()->getLookupContext();
493
494 // There is no way to qualify a name declared in a function or method.
495 if (HiddenCtx->isFunctionOrMethod())
496 return true;
497
498 if (HiddenCtx == Hiding->getDeclContext()->getLookupContext())
499 return true;
500
501 // We can refer to the result with the appropriate qualification. Do it.
502 R.Hidden = true;
503 R.QualifierIsInformative = false;
504
505 if (!R.Qualifier)
506 R.Qualifier = getRequiredQualification(SemaRef.Context,
507 CurContext,
508 R.Declaration->getDeclContext());
509 return false;
510}
511
Douglas Gregor1f5537a2010-07-08 23:20:03 +0000512/// \brief A simplified classification of types used to determine whether two
513/// types are "similar enough" when adjusting priorities.
Douglas Gregor1827e102010-08-16 16:18:59 +0000514SimplifiedTypeClass clang::getSimplifiedTypeClass(CanQualType T) {
Douglas Gregor1f5537a2010-07-08 23:20:03 +0000515 switch (T->getTypeClass()) {
516 case Type::Builtin:
517 switch (cast<BuiltinType>(T)->getKind()) {
518 case BuiltinType::Void:
519 return STC_Void;
520
521 case BuiltinType::NullPtr:
522 return STC_Pointer;
523
524 case BuiltinType::Overload:
525 case BuiltinType::Dependent:
526 case BuiltinType::UndeducedAuto:
527 return STC_Other;
528
529 case BuiltinType::ObjCId:
530 case BuiltinType::ObjCClass:
531 case BuiltinType::ObjCSel:
532 return STC_ObjectiveC;
533
534 default:
535 return STC_Arithmetic;
536 }
537 return STC_Other;
538
539 case Type::Complex:
540 return STC_Arithmetic;
541
542 case Type::Pointer:
543 return STC_Pointer;
544
545 case Type::BlockPointer:
546 return STC_Block;
547
548 case Type::LValueReference:
549 case Type::RValueReference:
550 return getSimplifiedTypeClass(T->getAs<ReferenceType>()->getPointeeType());
551
552 case Type::ConstantArray:
553 case Type::IncompleteArray:
554 case Type::VariableArray:
555 case Type::DependentSizedArray:
556 return STC_Array;
557
558 case Type::DependentSizedExtVector:
559 case Type::Vector:
560 case Type::ExtVector:
561 return STC_Arithmetic;
562
563 case Type::FunctionProto:
564 case Type::FunctionNoProto:
565 return STC_Function;
566
567 case Type::Record:
568 return STC_Record;
569
570 case Type::Enum:
571 return STC_Arithmetic;
572
573 case Type::ObjCObject:
574 case Type::ObjCInterface:
575 case Type::ObjCObjectPointer:
576 return STC_ObjectiveC;
577
578 default:
579 return STC_Other;
580 }
581}
582
583/// \brief Get the type that a given expression will have if this declaration
584/// is used as an expression in its "typical" code-completion form.
Douglas Gregor1827e102010-08-16 16:18:59 +0000585QualType clang::getDeclUsageType(ASTContext &C, NamedDecl *ND) {
Douglas Gregor1f5537a2010-07-08 23:20:03 +0000586 ND = cast<NamedDecl>(ND->getUnderlyingDecl());
587
588 if (TypeDecl *Type = dyn_cast<TypeDecl>(ND))
589 return C.getTypeDeclType(Type);
590 if (ObjCInterfaceDecl *Iface = dyn_cast<ObjCInterfaceDecl>(ND))
591 return C.getObjCInterfaceType(Iface);
592
593 QualType T;
594 if (FunctionDecl *Function = dyn_cast<FunctionDecl>(ND))
Douglas Gregor5291c3c2010-07-13 08:18:22 +0000595 T = Function->getCallResultType();
Douglas Gregor1f5537a2010-07-08 23:20:03 +0000596 else if (ObjCMethodDecl *Method = dyn_cast<ObjCMethodDecl>(ND))
Douglas Gregor5291c3c2010-07-13 08:18:22 +0000597 T = Method->getSendResultType();
Douglas Gregor1f5537a2010-07-08 23:20:03 +0000598 else if (FunctionTemplateDecl *FunTmpl = dyn_cast<FunctionTemplateDecl>(ND))
Douglas Gregor5291c3c2010-07-13 08:18:22 +0000599 T = FunTmpl->getTemplatedDecl()->getCallResultType();
Douglas Gregor1f5537a2010-07-08 23:20:03 +0000600 else if (EnumConstantDecl *Enumerator = dyn_cast<EnumConstantDecl>(ND))
601 T = C.getTypeDeclType(cast<EnumDecl>(Enumerator->getDeclContext()));
602 else if (ObjCPropertyDecl *Property = dyn_cast<ObjCPropertyDecl>(ND))
603 T = Property->getType();
604 else if (ValueDecl *Value = dyn_cast<ValueDecl>(ND))
605 T = Value->getType();
606 else
607 return QualType();
608
609 return T.getNonReferenceType();
610}
611
612void ResultBuilder::AdjustResultPriorityForPreferredType(Result &R) {
613 QualType T = getDeclUsageType(SemaRef.Context, R.Declaration);
614 if (T.isNull())
615 return;
616
617 CanQualType TC = SemaRef.Context.getCanonicalType(T);
618 // Check for exactly-matching types (modulo qualifiers).
Douglas Gregoreb0d0142010-08-24 23:58:17 +0000619 if (SemaRef.Context.hasSameUnqualifiedType(PreferredType, TC)) {
620 if (PreferredType->isVoidType())
621 R.Priority += CCD_VoidMatch;
622 else
623 R.Priority /= CCF_ExactTypeMatch;
624 } // Check for nearly-matching types, based on classification of each.
Douglas Gregor1f5537a2010-07-08 23:20:03 +0000625 else if ((getSimplifiedTypeClass(PreferredType)
626 == getSimplifiedTypeClass(TC)) &&
627 !(PreferredType->isEnumeralType() && TC->isEnumeralType()))
628 R.Priority /= CCF_SimilarTypeMatch;
629}
630
Douglas Gregore495b7f2010-01-14 00:20:49 +0000631void ResultBuilder::MaybeAddResult(Result R, DeclContext *CurContext) {
632 assert(!ShadowMaps.empty() && "Must enter into a results scope");
633
634 if (R.Kind != Result::RK_Declaration) {
635 // For non-declaration results, just add the result.
636 Results.push_back(R);
637 return;
638 }
639
640 // Look through using declarations.
641 if (UsingShadowDecl *Using = dyn_cast<UsingShadowDecl>(R.Declaration)) {
642 MaybeAddResult(Result(Using->getTargetDecl(), R.Qualifier), CurContext);
643 return;
644 }
645
646 Decl *CanonDecl = R.Declaration->getCanonicalDecl();
647 unsigned IDNS = CanonDecl->getIdentifierNamespace();
648
Douglas Gregor45bcd432010-01-14 03:21:49 +0000649 bool AsNestedNameSpecifier = false;
650 if (!isInterestingDecl(R.Declaration, AsNestedNameSpecifier))
Douglas Gregore495b7f2010-01-14 00:20:49 +0000651 return;
652
Douglas Gregor86d9a522009-09-21 16:56:56 +0000653 ShadowMap &SMap = ShadowMaps.back();
Douglas Gregorfbcb5d62009-12-06 20:23:50 +0000654 ShadowMapEntry::iterator I, IEnd;
655 ShadowMap::iterator NamePos = SMap.find(R.Declaration->getDeclName());
656 if (NamePos != SMap.end()) {
657 I = NamePos->second.begin();
658 IEnd = NamePos->second.end();
659 }
660
661 for (; I != IEnd; ++I) {
662 NamedDecl *ND = I->first;
663 unsigned Index = I->second;
Douglas Gregor86d9a522009-09-21 16:56:56 +0000664 if (ND->getCanonicalDecl() == CanonDecl) {
665 // This is a redeclaration. Always pick the newer declaration.
Douglas Gregor86d9a522009-09-21 16:56:56 +0000666 Results[Index].Declaration = R.Declaration;
667
Douglas Gregor86d9a522009-09-21 16:56:56 +0000668 // We're done.
669 return;
670 }
671 }
672
673 // This is a new declaration in this scope. However, check whether this
674 // declaration name is hidden by a similarly-named declaration in an outer
675 // scope.
676 std::list<ShadowMap>::iterator SM, SMEnd = ShadowMaps.end();
677 --SMEnd;
678 for (SM = ShadowMaps.begin(); SM != SMEnd; ++SM) {
Douglas Gregorfbcb5d62009-12-06 20:23:50 +0000679 ShadowMapEntry::iterator I, IEnd;
680 ShadowMap::iterator NamePos = SM->find(R.Declaration->getDeclName());
681 if (NamePos != SM->end()) {
682 I = NamePos->second.begin();
683 IEnd = NamePos->second.end();
684 }
685 for (; I != IEnd; ++I) {
Douglas Gregor86d9a522009-09-21 16:56:56 +0000686 // A tag declaration does not hide a non-tag declaration.
John McCall0d6b1642010-04-23 18:46:30 +0000687 if (I->first->hasTagIdentifierNamespace() &&
Douglas Gregor86d9a522009-09-21 16:56:56 +0000688 (IDNS & (Decl::IDNS_Member | Decl::IDNS_Ordinary |
689 Decl::IDNS_ObjCProtocol)))
690 continue;
691
692 // Protocols are in distinct namespaces from everything else.
Douglas Gregorfbcb5d62009-12-06 20:23:50 +0000693 if (((I->first->getIdentifierNamespace() & Decl::IDNS_ObjCProtocol)
Douglas Gregor86d9a522009-09-21 16:56:56 +0000694 || (IDNS & Decl::IDNS_ObjCProtocol)) &&
Douglas Gregorfbcb5d62009-12-06 20:23:50 +0000695 I->first->getIdentifierNamespace() != IDNS)
Douglas Gregor86d9a522009-09-21 16:56:56 +0000696 continue;
697
698 // The newly-added result is hidden by an entry in the shadow map.
Douglas Gregor6660d842010-01-14 00:41:07 +0000699 if (CheckHiddenResult(R, CurContext, I->first))
Douglas Gregor86d9a522009-09-21 16:56:56 +0000700 return;
Douglas Gregor86d9a522009-09-21 16:56:56 +0000701
702 break;
703 }
704 }
705
706 // Make sure that any given declaration only shows up in the result set once.
707 if (!AllDeclsFound.insert(CanonDecl))
708 return;
709
Douglas Gregoreb5758b2009-09-23 22:26:46 +0000710 // If the filter is for nested-name-specifiers, then this result starts a
711 // nested-name-specifier.
Douglas Gregor12e13132010-05-26 22:00:08 +0000712 if (AsNestedNameSpecifier) {
Douglas Gregoreb5758b2009-09-23 22:26:46 +0000713 R.StartsNestedNameSpecifier = true;
Douglas Gregor12e13132010-05-26 22:00:08 +0000714 R.Priority = CCP_NestedNameSpecifier;
Douglas Gregor1f5537a2010-07-08 23:20:03 +0000715 } else if (!PreferredType.isNull())
716 AdjustResultPriorityForPreferredType(R);
717
Douglas Gregor0563c262009-09-22 23:15:58 +0000718 // If this result is supposed to have an informative qualifier, add one.
Douglas Gregoreb5758b2009-09-23 22:26:46 +0000719 if (R.QualifierIsInformative && !R.Qualifier &&
720 !R.StartsNestedNameSpecifier) {
Douglas Gregor0563c262009-09-22 23:15:58 +0000721 DeclContext *Ctx = R.Declaration->getDeclContext();
722 if (NamespaceDecl *Namespace = dyn_cast<NamespaceDecl>(Ctx))
723 R.Qualifier = NestedNameSpecifier::Create(SemaRef.Context, 0, Namespace);
724 else if (TagDecl *Tag = dyn_cast<TagDecl>(Ctx))
725 R.Qualifier = NestedNameSpecifier::Create(SemaRef.Context, 0, false,
726 SemaRef.Context.getTypeDeclType(Tag).getTypePtr());
727 else
728 R.QualifierIsInformative = false;
729 }
Douglas Gregoreb5758b2009-09-23 22:26:46 +0000730
Douglas Gregor86d9a522009-09-21 16:56:56 +0000731 // Insert this result into the set of results and into the current shadow
732 // map.
Douglas Gregorfbcb5d62009-12-06 20:23:50 +0000733 SMap[R.Declaration->getDeclName()].Add(R.Declaration, Results.size());
Douglas Gregor86d9a522009-09-21 16:56:56 +0000734 Results.push_back(R);
735}
736
Douglas Gregor1ca6ae82010-01-14 01:09:38 +0000737void ResultBuilder::AddResult(Result R, DeclContext *CurContext,
Douglas Gregor0cc84042010-01-14 15:47:35 +0000738 NamedDecl *Hiding, bool InBaseClass = false) {
Douglas Gregora4477812010-01-14 16:01:26 +0000739 if (R.Kind != Result::RK_Declaration) {
740 // For non-declaration results, just add the result.
741 Results.push_back(R);
742 return;
743 }
744
Douglas Gregor1ca6ae82010-01-14 01:09:38 +0000745 // Look through using declarations.
746 if (UsingShadowDecl *Using = dyn_cast<UsingShadowDecl>(R.Declaration)) {
747 AddResult(Result(Using->getTargetDecl(), R.Qualifier), CurContext, Hiding);
748 return;
749 }
750
Douglas Gregor45bcd432010-01-14 03:21:49 +0000751 bool AsNestedNameSpecifier = false;
752 if (!isInterestingDecl(R.Declaration, AsNestedNameSpecifier))
Douglas Gregor1ca6ae82010-01-14 01:09:38 +0000753 return;
754
755 if (Hiding && CheckHiddenResult(R, CurContext, Hiding))
756 return;
757
758 // Make sure that any given declaration only shows up in the result set once.
759 if (!AllDeclsFound.insert(R.Declaration->getCanonicalDecl()))
760 return;
761
762 // If the filter is for nested-name-specifiers, then this result starts a
763 // nested-name-specifier.
Douglas Gregor12e13132010-05-26 22:00:08 +0000764 if (AsNestedNameSpecifier) {
Douglas Gregor1ca6ae82010-01-14 01:09:38 +0000765 R.StartsNestedNameSpecifier = true;
Douglas Gregor12e13132010-05-26 22:00:08 +0000766 R.Priority = CCP_NestedNameSpecifier;
767 }
Douglas Gregor0cc84042010-01-14 15:47:35 +0000768 else if (Filter == &ResultBuilder::IsMember && !R.Qualifier && InBaseClass &&
769 isa<CXXRecordDecl>(R.Declaration->getDeclContext()
770 ->getLookupContext()))
771 R.QualifierIsInformative = true;
772
Douglas Gregor1ca6ae82010-01-14 01:09:38 +0000773 // If this result is supposed to have an informative qualifier, add one.
774 if (R.QualifierIsInformative && !R.Qualifier &&
775 !R.StartsNestedNameSpecifier) {
776 DeclContext *Ctx = R.Declaration->getDeclContext();
777 if (NamespaceDecl *Namespace = dyn_cast<NamespaceDecl>(Ctx))
778 R.Qualifier = NestedNameSpecifier::Create(SemaRef.Context, 0, Namespace);
779 else if (TagDecl *Tag = dyn_cast<TagDecl>(Ctx))
780 R.Qualifier = NestedNameSpecifier::Create(SemaRef.Context, 0, false,
Douglas Gregor45bcd432010-01-14 03:21:49 +0000781 SemaRef.Context.getTypeDeclType(Tag).getTypePtr());
Douglas Gregor1ca6ae82010-01-14 01:09:38 +0000782 else
783 R.QualifierIsInformative = false;
784 }
785
Douglas Gregor12e13132010-05-26 22:00:08 +0000786 // Adjust the priority if this result comes from a base class.
787 if (InBaseClass)
788 R.Priority += CCD_InBaseClass;
789
Douglas Gregor1f5537a2010-07-08 23:20:03 +0000790 if (!PreferredType.isNull())
791 AdjustResultPriorityForPreferredType(R);
Douglas Gregor5ac3bdb2010-05-30 01:49:25 +0000792
Douglas Gregor3cdee122010-08-26 16:36:48 +0000793 if (HasObjectTypeQualifiers)
794 if (CXXMethodDecl *Method = dyn_cast<CXXMethodDecl>(R.Declaration))
795 if (Method->isInstance()) {
796 Qualifiers MethodQuals
797 = Qualifiers::fromCVRMask(Method->getTypeQualifiers());
798 if (ObjectTypeQualifiers == MethodQuals)
799 R.Priority += CCD_ObjectQualifierMatch;
800 else if (ObjectTypeQualifiers - MethodQuals) {
801 // The method cannot be invoked, because doing so would drop
802 // qualifiers.
803 return;
804 }
805 }
806
Douglas Gregor1ca6ae82010-01-14 01:09:38 +0000807 // Insert this result into the set of results.
808 Results.push_back(R);
809}
810
Douglas Gregora4477812010-01-14 16:01:26 +0000811void ResultBuilder::AddResult(Result R) {
812 assert(R.Kind != Result::RK_Declaration &&
813 "Declaration results need more context");
814 Results.push_back(R);
815}
816
Douglas Gregor86d9a522009-09-21 16:56:56 +0000817/// \brief Enter into a new scope.
818void ResultBuilder::EnterNewScope() {
819 ShadowMaps.push_back(ShadowMap());
820}
821
822/// \brief Exit from the current scope.
823void ResultBuilder::ExitScope() {
Douglas Gregorfbcb5d62009-12-06 20:23:50 +0000824 for (ShadowMap::iterator E = ShadowMaps.back().begin(),
825 EEnd = ShadowMaps.back().end();
826 E != EEnd;
827 ++E)
828 E->second.Destroy();
829
Douglas Gregor86d9a522009-09-21 16:56:56 +0000830 ShadowMaps.pop_back();
831}
832
Douglas Gregor791215b2009-09-21 20:51:25 +0000833/// \brief Determines whether this given declaration will be found by
834/// ordinary name lookup.
835bool ResultBuilder::IsOrdinaryName(NamedDecl *ND) const {
Douglas Gregor4710e5b2010-05-28 00:49:12 +0000836 ND = cast<NamedDecl>(ND->getUnderlyingDecl());
837
Douglas Gregor791215b2009-09-21 20:51:25 +0000838 unsigned IDNS = Decl::IDNS_Ordinary;
839 if (SemaRef.getLangOptions().CPlusPlus)
Douglas Gregor9b30b262010-06-15 20:26:51 +0000840 IDNS |= Decl::IDNS_Tag | Decl::IDNS_Namespace | Decl::IDNS_Member;
Douglas Gregor1ca6ae82010-01-14 01:09:38 +0000841 else if (SemaRef.getLangOptions().ObjC1 && isa<ObjCIvarDecl>(ND))
842 return true;
843
Douglas Gregor791215b2009-09-21 20:51:25 +0000844 return ND->getIdentifierNamespace() & IDNS;
845}
846
Douglas Gregor01dfea02010-01-10 23:08:15 +0000847/// \brief Determines whether this given declaration will be found by
Douglas Gregor4710e5b2010-05-28 00:49:12 +0000848/// ordinary name lookup but is not a type name.
849bool ResultBuilder::IsOrdinaryNonTypeName(NamedDecl *ND) const {
850 ND = cast<NamedDecl>(ND->getUnderlyingDecl());
851 if (isa<TypeDecl>(ND) || isa<ObjCInterfaceDecl>(ND))
852 return false;
853
854 unsigned IDNS = Decl::IDNS_Ordinary;
855 if (SemaRef.getLangOptions().CPlusPlus)
Douglas Gregor9b30b262010-06-15 20:26:51 +0000856 IDNS |= Decl::IDNS_Tag | Decl::IDNS_Namespace | Decl::IDNS_Member;
Douglas Gregor4710e5b2010-05-28 00:49:12 +0000857 else if (SemaRef.getLangOptions().ObjC1 && isa<ObjCIvarDecl>(ND))
858 return true;
859
860 return ND->getIdentifierNamespace() & IDNS;
861}
862
Douglas Gregorf9578432010-07-28 21:50:18 +0000863bool ResultBuilder::IsIntegralConstantValue(NamedDecl *ND) const {
864 if (!IsOrdinaryNonTypeName(ND))
865 return 0;
866
867 if (ValueDecl *VD = dyn_cast<ValueDecl>(ND->getUnderlyingDecl()))
868 if (VD->getType()->isIntegralOrEnumerationType())
869 return true;
870
871 return false;
872}
873
Douglas Gregor4710e5b2010-05-28 00:49:12 +0000874/// \brief Determines whether this given declaration will be found by
Douglas Gregor01dfea02010-01-10 23:08:15 +0000875/// ordinary name lookup.
876bool ResultBuilder::IsOrdinaryNonValueName(NamedDecl *ND) const {
Douglas Gregor4710e5b2010-05-28 00:49:12 +0000877 ND = cast<NamedDecl>(ND->getUnderlyingDecl());
878
Douglas Gregor01dfea02010-01-10 23:08:15 +0000879 unsigned IDNS = Decl::IDNS_Ordinary;
880 if (SemaRef.getLangOptions().CPlusPlus)
John McCall0d6b1642010-04-23 18:46:30 +0000881 IDNS |= Decl::IDNS_Tag | Decl::IDNS_Namespace;
Douglas Gregor01dfea02010-01-10 23:08:15 +0000882
883 return (ND->getIdentifierNamespace() & IDNS) &&
Douglas Gregor4710e5b2010-05-28 00:49:12 +0000884 !isa<ValueDecl>(ND) && !isa<FunctionTemplateDecl>(ND) &&
885 !isa<ObjCPropertyDecl>(ND);
Douglas Gregor01dfea02010-01-10 23:08:15 +0000886}
887
Douglas Gregor86d9a522009-09-21 16:56:56 +0000888/// \brief Determines whether the given declaration is suitable as the
889/// start of a C++ nested-name-specifier, e.g., a class or namespace.
890bool ResultBuilder::IsNestedNameSpecifier(NamedDecl *ND) const {
891 // Allow us to find class templates, too.
892 if (ClassTemplateDecl *ClassTemplate = dyn_cast<ClassTemplateDecl>(ND))
893 ND = ClassTemplate->getTemplatedDecl();
894
895 return SemaRef.isAcceptableNestedNameSpecifier(ND);
896}
897
898/// \brief Determines whether the given declaration is an enumeration.
899bool ResultBuilder::IsEnum(NamedDecl *ND) const {
900 return isa<EnumDecl>(ND);
901}
902
903/// \brief Determines whether the given declaration is a class or struct.
904bool ResultBuilder::IsClassOrStruct(NamedDecl *ND) const {
905 // Allow us to find class templates, too.
906 if (ClassTemplateDecl *ClassTemplate = dyn_cast<ClassTemplateDecl>(ND))
907 ND = ClassTemplate->getTemplatedDecl();
908
909 if (RecordDecl *RD = dyn_cast<RecordDecl>(ND))
Abramo Bagnara465d41b2010-05-11 21:36:43 +0000910 return RD->getTagKind() == TTK_Class ||
911 RD->getTagKind() == TTK_Struct;
Douglas Gregor86d9a522009-09-21 16:56:56 +0000912
913 return false;
914}
915
916/// \brief Determines whether the given declaration is a union.
917bool ResultBuilder::IsUnion(NamedDecl *ND) const {
918 // Allow us to find class templates, too.
919 if (ClassTemplateDecl *ClassTemplate = dyn_cast<ClassTemplateDecl>(ND))
920 ND = ClassTemplate->getTemplatedDecl();
921
922 if (RecordDecl *RD = dyn_cast<RecordDecl>(ND))
Abramo Bagnara465d41b2010-05-11 21:36:43 +0000923 return RD->getTagKind() == TTK_Union;
Douglas Gregor86d9a522009-09-21 16:56:56 +0000924
925 return false;
926}
927
928/// \brief Determines whether the given declaration is a namespace.
929bool ResultBuilder::IsNamespace(NamedDecl *ND) const {
930 return isa<NamespaceDecl>(ND);
931}
932
933/// \brief Determines whether the given declaration is a namespace or
934/// namespace alias.
935bool ResultBuilder::IsNamespaceOrAlias(NamedDecl *ND) const {
936 return isa<NamespaceDecl>(ND) || isa<NamespaceAliasDecl>(ND);
937}
938
Douglas Gregor76282942009-12-11 17:31:05 +0000939/// \brief Determines whether the given declaration is a type.
Douglas Gregor86d9a522009-09-21 16:56:56 +0000940bool ResultBuilder::IsType(NamedDecl *ND) const {
Douglas Gregord32b0222010-08-24 01:06:58 +0000941 if (UsingShadowDecl *Using = dyn_cast<UsingShadowDecl>(ND))
942 ND = Using->getTargetDecl();
943
944 return isa<TypeDecl>(ND) || isa<ObjCInterfaceDecl>(ND);
Douglas Gregor86d9a522009-09-21 16:56:56 +0000945}
946
Douglas Gregor76282942009-12-11 17:31:05 +0000947/// \brief Determines which members of a class should be visible via
948/// "." or "->". Only value declarations, nested name specifiers, and
949/// using declarations thereof should show up.
Douglas Gregoreb5758b2009-09-23 22:26:46 +0000950bool ResultBuilder::IsMember(NamedDecl *ND) const {
Douglas Gregor76282942009-12-11 17:31:05 +0000951 if (UsingShadowDecl *Using = dyn_cast<UsingShadowDecl>(ND))
952 ND = Using->getTargetDecl();
953
Douglas Gregorce821962009-12-11 18:14:22 +0000954 return isa<ValueDecl>(ND) || isa<FunctionTemplateDecl>(ND) ||
955 isa<ObjCPropertyDecl>(ND);
Douglas Gregoreb5758b2009-09-23 22:26:46 +0000956}
957
Douglas Gregor8e254cf2010-05-27 23:06:34 +0000958static bool isObjCReceiverType(ASTContext &C, QualType T) {
959 T = C.getCanonicalType(T);
960 switch (T->getTypeClass()) {
961 case Type::ObjCObject:
962 case Type::ObjCInterface:
963 case Type::ObjCObjectPointer:
964 return true;
965
966 case Type::Builtin:
967 switch (cast<BuiltinType>(T)->getKind()) {
968 case BuiltinType::ObjCId:
969 case BuiltinType::ObjCClass:
970 case BuiltinType::ObjCSel:
971 return true;
972
973 default:
974 break;
975 }
976 return false;
977
978 default:
979 break;
980 }
981
982 if (!C.getLangOptions().CPlusPlus)
983 return false;
984
985 // FIXME: We could perform more analysis here to determine whether a
986 // particular class type has any conversions to Objective-C types. For now,
987 // just accept all class types.
988 return T->isDependentType() || T->isRecordType();
989}
990
991bool ResultBuilder::IsObjCMessageReceiver(NamedDecl *ND) const {
992 QualType T = getDeclUsageType(SemaRef.Context, ND);
993 if (T.isNull())
994 return false;
995
996 T = SemaRef.Context.getBaseElementType(T);
997 return isObjCReceiverType(SemaRef.Context, T);
998}
999
Douglas Gregorfb629412010-08-23 21:17:50 +00001000bool ResultBuilder::IsObjCCollection(NamedDecl *ND) const {
1001 if ((SemaRef.getLangOptions().CPlusPlus && !IsOrdinaryName(ND)) ||
1002 (!SemaRef.getLangOptions().CPlusPlus && !IsOrdinaryNonTypeName(ND)))
1003 return false;
1004
1005 QualType T = getDeclUsageType(SemaRef.Context, ND);
1006 if (T.isNull())
1007 return false;
1008
1009 T = SemaRef.Context.getBaseElementType(T);
1010 return T->isObjCObjectType() || T->isObjCObjectPointerType() ||
1011 T->isObjCIdType() ||
1012 (SemaRef.getLangOptions().CPlusPlus && T->isRecordType());
1013}
Douglas Gregor8e254cf2010-05-27 23:06:34 +00001014
Douglas Gregor80f4f4c2010-01-14 16:08:12 +00001015/// \rief Determines whether the given declaration is an Objective-C
1016/// instance variable.
1017bool ResultBuilder::IsObjCIvar(NamedDecl *ND) const {
1018 return isa<ObjCIvarDecl>(ND);
1019}
1020
Douglas Gregor1ca6ae82010-01-14 01:09:38 +00001021namespace {
1022 /// \brief Visible declaration consumer that adds a code-completion result
1023 /// for each visible declaration.
1024 class CodeCompletionDeclConsumer : public VisibleDeclConsumer {
1025 ResultBuilder &Results;
1026 DeclContext *CurContext;
1027
1028 public:
1029 CodeCompletionDeclConsumer(ResultBuilder &Results, DeclContext *CurContext)
1030 : Results(Results), CurContext(CurContext) { }
1031
Douglas Gregor0cc84042010-01-14 15:47:35 +00001032 virtual void FoundDecl(NamedDecl *ND, NamedDecl *Hiding, bool InBaseClass) {
1033 Results.AddResult(ND, CurContext, Hiding, InBaseClass);
Douglas Gregor1ca6ae82010-01-14 01:09:38 +00001034 }
1035 };
1036}
1037
Douglas Gregor86d9a522009-09-21 16:56:56 +00001038/// \brief Add type specifiers for the current language as keyword results.
Douglas Gregorbca403c2010-01-13 23:51:12 +00001039static void AddTypeSpecifierResults(const LangOptions &LangOpts,
Douglas Gregor86d9a522009-09-21 16:56:56 +00001040 ResultBuilder &Results) {
John McCall0a2c5e22010-08-25 06:19:51 +00001041 typedef CodeCompletionResult Result;
Douglas Gregor12e13132010-05-26 22:00:08 +00001042 Results.AddResult(Result("short", CCP_Type));
1043 Results.AddResult(Result("long", CCP_Type));
1044 Results.AddResult(Result("signed", CCP_Type));
1045 Results.AddResult(Result("unsigned", CCP_Type));
1046 Results.AddResult(Result("void", CCP_Type));
1047 Results.AddResult(Result("char", CCP_Type));
1048 Results.AddResult(Result("int", CCP_Type));
1049 Results.AddResult(Result("float", CCP_Type));
1050 Results.AddResult(Result("double", CCP_Type));
1051 Results.AddResult(Result("enum", CCP_Type));
1052 Results.AddResult(Result("struct", CCP_Type));
1053 Results.AddResult(Result("union", CCP_Type));
1054 Results.AddResult(Result("const", CCP_Type));
1055 Results.AddResult(Result("volatile", CCP_Type));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001056
Douglas Gregor86d9a522009-09-21 16:56:56 +00001057 if (LangOpts.C99) {
1058 // C99-specific
Douglas Gregor12e13132010-05-26 22:00:08 +00001059 Results.AddResult(Result("_Complex", CCP_Type));
1060 Results.AddResult(Result("_Imaginary", CCP_Type));
1061 Results.AddResult(Result("_Bool", CCP_Type));
1062 Results.AddResult(Result("restrict", CCP_Type));
Douglas Gregor86d9a522009-09-21 16:56:56 +00001063 }
1064
1065 if (LangOpts.CPlusPlus) {
1066 // C++-specific
Douglas Gregor12e13132010-05-26 22:00:08 +00001067 Results.AddResult(Result("bool", CCP_Type));
1068 Results.AddResult(Result("class", CCP_Type));
1069 Results.AddResult(Result("wchar_t", CCP_Type));
Douglas Gregor86d9a522009-09-21 16:56:56 +00001070
Douglas Gregorc8bddde2010-05-28 00:22:41 +00001071 // typename qualified-id
1072 CodeCompletionString *Pattern = new CodeCompletionString;
1073 Pattern->AddTypedTextChunk("typename");
1074 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
1075 Pattern->AddPlaceholderChunk("qualifier");
1076 Pattern->AddTextChunk("::");
1077 Pattern->AddPlaceholderChunk("name");
1078 Results.AddResult(Result(Pattern));
Douglas Gregord8e8a582010-05-25 21:41:55 +00001079
Douglas Gregor86d9a522009-09-21 16:56:56 +00001080 if (LangOpts.CPlusPlus0x) {
Douglas Gregor12e13132010-05-26 22:00:08 +00001081 Results.AddResult(Result("auto", CCP_Type));
1082 Results.AddResult(Result("char16_t", CCP_Type));
1083 Results.AddResult(Result("char32_t", CCP_Type));
Douglas Gregorc8bddde2010-05-28 00:22:41 +00001084
1085 CodeCompletionString *Pattern = new CodeCompletionString;
1086 Pattern->AddTypedTextChunk("decltype");
1087 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
1088 Pattern->AddPlaceholderChunk("expression");
1089 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
1090 Results.AddResult(Result(Pattern));
Douglas Gregor86d9a522009-09-21 16:56:56 +00001091 }
1092 }
1093
1094 // GNU extensions
1095 if (LangOpts.GNUMode) {
1096 // FIXME: Enable when we actually support decimal floating point.
Douglas Gregora4477812010-01-14 16:01:26 +00001097 // Results.AddResult(Result("_Decimal32"));
1098 // Results.AddResult(Result("_Decimal64"));
1099 // Results.AddResult(Result("_Decimal128"));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001100
Douglas Gregorc8bddde2010-05-28 00:22:41 +00001101 CodeCompletionString *Pattern = new CodeCompletionString;
1102 Pattern->AddTypedTextChunk("typeof");
1103 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
1104 Pattern->AddPlaceholderChunk("expression");
1105 Results.AddResult(Result(Pattern));
1106
1107 Pattern = new CodeCompletionString;
1108 Pattern->AddTypedTextChunk("typeof");
1109 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
1110 Pattern->AddPlaceholderChunk("type");
1111 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
1112 Results.AddResult(Result(Pattern));
Douglas Gregor86d9a522009-09-21 16:56:56 +00001113 }
1114}
1115
John McCallf312b1e2010-08-26 23:41:50 +00001116static void AddStorageSpecifiers(Sema::ParserCompletionContext CCC,
Douglas Gregor01dfea02010-01-10 23:08:15 +00001117 const LangOptions &LangOpts,
Douglas Gregor01dfea02010-01-10 23:08:15 +00001118 ResultBuilder &Results) {
John McCall0a2c5e22010-08-25 06:19:51 +00001119 typedef CodeCompletionResult Result;
Douglas Gregor01dfea02010-01-10 23:08:15 +00001120 // Note: we don't suggest either "auto" or "register", because both
1121 // are pointless as storage specifiers. Elsewhere, we suggest "auto"
1122 // in C++0x as a type specifier.
Douglas Gregora4477812010-01-14 16:01:26 +00001123 Results.AddResult(Result("extern"));
1124 Results.AddResult(Result("static"));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001125}
1126
John McCallf312b1e2010-08-26 23:41:50 +00001127static void AddFunctionSpecifiers(Sema::ParserCompletionContext CCC,
Douglas Gregor01dfea02010-01-10 23:08:15 +00001128 const LangOptions &LangOpts,
Douglas Gregor01dfea02010-01-10 23:08:15 +00001129 ResultBuilder &Results) {
John McCall0a2c5e22010-08-25 06:19:51 +00001130 typedef CodeCompletionResult Result;
Douglas Gregor01dfea02010-01-10 23:08:15 +00001131 switch (CCC) {
John McCallf312b1e2010-08-26 23:41:50 +00001132 case Sema::PCC_Class:
1133 case Sema::PCC_MemberTemplate:
Douglas Gregor01dfea02010-01-10 23:08:15 +00001134 if (LangOpts.CPlusPlus) {
Douglas Gregora4477812010-01-14 16:01:26 +00001135 Results.AddResult(Result("explicit"));
1136 Results.AddResult(Result("friend"));
1137 Results.AddResult(Result("mutable"));
1138 Results.AddResult(Result("virtual"));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001139 }
1140 // Fall through
1141
John McCallf312b1e2010-08-26 23:41:50 +00001142 case Sema::PCC_ObjCInterface:
1143 case Sema::PCC_ObjCImplementation:
1144 case Sema::PCC_Namespace:
1145 case Sema::PCC_Template:
Douglas Gregor01dfea02010-01-10 23:08:15 +00001146 if (LangOpts.CPlusPlus || LangOpts.C99)
Douglas Gregora4477812010-01-14 16:01:26 +00001147 Results.AddResult(Result("inline"));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001148 break;
1149
John McCallf312b1e2010-08-26 23:41:50 +00001150 case Sema::PCC_ObjCInstanceVariableList:
1151 case Sema::PCC_Expression:
1152 case Sema::PCC_Statement:
1153 case Sema::PCC_ForInit:
1154 case Sema::PCC_Condition:
1155 case Sema::PCC_RecoveryInFunction:
1156 case Sema::PCC_Type:
Douglas Gregor01dfea02010-01-10 23:08:15 +00001157 break;
1158 }
1159}
1160
Douglas Gregorbca403c2010-01-13 23:51:12 +00001161static void AddObjCExpressionResults(ResultBuilder &Results, bool NeedAt);
1162static void AddObjCStatementResults(ResultBuilder &Results, bool NeedAt);
1163static void AddObjCVisibilityResults(const LangOptions &LangOpts,
Douglas Gregorc38c3e12010-01-13 21:54:15 +00001164 ResultBuilder &Results,
1165 bool NeedAt);
Douglas Gregorbca403c2010-01-13 23:51:12 +00001166static void AddObjCImplementationResults(const LangOptions &LangOpts,
Douglas Gregorb6ac2452010-01-13 21:24:21 +00001167 ResultBuilder &Results,
1168 bool NeedAt);
Douglas Gregorbca403c2010-01-13 23:51:12 +00001169static void AddObjCInterfaceResults(const LangOptions &LangOpts,
Douglas Gregorb6ac2452010-01-13 21:24:21 +00001170 ResultBuilder &Results,
1171 bool NeedAt);
Douglas Gregorbca403c2010-01-13 23:51:12 +00001172static void AddObjCTopLevelResults(ResultBuilder &Results, bool NeedAt);
Douglas Gregorb6ac2452010-01-13 21:24:21 +00001173
Douglas Gregorc8bddde2010-05-28 00:22:41 +00001174static void AddTypedefResult(ResultBuilder &Results) {
1175 CodeCompletionString *Pattern = new CodeCompletionString;
1176 Pattern->AddTypedTextChunk("typedef");
1177 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
1178 Pattern->AddPlaceholderChunk("type");
1179 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
1180 Pattern->AddPlaceholderChunk("name");
John McCall0a2c5e22010-08-25 06:19:51 +00001181 Results.AddResult(CodeCompletionResult(Pattern));
Douglas Gregorc8bddde2010-05-28 00:22:41 +00001182}
1183
John McCallf312b1e2010-08-26 23:41:50 +00001184static bool WantTypesInContext(Sema::ParserCompletionContext CCC,
Douglas Gregor4710e5b2010-05-28 00:49:12 +00001185 const LangOptions &LangOpts) {
1186 if (LangOpts.CPlusPlus)
1187 return true;
1188
1189 switch (CCC) {
John McCallf312b1e2010-08-26 23:41:50 +00001190 case Sema::PCC_Namespace:
1191 case Sema::PCC_Class:
1192 case Sema::PCC_ObjCInstanceVariableList:
1193 case Sema::PCC_Template:
1194 case Sema::PCC_MemberTemplate:
1195 case Sema::PCC_Statement:
1196 case Sema::PCC_RecoveryInFunction:
1197 case Sema::PCC_Type:
Douglas Gregor4710e5b2010-05-28 00:49:12 +00001198 return true;
1199
John McCallf312b1e2010-08-26 23:41:50 +00001200 case Sema::PCC_ObjCInterface:
1201 case Sema::PCC_ObjCImplementation:
1202 case Sema::PCC_Expression:
1203 case Sema::PCC_Condition:
Douglas Gregor4710e5b2010-05-28 00:49:12 +00001204 return false;
1205
John McCallf312b1e2010-08-26 23:41:50 +00001206 case Sema::PCC_ForInit:
Douglas Gregor4710e5b2010-05-28 00:49:12 +00001207 return LangOpts.ObjC1 || LangOpts.C99;
1208 }
1209
1210 return false;
1211}
1212
Douglas Gregor01dfea02010-01-10 23:08:15 +00001213/// \brief Add language constructs that show up for "ordinary" names.
John McCallf312b1e2010-08-26 23:41:50 +00001214static void AddOrdinaryNameResults(Sema::ParserCompletionContext CCC,
Douglas Gregor01dfea02010-01-10 23:08:15 +00001215 Scope *S,
1216 Sema &SemaRef,
Douglas Gregor01dfea02010-01-10 23:08:15 +00001217 ResultBuilder &Results) {
John McCall0a2c5e22010-08-25 06:19:51 +00001218 typedef CodeCompletionResult Result;
Douglas Gregor01dfea02010-01-10 23:08:15 +00001219 switch (CCC) {
John McCallf312b1e2010-08-26 23:41:50 +00001220 case Sema::PCC_Namespace:
Douglas Gregorc8bddde2010-05-28 00:22:41 +00001221 if (SemaRef.getLangOptions().CPlusPlus) {
1222 CodeCompletionString *Pattern = 0;
1223
1224 if (Results.includeCodePatterns()) {
1225 // namespace <identifier> { declarations }
1226 CodeCompletionString *Pattern = new CodeCompletionString;
1227 Pattern->AddTypedTextChunk("namespace");
1228 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
1229 Pattern->AddPlaceholderChunk("identifier");
1230 Pattern->AddChunk(CodeCompletionString::CK_LeftBrace);
1231 Pattern->AddPlaceholderChunk("declarations");
1232 Pattern->AddChunk(CodeCompletionString::CK_VerticalSpace);
1233 Pattern->AddChunk(CodeCompletionString::CK_RightBrace);
1234 Results.AddResult(Result(Pattern));
1235 }
1236
Douglas Gregor01dfea02010-01-10 23:08:15 +00001237 // namespace identifier = identifier ;
1238 Pattern = new CodeCompletionString;
1239 Pattern->AddTypedTextChunk("namespace");
1240 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
Douglas Gregorc8bddde2010-05-28 00:22:41 +00001241 Pattern->AddPlaceholderChunk("name");
Douglas Gregor01dfea02010-01-10 23:08:15 +00001242 Pattern->AddChunk(CodeCompletionString::CK_Equal);
Douglas Gregorc8bddde2010-05-28 00:22:41 +00001243 Pattern->AddPlaceholderChunk("namespace");
Douglas Gregora4477812010-01-14 16:01:26 +00001244 Results.AddResult(Result(Pattern));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001245
1246 // Using directives
1247 Pattern = new CodeCompletionString;
1248 Pattern->AddTypedTextChunk("using");
1249 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
1250 Pattern->AddTextChunk("namespace");
1251 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
1252 Pattern->AddPlaceholderChunk("identifier");
Douglas Gregora4477812010-01-14 16:01:26 +00001253 Results.AddResult(Result(Pattern));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001254
1255 // asm(string-literal)
1256 Pattern = new CodeCompletionString;
1257 Pattern->AddTypedTextChunk("asm");
1258 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
1259 Pattern->AddPlaceholderChunk("string-literal");
1260 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
Douglas Gregora4477812010-01-14 16:01:26 +00001261 Results.AddResult(Result(Pattern));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001262
Douglas Gregorc8bddde2010-05-28 00:22:41 +00001263 if (Results.includeCodePatterns()) {
1264 // Explicit template instantiation
1265 Pattern = new CodeCompletionString;
1266 Pattern->AddTypedTextChunk("template");
1267 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
1268 Pattern->AddPlaceholderChunk("declaration");
1269 Results.AddResult(Result(Pattern));
1270 }
Douglas Gregor01dfea02010-01-10 23:08:15 +00001271 }
Douglas Gregorb6ac2452010-01-13 21:24:21 +00001272
1273 if (SemaRef.getLangOptions().ObjC1)
Douglas Gregorbca403c2010-01-13 23:51:12 +00001274 AddObjCTopLevelResults(Results, true);
Douglas Gregorb6ac2452010-01-13 21:24:21 +00001275
Douglas Gregorc8bddde2010-05-28 00:22:41 +00001276 AddTypedefResult(Results);
Douglas Gregor01dfea02010-01-10 23:08:15 +00001277 // Fall through
1278
John McCallf312b1e2010-08-26 23:41:50 +00001279 case Sema::PCC_Class:
Douglas Gregorc8bddde2010-05-28 00:22:41 +00001280 if (SemaRef.getLangOptions().CPlusPlus) {
Douglas Gregor01dfea02010-01-10 23:08:15 +00001281 // Using declaration
1282 CodeCompletionString *Pattern = new CodeCompletionString;
1283 Pattern->AddTypedTextChunk("using");
1284 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
Douglas Gregorc8bddde2010-05-28 00:22:41 +00001285 Pattern->AddPlaceholderChunk("qualifier");
1286 Pattern->AddTextChunk("::");
1287 Pattern->AddPlaceholderChunk("name");
Douglas Gregora4477812010-01-14 16:01:26 +00001288 Results.AddResult(Result(Pattern));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001289
Douglas Gregorc8bddde2010-05-28 00:22:41 +00001290 // using typename qualifier::name (only in a dependent context)
Douglas Gregor01dfea02010-01-10 23:08:15 +00001291 if (SemaRef.CurContext->isDependentContext()) {
1292 Pattern = new CodeCompletionString;
1293 Pattern->AddTypedTextChunk("using");
1294 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
1295 Pattern->AddTextChunk("typename");
1296 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
Douglas Gregorc8bddde2010-05-28 00:22:41 +00001297 Pattern->AddPlaceholderChunk("qualifier");
1298 Pattern->AddTextChunk("::");
1299 Pattern->AddPlaceholderChunk("name");
Douglas Gregora4477812010-01-14 16:01:26 +00001300 Results.AddResult(Result(Pattern));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001301 }
1302
John McCallf312b1e2010-08-26 23:41:50 +00001303 if (CCC == Sema::PCC_Class) {
Douglas Gregorc8bddde2010-05-28 00:22:41 +00001304 AddTypedefResult(Results);
1305
Douglas Gregor01dfea02010-01-10 23:08:15 +00001306 // public:
1307 Pattern = new CodeCompletionString;
1308 Pattern->AddTypedTextChunk("public");
1309 Pattern->AddChunk(CodeCompletionString::CK_Colon);
Douglas Gregora4477812010-01-14 16:01:26 +00001310 Results.AddResult(Result(Pattern));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001311
1312 // protected:
1313 Pattern = new CodeCompletionString;
1314 Pattern->AddTypedTextChunk("protected");
1315 Pattern->AddChunk(CodeCompletionString::CK_Colon);
Douglas Gregora4477812010-01-14 16:01:26 +00001316 Results.AddResult(Result(Pattern));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001317
1318 // private:
1319 Pattern = new CodeCompletionString;
1320 Pattern->AddTypedTextChunk("private");
1321 Pattern->AddChunk(CodeCompletionString::CK_Colon);
Douglas Gregora4477812010-01-14 16:01:26 +00001322 Results.AddResult(Result(Pattern));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001323 }
1324 }
1325 // Fall through
1326
John McCallf312b1e2010-08-26 23:41:50 +00001327 case Sema::PCC_Template:
1328 case Sema::PCC_MemberTemplate:
Douglas Gregord8e8a582010-05-25 21:41:55 +00001329 if (SemaRef.getLangOptions().CPlusPlus && Results.includeCodePatterns()) {
Douglas Gregor01dfea02010-01-10 23:08:15 +00001330 // template < parameters >
1331 CodeCompletionString *Pattern = new CodeCompletionString;
1332 Pattern->AddTypedTextChunk("template");
1333 Pattern->AddChunk(CodeCompletionString::CK_LeftAngle);
1334 Pattern->AddPlaceholderChunk("parameters");
1335 Pattern->AddChunk(CodeCompletionString::CK_RightAngle);
Douglas Gregora4477812010-01-14 16:01:26 +00001336 Results.AddResult(Result(Pattern));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001337 }
1338
Douglas Gregorbca403c2010-01-13 23:51:12 +00001339 AddStorageSpecifiers(CCC, SemaRef.getLangOptions(), Results);
1340 AddFunctionSpecifiers(CCC, SemaRef.getLangOptions(), Results);
Douglas Gregor01dfea02010-01-10 23:08:15 +00001341 break;
1342
John McCallf312b1e2010-08-26 23:41:50 +00001343 case Sema::PCC_ObjCInterface:
Douglas Gregorbca403c2010-01-13 23:51:12 +00001344 AddObjCInterfaceResults(SemaRef.getLangOptions(), Results, true);
1345 AddStorageSpecifiers(CCC, SemaRef.getLangOptions(), Results);
1346 AddFunctionSpecifiers(CCC, SemaRef.getLangOptions(), Results);
Douglas Gregorb6ac2452010-01-13 21:24:21 +00001347 break;
1348
John McCallf312b1e2010-08-26 23:41:50 +00001349 case Sema::PCC_ObjCImplementation:
Douglas Gregorbca403c2010-01-13 23:51:12 +00001350 AddObjCImplementationResults(SemaRef.getLangOptions(), Results, true);
1351 AddStorageSpecifiers(CCC, SemaRef.getLangOptions(), Results);
1352 AddFunctionSpecifiers(CCC, SemaRef.getLangOptions(), Results);
Douglas Gregorb6ac2452010-01-13 21:24:21 +00001353 break;
1354
John McCallf312b1e2010-08-26 23:41:50 +00001355 case Sema::PCC_ObjCInstanceVariableList:
Douglas Gregorbca403c2010-01-13 23:51:12 +00001356 AddObjCVisibilityResults(SemaRef.getLangOptions(), Results, true);
Douglas Gregorc38c3e12010-01-13 21:54:15 +00001357 break;
1358
John McCallf312b1e2010-08-26 23:41:50 +00001359 case Sema::PCC_RecoveryInFunction:
1360 case Sema::PCC_Statement: {
Douglas Gregorc8bddde2010-05-28 00:22:41 +00001361 AddTypedefResult(Results);
Douglas Gregor01dfea02010-01-10 23:08:15 +00001362
1363 CodeCompletionString *Pattern = 0;
Douglas Gregord8e8a582010-05-25 21:41:55 +00001364 if (SemaRef.getLangOptions().CPlusPlus && Results.includeCodePatterns()) {
Douglas Gregor01dfea02010-01-10 23:08:15 +00001365 Pattern = new CodeCompletionString;
1366 Pattern->AddTypedTextChunk("try");
1367 Pattern->AddChunk(CodeCompletionString::CK_LeftBrace);
1368 Pattern->AddPlaceholderChunk("statements");
1369 Pattern->AddChunk(CodeCompletionString::CK_VerticalSpace);
1370 Pattern->AddChunk(CodeCompletionString::CK_RightBrace);
1371 Pattern->AddTextChunk("catch");
1372 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
1373 Pattern->AddPlaceholderChunk("declaration");
1374 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
1375 Pattern->AddChunk(CodeCompletionString::CK_LeftBrace);
1376 Pattern->AddPlaceholderChunk("statements");
1377 Pattern->AddChunk(CodeCompletionString::CK_VerticalSpace);
1378 Pattern->AddChunk(CodeCompletionString::CK_RightBrace);
Douglas Gregora4477812010-01-14 16:01:26 +00001379 Results.AddResult(Result(Pattern));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001380 }
Douglas Gregorb6ac2452010-01-13 21:24:21 +00001381 if (SemaRef.getLangOptions().ObjC1)
Douglas Gregorbca403c2010-01-13 23:51:12 +00001382 AddObjCStatementResults(Results, true);
Douglas Gregorb6ac2452010-01-13 21:24:21 +00001383
Douglas Gregord8e8a582010-05-25 21:41:55 +00001384 if (Results.includeCodePatterns()) {
1385 // if (condition) { statements }
1386 Pattern = new CodeCompletionString;
1387 Pattern->AddTypedTextChunk("if");
1388 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
1389 if (SemaRef.getLangOptions().CPlusPlus)
1390 Pattern->AddPlaceholderChunk("condition");
1391 else
1392 Pattern->AddPlaceholderChunk("expression");
1393 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
1394 Pattern->AddChunk(CodeCompletionString::CK_LeftBrace);
1395 Pattern->AddPlaceholderChunk("statements");
1396 Pattern->AddChunk(CodeCompletionString::CK_VerticalSpace);
1397 Pattern->AddChunk(CodeCompletionString::CK_RightBrace);
1398 Results.AddResult(Result(Pattern));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001399
Douglas Gregord8e8a582010-05-25 21:41:55 +00001400 // switch (condition) { }
1401 Pattern = new CodeCompletionString;
1402 Pattern->AddTypedTextChunk("switch");
1403 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
1404 if (SemaRef.getLangOptions().CPlusPlus)
1405 Pattern->AddPlaceholderChunk("condition");
1406 else
1407 Pattern->AddPlaceholderChunk("expression");
1408 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
1409 Pattern->AddChunk(CodeCompletionString::CK_LeftBrace);
1410 Pattern->AddChunk(CodeCompletionString::CK_VerticalSpace);
1411 Pattern->AddChunk(CodeCompletionString::CK_RightBrace);
1412 Results.AddResult(Result(Pattern));
1413 }
1414
Douglas Gregor01dfea02010-01-10 23:08:15 +00001415 // Switch-specific statements.
John McCall781472f2010-08-25 08:40:02 +00001416 if (!SemaRef.getCurFunction()->SwitchStack.empty()) {
Douglas Gregor01dfea02010-01-10 23:08:15 +00001417 // case expression:
1418 Pattern = new CodeCompletionString;
1419 Pattern->AddTypedTextChunk("case");
Douglas Gregorc8bddde2010-05-28 00:22:41 +00001420 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
Douglas Gregor01dfea02010-01-10 23:08:15 +00001421 Pattern->AddPlaceholderChunk("expression");
1422 Pattern->AddChunk(CodeCompletionString::CK_Colon);
Douglas Gregora4477812010-01-14 16:01:26 +00001423 Results.AddResult(Result(Pattern));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001424
1425 // default:
1426 Pattern = new CodeCompletionString;
1427 Pattern->AddTypedTextChunk("default");
1428 Pattern->AddChunk(CodeCompletionString::CK_Colon);
Douglas Gregora4477812010-01-14 16:01:26 +00001429 Results.AddResult(Result(Pattern));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001430 }
1431
Douglas Gregord8e8a582010-05-25 21:41:55 +00001432 if (Results.includeCodePatterns()) {
1433 /// while (condition) { statements }
1434 Pattern = new CodeCompletionString;
1435 Pattern->AddTypedTextChunk("while");
1436 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
1437 if (SemaRef.getLangOptions().CPlusPlus)
1438 Pattern->AddPlaceholderChunk("condition");
1439 else
1440 Pattern->AddPlaceholderChunk("expression");
1441 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
1442 Pattern->AddChunk(CodeCompletionString::CK_LeftBrace);
1443 Pattern->AddPlaceholderChunk("statements");
1444 Pattern->AddChunk(CodeCompletionString::CK_VerticalSpace);
1445 Pattern->AddChunk(CodeCompletionString::CK_RightBrace);
1446 Results.AddResult(Result(Pattern));
1447
1448 // do { statements } while ( expression );
1449 Pattern = new CodeCompletionString;
1450 Pattern->AddTypedTextChunk("do");
1451 Pattern->AddChunk(CodeCompletionString::CK_LeftBrace);
1452 Pattern->AddPlaceholderChunk("statements");
1453 Pattern->AddChunk(CodeCompletionString::CK_VerticalSpace);
1454 Pattern->AddChunk(CodeCompletionString::CK_RightBrace);
1455 Pattern->AddTextChunk("while");
1456 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
Douglas Gregor01dfea02010-01-10 23:08:15 +00001457 Pattern->AddPlaceholderChunk("expression");
Douglas Gregord8e8a582010-05-25 21:41:55 +00001458 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
1459 Results.AddResult(Result(Pattern));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001460
Douglas Gregord8e8a582010-05-25 21:41:55 +00001461 // for ( for-init-statement ; condition ; expression ) { statements }
1462 Pattern = new CodeCompletionString;
1463 Pattern->AddTypedTextChunk("for");
1464 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
1465 if (SemaRef.getLangOptions().CPlusPlus || SemaRef.getLangOptions().C99)
1466 Pattern->AddPlaceholderChunk("init-statement");
1467 else
1468 Pattern->AddPlaceholderChunk("init-expression");
1469 Pattern->AddChunk(CodeCompletionString::CK_SemiColon);
1470 Pattern->AddPlaceholderChunk("condition");
1471 Pattern->AddChunk(CodeCompletionString::CK_SemiColon);
1472 Pattern->AddPlaceholderChunk("inc-expression");
1473 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
1474 Pattern->AddChunk(CodeCompletionString::CK_LeftBrace);
1475 Pattern->AddPlaceholderChunk("statements");
1476 Pattern->AddChunk(CodeCompletionString::CK_VerticalSpace);
1477 Pattern->AddChunk(CodeCompletionString::CK_RightBrace);
1478 Results.AddResult(Result(Pattern));
1479 }
Douglas Gregor01dfea02010-01-10 23:08:15 +00001480
1481 if (S->getContinueParent()) {
1482 // continue ;
1483 Pattern = new CodeCompletionString;
1484 Pattern->AddTypedTextChunk("continue");
Douglas Gregora4477812010-01-14 16:01:26 +00001485 Results.AddResult(Result(Pattern));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001486 }
1487
1488 if (S->getBreakParent()) {
1489 // break ;
1490 Pattern = new CodeCompletionString;
1491 Pattern->AddTypedTextChunk("break");
Douglas Gregora4477812010-01-14 16:01:26 +00001492 Results.AddResult(Result(Pattern));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001493 }
1494
1495 // "return expression ;" or "return ;", depending on whether we
1496 // know the function is void or not.
1497 bool isVoid = false;
1498 if (FunctionDecl *Function = dyn_cast<FunctionDecl>(SemaRef.CurContext))
1499 isVoid = Function->getResultType()->isVoidType();
1500 else if (ObjCMethodDecl *Method
1501 = dyn_cast<ObjCMethodDecl>(SemaRef.CurContext))
1502 isVoid = Method->getResultType()->isVoidType();
Douglas Gregor9ea9bdb2010-03-01 23:15:13 +00001503 else if (SemaRef.getCurBlock() &&
1504 !SemaRef.getCurBlock()->ReturnType.isNull())
1505 isVoid = SemaRef.getCurBlock()->ReturnType->isVoidType();
Douglas Gregor01dfea02010-01-10 23:08:15 +00001506 Pattern = new CodeCompletionString;
1507 Pattern->AddTypedTextChunk("return");
Douglas Gregor93298002010-02-18 04:06:48 +00001508 if (!isVoid) {
1509 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
Douglas Gregor01dfea02010-01-10 23:08:15 +00001510 Pattern->AddPlaceholderChunk("expression");
Douglas Gregor93298002010-02-18 04:06:48 +00001511 }
Douglas Gregora4477812010-01-14 16:01:26 +00001512 Results.AddResult(Result(Pattern));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001513
Douglas Gregorc8bddde2010-05-28 00:22:41 +00001514 // goto identifier ;
1515 Pattern = new CodeCompletionString;
1516 Pattern->AddTypedTextChunk("goto");
1517 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
1518 Pattern->AddPlaceholderChunk("label");
1519 Results.AddResult(Result(Pattern));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001520
Douglas Gregorc8bddde2010-05-28 00:22:41 +00001521 // Using directives
1522 Pattern = new CodeCompletionString;
1523 Pattern->AddTypedTextChunk("using");
1524 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
1525 Pattern->AddTextChunk("namespace");
1526 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
1527 Pattern->AddPlaceholderChunk("identifier");
1528 Results.AddResult(Result(Pattern));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001529 }
1530
1531 // Fall through (for statement expressions).
John McCallf312b1e2010-08-26 23:41:50 +00001532 case Sema::PCC_ForInit:
1533 case Sema::PCC_Condition:
Douglas Gregorbca403c2010-01-13 23:51:12 +00001534 AddStorageSpecifiers(CCC, SemaRef.getLangOptions(), Results);
Douglas Gregor01dfea02010-01-10 23:08:15 +00001535 // Fall through: conditions and statements can have expressions.
1536
John McCallf312b1e2010-08-26 23:41:50 +00001537 case Sema::PCC_Expression: {
Douglas Gregor01dfea02010-01-10 23:08:15 +00001538 CodeCompletionString *Pattern = 0;
1539 if (SemaRef.getLangOptions().CPlusPlus) {
1540 // 'this', if we're in a non-static member function.
1541 if (CXXMethodDecl *Method = dyn_cast<CXXMethodDecl>(SemaRef.CurContext))
1542 if (!Method->isStatic())
Douglas Gregora4477812010-01-14 16:01:26 +00001543 Results.AddResult(Result("this"));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001544
1545 // true, false
Douglas Gregora4477812010-01-14 16:01:26 +00001546 Results.AddResult(Result("true"));
1547 Results.AddResult(Result("false"));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001548
Douglas Gregorc8bddde2010-05-28 00:22:41 +00001549 // dynamic_cast < type-id > ( expression )
1550 Pattern = new CodeCompletionString;
1551 Pattern->AddTypedTextChunk("dynamic_cast");
1552 Pattern->AddChunk(CodeCompletionString::CK_LeftAngle);
1553 Pattern->AddPlaceholderChunk("type");
1554 Pattern->AddChunk(CodeCompletionString::CK_RightAngle);
1555 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
1556 Pattern->AddPlaceholderChunk("expression");
1557 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
1558 Results.AddResult(Result(Pattern));
1559
1560 // static_cast < type-id > ( expression )
1561 Pattern = new CodeCompletionString;
1562 Pattern->AddTypedTextChunk("static_cast");
1563 Pattern->AddChunk(CodeCompletionString::CK_LeftAngle);
1564 Pattern->AddPlaceholderChunk("type");
1565 Pattern->AddChunk(CodeCompletionString::CK_RightAngle);
1566 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
1567 Pattern->AddPlaceholderChunk("expression");
1568 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
1569 Results.AddResult(Result(Pattern));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001570
Douglas Gregorc8bddde2010-05-28 00:22:41 +00001571 // reinterpret_cast < type-id > ( expression )
1572 Pattern = new CodeCompletionString;
1573 Pattern->AddTypedTextChunk("reinterpret_cast");
1574 Pattern->AddChunk(CodeCompletionString::CK_LeftAngle);
1575 Pattern->AddPlaceholderChunk("type");
1576 Pattern->AddChunk(CodeCompletionString::CK_RightAngle);
1577 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
1578 Pattern->AddPlaceholderChunk("expression");
1579 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
1580 Results.AddResult(Result(Pattern));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001581
Douglas Gregorc8bddde2010-05-28 00:22:41 +00001582 // const_cast < type-id > ( expression )
1583 Pattern = new CodeCompletionString;
1584 Pattern->AddTypedTextChunk("const_cast");
1585 Pattern->AddChunk(CodeCompletionString::CK_LeftAngle);
1586 Pattern->AddPlaceholderChunk("type");
1587 Pattern->AddChunk(CodeCompletionString::CK_RightAngle);
1588 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
1589 Pattern->AddPlaceholderChunk("expression");
1590 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
1591 Results.AddResult(Result(Pattern));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001592
Douglas Gregorc8bddde2010-05-28 00:22:41 +00001593 // typeid ( expression-or-type )
1594 Pattern = new CodeCompletionString;
1595 Pattern->AddTypedTextChunk("typeid");
1596 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
1597 Pattern->AddPlaceholderChunk("expression-or-type");
1598 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
1599 Results.AddResult(Result(Pattern));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001600
Douglas Gregorc8bddde2010-05-28 00:22:41 +00001601 // new T ( ... )
1602 Pattern = new CodeCompletionString;
1603 Pattern->AddTypedTextChunk("new");
1604 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
1605 Pattern->AddPlaceholderChunk("type");
1606 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
1607 Pattern->AddPlaceholderChunk("expressions");
1608 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
1609 Results.AddResult(Result(Pattern));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001610
Douglas Gregorc8bddde2010-05-28 00:22:41 +00001611 // new T [ ] ( ... )
1612 Pattern = new CodeCompletionString;
1613 Pattern->AddTypedTextChunk("new");
1614 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
1615 Pattern->AddPlaceholderChunk("type");
1616 Pattern->AddChunk(CodeCompletionString::CK_LeftBracket);
1617 Pattern->AddPlaceholderChunk("size");
1618 Pattern->AddChunk(CodeCompletionString::CK_RightBracket);
1619 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
1620 Pattern->AddPlaceholderChunk("expressions");
1621 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
1622 Results.AddResult(Result(Pattern));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001623
Douglas Gregorc8bddde2010-05-28 00:22:41 +00001624 // delete expression
1625 Pattern = new CodeCompletionString;
1626 Pattern->AddTypedTextChunk("delete");
1627 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
1628 Pattern->AddPlaceholderChunk("expression");
1629 Results.AddResult(Result(Pattern));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001630
Douglas Gregorc8bddde2010-05-28 00:22:41 +00001631 // delete [] expression
1632 Pattern = new CodeCompletionString;
1633 Pattern->AddTypedTextChunk("delete");
1634 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
1635 Pattern->AddChunk(CodeCompletionString::CK_LeftBracket);
1636 Pattern->AddChunk(CodeCompletionString::CK_RightBracket);
1637 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
1638 Pattern->AddPlaceholderChunk("expression");
1639 Results.AddResult(Result(Pattern));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001640
Douglas Gregorc8bddde2010-05-28 00:22:41 +00001641 // throw expression
1642 Pattern = new CodeCompletionString;
1643 Pattern->AddTypedTextChunk("throw");
1644 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
1645 Pattern->AddPlaceholderChunk("expression");
1646 Results.AddResult(Result(Pattern));
Douglas Gregor12e13132010-05-26 22:00:08 +00001647
1648 // FIXME: Rethrow?
Douglas Gregor01dfea02010-01-10 23:08:15 +00001649 }
1650
1651 if (SemaRef.getLangOptions().ObjC1) {
1652 // Add "super", if we're in an Objective-C class with a superclass.
Ted Kremenek681e2562010-05-31 21:43:10 +00001653 if (ObjCMethodDecl *Method = SemaRef.getCurMethodDecl()) {
1654 // The interface can be NULL.
1655 if (ObjCInterfaceDecl *ID = Method->getClassInterface())
1656 if (ID->getSuperClass())
1657 Results.AddResult(Result("super"));
1658 }
1659
Douglas Gregorbca403c2010-01-13 23:51:12 +00001660 AddObjCExpressionResults(Results, true);
Douglas Gregor01dfea02010-01-10 23:08:15 +00001661 }
1662
Douglas Gregorc8bddde2010-05-28 00:22:41 +00001663 // sizeof expression
1664 Pattern = new CodeCompletionString;
1665 Pattern->AddTypedTextChunk("sizeof");
1666 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
1667 Pattern->AddPlaceholderChunk("expression-or-type");
1668 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
1669 Results.AddResult(Result(Pattern));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001670 break;
1671 }
Douglas Gregord32b0222010-08-24 01:06:58 +00001672
John McCallf312b1e2010-08-26 23:41:50 +00001673 case Sema::PCC_Type:
Douglas Gregord32b0222010-08-24 01:06:58 +00001674 break;
Douglas Gregor01dfea02010-01-10 23:08:15 +00001675 }
1676
Douglas Gregor4710e5b2010-05-28 00:49:12 +00001677 if (WantTypesInContext(CCC, SemaRef.getLangOptions()))
1678 AddTypeSpecifierResults(SemaRef.getLangOptions(), Results);
Douglas Gregor01dfea02010-01-10 23:08:15 +00001679
John McCallf312b1e2010-08-26 23:41:50 +00001680 if (SemaRef.getLangOptions().CPlusPlus && CCC != Sema::PCC_Type)
Douglas Gregora4477812010-01-14 16:01:26 +00001681 Results.AddResult(Result("operator"));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001682}
1683
Douglas Gregorff5ce6e2009-12-18 18:53:37 +00001684/// \brief If the given declaration has an associated type, add it as a result
1685/// type chunk.
1686static void AddResultTypeChunk(ASTContext &Context,
1687 NamedDecl *ND,
1688 CodeCompletionString *Result) {
1689 if (!ND)
1690 return;
1691
1692 // Determine the type of the declaration (if it has a type).
1693 QualType T;
1694 if (FunctionDecl *Function = dyn_cast<FunctionDecl>(ND))
1695 T = Function->getResultType();
1696 else if (ObjCMethodDecl *Method = dyn_cast<ObjCMethodDecl>(ND))
1697 T = Method->getResultType();
1698 else if (FunctionTemplateDecl *FunTmpl = dyn_cast<FunctionTemplateDecl>(ND))
1699 T = FunTmpl->getTemplatedDecl()->getResultType();
1700 else if (EnumConstantDecl *Enumerator = dyn_cast<EnumConstantDecl>(ND))
1701 T = Context.getTypeDeclType(cast<TypeDecl>(Enumerator->getDeclContext()));
1702 else if (isa<UnresolvedUsingValueDecl>(ND)) {
1703 /* Do nothing: ignore unresolved using declarations*/
1704 } else if (ValueDecl *Value = dyn_cast<ValueDecl>(ND))
1705 T = Value->getType();
1706 else if (ObjCPropertyDecl *Property = dyn_cast<ObjCPropertyDecl>(ND))
1707 T = Property->getType();
1708
1709 if (T.isNull() || Context.hasSameType(T, Context.DependentTy))
1710 return;
1711
Douglas Gregor84139d62010-04-05 21:25:31 +00001712 PrintingPolicy Policy(Context.PrintingPolicy);
1713 Policy.AnonymousTagLocations = false;
1714
Douglas Gregorff5ce6e2009-12-18 18:53:37 +00001715 std::string TypeStr;
Douglas Gregor84139d62010-04-05 21:25:31 +00001716 T.getAsStringInternal(TypeStr, Policy);
Douglas Gregorff5ce6e2009-12-18 18:53:37 +00001717 Result->AddResultTypeChunk(TypeStr);
1718}
1719
Douglas Gregoraaa107a2010-08-23 23:51:41 +00001720static void MaybeAddSentinel(ASTContext &Context, NamedDecl *FunctionOrMethod,
1721 CodeCompletionString *Result) {
1722 if (SentinelAttr *Sentinel = FunctionOrMethod->getAttr<SentinelAttr>())
1723 if (Sentinel->getSentinel() == 0) {
1724 if (Context.getLangOptions().ObjC1 &&
1725 Context.Idents.get("nil").hasMacroDefinition())
1726 Result->AddTextChunk(", nil");
1727 else if (Context.Idents.get("NULL").hasMacroDefinition())
1728 Result->AddTextChunk(", NULL");
1729 else
1730 Result->AddTextChunk(", (void*)0");
1731 }
1732}
1733
Douglas Gregor83482d12010-08-24 16:15:59 +00001734static std::string FormatFunctionParameter(ASTContext &Context,
1735 ParmVarDecl *Param) {
1736 bool ObjCMethodParam = isa<ObjCMethodDecl>(Param->getDeclContext());
1737 if (Param->getType()->isDependentType() ||
1738 !Param->getType()->isBlockPointerType()) {
1739 // The argument for a dependent or non-block parameter is a placeholder
1740 // containing that parameter's type.
1741 std::string Result;
1742
1743 if (Param->getIdentifier() && !ObjCMethodParam)
1744 Result = Param->getIdentifier()->getName();
1745
1746 Param->getType().getAsStringInternal(Result,
1747 Context.PrintingPolicy);
1748
1749 if (ObjCMethodParam) {
1750 Result = "(" + Result;
1751 Result += ")";
1752 if (Param->getIdentifier())
1753 Result += Param->getIdentifier()->getName();
1754 }
1755 return Result;
1756 }
1757
1758 // The argument for a block pointer parameter is a block literal with
1759 // the appropriate type.
1760 FunctionProtoTypeLoc *Block = 0;
1761 TypeLoc TL;
1762 if (TypeSourceInfo *TSInfo = Param->getTypeSourceInfo()) {
1763 TL = TSInfo->getTypeLoc().getUnqualifiedLoc();
1764 while (true) {
1765 // Look through typedefs.
1766 if (TypedefTypeLoc *TypedefTL = dyn_cast<TypedefTypeLoc>(&TL)) {
1767 if (TypeSourceInfo *InnerTSInfo
1768 = TypedefTL->getTypedefDecl()->getTypeSourceInfo()) {
1769 TL = InnerTSInfo->getTypeLoc().getUnqualifiedLoc();
1770 continue;
1771 }
1772 }
1773
1774 // Look through qualified types
1775 if (QualifiedTypeLoc *QualifiedTL = dyn_cast<QualifiedTypeLoc>(&TL)) {
1776 TL = QualifiedTL->getUnqualifiedLoc();
1777 continue;
1778 }
1779
1780 // Try to get the function prototype behind the block pointer type,
1781 // then we're done.
1782 if (BlockPointerTypeLoc *BlockPtr
1783 = dyn_cast<BlockPointerTypeLoc>(&TL)) {
1784 TL = BlockPtr->getPointeeLoc();
1785 Block = dyn_cast<FunctionProtoTypeLoc>(&TL);
1786 }
1787 break;
1788 }
1789 }
1790
1791 if (!Block) {
1792 // We were unable to find a FunctionProtoTypeLoc with parameter names
1793 // for the block; just use the parameter type as a placeholder.
1794 std::string Result;
1795 Param->getType().getUnqualifiedType().
1796 getAsStringInternal(Result, Context.PrintingPolicy);
1797
1798 if (ObjCMethodParam) {
1799 Result = "(" + Result;
1800 Result += ")";
1801 if (Param->getIdentifier())
1802 Result += Param->getIdentifier()->getName();
1803 }
1804
1805 return Result;
1806 }
1807
1808 // We have the function prototype behind the block pointer type, as it was
1809 // written in the source.
1810 std::string Result = "(^)(";
1811 for (unsigned I = 0, N = Block->getNumArgs(); I != N; ++I) {
1812 if (I)
1813 Result += ", ";
1814 Result += FormatFunctionParameter(Context, Block->getArg(I));
1815 }
1816 if (Block->getTypePtr()->isVariadic()) {
1817 if (Block->getNumArgs() > 0)
1818 Result += ", ...";
1819 else
1820 Result += "...";
1821 } else if (Block->getNumArgs() == 0 && !Context.getLangOptions().CPlusPlus)
1822 Result += "void";
1823
1824 Result += ")";
1825 Block->getTypePtr()->getResultType().getAsStringInternal(Result,
1826 Context.PrintingPolicy);
1827 return Result;
1828}
1829
Douglas Gregor86d9a522009-09-21 16:56:56 +00001830/// \brief Add function parameter chunks to the given code completion string.
1831static void AddFunctionParameterChunks(ASTContext &Context,
1832 FunctionDecl *Function,
1833 CodeCompletionString *Result) {
Douglas Gregor0c8296d2009-11-07 00:00:49 +00001834 typedef CodeCompletionString::Chunk Chunk;
1835
Douglas Gregor86d9a522009-09-21 16:56:56 +00001836 CodeCompletionString *CCStr = Result;
1837
1838 for (unsigned P = 0, N = Function->getNumParams(); P != N; ++P) {
1839 ParmVarDecl *Param = Function->getParamDecl(P);
1840
1841 if (Param->hasDefaultArg()) {
1842 // When we see an optional default argument, put that argument and
1843 // the remaining default arguments into a new, optional string.
1844 CodeCompletionString *Opt = new CodeCompletionString;
1845 CCStr->AddOptionalChunk(std::auto_ptr<CodeCompletionString>(Opt));
1846 CCStr = Opt;
1847 }
1848
1849 if (P != 0)
Douglas Gregor0c8296d2009-11-07 00:00:49 +00001850 CCStr->AddChunk(Chunk(CodeCompletionString::CK_Comma));
Douglas Gregor86d9a522009-09-21 16:56:56 +00001851
1852 // Format the placeholder string.
Douglas Gregor83482d12010-08-24 16:15:59 +00001853 std::string PlaceholderStr = FormatFunctionParameter(Context, Param);
1854
Douglas Gregor86d9a522009-09-21 16:56:56 +00001855 // Add the placeholder string.
Benjamin Kramer660cc182009-11-29 20:18:50 +00001856 CCStr->AddPlaceholderChunk(PlaceholderStr);
Douglas Gregor86d9a522009-09-21 16:56:56 +00001857 }
Douglas Gregorb3d45252009-09-22 21:42:17 +00001858
1859 if (const FunctionProtoType *Proto
1860 = Function->getType()->getAs<FunctionProtoType>())
Douglas Gregoraaa107a2010-08-23 23:51:41 +00001861 if (Proto->isVariadic()) {
Douglas Gregorb3d45252009-09-22 21:42:17 +00001862 CCStr->AddPlaceholderChunk(", ...");
Douglas Gregoraaa107a2010-08-23 23:51:41 +00001863
1864 MaybeAddSentinel(Context, Function, CCStr);
1865 }
Douglas Gregor86d9a522009-09-21 16:56:56 +00001866}
1867
1868/// \brief Add template parameter chunks to the given code completion string.
1869static void AddTemplateParameterChunks(ASTContext &Context,
1870 TemplateDecl *Template,
1871 CodeCompletionString *Result,
1872 unsigned MaxParameters = 0) {
Douglas Gregor0c8296d2009-11-07 00:00:49 +00001873 typedef CodeCompletionString::Chunk Chunk;
1874
Douglas Gregor86d9a522009-09-21 16:56:56 +00001875 CodeCompletionString *CCStr = Result;
1876 bool FirstParameter = true;
1877
1878 TemplateParameterList *Params = Template->getTemplateParameters();
1879 TemplateParameterList::iterator PEnd = Params->end();
1880 if (MaxParameters)
1881 PEnd = Params->begin() + MaxParameters;
1882 for (TemplateParameterList::iterator P = Params->begin(); P != PEnd; ++P) {
1883 bool HasDefaultArg = false;
1884 std::string PlaceholderStr;
1885 if (TemplateTypeParmDecl *TTP = dyn_cast<TemplateTypeParmDecl>(*P)) {
1886 if (TTP->wasDeclaredWithTypename())
1887 PlaceholderStr = "typename";
1888 else
1889 PlaceholderStr = "class";
1890
1891 if (TTP->getIdentifier()) {
1892 PlaceholderStr += ' ';
1893 PlaceholderStr += TTP->getIdentifier()->getName();
1894 }
1895
1896 HasDefaultArg = TTP->hasDefaultArgument();
1897 } else if (NonTypeTemplateParmDecl *NTTP
1898 = dyn_cast<NonTypeTemplateParmDecl>(*P)) {
1899 if (NTTP->getIdentifier())
1900 PlaceholderStr = NTTP->getIdentifier()->getName();
1901 NTTP->getType().getAsStringInternal(PlaceholderStr,
1902 Context.PrintingPolicy);
1903 HasDefaultArg = NTTP->hasDefaultArgument();
1904 } else {
1905 assert(isa<TemplateTemplateParmDecl>(*P));
1906 TemplateTemplateParmDecl *TTP = cast<TemplateTemplateParmDecl>(*P);
1907
1908 // Since putting the template argument list into the placeholder would
1909 // be very, very long, we just use an abbreviation.
1910 PlaceholderStr = "template<...> class";
1911 if (TTP->getIdentifier()) {
1912 PlaceholderStr += ' ';
1913 PlaceholderStr += TTP->getIdentifier()->getName();
1914 }
1915
1916 HasDefaultArg = TTP->hasDefaultArgument();
1917 }
1918
1919 if (HasDefaultArg) {
1920 // When we see an optional default argument, put that argument and
1921 // the remaining default arguments into a new, optional string.
1922 CodeCompletionString *Opt = new CodeCompletionString;
1923 CCStr->AddOptionalChunk(std::auto_ptr<CodeCompletionString>(Opt));
1924 CCStr = Opt;
1925 }
1926
1927 if (FirstParameter)
1928 FirstParameter = false;
1929 else
Douglas Gregor0c8296d2009-11-07 00:00:49 +00001930 CCStr->AddChunk(Chunk(CodeCompletionString::CK_Comma));
Douglas Gregor86d9a522009-09-21 16:56:56 +00001931
1932 // Add the placeholder string.
Benjamin Kramer660cc182009-11-29 20:18:50 +00001933 CCStr->AddPlaceholderChunk(PlaceholderStr);
Douglas Gregor86d9a522009-09-21 16:56:56 +00001934 }
1935}
1936
Douglas Gregorb9d0ef72009-09-21 19:57:38 +00001937/// \brief Add a qualifier to the given code-completion string, if the
1938/// provided nested-name-specifier is non-NULL.
Douglas Gregora61a8792009-12-11 18:44:16 +00001939static void
1940AddQualifierToCompletionString(CodeCompletionString *Result,
1941 NestedNameSpecifier *Qualifier,
1942 bool QualifierIsInformative,
1943 ASTContext &Context) {
Douglas Gregorb9d0ef72009-09-21 19:57:38 +00001944 if (!Qualifier)
1945 return;
1946
1947 std::string PrintedNNS;
1948 {
1949 llvm::raw_string_ostream OS(PrintedNNS);
1950 Qualifier->print(OS, Context.PrintingPolicy);
1951 }
Douglas Gregor0563c262009-09-22 23:15:58 +00001952 if (QualifierIsInformative)
Benjamin Kramer660cc182009-11-29 20:18:50 +00001953 Result->AddInformativeChunk(PrintedNNS);
Douglas Gregor0563c262009-09-22 23:15:58 +00001954 else
Benjamin Kramer660cc182009-11-29 20:18:50 +00001955 Result->AddTextChunk(PrintedNNS);
Douglas Gregorb9d0ef72009-09-21 19:57:38 +00001956}
1957
Douglas Gregora61a8792009-12-11 18:44:16 +00001958static void AddFunctionTypeQualsToCompletionString(CodeCompletionString *Result,
1959 FunctionDecl *Function) {
1960 const FunctionProtoType *Proto
1961 = Function->getType()->getAs<FunctionProtoType>();
1962 if (!Proto || !Proto->getTypeQuals())
1963 return;
1964
1965 std::string QualsStr;
1966 if (Proto->getTypeQuals() & Qualifiers::Const)
1967 QualsStr += " const";
1968 if (Proto->getTypeQuals() & Qualifiers::Volatile)
1969 QualsStr += " volatile";
1970 if (Proto->getTypeQuals() & Qualifiers::Restrict)
1971 QualsStr += " restrict";
1972 Result->AddInformativeChunk(QualsStr);
1973}
1974
Douglas Gregor86d9a522009-09-21 16:56:56 +00001975/// \brief If possible, create a new code completion string for the given
1976/// result.
1977///
1978/// \returns Either a new, heap-allocated code completion string describing
1979/// how to use this result, or NULL to indicate that the string or name of the
1980/// result is all that is needed.
1981CodeCompletionString *
John McCall0a2c5e22010-08-25 06:19:51 +00001982CodeCompletionResult::CreateCodeCompletionString(Sema &S,
Douglas Gregor1abc6bc2010-08-04 16:47:14 +00001983 CodeCompletionString *Result) {
Douglas Gregor0c8296d2009-11-07 00:00:49 +00001984 typedef CodeCompletionString::Chunk Chunk;
1985
Douglas Gregor2b4074f2009-12-01 05:55:20 +00001986 if (Kind == RK_Pattern)
Douglas Gregor1abc6bc2010-08-04 16:47:14 +00001987 return Pattern->Clone(Result);
Douglas Gregor2b4074f2009-12-01 05:55:20 +00001988
Douglas Gregor1abc6bc2010-08-04 16:47:14 +00001989 if (!Result)
1990 Result = new CodeCompletionString;
Douglas Gregor2b4074f2009-12-01 05:55:20 +00001991
1992 if (Kind == RK_Keyword) {
1993 Result->AddTypedTextChunk(Keyword);
1994 return Result;
1995 }
Douglas Gregor86d9a522009-09-21 16:56:56 +00001996
Douglas Gregor3f7c7f42009-10-30 16:50:04 +00001997 if (Kind == RK_Macro) {
1998 MacroInfo *MI = S.PP.getMacroInfo(Macro);
Douglas Gregor2b4074f2009-12-01 05:55:20 +00001999 assert(MI && "Not a macro?");
2000
2001 Result->AddTypedTextChunk(Macro->getName());
2002
2003 if (!MI->isFunctionLike())
2004 return Result;
Douglas Gregor3f7c7f42009-10-30 16:50:04 +00002005
2006 // Format a function-like macro with placeholders for the arguments.
Douglas Gregor0c8296d2009-11-07 00:00:49 +00002007 Result->AddChunk(Chunk(CodeCompletionString::CK_LeftParen));
Douglas Gregor3f7c7f42009-10-30 16:50:04 +00002008 for (MacroInfo::arg_iterator A = MI->arg_begin(), AEnd = MI->arg_end();
2009 A != AEnd; ++A) {
2010 if (A != MI->arg_begin())
Douglas Gregor0c8296d2009-11-07 00:00:49 +00002011 Result->AddChunk(Chunk(CodeCompletionString::CK_Comma));
Douglas Gregor3f7c7f42009-10-30 16:50:04 +00002012
2013 if (!MI->isVariadic() || A != AEnd - 1) {
2014 // Non-variadic argument.
Benjamin Kramer660cc182009-11-29 20:18:50 +00002015 Result->AddPlaceholderChunk((*A)->getName());
Douglas Gregor3f7c7f42009-10-30 16:50:04 +00002016 continue;
2017 }
2018
2019 // Variadic argument; cope with the different between GNU and C99
2020 // variadic macros, providing a single placeholder for the rest of the
2021 // arguments.
2022 if ((*A)->isStr("__VA_ARGS__"))
2023 Result->AddPlaceholderChunk("...");
2024 else {
2025 std::string Arg = (*A)->getName();
2026 Arg += "...";
Benjamin Kramer660cc182009-11-29 20:18:50 +00002027 Result->AddPlaceholderChunk(Arg);
Douglas Gregor3f7c7f42009-10-30 16:50:04 +00002028 }
2029 }
Douglas Gregor0c8296d2009-11-07 00:00:49 +00002030 Result->AddChunk(Chunk(CodeCompletionString::CK_RightParen));
Douglas Gregor3f7c7f42009-10-30 16:50:04 +00002031 return Result;
2032 }
2033
Douglas Gregord8e8a582010-05-25 21:41:55 +00002034 assert(Kind == RK_Declaration && "Missed a result kind?");
Douglas Gregor86d9a522009-09-21 16:56:56 +00002035 NamedDecl *ND = Declaration;
2036
Douglas Gregor0c8296d2009-11-07 00:00:49 +00002037 if (StartsNestedNameSpecifier) {
Benjamin Kramer660cc182009-11-29 20:18:50 +00002038 Result->AddTypedTextChunk(ND->getNameAsString());
Douglas Gregor0c8296d2009-11-07 00:00:49 +00002039 Result->AddTextChunk("::");
2040 return Result;
2041 }
2042
Douglas Gregorff5ce6e2009-12-18 18:53:37 +00002043 AddResultTypeChunk(S.Context, ND, Result);
2044
Douglas Gregor86d9a522009-09-21 16:56:56 +00002045 if (FunctionDecl *Function = dyn_cast<FunctionDecl>(ND)) {
Douglas Gregor0563c262009-09-22 23:15:58 +00002046 AddQualifierToCompletionString(Result, Qualifier, QualifierIsInformative,
2047 S.Context);
Benjamin Kramer660cc182009-11-29 20:18:50 +00002048 Result->AddTypedTextChunk(Function->getNameAsString());
Douglas Gregor0c8296d2009-11-07 00:00:49 +00002049 Result->AddChunk(Chunk(CodeCompletionString::CK_LeftParen));
Douglas Gregor86d9a522009-09-21 16:56:56 +00002050 AddFunctionParameterChunks(S.Context, Function, Result);
Douglas Gregor0c8296d2009-11-07 00:00:49 +00002051 Result->AddChunk(Chunk(CodeCompletionString::CK_RightParen));
Douglas Gregora61a8792009-12-11 18:44:16 +00002052 AddFunctionTypeQualsToCompletionString(Result, Function);
Douglas Gregor86d9a522009-09-21 16:56:56 +00002053 return Result;
2054 }
2055
2056 if (FunctionTemplateDecl *FunTmpl = dyn_cast<FunctionTemplateDecl>(ND)) {
Douglas Gregor0563c262009-09-22 23:15:58 +00002057 AddQualifierToCompletionString(Result, Qualifier, QualifierIsInformative,
2058 S.Context);
Douglas Gregor86d9a522009-09-21 16:56:56 +00002059 FunctionDecl *Function = FunTmpl->getTemplatedDecl();
Benjamin Kramer660cc182009-11-29 20:18:50 +00002060 Result->AddTypedTextChunk(Function->getNameAsString());
Douglas Gregor86d9a522009-09-21 16:56:56 +00002061
2062 // Figure out which template parameters are deduced (or have default
2063 // arguments).
2064 llvm::SmallVector<bool, 16> Deduced;
2065 S.MarkDeducedTemplateParameters(FunTmpl, Deduced);
2066 unsigned LastDeducibleArgument;
2067 for (LastDeducibleArgument = Deduced.size(); LastDeducibleArgument > 0;
2068 --LastDeducibleArgument) {
2069 if (!Deduced[LastDeducibleArgument - 1]) {
2070 // C++0x: Figure out if the template argument has a default. If so,
2071 // the user doesn't need to type this argument.
2072 // FIXME: We need to abstract template parameters better!
2073 bool HasDefaultArg = false;
2074 NamedDecl *Param = FunTmpl->getTemplateParameters()->getParam(
2075 LastDeducibleArgument - 1);
2076 if (TemplateTypeParmDecl *TTP = dyn_cast<TemplateTypeParmDecl>(Param))
2077 HasDefaultArg = TTP->hasDefaultArgument();
2078 else if (NonTypeTemplateParmDecl *NTTP
2079 = dyn_cast<NonTypeTemplateParmDecl>(Param))
2080 HasDefaultArg = NTTP->hasDefaultArgument();
2081 else {
2082 assert(isa<TemplateTemplateParmDecl>(Param));
2083 HasDefaultArg
Douglas Gregor0c8296d2009-11-07 00:00:49 +00002084 = cast<TemplateTemplateParmDecl>(Param)->hasDefaultArgument();
Douglas Gregor86d9a522009-09-21 16:56:56 +00002085 }
2086
2087 if (!HasDefaultArg)
2088 break;
2089 }
2090 }
2091
2092 if (LastDeducibleArgument) {
2093 // Some of the function template arguments cannot be deduced from a
2094 // function call, so we introduce an explicit template argument list
2095 // containing all of the arguments up to the first deducible argument.
Douglas Gregor0c8296d2009-11-07 00:00:49 +00002096 Result->AddChunk(Chunk(CodeCompletionString::CK_LeftAngle));
Douglas Gregor86d9a522009-09-21 16:56:56 +00002097 AddTemplateParameterChunks(S.Context, FunTmpl, Result,
2098 LastDeducibleArgument);
Douglas Gregor0c8296d2009-11-07 00:00:49 +00002099 Result->AddChunk(Chunk(CodeCompletionString::CK_RightAngle));
Douglas Gregor86d9a522009-09-21 16:56:56 +00002100 }
2101
2102 // Add the function parameters
Douglas Gregor0c8296d2009-11-07 00:00:49 +00002103 Result->AddChunk(Chunk(CodeCompletionString::CK_LeftParen));
Douglas Gregor86d9a522009-09-21 16:56:56 +00002104 AddFunctionParameterChunks(S.Context, Function, Result);
Douglas Gregor0c8296d2009-11-07 00:00:49 +00002105 Result->AddChunk(Chunk(CodeCompletionString::CK_RightParen));
Douglas Gregora61a8792009-12-11 18:44:16 +00002106 AddFunctionTypeQualsToCompletionString(Result, Function);
Douglas Gregor86d9a522009-09-21 16:56:56 +00002107 return Result;
2108 }
2109
2110 if (TemplateDecl *Template = dyn_cast<TemplateDecl>(ND)) {
Douglas Gregor0563c262009-09-22 23:15:58 +00002111 AddQualifierToCompletionString(Result, Qualifier, QualifierIsInformative,
2112 S.Context);
Benjamin Kramer660cc182009-11-29 20:18:50 +00002113 Result->AddTypedTextChunk(Template->getNameAsString());
Douglas Gregor0c8296d2009-11-07 00:00:49 +00002114 Result->AddChunk(Chunk(CodeCompletionString::CK_LeftAngle));
Douglas Gregor86d9a522009-09-21 16:56:56 +00002115 AddTemplateParameterChunks(S.Context, Template, Result);
Douglas Gregor0c8296d2009-11-07 00:00:49 +00002116 Result->AddChunk(Chunk(CodeCompletionString::CK_RightAngle));
Douglas Gregor86d9a522009-09-21 16:56:56 +00002117 return Result;
2118 }
2119
Douglas Gregor9630eb62009-11-17 16:44:22 +00002120 if (ObjCMethodDecl *Method = dyn_cast<ObjCMethodDecl>(ND)) {
Douglas Gregor9630eb62009-11-17 16:44:22 +00002121 Selector Sel = Method->getSelector();
2122 if (Sel.isUnarySelector()) {
2123 Result->AddTypedTextChunk(Sel.getIdentifierInfoForSlot(0)->getName());
2124 return Result;
2125 }
2126
Douglas Gregord3c68542009-11-19 01:08:35 +00002127 std::string SelName = Sel.getIdentifierInfoForSlot(0)->getName().str();
2128 SelName += ':';
2129 if (StartParameter == 0)
2130 Result->AddTypedTextChunk(SelName);
2131 else {
2132 Result->AddInformativeChunk(SelName);
2133
2134 // If there is only one parameter, and we're past it, add an empty
2135 // typed-text chunk since there is nothing to type.
2136 if (Method->param_size() == 1)
2137 Result->AddTypedTextChunk("");
2138 }
Douglas Gregor9630eb62009-11-17 16:44:22 +00002139 unsigned Idx = 0;
2140 for (ObjCMethodDecl::param_iterator P = Method->param_begin(),
2141 PEnd = Method->param_end();
2142 P != PEnd; (void)++P, ++Idx) {
2143 if (Idx > 0) {
Douglas Gregord3c68542009-11-19 01:08:35 +00002144 std::string Keyword;
2145 if (Idx > StartParameter)
Douglas Gregor834389b2010-01-12 06:38:28 +00002146 Result->AddChunk(CodeCompletionString::CK_HorizontalSpace);
Douglas Gregor9630eb62009-11-17 16:44:22 +00002147 if (IdentifierInfo *II = Sel.getIdentifierInfoForSlot(Idx))
2148 Keyword += II->getName().str();
2149 Keyword += ":";
Douglas Gregor1f5537a2010-07-08 23:20:03 +00002150 if (Idx < StartParameter || AllParametersAreInformative)
Douglas Gregord3c68542009-11-19 01:08:35 +00002151 Result->AddInformativeChunk(Keyword);
Douglas Gregor1f5537a2010-07-08 23:20:03 +00002152 else if (Idx == StartParameter)
Douglas Gregord3c68542009-11-19 01:08:35 +00002153 Result->AddTypedTextChunk(Keyword);
2154 else
2155 Result->AddTextChunk(Keyword);
Douglas Gregor9630eb62009-11-17 16:44:22 +00002156 }
Douglas Gregord3c68542009-11-19 01:08:35 +00002157
2158 // If we're before the starting parameter, skip the placeholder.
2159 if (Idx < StartParameter)
2160 continue;
Douglas Gregor9630eb62009-11-17 16:44:22 +00002161
2162 std::string Arg;
Douglas Gregor83482d12010-08-24 16:15:59 +00002163
2164 if ((*P)->getType()->isBlockPointerType() && !DeclaringEntity)
2165 Arg = FormatFunctionParameter(S.Context, *P);
2166 else {
2167 (*P)->getType().getAsStringInternal(Arg, S.Context.PrintingPolicy);
2168 Arg = "(" + Arg + ")";
2169 if (IdentifierInfo *II = (*P)->getIdentifier())
2170 Arg += II->getName().str();
2171 }
2172
Douglas Gregor1f5537a2010-07-08 23:20:03 +00002173 if (DeclaringEntity)
2174 Result->AddTextChunk(Arg);
2175 else if (AllParametersAreInformative)
Douglas Gregor4ad96852009-11-19 07:41:15 +00002176 Result->AddInformativeChunk(Arg);
2177 else
2178 Result->AddPlaceholderChunk(Arg);
Douglas Gregor9630eb62009-11-17 16:44:22 +00002179 }
2180
Douglas Gregor2a17af02009-12-23 00:21:46 +00002181 if (Method->isVariadic()) {
Douglas Gregor1f5537a2010-07-08 23:20:03 +00002182 if (DeclaringEntity)
2183 Result->AddTextChunk(", ...");
2184 else if (AllParametersAreInformative)
Douglas Gregor2a17af02009-12-23 00:21:46 +00002185 Result->AddInformativeChunk(", ...");
2186 else
2187 Result->AddPlaceholderChunk(", ...");
Douglas Gregoraaa107a2010-08-23 23:51:41 +00002188
2189 MaybeAddSentinel(S.Context, Method, Result);
Douglas Gregor2a17af02009-12-23 00:21:46 +00002190 }
2191
Douglas Gregor9630eb62009-11-17 16:44:22 +00002192 return Result;
2193 }
2194
Douglas Gregor2b4074f2009-12-01 05:55:20 +00002195 if (Qualifier)
Douglas Gregor0563c262009-09-22 23:15:58 +00002196 AddQualifierToCompletionString(Result, Qualifier, QualifierIsInformative,
2197 S.Context);
Douglas Gregor2b4074f2009-12-01 05:55:20 +00002198
2199 Result->AddTypedTextChunk(ND->getNameAsString());
2200 return Result;
Douglas Gregor86d9a522009-09-21 16:56:56 +00002201}
2202
Douglas Gregor86d802e2009-09-23 00:34:09 +00002203CodeCompletionString *
2204CodeCompleteConsumer::OverloadCandidate::CreateSignatureString(
2205 unsigned CurrentArg,
2206 Sema &S) const {
Douglas Gregor0c8296d2009-11-07 00:00:49 +00002207 typedef CodeCompletionString::Chunk Chunk;
2208
Douglas Gregor86d802e2009-09-23 00:34:09 +00002209 CodeCompletionString *Result = new CodeCompletionString;
2210 FunctionDecl *FDecl = getFunction();
Douglas Gregorff5ce6e2009-12-18 18:53:37 +00002211 AddResultTypeChunk(S.Context, FDecl, Result);
Douglas Gregor86d802e2009-09-23 00:34:09 +00002212 const FunctionProtoType *Proto
2213 = dyn_cast<FunctionProtoType>(getFunctionType());
2214 if (!FDecl && !Proto) {
2215 // Function without a prototype. Just give the return type and a
2216 // highlighted ellipsis.
2217 const FunctionType *FT = getFunctionType();
2218 Result->AddTextChunk(
Benjamin Kramer660cc182009-11-29 20:18:50 +00002219 FT->getResultType().getAsString(S.Context.PrintingPolicy));
Douglas Gregor0c8296d2009-11-07 00:00:49 +00002220 Result->AddChunk(Chunk(CodeCompletionString::CK_LeftParen));
2221 Result->AddChunk(Chunk(CodeCompletionString::CK_CurrentParameter, "..."));
2222 Result->AddChunk(Chunk(CodeCompletionString::CK_RightParen));
Douglas Gregor86d802e2009-09-23 00:34:09 +00002223 return Result;
2224 }
2225
2226 if (FDecl)
Benjamin Kramer660cc182009-11-29 20:18:50 +00002227 Result->AddTextChunk(FDecl->getNameAsString());
Douglas Gregor86d802e2009-09-23 00:34:09 +00002228 else
2229 Result->AddTextChunk(
Benjamin Kramer660cc182009-11-29 20:18:50 +00002230 Proto->getResultType().getAsString(S.Context.PrintingPolicy));
Douglas Gregor86d802e2009-09-23 00:34:09 +00002231
Douglas Gregor0c8296d2009-11-07 00:00:49 +00002232 Result->AddChunk(Chunk(CodeCompletionString::CK_LeftParen));
Douglas Gregor86d802e2009-09-23 00:34:09 +00002233 unsigned NumParams = FDecl? FDecl->getNumParams() : Proto->getNumArgs();
2234 for (unsigned I = 0; I != NumParams; ++I) {
2235 if (I)
Douglas Gregor0c8296d2009-11-07 00:00:49 +00002236 Result->AddChunk(Chunk(CodeCompletionString::CK_Comma));
Douglas Gregor86d802e2009-09-23 00:34:09 +00002237
2238 std::string ArgString;
2239 QualType ArgType;
2240
2241 if (FDecl) {
2242 ArgString = FDecl->getParamDecl(I)->getNameAsString();
2243 ArgType = FDecl->getParamDecl(I)->getOriginalType();
2244 } else {
2245 ArgType = Proto->getArgType(I);
2246 }
2247
2248 ArgType.getAsStringInternal(ArgString, S.Context.PrintingPolicy);
2249
2250 if (I == CurrentArg)
Douglas Gregor0c8296d2009-11-07 00:00:49 +00002251 Result->AddChunk(Chunk(CodeCompletionString::CK_CurrentParameter,
Benjamin Kramer660cc182009-11-29 20:18:50 +00002252 ArgString));
Douglas Gregor86d802e2009-09-23 00:34:09 +00002253 else
Benjamin Kramer660cc182009-11-29 20:18:50 +00002254 Result->AddTextChunk(ArgString);
Douglas Gregor86d802e2009-09-23 00:34:09 +00002255 }
2256
2257 if (Proto && Proto->isVariadic()) {
Douglas Gregor0c8296d2009-11-07 00:00:49 +00002258 Result->AddChunk(Chunk(CodeCompletionString::CK_Comma));
Douglas Gregor86d802e2009-09-23 00:34:09 +00002259 if (CurrentArg < NumParams)
2260 Result->AddTextChunk("...");
2261 else
Douglas Gregor0c8296d2009-11-07 00:00:49 +00002262 Result->AddChunk(Chunk(CodeCompletionString::CK_CurrentParameter, "..."));
Douglas Gregor86d802e2009-09-23 00:34:09 +00002263 }
Douglas Gregor0c8296d2009-11-07 00:00:49 +00002264 Result->AddChunk(Chunk(CodeCompletionString::CK_RightParen));
Douglas Gregor86d802e2009-09-23 00:34:09 +00002265
2266 return Result;
2267}
2268
Douglas Gregor1827e102010-08-16 16:18:59 +00002269unsigned clang::getMacroUsagePriority(llvm::StringRef MacroName,
2270 bool PreferredTypeIsPointer) {
2271 unsigned Priority = CCP_Macro;
2272
2273 // Treat the "nil" and "NULL" macros as null pointer constants.
2274 if (MacroName.equals("nil") || MacroName.equals("NULL")) {
2275 Priority = CCP_Constant;
2276 if (PreferredTypeIsPointer)
2277 Priority = Priority / CCF_SimilarTypeMatch;
2278 }
2279
2280 return Priority;
2281}
2282
Douglas Gregor590c7d52010-07-08 20:55:51 +00002283static void AddMacroResults(Preprocessor &PP, ResultBuilder &Results,
2284 bool TargetTypeIsPointer = false) {
John McCall0a2c5e22010-08-25 06:19:51 +00002285 typedef CodeCompletionResult Result;
Douglas Gregor590c7d52010-07-08 20:55:51 +00002286
Douglas Gregor3f7c7f42009-10-30 16:50:04 +00002287 Results.EnterNewScope();
Douglas Gregor0c8296d2009-11-07 00:00:49 +00002288 for (Preprocessor::macro_iterator M = PP.macro_begin(),
2289 MEnd = PP.macro_end();
Douglas Gregor590c7d52010-07-08 20:55:51 +00002290 M != MEnd; ++M) {
Douglas Gregor1827e102010-08-16 16:18:59 +00002291 Results.AddResult(Result(M->first,
2292 getMacroUsagePriority(M->first->getName(),
2293 TargetTypeIsPointer)));
Douglas Gregor590c7d52010-07-08 20:55:51 +00002294 }
Douglas Gregor3f7c7f42009-10-30 16:50:04 +00002295 Results.ExitScope();
2296}
2297
Douglas Gregoraa5f77b2010-08-23 21:54:33 +00002298static void AddPrettyFunctionResults(const LangOptions &LangOpts,
2299 ResultBuilder &Results) {
John McCall0a2c5e22010-08-25 06:19:51 +00002300 typedef CodeCompletionResult Result;
Douglas Gregoraa5f77b2010-08-23 21:54:33 +00002301
2302 Results.EnterNewScope();
2303 Results.AddResult(Result("__PRETTY_FUNCTION__", CCP_Constant));
2304 Results.AddResult(Result("__FUNCTION__", CCP_Constant));
2305 if (LangOpts.C99 || LangOpts.CPlusPlus0x)
2306 Results.AddResult(Result("__func__", CCP_Constant));
2307 Results.ExitScope();
2308}
2309
Daniel Dunbar3a2838d2009-11-13 08:58:20 +00002310static void HandleCodeCompleteResults(Sema *S,
2311 CodeCompleteConsumer *CodeCompleter,
Douglas Gregore6b1bb62010-08-11 21:23:17 +00002312 CodeCompletionContext Context,
John McCall0a2c5e22010-08-25 06:19:51 +00002313 CodeCompletionResult *Results,
Douglas Gregore6b1bb62010-08-11 21:23:17 +00002314 unsigned NumResults) {
Douglas Gregor86d9a522009-09-21 16:56:56 +00002315 if (CodeCompleter)
Douglas Gregore6b1bb62010-08-11 21:23:17 +00002316 CodeCompleter->ProcessCodeCompleteResults(*S, Context, Results, NumResults);
Douglas Gregor54f01612009-11-19 00:01:57 +00002317
2318 for (unsigned I = 0; I != NumResults; ++I)
2319 Results[I].Destroy();
Douglas Gregor86d9a522009-09-21 16:56:56 +00002320}
2321
Douglas Gregore6b1bb62010-08-11 21:23:17 +00002322static enum CodeCompletionContext::Kind mapCodeCompletionContext(Sema &S,
2323 Sema::ParserCompletionContext PCC) {
2324 switch (PCC) {
John McCallf312b1e2010-08-26 23:41:50 +00002325 case Sema::PCC_Namespace:
Douglas Gregore6b1bb62010-08-11 21:23:17 +00002326 return CodeCompletionContext::CCC_TopLevel;
2327
John McCallf312b1e2010-08-26 23:41:50 +00002328 case Sema::PCC_Class:
Douglas Gregore6b1bb62010-08-11 21:23:17 +00002329 return CodeCompletionContext::CCC_ClassStructUnion;
2330
John McCallf312b1e2010-08-26 23:41:50 +00002331 case Sema::PCC_ObjCInterface:
Douglas Gregore6b1bb62010-08-11 21:23:17 +00002332 return CodeCompletionContext::CCC_ObjCInterface;
2333
John McCallf312b1e2010-08-26 23:41:50 +00002334 case Sema::PCC_ObjCImplementation:
Douglas Gregore6b1bb62010-08-11 21:23:17 +00002335 return CodeCompletionContext::CCC_ObjCImplementation;
2336
John McCallf312b1e2010-08-26 23:41:50 +00002337 case Sema::PCC_ObjCInstanceVariableList:
Douglas Gregore6b1bb62010-08-11 21:23:17 +00002338 return CodeCompletionContext::CCC_ObjCIvarList;
2339
John McCallf312b1e2010-08-26 23:41:50 +00002340 case Sema::PCC_Template:
2341 case Sema::PCC_MemberTemplate:
2342 case Sema::PCC_RecoveryInFunction:
Douglas Gregore6b1bb62010-08-11 21:23:17 +00002343 return CodeCompletionContext::CCC_Other;
2344
John McCallf312b1e2010-08-26 23:41:50 +00002345 case Sema::PCC_Expression:
2346 case Sema::PCC_ForInit:
2347 case Sema::PCC_Condition:
Douglas Gregore6b1bb62010-08-11 21:23:17 +00002348 return CodeCompletionContext::CCC_Expression;
2349
John McCallf312b1e2010-08-26 23:41:50 +00002350 case Sema::PCC_Statement:
Douglas Gregore6b1bb62010-08-11 21:23:17 +00002351 return CodeCompletionContext::CCC_Statement;
Douglas Gregor72db1082010-08-24 01:11:00 +00002352
John McCallf312b1e2010-08-26 23:41:50 +00002353 case Sema::PCC_Type:
Douglas Gregor72db1082010-08-24 01:11:00 +00002354 return CodeCompletionContext::CCC_Type;
Douglas Gregore6b1bb62010-08-11 21:23:17 +00002355 }
2356
2357 return CodeCompletionContext::CCC_Other;
2358}
2359
Douglas Gregor01dfea02010-01-10 23:08:15 +00002360void Sema::CodeCompleteOrdinaryName(Scope *S,
Douglas Gregore6b1bb62010-08-11 21:23:17 +00002361 ParserCompletionContext CompletionContext) {
John McCall0a2c5e22010-08-25 06:19:51 +00002362 typedef CodeCompletionResult Result;
Douglas Gregor2ccccb32010-08-23 18:23:48 +00002363 ResultBuilder Results(*this);
Douglas Gregor01dfea02010-01-10 23:08:15 +00002364
2365 // Determine how to filter results, e.g., so that the names of
2366 // values (functions, enumerators, function templates, etc.) are
2367 // only allowed where we can have an expression.
2368 switch (CompletionContext) {
Douglas Gregore6b1bb62010-08-11 21:23:17 +00002369 case PCC_Namespace:
2370 case PCC_Class:
2371 case PCC_ObjCInterface:
2372 case PCC_ObjCImplementation:
2373 case PCC_ObjCInstanceVariableList:
2374 case PCC_Template:
2375 case PCC_MemberTemplate:
Douglas Gregor72db1082010-08-24 01:11:00 +00002376 case PCC_Type:
Douglas Gregor01dfea02010-01-10 23:08:15 +00002377 Results.setFilter(&ResultBuilder::IsOrdinaryNonValueName);
2378 break;
2379
Douglas Gregore6b1bb62010-08-11 21:23:17 +00002380 case PCC_Statement:
Douglas Gregoreb0d0142010-08-24 23:58:17 +00002381 // For statements that are expressions, we prefer to call 'void' functions
2382 // rather than functions that return a result, since then the result would
2383 // be ignored.
2384 Results.setPreferredType(Context.VoidTy);
2385 // Fall through
2386
2387 case PCC_Expression:
Douglas Gregore6b1bb62010-08-11 21:23:17 +00002388 case PCC_ForInit:
2389 case PCC_Condition:
Douglas Gregor4710e5b2010-05-28 00:49:12 +00002390 if (WantTypesInContext(CompletionContext, getLangOptions()))
2391 Results.setFilter(&ResultBuilder::IsOrdinaryName);
2392 else
2393 Results.setFilter(&ResultBuilder::IsOrdinaryNonTypeName);
Douglas Gregor01dfea02010-01-10 23:08:15 +00002394 break;
Douglas Gregordc845342010-05-25 05:58:43 +00002395
Douglas Gregore6b1bb62010-08-11 21:23:17 +00002396 case PCC_RecoveryInFunction:
Douglas Gregordc845342010-05-25 05:58:43 +00002397 // Unfiltered
2398 break;
Douglas Gregor01dfea02010-01-10 23:08:15 +00002399 }
2400
Douglas Gregor3cdee122010-08-26 16:36:48 +00002401 // If we are in a C++ non-static member function, check the qualifiers on
2402 // the member function to filter/prioritize the results list.
2403 if (CXXMethodDecl *CurMethod = dyn_cast<CXXMethodDecl>(CurContext))
2404 if (CurMethod->isInstance())
2405 Results.setObjectTypeQualifiers(
2406 Qualifiers::fromCVRMask(CurMethod->getTypeQualifiers()));
2407
Douglas Gregor1ca6ae82010-01-14 01:09:38 +00002408 CodeCompletionDeclConsumer Consumer(Results, CurContext);
Douglas Gregor8071e422010-08-15 06:18:01 +00002409 LookupVisibleDecls(S, LookupOrdinaryName, Consumer,
2410 CodeCompleter->includeGlobals());
Douglas Gregor2a7925c2009-12-07 09:54:55 +00002411
2412 Results.EnterNewScope();
Douglas Gregorbca403c2010-01-13 23:51:12 +00002413 AddOrdinaryNameResults(CompletionContext, S, *this, Results);
Douglas Gregor2a7925c2009-12-07 09:54:55 +00002414 Results.ExitScope();
2415
Douglas Gregoraa5f77b2010-08-23 21:54:33 +00002416 switch (CompletionContext) {
Douglas Gregor72db1082010-08-24 01:11:00 +00002417 case PCC_Expression:
2418 case PCC_Statement:
2419 case PCC_RecoveryInFunction:
2420 if (S->getFnParent())
2421 AddPrettyFunctionResults(PP.getLangOptions(), Results);
2422 break;
2423
2424 case PCC_Namespace:
2425 case PCC_Class:
2426 case PCC_ObjCInterface:
2427 case PCC_ObjCImplementation:
2428 case PCC_ObjCInstanceVariableList:
2429 case PCC_Template:
2430 case PCC_MemberTemplate:
2431 case PCC_ForInit:
2432 case PCC_Condition:
2433 case PCC_Type:
2434 break;
Douglas Gregoraa5f77b2010-08-23 21:54:33 +00002435 }
2436
Douglas Gregor0c8296d2009-11-07 00:00:49 +00002437 if (CodeCompleter->includeMacros())
Douglas Gregorbca403c2010-01-13 23:51:12 +00002438 AddMacroResults(PP, Results);
Douglas Gregoraa5f77b2010-08-23 21:54:33 +00002439
Douglas Gregore6b1bb62010-08-11 21:23:17 +00002440 HandleCodeCompleteResults(this, CodeCompleter,
2441 mapCodeCompletionContext(*this, CompletionContext),
2442 Results.data(),Results.size());
Douglas Gregor791215b2009-09-21 20:51:25 +00002443}
2444
Douglas Gregor2ccccb32010-08-23 18:23:48 +00002445void Sema::CodeCompleteDeclarator(Scope *S,
2446 bool AllowNonIdentifiers,
2447 bool AllowNestedNameSpecifiers) {
John McCall0a2c5e22010-08-25 06:19:51 +00002448 typedef CodeCompletionResult Result;
Douglas Gregor2ccccb32010-08-23 18:23:48 +00002449 ResultBuilder Results(*this);
2450 Results.EnterNewScope();
2451
2452 // Type qualifiers can come after names.
2453 Results.AddResult(Result("const"));
2454 Results.AddResult(Result("volatile"));
2455 if (getLangOptions().C99)
2456 Results.AddResult(Result("restrict"));
2457
2458 if (getLangOptions().CPlusPlus) {
2459 if (AllowNonIdentifiers) {
2460 Results.AddResult(Result("operator"));
2461 }
2462
2463 // Add nested-name-specifiers.
2464 if (AllowNestedNameSpecifiers) {
2465 Results.allowNestedNameSpecifiers();
2466 CodeCompletionDeclConsumer Consumer(Results, CurContext);
2467 LookupVisibleDecls(S, LookupNestedNameSpecifierName, Consumer,
2468 CodeCompleter->includeGlobals());
2469 }
2470 }
2471 Results.ExitScope();
2472
Douglas Gregor4497dd42010-08-24 04:59:56 +00002473 // Note that we intentionally suppress macro results here, since we do not
2474 // encourage using macros to produce the names of entities.
2475
Douglas Gregor2ccccb32010-08-23 18:23:48 +00002476 HandleCodeCompleteResults(this, CodeCompleter,
2477 AllowNestedNameSpecifiers
2478 ? CodeCompletionContext::CCC_PotentiallyQualifiedName
2479 : CodeCompletionContext::CCC_Name,
2480 Results.data(), Results.size());
2481}
2482
Douglas Gregorfb629412010-08-23 21:17:50 +00002483struct Sema::CodeCompleteExpressionData {
2484 CodeCompleteExpressionData(QualType PreferredType = QualType())
2485 : PreferredType(PreferredType), IntegralConstantExpression(false),
2486 ObjCCollection(false) { }
2487
2488 QualType PreferredType;
2489 bool IntegralConstantExpression;
2490 bool ObjCCollection;
2491 llvm::SmallVector<Decl *, 4> IgnoreDecls;
2492};
2493
Douglas Gregor5ac3bdb2010-05-30 01:49:25 +00002494/// \brief Perform code-completion in an expression context when we know what
2495/// type we're looking for.
Douglas Gregorf9578432010-07-28 21:50:18 +00002496///
2497/// \param IntegralConstantExpression Only permit integral constant
2498/// expressions.
Douglas Gregorfb629412010-08-23 21:17:50 +00002499void Sema::CodeCompleteExpression(Scope *S,
2500 const CodeCompleteExpressionData &Data) {
John McCall0a2c5e22010-08-25 06:19:51 +00002501 typedef CodeCompletionResult Result;
Douglas Gregor5ac3bdb2010-05-30 01:49:25 +00002502 ResultBuilder Results(*this);
2503
Douglas Gregorfb629412010-08-23 21:17:50 +00002504 if (Data.ObjCCollection)
2505 Results.setFilter(&ResultBuilder::IsObjCCollection);
2506 else if (Data.IntegralConstantExpression)
Douglas Gregorf9578432010-07-28 21:50:18 +00002507 Results.setFilter(&ResultBuilder::IsIntegralConstantValue);
Douglas Gregore6b1bb62010-08-11 21:23:17 +00002508 else if (WantTypesInContext(PCC_Expression, getLangOptions()))
Douglas Gregor5ac3bdb2010-05-30 01:49:25 +00002509 Results.setFilter(&ResultBuilder::IsOrdinaryName);
2510 else
2511 Results.setFilter(&ResultBuilder::IsOrdinaryNonTypeName);
Douglas Gregorfb629412010-08-23 21:17:50 +00002512
2513 if (!Data.PreferredType.isNull())
2514 Results.setPreferredType(Data.PreferredType.getNonReferenceType());
2515
2516 // Ignore any declarations that we were told that we don't care about.
2517 for (unsigned I = 0, N = Data.IgnoreDecls.size(); I != N; ++I)
2518 Results.Ignore(Data.IgnoreDecls[I]);
Douglas Gregor5ac3bdb2010-05-30 01:49:25 +00002519
2520 CodeCompletionDeclConsumer Consumer(Results, CurContext);
Douglas Gregor8071e422010-08-15 06:18:01 +00002521 LookupVisibleDecls(S, LookupOrdinaryName, Consumer,
2522 CodeCompleter->includeGlobals());
Douglas Gregor5ac3bdb2010-05-30 01:49:25 +00002523
2524 Results.EnterNewScope();
Douglas Gregore6b1bb62010-08-11 21:23:17 +00002525 AddOrdinaryNameResults(PCC_Expression, S, *this, Results);
Douglas Gregor5ac3bdb2010-05-30 01:49:25 +00002526 Results.ExitScope();
2527
Douglas Gregor590c7d52010-07-08 20:55:51 +00002528 bool PreferredTypeIsPointer = false;
Douglas Gregorfb629412010-08-23 21:17:50 +00002529 if (!Data.PreferredType.isNull())
2530 PreferredTypeIsPointer = Data.PreferredType->isAnyPointerType()
2531 || Data.PreferredType->isMemberPointerType()
2532 || Data.PreferredType->isBlockPointerType();
Douglas Gregor590c7d52010-07-08 20:55:51 +00002533
Douglas Gregoraa5f77b2010-08-23 21:54:33 +00002534 if (S->getFnParent() &&
2535 !Data.ObjCCollection &&
2536 !Data.IntegralConstantExpression)
2537 AddPrettyFunctionResults(PP.getLangOptions(), Results);
2538
Douglas Gregor5ac3bdb2010-05-30 01:49:25 +00002539 if (CodeCompleter->includeMacros())
Douglas Gregor590c7d52010-07-08 20:55:51 +00002540 AddMacroResults(PP, Results, PreferredTypeIsPointer);
Douglas Gregore6b1bb62010-08-11 21:23:17 +00002541 HandleCodeCompleteResults(this, CodeCompleter,
Douglas Gregorfb629412010-08-23 21:17:50 +00002542 CodeCompletionContext(CodeCompletionContext::CCC_Expression,
2543 Data.PreferredType),
Douglas Gregore6b1bb62010-08-11 21:23:17 +00002544 Results.data(),Results.size());
Douglas Gregor5ac3bdb2010-05-30 01:49:25 +00002545}
2546
2547
Douglas Gregor95ac6552009-11-18 01:29:26 +00002548static void AddObjCProperties(ObjCContainerDecl *Container,
Douglas Gregor322328b2009-11-18 22:32:06 +00002549 bool AllowCategories,
Douglas Gregor95ac6552009-11-18 01:29:26 +00002550 DeclContext *CurContext,
2551 ResultBuilder &Results) {
John McCall0a2c5e22010-08-25 06:19:51 +00002552 typedef CodeCompletionResult Result;
Douglas Gregor95ac6552009-11-18 01:29:26 +00002553
2554 // Add properties in this container.
2555 for (ObjCContainerDecl::prop_iterator P = Container->prop_begin(),
2556 PEnd = Container->prop_end();
2557 P != PEnd;
2558 ++P)
2559 Results.MaybeAddResult(Result(*P, 0), CurContext);
2560
2561 // Add properties in referenced protocols.
2562 if (ObjCProtocolDecl *Protocol = dyn_cast<ObjCProtocolDecl>(Container)) {
2563 for (ObjCProtocolDecl::protocol_iterator P = Protocol->protocol_begin(),
2564 PEnd = Protocol->protocol_end();
2565 P != PEnd; ++P)
Douglas Gregor322328b2009-11-18 22:32:06 +00002566 AddObjCProperties(*P, AllowCategories, CurContext, Results);
Douglas Gregor95ac6552009-11-18 01:29:26 +00002567 } else if (ObjCInterfaceDecl *IFace = dyn_cast<ObjCInterfaceDecl>(Container)){
Douglas Gregor322328b2009-11-18 22:32:06 +00002568 if (AllowCategories) {
2569 // Look through categories.
2570 for (ObjCCategoryDecl *Category = IFace->getCategoryList();
2571 Category; Category = Category->getNextClassCategory())
2572 AddObjCProperties(Category, AllowCategories, CurContext, Results);
2573 }
Douglas Gregor95ac6552009-11-18 01:29:26 +00002574
2575 // Look through protocols.
2576 for (ObjCInterfaceDecl::protocol_iterator I = IFace->protocol_begin(),
2577 E = IFace->protocol_end();
2578 I != E; ++I)
Douglas Gregor322328b2009-11-18 22:32:06 +00002579 AddObjCProperties(*I, AllowCategories, CurContext, Results);
Douglas Gregor95ac6552009-11-18 01:29:26 +00002580
2581 // Look in the superclass.
2582 if (IFace->getSuperClass())
Douglas Gregor322328b2009-11-18 22:32:06 +00002583 AddObjCProperties(IFace->getSuperClass(), AllowCategories, CurContext,
2584 Results);
Douglas Gregor95ac6552009-11-18 01:29:26 +00002585 } else if (const ObjCCategoryDecl *Category
2586 = dyn_cast<ObjCCategoryDecl>(Container)) {
2587 // Look through protocols.
2588 for (ObjCInterfaceDecl::protocol_iterator P = Category->protocol_begin(),
2589 PEnd = Category->protocol_end();
2590 P != PEnd; ++P)
Douglas Gregor322328b2009-11-18 22:32:06 +00002591 AddObjCProperties(*P, AllowCategories, CurContext, Results);
Douglas Gregor95ac6552009-11-18 01:29:26 +00002592 }
2593}
2594
Douglas Gregor81b747b2009-09-17 21:32:03 +00002595void Sema::CodeCompleteMemberReferenceExpr(Scope *S, ExprTy *BaseE,
2596 SourceLocation OpLoc,
2597 bool IsArrow) {
2598 if (!BaseE || !CodeCompleter)
2599 return;
2600
John McCall0a2c5e22010-08-25 06:19:51 +00002601 typedef CodeCompletionResult Result;
Douglas Gregor86d9a522009-09-21 16:56:56 +00002602
Douglas Gregor81b747b2009-09-17 21:32:03 +00002603 Expr *Base = static_cast<Expr *>(BaseE);
2604 QualType BaseType = Base->getType();
Douglas Gregor86d9a522009-09-21 16:56:56 +00002605
2606 if (IsArrow) {
2607 if (const PointerType *Ptr = BaseType->getAs<PointerType>())
2608 BaseType = Ptr->getPointeeType();
2609 else if (BaseType->isObjCObjectPointerType())
Douglas Gregor3cdee122010-08-26 16:36:48 +00002610 /*Do nothing*/ ;
Douglas Gregor86d9a522009-09-21 16:56:56 +00002611 else
2612 return;
2613 }
2614
Douglas Gregoreb5758b2009-09-23 22:26:46 +00002615 ResultBuilder Results(*this, &ResultBuilder::IsMember);
Douglas Gregor95ac6552009-11-18 01:29:26 +00002616 Results.EnterNewScope();
2617 if (const RecordType *Record = BaseType->getAs<RecordType>()) {
Douglas Gregor3cdee122010-08-26 16:36:48 +00002618 // Indicate that we are performing a member access, and the cv-qualifiers
2619 // for the base object type.
2620 Results.setObjectTypeQualifiers(BaseType.getQualifiers());
2621
Douglas Gregor95ac6552009-11-18 01:29:26 +00002622 // Access to a C/C++ class, struct, or union.
Douglas Gregor45bcd432010-01-14 03:21:49 +00002623 Results.allowNestedNameSpecifiers();
Douglas Gregor0cc84042010-01-14 15:47:35 +00002624 CodeCompletionDeclConsumer Consumer(Results, CurContext);
Douglas Gregor8071e422010-08-15 06:18:01 +00002625 LookupVisibleDecls(Record->getDecl(), LookupMemberName, Consumer,
2626 CodeCompleter->includeGlobals());
Daniel Dunbar3a2838d2009-11-13 08:58:20 +00002627
Douglas Gregor95ac6552009-11-18 01:29:26 +00002628 if (getLangOptions().CPlusPlus) {
2629 if (!Results.empty()) {
2630 // The "template" keyword can follow "->" or "." in the grammar.
2631 // However, we only want to suggest the template keyword if something
2632 // is dependent.
2633 bool IsDependent = BaseType->isDependentType();
2634 if (!IsDependent) {
2635 for (Scope *DepScope = S; DepScope; DepScope = DepScope->getParent())
2636 if (DeclContext *Ctx = (DeclContext *)DepScope->getEntity()) {
2637 IsDependent = Ctx->isDependentContext();
2638 break;
2639 }
2640 }
Daniel Dunbar3a2838d2009-11-13 08:58:20 +00002641
Douglas Gregor95ac6552009-11-18 01:29:26 +00002642 if (IsDependent)
Douglas Gregora4477812010-01-14 16:01:26 +00002643 Results.AddResult(Result("template"));
Daniel Dunbar3a2838d2009-11-13 08:58:20 +00002644 }
Daniel Dunbar3a2838d2009-11-13 08:58:20 +00002645 }
Douglas Gregor95ac6552009-11-18 01:29:26 +00002646 } else if (!IsArrow && BaseType->getAsObjCInterfacePointerType()) {
2647 // Objective-C property reference.
2648
2649 // Add property results based on our interface.
2650 const ObjCObjectPointerType *ObjCPtr
2651 = BaseType->getAsObjCInterfacePointerType();
2652 assert(ObjCPtr && "Non-NULL pointer guaranteed above!");
Douglas Gregor322328b2009-11-18 22:32:06 +00002653 AddObjCProperties(ObjCPtr->getInterfaceDecl(), true, CurContext, Results);
Douglas Gregor95ac6552009-11-18 01:29:26 +00002654
2655 // Add properties from the protocols in a qualified interface.
2656 for (ObjCObjectPointerType::qual_iterator I = ObjCPtr->qual_begin(),
2657 E = ObjCPtr->qual_end();
2658 I != E; ++I)
Douglas Gregor322328b2009-11-18 22:32:06 +00002659 AddObjCProperties(*I, true, CurContext, Results);
Douglas Gregor95ac6552009-11-18 01:29:26 +00002660 } else if ((IsArrow && BaseType->isObjCObjectPointerType()) ||
John McCallc12c5bb2010-05-15 11:32:37 +00002661 (!IsArrow && BaseType->isObjCObjectType())) {
Douglas Gregor95ac6552009-11-18 01:29:26 +00002662 // Objective-C instance variable access.
2663 ObjCInterfaceDecl *Class = 0;
2664 if (const ObjCObjectPointerType *ObjCPtr
2665 = BaseType->getAs<ObjCObjectPointerType>())
2666 Class = ObjCPtr->getInterfaceDecl();
2667 else
John McCallc12c5bb2010-05-15 11:32:37 +00002668 Class = BaseType->getAs<ObjCObjectType>()->getInterface();
Douglas Gregor95ac6552009-11-18 01:29:26 +00002669
2670 // Add all ivars from this class and its superclasses.
Douglas Gregor80f4f4c2010-01-14 16:08:12 +00002671 if (Class) {
2672 CodeCompletionDeclConsumer Consumer(Results, CurContext);
2673 Results.setFilter(&ResultBuilder::IsObjCIvar);
Douglas Gregor8071e422010-08-15 06:18:01 +00002674 LookupVisibleDecls(Class, LookupMemberName, Consumer,
2675 CodeCompleter->includeGlobals());
Douglas Gregor95ac6552009-11-18 01:29:26 +00002676 }
Douglas Gregor86d9a522009-09-21 16:56:56 +00002677 }
Douglas Gregor95ac6552009-11-18 01:29:26 +00002678
2679 // FIXME: How do we cope with isa?
2680
2681 Results.ExitScope();
Daniel Dunbar3a2838d2009-11-13 08:58:20 +00002682
Daniel Dunbar3a2838d2009-11-13 08:58:20 +00002683 // Hand off the results found for code completion.
Douglas Gregore6b1bb62010-08-11 21:23:17 +00002684 HandleCodeCompleteResults(this, CodeCompleter,
2685 CodeCompletionContext(CodeCompletionContext::CCC_MemberAccess,
2686 BaseType),
2687 Results.data(),Results.size());
Douglas Gregor81b747b2009-09-17 21:32:03 +00002688}
2689
Douglas Gregor374929f2009-09-18 15:37:17 +00002690void Sema::CodeCompleteTag(Scope *S, unsigned TagSpec) {
2691 if (!CodeCompleter)
2692 return;
2693
John McCall0a2c5e22010-08-25 06:19:51 +00002694 typedef CodeCompletionResult Result;
Douglas Gregor86d9a522009-09-21 16:56:56 +00002695 ResultBuilder::LookupFilter Filter = 0;
Douglas Gregore6b1bb62010-08-11 21:23:17 +00002696 enum CodeCompletionContext::Kind ContextKind
2697 = CodeCompletionContext::CCC_Other;
Douglas Gregor374929f2009-09-18 15:37:17 +00002698 switch ((DeclSpec::TST)TagSpec) {
2699 case DeclSpec::TST_enum:
Douglas Gregor86d9a522009-09-21 16:56:56 +00002700 Filter = &ResultBuilder::IsEnum;
Douglas Gregore6b1bb62010-08-11 21:23:17 +00002701 ContextKind = CodeCompletionContext::CCC_EnumTag;
Douglas Gregor374929f2009-09-18 15:37:17 +00002702 break;
2703
2704 case DeclSpec::TST_union:
Douglas Gregor86d9a522009-09-21 16:56:56 +00002705 Filter = &ResultBuilder::IsUnion;
Douglas Gregore6b1bb62010-08-11 21:23:17 +00002706 ContextKind = CodeCompletionContext::CCC_UnionTag;
Douglas Gregor374929f2009-09-18 15:37:17 +00002707 break;
2708
2709 case DeclSpec::TST_struct:
Douglas Gregor374929f2009-09-18 15:37:17 +00002710 case DeclSpec::TST_class:
Douglas Gregor86d9a522009-09-21 16:56:56 +00002711 Filter = &ResultBuilder::IsClassOrStruct;
Douglas Gregore6b1bb62010-08-11 21:23:17 +00002712 ContextKind = CodeCompletionContext::CCC_ClassOrStructTag;
Douglas Gregor374929f2009-09-18 15:37:17 +00002713 break;
2714
2715 default:
2716 assert(false && "Unknown type specifier kind in CodeCompleteTag");
2717 return;
2718 }
Douglas Gregor86d9a522009-09-21 16:56:56 +00002719
John McCall0d6b1642010-04-23 18:46:30 +00002720 ResultBuilder Results(*this);
Douglas Gregor5d2fc402010-01-14 03:27:13 +00002721 CodeCompletionDeclConsumer Consumer(Results, CurContext);
John McCall0d6b1642010-04-23 18:46:30 +00002722
2723 // First pass: look for tags.
2724 Results.setFilter(Filter);
Douglas Gregor8071e422010-08-15 06:18:01 +00002725 LookupVisibleDecls(S, LookupTagName, Consumer,
2726 CodeCompleter->includeGlobals());
John McCall0d6b1642010-04-23 18:46:30 +00002727
Douglas Gregor8071e422010-08-15 06:18:01 +00002728 if (CodeCompleter->includeGlobals()) {
2729 // Second pass: look for nested name specifiers.
2730 Results.setFilter(&ResultBuilder::IsNestedNameSpecifier);
2731 LookupVisibleDecls(S, LookupNestedNameSpecifierName, Consumer);
2732 }
Douglas Gregor86d9a522009-09-21 16:56:56 +00002733
Douglas Gregore6b1bb62010-08-11 21:23:17 +00002734 HandleCodeCompleteResults(this, CodeCompleter, ContextKind,
2735 Results.data(),Results.size());
Douglas Gregor374929f2009-09-18 15:37:17 +00002736}
2737
Douglas Gregor3e1005f2009-09-21 18:10:23 +00002738void Sema::CodeCompleteCase(Scope *S) {
John McCall781472f2010-08-25 08:40:02 +00002739 if (getCurFunction()->SwitchStack.empty() || !CodeCompleter)
Douglas Gregor3e1005f2009-09-21 18:10:23 +00002740 return;
2741
John McCall781472f2010-08-25 08:40:02 +00002742 SwitchStmt *Switch = getCurFunction()->SwitchStack.back();
Douglas Gregorf9578432010-07-28 21:50:18 +00002743 if (!Switch->getCond()->getType()->isEnumeralType()) {
Douglas Gregorfb629412010-08-23 21:17:50 +00002744 CodeCompleteExpressionData Data(Switch->getCond()->getType());
2745 Data.IntegralConstantExpression = true;
2746 CodeCompleteExpression(S, Data);
Douglas Gregor3e1005f2009-09-21 18:10:23 +00002747 return;
Douglas Gregorf9578432010-07-28 21:50:18 +00002748 }
Douglas Gregor3e1005f2009-09-21 18:10:23 +00002749
2750 // Code-complete the cases of a switch statement over an enumeration type
2751 // by providing the list of
2752 EnumDecl *Enum = Switch->getCond()->getType()->getAs<EnumType>()->getDecl();
2753
2754 // Determine which enumerators we have already seen in the switch statement.
2755 // FIXME: Ideally, we would also be able to look *past* the code-completion
2756 // token, in case we are code-completing in the middle of the switch and not
2757 // at the end. However, we aren't able to do so at the moment.
2758 llvm::SmallPtrSet<EnumConstantDecl *, 8> EnumeratorsSeen;
Douglas Gregorb9d0ef72009-09-21 19:57:38 +00002759 NestedNameSpecifier *Qualifier = 0;
Douglas Gregor3e1005f2009-09-21 18:10:23 +00002760 for (SwitchCase *SC = Switch->getSwitchCaseList(); SC;
2761 SC = SC->getNextSwitchCase()) {
2762 CaseStmt *Case = dyn_cast<CaseStmt>(SC);
2763 if (!Case)
2764 continue;
2765
2766 Expr *CaseVal = Case->getLHS()->IgnoreParenCasts();
2767 if (DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(CaseVal))
2768 if (EnumConstantDecl *Enumerator
2769 = dyn_cast<EnumConstantDecl>(DRE->getDecl())) {
2770 // We look into the AST of the case statement to determine which
2771 // enumerator was named. Alternatively, we could compute the value of
2772 // the integral constant expression, then compare it against the
2773 // values of each enumerator. However, value-based approach would not
2774 // work as well with C++ templates where enumerators declared within a
2775 // template are type- and value-dependent.
2776 EnumeratorsSeen.insert(Enumerator);
2777
Douglas Gregorb9d0ef72009-09-21 19:57:38 +00002778 // If this is a qualified-id, keep track of the nested-name-specifier
2779 // so that we can reproduce it as part of code completion, e.g.,
Douglas Gregor3e1005f2009-09-21 18:10:23 +00002780 //
2781 // switch (TagD.getKind()) {
2782 // case TagDecl::TK_enum:
2783 // break;
2784 // case XXX
2785 //
Douglas Gregorb9d0ef72009-09-21 19:57:38 +00002786 // At the XXX, our completions are TagDecl::TK_union,
Douglas Gregor3e1005f2009-09-21 18:10:23 +00002787 // TagDecl::TK_struct, and TagDecl::TK_class, rather than TK_union,
2788 // TK_struct, and TK_class.
Douglas Gregora2813ce2009-10-23 18:54:35 +00002789 Qualifier = DRE->getQualifier();
Douglas Gregor3e1005f2009-09-21 18:10:23 +00002790 }
2791 }
2792
Douglas Gregorb9d0ef72009-09-21 19:57:38 +00002793 if (getLangOptions().CPlusPlus && !Qualifier && EnumeratorsSeen.empty()) {
2794 // If there are no prior enumerators in C++, check whether we have to
2795 // qualify the names of the enumerators that we suggest, because they
2796 // may not be visible in this scope.
2797 Qualifier = getRequiredQualification(Context, CurContext,
2798 Enum->getDeclContext());
2799
2800 // FIXME: Scoped enums need to start with "EnumDecl" as the context!
2801 }
2802
Douglas Gregor3e1005f2009-09-21 18:10:23 +00002803 // Add any enumerators that have not yet been mentioned.
2804 ResultBuilder Results(*this);
2805 Results.EnterNewScope();
2806 for (EnumDecl::enumerator_iterator E = Enum->enumerator_begin(),
2807 EEnd = Enum->enumerator_end();
2808 E != EEnd; ++E) {
2809 if (EnumeratorsSeen.count(*E))
2810 continue;
2811
John McCall0a2c5e22010-08-25 06:19:51 +00002812 Results.AddResult(CodeCompletionResult(*E, Qualifier),
Douglas Gregor608300b2010-01-14 16:14:35 +00002813 CurContext, 0, false);
Douglas Gregor3e1005f2009-09-21 18:10:23 +00002814 }
2815 Results.ExitScope();
Douglas Gregor2f880e42010-04-06 20:02:15 +00002816
Douglas Gregor0c8296d2009-11-07 00:00:49 +00002817 if (CodeCompleter->includeMacros())
Douglas Gregorbca403c2010-01-13 23:51:12 +00002818 AddMacroResults(PP, Results);
Douglas Gregore6b1bb62010-08-11 21:23:17 +00002819 HandleCodeCompleteResults(this, CodeCompleter,
2820 CodeCompletionContext::CCC_Expression,
2821 Results.data(),Results.size());
Douglas Gregor3e1005f2009-09-21 18:10:23 +00002822}
2823
Douglas Gregor9c6a0e92009-09-22 15:41:20 +00002824namespace {
2825 struct IsBetterOverloadCandidate {
2826 Sema &S;
John McCall5769d612010-02-08 23:07:23 +00002827 SourceLocation Loc;
Douglas Gregor9c6a0e92009-09-22 15:41:20 +00002828
2829 public:
John McCall5769d612010-02-08 23:07:23 +00002830 explicit IsBetterOverloadCandidate(Sema &S, SourceLocation Loc)
2831 : S(S), Loc(Loc) { }
Douglas Gregor9c6a0e92009-09-22 15:41:20 +00002832
2833 bool
2834 operator()(const OverloadCandidate &X, const OverloadCandidate &Y) const {
John McCall120d63c2010-08-24 20:38:10 +00002835 return isBetterOverloadCandidate(S, X, Y, Loc);
Douglas Gregor9c6a0e92009-09-22 15:41:20 +00002836 }
2837 };
2838}
2839
Douglas Gregord28dcd72010-05-30 06:10:08 +00002840static bool anyNullArguments(Expr **Args, unsigned NumArgs) {
2841 if (NumArgs && !Args)
2842 return true;
2843
2844 for (unsigned I = 0; I != NumArgs; ++I)
2845 if (!Args[I])
2846 return true;
2847
2848 return false;
2849}
2850
Douglas Gregor9c6a0e92009-09-22 15:41:20 +00002851void Sema::CodeCompleteCall(Scope *S, ExprTy *FnIn,
2852 ExprTy **ArgsIn, unsigned NumArgs) {
2853 if (!CodeCompleter)
2854 return;
Douglas Gregoref96eac2009-12-11 19:06:04 +00002855
2856 // When we're code-completing for a call, we fall back to ordinary
2857 // name code-completion whenever we can't produce specific
2858 // results. We may want to revisit this strategy in the future,
2859 // e.g., by merging the two kinds of results.
2860
Douglas Gregor9c6a0e92009-09-22 15:41:20 +00002861 Expr *Fn = (Expr *)FnIn;
2862 Expr **Args = (Expr **)ArgsIn;
Douglas Gregoref96eac2009-12-11 19:06:04 +00002863
Douglas Gregor9c6a0e92009-09-22 15:41:20 +00002864 // Ignore type-dependent call expressions entirely.
Douglas Gregord28dcd72010-05-30 06:10:08 +00002865 if (!Fn || Fn->isTypeDependent() || anyNullArguments(Args, NumArgs) ||
Douglas Gregoref96eac2009-12-11 19:06:04 +00002866 Expr::hasAnyTypeDependentArguments(Args, NumArgs)) {
Douglas Gregore6b1bb62010-08-11 21:23:17 +00002867 CodeCompleteOrdinaryName(S, PCC_Expression);
Douglas Gregor9c6a0e92009-09-22 15:41:20 +00002868 return;
Douglas Gregoref96eac2009-12-11 19:06:04 +00002869 }
Douglas Gregor9c6a0e92009-09-22 15:41:20 +00002870
John McCall3b4294e2009-12-16 12:17:52 +00002871 // Build an overload candidate set based on the functions we find.
John McCall5769d612010-02-08 23:07:23 +00002872 SourceLocation Loc = Fn->getExprLoc();
2873 OverloadCandidateSet CandidateSet(Loc);
John McCall3b4294e2009-12-16 12:17:52 +00002874
Douglas Gregor9c6a0e92009-09-22 15:41:20 +00002875 // FIXME: What if we're calling something that isn't a function declaration?
2876 // FIXME: What if we're calling a pseudo-destructor?
2877 // FIXME: What if we're calling a member function?
2878
Douglas Gregorc0265402010-01-21 15:46:19 +00002879 typedef CodeCompleteConsumer::OverloadCandidate ResultCandidate;
2880 llvm::SmallVector<ResultCandidate, 8> Results;
2881
John McCall3b4294e2009-12-16 12:17:52 +00002882 Expr *NakedFn = Fn->IgnoreParenCasts();
2883 if (UnresolvedLookupExpr *ULE = dyn_cast<UnresolvedLookupExpr>(NakedFn))
2884 AddOverloadedCallCandidates(ULE, Args, NumArgs, CandidateSet,
2885 /*PartialOverloading=*/ true);
2886 else if (DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(NakedFn)) {
2887 FunctionDecl *FDecl = dyn_cast<FunctionDecl>(DRE->getDecl());
Douglas Gregorc0265402010-01-21 15:46:19 +00002888 if (FDecl) {
Douglas Gregord28dcd72010-05-30 06:10:08 +00002889 if (!getLangOptions().CPlusPlus ||
2890 !FDecl->getType()->getAs<FunctionProtoType>())
Douglas Gregorc0265402010-01-21 15:46:19 +00002891 Results.push_back(ResultCandidate(FDecl));
2892 else
John McCall86820f52010-01-26 01:37:31 +00002893 // FIXME: access?
John McCall9aa472c2010-03-19 07:35:19 +00002894 AddOverloadCandidate(FDecl, DeclAccessPair::make(FDecl, AS_none),
2895 Args, NumArgs, CandidateSet,
Douglas Gregorc27d6c52010-04-16 17:41:49 +00002896 false, /*PartialOverloading*/true);
Douglas Gregorc0265402010-01-21 15:46:19 +00002897 }
John McCall3b4294e2009-12-16 12:17:52 +00002898 }
Douglas Gregor9c6a0e92009-09-22 15:41:20 +00002899
Douglas Gregor5ac3bdb2010-05-30 01:49:25 +00002900 QualType ParamType;
2901
Douglas Gregorc0265402010-01-21 15:46:19 +00002902 if (!CandidateSet.empty()) {
2903 // Sort the overload candidate set by placing the best overloads first.
2904 std::stable_sort(CandidateSet.begin(), CandidateSet.end(),
John McCall5769d612010-02-08 23:07:23 +00002905 IsBetterOverloadCandidate(*this, Loc));
Douglas Gregor9c6a0e92009-09-22 15:41:20 +00002906
Douglas Gregorc0265402010-01-21 15:46:19 +00002907 // Add the remaining viable overload candidates as code-completion reslults.
2908 for (OverloadCandidateSet::iterator Cand = CandidateSet.begin(),
2909 CandEnd = CandidateSet.end();
2910 Cand != CandEnd; ++Cand) {
2911 if (Cand->Viable)
2912 Results.push_back(ResultCandidate(Cand->Function));
2913 }
Douglas Gregor5ac3bdb2010-05-30 01:49:25 +00002914
2915 // From the viable candidates, try to determine the type of this parameter.
2916 for (unsigned I = 0, N = Results.size(); I != N; ++I) {
2917 if (const FunctionType *FType = Results[I].getFunctionType())
2918 if (const FunctionProtoType *Proto = dyn_cast<FunctionProtoType>(FType))
2919 if (NumArgs < Proto->getNumArgs()) {
2920 if (ParamType.isNull())
2921 ParamType = Proto->getArgType(NumArgs);
2922 else if (!Context.hasSameUnqualifiedType(
2923 ParamType.getNonReferenceType(),
2924 Proto->getArgType(NumArgs).getNonReferenceType())) {
2925 ParamType = QualType();
2926 break;
2927 }
2928 }
2929 }
2930 } else {
2931 // Try to determine the parameter type from the type of the expression
2932 // being called.
2933 QualType FunctionType = Fn->getType();
2934 if (const PointerType *Ptr = FunctionType->getAs<PointerType>())
2935 FunctionType = Ptr->getPointeeType();
2936 else if (const BlockPointerType *BlockPtr
2937 = FunctionType->getAs<BlockPointerType>())
2938 FunctionType = BlockPtr->getPointeeType();
2939 else if (const MemberPointerType *MemPtr
2940 = FunctionType->getAs<MemberPointerType>())
2941 FunctionType = MemPtr->getPointeeType();
2942
2943 if (const FunctionProtoType *Proto
2944 = FunctionType->getAs<FunctionProtoType>()) {
2945 if (NumArgs < Proto->getNumArgs())
2946 ParamType = Proto->getArgType(NumArgs);
2947 }
Douglas Gregor9c6a0e92009-09-22 15:41:20 +00002948 }
Douglas Gregoref96eac2009-12-11 19:06:04 +00002949
Douglas Gregor5ac3bdb2010-05-30 01:49:25 +00002950 if (ParamType.isNull())
Douglas Gregore6b1bb62010-08-11 21:23:17 +00002951 CodeCompleteOrdinaryName(S, PCC_Expression);
Douglas Gregor5ac3bdb2010-05-30 01:49:25 +00002952 else
2953 CodeCompleteExpression(S, ParamType);
2954
Douglas Gregor2e4c7a52010-04-06 20:19:47 +00002955 if (!Results.empty())
Douglas Gregoref96eac2009-12-11 19:06:04 +00002956 CodeCompleter->ProcessOverloadCandidates(*this, NumArgs, Results.data(),
2957 Results.size());
Douglas Gregor9c6a0e92009-09-22 15:41:20 +00002958}
2959
John McCalld226f652010-08-21 09:40:31 +00002960void Sema::CodeCompleteInitializer(Scope *S, Decl *D) {
2961 ValueDecl *VD = dyn_cast_or_null<ValueDecl>(D);
Douglas Gregor5ac3bdb2010-05-30 01:49:25 +00002962 if (!VD) {
Douglas Gregore6b1bb62010-08-11 21:23:17 +00002963 CodeCompleteOrdinaryName(S, PCC_Expression);
Douglas Gregor5ac3bdb2010-05-30 01:49:25 +00002964 return;
2965 }
2966
2967 CodeCompleteExpression(S, VD->getType());
2968}
2969
2970void Sema::CodeCompleteReturn(Scope *S) {
2971 QualType ResultType;
2972 if (isa<BlockDecl>(CurContext)) {
2973 if (BlockScopeInfo *BSI = getCurBlock())
2974 ResultType = BSI->ReturnType;
2975 } else if (FunctionDecl *Function = dyn_cast<FunctionDecl>(CurContext))
2976 ResultType = Function->getResultType();
2977 else if (ObjCMethodDecl *Method = dyn_cast<ObjCMethodDecl>(CurContext))
2978 ResultType = Method->getResultType();
2979
2980 if (ResultType.isNull())
Douglas Gregore6b1bb62010-08-11 21:23:17 +00002981 CodeCompleteOrdinaryName(S, PCC_Expression);
Douglas Gregor5ac3bdb2010-05-30 01:49:25 +00002982 else
2983 CodeCompleteExpression(S, ResultType);
2984}
2985
2986void Sema::CodeCompleteAssignmentRHS(Scope *S, ExprTy *LHS) {
2987 if (LHS)
2988 CodeCompleteExpression(S, static_cast<Expr *>(LHS)->getType());
2989 else
Douglas Gregore6b1bb62010-08-11 21:23:17 +00002990 CodeCompleteOrdinaryName(S, PCC_Expression);
Douglas Gregor5ac3bdb2010-05-30 01:49:25 +00002991}
2992
Jeffrey Yasskin9ab14542010-04-08 16:38:48 +00002993void Sema::CodeCompleteQualifiedId(Scope *S, CXXScopeSpec &SS,
Douglas Gregor81b747b2009-09-17 21:32:03 +00002994 bool EnteringContext) {
2995 if (!SS.getScopeRep() || !CodeCompleter)
2996 return;
2997
Douglas Gregor86d9a522009-09-21 16:56:56 +00002998 DeclContext *Ctx = computeDeclContext(SS, EnteringContext);
2999 if (!Ctx)
3000 return;
Douglas Gregord1cd31a2009-12-11 18:28:39 +00003001
3002 // Try to instantiate any non-dependent declaration contexts before
3003 // we look in them.
John McCall77bb1aa2010-05-01 00:40:08 +00003004 if (!isDependentScopeSpecifier(SS) && RequireCompleteDeclContext(SS, Ctx))
Douglas Gregord1cd31a2009-12-11 18:28:39 +00003005 return;
3006
Douglas Gregor86d9a522009-09-21 16:56:56 +00003007 ResultBuilder Results(*this);
Douglas Gregordef91072010-01-14 03:35:48 +00003008 CodeCompletionDeclConsumer Consumer(Results, CurContext);
3009 LookupVisibleDecls(Ctx, LookupOrdinaryName, Consumer);
Douglas Gregor86d9a522009-09-21 16:56:56 +00003010
3011 // The "template" keyword can follow "::" in the grammar, but only
3012 // put it into the grammar if the nested-name-specifier is dependent.
3013 NestedNameSpecifier *NNS = (NestedNameSpecifier *)SS.getScopeRep();
3014 if (!Results.empty() && NNS->isDependent())
Douglas Gregora4477812010-01-14 16:01:26 +00003015 Results.AddResult("template");
Douglas Gregor86d9a522009-09-21 16:56:56 +00003016
Douglas Gregore6b1bb62010-08-11 21:23:17 +00003017 HandleCodeCompleteResults(this, CodeCompleter,
3018 CodeCompletionContext::CCC_Other,
3019 Results.data(),Results.size());
Douglas Gregor81b747b2009-09-17 21:32:03 +00003020}
Douglas Gregor49f40bd2009-09-18 19:03:04 +00003021
3022void Sema::CodeCompleteUsing(Scope *S) {
3023 if (!CodeCompleter)
3024 return;
3025
Douglas Gregor86d9a522009-09-21 16:56:56 +00003026 ResultBuilder Results(*this, &ResultBuilder::IsNestedNameSpecifier);
Douglas Gregor8e0a0e42009-09-22 23:31:26 +00003027 Results.EnterNewScope();
Douglas Gregor86d9a522009-09-21 16:56:56 +00003028
3029 // If we aren't in class scope, we could see the "namespace" keyword.
3030 if (!S->isClassScope())
John McCall0a2c5e22010-08-25 06:19:51 +00003031 Results.AddResult(CodeCompletionResult("namespace"));
Douglas Gregor86d9a522009-09-21 16:56:56 +00003032
3033 // After "using", we can see anything that would start a
3034 // nested-name-specifier.
Douglas Gregor5d2fc402010-01-14 03:27:13 +00003035 CodeCompletionDeclConsumer Consumer(Results, CurContext);
Douglas Gregor8071e422010-08-15 06:18:01 +00003036 LookupVisibleDecls(S, LookupOrdinaryName, Consumer,
3037 CodeCompleter->includeGlobals());
Douglas Gregor8e0a0e42009-09-22 23:31:26 +00003038 Results.ExitScope();
Douglas Gregor86d9a522009-09-21 16:56:56 +00003039
Douglas Gregore6b1bb62010-08-11 21:23:17 +00003040 HandleCodeCompleteResults(this, CodeCompleter,
3041 CodeCompletionContext::CCC_Other,
3042 Results.data(),Results.size());
Douglas Gregor49f40bd2009-09-18 19:03:04 +00003043}
3044
3045void Sema::CodeCompleteUsingDirective(Scope *S) {
3046 if (!CodeCompleter)
3047 return;
3048
Douglas Gregor86d9a522009-09-21 16:56:56 +00003049 // After "using namespace", we expect to see a namespace name or namespace
3050 // alias.
3051 ResultBuilder Results(*this, &ResultBuilder::IsNamespaceOrAlias);
Douglas Gregor8e0a0e42009-09-22 23:31:26 +00003052 Results.EnterNewScope();
Douglas Gregor5d2fc402010-01-14 03:27:13 +00003053 CodeCompletionDeclConsumer Consumer(Results, CurContext);
Douglas Gregor8071e422010-08-15 06:18:01 +00003054 LookupVisibleDecls(S, LookupOrdinaryName, Consumer,
3055 CodeCompleter->includeGlobals());
Douglas Gregor8e0a0e42009-09-22 23:31:26 +00003056 Results.ExitScope();
Douglas Gregore6b1bb62010-08-11 21:23:17 +00003057 HandleCodeCompleteResults(this, CodeCompleter,
Douglas Gregor8071e422010-08-15 06:18:01 +00003058 CodeCompletionContext::CCC_Namespace,
Douglas Gregore6b1bb62010-08-11 21:23:17 +00003059 Results.data(),Results.size());
Douglas Gregor49f40bd2009-09-18 19:03:04 +00003060}
3061
3062void Sema::CodeCompleteNamespaceDecl(Scope *S) {
3063 if (!CodeCompleter)
3064 return;
3065
Douglas Gregor86d9a522009-09-21 16:56:56 +00003066 ResultBuilder Results(*this, &ResultBuilder::IsNamespace);
3067 DeclContext *Ctx = (DeclContext *)S->getEntity();
3068 if (!S->getParent())
3069 Ctx = Context.getTranslationUnitDecl();
3070
3071 if (Ctx && Ctx->isFileContext()) {
3072 // We only want to see those namespaces that have already been defined
3073 // within this scope, because its likely that the user is creating an
3074 // extended namespace declaration. Keep track of the most recent
3075 // definition of each namespace.
3076 std::map<NamespaceDecl *, NamespaceDecl *> OrigToLatest;
3077 for (DeclContext::specific_decl_iterator<NamespaceDecl>
3078 NS(Ctx->decls_begin()), NSEnd(Ctx->decls_end());
3079 NS != NSEnd; ++NS)
3080 OrigToLatest[NS->getOriginalNamespace()] = *NS;
3081
3082 // Add the most recent definition (or extended definition) of each
3083 // namespace to the list of results.
Douglas Gregor8e0a0e42009-09-22 23:31:26 +00003084 Results.EnterNewScope();
Douglas Gregor86d9a522009-09-21 16:56:56 +00003085 for (std::map<NamespaceDecl *, NamespaceDecl *>::iterator
3086 NS = OrigToLatest.begin(), NSEnd = OrigToLatest.end();
3087 NS != NSEnd; ++NS)
John McCall0a2c5e22010-08-25 06:19:51 +00003088 Results.AddResult(CodeCompletionResult(NS->second, 0),
Douglas Gregor608300b2010-01-14 16:14:35 +00003089 CurContext, 0, false);
Douglas Gregor8e0a0e42009-09-22 23:31:26 +00003090 Results.ExitScope();
Douglas Gregor86d9a522009-09-21 16:56:56 +00003091 }
3092
Douglas Gregore6b1bb62010-08-11 21:23:17 +00003093 HandleCodeCompleteResults(this, CodeCompleter,
3094 CodeCompletionContext::CCC_Other,
3095 Results.data(),Results.size());
Douglas Gregor49f40bd2009-09-18 19:03:04 +00003096}
3097
3098void Sema::CodeCompleteNamespaceAliasDecl(Scope *S) {
3099 if (!CodeCompleter)
3100 return;
3101
Douglas Gregor86d9a522009-09-21 16:56:56 +00003102 // After "namespace", we expect to see a namespace or alias.
3103 ResultBuilder Results(*this, &ResultBuilder::IsNamespaceOrAlias);
Douglas Gregor5d2fc402010-01-14 03:27:13 +00003104 CodeCompletionDeclConsumer Consumer(Results, CurContext);
Douglas Gregor8071e422010-08-15 06:18:01 +00003105 LookupVisibleDecls(S, LookupOrdinaryName, Consumer,
3106 CodeCompleter->includeGlobals());
Douglas Gregore6b1bb62010-08-11 21:23:17 +00003107 HandleCodeCompleteResults(this, CodeCompleter,
Douglas Gregor8071e422010-08-15 06:18:01 +00003108 CodeCompletionContext::CCC_Namespace,
Douglas Gregore6b1bb62010-08-11 21:23:17 +00003109 Results.data(),Results.size());
Douglas Gregor49f40bd2009-09-18 19:03:04 +00003110}
3111
Douglas Gregored8d3222009-09-18 20:05:18 +00003112void Sema::CodeCompleteOperatorName(Scope *S) {
3113 if (!CodeCompleter)
3114 return;
Douglas Gregor86d9a522009-09-21 16:56:56 +00003115
John McCall0a2c5e22010-08-25 06:19:51 +00003116 typedef CodeCompletionResult Result;
Douglas Gregor86d9a522009-09-21 16:56:56 +00003117 ResultBuilder Results(*this, &ResultBuilder::IsType);
Douglas Gregor8e0a0e42009-09-22 23:31:26 +00003118 Results.EnterNewScope();
Douglas Gregored8d3222009-09-18 20:05:18 +00003119
Douglas Gregor86d9a522009-09-21 16:56:56 +00003120 // Add the names of overloadable operators.
3121#define OVERLOADED_OPERATOR(Name,Spelling,Token,Unary,Binary,MemberOnly) \
3122 if (std::strcmp(Spelling, "?")) \
Douglas Gregora4477812010-01-14 16:01:26 +00003123 Results.AddResult(Result(Spelling));
Douglas Gregor86d9a522009-09-21 16:56:56 +00003124#include "clang/Basic/OperatorKinds.def"
3125
3126 // Add any type names visible from the current scope
Douglas Gregor45bcd432010-01-14 03:21:49 +00003127 Results.allowNestedNameSpecifiers();
Douglas Gregor5d2fc402010-01-14 03:27:13 +00003128 CodeCompletionDeclConsumer Consumer(Results, CurContext);
Douglas Gregor8071e422010-08-15 06:18:01 +00003129 LookupVisibleDecls(S, LookupOrdinaryName, Consumer,
3130 CodeCompleter->includeGlobals());
Douglas Gregor86d9a522009-09-21 16:56:56 +00003131
3132 // Add any type specifiers
Douglas Gregorbca403c2010-01-13 23:51:12 +00003133 AddTypeSpecifierResults(getLangOptions(), Results);
Douglas Gregor8e0a0e42009-09-22 23:31:26 +00003134 Results.ExitScope();
Douglas Gregor86d9a522009-09-21 16:56:56 +00003135
Douglas Gregore6b1bb62010-08-11 21:23:17 +00003136 HandleCodeCompleteResults(this, CodeCompleter,
Douglas Gregor8071e422010-08-15 06:18:01 +00003137 CodeCompletionContext::CCC_Type,
Douglas Gregore6b1bb62010-08-11 21:23:17 +00003138 Results.data(),Results.size());
Douglas Gregored8d3222009-09-18 20:05:18 +00003139}
Douglas Gregor49f40bd2009-09-18 19:03:04 +00003140
Douglas Gregorb6ac2452010-01-13 21:24:21 +00003141// Macro that expands to @Keyword or Keyword, depending on whether NeedAt is
3142// true or false.
3143#define OBJC_AT_KEYWORD_NAME(NeedAt,Keyword) NeedAt? "@" #Keyword : #Keyword
Douglas Gregorbca403c2010-01-13 23:51:12 +00003144static void AddObjCImplementationResults(const LangOptions &LangOpts,
Douglas Gregorb6ac2452010-01-13 21:24:21 +00003145 ResultBuilder &Results,
3146 bool NeedAt) {
John McCall0a2c5e22010-08-25 06:19:51 +00003147 typedef CodeCompletionResult Result;
Douglas Gregorb6ac2452010-01-13 21:24:21 +00003148 // Since we have an implementation, we can end it.
Douglas Gregora4477812010-01-14 16:01:26 +00003149 Results.AddResult(Result(OBJC_AT_KEYWORD_NAME(NeedAt,end)));
Douglas Gregorb6ac2452010-01-13 21:24:21 +00003150
3151 CodeCompletionString *Pattern = 0;
3152 if (LangOpts.ObjC2) {
3153 // @dynamic
3154 Pattern = new CodeCompletionString;
3155 Pattern->AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt,dynamic));
3156 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
3157 Pattern->AddPlaceholderChunk("property");
Douglas Gregora4477812010-01-14 16:01:26 +00003158 Results.AddResult(Result(Pattern));
Douglas Gregorb6ac2452010-01-13 21:24:21 +00003159
3160 // @synthesize
3161 Pattern = new CodeCompletionString;
3162 Pattern->AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt,synthesize));
3163 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
3164 Pattern->AddPlaceholderChunk("property");
Douglas Gregora4477812010-01-14 16:01:26 +00003165 Results.AddResult(Result(Pattern));
Douglas Gregorb6ac2452010-01-13 21:24:21 +00003166 }
3167}
3168
Douglas Gregorbca403c2010-01-13 23:51:12 +00003169static void AddObjCInterfaceResults(const LangOptions &LangOpts,
Douglas Gregorb6ac2452010-01-13 21:24:21 +00003170 ResultBuilder &Results,
3171 bool NeedAt) {
John McCall0a2c5e22010-08-25 06:19:51 +00003172 typedef CodeCompletionResult Result;
Douglas Gregorb6ac2452010-01-13 21:24:21 +00003173
3174 // Since we have an interface or protocol, we can end it.
Douglas Gregora4477812010-01-14 16:01:26 +00003175 Results.AddResult(Result(OBJC_AT_KEYWORD_NAME(NeedAt,end)));
Douglas Gregorb6ac2452010-01-13 21:24:21 +00003176
3177 if (LangOpts.ObjC2) {
3178 // @property
Douglas Gregora4477812010-01-14 16:01:26 +00003179 Results.AddResult(Result(OBJC_AT_KEYWORD_NAME(NeedAt,property)));
Douglas Gregorb6ac2452010-01-13 21:24:21 +00003180
3181 // @required
Douglas Gregora4477812010-01-14 16:01:26 +00003182 Results.AddResult(Result(OBJC_AT_KEYWORD_NAME(NeedAt,required)));
Douglas Gregorb6ac2452010-01-13 21:24:21 +00003183
3184 // @optional
Douglas Gregora4477812010-01-14 16:01:26 +00003185 Results.AddResult(Result(OBJC_AT_KEYWORD_NAME(NeedAt,optional)));
Douglas Gregorb6ac2452010-01-13 21:24:21 +00003186 }
3187}
3188
Douglas Gregorbca403c2010-01-13 23:51:12 +00003189static void AddObjCTopLevelResults(ResultBuilder &Results, bool NeedAt) {
John McCall0a2c5e22010-08-25 06:19:51 +00003190 typedef CodeCompletionResult Result;
Douglas Gregorb6ac2452010-01-13 21:24:21 +00003191 CodeCompletionString *Pattern = 0;
3192
3193 // @class name ;
3194 Pattern = new CodeCompletionString;
3195 Pattern->AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt,class));
3196 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
Douglas Gregorc8bddde2010-05-28 00:22:41 +00003197 Pattern->AddPlaceholderChunk("name");
Douglas Gregora4477812010-01-14 16:01:26 +00003198 Results.AddResult(Result(Pattern));
Douglas Gregorb6ac2452010-01-13 21:24:21 +00003199
Douglas Gregorc8bddde2010-05-28 00:22:41 +00003200 if (Results.includeCodePatterns()) {
3201 // @interface name
3202 // FIXME: Could introduce the whole pattern, including superclasses and
3203 // such.
3204 Pattern = new CodeCompletionString;
3205 Pattern->AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt,interface));
3206 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
3207 Pattern->AddPlaceholderChunk("class");
3208 Results.AddResult(Result(Pattern));
Douglas Gregorb6ac2452010-01-13 21:24:21 +00003209
Douglas Gregorc8bddde2010-05-28 00:22:41 +00003210 // @protocol name
3211 Pattern = new CodeCompletionString;
3212 Pattern->AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt,protocol));
3213 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
3214 Pattern->AddPlaceholderChunk("protocol");
3215 Results.AddResult(Result(Pattern));
3216
3217 // @implementation name
3218 Pattern = new CodeCompletionString;
3219 Pattern->AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt,implementation));
3220 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
3221 Pattern->AddPlaceholderChunk("class");
3222 Results.AddResult(Result(Pattern));
3223 }
Douglas Gregorb6ac2452010-01-13 21:24:21 +00003224
3225 // @compatibility_alias name
3226 Pattern = new CodeCompletionString;
3227 Pattern->AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt,compatibility_alias));
3228 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
3229 Pattern->AddPlaceholderChunk("alias");
3230 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
3231 Pattern->AddPlaceholderChunk("class");
Douglas Gregora4477812010-01-14 16:01:26 +00003232 Results.AddResult(Result(Pattern));
Douglas Gregorb6ac2452010-01-13 21:24:21 +00003233}
3234
John McCalld226f652010-08-21 09:40:31 +00003235void Sema::CodeCompleteObjCAtDirective(Scope *S, Decl *ObjCImpDecl,
Douglas Gregorc464ae82009-12-07 09:27:33 +00003236 bool InInterface) {
John McCall0a2c5e22010-08-25 06:19:51 +00003237 typedef CodeCompletionResult Result;
Douglas Gregorc464ae82009-12-07 09:27:33 +00003238 ResultBuilder Results(*this);
3239 Results.EnterNewScope();
Douglas Gregorb6ac2452010-01-13 21:24:21 +00003240 if (ObjCImpDecl)
Douglas Gregorbca403c2010-01-13 23:51:12 +00003241 AddObjCImplementationResults(getLangOptions(), Results, false);
Douglas Gregorb6ac2452010-01-13 21:24:21 +00003242 else if (InInterface)
Douglas Gregorbca403c2010-01-13 23:51:12 +00003243 AddObjCInterfaceResults(getLangOptions(), Results, false);
Douglas Gregorb6ac2452010-01-13 21:24:21 +00003244 else
Douglas Gregorbca403c2010-01-13 23:51:12 +00003245 AddObjCTopLevelResults(Results, false);
Douglas Gregorc464ae82009-12-07 09:27:33 +00003246 Results.ExitScope();
Douglas Gregore6b1bb62010-08-11 21:23:17 +00003247 HandleCodeCompleteResults(this, CodeCompleter,
3248 CodeCompletionContext::CCC_Other,
3249 Results.data(),Results.size());
Douglas Gregorc464ae82009-12-07 09:27:33 +00003250}
3251
Douglas Gregorbca403c2010-01-13 23:51:12 +00003252static void AddObjCExpressionResults(ResultBuilder &Results, bool NeedAt) {
John McCall0a2c5e22010-08-25 06:19:51 +00003253 typedef CodeCompletionResult Result;
Douglas Gregor9a0c85e2009-12-07 09:51:25 +00003254 CodeCompletionString *Pattern = 0;
3255
3256 // @encode ( type-name )
3257 Pattern = new CodeCompletionString;
Douglas Gregorb6ac2452010-01-13 21:24:21 +00003258 Pattern->AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt,encode));
Douglas Gregor9a0c85e2009-12-07 09:51:25 +00003259 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
3260 Pattern->AddPlaceholderChunk("type-name");
3261 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
Douglas Gregora4477812010-01-14 16:01:26 +00003262 Results.AddResult(Result(Pattern));
Douglas Gregor9a0c85e2009-12-07 09:51:25 +00003263
3264 // @protocol ( protocol-name )
3265 Pattern = new CodeCompletionString;
Douglas Gregorb6ac2452010-01-13 21:24:21 +00003266 Pattern->AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt,protocol));
Douglas Gregor9a0c85e2009-12-07 09:51:25 +00003267 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
3268 Pattern->AddPlaceholderChunk("protocol-name");
3269 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
Douglas Gregora4477812010-01-14 16:01:26 +00003270 Results.AddResult(Result(Pattern));
Douglas Gregor9a0c85e2009-12-07 09:51:25 +00003271
3272 // @selector ( selector )
3273 Pattern = new CodeCompletionString;
Douglas Gregorb6ac2452010-01-13 21:24:21 +00003274 Pattern->AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt,selector));
Douglas Gregor9a0c85e2009-12-07 09:51:25 +00003275 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
3276 Pattern->AddPlaceholderChunk("selector");
3277 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
Douglas Gregora4477812010-01-14 16:01:26 +00003278 Results.AddResult(Result(Pattern));
Douglas Gregor9a0c85e2009-12-07 09:51:25 +00003279}
3280
Douglas Gregorbca403c2010-01-13 23:51:12 +00003281static void AddObjCStatementResults(ResultBuilder &Results, bool NeedAt) {
John McCall0a2c5e22010-08-25 06:19:51 +00003282 typedef CodeCompletionResult Result;
Douglas Gregor9a0c85e2009-12-07 09:51:25 +00003283 CodeCompletionString *Pattern = 0;
Douglas Gregorb6ac2452010-01-13 21:24:21 +00003284
Douglas Gregorc8bddde2010-05-28 00:22:41 +00003285 if (Results.includeCodePatterns()) {
3286 // @try { statements } @catch ( declaration ) { statements } @finally
3287 // { statements }
3288 Pattern = new CodeCompletionString;
3289 Pattern->AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt,try));
3290 Pattern->AddChunk(CodeCompletionString::CK_LeftBrace);
3291 Pattern->AddPlaceholderChunk("statements");
3292 Pattern->AddChunk(CodeCompletionString::CK_RightBrace);
3293 Pattern->AddTextChunk("@catch");
3294 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
3295 Pattern->AddPlaceholderChunk("parameter");
3296 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
3297 Pattern->AddChunk(CodeCompletionString::CK_LeftBrace);
3298 Pattern->AddPlaceholderChunk("statements");
3299 Pattern->AddChunk(CodeCompletionString::CK_RightBrace);
3300 Pattern->AddTextChunk("@finally");
3301 Pattern->AddChunk(CodeCompletionString::CK_LeftBrace);
3302 Pattern->AddPlaceholderChunk("statements");
3303 Pattern->AddChunk(CodeCompletionString::CK_RightBrace);
3304 Results.AddResult(Result(Pattern));
3305 }
Douglas Gregorb6ac2452010-01-13 21:24:21 +00003306
Douglas Gregor9a0c85e2009-12-07 09:51:25 +00003307 // @throw
3308 Pattern = new CodeCompletionString;
Douglas Gregorb6ac2452010-01-13 21:24:21 +00003309 Pattern->AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt,throw));
Douglas Gregor834389b2010-01-12 06:38:28 +00003310 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
Douglas Gregor9a0c85e2009-12-07 09:51:25 +00003311 Pattern->AddPlaceholderChunk("expression");
Douglas Gregora4477812010-01-14 16:01:26 +00003312 Results.AddResult(Result(Pattern));
Douglas Gregorb6ac2452010-01-13 21:24:21 +00003313
Douglas Gregorc8bddde2010-05-28 00:22:41 +00003314 if (Results.includeCodePatterns()) {
3315 // @synchronized ( expression ) { statements }
3316 Pattern = new CodeCompletionString;
3317 Pattern->AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt,synchronized));
3318 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
3319 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
3320 Pattern->AddPlaceholderChunk("expression");
3321 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
3322 Pattern->AddChunk(CodeCompletionString::CK_LeftBrace);
3323 Pattern->AddPlaceholderChunk("statements");
3324 Pattern->AddChunk(CodeCompletionString::CK_RightBrace);
3325 Results.AddResult(Result(Pattern));
3326 }
Douglas Gregorb6ac2452010-01-13 21:24:21 +00003327}
Douglas Gregor9a0c85e2009-12-07 09:51:25 +00003328
Douglas Gregorbca403c2010-01-13 23:51:12 +00003329static void AddObjCVisibilityResults(const LangOptions &LangOpts,
Douglas Gregorc38c3e12010-01-13 21:54:15 +00003330 ResultBuilder &Results,
3331 bool NeedAt) {
John McCall0a2c5e22010-08-25 06:19:51 +00003332 typedef CodeCompletionResult Result;
Douglas Gregora4477812010-01-14 16:01:26 +00003333 Results.AddResult(Result(OBJC_AT_KEYWORD_NAME(NeedAt,private)));
3334 Results.AddResult(Result(OBJC_AT_KEYWORD_NAME(NeedAt,protected)));
3335 Results.AddResult(Result(OBJC_AT_KEYWORD_NAME(NeedAt,public)));
Douglas Gregorc38c3e12010-01-13 21:54:15 +00003336 if (LangOpts.ObjC2)
Douglas Gregora4477812010-01-14 16:01:26 +00003337 Results.AddResult(Result(OBJC_AT_KEYWORD_NAME(NeedAt,package)));
Douglas Gregorc38c3e12010-01-13 21:54:15 +00003338}
3339
3340void Sema::CodeCompleteObjCAtVisibility(Scope *S) {
3341 ResultBuilder Results(*this);
3342 Results.EnterNewScope();
Douglas Gregorbca403c2010-01-13 23:51:12 +00003343 AddObjCVisibilityResults(getLangOptions(), Results, false);
Douglas Gregorc38c3e12010-01-13 21:54:15 +00003344 Results.ExitScope();
Douglas Gregore6b1bb62010-08-11 21:23:17 +00003345 HandleCodeCompleteResults(this, CodeCompleter,
3346 CodeCompletionContext::CCC_Other,
3347 Results.data(),Results.size());
Douglas Gregorc38c3e12010-01-13 21:54:15 +00003348}
3349
3350void Sema::CodeCompleteObjCAtStatement(Scope *S) {
Douglas Gregorb6ac2452010-01-13 21:24:21 +00003351 ResultBuilder Results(*this);
3352 Results.EnterNewScope();
Douglas Gregorbca403c2010-01-13 23:51:12 +00003353 AddObjCStatementResults(Results, false);
3354 AddObjCExpressionResults(Results, false);
Douglas Gregor9a0c85e2009-12-07 09:51:25 +00003355 Results.ExitScope();
Douglas Gregore6b1bb62010-08-11 21:23:17 +00003356 HandleCodeCompleteResults(this, CodeCompleter,
3357 CodeCompletionContext::CCC_Other,
3358 Results.data(),Results.size());
Douglas Gregor9a0c85e2009-12-07 09:51:25 +00003359}
3360
3361void Sema::CodeCompleteObjCAtExpression(Scope *S) {
3362 ResultBuilder Results(*this);
3363 Results.EnterNewScope();
Douglas Gregorbca403c2010-01-13 23:51:12 +00003364 AddObjCExpressionResults(Results, false);
Douglas Gregor9a0c85e2009-12-07 09:51:25 +00003365 Results.ExitScope();
Douglas Gregore6b1bb62010-08-11 21:23:17 +00003366 HandleCodeCompleteResults(this, CodeCompleter,
3367 CodeCompletionContext::CCC_Other,
3368 Results.data(),Results.size());
Douglas Gregor9a0c85e2009-12-07 09:51:25 +00003369}
3370
Douglas Gregor988358f2009-11-19 00:14:45 +00003371/// \brief Determine whether the addition of the given flag to an Objective-C
3372/// property's attributes will cause a conflict.
3373static bool ObjCPropertyFlagConflicts(unsigned Attributes, unsigned NewFlag) {
3374 // Check if we've already added this flag.
3375 if (Attributes & NewFlag)
3376 return true;
3377
3378 Attributes |= NewFlag;
3379
3380 // Check for collisions with "readonly".
3381 if ((Attributes & ObjCDeclSpec::DQ_PR_readonly) &&
3382 (Attributes & (ObjCDeclSpec::DQ_PR_readwrite |
3383 ObjCDeclSpec::DQ_PR_assign |
3384 ObjCDeclSpec::DQ_PR_copy |
3385 ObjCDeclSpec::DQ_PR_retain)))
3386 return true;
3387
3388 // Check for more than one of { assign, copy, retain }.
3389 unsigned AssignCopyRetMask = Attributes & (ObjCDeclSpec::DQ_PR_assign |
3390 ObjCDeclSpec::DQ_PR_copy |
3391 ObjCDeclSpec::DQ_PR_retain);
3392 if (AssignCopyRetMask &&
3393 AssignCopyRetMask != ObjCDeclSpec::DQ_PR_assign &&
3394 AssignCopyRetMask != ObjCDeclSpec::DQ_PR_copy &&
3395 AssignCopyRetMask != ObjCDeclSpec::DQ_PR_retain)
3396 return true;
3397
3398 return false;
3399}
3400
Douglas Gregora93b1082009-11-18 23:08:07 +00003401void Sema::CodeCompleteObjCPropertyFlags(Scope *S, ObjCDeclSpec &ODS) {
Steve Naroffece8e712009-10-08 21:55:05 +00003402 if (!CodeCompleter)
3403 return;
Douglas Gregord3c68542009-11-19 01:08:35 +00003404
Steve Naroffece8e712009-10-08 21:55:05 +00003405 unsigned Attributes = ODS.getPropertyAttributes();
3406
John McCall0a2c5e22010-08-25 06:19:51 +00003407 typedef CodeCompletionResult Result;
Steve Naroffece8e712009-10-08 21:55:05 +00003408 ResultBuilder Results(*this);
3409 Results.EnterNewScope();
Douglas Gregor988358f2009-11-19 00:14:45 +00003410 if (!ObjCPropertyFlagConflicts(Attributes, ObjCDeclSpec::DQ_PR_readonly))
John McCall0a2c5e22010-08-25 06:19:51 +00003411 Results.AddResult(CodeCompletionResult("readonly"));
Douglas Gregor988358f2009-11-19 00:14:45 +00003412 if (!ObjCPropertyFlagConflicts(Attributes, ObjCDeclSpec::DQ_PR_assign))
John McCall0a2c5e22010-08-25 06:19:51 +00003413 Results.AddResult(CodeCompletionResult("assign"));
Douglas Gregor988358f2009-11-19 00:14:45 +00003414 if (!ObjCPropertyFlagConflicts(Attributes, ObjCDeclSpec::DQ_PR_readwrite))
John McCall0a2c5e22010-08-25 06:19:51 +00003415 Results.AddResult(CodeCompletionResult("readwrite"));
Douglas Gregor988358f2009-11-19 00:14:45 +00003416 if (!ObjCPropertyFlagConflicts(Attributes, ObjCDeclSpec::DQ_PR_retain))
John McCall0a2c5e22010-08-25 06:19:51 +00003417 Results.AddResult(CodeCompletionResult("retain"));
Douglas Gregor988358f2009-11-19 00:14:45 +00003418 if (!ObjCPropertyFlagConflicts(Attributes, ObjCDeclSpec::DQ_PR_copy))
John McCall0a2c5e22010-08-25 06:19:51 +00003419 Results.AddResult(CodeCompletionResult("copy"));
Douglas Gregor988358f2009-11-19 00:14:45 +00003420 if (!ObjCPropertyFlagConflicts(Attributes, ObjCDeclSpec::DQ_PR_nonatomic))
John McCall0a2c5e22010-08-25 06:19:51 +00003421 Results.AddResult(CodeCompletionResult("nonatomic"));
Douglas Gregor988358f2009-11-19 00:14:45 +00003422 if (!ObjCPropertyFlagConflicts(Attributes, ObjCDeclSpec::DQ_PR_setter)) {
Douglas Gregor54f01612009-11-19 00:01:57 +00003423 CodeCompletionString *Setter = new CodeCompletionString;
3424 Setter->AddTypedTextChunk("setter");
3425 Setter->AddTextChunk(" = ");
3426 Setter->AddPlaceholderChunk("method");
John McCall0a2c5e22010-08-25 06:19:51 +00003427 Results.AddResult(CodeCompletionResult(Setter));
Douglas Gregor54f01612009-11-19 00:01:57 +00003428 }
Douglas Gregor988358f2009-11-19 00:14:45 +00003429 if (!ObjCPropertyFlagConflicts(Attributes, ObjCDeclSpec::DQ_PR_getter)) {
Douglas Gregor54f01612009-11-19 00:01:57 +00003430 CodeCompletionString *Getter = new CodeCompletionString;
3431 Getter->AddTypedTextChunk("getter");
3432 Getter->AddTextChunk(" = ");
3433 Getter->AddPlaceholderChunk("method");
John McCall0a2c5e22010-08-25 06:19:51 +00003434 Results.AddResult(CodeCompletionResult(Getter));
Douglas Gregor54f01612009-11-19 00:01:57 +00003435 }
Steve Naroffece8e712009-10-08 21:55:05 +00003436 Results.ExitScope();
Douglas Gregore6b1bb62010-08-11 21:23:17 +00003437 HandleCodeCompleteResults(this, CodeCompleter,
3438 CodeCompletionContext::CCC_Other,
3439 Results.data(),Results.size());
Steve Naroffece8e712009-10-08 21:55:05 +00003440}
Steve Naroffc4df6d22009-11-07 02:08:14 +00003441
Douglas Gregor4ad96852009-11-19 07:41:15 +00003442/// \brief Descripts the kind of Objective-C method that we want to find
3443/// via code completion.
3444enum ObjCMethodKind {
3445 MK_Any, //< Any kind of method, provided it means other specified criteria.
3446 MK_ZeroArgSelector, //< Zero-argument (unary) selector.
3447 MK_OneArgSelector //< One-argument selector.
3448};
3449
Douglas Gregor458433d2010-08-26 15:07:07 +00003450static bool isAcceptableObjCSelector(Selector Sel,
3451 ObjCMethodKind WantKind,
3452 IdentifierInfo **SelIdents,
3453 unsigned NumSelIdents) {
3454 if (NumSelIdents > Sel.getNumArgs())
3455 return false;
3456
3457 switch (WantKind) {
3458 case MK_Any: break;
3459 case MK_ZeroArgSelector: return Sel.isUnarySelector();
3460 case MK_OneArgSelector: return Sel.getNumArgs() == 1;
3461 }
3462
3463 for (unsigned I = 0; I != NumSelIdents; ++I)
3464 if (SelIdents[I] != Sel.getIdentifierInfoForSlot(I))
3465 return false;
3466
3467 return true;
3468}
3469
Douglas Gregor4ad96852009-11-19 07:41:15 +00003470static bool isAcceptableObjCMethod(ObjCMethodDecl *Method,
3471 ObjCMethodKind WantKind,
3472 IdentifierInfo **SelIdents,
3473 unsigned NumSelIdents) {
Douglas Gregor458433d2010-08-26 15:07:07 +00003474 return isAcceptableObjCSelector(Method->getSelector(), WantKind, SelIdents,
3475 NumSelIdents);
Douglas Gregor4ad96852009-11-19 07:41:15 +00003476}
3477
Douglas Gregor36ecb042009-11-17 23:22:23 +00003478/// \brief Add all of the Objective-C methods in the given Objective-C
3479/// container to the set of results.
3480///
3481/// The container will be a class, protocol, category, or implementation of
3482/// any of the above. This mether will recurse to include methods from
3483/// the superclasses of classes along with their categories, protocols, and
3484/// implementations.
3485///
3486/// \param Container the container in which we'll look to find methods.
3487///
3488/// \param WantInstance whether to add instance methods (only); if false, this
3489/// routine will add factory methods (only).
3490///
3491/// \param CurContext the context in which we're performing the lookup that
3492/// finds methods.
3493///
3494/// \param Results the structure into which we'll add results.
3495static void AddObjCMethods(ObjCContainerDecl *Container,
3496 bool WantInstanceMethods,
Douglas Gregor4ad96852009-11-19 07:41:15 +00003497 ObjCMethodKind WantKind,
Douglas Gregord3c68542009-11-19 01:08:35 +00003498 IdentifierInfo **SelIdents,
3499 unsigned NumSelIdents,
Douglas Gregor36ecb042009-11-17 23:22:23 +00003500 DeclContext *CurContext,
Douglas Gregor408be5a2010-08-25 01:08:01 +00003501 ResultBuilder &Results,
3502 bool InOriginalClass = true) {
John McCall0a2c5e22010-08-25 06:19:51 +00003503 typedef CodeCompletionResult Result;
Douglas Gregor36ecb042009-11-17 23:22:23 +00003504 for (ObjCContainerDecl::method_iterator M = Container->meth_begin(),
3505 MEnd = Container->meth_end();
3506 M != MEnd; ++M) {
Douglas Gregord3c68542009-11-19 01:08:35 +00003507 if ((*M)->isInstanceMethod() == WantInstanceMethods) {
3508 // Check whether the selector identifiers we've been given are a
3509 // subset of the identifiers for this particular method.
Douglas Gregor4ad96852009-11-19 07:41:15 +00003510 if (!isAcceptableObjCMethod(*M, WantKind, SelIdents, NumSelIdents))
Douglas Gregord3c68542009-11-19 01:08:35 +00003511 continue;
Douglas Gregor4ad96852009-11-19 07:41:15 +00003512
Douglas Gregord3c68542009-11-19 01:08:35 +00003513 Result R = Result(*M, 0);
3514 R.StartParameter = NumSelIdents;
Douglas Gregor4ad96852009-11-19 07:41:15 +00003515 R.AllParametersAreInformative = (WantKind != MK_Any);
Douglas Gregor408be5a2010-08-25 01:08:01 +00003516 if (!InOriginalClass)
3517 R.Priority += CCD_InBaseClass;
Douglas Gregord3c68542009-11-19 01:08:35 +00003518 Results.MaybeAddResult(R, CurContext);
3519 }
Douglas Gregor36ecb042009-11-17 23:22:23 +00003520 }
3521
3522 ObjCInterfaceDecl *IFace = dyn_cast<ObjCInterfaceDecl>(Container);
3523 if (!IFace)
3524 return;
3525
3526 // Add methods in protocols.
3527 const ObjCList<ObjCProtocolDecl> &Protocols= IFace->getReferencedProtocols();
3528 for (ObjCList<ObjCProtocolDecl>::iterator I = Protocols.begin(),
3529 E = Protocols.end();
3530 I != E; ++I)
Douglas Gregor4ad96852009-11-19 07:41:15 +00003531 AddObjCMethods(*I, WantInstanceMethods, WantKind, SelIdents, NumSelIdents,
Douglas Gregor408be5a2010-08-25 01:08:01 +00003532 CurContext, Results, false);
Douglas Gregor36ecb042009-11-17 23:22:23 +00003533
3534 // Add methods in categories.
3535 for (ObjCCategoryDecl *CatDecl = IFace->getCategoryList(); CatDecl;
3536 CatDecl = CatDecl->getNextClassCategory()) {
Douglas Gregor4ad96852009-11-19 07:41:15 +00003537 AddObjCMethods(CatDecl, WantInstanceMethods, WantKind, SelIdents,
Douglas Gregor408be5a2010-08-25 01:08:01 +00003538 NumSelIdents, CurContext, Results, InOriginalClass);
Douglas Gregor36ecb042009-11-17 23:22:23 +00003539
3540 // Add a categories protocol methods.
3541 const ObjCList<ObjCProtocolDecl> &Protocols
3542 = CatDecl->getReferencedProtocols();
3543 for (ObjCList<ObjCProtocolDecl>::iterator I = Protocols.begin(),
3544 E = Protocols.end();
3545 I != E; ++I)
Douglas Gregor4ad96852009-11-19 07:41:15 +00003546 AddObjCMethods(*I, WantInstanceMethods, WantKind, SelIdents,
Douglas Gregor408be5a2010-08-25 01:08:01 +00003547 NumSelIdents, CurContext, Results, false);
Douglas Gregor36ecb042009-11-17 23:22:23 +00003548
3549 // Add methods in category implementations.
3550 if (ObjCCategoryImplDecl *Impl = CatDecl->getImplementation())
Douglas Gregor4ad96852009-11-19 07:41:15 +00003551 AddObjCMethods(Impl, WantInstanceMethods, WantKind, SelIdents,
Douglas Gregor408be5a2010-08-25 01:08:01 +00003552 NumSelIdents, CurContext, Results, InOriginalClass);
Douglas Gregor36ecb042009-11-17 23:22:23 +00003553 }
3554
3555 // Add methods in superclass.
3556 if (IFace->getSuperClass())
Douglas Gregor4ad96852009-11-19 07:41:15 +00003557 AddObjCMethods(IFace->getSuperClass(), WantInstanceMethods, WantKind,
Douglas Gregor408be5a2010-08-25 01:08:01 +00003558 SelIdents, NumSelIdents, CurContext, Results, false);
Douglas Gregor36ecb042009-11-17 23:22:23 +00003559
3560 // Add methods in our implementation, if any.
3561 if (ObjCImplementationDecl *Impl = IFace->getImplementation())
Douglas Gregor4ad96852009-11-19 07:41:15 +00003562 AddObjCMethods(Impl, WantInstanceMethods, WantKind, SelIdents,
Douglas Gregor408be5a2010-08-25 01:08:01 +00003563 NumSelIdents, CurContext, Results, InOriginalClass);
Douglas Gregor4ad96852009-11-19 07:41:15 +00003564}
3565
3566
John McCalld226f652010-08-21 09:40:31 +00003567void Sema::CodeCompleteObjCPropertyGetter(Scope *S, Decl *ClassDecl,
3568 Decl **Methods,
Douglas Gregor4ad96852009-11-19 07:41:15 +00003569 unsigned NumMethods) {
John McCall0a2c5e22010-08-25 06:19:51 +00003570 typedef CodeCompletionResult Result;
Douglas Gregor4ad96852009-11-19 07:41:15 +00003571
3572 // Try to find the interface where getters might live.
John McCalld226f652010-08-21 09:40:31 +00003573 ObjCInterfaceDecl *Class = dyn_cast_or_null<ObjCInterfaceDecl>(ClassDecl);
Douglas Gregor4ad96852009-11-19 07:41:15 +00003574 if (!Class) {
3575 if (ObjCCategoryDecl *Category
John McCalld226f652010-08-21 09:40:31 +00003576 = dyn_cast_or_null<ObjCCategoryDecl>(ClassDecl))
Douglas Gregor4ad96852009-11-19 07:41:15 +00003577 Class = Category->getClassInterface();
3578
3579 if (!Class)
3580 return;
3581 }
3582
3583 // Find all of the potential getters.
3584 ResultBuilder Results(*this);
3585 Results.EnterNewScope();
3586
3587 // FIXME: We need to do this because Objective-C methods don't get
3588 // pushed into DeclContexts early enough. Argh!
3589 for (unsigned I = 0; I != NumMethods; ++I) {
3590 if (ObjCMethodDecl *Method
John McCalld226f652010-08-21 09:40:31 +00003591 = dyn_cast_or_null<ObjCMethodDecl>(Methods[I]))
Douglas Gregor4ad96852009-11-19 07:41:15 +00003592 if (Method->isInstanceMethod() &&
3593 isAcceptableObjCMethod(Method, MK_ZeroArgSelector, 0, 0)) {
3594 Result R = Result(Method, 0);
3595 R.AllParametersAreInformative = true;
3596 Results.MaybeAddResult(R, CurContext);
3597 }
3598 }
3599
3600 AddObjCMethods(Class, true, MK_ZeroArgSelector, 0, 0, CurContext, Results);
3601 Results.ExitScope();
Douglas Gregore6b1bb62010-08-11 21:23:17 +00003602 HandleCodeCompleteResults(this, CodeCompleter,
3603 CodeCompletionContext::CCC_Other,
3604 Results.data(),Results.size());
Douglas Gregor4ad96852009-11-19 07:41:15 +00003605}
3606
John McCalld226f652010-08-21 09:40:31 +00003607void Sema::CodeCompleteObjCPropertySetter(Scope *S, Decl *ObjCImplDecl,
3608 Decl **Methods,
Douglas Gregor4ad96852009-11-19 07:41:15 +00003609 unsigned NumMethods) {
John McCall0a2c5e22010-08-25 06:19:51 +00003610 typedef CodeCompletionResult Result;
Douglas Gregor4ad96852009-11-19 07:41:15 +00003611
3612 // Try to find the interface where setters might live.
3613 ObjCInterfaceDecl *Class
John McCalld226f652010-08-21 09:40:31 +00003614 = dyn_cast_or_null<ObjCInterfaceDecl>(ObjCImplDecl);
Douglas Gregor4ad96852009-11-19 07:41:15 +00003615 if (!Class) {
3616 if (ObjCCategoryDecl *Category
John McCalld226f652010-08-21 09:40:31 +00003617 = dyn_cast_or_null<ObjCCategoryDecl>(ObjCImplDecl))
Douglas Gregor4ad96852009-11-19 07:41:15 +00003618 Class = Category->getClassInterface();
3619
3620 if (!Class)
3621 return;
3622 }
3623
3624 // Find all of the potential getters.
3625 ResultBuilder Results(*this);
3626 Results.EnterNewScope();
3627
3628 // FIXME: We need to do this because Objective-C methods don't get
3629 // pushed into DeclContexts early enough. Argh!
3630 for (unsigned I = 0; I != NumMethods; ++I) {
3631 if (ObjCMethodDecl *Method
John McCalld226f652010-08-21 09:40:31 +00003632 = dyn_cast_or_null<ObjCMethodDecl>(Methods[I]))
Douglas Gregor4ad96852009-11-19 07:41:15 +00003633 if (Method->isInstanceMethod() &&
3634 isAcceptableObjCMethod(Method, MK_OneArgSelector, 0, 0)) {
3635 Result R = Result(Method, 0);
3636 R.AllParametersAreInformative = true;
3637 Results.MaybeAddResult(R, CurContext);
3638 }
3639 }
3640
3641 AddObjCMethods(Class, true, MK_OneArgSelector, 0, 0, CurContext, Results);
3642
3643 Results.ExitScope();
Douglas Gregore6b1bb62010-08-11 21:23:17 +00003644 HandleCodeCompleteResults(this, CodeCompleter,
3645 CodeCompletionContext::CCC_Other,
3646 Results.data(),Results.size());
Douglas Gregor36ecb042009-11-17 23:22:23 +00003647}
3648
Douglas Gregord32b0222010-08-24 01:06:58 +00003649void Sema::CodeCompleteObjCPassingType(Scope *S, ObjCDeclSpec &DS) {
John McCall0a2c5e22010-08-25 06:19:51 +00003650 typedef CodeCompletionResult Result;
Douglas Gregord32b0222010-08-24 01:06:58 +00003651 ResultBuilder Results(*this);
3652 Results.EnterNewScope();
3653
3654 // Add context-sensitive, Objective-C parameter-passing keywords.
3655 bool AddedInOut = false;
3656 if ((DS.getObjCDeclQualifier() &
3657 (ObjCDeclSpec::DQ_In | ObjCDeclSpec::DQ_Inout)) == 0) {
3658 Results.AddResult("in");
3659 Results.AddResult("inout");
3660 AddedInOut = true;
3661 }
3662 if ((DS.getObjCDeclQualifier() &
3663 (ObjCDeclSpec::DQ_Out | ObjCDeclSpec::DQ_Inout)) == 0) {
3664 Results.AddResult("out");
3665 if (!AddedInOut)
3666 Results.AddResult("inout");
3667 }
3668 if ((DS.getObjCDeclQualifier() &
3669 (ObjCDeclSpec::DQ_Bycopy | ObjCDeclSpec::DQ_Byref |
3670 ObjCDeclSpec::DQ_Oneway)) == 0) {
3671 Results.AddResult("bycopy");
3672 Results.AddResult("byref");
3673 Results.AddResult("oneway");
3674 }
3675
3676 // Add various builtin type names and specifiers.
3677 AddOrdinaryNameResults(PCC_Type, S, *this, Results);
3678 Results.ExitScope();
3679
3680 // Add the various type names
3681 Results.setFilter(&ResultBuilder::IsOrdinaryNonValueName);
3682 CodeCompletionDeclConsumer Consumer(Results, CurContext);
3683 LookupVisibleDecls(S, LookupOrdinaryName, Consumer,
3684 CodeCompleter->includeGlobals());
3685
3686 if (CodeCompleter->includeMacros())
3687 AddMacroResults(PP, Results);
3688
3689 HandleCodeCompleteResults(this, CodeCompleter,
3690 CodeCompletionContext::CCC_Type,
3691 Results.data(), Results.size());
3692}
3693
Douglas Gregor22f56992010-04-06 19:22:33 +00003694/// \brief When we have an expression with type "id", we may assume
3695/// that it has some more-specific class type based on knowledge of
3696/// common uses of Objective-C. This routine returns that class type,
3697/// or NULL if no better result could be determined.
3698static ObjCInterfaceDecl *GetAssumedMessageSendExprType(Expr *E) {
3699 ObjCMessageExpr *Msg = dyn_cast<ObjCMessageExpr>(E);
3700 if (!Msg)
3701 return 0;
3702
3703 Selector Sel = Msg->getSelector();
3704 if (Sel.isNull())
3705 return 0;
3706
3707 IdentifierInfo *Id = Sel.getIdentifierInfoForSlot(0);
3708 if (!Id)
3709 return 0;
3710
3711 ObjCMethodDecl *Method = Msg->getMethodDecl();
3712 if (!Method)
3713 return 0;
3714
3715 // Determine the class that we're sending the message to.
Douglas Gregor04badcf2010-04-21 00:45:42 +00003716 ObjCInterfaceDecl *IFace = 0;
3717 switch (Msg->getReceiverKind()) {
3718 case ObjCMessageExpr::Class:
John McCallc12c5bb2010-05-15 11:32:37 +00003719 if (const ObjCObjectType *ObjType
3720 = Msg->getClassReceiver()->getAs<ObjCObjectType>())
3721 IFace = ObjType->getInterface();
Douglas Gregor04badcf2010-04-21 00:45:42 +00003722 break;
3723
3724 case ObjCMessageExpr::Instance: {
3725 QualType T = Msg->getInstanceReceiver()->getType();
3726 if (const ObjCObjectPointerType *Ptr = T->getAs<ObjCObjectPointerType>())
3727 IFace = Ptr->getInterfaceDecl();
3728 break;
3729 }
3730
3731 case ObjCMessageExpr::SuperInstance:
3732 case ObjCMessageExpr::SuperClass:
3733 break;
Douglas Gregor22f56992010-04-06 19:22:33 +00003734 }
3735
3736 if (!IFace)
3737 return 0;
3738
3739 ObjCInterfaceDecl *Super = IFace->getSuperClass();
3740 if (Method->isInstanceMethod())
3741 return llvm::StringSwitch<ObjCInterfaceDecl *>(Id->getName())
3742 .Case("retain", IFace)
3743 .Case("autorelease", IFace)
3744 .Case("copy", IFace)
3745 .Case("copyWithZone", IFace)
3746 .Case("mutableCopy", IFace)
3747 .Case("mutableCopyWithZone", IFace)
3748 .Case("awakeFromCoder", IFace)
3749 .Case("replacementObjectFromCoder", IFace)
3750 .Case("class", IFace)
3751 .Case("classForCoder", IFace)
3752 .Case("superclass", Super)
3753 .Default(0);
3754
3755 return llvm::StringSwitch<ObjCInterfaceDecl *>(Id->getName())
3756 .Case("new", IFace)
3757 .Case("alloc", IFace)
3758 .Case("allocWithZone", IFace)
3759 .Case("class", IFace)
3760 .Case("superclass", Super)
3761 .Default(0);
3762}
3763
Douglas Gregor03d8aec2010-08-27 15:10:57 +00003764// Add a special completion for a message send to "super", which fills in the
3765// most likely case of forwarding all of our arguments to the superclass
3766// function.
3767///
3768/// \param S The semantic analysis object.
3769///
3770/// \param S NeedSuperKeyword Whether we need to prefix this completion with
3771/// the "super" keyword. Otherwise, we just need to provide the arguments.
3772///
3773/// \param SelIdents The identifiers in the selector that have already been
3774/// provided as arguments for a send to "super".
3775///
3776/// \param NumSelIdents The number of identifiers in \p SelIdents.
3777///
3778/// \param Results The set of results to augment.
3779///
3780/// \returns the Objective-C method declaration that would be invoked by
3781/// this "super" completion. If NULL, no completion was added.
3782static ObjCMethodDecl *AddSuperSendCompletion(Sema &S, bool NeedSuperKeyword,
3783 IdentifierInfo **SelIdents,
3784 unsigned NumSelIdents,
3785 ResultBuilder &Results) {
3786 ObjCMethodDecl *CurMethod = S.getCurMethodDecl();
3787 if (!CurMethod)
3788 return 0;
3789
3790 ObjCInterfaceDecl *Class = CurMethod->getClassInterface();
3791 if (!Class)
3792 return 0;
3793
3794 // Try to find a superclass method with the same selector.
3795 ObjCMethodDecl *SuperMethod = 0;
3796 while ((Class = Class->getSuperClass()) && !SuperMethod)
3797 SuperMethod = Class->getMethod(CurMethod->getSelector(),
3798 CurMethod->isInstanceMethod());
3799
3800 if (!SuperMethod)
3801 return 0;
3802
3803 // Check whether the superclass method has the same signature.
3804 if (CurMethod->param_size() != SuperMethod->param_size() ||
3805 CurMethod->isVariadic() != SuperMethod->isVariadic())
3806 return 0;
3807
3808 for (ObjCMethodDecl::param_iterator CurP = CurMethod->param_begin(),
3809 CurPEnd = CurMethod->param_end(),
3810 SuperP = SuperMethod->param_begin();
3811 CurP != CurPEnd; ++CurP, ++SuperP) {
3812 // Make sure the parameter types are compatible.
3813 if (!S.Context.hasSameUnqualifiedType((*CurP)->getType(),
3814 (*SuperP)->getType()))
3815 return 0;
3816
3817 // Make sure we have a parameter name to forward!
3818 if (!(*CurP)->getIdentifier())
3819 return 0;
3820 }
3821
3822 // We have a superclass method. Now, form the send-to-super completion.
3823 CodeCompletionString *Pattern = new CodeCompletionString;
3824
3825 // Give this completion a return type.
3826 AddResultTypeChunk(S.Context, SuperMethod, Pattern);
3827
3828 // If we need the "super" keyword, add it (plus some spacing).
3829 if (NeedSuperKeyword) {
3830 Pattern->AddTypedTextChunk("super");
3831 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
3832 }
3833
3834 Selector Sel = CurMethod->getSelector();
3835 if (Sel.isUnarySelector()) {
3836 if (NeedSuperKeyword)
3837 Pattern->AddTextChunk(Sel.getIdentifierInfoForSlot(0)->getName());
3838 else
3839 Pattern->AddTypedTextChunk(Sel.getIdentifierInfoForSlot(0)->getName());
3840 } else {
3841 ObjCMethodDecl::param_iterator CurP = CurMethod->param_begin();
3842 for (unsigned I = 0, N = Sel.getNumArgs(); I != N; ++I, ++CurP) {
3843 if (I > NumSelIdents)
3844 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
3845
3846 if (I < NumSelIdents)
3847 Pattern->AddInformativeChunk(
3848 Sel.getIdentifierInfoForSlot(I)->getName().str() + ":");
3849 else if (NeedSuperKeyword || I > NumSelIdents) {
3850 Pattern->AddTextChunk(
3851 Sel.getIdentifierInfoForSlot(I)->getName().str() + ":");
3852 Pattern->AddPlaceholderChunk((*CurP)->getIdentifier()->getName());
3853 } else {
3854 Pattern->AddTypedTextChunk(
3855 Sel.getIdentifierInfoForSlot(I)->getName().str() + ":");
3856 Pattern->AddPlaceholderChunk((*CurP)->getIdentifier()->getName());
3857 }
3858 }
3859 }
3860
3861 Results.AddResult(CodeCompletionResult(Pattern, CCP_SuperCompletion,
3862 SuperMethod->isInstanceMethod()
3863 ? CXCursor_ObjCInstanceMethodDecl
3864 : CXCursor_ObjCClassMethodDecl));
3865 return SuperMethod;
3866}
3867
Douglas Gregor8e254cf2010-05-27 23:06:34 +00003868void Sema::CodeCompleteObjCMessageReceiver(Scope *S) {
John McCall0a2c5e22010-08-25 06:19:51 +00003869 typedef CodeCompletionResult Result;
Douglas Gregor8e254cf2010-05-27 23:06:34 +00003870 ResultBuilder Results(*this);
3871
3872 // Find anything that looks like it could be a message receiver.
3873 Results.setFilter(&ResultBuilder::IsObjCMessageReceiver);
3874 CodeCompletionDeclConsumer Consumer(Results, CurContext);
3875 Results.EnterNewScope();
Douglas Gregor8071e422010-08-15 06:18:01 +00003876 LookupVisibleDecls(S, LookupOrdinaryName, Consumer,
3877 CodeCompleter->includeGlobals());
Douglas Gregor8e254cf2010-05-27 23:06:34 +00003878
3879 // If we are in an Objective-C method inside a class that has a superclass,
3880 // add "super" as an option.
3881 if (ObjCMethodDecl *Method = getCurMethodDecl())
3882 if (ObjCInterfaceDecl *Iface = Method->getClassInterface())
Douglas Gregor03d8aec2010-08-27 15:10:57 +00003883 if (Iface->getSuperClass()) {
Douglas Gregor8e254cf2010-05-27 23:06:34 +00003884 Results.AddResult(Result("super"));
Douglas Gregor03d8aec2010-08-27 15:10:57 +00003885
3886 AddSuperSendCompletion(*this, /*NeedSuperKeyword=*/true, 0, 0, Results);
3887 }
Douglas Gregor8e254cf2010-05-27 23:06:34 +00003888
3889 Results.ExitScope();
3890
3891 if (CodeCompleter->includeMacros())
3892 AddMacroResults(PP, Results);
Douglas Gregore6b1bb62010-08-11 21:23:17 +00003893 HandleCodeCompleteResults(this, CodeCompleter,
3894 CodeCompletionContext::CCC_ObjCMessageReceiver,
3895 Results.data(), Results.size());
Douglas Gregor8e254cf2010-05-27 23:06:34 +00003896
3897}
3898
Douglas Gregor2725ca82010-04-21 19:57:20 +00003899void Sema::CodeCompleteObjCSuperMessage(Scope *S, SourceLocation SuperLoc,
3900 IdentifierInfo **SelIdents,
3901 unsigned NumSelIdents) {
3902 ObjCInterfaceDecl *CDecl = 0;
3903 if (ObjCMethodDecl *CurMethod = getCurMethodDecl()) {
3904 // Figure out which interface we're in.
3905 CDecl = CurMethod->getClassInterface();
3906 if (!CDecl)
3907 return;
3908
3909 // Find the superclass of this class.
3910 CDecl = CDecl->getSuperClass();
3911 if (!CDecl)
3912 return;
3913
3914 if (CurMethod->isInstanceMethod()) {
3915 // We are inside an instance method, which means that the message
3916 // send [super ...] is actually calling an instance method on the
3917 // current object. Build the super expression and handle this like
3918 // an instance method.
3919 QualType SuperTy = Context.getObjCInterfaceType(CDecl);
3920 SuperTy = Context.getObjCObjectPointerType(SuperTy);
John McCall60d7b3a2010-08-24 06:29:42 +00003921 ExprResult Super
Douglas Gregor2725ca82010-04-21 19:57:20 +00003922 = Owned(new (Context) ObjCSuperExpr(SuperLoc, SuperTy));
3923 return CodeCompleteObjCInstanceMessage(S, (Expr *)Super.get(),
Douglas Gregor03d8aec2010-08-27 15:10:57 +00003924 SelIdents, NumSelIdents,
3925 /*IsSuper=*/true);
Douglas Gregor2725ca82010-04-21 19:57:20 +00003926 }
3927
3928 // Fall through to send to the superclass in CDecl.
3929 } else {
3930 // "super" may be the name of a type or variable. Figure out which
3931 // it is.
3932 IdentifierInfo *Super = &Context.Idents.get("super");
3933 NamedDecl *ND = LookupSingleName(S, Super, SuperLoc,
3934 LookupOrdinaryName);
3935 if ((CDecl = dyn_cast_or_null<ObjCInterfaceDecl>(ND))) {
3936 // "super" names an interface. Use it.
3937 } else if (TypeDecl *TD = dyn_cast_or_null<TypeDecl>(ND)) {
John McCallc12c5bb2010-05-15 11:32:37 +00003938 if (const ObjCObjectType *Iface
3939 = Context.getTypeDeclType(TD)->getAs<ObjCObjectType>())
3940 CDecl = Iface->getInterface();
Douglas Gregor2725ca82010-04-21 19:57:20 +00003941 } else if (ND && isa<UnresolvedUsingTypenameDecl>(ND)) {
3942 // "super" names an unresolved type; we can't be more specific.
3943 } else {
3944 // Assume that "super" names some kind of value and parse that way.
3945 CXXScopeSpec SS;
3946 UnqualifiedId id;
3947 id.setIdentifier(Super, SuperLoc);
John McCall60d7b3a2010-08-24 06:29:42 +00003948 ExprResult SuperExpr = ActOnIdExpression(S, SS, id, false, false);
Douglas Gregor2725ca82010-04-21 19:57:20 +00003949 return CodeCompleteObjCInstanceMessage(S, (Expr *)SuperExpr.get(),
3950 SelIdents, NumSelIdents);
3951 }
3952
3953 // Fall through
3954 }
3955
John McCallb3d87482010-08-24 05:47:05 +00003956 ParsedType Receiver;
Douglas Gregor2725ca82010-04-21 19:57:20 +00003957 if (CDecl)
John McCallb3d87482010-08-24 05:47:05 +00003958 Receiver = ParsedType::make(Context.getObjCInterfaceType(CDecl));
Douglas Gregor2725ca82010-04-21 19:57:20 +00003959 return CodeCompleteObjCClassMessage(S, Receiver, SelIdents,
Douglas Gregor03d8aec2010-08-27 15:10:57 +00003960 NumSelIdents, /*IsSuper=*/true);
Douglas Gregor2725ca82010-04-21 19:57:20 +00003961}
3962
John McCallb3d87482010-08-24 05:47:05 +00003963void Sema::CodeCompleteObjCClassMessage(Scope *S, ParsedType Receiver,
Douglas Gregord3c68542009-11-19 01:08:35 +00003964 IdentifierInfo **SelIdents,
3965 unsigned NumSelIdents) {
Douglas Gregor03d8aec2010-08-27 15:10:57 +00003966 CodeCompleteObjCClassMessage(S, Receiver, SelIdents, NumSelIdents, false);
3967}
3968
3969void Sema::CodeCompleteObjCClassMessage(Scope *S, ParsedType Receiver,
3970 IdentifierInfo **SelIdents,
3971 unsigned NumSelIdents,
3972 bool IsSuper) {
John McCall0a2c5e22010-08-25 06:19:51 +00003973 typedef CodeCompletionResult Result;
Douglas Gregor24a069f2009-11-17 17:59:40 +00003974 ObjCInterfaceDecl *CDecl = 0;
3975
Douglas Gregor24a069f2009-11-17 17:59:40 +00003976 // If the given name refers to an interface type, retrieve the
3977 // corresponding declaration.
Douglas Gregor2725ca82010-04-21 19:57:20 +00003978 if (Receiver) {
3979 QualType T = GetTypeFromParser(Receiver, 0);
3980 if (!T.isNull())
John McCallc12c5bb2010-05-15 11:32:37 +00003981 if (const ObjCObjectType *Interface = T->getAs<ObjCObjectType>())
3982 CDecl = Interface->getInterface();
Douglas Gregor24a069f2009-11-17 17:59:40 +00003983 }
3984
Douglas Gregor36ecb042009-11-17 23:22:23 +00003985 // Add all of the factory methods in this Objective-C class, its protocols,
3986 // superclasses, categories, implementation, etc.
Steve Naroffc4df6d22009-11-07 02:08:14 +00003987 ResultBuilder Results(*this);
3988 Results.EnterNewScope();
Douglas Gregor13438f92010-04-06 16:40:00 +00003989
Douglas Gregor03d8aec2010-08-27 15:10:57 +00003990 // If this is a send-to-super, try to add the special "super" send
3991 // completion.
3992 if (IsSuper) {
3993 if (ObjCMethodDecl *SuperMethod
3994 = AddSuperSendCompletion(*this, false, SelIdents, NumSelIdents,
3995 Results))
3996 Results.Ignore(SuperMethod);
3997 }
3998
Douglas Gregor13438f92010-04-06 16:40:00 +00003999 if (CDecl)
4000 AddObjCMethods(CDecl, false, MK_Any, SelIdents, NumSelIdents, CurContext,
4001 Results);
Douglas Gregor2725ca82010-04-21 19:57:20 +00004002 else {
Douglas Gregor13438f92010-04-06 16:40:00 +00004003 // We're messaging "id" as a type; provide all class/factory methods.
4004
Douglas Gregor719770d2010-04-06 17:30:22 +00004005 // If we have an external source, load the entire class method
Sebastian Redl3c7f4132010-08-18 23:57:06 +00004006 // pool from the AST file.
Douglas Gregor719770d2010-04-06 17:30:22 +00004007 if (ExternalSource) {
John McCall76bd1f32010-06-01 09:23:16 +00004008 for (uint32_t I = 0, N = ExternalSource->GetNumExternalSelectors();
4009 I != N; ++I) {
4010 Selector Sel = ExternalSource->GetExternalSelector(I);
Sebastian Redldb9d2142010-08-02 23:18:59 +00004011 if (Sel.isNull() || MethodPool.count(Sel))
Douglas Gregor719770d2010-04-06 17:30:22 +00004012 continue;
4013
Sebastian Redldb9d2142010-08-02 23:18:59 +00004014 ReadMethodPool(Sel);
Douglas Gregor719770d2010-04-06 17:30:22 +00004015 }
4016 }
4017
Sebastian Redldb9d2142010-08-02 23:18:59 +00004018 for (GlobalMethodPool::iterator M = MethodPool.begin(),
4019 MEnd = MethodPool.end();
4020 M != MEnd; ++M) {
4021 for (ObjCMethodList *MethList = &M->second.second;
4022 MethList && MethList->Method;
Douglas Gregor13438f92010-04-06 16:40:00 +00004023 MethList = MethList->Next) {
4024 if (!isAcceptableObjCMethod(MethList->Method, MK_Any, SelIdents,
4025 NumSelIdents))
4026 continue;
4027
4028 Result R(MethList->Method, 0);
4029 R.StartParameter = NumSelIdents;
4030 R.AllParametersAreInformative = false;
4031 Results.MaybeAddResult(R, CurContext);
4032 }
4033 }
4034 }
4035
Steve Naroffc4df6d22009-11-07 02:08:14 +00004036 Results.ExitScope();
Douglas Gregore6b1bb62010-08-11 21:23:17 +00004037 HandleCodeCompleteResults(this, CodeCompleter,
4038 CodeCompletionContext::CCC_Other,
Douglas Gregor03d8aec2010-08-27 15:10:57 +00004039 Results.data(), Results.size());
Steve Naroffc4df6d22009-11-07 02:08:14 +00004040}
4041
Douglas Gregord3c68542009-11-19 01:08:35 +00004042void Sema::CodeCompleteObjCInstanceMessage(Scope *S, ExprTy *Receiver,
4043 IdentifierInfo **SelIdents,
4044 unsigned NumSelIdents) {
Douglas Gregor03d8aec2010-08-27 15:10:57 +00004045 CodeCompleteObjCInstanceMessage(S, Receiver, SelIdents, NumSelIdents, false);
4046}
4047
4048void Sema::CodeCompleteObjCInstanceMessage(Scope *S, ExprTy *Receiver,
4049 IdentifierInfo **SelIdents,
4050 unsigned NumSelIdents,
4051 bool IsSuper) {
John McCall0a2c5e22010-08-25 06:19:51 +00004052 typedef CodeCompletionResult Result;
Steve Naroffc4df6d22009-11-07 02:08:14 +00004053
4054 Expr *RecExpr = static_cast<Expr *>(Receiver);
Steve Naroffc4df6d22009-11-07 02:08:14 +00004055
Douglas Gregor36ecb042009-11-17 23:22:23 +00004056 // If necessary, apply function/array conversion to the receiver.
4057 // C99 6.7.5.3p[7,8].
Douglas Gregora873dfc2010-02-03 00:27:59 +00004058 DefaultFunctionArrayLvalueConversion(RecExpr);
Douglas Gregor36ecb042009-11-17 23:22:23 +00004059 QualType ReceiverType = RecExpr->getType();
Steve Naroffc4df6d22009-11-07 02:08:14 +00004060
Douglas Gregor36ecb042009-11-17 23:22:23 +00004061 // Build the set of methods we can see.
4062 ResultBuilder Results(*this);
4063 Results.EnterNewScope();
Douglas Gregor22f56992010-04-06 19:22:33 +00004064
Douglas Gregor03d8aec2010-08-27 15:10:57 +00004065 // If this is a send-to-super, try to add the special "super" send
4066 // completion.
4067 if (IsSuper) {
4068 if (ObjCMethodDecl *SuperMethod
4069 = AddSuperSendCompletion(*this, false, SelIdents, NumSelIdents,
4070 Results))
4071 Results.Ignore(SuperMethod);
4072 }
4073
Douglas Gregor22f56992010-04-06 19:22:33 +00004074 // If we're messaging an expression with type "id" or "Class", check
4075 // whether we know something special about the receiver that allows
4076 // us to assume a more-specific receiver type.
4077 if (ReceiverType->isObjCIdType() || ReceiverType->isObjCClassType())
4078 if (ObjCInterfaceDecl *IFace = GetAssumedMessageSendExprType(RecExpr))
4079 ReceiverType = Context.getObjCObjectPointerType(
4080 Context.getObjCInterfaceType(IFace));
Douglas Gregor36ecb042009-11-17 23:22:23 +00004081
Douglas Gregorf74a4192009-11-18 00:06:18 +00004082 // Handle messages to Class. This really isn't a message to an instance
4083 // method, so we treat it the same way we would treat a message send to a
4084 // class method.
4085 if (ReceiverType->isObjCClassType() ||
4086 ReceiverType->isObjCQualifiedClassType()) {
4087 if (ObjCMethodDecl *CurMethod = getCurMethodDecl()) {
4088 if (ObjCInterfaceDecl *ClassDecl = CurMethod->getClassInterface())
Douglas Gregor4ad96852009-11-19 07:41:15 +00004089 AddObjCMethods(ClassDecl, false, MK_Any, SelIdents, NumSelIdents,
4090 CurContext, Results);
Douglas Gregorf74a4192009-11-18 00:06:18 +00004091 }
4092 }
4093 // Handle messages to a qualified ID ("id<foo>").
4094 else if (const ObjCObjectPointerType *QualID
4095 = ReceiverType->getAsObjCQualifiedIdType()) {
4096 // Search protocols for instance methods.
4097 for (ObjCObjectPointerType::qual_iterator I = QualID->qual_begin(),
4098 E = QualID->qual_end();
4099 I != E; ++I)
Douglas Gregor4ad96852009-11-19 07:41:15 +00004100 AddObjCMethods(*I, true, MK_Any, SelIdents, NumSelIdents, CurContext,
4101 Results);
Douglas Gregorf74a4192009-11-18 00:06:18 +00004102 }
4103 // Handle messages to a pointer to interface type.
4104 else if (const ObjCObjectPointerType *IFacePtr
4105 = ReceiverType->getAsObjCInterfacePointerType()) {
4106 // Search the class, its superclasses, etc., for instance methods.
Douglas Gregor4ad96852009-11-19 07:41:15 +00004107 AddObjCMethods(IFacePtr->getInterfaceDecl(), true, MK_Any, SelIdents,
4108 NumSelIdents, CurContext, Results);
Douglas Gregorf74a4192009-11-18 00:06:18 +00004109
4110 // Search protocols for instance methods.
4111 for (ObjCObjectPointerType::qual_iterator I = IFacePtr->qual_begin(),
4112 E = IFacePtr->qual_end();
4113 I != E; ++I)
Douglas Gregor4ad96852009-11-19 07:41:15 +00004114 AddObjCMethods(*I, true, MK_Any, SelIdents, NumSelIdents, CurContext,
4115 Results);
Douglas Gregorf74a4192009-11-18 00:06:18 +00004116 }
Douglas Gregor13438f92010-04-06 16:40:00 +00004117 // Handle messages to "id".
4118 else if (ReceiverType->isObjCIdType()) {
Douglas Gregor719770d2010-04-06 17:30:22 +00004119 // We're messaging "id", so provide all instance methods we know
4120 // about as code-completion results.
4121
4122 // If we have an external source, load the entire class method
Sebastian Redl3c7f4132010-08-18 23:57:06 +00004123 // pool from the AST file.
Douglas Gregor719770d2010-04-06 17:30:22 +00004124 if (ExternalSource) {
John McCall76bd1f32010-06-01 09:23:16 +00004125 for (uint32_t I = 0, N = ExternalSource->GetNumExternalSelectors();
4126 I != N; ++I) {
4127 Selector Sel = ExternalSource->GetExternalSelector(I);
Sebastian Redldb9d2142010-08-02 23:18:59 +00004128 if (Sel.isNull() || MethodPool.count(Sel))
Douglas Gregor719770d2010-04-06 17:30:22 +00004129 continue;
4130
Sebastian Redldb9d2142010-08-02 23:18:59 +00004131 ReadMethodPool(Sel);
Douglas Gregor719770d2010-04-06 17:30:22 +00004132 }
4133 }
4134
Sebastian Redldb9d2142010-08-02 23:18:59 +00004135 for (GlobalMethodPool::iterator M = MethodPool.begin(),
4136 MEnd = MethodPool.end();
4137 M != MEnd; ++M) {
4138 for (ObjCMethodList *MethList = &M->second.first;
4139 MethList && MethList->Method;
Douglas Gregor13438f92010-04-06 16:40:00 +00004140 MethList = MethList->Next) {
4141 if (!isAcceptableObjCMethod(MethList->Method, MK_Any, SelIdents,
4142 NumSelIdents))
4143 continue;
4144
4145 Result R(MethList->Method, 0);
4146 R.StartParameter = NumSelIdents;
4147 R.AllParametersAreInformative = false;
4148 Results.MaybeAddResult(R, CurContext);
4149 }
4150 }
4151 }
4152
Steve Naroffc4df6d22009-11-07 02:08:14 +00004153 Results.ExitScope();
Douglas Gregore6b1bb62010-08-11 21:23:17 +00004154 HandleCodeCompleteResults(this, CodeCompleter,
4155 CodeCompletionContext::CCC_Other,
4156 Results.data(),Results.size());
Steve Naroffc4df6d22009-11-07 02:08:14 +00004157}
Douglas Gregor55385fe2009-11-18 04:19:12 +00004158
Douglas Gregorfb629412010-08-23 21:17:50 +00004159void Sema::CodeCompleteObjCForCollection(Scope *S,
4160 DeclGroupPtrTy IterationVar) {
4161 CodeCompleteExpressionData Data;
4162 Data.ObjCCollection = true;
4163
4164 if (IterationVar.getAsOpaquePtr()) {
4165 DeclGroupRef DG = IterationVar.getAsVal<DeclGroupRef>();
4166 for (DeclGroupRef::iterator I = DG.begin(), End = DG.end(); I != End; ++I) {
4167 if (*I)
4168 Data.IgnoreDecls.push_back(*I);
4169 }
4170 }
4171
4172 CodeCompleteExpression(S, Data);
4173}
4174
Douglas Gregor458433d2010-08-26 15:07:07 +00004175void Sema::CodeCompleteObjCSelector(Scope *S, IdentifierInfo **SelIdents,
4176 unsigned NumSelIdents) {
4177 // If we have an external source, load the entire class method
4178 // pool from the AST file.
4179 if (ExternalSource) {
4180 for (uint32_t I = 0, N = ExternalSource->GetNumExternalSelectors();
4181 I != N; ++I) {
4182 Selector Sel = ExternalSource->GetExternalSelector(I);
4183 if (Sel.isNull() || MethodPool.count(Sel))
4184 continue;
4185
4186 ReadMethodPool(Sel);
4187 }
4188 }
4189
4190 ResultBuilder Results(*this);
4191 Results.EnterNewScope();
4192 for (GlobalMethodPool::iterator M = MethodPool.begin(),
4193 MEnd = MethodPool.end();
4194 M != MEnd; ++M) {
4195
4196 Selector Sel = M->first;
4197 if (!isAcceptableObjCSelector(Sel, MK_Any, SelIdents, NumSelIdents))
4198 continue;
4199
4200 CodeCompletionString *Pattern = new CodeCompletionString;
4201 if (Sel.isUnarySelector()) {
4202 Pattern->AddTypedTextChunk(Sel.getIdentifierInfoForSlot(0)->getName());
4203 Results.AddResult(Pattern);
4204 continue;
4205 }
4206
Douglas Gregor2d9e21f2010-08-26 16:46:39 +00004207 std::string Accumulator;
Douglas Gregor458433d2010-08-26 15:07:07 +00004208 for (unsigned I = 0, N = Sel.getNumArgs(); I != N; ++I) {
Douglas Gregor2d9e21f2010-08-26 16:46:39 +00004209 if (I == NumSelIdents) {
4210 if (!Accumulator.empty()) {
4211 Pattern->AddInformativeChunk(Accumulator);
4212 Accumulator.clear();
4213 }
4214 }
4215
4216 Accumulator += Sel.getIdentifierInfoForSlot(I)->getName().str();
4217 Accumulator += ':';
Douglas Gregor458433d2010-08-26 15:07:07 +00004218 }
Douglas Gregor2d9e21f2010-08-26 16:46:39 +00004219 Pattern->AddTypedTextChunk(Accumulator);
Douglas Gregor458433d2010-08-26 15:07:07 +00004220 Results.AddResult(Pattern);
4221 }
4222 Results.ExitScope();
4223
4224 HandleCodeCompleteResults(this, CodeCompleter,
4225 CodeCompletionContext::CCC_SelectorName,
4226 Results.data(), Results.size());
4227}
4228
Douglas Gregor55385fe2009-11-18 04:19:12 +00004229/// \brief Add all of the protocol declarations that we find in the given
4230/// (translation unit) context.
4231static void AddProtocolResults(DeclContext *Ctx, DeclContext *CurContext,
Douglas Gregor083128f2009-11-18 04:49:41 +00004232 bool OnlyForwardDeclarations,
Douglas Gregor55385fe2009-11-18 04:19:12 +00004233 ResultBuilder &Results) {
John McCall0a2c5e22010-08-25 06:19:51 +00004234 typedef CodeCompletionResult Result;
Douglas Gregor55385fe2009-11-18 04:19:12 +00004235
4236 for (DeclContext::decl_iterator D = Ctx->decls_begin(),
4237 DEnd = Ctx->decls_end();
4238 D != DEnd; ++D) {
4239 // Record any protocols we find.
4240 if (ObjCProtocolDecl *Proto = dyn_cast<ObjCProtocolDecl>(*D))
Douglas Gregor083128f2009-11-18 04:49:41 +00004241 if (!OnlyForwardDeclarations || Proto->isForwardDecl())
Douglas Gregor608300b2010-01-14 16:14:35 +00004242 Results.AddResult(Result(Proto, 0), CurContext, 0, false);
Douglas Gregor55385fe2009-11-18 04:19:12 +00004243
4244 // Record any forward-declared protocols we find.
4245 if (ObjCForwardProtocolDecl *Forward
4246 = dyn_cast<ObjCForwardProtocolDecl>(*D)) {
4247 for (ObjCForwardProtocolDecl::protocol_iterator
4248 P = Forward->protocol_begin(),
4249 PEnd = Forward->protocol_end();
4250 P != PEnd; ++P)
Douglas Gregor083128f2009-11-18 04:49:41 +00004251 if (!OnlyForwardDeclarations || (*P)->isForwardDecl())
Douglas Gregor608300b2010-01-14 16:14:35 +00004252 Results.AddResult(Result(*P, 0), CurContext, 0, false);
Douglas Gregor55385fe2009-11-18 04:19:12 +00004253 }
4254 }
4255}
4256
4257void Sema::CodeCompleteObjCProtocolReferences(IdentifierLocPair *Protocols,
4258 unsigned NumProtocols) {
4259 ResultBuilder Results(*this);
4260 Results.EnterNewScope();
4261
4262 // Tell the result set to ignore all of the protocols we have
4263 // already seen.
4264 for (unsigned I = 0; I != NumProtocols; ++I)
Douglas Gregorc83c6872010-04-15 22:33:43 +00004265 if (ObjCProtocolDecl *Protocol = LookupProtocol(Protocols[I].first,
4266 Protocols[I].second))
Douglas Gregor55385fe2009-11-18 04:19:12 +00004267 Results.Ignore(Protocol);
4268
4269 // Add all protocols.
Douglas Gregor083128f2009-11-18 04:49:41 +00004270 AddProtocolResults(Context.getTranslationUnitDecl(), CurContext, false,
4271 Results);
4272
4273 Results.ExitScope();
Douglas Gregore6b1bb62010-08-11 21:23:17 +00004274 HandleCodeCompleteResults(this, CodeCompleter,
4275 CodeCompletionContext::CCC_ObjCProtocolName,
4276 Results.data(),Results.size());
Douglas Gregor083128f2009-11-18 04:49:41 +00004277}
4278
4279void Sema::CodeCompleteObjCProtocolDecl(Scope *) {
4280 ResultBuilder Results(*this);
4281 Results.EnterNewScope();
4282
4283 // Add all protocols.
4284 AddProtocolResults(Context.getTranslationUnitDecl(), CurContext, true,
4285 Results);
Douglas Gregor55385fe2009-11-18 04:19:12 +00004286
4287 Results.ExitScope();
Douglas Gregore6b1bb62010-08-11 21:23:17 +00004288 HandleCodeCompleteResults(this, CodeCompleter,
4289 CodeCompletionContext::CCC_ObjCProtocolName,
4290 Results.data(),Results.size());
Douglas Gregor55385fe2009-11-18 04:19:12 +00004291}
Douglas Gregor3b49aca2009-11-18 16:26:39 +00004292
4293/// \brief Add all of the Objective-C interface declarations that we find in
4294/// the given (translation unit) context.
4295static void AddInterfaceResults(DeclContext *Ctx, DeclContext *CurContext,
4296 bool OnlyForwardDeclarations,
4297 bool OnlyUnimplemented,
4298 ResultBuilder &Results) {
John McCall0a2c5e22010-08-25 06:19:51 +00004299 typedef CodeCompletionResult Result;
Douglas Gregor3b49aca2009-11-18 16:26:39 +00004300
4301 for (DeclContext::decl_iterator D = Ctx->decls_begin(),
4302 DEnd = Ctx->decls_end();
4303 D != DEnd; ++D) {
Douglas Gregordeacbdc2010-08-11 12:19:30 +00004304 // Record any interfaces we find.
4305 if (ObjCInterfaceDecl *Class = dyn_cast<ObjCInterfaceDecl>(*D))
4306 if ((!OnlyForwardDeclarations || Class->isForwardDecl()) &&
4307 (!OnlyUnimplemented || !Class->getImplementation()))
4308 Results.AddResult(Result(Class, 0), CurContext, 0, false);
Douglas Gregor3b49aca2009-11-18 16:26:39 +00004309
4310 // Record any forward-declared interfaces we find.
4311 if (ObjCClassDecl *Forward = dyn_cast<ObjCClassDecl>(*D)) {
4312 for (ObjCClassDecl::iterator C = Forward->begin(), CEnd = Forward->end();
Douglas Gregordeacbdc2010-08-11 12:19:30 +00004313 C != CEnd; ++C)
4314 if ((!OnlyForwardDeclarations || C->getInterface()->isForwardDecl()) &&
4315 (!OnlyUnimplemented || !C->getInterface()->getImplementation()))
4316 Results.AddResult(Result(C->getInterface(), 0), CurContext,
Douglas Gregor608300b2010-01-14 16:14:35 +00004317 0, false);
Douglas Gregor3b49aca2009-11-18 16:26:39 +00004318 }
4319 }
4320}
4321
4322void Sema::CodeCompleteObjCInterfaceDecl(Scope *S) {
4323 ResultBuilder Results(*this);
4324 Results.EnterNewScope();
4325
4326 // Add all classes.
4327 AddInterfaceResults(Context.getTranslationUnitDecl(), CurContext, true,
4328 false, Results);
4329
4330 Results.ExitScope();
Douglas Gregore6b1bb62010-08-11 21:23:17 +00004331 HandleCodeCompleteResults(this, CodeCompleter,
4332 CodeCompletionContext::CCC_Other,
4333 Results.data(),Results.size());
Douglas Gregor3b49aca2009-11-18 16:26:39 +00004334}
4335
Douglas Gregorc83c6872010-04-15 22:33:43 +00004336void Sema::CodeCompleteObjCSuperclass(Scope *S, IdentifierInfo *ClassName,
4337 SourceLocation ClassNameLoc) {
Douglas Gregor3b49aca2009-11-18 16:26:39 +00004338 ResultBuilder Results(*this);
4339 Results.EnterNewScope();
4340
4341 // Make sure that we ignore the class we're currently defining.
4342 NamedDecl *CurClass
Douglas Gregorc83c6872010-04-15 22:33:43 +00004343 = LookupSingleName(TUScope, ClassName, ClassNameLoc, LookupOrdinaryName);
Douglas Gregor33ced0b2009-11-18 19:08:43 +00004344 if (CurClass && isa<ObjCInterfaceDecl>(CurClass))
Douglas Gregor3b49aca2009-11-18 16:26:39 +00004345 Results.Ignore(CurClass);
4346
4347 // Add all classes.
4348 AddInterfaceResults(Context.getTranslationUnitDecl(), CurContext, false,
4349 false, Results);
4350
4351 Results.ExitScope();
Douglas Gregore6b1bb62010-08-11 21:23:17 +00004352 HandleCodeCompleteResults(this, CodeCompleter,
4353 CodeCompletionContext::CCC_Other,
4354 Results.data(),Results.size());
Douglas Gregor3b49aca2009-11-18 16:26:39 +00004355}
4356
4357void Sema::CodeCompleteObjCImplementationDecl(Scope *S) {
4358 ResultBuilder Results(*this);
4359 Results.EnterNewScope();
4360
4361 // Add all unimplemented classes.
4362 AddInterfaceResults(Context.getTranslationUnitDecl(), CurContext, false,
4363 true, Results);
4364
4365 Results.ExitScope();
Douglas Gregore6b1bb62010-08-11 21:23:17 +00004366 HandleCodeCompleteResults(this, CodeCompleter,
4367 CodeCompletionContext::CCC_Other,
4368 Results.data(),Results.size());
Douglas Gregor3b49aca2009-11-18 16:26:39 +00004369}
Douglas Gregor33ced0b2009-11-18 19:08:43 +00004370
4371void Sema::CodeCompleteObjCInterfaceCategory(Scope *S,
Douglas Gregorc83c6872010-04-15 22:33:43 +00004372 IdentifierInfo *ClassName,
4373 SourceLocation ClassNameLoc) {
John McCall0a2c5e22010-08-25 06:19:51 +00004374 typedef CodeCompletionResult Result;
Douglas Gregor33ced0b2009-11-18 19:08:43 +00004375
4376 ResultBuilder Results(*this);
4377
4378 // Ignore any categories we find that have already been implemented by this
4379 // interface.
4380 llvm::SmallPtrSet<IdentifierInfo *, 16> CategoryNames;
4381 NamedDecl *CurClass
Douglas Gregorc83c6872010-04-15 22:33:43 +00004382 = LookupSingleName(TUScope, ClassName, ClassNameLoc, LookupOrdinaryName);
Douglas Gregor33ced0b2009-11-18 19:08:43 +00004383 if (ObjCInterfaceDecl *Class = dyn_cast_or_null<ObjCInterfaceDecl>(CurClass))
4384 for (ObjCCategoryDecl *Category = Class->getCategoryList(); Category;
4385 Category = Category->getNextClassCategory())
4386 CategoryNames.insert(Category->getIdentifier());
4387
4388 // Add all of the categories we know about.
4389 Results.EnterNewScope();
4390 TranslationUnitDecl *TU = Context.getTranslationUnitDecl();
4391 for (DeclContext::decl_iterator D = TU->decls_begin(),
4392 DEnd = TU->decls_end();
4393 D != DEnd; ++D)
4394 if (ObjCCategoryDecl *Category = dyn_cast<ObjCCategoryDecl>(*D))
4395 if (CategoryNames.insert(Category->getIdentifier()))
Douglas Gregor608300b2010-01-14 16:14:35 +00004396 Results.AddResult(Result(Category, 0), CurContext, 0, false);
Douglas Gregor33ced0b2009-11-18 19:08:43 +00004397 Results.ExitScope();
4398
Douglas Gregore6b1bb62010-08-11 21:23:17 +00004399 HandleCodeCompleteResults(this, CodeCompleter,
4400 CodeCompletionContext::CCC_Other,
4401 Results.data(),Results.size());
Douglas Gregor33ced0b2009-11-18 19:08:43 +00004402}
4403
4404void Sema::CodeCompleteObjCImplementationCategory(Scope *S,
Douglas Gregorc83c6872010-04-15 22:33:43 +00004405 IdentifierInfo *ClassName,
4406 SourceLocation ClassNameLoc) {
John McCall0a2c5e22010-08-25 06:19:51 +00004407 typedef CodeCompletionResult Result;
Douglas Gregor33ced0b2009-11-18 19:08:43 +00004408
4409 // Find the corresponding interface. If we couldn't find the interface, the
4410 // program itself is ill-formed. However, we'll try to be helpful still by
4411 // providing the list of all of the categories we know about.
4412 NamedDecl *CurClass
Douglas Gregorc83c6872010-04-15 22:33:43 +00004413 = LookupSingleName(TUScope, ClassName, ClassNameLoc, LookupOrdinaryName);
Douglas Gregor33ced0b2009-11-18 19:08:43 +00004414 ObjCInterfaceDecl *Class = dyn_cast_or_null<ObjCInterfaceDecl>(CurClass);
4415 if (!Class)
Douglas Gregorc83c6872010-04-15 22:33:43 +00004416 return CodeCompleteObjCInterfaceCategory(S, ClassName, ClassNameLoc);
Douglas Gregor33ced0b2009-11-18 19:08:43 +00004417
4418 ResultBuilder Results(*this);
4419
4420 // Add all of the categories that have have corresponding interface
4421 // declarations in this class and any of its superclasses, except for
4422 // already-implemented categories in the class itself.
4423 llvm::SmallPtrSet<IdentifierInfo *, 16> CategoryNames;
4424 Results.EnterNewScope();
4425 bool IgnoreImplemented = true;
4426 while (Class) {
4427 for (ObjCCategoryDecl *Category = Class->getCategoryList(); Category;
4428 Category = Category->getNextClassCategory())
4429 if ((!IgnoreImplemented || !Category->getImplementation()) &&
4430 CategoryNames.insert(Category->getIdentifier()))
Douglas Gregor608300b2010-01-14 16:14:35 +00004431 Results.AddResult(Result(Category, 0), CurContext, 0, false);
Douglas Gregor33ced0b2009-11-18 19:08:43 +00004432
4433 Class = Class->getSuperClass();
4434 IgnoreImplemented = false;
4435 }
4436 Results.ExitScope();
4437
Douglas Gregore6b1bb62010-08-11 21:23:17 +00004438 HandleCodeCompleteResults(this, CodeCompleter,
4439 CodeCompletionContext::CCC_Other,
4440 Results.data(),Results.size());
Douglas Gregor33ced0b2009-11-18 19:08:43 +00004441}
Douglas Gregor322328b2009-11-18 22:32:06 +00004442
John McCalld226f652010-08-21 09:40:31 +00004443void Sema::CodeCompleteObjCPropertyDefinition(Scope *S, Decl *ObjCImpDecl) {
John McCall0a2c5e22010-08-25 06:19:51 +00004444 typedef CodeCompletionResult Result;
Douglas Gregor322328b2009-11-18 22:32:06 +00004445 ResultBuilder Results(*this);
4446
4447 // Figure out where this @synthesize lives.
4448 ObjCContainerDecl *Container
John McCalld226f652010-08-21 09:40:31 +00004449 = dyn_cast_or_null<ObjCContainerDecl>(ObjCImpDecl);
Douglas Gregor322328b2009-11-18 22:32:06 +00004450 if (!Container ||
4451 (!isa<ObjCImplementationDecl>(Container) &&
4452 !isa<ObjCCategoryImplDecl>(Container)))
4453 return;
4454
4455 // Ignore any properties that have already been implemented.
4456 for (DeclContext::decl_iterator D = Container->decls_begin(),
4457 DEnd = Container->decls_end();
4458 D != DEnd; ++D)
4459 if (ObjCPropertyImplDecl *PropertyImpl = dyn_cast<ObjCPropertyImplDecl>(*D))
4460 Results.Ignore(PropertyImpl->getPropertyDecl());
4461
4462 // Add any properties that we find.
4463 Results.EnterNewScope();
4464 if (ObjCImplementationDecl *ClassImpl
4465 = dyn_cast<ObjCImplementationDecl>(Container))
4466 AddObjCProperties(ClassImpl->getClassInterface(), false, CurContext,
4467 Results);
4468 else
4469 AddObjCProperties(cast<ObjCCategoryImplDecl>(Container)->getCategoryDecl(),
4470 false, CurContext, Results);
4471 Results.ExitScope();
4472
Douglas Gregore6b1bb62010-08-11 21:23:17 +00004473 HandleCodeCompleteResults(this, CodeCompleter,
4474 CodeCompletionContext::CCC_Other,
4475 Results.data(),Results.size());
Douglas Gregor322328b2009-11-18 22:32:06 +00004476}
4477
4478void Sema::CodeCompleteObjCPropertySynthesizeIvar(Scope *S,
4479 IdentifierInfo *PropertyName,
John McCalld226f652010-08-21 09:40:31 +00004480 Decl *ObjCImpDecl) {
John McCall0a2c5e22010-08-25 06:19:51 +00004481 typedef CodeCompletionResult Result;
Douglas Gregor322328b2009-11-18 22:32:06 +00004482 ResultBuilder Results(*this);
4483
4484 // Figure out where this @synthesize lives.
4485 ObjCContainerDecl *Container
John McCalld226f652010-08-21 09:40:31 +00004486 = dyn_cast_or_null<ObjCContainerDecl>(ObjCImpDecl);
Douglas Gregor322328b2009-11-18 22:32:06 +00004487 if (!Container ||
4488 (!isa<ObjCImplementationDecl>(Container) &&
4489 !isa<ObjCCategoryImplDecl>(Container)))
4490 return;
4491
4492 // Figure out which interface we're looking into.
4493 ObjCInterfaceDecl *Class = 0;
4494 if (ObjCImplementationDecl *ClassImpl
4495 = dyn_cast<ObjCImplementationDecl>(Container))
4496 Class = ClassImpl->getClassInterface();
4497 else
4498 Class = cast<ObjCCategoryImplDecl>(Container)->getCategoryDecl()
4499 ->getClassInterface();
4500
4501 // Add all of the instance variables in this class and its superclasses.
4502 Results.EnterNewScope();
4503 for(; Class; Class = Class->getSuperClass()) {
4504 // FIXME: We could screen the type of each ivar for compatibility with
4505 // the property, but is that being too paternal?
4506 for (ObjCInterfaceDecl::ivar_iterator IVar = Class->ivar_begin(),
4507 IVarEnd = Class->ivar_end();
4508 IVar != IVarEnd; ++IVar)
Douglas Gregor608300b2010-01-14 16:14:35 +00004509 Results.AddResult(Result(*IVar, 0), CurContext, 0, false);
Douglas Gregor322328b2009-11-18 22:32:06 +00004510 }
4511 Results.ExitScope();
4512
Douglas Gregore6b1bb62010-08-11 21:23:17 +00004513 HandleCodeCompleteResults(this, CodeCompleter,
4514 CodeCompletionContext::CCC_Other,
4515 Results.data(),Results.size());
Douglas Gregor322328b2009-11-18 22:32:06 +00004516}
Douglas Gregore8f5a172010-04-07 00:21:17 +00004517
Douglas Gregor408be5a2010-08-25 01:08:01 +00004518// Mapping from selectors to the methods that implement that selector, along
4519// with the "in original class" flag.
4520typedef llvm::DenseMap<Selector, std::pair<ObjCMethodDecl *, bool> >
4521 KnownMethodsMap;
Douglas Gregore8f5a172010-04-07 00:21:17 +00004522
4523/// \brief Find all of the methods that reside in the given container
4524/// (and its superclasses, protocols, etc.) that meet the given
4525/// criteria. Insert those methods into the map of known methods,
4526/// indexed by selector so they can be easily found.
4527static void FindImplementableMethods(ASTContext &Context,
4528 ObjCContainerDecl *Container,
4529 bool WantInstanceMethods,
4530 QualType ReturnType,
4531 bool IsInImplementation,
Douglas Gregor408be5a2010-08-25 01:08:01 +00004532 KnownMethodsMap &KnownMethods,
4533 bool InOriginalClass = true) {
Douglas Gregore8f5a172010-04-07 00:21:17 +00004534 if (ObjCInterfaceDecl *IFace = dyn_cast<ObjCInterfaceDecl>(Container)) {
4535 // Recurse into protocols.
4536 const ObjCList<ObjCProtocolDecl> &Protocols
4537 = IFace->getReferencedProtocols();
4538 for (ObjCList<ObjCProtocolDecl>::iterator I = Protocols.begin(),
4539 E = Protocols.end();
4540 I != E; ++I)
4541 FindImplementableMethods(Context, *I, WantInstanceMethods, ReturnType,
Douglas Gregor408be5a2010-08-25 01:08:01 +00004542 IsInImplementation, KnownMethods,
4543 InOriginalClass);
Douglas Gregore8f5a172010-04-07 00:21:17 +00004544
4545 // If we're not in the implementation of a class, also visit the
4546 // superclass.
4547 if (!IsInImplementation && IFace->getSuperClass())
4548 FindImplementableMethods(Context, IFace->getSuperClass(),
4549 WantInstanceMethods, ReturnType,
Douglas Gregor408be5a2010-08-25 01:08:01 +00004550 IsInImplementation, KnownMethods,
4551 false);
Douglas Gregore8f5a172010-04-07 00:21:17 +00004552
4553 // Add methods from any class extensions (but not from categories;
4554 // those should go into category implementations).
Fariborz Jahanian80aa1cd2010-06-22 23:20:40 +00004555 for (const ObjCCategoryDecl *Cat = IFace->getFirstClassExtension(); Cat;
4556 Cat = Cat->getNextClassExtension())
4557 FindImplementableMethods(Context, const_cast<ObjCCategoryDecl*>(Cat),
4558 WantInstanceMethods, ReturnType,
Douglas Gregor408be5a2010-08-25 01:08:01 +00004559 IsInImplementation, KnownMethods,
4560 InOriginalClass);
Douglas Gregore8f5a172010-04-07 00:21:17 +00004561 }
4562
4563 if (ObjCCategoryDecl *Category = dyn_cast<ObjCCategoryDecl>(Container)) {
4564 // Recurse into protocols.
4565 const ObjCList<ObjCProtocolDecl> &Protocols
4566 = Category->getReferencedProtocols();
4567 for (ObjCList<ObjCProtocolDecl>::iterator I = Protocols.begin(),
4568 E = Protocols.end();
4569 I != E; ++I)
4570 FindImplementableMethods(Context, *I, WantInstanceMethods, ReturnType,
Douglas Gregor408be5a2010-08-25 01:08:01 +00004571 IsInImplementation, KnownMethods,
4572 InOriginalClass);
Douglas Gregore8f5a172010-04-07 00:21:17 +00004573 }
4574
4575 if (ObjCProtocolDecl *Protocol = dyn_cast<ObjCProtocolDecl>(Container)) {
4576 // Recurse into protocols.
4577 const ObjCList<ObjCProtocolDecl> &Protocols
4578 = Protocol->getReferencedProtocols();
4579 for (ObjCList<ObjCProtocolDecl>::iterator I = Protocols.begin(),
4580 E = Protocols.end();
4581 I != E; ++I)
4582 FindImplementableMethods(Context, *I, WantInstanceMethods, ReturnType,
Douglas Gregor408be5a2010-08-25 01:08:01 +00004583 IsInImplementation, KnownMethods, false);
Douglas Gregore8f5a172010-04-07 00:21:17 +00004584 }
4585
4586 // Add methods in this container. This operation occurs last because
4587 // we want the methods from this container to override any methods
4588 // we've previously seen with the same selector.
4589 for (ObjCContainerDecl::method_iterator M = Container->meth_begin(),
4590 MEnd = Container->meth_end();
4591 M != MEnd; ++M) {
4592 if ((*M)->isInstanceMethod() == WantInstanceMethods) {
4593 if (!ReturnType.isNull() &&
4594 !Context.hasSameUnqualifiedType(ReturnType, (*M)->getResultType()))
4595 continue;
4596
Douglas Gregor408be5a2010-08-25 01:08:01 +00004597 KnownMethods[(*M)->getSelector()] = std::make_pair(*M, InOriginalClass);
Douglas Gregore8f5a172010-04-07 00:21:17 +00004598 }
4599 }
4600}
4601
4602void Sema::CodeCompleteObjCMethodDecl(Scope *S,
4603 bool IsInstanceMethod,
John McCallb3d87482010-08-24 05:47:05 +00004604 ParsedType ReturnTy,
John McCalld226f652010-08-21 09:40:31 +00004605 Decl *IDecl) {
Douglas Gregore8f5a172010-04-07 00:21:17 +00004606 // Determine the return type of the method we're declaring, if
4607 // provided.
4608 QualType ReturnType = GetTypeFromParser(ReturnTy);
4609
4610 // Determine where we should start searching for methods, and where we
4611 ObjCContainerDecl *SearchDecl = 0, *CurrentDecl = 0;
4612 bool IsInImplementation = false;
John McCalld226f652010-08-21 09:40:31 +00004613 if (Decl *D = IDecl) {
Douglas Gregore8f5a172010-04-07 00:21:17 +00004614 if (ObjCImplementationDecl *Impl = dyn_cast<ObjCImplementationDecl>(D)) {
4615 SearchDecl = Impl->getClassInterface();
4616 CurrentDecl = Impl;
4617 IsInImplementation = true;
4618 } else if (ObjCCategoryImplDecl *CatImpl
4619 = dyn_cast<ObjCCategoryImplDecl>(D)) {
4620 SearchDecl = CatImpl->getCategoryDecl();
4621 CurrentDecl = CatImpl;
4622 IsInImplementation = true;
4623 } else {
4624 SearchDecl = dyn_cast<ObjCContainerDecl>(D);
4625 CurrentDecl = SearchDecl;
4626 }
4627 }
4628
4629 if (!SearchDecl && S) {
4630 if (DeclContext *DC = static_cast<DeclContext *>(S->getEntity())) {
4631 SearchDecl = dyn_cast<ObjCContainerDecl>(DC);
4632 CurrentDecl = SearchDecl;
4633 }
4634 }
4635
4636 if (!SearchDecl || !CurrentDecl) {
Douglas Gregore6b1bb62010-08-11 21:23:17 +00004637 HandleCodeCompleteResults(this, CodeCompleter,
4638 CodeCompletionContext::CCC_Other,
4639 0, 0);
Douglas Gregore8f5a172010-04-07 00:21:17 +00004640 return;
4641 }
4642
4643 // Find all of the methods that we could declare/implement here.
4644 KnownMethodsMap KnownMethods;
4645 FindImplementableMethods(Context, SearchDecl, IsInstanceMethod,
4646 ReturnType, IsInImplementation, KnownMethods);
4647
4648 // Erase any methods that have already been declared or
4649 // implemented here.
4650 for (ObjCContainerDecl::method_iterator M = CurrentDecl->meth_begin(),
4651 MEnd = CurrentDecl->meth_end();
4652 M != MEnd; ++M) {
4653 if ((*M)->isInstanceMethod() != IsInstanceMethod)
4654 continue;
4655
4656 KnownMethodsMap::iterator Pos = KnownMethods.find((*M)->getSelector());
4657 if (Pos != KnownMethods.end())
4658 KnownMethods.erase(Pos);
4659 }
4660
4661 // Add declarations or definitions for each of the known methods.
John McCall0a2c5e22010-08-25 06:19:51 +00004662 typedef CodeCompletionResult Result;
Douglas Gregore8f5a172010-04-07 00:21:17 +00004663 ResultBuilder Results(*this);
4664 Results.EnterNewScope();
4665 PrintingPolicy Policy(Context.PrintingPolicy);
4666 Policy.AnonymousTagLocations = false;
4667 for (KnownMethodsMap::iterator M = KnownMethods.begin(),
4668 MEnd = KnownMethods.end();
4669 M != MEnd; ++M) {
Douglas Gregor408be5a2010-08-25 01:08:01 +00004670 ObjCMethodDecl *Method = M->second.first;
Douglas Gregore8f5a172010-04-07 00:21:17 +00004671 CodeCompletionString *Pattern = new CodeCompletionString;
4672
4673 // If the result type was not already provided, add it to the
4674 // pattern as (type).
4675 if (ReturnType.isNull()) {
4676 std::string TypeStr;
4677 Method->getResultType().getAsStringInternal(TypeStr, Policy);
4678 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
4679 Pattern->AddTextChunk(TypeStr);
4680 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
4681 }
4682
4683 Selector Sel = Method->getSelector();
4684
4685 // Add the first part of the selector to the pattern.
4686 Pattern->AddTypedTextChunk(Sel.getIdentifierInfoForSlot(0)->getName());
4687
4688 // Add parameters to the pattern.
4689 unsigned I = 0;
4690 for (ObjCMethodDecl::param_iterator P = Method->param_begin(),
4691 PEnd = Method->param_end();
4692 P != PEnd; (void)++P, ++I) {
4693 // Add the part of the selector name.
4694 if (I == 0)
4695 Pattern->AddChunk(CodeCompletionString::CK_Colon);
4696 else if (I < Sel.getNumArgs()) {
4697 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
Douglas Gregor47c03a72010-08-17 15:53:35 +00004698 Pattern->AddTextChunk(Sel.getIdentifierInfoForSlot(I)->getName());
Douglas Gregore8f5a172010-04-07 00:21:17 +00004699 Pattern->AddChunk(CodeCompletionString::CK_Colon);
4700 } else
4701 break;
4702
4703 // Add the parameter type.
4704 std::string TypeStr;
4705 (*P)->getOriginalType().getAsStringInternal(TypeStr, Policy);
4706 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
4707 Pattern->AddTextChunk(TypeStr);
4708 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
4709
4710 if (IdentifierInfo *Id = (*P)->getIdentifier())
4711 Pattern->AddTextChunk(Id->getName());
4712 }
4713
4714 if (Method->isVariadic()) {
4715 if (Method->param_size() > 0)
4716 Pattern->AddChunk(CodeCompletionString::CK_Comma);
4717 Pattern->AddTextChunk("...");
4718 }
4719
Douglas Gregor447107d2010-05-28 00:57:46 +00004720 if (IsInImplementation && Results.includeCodePatterns()) {
Douglas Gregore8f5a172010-04-07 00:21:17 +00004721 // We will be defining the method here, so add a compound statement.
4722 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
4723 Pattern->AddChunk(CodeCompletionString::CK_LeftBrace);
4724 Pattern->AddChunk(CodeCompletionString::CK_VerticalSpace);
4725 if (!Method->getResultType()->isVoidType()) {
4726 // If the result type is not void, add a return clause.
4727 Pattern->AddTextChunk("return");
4728 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
4729 Pattern->AddPlaceholderChunk("expression");
4730 Pattern->AddChunk(CodeCompletionString::CK_SemiColon);
4731 } else
4732 Pattern->AddPlaceholderChunk("statements");
4733
4734 Pattern->AddChunk(CodeCompletionString::CK_VerticalSpace);
4735 Pattern->AddChunk(CodeCompletionString::CK_RightBrace);
4736 }
4737
Douglas Gregor408be5a2010-08-25 01:08:01 +00004738 unsigned Priority = CCP_CodePattern;
4739 if (!M->second.second)
4740 Priority += CCD_InBaseClass;
4741
4742 Results.AddResult(Result(Pattern, Priority,
Douglas Gregor16ed9ad2010-08-17 16:06:07 +00004743 Method->isInstanceMethod()
4744 ? CXCursor_ObjCInstanceMethodDecl
4745 : CXCursor_ObjCClassMethodDecl));
Douglas Gregore8f5a172010-04-07 00:21:17 +00004746 }
4747
4748 Results.ExitScope();
4749
Douglas Gregore6b1bb62010-08-11 21:23:17 +00004750 HandleCodeCompleteResults(this, CodeCompleter,
4751 CodeCompletionContext::CCC_Other,
4752 Results.data(),Results.size());
Douglas Gregore8f5a172010-04-07 00:21:17 +00004753}
Douglas Gregor1f5537a2010-07-08 23:20:03 +00004754
4755void Sema::CodeCompleteObjCMethodDeclSelector(Scope *S,
4756 bool IsInstanceMethod,
Douglas Gregor40ed9a12010-07-08 23:37:41 +00004757 bool AtParameterName,
John McCallb3d87482010-08-24 05:47:05 +00004758 ParsedType ReturnTy,
Douglas Gregor1f5537a2010-07-08 23:20:03 +00004759 IdentifierInfo **SelIdents,
4760 unsigned NumSelIdents) {
Douglas Gregor1f5537a2010-07-08 23:20:03 +00004761 // If we have an external source, load the entire class method
Sebastian Redl3c7f4132010-08-18 23:57:06 +00004762 // pool from the AST file.
Douglas Gregor1f5537a2010-07-08 23:20:03 +00004763 if (ExternalSource) {
4764 for (uint32_t I = 0, N = ExternalSource->GetNumExternalSelectors();
4765 I != N; ++I) {
4766 Selector Sel = ExternalSource->GetExternalSelector(I);
Sebastian Redldb9d2142010-08-02 23:18:59 +00004767 if (Sel.isNull() || MethodPool.count(Sel))
Douglas Gregor1f5537a2010-07-08 23:20:03 +00004768 continue;
Sebastian Redldb9d2142010-08-02 23:18:59 +00004769
4770 ReadMethodPool(Sel);
Douglas Gregor1f5537a2010-07-08 23:20:03 +00004771 }
4772 }
4773
4774 // Build the set of methods we can see.
John McCall0a2c5e22010-08-25 06:19:51 +00004775 typedef CodeCompletionResult Result;
Douglas Gregor1f5537a2010-07-08 23:20:03 +00004776 ResultBuilder Results(*this);
4777
4778 if (ReturnTy)
4779 Results.setPreferredType(GetTypeFromParser(ReturnTy).getNonReferenceType());
Sebastian Redldb9d2142010-08-02 23:18:59 +00004780
Douglas Gregor1f5537a2010-07-08 23:20:03 +00004781 Results.EnterNewScope();
Sebastian Redldb9d2142010-08-02 23:18:59 +00004782 for (GlobalMethodPool::iterator M = MethodPool.begin(),
4783 MEnd = MethodPool.end();
4784 M != MEnd; ++M) {
4785 for (ObjCMethodList *MethList = IsInstanceMethod ? &M->second.first :
4786 &M->second.second;
4787 MethList && MethList->Method;
Douglas Gregor1f5537a2010-07-08 23:20:03 +00004788 MethList = MethList->Next) {
4789 if (!isAcceptableObjCMethod(MethList->Method, MK_Any, SelIdents,
4790 NumSelIdents))
4791 continue;
4792
Douglas Gregor40ed9a12010-07-08 23:37:41 +00004793 if (AtParameterName) {
4794 // Suggest parameter names we've seen before.
4795 if (NumSelIdents && NumSelIdents <= MethList->Method->param_size()) {
4796 ParmVarDecl *Param = MethList->Method->param_begin()[NumSelIdents-1];
4797 if (Param->getIdentifier()) {
4798 CodeCompletionString *Pattern = new CodeCompletionString;
4799 Pattern->AddTypedTextChunk(Param->getIdentifier()->getName());
4800 Results.AddResult(Pattern);
4801 }
4802 }
4803
4804 continue;
4805 }
4806
Douglas Gregor1f5537a2010-07-08 23:20:03 +00004807 Result R(MethList->Method, 0);
4808 R.StartParameter = NumSelIdents;
4809 R.AllParametersAreInformative = false;
4810 R.DeclaringEntity = true;
4811 Results.MaybeAddResult(R, CurContext);
4812 }
4813 }
4814
4815 Results.ExitScope();
Douglas Gregore6b1bb62010-08-11 21:23:17 +00004816 HandleCodeCompleteResults(this, CodeCompleter,
4817 CodeCompletionContext::CCC_Other,
4818 Results.data(),Results.size());
Douglas Gregor1f5537a2010-07-08 23:20:03 +00004819}
Douglas Gregor87c08a52010-08-13 22:48:40 +00004820
Douglas Gregorf29c5232010-08-24 22:20:20 +00004821void Sema::CodeCompletePreprocessorDirective(bool InConditional) {
Douglas Gregorf44e8542010-08-24 19:08:16 +00004822 ResultBuilder Results(*this);
4823 Results.EnterNewScope();
4824
4825 // #if <condition>
4826 CodeCompletionString *Pattern = new CodeCompletionString;
4827 Pattern->AddTypedTextChunk("if");
4828 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
4829 Pattern->AddPlaceholderChunk("condition");
4830 Results.AddResult(Pattern);
4831
4832 // #ifdef <macro>
4833 Pattern = new CodeCompletionString;
4834 Pattern->AddTypedTextChunk("ifdef");
4835 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
4836 Pattern->AddPlaceholderChunk("macro");
4837 Results.AddResult(Pattern);
4838
4839 // #ifndef <macro>
4840 Pattern = new CodeCompletionString;
4841 Pattern->AddTypedTextChunk("ifndef");
4842 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
4843 Pattern->AddPlaceholderChunk("macro");
4844 Results.AddResult(Pattern);
4845
4846 if (InConditional) {
4847 // #elif <condition>
4848 Pattern = new CodeCompletionString;
4849 Pattern->AddTypedTextChunk("elif");
4850 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
4851 Pattern->AddPlaceholderChunk("condition");
4852 Results.AddResult(Pattern);
4853
4854 // #else
4855 Pattern = new CodeCompletionString;
4856 Pattern->AddTypedTextChunk("else");
4857 Results.AddResult(Pattern);
4858
4859 // #endif
4860 Pattern = new CodeCompletionString;
4861 Pattern->AddTypedTextChunk("endif");
4862 Results.AddResult(Pattern);
4863 }
4864
4865 // #include "header"
4866 Pattern = new CodeCompletionString;
4867 Pattern->AddTypedTextChunk("include");
4868 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
4869 Pattern->AddTextChunk("\"");
4870 Pattern->AddPlaceholderChunk("header");
4871 Pattern->AddTextChunk("\"");
4872 Results.AddResult(Pattern);
4873
4874 // #include <header>
4875 Pattern = new CodeCompletionString;
4876 Pattern->AddTypedTextChunk("include");
4877 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
4878 Pattern->AddTextChunk("<");
4879 Pattern->AddPlaceholderChunk("header");
4880 Pattern->AddTextChunk(">");
4881 Results.AddResult(Pattern);
4882
4883 // #define <macro>
4884 Pattern = new CodeCompletionString;
4885 Pattern->AddTypedTextChunk("define");
4886 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
4887 Pattern->AddPlaceholderChunk("macro");
4888 Results.AddResult(Pattern);
4889
4890 // #define <macro>(<args>)
4891 Pattern = new CodeCompletionString;
4892 Pattern->AddTypedTextChunk("define");
4893 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
4894 Pattern->AddPlaceholderChunk("macro");
4895 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
4896 Pattern->AddPlaceholderChunk("args");
4897 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
4898 Results.AddResult(Pattern);
4899
4900 // #undef <macro>
4901 Pattern = new CodeCompletionString;
4902 Pattern->AddTypedTextChunk("undef");
4903 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
4904 Pattern->AddPlaceholderChunk("macro");
4905 Results.AddResult(Pattern);
4906
4907 // #line <number>
4908 Pattern = new CodeCompletionString;
4909 Pattern->AddTypedTextChunk("line");
4910 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
4911 Pattern->AddPlaceholderChunk("number");
4912 Results.AddResult(Pattern);
4913
4914 // #line <number> "filename"
4915 Pattern = new CodeCompletionString;
4916 Pattern->AddTypedTextChunk("line");
4917 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
4918 Pattern->AddPlaceholderChunk("number");
4919 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
4920 Pattern->AddTextChunk("\"");
4921 Pattern->AddPlaceholderChunk("filename");
4922 Pattern->AddTextChunk("\"");
4923 Results.AddResult(Pattern);
4924
4925 // #error <message>
4926 Pattern = new CodeCompletionString;
4927 Pattern->AddTypedTextChunk("error");
4928 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
4929 Pattern->AddPlaceholderChunk("message");
4930 Results.AddResult(Pattern);
4931
4932 // #pragma <arguments>
4933 Pattern = new CodeCompletionString;
4934 Pattern->AddTypedTextChunk("pragma");
4935 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
4936 Pattern->AddPlaceholderChunk("arguments");
4937 Results.AddResult(Pattern);
4938
4939 if (getLangOptions().ObjC1) {
4940 // #import "header"
4941 Pattern = new CodeCompletionString;
4942 Pattern->AddTypedTextChunk("import");
4943 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
4944 Pattern->AddTextChunk("\"");
4945 Pattern->AddPlaceholderChunk("header");
4946 Pattern->AddTextChunk("\"");
4947 Results.AddResult(Pattern);
4948
4949 // #import <header>
4950 Pattern = new CodeCompletionString;
4951 Pattern->AddTypedTextChunk("import");
4952 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
4953 Pattern->AddTextChunk("<");
4954 Pattern->AddPlaceholderChunk("header");
4955 Pattern->AddTextChunk(">");
4956 Results.AddResult(Pattern);
4957 }
4958
4959 // #include_next "header"
4960 Pattern = new CodeCompletionString;
4961 Pattern->AddTypedTextChunk("include_next");
4962 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
4963 Pattern->AddTextChunk("\"");
4964 Pattern->AddPlaceholderChunk("header");
4965 Pattern->AddTextChunk("\"");
4966 Results.AddResult(Pattern);
4967
4968 // #include_next <header>
4969 Pattern = new CodeCompletionString;
4970 Pattern->AddTypedTextChunk("include_next");
4971 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
4972 Pattern->AddTextChunk("<");
4973 Pattern->AddPlaceholderChunk("header");
4974 Pattern->AddTextChunk(">");
4975 Results.AddResult(Pattern);
4976
4977 // #warning <message>
4978 Pattern = new CodeCompletionString;
4979 Pattern->AddTypedTextChunk("warning");
4980 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
4981 Pattern->AddPlaceholderChunk("message");
4982 Results.AddResult(Pattern);
4983
4984 // Note: #ident and #sccs are such crazy anachronisms that we don't provide
4985 // completions for them. And __include_macros is a Clang-internal extension
4986 // that we don't want to encourage anyone to use.
4987
4988 // FIXME: we don't support #assert or #unassert, so don't suggest them.
4989 Results.ExitScope();
4990
Douglas Gregorf44e8542010-08-24 19:08:16 +00004991 HandleCodeCompleteResults(this, CodeCompleter,
Douglas Gregor721f3592010-08-25 18:41:16 +00004992 CodeCompletionContext::CCC_PreprocessorDirective,
Douglas Gregorf44e8542010-08-24 19:08:16 +00004993 Results.data(), Results.size());
4994}
4995
4996void Sema::CodeCompleteInPreprocessorConditionalExclusion(Scope *S) {
Douglas Gregorf29c5232010-08-24 22:20:20 +00004997 CodeCompleteOrdinaryName(S,
John McCallf312b1e2010-08-26 23:41:50 +00004998 S->getFnParent()? Sema::PCC_RecoveryInFunction
4999 : Sema::PCC_Namespace);
Douglas Gregorf44e8542010-08-24 19:08:16 +00005000}
5001
Douglas Gregorf29c5232010-08-24 22:20:20 +00005002void Sema::CodeCompletePreprocessorMacroName(bool IsDefinition) {
Douglas Gregor1fbb4472010-08-24 20:21:13 +00005003 ResultBuilder Results(*this);
5004 if (!IsDefinition && (!CodeCompleter || CodeCompleter->includeMacros())) {
5005 // Add just the names of macros, not their arguments.
5006 Results.EnterNewScope();
5007 for (Preprocessor::macro_iterator M = PP.macro_begin(),
5008 MEnd = PP.macro_end();
5009 M != MEnd; ++M) {
5010 CodeCompletionString *Pattern = new CodeCompletionString;
5011 Pattern->AddTypedTextChunk(M->first->getName());
5012 Results.AddResult(Pattern);
5013 }
5014 Results.ExitScope();
5015 } else if (IsDefinition) {
5016 // FIXME: Can we detect when the user just wrote an include guard above?
5017 }
5018
5019 HandleCodeCompleteResults(this, CodeCompleter,
5020 IsDefinition? CodeCompletionContext::CCC_MacroName
5021 : CodeCompletionContext::CCC_MacroNameUse,
5022 Results.data(), Results.size());
5023}
5024
Douglas Gregorf29c5232010-08-24 22:20:20 +00005025void Sema::CodeCompletePreprocessorExpression() {
5026 ResultBuilder Results(*this);
5027
5028 if (!CodeCompleter || CodeCompleter->includeMacros())
5029 AddMacroResults(PP, Results);
5030
5031 // defined (<macro>)
5032 Results.EnterNewScope();
5033 CodeCompletionString *Pattern = new CodeCompletionString;
5034 Pattern->AddTypedTextChunk("defined");
5035 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
5036 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
5037 Pattern->AddPlaceholderChunk("macro");
5038 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
5039 Results.AddResult(Pattern);
5040 Results.ExitScope();
5041
5042 HandleCodeCompleteResults(this, CodeCompleter,
5043 CodeCompletionContext::CCC_PreprocessorExpression,
5044 Results.data(), Results.size());
5045}
5046
5047void Sema::CodeCompletePreprocessorMacroArgument(Scope *S,
5048 IdentifierInfo *Macro,
5049 MacroInfo *MacroInfo,
5050 unsigned Argument) {
5051 // FIXME: In the future, we could provide "overload" results, much like we
5052 // do for function calls.
5053
5054 CodeCompleteOrdinaryName(S,
John McCallf312b1e2010-08-26 23:41:50 +00005055 S->getFnParent()? Sema::PCC_RecoveryInFunction
5056 : Sema::PCC_Namespace);
Douglas Gregorf29c5232010-08-24 22:20:20 +00005057}
5058
Douglas Gregor55817af2010-08-25 17:04:25 +00005059void Sema::CodeCompleteNaturalLanguage() {
Douglas Gregor55817af2010-08-25 17:04:25 +00005060 HandleCodeCompleteResults(this, CodeCompleter,
Douglas Gregoraf1c6b52010-08-25 17:10:00 +00005061 CodeCompletionContext::CCC_NaturalLanguage,
Douglas Gregor55817af2010-08-25 17:04:25 +00005062 0, 0);
5063}
5064
Douglas Gregor87c08a52010-08-13 22:48:40 +00005065void Sema::GatherGlobalCodeCompletions(
John McCall0a2c5e22010-08-25 06:19:51 +00005066 llvm::SmallVectorImpl<CodeCompletionResult> &Results) {
Douglas Gregor87c08a52010-08-13 22:48:40 +00005067 ResultBuilder Builder(*this);
5068
Douglas Gregor8071e422010-08-15 06:18:01 +00005069 if (!CodeCompleter || CodeCompleter->includeGlobals()) {
5070 CodeCompletionDeclConsumer Consumer(Builder,
5071 Context.getTranslationUnitDecl());
5072 LookupVisibleDecls(Context.getTranslationUnitDecl(), LookupAnyName,
5073 Consumer);
5074 }
Douglas Gregor87c08a52010-08-13 22:48:40 +00005075
5076 if (!CodeCompleter || CodeCompleter->includeMacros())
5077 AddMacroResults(PP, Builder);
5078
5079 Results.clear();
5080 Results.insert(Results.end(),
5081 Builder.data(), Builder.data() + Builder.size());
5082}