blob: 371921ca11e47066d636f4097149d44a98308d2c [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 Gregord36adf52010-09-16 16:06:31 +000025#include "llvm/ADT/DenseSet.h"
Douglas Gregor86d9a522009-09-21 16:56:56 +000026#include "llvm/ADT/SmallPtrSet.h"
Douglas Gregor6a684032009-09-28 03:51:44 +000027#include "llvm/ADT/StringExtras.h"
Douglas Gregor22f56992010-04-06 19:22:33 +000028#include "llvm/ADT/StringSwitch.h"
Douglas Gregor458433d2010-08-26 15:07:07 +000029#include "llvm/ADT/Twine.h"
Douglas Gregor86d9a522009-09-21 16:56:56 +000030#include <list>
31#include <map>
32#include <vector>
Douglas Gregor81b747b2009-09-17 21:32:03 +000033
34using namespace clang;
John McCall781472f2010-08-25 08:40:02 +000035using namespace sema;
Douglas Gregor81b747b2009-09-17 21:32:03 +000036
Douglas Gregor86d9a522009-09-21 16:56:56 +000037namespace {
38 /// \brief A container of code-completion results.
39 class ResultBuilder {
40 public:
41 /// \brief The type of a name-lookup filter, which can be provided to the
42 /// name-lookup routines to specify which declarations should be included in
43 /// the result set (when it returns true) and which declarations should be
44 /// filtered out (returns false).
45 typedef bool (ResultBuilder::*LookupFilter)(NamedDecl *) const;
46
John McCall0a2c5e22010-08-25 06:19:51 +000047 typedef CodeCompletionResult Result;
Douglas Gregor86d9a522009-09-21 16:56:56 +000048
49 private:
50 /// \brief The actual results we have found.
51 std::vector<Result> Results;
52
53 /// \brief A record of all of the declarations we have found and placed
54 /// into the result set, used to ensure that no declaration ever gets into
55 /// the result set twice.
56 llvm::SmallPtrSet<Decl*, 16> AllDeclsFound;
57
Douglas Gregorfbcb5d62009-12-06 20:23:50 +000058 typedef std::pair<NamedDecl *, unsigned> DeclIndexPair;
59
60 /// \brief An entry in the shadow map, which is optimized to store
61 /// a single (declaration, index) mapping (the common case) but
62 /// can also store a list of (declaration, index) mappings.
63 class ShadowMapEntry {
64 typedef llvm::SmallVector<DeclIndexPair, 4> DeclIndexPairVector;
65
66 /// \brief Contains either the solitary NamedDecl * or a vector
67 /// of (declaration, index) pairs.
68 llvm::PointerUnion<NamedDecl *, DeclIndexPairVector*> DeclOrVector;
69
70 /// \brief When the entry contains a single declaration, this is
71 /// the index associated with that entry.
72 unsigned SingleDeclIndex;
73
74 public:
75 ShadowMapEntry() : DeclOrVector(), SingleDeclIndex(0) { }
76
77 void Add(NamedDecl *ND, unsigned Index) {
78 if (DeclOrVector.isNull()) {
79 // 0 - > 1 elements: just set the single element information.
80 DeclOrVector = ND;
81 SingleDeclIndex = Index;
82 return;
83 }
84
85 if (NamedDecl *PrevND = DeclOrVector.dyn_cast<NamedDecl *>()) {
86 // 1 -> 2 elements: create the vector of results and push in the
87 // existing declaration.
88 DeclIndexPairVector *Vec = new DeclIndexPairVector;
89 Vec->push_back(DeclIndexPair(PrevND, SingleDeclIndex));
90 DeclOrVector = Vec;
91 }
92
93 // Add the new element to the end of the vector.
94 DeclOrVector.get<DeclIndexPairVector*>()->push_back(
95 DeclIndexPair(ND, Index));
96 }
97
98 void Destroy() {
99 if (DeclIndexPairVector *Vec
100 = DeclOrVector.dyn_cast<DeclIndexPairVector *>()) {
101 delete Vec;
102 DeclOrVector = ((NamedDecl *)0);
103 }
104 }
105
106 // Iteration.
107 class iterator;
108 iterator begin() const;
109 iterator end() const;
110 };
111
Douglas Gregor86d9a522009-09-21 16:56:56 +0000112 /// \brief A mapping from declaration names to the declarations that have
113 /// this name within a particular scope and their index within the list of
114 /// results.
Douglas Gregorfbcb5d62009-12-06 20:23:50 +0000115 typedef llvm::DenseMap<DeclarationName, ShadowMapEntry> ShadowMap;
Douglas Gregor86d9a522009-09-21 16:56:56 +0000116
117 /// \brief The semantic analysis object for which results are being
118 /// produced.
119 Sema &SemaRef;
120
121 /// \brief If non-NULL, a filter function used to remove any code-completion
122 /// results that are not desirable.
123 LookupFilter Filter;
Douglas Gregor45bcd432010-01-14 03:21:49 +0000124
125 /// \brief Whether we should allow declarations as
126 /// nested-name-specifiers that would otherwise be filtered out.
127 bool AllowNestedNameSpecifiers;
128
Douglas Gregor5ac3bdb2010-05-30 01:49:25 +0000129 /// \brief If set, the type that we would prefer our resulting value
130 /// declarations to have.
131 ///
132 /// Closely matching the preferred type gives a boost to a result's
133 /// priority.
134 CanQualType PreferredType;
135
Douglas Gregor86d9a522009-09-21 16:56:56 +0000136 /// \brief A list of shadow maps, which is used to model name hiding at
137 /// different levels of, e.g., the inheritance hierarchy.
138 std::list<ShadowMap> ShadowMaps;
139
Douglas Gregor3cdee122010-08-26 16:36:48 +0000140 /// \brief If we're potentially referring to a C++ member function, the set
141 /// of qualifiers applied to the object type.
142 Qualifiers ObjectTypeQualifiers;
143
144 /// \brief Whether the \p ObjectTypeQualifiers field is active.
145 bool HasObjectTypeQualifiers;
146
Douglas Gregor265f7492010-08-27 15:29:55 +0000147 /// \brief The selector that we prefer.
148 Selector PreferredSelector;
149
Douglas Gregor1f5537a2010-07-08 23:20:03 +0000150 void AdjustResultPriorityForPreferredType(Result &R);
151
Douglas Gregor86d9a522009-09-21 16:56:56 +0000152 public:
153 explicit ResultBuilder(Sema &SemaRef, LookupFilter Filter = 0)
Douglas Gregor3cdee122010-08-26 16:36:48 +0000154 : SemaRef(SemaRef), Filter(Filter), AllowNestedNameSpecifiers(false),
155 HasObjectTypeQualifiers(false) { }
Douglas Gregor86d9a522009-09-21 16:56:56 +0000156
Douglas Gregord8e8a582010-05-25 21:41:55 +0000157 /// \brief Whether we should include code patterns in the completion
158 /// results.
159 bool includeCodePatterns() const {
160 return SemaRef.CodeCompleter &&
Douglas Gregorf6961522010-08-27 21:18:54 +0000161 SemaRef.CodeCompleter->includeCodePatterns();
Douglas Gregord8e8a582010-05-25 21:41:55 +0000162 }
163
Douglas Gregor86d9a522009-09-21 16:56:56 +0000164 /// \brief Set the filter used for code-completion results.
165 void setFilter(LookupFilter Filter) {
166 this->Filter = Filter;
167 }
168
Douglas Gregor86d9a522009-09-21 16:56:56 +0000169 Result *data() { return Results.empty()? 0 : &Results.front(); }
170 unsigned size() const { return Results.size(); }
171 bool empty() const { return Results.empty(); }
172
Douglas 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 Gregor265f7492010-08-27 15:29:55 +0000190 /// \brief Set the preferred selector.
191 ///
192 /// When an Objective-C method declaration result is added, and that
193 /// method's selector matches this preferred selector, we give that method
194 /// a slight priority boost.
195 void setPreferredSelector(Selector Sel) {
196 PreferredSelector = Sel;
197 }
198
Douglas Gregor45bcd432010-01-14 03:21:49 +0000199 /// \brief Specify whether nested-name-specifiers are allowed.
200 void allowNestedNameSpecifiers(bool Allow = true) {
201 AllowNestedNameSpecifiers = Allow;
202 }
203
Douglas Gregore495b7f2010-01-14 00:20:49 +0000204 /// \brief Determine whether the given declaration is at all interesting
205 /// as a code-completion result.
Douglas Gregor45bcd432010-01-14 03:21:49 +0000206 ///
207 /// \param ND the declaration that we are inspecting.
208 ///
209 /// \param AsNestedNameSpecifier will be set true if this declaration is
210 /// only interesting when it is a nested-name-specifier.
211 bool isInterestingDecl(NamedDecl *ND, bool &AsNestedNameSpecifier) const;
Douglas Gregor6660d842010-01-14 00:41:07 +0000212
213 /// \brief Check whether the result is hidden by the Hiding declaration.
214 ///
215 /// \returns true if the result is hidden and cannot be found, false if
216 /// the hidden result could still be found. When false, \p R may be
217 /// modified to describe how the result can be found (e.g., via extra
218 /// qualification).
219 bool CheckHiddenResult(Result &R, DeclContext *CurContext,
220 NamedDecl *Hiding);
221
Douglas Gregor86d9a522009-09-21 16:56:56 +0000222 /// \brief Add a new result to this result set (if it isn't already in one
223 /// of the shadow maps), or replace an existing result (for, e.g., a
224 /// redeclaration).
Douglas Gregor456c4a12009-09-21 20:12:40 +0000225 ///
Douglas Gregor1ca6ae82010-01-14 01:09:38 +0000226 /// \param CurContext the result to add (if it is unique).
Douglas Gregor456c4a12009-09-21 20:12:40 +0000227 ///
228 /// \param R the context in which this result will be named.
229 void MaybeAddResult(Result R, DeclContext *CurContext = 0);
Douglas Gregor86d9a522009-09-21 16:56:56 +0000230
Douglas Gregor1ca6ae82010-01-14 01:09:38 +0000231 /// \brief Add a new result to this result set, where we already know
232 /// the hiding declation (if any).
233 ///
234 /// \param R the result to add (if it is unique).
235 ///
236 /// \param CurContext the context in which this result will be named.
237 ///
238 /// \param Hiding the declaration that hides the result.
Douglas Gregor0cc84042010-01-14 15:47:35 +0000239 ///
240 /// \param InBaseClass whether the result was found in a base
241 /// class of the searched context.
242 void AddResult(Result R, DeclContext *CurContext, NamedDecl *Hiding,
243 bool InBaseClass);
Douglas Gregor1ca6ae82010-01-14 01:09:38 +0000244
Douglas Gregora4477812010-01-14 16:01:26 +0000245 /// \brief Add a new non-declaration result to this result set.
246 void AddResult(Result R);
247
Douglas Gregor86d9a522009-09-21 16:56:56 +0000248 /// \brief Enter into a new scope.
249 void EnterNewScope();
250
251 /// \brief Exit from the current scope.
252 void ExitScope();
253
Douglas Gregor55385fe2009-11-18 04:19:12 +0000254 /// \brief Ignore this declaration, if it is seen again.
255 void Ignore(Decl *D) { AllDeclsFound.insert(D->getCanonicalDecl()); }
256
Douglas Gregor86d9a522009-09-21 16:56:56 +0000257 /// \name Name lookup predicates
258 ///
259 /// These predicates can be passed to the name lookup functions to filter the
260 /// results of name lookup. All of the predicates have the same type, so that
261 ///
262 //@{
Douglas Gregor791215b2009-09-21 20:51:25 +0000263 bool IsOrdinaryName(NamedDecl *ND) const;
Douglas Gregor4710e5b2010-05-28 00:49:12 +0000264 bool IsOrdinaryNonTypeName(NamedDecl *ND) const;
Douglas Gregorf9578432010-07-28 21:50:18 +0000265 bool IsIntegralConstantValue(NamedDecl *ND) const;
Douglas Gregor01dfea02010-01-10 23:08:15 +0000266 bool IsOrdinaryNonValueName(NamedDecl *ND) const;
Douglas Gregor86d9a522009-09-21 16:56:56 +0000267 bool IsNestedNameSpecifier(NamedDecl *ND) const;
268 bool IsEnum(NamedDecl *ND) const;
269 bool IsClassOrStruct(NamedDecl *ND) const;
270 bool IsUnion(NamedDecl *ND) const;
271 bool IsNamespace(NamedDecl *ND) const;
272 bool IsNamespaceOrAlias(NamedDecl *ND) const;
273 bool IsType(NamedDecl *ND) const;
Douglas Gregoreb5758b2009-09-23 22:26:46 +0000274 bool IsMember(NamedDecl *ND) const;
Douglas Gregor80f4f4c2010-01-14 16:08:12 +0000275 bool IsObjCIvar(NamedDecl *ND) const;
Douglas Gregor8e254cf2010-05-27 23:06:34 +0000276 bool IsObjCMessageReceiver(NamedDecl *ND) const;
Douglas Gregorfb629412010-08-23 21:17:50 +0000277 bool IsObjCCollection(NamedDecl *ND) const;
Douglas Gregor86d9a522009-09-21 16:56:56 +0000278 //@}
279 };
280}
281
Douglas Gregorfbcb5d62009-12-06 20:23:50 +0000282class ResultBuilder::ShadowMapEntry::iterator {
283 llvm::PointerUnion<NamedDecl*, const DeclIndexPair*> DeclOrIterator;
284 unsigned SingleDeclIndex;
285
286public:
287 typedef DeclIndexPair value_type;
288 typedef value_type reference;
289 typedef std::ptrdiff_t difference_type;
290 typedef std::input_iterator_tag iterator_category;
291
292 class pointer {
293 DeclIndexPair Value;
294
295 public:
296 pointer(const DeclIndexPair &Value) : Value(Value) { }
297
298 const DeclIndexPair *operator->() const {
299 return &Value;
300 }
301 };
302
303 iterator() : DeclOrIterator((NamedDecl *)0), SingleDeclIndex(0) { }
304
305 iterator(NamedDecl *SingleDecl, unsigned Index)
306 : DeclOrIterator(SingleDecl), SingleDeclIndex(Index) { }
307
308 iterator(const DeclIndexPair *Iterator)
309 : DeclOrIterator(Iterator), SingleDeclIndex(0) { }
310
311 iterator &operator++() {
312 if (DeclOrIterator.is<NamedDecl *>()) {
313 DeclOrIterator = (NamedDecl *)0;
314 SingleDeclIndex = 0;
315 return *this;
316 }
317
318 const DeclIndexPair *I = DeclOrIterator.get<const DeclIndexPair*>();
319 ++I;
320 DeclOrIterator = I;
321 return *this;
322 }
323
Chris Lattner66392d42010-09-04 18:12:20 +0000324 /*iterator operator++(int) {
Douglas Gregorfbcb5d62009-12-06 20:23:50 +0000325 iterator tmp(*this);
326 ++(*this);
327 return tmp;
Chris Lattner66392d42010-09-04 18:12:20 +0000328 }*/
Douglas Gregorfbcb5d62009-12-06 20:23:50 +0000329
330 reference operator*() const {
331 if (NamedDecl *ND = DeclOrIterator.dyn_cast<NamedDecl *>())
332 return reference(ND, SingleDeclIndex);
333
Douglas Gregord490f952009-12-06 21:27:58 +0000334 return *DeclOrIterator.get<const DeclIndexPair*>();
Douglas Gregorfbcb5d62009-12-06 20:23:50 +0000335 }
336
337 pointer operator->() const {
338 return pointer(**this);
339 }
340
341 friend bool operator==(const iterator &X, const iterator &Y) {
Douglas Gregord490f952009-12-06 21:27:58 +0000342 return X.DeclOrIterator.getOpaqueValue()
343 == Y.DeclOrIterator.getOpaqueValue() &&
Douglas Gregorfbcb5d62009-12-06 20:23:50 +0000344 X.SingleDeclIndex == Y.SingleDeclIndex;
345 }
346
347 friend bool operator!=(const iterator &X, const iterator &Y) {
Douglas Gregord490f952009-12-06 21:27:58 +0000348 return !(X == Y);
Douglas Gregorfbcb5d62009-12-06 20:23:50 +0000349 }
350};
351
Douglas Gregorfbcb5d62009-12-06 20:23:50 +0000352ResultBuilder::ShadowMapEntry::iterator
353ResultBuilder::ShadowMapEntry::begin() const {
354 if (DeclOrVector.isNull())
355 return iterator();
356
357 if (NamedDecl *ND = DeclOrVector.dyn_cast<NamedDecl *>())
358 return iterator(ND, SingleDeclIndex);
359
360 return iterator(DeclOrVector.get<DeclIndexPairVector *>()->begin());
361}
362
363ResultBuilder::ShadowMapEntry::iterator
364ResultBuilder::ShadowMapEntry::end() const {
365 if (DeclOrVector.is<NamedDecl *>() || DeclOrVector.isNull())
366 return iterator();
367
368 return iterator(DeclOrVector.get<DeclIndexPairVector *>()->end());
369}
370
Douglas Gregor456c4a12009-09-21 20:12:40 +0000371/// \brief Compute the qualification required to get from the current context
372/// (\p CurContext) to the target context (\p TargetContext).
373///
374/// \param Context the AST context in which the qualification will be used.
375///
376/// \param CurContext the context where an entity is being named, which is
377/// typically based on the current scope.
378///
379/// \param TargetContext the context in which the named entity actually
380/// resides.
381///
382/// \returns a nested name specifier that refers into the target context, or
383/// NULL if no qualification is needed.
384static NestedNameSpecifier *
385getRequiredQualification(ASTContext &Context,
386 DeclContext *CurContext,
387 DeclContext *TargetContext) {
388 llvm::SmallVector<DeclContext *, 4> TargetParents;
389
390 for (DeclContext *CommonAncestor = TargetContext;
391 CommonAncestor && !CommonAncestor->Encloses(CurContext);
392 CommonAncestor = CommonAncestor->getLookupParent()) {
393 if (CommonAncestor->isTransparentContext() ||
394 CommonAncestor->isFunctionOrMethod())
395 continue;
396
397 TargetParents.push_back(CommonAncestor);
398 }
399
400 NestedNameSpecifier *Result = 0;
401 while (!TargetParents.empty()) {
402 DeclContext *Parent = TargetParents.back();
403 TargetParents.pop_back();
404
Douglas Gregorfb629412010-08-23 21:17:50 +0000405 if (NamespaceDecl *Namespace = dyn_cast<NamespaceDecl>(Parent)) {
406 if (!Namespace->getIdentifier())
407 continue;
408
Douglas Gregor456c4a12009-09-21 20:12:40 +0000409 Result = NestedNameSpecifier::Create(Context, Result, Namespace);
Douglas Gregorfb629412010-08-23 21:17:50 +0000410 }
Douglas Gregor456c4a12009-09-21 20:12:40 +0000411 else if (TagDecl *TD = dyn_cast<TagDecl>(Parent))
412 Result = NestedNameSpecifier::Create(Context, Result,
413 false,
414 Context.getTypeDeclType(TD).getTypePtr());
Douglas Gregor0c8296d2009-11-07 00:00:49 +0000415 }
Douglas Gregor456c4a12009-09-21 20:12:40 +0000416 return Result;
417}
418
Douglas Gregor45bcd432010-01-14 03:21:49 +0000419bool ResultBuilder::isInterestingDecl(NamedDecl *ND,
420 bool &AsNestedNameSpecifier) const {
421 AsNestedNameSpecifier = false;
422
Douglas Gregore495b7f2010-01-14 00:20:49 +0000423 ND = ND->getUnderlyingDecl();
424 unsigned IDNS = ND->getIdentifierNamespace();
Douglas Gregorf52cede2009-10-09 22:16:47 +0000425
426 // Skip unnamed entities.
Douglas Gregore495b7f2010-01-14 00:20:49 +0000427 if (!ND->getDeclName())
428 return false;
Douglas Gregor86d9a522009-09-21 16:56:56 +0000429
430 // Friend declarations and declarations introduced due to friends are never
431 // added as results.
John McCall92b7f702010-03-11 07:50:04 +0000432 if (IDNS & (Decl::IDNS_OrdinaryFriend | Decl::IDNS_TagFriend))
Douglas Gregore495b7f2010-01-14 00:20:49 +0000433 return false;
434
Douglas Gregor76282942009-12-11 17:31:05 +0000435 // Class template (partial) specializations are never added as results.
Douglas Gregore495b7f2010-01-14 00:20:49 +0000436 if (isa<ClassTemplateSpecializationDecl>(ND) ||
437 isa<ClassTemplatePartialSpecializationDecl>(ND))
438 return false;
Douglas Gregor86d9a522009-09-21 16:56:56 +0000439
Douglas Gregor76282942009-12-11 17:31:05 +0000440 // Using declarations themselves are never added as results.
Douglas Gregore495b7f2010-01-14 00:20:49 +0000441 if (isa<UsingDecl>(ND))
442 return false;
443
444 // Some declarations have reserved names that we don't want to ever show.
445 if (const IdentifierInfo *Id = ND->getIdentifier()) {
Douglas Gregor86d9a522009-09-21 16:56:56 +0000446 // __va_list_tag is a freak of nature. Find it and skip it.
447 if (Id->isStr("__va_list_tag") || Id->isStr("__builtin_va_list"))
Douglas Gregore495b7f2010-01-14 00:20:49 +0000448 return false;
Douglas Gregor86d9a522009-09-21 16:56:56 +0000449
Douglas Gregorf52cede2009-10-09 22:16:47 +0000450 // Filter out names reserved for the implementation (C99 7.1.3,
Douglas Gregor797efb52010-07-14 17:44:04 +0000451 // C++ [lib.global.names]) if they come from a system header.
Daniel Dunbare013d682009-10-18 20:26:12 +0000452 //
453 // FIXME: Add predicate for this.
Douglas Gregorf52cede2009-10-09 22:16:47 +0000454 if (Id->getLength() >= 2) {
Daniel Dunbare013d682009-10-18 20:26:12 +0000455 const char *Name = Id->getNameStart();
Douglas Gregorf52cede2009-10-09 22:16:47 +0000456 if (Name[0] == '_' &&
Douglas Gregor797efb52010-07-14 17:44:04 +0000457 (Name[1] == '_' || (Name[1] >= 'A' && Name[1] <= 'Z')) &&
458 (ND->getLocation().isInvalid() ||
459 SemaRef.SourceMgr.isInSystemHeader(
460 SemaRef.SourceMgr.getSpellingLoc(ND->getLocation()))))
Douglas Gregore495b7f2010-01-14 00:20:49 +0000461 return false;
Douglas Gregorf52cede2009-10-09 22:16:47 +0000462 }
Douglas Gregor86d9a522009-09-21 16:56:56 +0000463 }
Douglas Gregore495b7f2010-01-14 00:20:49 +0000464
Douglas Gregor86d9a522009-09-21 16:56:56 +0000465 // C++ constructors are never found by name lookup.
Douglas Gregore495b7f2010-01-14 00:20:49 +0000466 if (isa<CXXConstructorDecl>(ND))
467 return false;
Douglas Gregor86d9a522009-09-21 16:56:56 +0000468
Douglas Gregora5fb7c32010-08-16 23:05:20 +0000469 if (Filter == &ResultBuilder::IsNestedNameSpecifier ||
470 ((isa<NamespaceDecl>(ND) || isa<NamespaceAliasDecl>(ND)) &&
471 Filter != &ResultBuilder::IsNamespace &&
472 Filter != &ResultBuilder::IsNamespaceOrAlias))
473 AsNestedNameSpecifier = true;
474
Douglas Gregor86d9a522009-09-21 16:56:56 +0000475 // Filter out any unwanted results.
Douglas Gregor45bcd432010-01-14 03:21:49 +0000476 if (Filter && !(this->*Filter)(ND)) {
477 // Check whether it is interesting as a nested-name-specifier.
478 if (AllowNestedNameSpecifiers && SemaRef.getLangOptions().CPlusPlus &&
479 IsNestedNameSpecifier(ND) &&
480 (Filter != &ResultBuilder::IsMember ||
481 (isa<CXXRecordDecl>(ND) &&
482 cast<CXXRecordDecl>(ND)->isInjectedClassName()))) {
483 AsNestedNameSpecifier = true;
484 return true;
485 }
486
Douglas Gregore495b7f2010-01-14 00:20:49 +0000487 return false;
Douglas Gregora5fb7c32010-08-16 23:05:20 +0000488 }
Douglas Gregore495b7f2010-01-14 00:20:49 +0000489 // ... then it must be interesting!
490 return true;
491}
492
Douglas Gregor6660d842010-01-14 00:41:07 +0000493bool ResultBuilder::CheckHiddenResult(Result &R, DeclContext *CurContext,
494 NamedDecl *Hiding) {
495 // In C, there is no way to refer to a hidden name.
496 // FIXME: This isn't true; we can find a tag name hidden by an ordinary
497 // name if we introduce the tag type.
498 if (!SemaRef.getLangOptions().CPlusPlus)
499 return true;
500
Sebastian Redl7a126a42010-08-31 00:36:30 +0000501 DeclContext *HiddenCtx = R.Declaration->getDeclContext()->getRedeclContext();
Douglas Gregor6660d842010-01-14 00:41:07 +0000502
503 // There is no way to qualify a name declared in a function or method.
504 if (HiddenCtx->isFunctionOrMethod())
505 return true;
506
Sebastian Redl7a126a42010-08-31 00:36:30 +0000507 if (HiddenCtx == Hiding->getDeclContext()->getRedeclContext())
Douglas Gregor6660d842010-01-14 00:41:07 +0000508 return true;
509
510 // We can refer to the result with the appropriate qualification. Do it.
511 R.Hidden = true;
512 R.QualifierIsInformative = false;
513
514 if (!R.Qualifier)
515 R.Qualifier = getRequiredQualification(SemaRef.Context,
516 CurContext,
517 R.Declaration->getDeclContext());
518 return false;
519}
520
Douglas Gregor1f5537a2010-07-08 23:20:03 +0000521/// \brief A simplified classification of types used to determine whether two
522/// types are "similar enough" when adjusting priorities.
Douglas Gregor1827e102010-08-16 16:18:59 +0000523SimplifiedTypeClass clang::getSimplifiedTypeClass(CanQualType T) {
Douglas Gregor1f5537a2010-07-08 23:20:03 +0000524 switch (T->getTypeClass()) {
525 case Type::Builtin:
526 switch (cast<BuiltinType>(T)->getKind()) {
527 case BuiltinType::Void:
528 return STC_Void;
529
530 case BuiltinType::NullPtr:
531 return STC_Pointer;
532
533 case BuiltinType::Overload:
534 case BuiltinType::Dependent:
535 case BuiltinType::UndeducedAuto:
536 return STC_Other;
537
538 case BuiltinType::ObjCId:
539 case BuiltinType::ObjCClass:
540 case BuiltinType::ObjCSel:
541 return STC_ObjectiveC;
542
543 default:
544 return STC_Arithmetic;
545 }
546 return STC_Other;
547
548 case Type::Complex:
549 return STC_Arithmetic;
550
551 case Type::Pointer:
552 return STC_Pointer;
553
554 case Type::BlockPointer:
555 return STC_Block;
556
557 case Type::LValueReference:
558 case Type::RValueReference:
559 return getSimplifiedTypeClass(T->getAs<ReferenceType>()->getPointeeType());
560
561 case Type::ConstantArray:
562 case Type::IncompleteArray:
563 case Type::VariableArray:
564 case Type::DependentSizedArray:
565 return STC_Array;
566
567 case Type::DependentSizedExtVector:
568 case Type::Vector:
569 case Type::ExtVector:
570 return STC_Arithmetic;
571
572 case Type::FunctionProto:
573 case Type::FunctionNoProto:
574 return STC_Function;
575
576 case Type::Record:
577 return STC_Record;
578
579 case Type::Enum:
580 return STC_Arithmetic;
581
582 case Type::ObjCObject:
583 case Type::ObjCInterface:
584 case Type::ObjCObjectPointer:
585 return STC_ObjectiveC;
586
587 default:
588 return STC_Other;
589 }
590}
591
592/// \brief Get the type that a given expression will have if this declaration
593/// is used as an expression in its "typical" code-completion form.
Douglas Gregor1827e102010-08-16 16:18:59 +0000594QualType clang::getDeclUsageType(ASTContext &C, NamedDecl *ND) {
Douglas Gregor1f5537a2010-07-08 23:20:03 +0000595 ND = cast<NamedDecl>(ND->getUnderlyingDecl());
596
597 if (TypeDecl *Type = dyn_cast<TypeDecl>(ND))
598 return C.getTypeDeclType(Type);
599 if (ObjCInterfaceDecl *Iface = dyn_cast<ObjCInterfaceDecl>(ND))
600 return C.getObjCInterfaceType(Iface);
601
602 QualType T;
603 if (FunctionDecl *Function = dyn_cast<FunctionDecl>(ND))
Douglas Gregor5291c3c2010-07-13 08:18:22 +0000604 T = Function->getCallResultType();
Douglas Gregor1f5537a2010-07-08 23:20:03 +0000605 else if (ObjCMethodDecl *Method = dyn_cast<ObjCMethodDecl>(ND))
Douglas Gregor5291c3c2010-07-13 08:18:22 +0000606 T = Method->getSendResultType();
Douglas Gregor1f5537a2010-07-08 23:20:03 +0000607 else if (FunctionTemplateDecl *FunTmpl = dyn_cast<FunctionTemplateDecl>(ND))
Douglas Gregor5291c3c2010-07-13 08:18:22 +0000608 T = FunTmpl->getTemplatedDecl()->getCallResultType();
Douglas Gregor1f5537a2010-07-08 23:20:03 +0000609 else if (EnumConstantDecl *Enumerator = dyn_cast<EnumConstantDecl>(ND))
610 T = C.getTypeDeclType(cast<EnumDecl>(Enumerator->getDeclContext()));
611 else if (ObjCPropertyDecl *Property = dyn_cast<ObjCPropertyDecl>(ND))
612 T = Property->getType();
613 else if (ValueDecl *Value = dyn_cast<ValueDecl>(ND))
614 T = Value->getType();
615 else
616 return QualType();
617
618 return T.getNonReferenceType();
619}
620
621void ResultBuilder::AdjustResultPriorityForPreferredType(Result &R) {
622 QualType T = getDeclUsageType(SemaRef.Context, R.Declaration);
623 if (T.isNull())
624 return;
625
626 CanQualType TC = SemaRef.Context.getCanonicalType(T);
627 // Check for exactly-matching types (modulo qualifiers).
Douglas Gregoreb0d0142010-08-24 23:58:17 +0000628 if (SemaRef.Context.hasSameUnqualifiedType(PreferredType, TC)) {
629 if (PreferredType->isVoidType())
630 R.Priority += CCD_VoidMatch;
631 else
632 R.Priority /= CCF_ExactTypeMatch;
633 } // Check for nearly-matching types, based on classification of each.
Douglas Gregor1f5537a2010-07-08 23:20:03 +0000634 else if ((getSimplifiedTypeClass(PreferredType)
635 == getSimplifiedTypeClass(TC)) &&
636 !(PreferredType->isEnumeralType() && TC->isEnumeralType()))
637 R.Priority /= CCF_SimilarTypeMatch;
638}
639
Douglas Gregore495b7f2010-01-14 00:20:49 +0000640void ResultBuilder::MaybeAddResult(Result R, DeclContext *CurContext) {
641 assert(!ShadowMaps.empty() && "Must enter into a results scope");
642
643 if (R.Kind != Result::RK_Declaration) {
644 // For non-declaration results, just add the result.
645 Results.push_back(R);
646 return;
647 }
648
649 // Look through using declarations.
650 if (UsingShadowDecl *Using = dyn_cast<UsingShadowDecl>(R.Declaration)) {
651 MaybeAddResult(Result(Using->getTargetDecl(), R.Qualifier), CurContext);
652 return;
653 }
654
655 Decl *CanonDecl = R.Declaration->getCanonicalDecl();
656 unsigned IDNS = CanonDecl->getIdentifierNamespace();
657
Douglas Gregor45bcd432010-01-14 03:21:49 +0000658 bool AsNestedNameSpecifier = false;
659 if (!isInterestingDecl(R.Declaration, AsNestedNameSpecifier))
Douglas Gregore495b7f2010-01-14 00:20:49 +0000660 return;
661
Douglas Gregor86d9a522009-09-21 16:56:56 +0000662 ShadowMap &SMap = ShadowMaps.back();
Douglas Gregorfbcb5d62009-12-06 20:23:50 +0000663 ShadowMapEntry::iterator I, IEnd;
664 ShadowMap::iterator NamePos = SMap.find(R.Declaration->getDeclName());
665 if (NamePos != SMap.end()) {
666 I = NamePos->second.begin();
667 IEnd = NamePos->second.end();
668 }
669
670 for (; I != IEnd; ++I) {
671 NamedDecl *ND = I->first;
672 unsigned Index = I->second;
Douglas Gregor86d9a522009-09-21 16:56:56 +0000673 if (ND->getCanonicalDecl() == CanonDecl) {
674 // This is a redeclaration. Always pick the newer declaration.
Douglas Gregor86d9a522009-09-21 16:56:56 +0000675 Results[Index].Declaration = R.Declaration;
676
Douglas Gregor86d9a522009-09-21 16:56:56 +0000677 // We're done.
678 return;
679 }
680 }
681
682 // This is a new declaration in this scope. However, check whether this
683 // declaration name is hidden by a similarly-named declaration in an outer
684 // scope.
685 std::list<ShadowMap>::iterator SM, SMEnd = ShadowMaps.end();
686 --SMEnd;
687 for (SM = ShadowMaps.begin(); SM != SMEnd; ++SM) {
Douglas Gregorfbcb5d62009-12-06 20:23:50 +0000688 ShadowMapEntry::iterator I, IEnd;
689 ShadowMap::iterator NamePos = SM->find(R.Declaration->getDeclName());
690 if (NamePos != SM->end()) {
691 I = NamePos->second.begin();
692 IEnd = NamePos->second.end();
693 }
694 for (; I != IEnd; ++I) {
Douglas Gregor86d9a522009-09-21 16:56:56 +0000695 // A tag declaration does not hide a non-tag declaration.
John McCall0d6b1642010-04-23 18:46:30 +0000696 if (I->first->hasTagIdentifierNamespace() &&
Douglas Gregor86d9a522009-09-21 16:56:56 +0000697 (IDNS & (Decl::IDNS_Member | Decl::IDNS_Ordinary |
698 Decl::IDNS_ObjCProtocol)))
699 continue;
700
701 // Protocols are in distinct namespaces from everything else.
Douglas Gregorfbcb5d62009-12-06 20:23:50 +0000702 if (((I->first->getIdentifierNamespace() & Decl::IDNS_ObjCProtocol)
Douglas Gregor86d9a522009-09-21 16:56:56 +0000703 || (IDNS & Decl::IDNS_ObjCProtocol)) &&
Douglas Gregorfbcb5d62009-12-06 20:23:50 +0000704 I->first->getIdentifierNamespace() != IDNS)
Douglas Gregor86d9a522009-09-21 16:56:56 +0000705 continue;
706
707 // The newly-added result is hidden by an entry in the shadow map.
Douglas Gregor6660d842010-01-14 00:41:07 +0000708 if (CheckHiddenResult(R, CurContext, I->first))
Douglas Gregor86d9a522009-09-21 16:56:56 +0000709 return;
Douglas Gregor86d9a522009-09-21 16:56:56 +0000710
711 break;
712 }
713 }
714
715 // Make sure that any given declaration only shows up in the result set once.
716 if (!AllDeclsFound.insert(CanonDecl))
717 return;
Douglas Gregor265f7492010-08-27 15:29:55 +0000718
719 // If this is an Objective-C method declaration whose selector matches our
720 // preferred selector, give it a priority boost.
721 if (!PreferredSelector.isNull())
722 if (ObjCMethodDecl *Method = dyn_cast<ObjCMethodDecl>(R.Declaration))
723 if (PreferredSelector == Method->getSelector())
724 R.Priority += CCD_SelectorMatch;
725
Douglas Gregoreb5758b2009-09-23 22:26:46 +0000726 // If the filter is for nested-name-specifiers, then this result starts a
727 // nested-name-specifier.
Douglas Gregor12e13132010-05-26 22:00:08 +0000728 if (AsNestedNameSpecifier) {
Douglas Gregoreb5758b2009-09-23 22:26:46 +0000729 R.StartsNestedNameSpecifier = true;
Douglas Gregor12e13132010-05-26 22:00:08 +0000730 R.Priority = CCP_NestedNameSpecifier;
Douglas Gregor1f5537a2010-07-08 23:20:03 +0000731 } else if (!PreferredType.isNull())
732 AdjustResultPriorityForPreferredType(R);
Douglas Gregor265f7492010-08-27 15:29:55 +0000733
Douglas Gregor0563c262009-09-22 23:15:58 +0000734 // If this result is supposed to have an informative qualifier, add one.
Douglas Gregoreb5758b2009-09-23 22:26:46 +0000735 if (R.QualifierIsInformative && !R.Qualifier &&
736 !R.StartsNestedNameSpecifier) {
Douglas Gregor0563c262009-09-22 23:15:58 +0000737 DeclContext *Ctx = R.Declaration->getDeclContext();
738 if (NamespaceDecl *Namespace = dyn_cast<NamespaceDecl>(Ctx))
739 R.Qualifier = NestedNameSpecifier::Create(SemaRef.Context, 0, Namespace);
740 else if (TagDecl *Tag = dyn_cast<TagDecl>(Ctx))
741 R.Qualifier = NestedNameSpecifier::Create(SemaRef.Context, 0, false,
742 SemaRef.Context.getTypeDeclType(Tag).getTypePtr());
743 else
744 R.QualifierIsInformative = false;
745 }
Douglas Gregoreb5758b2009-09-23 22:26:46 +0000746
Douglas Gregor86d9a522009-09-21 16:56:56 +0000747 // Insert this result into the set of results and into the current shadow
748 // map.
Douglas Gregorfbcb5d62009-12-06 20:23:50 +0000749 SMap[R.Declaration->getDeclName()].Add(R.Declaration, Results.size());
Douglas Gregor86d9a522009-09-21 16:56:56 +0000750 Results.push_back(R);
751}
752
Douglas Gregor1ca6ae82010-01-14 01:09:38 +0000753void ResultBuilder::AddResult(Result R, DeclContext *CurContext,
Douglas Gregor0cc84042010-01-14 15:47:35 +0000754 NamedDecl *Hiding, bool InBaseClass = false) {
Douglas Gregora4477812010-01-14 16:01:26 +0000755 if (R.Kind != Result::RK_Declaration) {
756 // For non-declaration results, just add the result.
757 Results.push_back(R);
758 return;
759 }
760
Douglas Gregor1ca6ae82010-01-14 01:09:38 +0000761 // Look through using declarations.
762 if (UsingShadowDecl *Using = dyn_cast<UsingShadowDecl>(R.Declaration)) {
763 AddResult(Result(Using->getTargetDecl(), R.Qualifier), CurContext, Hiding);
764 return;
765 }
766
Douglas Gregor45bcd432010-01-14 03:21:49 +0000767 bool AsNestedNameSpecifier = false;
768 if (!isInterestingDecl(R.Declaration, AsNestedNameSpecifier))
Douglas Gregor1ca6ae82010-01-14 01:09:38 +0000769 return;
770
771 if (Hiding && CheckHiddenResult(R, CurContext, Hiding))
772 return;
773
774 // Make sure that any given declaration only shows up in the result set once.
775 if (!AllDeclsFound.insert(R.Declaration->getCanonicalDecl()))
776 return;
777
778 // If the filter is for nested-name-specifiers, then this result starts a
779 // nested-name-specifier.
Douglas Gregor12e13132010-05-26 22:00:08 +0000780 if (AsNestedNameSpecifier) {
Douglas Gregor1ca6ae82010-01-14 01:09:38 +0000781 R.StartsNestedNameSpecifier = true;
Douglas Gregor12e13132010-05-26 22:00:08 +0000782 R.Priority = CCP_NestedNameSpecifier;
783 }
Douglas Gregor0cc84042010-01-14 15:47:35 +0000784 else if (Filter == &ResultBuilder::IsMember && !R.Qualifier && InBaseClass &&
785 isa<CXXRecordDecl>(R.Declaration->getDeclContext()
Sebastian Redl7a126a42010-08-31 00:36:30 +0000786 ->getRedeclContext()))
Douglas Gregor0cc84042010-01-14 15:47:35 +0000787 R.QualifierIsInformative = true;
788
Douglas Gregor1ca6ae82010-01-14 01:09:38 +0000789 // If this result is supposed to have an informative qualifier, add one.
790 if (R.QualifierIsInformative && !R.Qualifier &&
791 !R.StartsNestedNameSpecifier) {
792 DeclContext *Ctx = R.Declaration->getDeclContext();
793 if (NamespaceDecl *Namespace = dyn_cast<NamespaceDecl>(Ctx))
794 R.Qualifier = NestedNameSpecifier::Create(SemaRef.Context, 0, Namespace);
795 else if (TagDecl *Tag = dyn_cast<TagDecl>(Ctx))
796 R.Qualifier = NestedNameSpecifier::Create(SemaRef.Context, 0, false,
Douglas Gregor45bcd432010-01-14 03:21:49 +0000797 SemaRef.Context.getTypeDeclType(Tag).getTypePtr());
Douglas Gregor1ca6ae82010-01-14 01:09:38 +0000798 else
799 R.QualifierIsInformative = false;
800 }
801
Douglas Gregor12e13132010-05-26 22:00:08 +0000802 // Adjust the priority if this result comes from a base class.
803 if (InBaseClass)
804 R.Priority += CCD_InBaseClass;
805
Douglas Gregor265f7492010-08-27 15:29:55 +0000806 // If this is an Objective-C method declaration whose selector matches our
807 // preferred selector, give it a priority boost.
808 if (!PreferredSelector.isNull())
809 if (ObjCMethodDecl *Method = dyn_cast<ObjCMethodDecl>(R.Declaration))
810 if (PreferredSelector == Method->getSelector())
811 R.Priority += CCD_SelectorMatch;
812
Douglas Gregor1f5537a2010-07-08 23:20:03 +0000813 if (!PreferredType.isNull())
814 AdjustResultPriorityForPreferredType(R);
Douglas Gregor5ac3bdb2010-05-30 01:49:25 +0000815
Douglas Gregor3cdee122010-08-26 16:36:48 +0000816 if (HasObjectTypeQualifiers)
817 if (CXXMethodDecl *Method = dyn_cast<CXXMethodDecl>(R.Declaration))
818 if (Method->isInstance()) {
819 Qualifiers MethodQuals
820 = Qualifiers::fromCVRMask(Method->getTypeQualifiers());
821 if (ObjectTypeQualifiers == MethodQuals)
822 R.Priority += CCD_ObjectQualifierMatch;
823 else if (ObjectTypeQualifiers - MethodQuals) {
824 // The method cannot be invoked, because doing so would drop
825 // qualifiers.
826 return;
827 }
828 }
829
Douglas Gregor1ca6ae82010-01-14 01:09:38 +0000830 // Insert this result into the set of results.
831 Results.push_back(R);
832}
833
Douglas Gregora4477812010-01-14 16:01:26 +0000834void ResultBuilder::AddResult(Result R) {
835 assert(R.Kind != Result::RK_Declaration &&
836 "Declaration results need more context");
837 Results.push_back(R);
838}
839
Douglas Gregor86d9a522009-09-21 16:56:56 +0000840/// \brief Enter into a new scope.
841void ResultBuilder::EnterNewScope() {
842 ShadowMaps.push_back(ShadowMap());
843}
844
845/// \brief Exit from the current scope.
846void ResultBuilder::ExitScope() {
Douglas Gregorfbcb5d62009-12-06 20:23:50 +0000847 for (ShadowMap::iterator E = ShadowMaps.back().begin(),
848 EEnd = ShadowMaps.back().end();
849 E != EEnd;
850 ++E)
851 E->second.Destroy();
852
Douglas Gregor86d9a522009-09-21 16:56:56 +0000853 ShadowMaps.pop_back();
854}
855
Douglas Gregor791215b2009-09-21 20:51:25 +0000856/// \brief Determines whether this given declaration will be found by
857/// ordinary name lookup.
858bool ResultBuilder::IsOrdinaryName(NamedDecl *ND) const {
Douglas Gregor4710e5b2010-05-28 00:49:12 +0000859 ND = cast<NamedDecl>(ND->getUnderlyingDecl());
860
Douglas Gregor791215b2009-09-21 20:51:25 +0000861 unsigned IDNS = Decl::IDNS_Ordinary;
862 if (SemaRef.getLangOptions().CPlusPlus)
Douglas Gregor9b30b262010-06-15 20:26:51 +0000863 IDNS |= Decl::IDNS_Tag | Decl::IDNS_Namespace | Decl::IDNS_Member;
Douglas Gregor1ca6ae82010-01-14 01:09:38 +0000864 else if (SemaRef.getLangOptions().ObjC1 && isa<ObjCIvarDecl>(ND))
865 return true;
866
Douglas Gregor791215b2009-09-21 20:51:25 +0000867 return ND->getIdentifierNamespace() & IDNS;
868}
869
Douglas Gregor01dfea02010-01-10 23:08:15 +0000870/// \brief Determines whether this given declaration will be found by
Douglas Gregor4710e5b2010-05-28 00:49:12 +0000871/// ordinary name lookup but is not a type name.
872bool ResultBuilder::IsOrdinaryNonTypeName(NamedDecl *ND) const {
873 ND = cast<NamedDecl>(ND->getUnderlyingDecl());
874 if (isa<TypeDecl>(ND) || isa<ObjCInterfaceDecl>(ND))
875 return false;
876
877 unsigned IDNS = Decl::IDNS_Ordinary;
878 if (SemaRef.getLangOptions().CPlusPlus)
Douglas Gregor9b30b262010-06-15 20:26:51 +0000879 IDNS |= Decl::IDNS_Tag | Decl::IDNS_Namespace | Decl::IDNS_Member;
Douglas Gregor4710e5b2010-05-28 00:49:12 +0000880 else if (SemaRef.getLangOptions().ObjC1 && isa<ObjCIvarDecl>(ND))
881 return true;
882
883 return ND->getIdentifierNamespace() & IDNS;
884}
885
Douglas Gregorf9578432010-07-28 21:50:18 +0000886bool ResultBuilder::IsIntegralConstantValue(NamedDecl *ND) const {
887 if (!IsOrdinaryNonTypeName(ND))
888 return 0;
889
890 if (ValueDecl *VD = dyn_cast<ValueDecl>(ND->getUnderlyingDecl()))
891 if (VD->getType()->isIntegralOrEnumerationType())
892 return true;
893
894 return false;
895}
896
Douglas Gregor4710e5b2010-05-28 00:49:12 +0000897/// \brief Determines whether this given declaration will be found by
Douglas Gregor01dfea02010-01-10 23:08:15 +0000898/// ordinary name lookup.
899bool ResultBuilder::IsOrdinaryNonValueName(NamedDecl *ND) const {
Douglas Gregor4710e5b2010-05-28 00:49:12 +0000900 ND = cast<NamedDecl>(ND->getUnderlyingDecl());
901
Douglas Gregor01dfea02010-01-10 23:08:15 +0000902 unsigned IDNS = Decl::IDNS_Ordinary;
903 if (SemaRef.getLangOptions().CPlusPlus)
John McCall0d6b1642010-04-23 18:46:30 +0000904 IDNS |= Decl::IDNS_Tag | Decl::IDNS_Namespace;
Douglas Gregor01dfea02010-01-10 23:08:15 +0000905
906 return (ND->getIdentifierNamespace() & IDNS) &&
Douglas Gregor4710e5b2010-05-28 00:49:12 +0000907 !isa<ValueDecl>(ND) && !isa<FunctionTemplateDecl>(ND) &&
908 !isa<ObjCPropertyDecl>(ND);
Douglas Gregor01dfea02010-01-10 23:08:15 +0000909}
910
Douglas Gregor86d9a522009-09-21 16:56:56 +0000911/// \brief Determines whether the given declaration is suitable as the
912/// start of a C++ nested-name-specifier, e.g., a class or namespace.
913bool ResultBuilder::IsNestedNameSpecifier(NamedDecl *ND) const {
914 // Allow us to find class templates, too.
915 if (ClassTemplateDecl *ClassTemplate = dyn_cast<ClassTemplateDecl>(ND))
916 ND = ClassTemplate->getTemplatedDecl();
917
918 return SemaRef.isAcceptableNestedNameSpecifier(ND);
919}
920
921/// \brief Determines whether the given declaration is an enumeration.
922bool ResultBuilder::IsEnum(NamedDecl *ND) const {
923 return isa<EnumDecl>(ND);
924}
925
926/// \brief Determines whether the given declaration is a class or struct.
927bool ResultBuilder::IsClassOrStruct(NamedDecl *ND) const {
928 // Allow us to find class templates, too.
929 if (ClassTemplateDecl *ClassTemplate = dyn_cast<ClassTemplateDecl>(ND))
930 ND = ClassTemplate->getTemplatedDecl();
931
932 if (RecordDecl *RD = dyn_cast<RecordDecl>(ND))
Abramo Bagnara465d41b2010-05-11 21:36:43 +0000933 return RD->getTagKind() == TTK_Class ||
934 RD->getTagKind() == TTK_Struct;
Douglas Gregor86d9a522009-09-21 16:56:56 +0000935
936 return false;
937}
938
939/// \brief Determines whether the given declaration is a union.
940bool ResultBuilder::IsUnion(NamedDecl *ND) const {
941 // Allow us to find class templates, too.
942 if (ClassTemplateDecl *ClassTemplate = dyn_cast<ClassTemplateDecl>(ND))
943 ND = ClassTemplate->getTemplatedDecl();
944
945 if (RecordDecl *RD = dyn_cast<RecordDecl>(ND))
Abramo Bagnara465d41b2010-05-11 21:36:43 +0000946 return RD->getTagKind() == TTK_Union;
Douglas Gregor86d9a522009-09-21 16:56:56 +0000947
948 return false;
949}
950
951/// \brief Determines whether the given declaration is a namespace.
952bool ResultBuilder::IsNamespace(NamedDecl *ND) const {
953 return isa<NamespaceDecl>(ND);
954}
955
956/// \brief Determines whether the given declaration is a namespace or
957/// namespace alias.
958bool ResultBuilder::IsNamespaceOrAlias(NamedDecl *ND) const {
959 return isa<NamespaceDecl>(ND) || isa<NamespaceAliasDecl>(ND);
960}
961
Douglas Gregor76282942009-12-11 17:31:05 +0000962/// \brief Determines whether the given declaration is a type.
Douglas Gregor86d9a522009-09-21 16:56:56 +0000963bool ResultBuilder::IsType(NamedDecl *ND) const {
Douglas Gregord32b0222010-08-24 01:06:58 +0000964 if (UsingShadowDecl *Using = dyn_cast<UsingShadowDecl>(ND))
965 ND = Using->getTargetDecl();
966
967 return isa<TypeDecl>(ND) || isa<ObjCInterfaceDecl>(ND);
Douglas Gregor86d9a522009-09-21 16:56:56 +0000968}
969
Douglas Gregor76282942009-12-11 17:31:05 +0000970/// \brief Determines which members of a class should be visible via
971/// "." or "->". Only value declarations, nested name specifiers, and
972/// using declarations thereof should show up.
Douglas Gregoreb5758b2009-09-23 22:26:46 +0000973bool ResultBuilder::IsMember(NamedDecl *ND) const {
Douglas Gregor76282942009-12-11 17:31:05 +0000974 if (UsingShadowDecl *Using = dyn_cast<UsingShadowDecl>(ND))
975 ND = Using->getTargetDecl();
976
Douglas Gregorce821962009-12-11 18:14:22 +0000977 return isa<ValueDecl>(ND) || isa<FunctionTemplateDecl>(ND) ||
978 isa<ObjCPropertyDecl>(ND);
Douglas Gregoreb5758b2009-09-23 22:26:46 +0000979}
980
Douglas Gregor8e254cf2010-05-27 23:06:34 +0000981static bool isObjCReceiverType(ASTContext &C, QualType T) {
982 T = C.getCanonicalType(T);
983 switch (T->getTypeClass()) {
984 case Type::ObjCObject:
985 case Type::ObjCInterface:
986 case Type::ObjCObjectPointer:
987 return true;
988
989 case Type::Builtin:
990 switch (cast<BuiltinType>(T)->getKind()) {
991 case BuiltinType::ObjCId:
992 case BuiltinType::ObjCClass:
993 case BuiltinType::ObjCSel:
994 return true;
995
996 default:
997 break;
998 }
999 return false;
1000
1001 default:
1002 break;
1003 }
1004
1005 if (!C.getLangOptions().CPlusPlus)
1006 return false;
1007
1008 // FIXME: We could perform more analysis here to determine whether a
1009 // particular class type has any conversions to Objective-C types. For now,
1010 // just accept all class types.
1011 return T->isDependentType() || T->isRecordType();
1012}
1013
1014bool ResultBuilder::IsObjCMessageReceiver(NamedDecl *ND) const {
1015 QualType T = getDeclUsageType(SemaRef.Context, ND);
1016 if (T.isNull())
1017 return false;
1018
1019 T = SemaRef.Context.getBaseElementType(T);
1020 return isObjCReceiverType(SemaRef.Context, T);
1021}
1022
Douglas Gregorfb629412010-08-23 21:17:50 +00001023bool ResultBuilder::IsObjCCollection(NamedDecl *ND) const {
1024 if ((SemaRef.getLangOptions().CPlusPlus && !IsOrdinaryName(ND)) ||
1025 (!SemaRef.getLangOptions().CPlusPlus && !IsOrdinaryNonTypeName(ND)))
1026 return false;
1027
1028 QualType T = getDeclUsageType(SemaRef.Context, ND);
1029 if (T.isNull())
1030 return false;
1031
1032 T = SemaRef.Context.getBaseElementType(T);
1033 return T->isObjCObjectType() || T->isObjCObjectPointerType() ||
1034 T->isObjCIdType() ||
1035 (SemaRef.getLangOptions().CPlusPlus && T->isRecordType());
1036}
Douglas Gregor8e254cf2010-05-27 23:06:34 +00001037
Douglas Gregor80f4f4c2010-01-14 16:08:12 +00001038/// \rief Determines whether the given declaration is an Objective-C
1039/// instance variable.
1040bool ResultBuilder::IsObjCIvar(NamedDecl *ND) const {
1041 return isa<ObjCIvarDecl>(ND);
1042}
1043
Douglas Gregor1ca6ae82010-01-14 01:09:38 +00001044namespace {
1045 /// \brief Visible declaration consumer that adds a code-completion result
1046 /// for each visible declaration.
1047 class CodeCompletionDeclConsumer : public VisibleDeclConsumer {
1048 ResultBuilder &Results;
1049 DeclContext *CurContext;
1050
1051 public:
1052 CodeCompletionDeclConsumer(ResultBuilder &Results, DeclContext *CurContext)
1053 : Results(Results), CurContext(CurContext) { }
1054
Douglas Gregor0cc84042010-01-14 15:47:35 +00001055 virtual void FoundDecl(NamedDecl *ND, NamedDecl *Hiding, bool InBaseClass) {
1056 Results.AddResult(ND, CurContext, Hiding, InBaseClass);
Douglas Gregor1ca6ae82010-01-14 01:09:38 +00001057 }
1058 };
1059}
1060
Douglas Gregor86d9a522009-09-21 16:56:56 +00001061/// \brief Add type specifiers for the current language as keyword results.
Douglas Gregorbca403c2010-01-13 23:51:12 +00001062static void AddTypeSpecifierResults(const LangOptions &LangOpts,
Douglas Gregor86d9a522009-09-21 16:56:56 +00001063 ResultBuilder &Results) {
John McCall0a2c5e22010-08-25 06:19:51 +00001064 typedef CodeCompletionResult Result;
Douglas Gregor12e13132010-05-26 22:00:08 +00001065 Results.AddResult(Result("short", CCP_Type));
1066 Results.AddResult(Result("long", CCP_Type));
1067 Results.AddResult(Result("signed", CCP_Type));
1068 Results.AddResult(Result("unsigned", CCP_Type));
1069 Results.AddResult(Result("void", CCP_Type));
1070 Results.AddResult(Result("char", CCP_Type));
1071 Results.AddResult(Result("int", CCP_Type));
1072 Results.AddResult(Result("float", CCP_Type));
1073 Results.AddResult(Result("double", CCP_Type));
1074 Results.AddResult(Result("enum", CCP_Type));
1075 Results.AddResult(Result("struct", CCP_Type));
1076 Results.AddResult(Result("union", CCP_Type));
1077 Results.AddResult(Result("const", CCP_Type));
1078 Results.AddResult(Result("volatile", CCP_Type));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001079
Douglas Gregor86d9a522009-09-21 16:56:56 +00001080 if (LangOpts.C99) {
1081 // C99-specific
Douglas Gregor12e13132010-05-26 22:00:08 +00001082 Results.AddResult(Result("_Complex", CCP_Type));
1083 Results.AddResult(Result("_Imaginary", CCP_Type));
1084 Results.AddResult(Result("_Bool", CCP_Type));
1085 Results.AddResult(Result("restrict", CCP_Type));
Douglas Gregor86d9a522009-09-21 16:56:56 +00001086 }
1087
1088 if (LangOpts.CPlusPlus) {
1089 // C++-specific
Douglas Gregor12e13132010-05-26 22:00:08 +00001090 Results.AddResult(Result("bool", CCP_Type));
1091 Results.AddResult(Result("class", CCP_Type));
1092 Results.AddResult(Result("wchar_t", CCP_Type));
Douglas Gregor86d9a522009-09-21 16:56:56 +00001093
Douglas Gregorc8bddde2010-05-28 00:22:41 +00001094 // typename qualified-id
1095 CodeCompletionString *Pattern = new CodeCompletionString;
1096 Pattern->AddTypedTextChunk("typename");
1097 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
1098 Pattern->AddPlaceholderChunk("qualifier");
1099 Pattern->AddTextChunk("::");
1100 Pattern->AddPlaceholderChunk("name");
1101 Results.AddResult(Result(Pattern));
Douglas Gregord8e8a582010-05-25 21:41:55 +00001102
Douglas Gregor86d9a522009-09-21 16:56:56 +00001103 if (LangOpts.CPlusPlus0x) {
Douglas Gregor12e13132010-05-26 22:00:08 +00001104 Results.AddResult(Result("auto", CCP_Type));
1105 Results.AddResult(Result("char16_t", CCP_Type));
1106 Results.AddResult(Result("char32_t", CCP_Type));
Douglas Gregorc8bddde2010-05-28 00:22:41 +00001107
1108 CodeCompletionString *Pattern = new CodeCompletionString;
1109 Pattern->AddTypedTextChunk("decltype");
1110 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
1111 Pattern->AddPlaceholderChunk("expression");
1112 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
1113 Results.AddResult(Result(Pattern));
Douglas Gregor86d9a522009-09-21 16:56:56 +00001114 }
1115 }
1116
1117 // GNU extensions
1118 if (LangOpts.GNUMode) {
1119 // FIXME: Enable when we actually support decimal floating point.
Douglas Gregora4477812010-01-14 16:01:26 +00001120 // Results.AddResult(Result("_Decimal32"));
1121 // Results.AddResult(Result("_Decimal64"));
1122 // Results.AddResult(Result("_Decimal128"));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001123
Douglas Gregorc8bddde2010-05-28 00:22:41 +00001124 CodeCompletionString *Pattern = new CodeCompletionString;
1125 Pattern->AddTypedTextChunk("typeof");
1126 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
1127 Pattern->AddPlaceholderChunk("expression");
1128 Results.AddResult(Result(Pattern));
1129
1130 Pattern = new CodeCompletionString;
1131 Pattern->AddTypedTextChunk("typeof");
1132 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
1133 Pattern->AddPlaceholderChunk("type");
1134 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
1135 Results.AddResult(Result(Pattern));
Douglas Gregor86d9a522009-09-21 16:56:56 +00001136 }
1137}
1138
John McCallf312b1e2010-08-26 23:41:50 +00001139static void AddStorageSpecifiers(Sema::ParserCompletionContext CCC,
Douglas Gregor01dfea02010-01-10 23:08:15 +00001140 const LangOptions &LangOpts,
Douglas Gregor01dfea02010-01-10 23:08:15 +00001141 ResultBuilder &Results) {
John McCall0a2c5e22010-08-25 06:19:51 +00001142 typedef CodeCompletionResult Result;
Douglas Gregor01dfea02010-01-10 23:08:15 +00001143 // Note: we don't suggest either "auto" or "register", because both
1144 // are pointless as storage specifiers. Elsewhere, we suggest "auto"
1145 // in C++0x as a type specifier.
Douglas Gregora4477812010-01-14 16:01:26 +00001146 Results.AddResult(Result("extern"));
1147 Results.AddResult(Result("static"));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001148}
1149
John McCallf312b1e2010-08-26 23:41:50 +00001150static void AddFunctionSpecifiers(Sema::ParserCompletionContext CCC,
Douglas Gregor01dfea02010-01-10 23:08:15 +00001151 const LangOptions &LangOpts,
Douglas Gregor01dfea02010-01-10 23:08:15 +00001152 ResultBuilder &Results) {
John McCall0a2c5e22010-08-25 06:19:51 +00001153 typedef CodeCompletionResult Result;
Douglas Gregor01dfea02010-01-10 23:08:15 +00001154 switch (CCC) {
John McCallf312b1e2010-08-26 23:41:50 +00001155 case Sema::PCC_Class:
1156 case Sema::PCC_MemberTemplate:
Douglas Gregor01dfea02010-01-10 23:08:15 +00001157 if (LangOpts.CPlusPlus) {
Douglas Gregora4477812010-01-14 16:01:26 +00001158 Results.AddResult(Result("explicit"));
1159 Results.AddResult(Result("friend"));
1160 Results.AddResult(Result("mutable"));
1161 Results.AddResult(Result("virtual"));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001162 }
1163 // Fall through
1164
John McCallf312b1e2010-08-26 23:41:50 +00001165 case Sema::PCC_ObjCInterface:
1166 case Sema::PCC_ObjCImplementation:
1167 case Sema::PCC_Namespace:
1168 case Sema::PCC_Template:
Douglas Gregor01dfea02010-01-10 23:08:15 +00001169 if (LangOpts.CPlusPlus || LangOpts.C99)
Douglas Gregora4477812010-01-14 16:01:26 +00001170 Results.AddResult(Result("inline"));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001171 break;
1172
John McCallf312b1e2010-08-26 23:41:50 +00001173 case Sema::PCC_ObjCInstanceVariableList:
1174 case Sema::PCC_Expression:
1175 case Sema::PCC_Statement:
1176 case Sema::PCC_ForInit:
1177 case Sema::PCC_Condition:
1178 case Sema::PCC_RecoveryInFunction:
1179 case Sema::PCC_Type:
Douglas Gregor02688102010-09-14 23:59:36 +00001180 case Sema::PCC_ParenthesizedExpression:
Douglas Gregor01dfea02010-01-10 23:08:15 +00001181 break;
1182 }
1183}
1184
Douglas Gregorbca403c2010-01-13 23:51:12 +00001185static void AddObjCExpressionResults(ResultBuilder &Results, bool NeedAt);
1186static void AddObjCStatementResults(ResultBuilder &Results, bool NeedAt);
1187static void AddObjCVisibilityResults(const LangOptions &LangOpts,
Douglas Gregorc38c3e12010-01-13 21:54:15 +00001188 ResultBuilder &Results,
1189 bool NeedAt);
Douglas Gregorbca403c2010-01-13 23:51:12 +00001190static void AddObjCImplementationResults(const LangOptions &LangOpts,
Douglas Gregorb6ac2452010-01-13 21:24:21 +00001191 ResultBuilder &Results,
1192 bool NeedAt);
Douglas Gregorbca403c2010-01-13 23:51:12 +00001193static void AddObjCInterfaceResults(const LangOptions &LangOpts,
Douglas Gregorb6ac2452010-01-13 21:24:21 +00001194 ResultBuilder &Results,
1195 bool NeedAt);
Douglas Gregorbca403c2010-01-13 23:51:12 +00001196static void AddObjCTopLevelResults(ResultBuilder &Results, bool NeedAt);
Douglas Gregorb6ac2452010-01-13 21:24:21 +00001197
Douglas Gregorc8bddde2010-05-28 00:22:41 +00001198static void AddTypedefResult(ResultBuilder &Results) {
1199 CodeCompletionString *Pattern = new CodeCompletionString;
1200 Pattern->AddTypedTextChunk("typedef");
1201 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
1202 Pattern->AddPlaceholderChunk("type");
1203 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
1204 Pattern->AddPlaceholderChunk("name");
John McCall0a2c5e22010-08-25 06:19:51 +00001205 Results.AddResult(CodeCompletionResult(Pattern));
Douglas Gregorc8bddde2010-05-28 00:22:41 +00001206}
1207
John McCallf312b1e2010-08-26 23:41:50 +00001208static bool WantTypesInContext(Sema::ParserCompletionContext CCC,
Douglas Gregor4710e5b2010-05-28 00:49:12 +00001209 const LangOptions &LangOpts) {
Douglas Gregor4710e5b2010-05-28 00:49:12 +00001210 switch (CCC) {
John McCallf312b1e2010-08-26 23:41:50 +00001211 case Sema::PCC_Namespace:
1212 case Sema::PCC_Class:
1213 case Sema::PCC_ObjCInstanceVariableList:
1214 case Sema::PCC_Template:
1215 case Sema::PCC_MemberTemplate:
1216 case Sema::PCC_Statement:
1217 case Sema::PCC_RecoveryInFunction:
1218 case Sema::PCC_Type:
Douglas Gregor02688102010-09-14 23:59:36 +00001219 case Sema::PCC_ParenthesizedExpression:
Douglas Gregor4710e5b2010-05-28 00:49:12 +00001220 return true;
1221
John McCallf312b1e2010-08-26 23:41:50 +00001222 case Sema::PCC_Expression:
1223 case Sema::PCC_Condition:
Douglas Gregor02688102010-09-14 23:59:36 +00001224 return LangOpts.CPlusPlus;
1225
1226 case Sema::PCC_ObjCInterface:
1227 case Sema::PCC_ObjCImplementation:
Douglas Gregor4710e5b2010-05-28 00:49:12 +00001228 return false;
1229
John McCallf312b1e2010-08-26 23:41:50 +00001230 case Sema::PCC_ForInit:
Douglas Gregor02688102010-09-14 23:59:36 +00001231 return LangOpts.CPlusPlus || LangOpts.ObjC1 || LangOpts.C99;
Douglas Gregor4710e5b2010-05-28 00:49:12 +00001232 }
1233
1234 return false;
1235}
1236
Douglas Gregor01dfea02010-01-10 23:08:15 +00001237/// \brief Add language constructs that show up for "ordinary" names.
John McCallf312b1e2010-08-26 23:41:50 +00001238static void AddOrdinaryNameResults(Sema::ParserCompletionContext CCC,
Douglas Gregor01dfea02010-01-10 23:08:15 +00001239 Scope *S,
1240 Sema &SemaRef,
Douglas Gregor01dfea02010-01-10 23:08:15 +00001241 ResultBuilder &Results) {
John McCall0a2c5e22010-08-25 06:19:51 +00001242 typedef CodeCompletionResult Result;
Douglas Gregor01dfea02010-01-10 23:08:15 +00001243 switch (CCC) {
John McCallf312b1e2010-08-26 23:41:50 +00001244 case Sema::PCC_Namespace:
Douglas Gregorc8bddde2010-05-28 00:22:41 +00001245 if (SemaRef.getLangOptions().CPlusPlus) {
1246 CodeCompletionString *Pattern = 0;
1247
1248 if (Results.includeCodePatterns()) {
1249 // namespace <identifier> { declarations }
1250 CodeCompletionString *Pattern = new CodeCompletionString;
1251 Pattern->AddTypedTextChunk("namespace");
1252 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
1253 Pattern->AddPlaceholderChunk("identifier");
1254 Pattern->AddChunk(CodeCompletionString::CK_LeftBrace);
1255 Pattern->AddPlaceholderChunk("declarations");
1256 Pattern->AddChunk(CodeCompletionString::CK_VerticalSpace);
1257 Pattern->AddChunk(CodeCompletionString::CK_RightBrace);
1258 Results.AddResult(Result(Pattern));
1259 }
1260
Douglas Gregor01dfea02010-01-10 23:08:15 +00001261 // namespace identifier = identifier ;
1262 Pattern = new CodeCompletionString;
1263 Pattern->AddTypedTextChunk("namespace");
1264 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
Douglas Gregorc8bddde2010-05-28 00:22:41 +00001265 Pattern->AddPlaceholderChunk("name");
Douglas Gregor01dfea02010-01-10 23:08:15 +00001266 Pattern->AddChunk(CodeCompletionString::CK_Equal);
Douglas Gregorc8bddde2010-05-28 00:22:41 +00001267 Pattern->AddPlaceholderChunk("namespace");
Douglas Gregora4477812010-01-14 16:01:26 +00001268 Results.AddResult(Result(Pattern));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001269
1270 // Using directives
1271 Pattern = new CodeCompletionString;
1272 Pattern->AddTypedTextChunk("using");
1273 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
1274 Pattern->AddTextChunk("namespace");
1275 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
1276 Pattern->AddPlaceholderChunk("identifier");
Douglas Gregora4477812010-01-14 16:01:26 +00001277 Results.AddResult(Result(Pattern));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001278
1279 // asm(string-literal)
1280 Pattern = new CodeCompletionString;
1281 Pattern->AddTypedTextChunk("asm");
1282 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
1283 Pattern->AddPlaceholderChunk("string-literal");
1284 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
Douglas Gregora4477812010-01-14 16:01:26 +00001285 Results.AddResult(Result(Pattern));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001286
Douglas Gregorc8bddde2010-05-28 00:22:41 +00001287 if (Results.includeCodePatterns()) {
1288 // Explicit template instantiation
1289 Pattern = new CodeCompletionString;
1290 Pattern->AddTypedTextChunk("template");
1291 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
1292 Pattern->AddPlaceholderChunk("declaration");
1293 Results.AddResult(Result(Pattern));
1294 }
Douglas Gregor01dfea02010-01-10 23:08:15 +00001295 }
Douglas Gregorb6ac2452010-01-13 21:24:21 +00001296
1297 if (SemaRef.getLangOptions().ObjC1)
Douglas Gregorbca403c2010-01-13 23:51:12 +00001298 AddObjCTopLevelResults(Results, true);
Douglas Gregorb6ac2452010-01-13 21:24:21 +00001299
Douglas Gregorc8bddde2010-05-28 00:22:41 +00001300 AddTypedefResult(Results);
Douglas Gregor01dfea02010-01-10 23:08:15 +00001301 // Fall through
1302
John McCallf312b1e2010-08-26 23:41:50 +00001303 case Sema::PCC_Class:
Douglas Gregorc8bddde2010-05-28 00:22:41 +00001304 if (SemaRef.getLangOptions().CPlusPlus) {
Douglas Gregor01dfea02010-01-10 23:08:15 +00001305 // Using declaration
1306 CodeCompletionString *Pattern = new CodeCompletionString;
1307 Pattern->AddTypedTextChunk("using");
1308 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
Douglas Gregorc8bddde2010-05-28 00:22:41 +00001309 Pattern->AddPlaceholderChunk("qualifier");
1310 Pattern->AddTextChunk("::");
1311 Pattern->AddPlaceholderChunk("name");
Douglas Gregora4477812010-01-14 16:01:26 +00001312 Results.AddResult(Result(Pattern));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001313
Douglas Gregorc8bddde2010-05-28 00:22:41 +00001314 // using typename qualifier::name (only in a dependent context)
Douglas Gregor01dfea02010-01-10 23:08:15 +00001315 if (SemaRef.CurContext->isDependentContext()) {
1316 Pattern = new CodeCompletionString;
1317 Pattern->AddTypedTextChunk("using");
1318 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
1319 Pattern->AddTextChunk("typename");
1320 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
Douglas Gregorc8bddde2010-05-28 00:22:41 +00001321 Pattern->AddPlaceholderChunk("qualifier");
1322 Pattern->AddTextChunk("::");
1323 Pattern->AddPlaceholderChunk("name");
Douglas Gregora4477812010-01-14 16:01:26 +00001324 Results.AddResult(Result(Pattern));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001325 }
1326
John McCallf312b1e2010-08-26 23:41:50 +00001327 if (CCC == Sema::PCC_Class) {
Douglas Gregorc8bddde2010-05-28 00:22:41 +00001328 AddTypedefResult(Results);
1329
Douglas Gregor01dfea02010-01-10 23:08:15 +00001330 // public:
1331 Pattern = new CodeCompletionString;
1332 Pattern->AddTypedTextChunk("public");
1333 Pattern->AddChunk(CodeCompletionString::CK_Colon);
Douglas Gregora4477812010-01-14 16:01:26 +00001334 Results.AddResult(Result(Pattern));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001335
1336 // protected:
1337 Pattern = new CodeCompletionString;
1338 Pattern->AddTypedTextChunk("protected");
1339 Pattern->AddChunk(CodeCompletionString::CK_Colon);
Douglas Gregora4477812010-01-14 16:01:26 +00001340 Results.AddResult(Result(Pattern));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001341
1342 // private:
1343 Pattern = new CodeCompletionString;
1344 Pattern->AddTypedTextChunk("private");
1345 Pattern->AddChunk(CodeCompletionString::CK_Colon);
Douglas Gregora4477812010-01-14 16:01:26 +00001346 Results.AddResult(Result(Pattern));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001347 }
1348 }
1349 // Fall through
1350
John McCallf312b1e2010-08-26 23:41:50 +00001351 case Sema::PCC_Template:
1352 case Sema::PCC_MemberTemplate:
Douglas Gregord8e8a582010-05-25 21:41:55 +00001353 if (SemaRef.getLangOptions().CPlusPlus && Results.includeCodePatterns()) {
Douglas Gregor01dfea02010-01-10 23:08:15 +00001354 // template < parameters >
1355 CodeCompletionString *Pattern = new CodeCompletionString;
1356 Pattern->AddTypedTextChunk("template");
1357 Pattern->AddChunk(CodeCompletionString::CK_LeftAngle);
1358 Pattern->AddPlaceholderChunk("parameters");
1359 Pattern->AddChunk(CodeCompletionString::CK_RightAngle);
Douglas Gregora4477812010-01-14 16:01:26 +00001360 Results.AddResult(Result(Pattern));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001361 }
1362
Douglas Gregorbca403c2010-01-13 23:51:12 +00001363 AddStorageSpecifiers(CCC, SemaRef.getLangOptions(), Results);
1364 AddFunctionSpecifiers(CCC, SemaRef.getLangOptions(), Results);
Douglas Gregor01dfea02010-01-10 23:08:15 +00001365 break;
1366
John McCallf312b1e2010-08-26 23:41:50 +00001367 case Sema::PCC_ObjCInterface:
Douglas Gregorbca403c2010-01-13 23:51:12 +00001368 AddObjCInterfaceResults(SemaRef.getLangOptions(), Results, true);
1369 AddStorageSpecifiers(CCC, SemaRef.getLangOptions(), Results);
1370 AddFunctionSpecifiers(CCC, SemaRef.getLangOptions(), Results);
Douglas Gregorb6ac2452010-01-13 21:24:21 +00001371 break;
1372
John McCallf312b1e2010-08-26 23:41:50 +00001373 case Sema::PCC_ObjCImplementation:
Douglas Gregorbca403c2010-01-13 23:51:12 +00001374 AddObjCImplementationResults(SemaRef.getLangOptions(), Results, true);
1375 AddStorageSpecifiers(CCC, SemaRef.getLangOptions(), Results);
1376 AddFunctionSpecifiers(CCC, SemaRef.getLangOptions(), Results);
Douglas Gregorb6ac2452010-01-13 21:24:21 +00001377 break;
1378
John McCallf312b1e2010-08-26 23:41:50 +00001379 case Sema::PCC_ObjCInstanceVariableList:
Douglas Gregorbca403c2010-01-13 23:51:12 +00001380 AddObjCVisibilityResults(SemaRef.getLangOptions(), Results, true);
Douglas Gregorc38c3e12010-01-13 21:54:15 +00001381 break;
1382
John McCallf312b1e2010-08-26 23:41:50 +00001383 case Sema::PCC_RecoveryInFunction:
1384 case Sema::PCC_Statement: {
Douglas Gregorc8bddde2010-05-28 00:22:41 +00001385 AddTypedefResult(Results);
Douglas Gregor01dfea02010-01-10 23:08:15 +00001386
1387 CodeCompletionString *Pattern = 0;
Douglas Gregord8e8a582010-05-25 21:41:55 +00001388 if (SemaRef.getLangOptions().CPlusPlus && Results.includeCodePatterns()) {
Douglas Gregor01dfea02010-01-10 23:08:15 +00001389 Pattern = new CodeCompletionString;
1390 Pattern->AddTypedTextChunk("try");
1391 Pattern->AddChunk(CodeCompletionString::CK_LeftBrace);
1392 Pattern->AddPlaceholderChunk("statements");
1393 Pattern->AddChunk(CodeCompletionString::CK_VerticalSpace);
1394 Pattern->AddChunk(CodeCompletionString::CK_RightBrace);
1395 Pattern->AddTextChunk("catch");
1396 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
1397 Pattern->AddPlaceholderChunk("declaration");
1398 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
1399 Pattern->AddChunk(CodeCompletionString::CK_LeftBrace);
1400 Pattern->AddPlaceholderChunk("statements");
1401 Pattern->AddChunk(CodeCompletionString::CK_VerticalSpace);
1402 Pattern->AddChunk(CodeCompletionString::CK_RightBrace);
Douglas Gregora4477812010-01-14 16:01:26 +00001403 Results.AddResult(Result(Pattern));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001404 }
Douglas Gregorb6ac2452010-01-13 21:24:21 +00001405 if (SemaRef.getLangOptions().ObjC1)
Douglas Gregorbca403c2010-01-13 23:51:12 +00001406 AddObjCStatementResults(Results, true);
Douglas Gregorb6ac2452010-01-13 21:24:21 +00001407
Douglas Gregord8e8a582010-05-25 21:41:55 +00001408 if (Results.includeCodePatterns()) {
1409 // if (condition) { statements }
1410 Pattern = new CodeCompletionString;
1411 Pattern->AddTypedTextChunk("if");
1412 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
1413 if (SemaRef.getLangOptions().CPlusPlus)
1414 Pattern->AddPlaceholderChunk("condition");
1415 else
1416 Pattern->AddPlaceholderChunk("expression");
1417 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
1418 Pattern->AddChunk(CodeCompletionString::CK_LeftBrace);
1419 Pattern->AddPlaceholderChunk("statements");
1420 Pattern->AddChunk(CodeCompletionString::CK_VerticalSpace);
1421 Pattern->AddChunk(CodeCompletionString::CK_RightBrace);
1422 Results.AddResult(Result(Pattern));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001423
Douglas Gregord8e8a582010-05-25 21:41:55 +00001424 // switch (condition) { }
1425 Pattern = new CodeCompletionString;
1426 Pattern->AddTypedTextChunk("switch");
1427 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
1428 if (SemaRef.getLangOptions().CPlusPlus)
1429 Pattern->AddPlaceholderChunk("condition");
1430 else
1431 Pattern->AddPlaceholderChunk("expression");
1432 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
1433 Pattern->AddChunk(CodeCompletionString::CK_LeftBrace);
1434 Pattern->AddChunk(CodeCompletionString::CK_VerticalSpace);
1435 Pattern->AddChunk(CodeCompletionString::CK_RightBrace);
1436 Results.AddResult(Result(Pattern));
1437 }
1438
Douglas Gregor01dfea02010-01-10 23:08:15 +00001439 // Switch-specific statements.
John McCall781472f2010-08-25 08:40:02 +00001440 if (!SemaRef.getCurFunction()->SwitchStack.empty()) {
Douglas Gregor01dfea02010-01-10 23:08:15 +00001441 // case expression:
1442 Pattern = new CodeCompletionString;
1443 Pattern->AddTypedTextChunk("case");
Douglas Gregorc8bddde2010-05-28 00:22:41 +00001444 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
Douglas Gregor01dfea02010-01-10 23:08:15 +00001445 Pattern->AddPlaceholderChunk("expression");
1446 Pattern->AddChunk(CodeCompletionString::CK_Colon);
Douglas Gregora4477812010-01-14 16:01:26 +00001447 Results.AddResult(Result(Pattern));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001448
1449 // default:
1450 Pattern = new CodeCompletionString;
1451 Pattern->AddTypedTextChunk("default");
1452 Pattern->AddChunk(CodeCompletionString::CK_Colon);
Douglas Gregora4477812010-01-14 16:01:26 +00001453 Results.AddResult(Result(Pattern));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001454 }
1455
Douglas Gregord8e8a582010-05-25 21:41:55 +00001456 if (Results.includeCodePatterns()) {
1457 /// while (condition) { statements }
1458 Pattern = new CodeCompletionString;
1459 Pattern->AddTypedTextChunk("while");
1460 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
1461 if (SemaRef.getLangOptions().CPlusPlus)
1462 Pattern->AddPlaceholderChunk("condition");
1463 else
1464 Pattern->AddPlaceholderChunk("expression");
1465 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
1466 Pattern->AddChunk(CodeCompletionString::CK_LeftBrace);
1467 Pattern->AddPlaceholderChunk("statements");
1468 Pattern->AddChunk(CodeCompletionString::CK_VerticalSpace);
1469 Pattern->AddChunk(CodeCompletionString::CK_RightBrace);
1470 Results.AddResult(Result(Pattern));
1471
1472 // do { statements } while ( expression );
1473 Pattern = new CodeCompletionString;
1474 Pattern->AddTypedTextChunk("do");
1475 Pattern->AddChunk(CodeCompletionString::CK_LeftBrace);
1476 Pattern->AddPlaceholderChunk("statements");
1477 Pattern->AddChunk(CodeCompletionString::CK_VerticalSpace);
1478 Pattern->AddChunk(CodeCompletionString::CK_RightBrace);
1479 Pattern->AddTextChunk("while");
1480 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
Douglas Gregor01dfea02010-01-10 23:08:15 +00001481 Pattern->AddPlaceholderChunk("expression");
Douglas Gregord8e8a582010-05-25 21:41:55 +00001482 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
1483 Results.AddResult(Result(Pattern));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001484
Douglas Gregord8e8a582010-05-25 21:41:55 +00001485 // for ( for-init-statement ; condition ; expression ) { statements }
1486 Pattern = new CodeCompletionString;
1487 Pattern->AddTypedTextChunk("for");
1488 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
1489 if (SemaRef.getLangOptions().CPlusPlus || SemaRef.getLangOptions().C99)
1490 Pattern->AddPlaceholderChunk("init-statement");
1491 else
1492 Pattern->AddPlaceholderChunk("init-expression");
1493 Pattern->AddChunk(CodeCompletionString::CK_SemiColon);
1494 Pattern->AddPlaceholderChunk("condition");
1495 Pattern->AddChunk(CodeCompletionString::CK_SemiColon);
1496 Pattern->AddPlaceholderChunk("inc-expression");
1497 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
1498 Pattern->AddChunk(CodeCompletionString::CK_LeftBrace);
1499 Pattern->AddPlaceholderChunk("statements");
1500 Pattern->AddChunk(CodeCompletionString::CK_VerticalSpace);
1501 Pattern->AddChunk(CodeCompletionString::CK_RightBrace);
1502 Results.AddResult(Result(Pattern));
1503 }
Douglas Gregor01dfea02010-01-10 23:08:15 +00001504
1505 if (S->getContinueParent()) {
1506 // continue ;
1507 Pattern = new CodeCompletionString;
1508 Pattern->AddTypedTextChunk("continue");
Douglas Gregora4477812010-01-14 16:01:26 +00001509 Results.AddResult(Result(Pattern));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001510 }
1511
1512 if (S->getBreakParent()) {
1513 // break ;
1514 Pattern = new CodeCompletionString;
1515 Pattern->AddTypedTextChunk("break");
Douglas Gregora4477812010-01-14 16:01:26 +00001516 Results.AddResult(Result(Pattern));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001517 }
1518
1519 // "return expression ;" or "return ;", depending on whether we
1520 // know the function is void or not.
1521 bool isVoid = false;
1522 if (FunctionDecl *Function = dyn_cast<FunctionDecl>(SemaRef.CurContext))
1523 isVoid = Function->getResultType()->isVoidType();
1524 else if (ObjCMethodDecl *Method
1525 = dyn_cast<ObjCMethodDecl>(SemaRef.CurContext))
1526 isVoid = Method->getResultType()->isVoidType();
Douglas Gregor9ea9bdb2010-03-01 23:15:13 +00001527 else if (SemaRef.getCurBlock() &&
1528 !SemaRef.getCurBlock()->ReturnType.isNull())
1529 isVoid = SemaRef.getCurBlock()->ReturnType->isVoidType();
Douglas Gregor01dfea02010-01-10 23:08:15 +00001530 Pattern = new CodeCompletionString;
1531 Pattern->AddTypedTextChunk("return");
Douglas Gregor93298002010-02-18 04:06:48 +00001532 if (!isVoid) {
1533 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
Douglas Gregor01dfea02010-01-10 23:08:15 +00001534 Pattern->AddPlaceholderChunk("expression");
Douglas Gregor93298002010-02-18 04:06:48 +00001535 }
Douglas Gregora4477812010-01-14 16:01:26 +00001536 Results.AddResult(Result(Pattern));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001537
Douglas Gregorc8bddde2010-05-28 00:22:41 +00001538 // goto identifier ;
1539 Pattern = new CodeCompletionString;
1540 Pattern->AddTypedTextChunk("goto");
1541 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
1542 Pattern->AddPlaceholderChunk("label");
1543 Results.AddResult(Result(Pattern));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001544
Douglas Gregorc8bddde2010-05-28 00:22:41 +00001545 // Using directives
1546 Pattern = new CodeCompletionString;
1547 Pattern->AddTypedTextChunk("using");
1548 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
1549 Pattern->AddTextChunk("namespace");
1550 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
1551 Pattern->AddPlaceholderChunk("identifier");
1552 Results.AddResult(Result(Pattern));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001553 }
1554
1555 // Fall through (for statement expressions).
John McCallf312b1e2010-08-26 23:41:50 +00001556 case Sema::PCC_ForInit:
1557 case Sema::PCC_Condition:
Douglas Gregorbca403c2010-01-13 23:51:12 +00001558 AddStorageSpecifiers(CCC, SemaRef.getLangOptions(), Results);
Douglas Gregor01dfea02010-01-10 23:08:15 +00001559 // Fall through: conditions and statements can have expressions.
1560
Douglas Gregor02688102010-09-14 23:59:36 +00001561 case Sema::PCC_ParenthesizedExpression:
John McCallf312b1e2010-08-26 23:41:50 +00001562 case Sema::PCC_Expression: {
Douglas Gregor01dfea02010-01-10 23:08:15 +00001563 CodeCompletionString *Pattern = 0;
1564 if (SemaRef.getLangOptions().CPlusPlus) {
1565 // 'this', if we're in a non-static member function.
1566 if (CXXMethodDecl *Method = dyn_cast<CXXMethodDecl>(SemaRef.CurContext))
1567 if (!Method->isStatic())
Douglas Gregora4477812010-01-14 16:01:26 +00001568 Results.AddResult(Result("this"));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001569
1570 // true, false
Douglas Gregora4477812010-01-14 16:01:26 +00001571 Results.AddResult(Result("true"));
1572 Results.AddResult(Result("false"));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001573
Douglas Gregorc8bddde2010-05-28 00:22:41 +00001574 // dynamic_cast < type-id > ( expression )
1575 Pattern = new CodeCompletionString;
1576 Pattern->AddTypedTextChunk("dynamic_cast");
1577 Pattern->AddChunk(CodeCompletionString::CK_LeftAngle);
1578 Pattern->AddPlaceholderChunk("type");
1579 Pattern->AddChunk(CodeCompletionString::CK_RightAngle);
1580 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
1581 Pattern->AddPlaceholderChunk("expression");
1582 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
1583 Results.AddResult(Result(Pattern));
1584
1585 // static_cast < type-id > ( expression )
1586 Pattern = new CodeCompletionString;
1587 Pattern->AddTypedTextChunk("static_cast");
1588 Pattern->AddChunk(CodeCompletionString::CK_LeftAngle);
1589 Pattern->AddPlaceholderChunk("type");
1590 Pattern->AddChunk(CodeCompletionString::CK_RightAngle);
1591 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
1592 Pattern->AddPlaceholderChunk("expression");
1593 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
1594 Results.AddResult(Result(Pattern));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001595
Douglas Gregorc8bddde2010-05-28 00:22:41 +00001596 // reinterpret_cast < type-id > ( expression )
1597 Pattern = new CodeCompletionString;
1598 Pattern->AddTypedTextChunk("reinterpret_cast");
1599 Pattern->AddChunk(CodeCompletionString::CK_LeftAngle);
1600 Pattern->AddPlaceholderChunk("type");
1601 Pattern->AddChunk(CodeCompletionString::CK_RightAngle);
1602 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
1603 Pattern->AddPlaceholderChunk("expression");
1604 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
1605 Results.AddResult(Result(Pattern));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001606
Douglas Gregorc8bddde2010-05-28 00:22:41 +00001607 // const_cast < type-id > ( expression )
1608 Pattern = new CodeCompletionString;
1609 Pattern->AddTypedTextChunk("const_cast");
1610 Pattern->AddChunk(CodeCompletionString::CK_LeftAngle);
1611 Pattern->AddPlaceholderChunk("type");
1612 Pattern->AddChunk(CodeCompletionString::CK_RightAngle);
1613 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
1614 Pattern->AddPlaceholderChunk("expression");
1615 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
1616 Results.AddResult(Result(Pattern));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001617
Douglas Gregorc8bddde2010-05-28 00:22:41 +00001618 // typeid ( expression-or-type )
1619 Pattern = new CodeCompletionString;
1620 Pattern->AddTypedTextChunk("typeid");
1621 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
1622 Pattern->AddPlaceholderChunk("expression-or-type");
1623 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
1624 Results.AddResult(Result(Pattern));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001625
Douglas Gregorc8bddde2010-05-28 00:22:41 +00001626 // new T ( ... )
1627 Pattern = new CodeCompletionString;
1628 Pattern->AddTypedTextChunk("new");
1629 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
1630 Pattern->AddPlaceholderChunk("type");
1631 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
1632 Pattern->AddPlaceholderChunk("expressions");
1633 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
1634 Results.AddResult(Result(Pattern));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001635
Douglas Gregorc8bddde2010-05-28 00:22:41 +00001636 // new T [ ] ( ... )
1637 Pattern = new CodeCompletionString;
1638 Pattern->AddTypedTextChunk("new");
1639 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
1640 Pattern->AddPlaceholderChunk("type");
1641 Pattern->AddChunk(CodeCompletionString::CK_LeftBracket);
1642 Pattern->AddPlaceholderChunk("size");
1643 Pattern->AddChunk(CodeCompletionString::CK_RightBracket);
1644 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
1645 Pattern->AddPlaceholderChunk("expressions");
1646 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
1647 Results.AddResult(Result(Pattern));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001648
Douglas Gregorc8bddde2010-05-28 00:22:41 +00001649 // delete expression
1650 Pattern = new CodeCompletionString;
1651 Pattern->AddTypedTextChunk("delete");
1652 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
1653 Pattern->AddPlaceholderChunk("expression");
1654 Results.AddResult(Result(Pattern));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001655
Douglas Gregorc8bddde2010-05-28 00:22:41 +00001656 // delete [] expression
1657 Pattern = new CodeCompletionString;
1658 Pattern->AddTypedTextChunk("delete");
1659 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
1660 Pattern->AddChunk(CodeCompletionString::CK_LeftBracket);
1661 Pattern->AddChunk(CodeCompletionString::CK_RightBracket);
1662 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
1663 Pattern->AddPlaceholderChunk("expression");
1664 Results.AddResult(Result(Pattern));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001665
Douglas Gregorc8bddde2010-05-28 00:22:41 +00001666 // throw expression
1667 Pattern = new CodeCompletionString;
1668 Pattern->AddTypedTextChunk("throw");
1669 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
1670 Pattern->AddPlaceholderChunk("expression");
1671 Results.AddResult(Result(Pattern));
Douglas Gregor12e13132010-05-26 22:00:08 +00001672
1673 // FIXME: Rethrow?
Douglas Gregor01dfea02010-01-10 23:08:15 +00001674 }
1675
1676 if (SemaRef.getLangOptions().ObjC1) {
1677 // Add "super", if we're in an Objective-C class with a superclass.
Ted Kremenek681e2562010-05-31 21:43:10 +00001678 if (ObjCMethodDecl *Method = SemaRef.getCurMethodDecl()) {
1679 // The interface can be NULL.
1680 if (ObjCInterfaceDecl *ID = Method->getClassInterface())
1681 if (ID->getSuperClass())
1682 Results.AddResult(Result("super"));
1683 }
1684
Douglas Gregorbca403c2010-01-13 23:51:12 +00001685 AddObjCExpressionResults(Results, true);
Douglas Gregor01dfea02010-01-10 23:08:15 +00001686 }
1687
Douglas Gregorc8bddde2010-05-28 00:22:41 +00001688 // sizeof expression
1689 Pattern = new CodeCompletionString;
1690 Pattern->AddTypedTextChunk("sizeof");
1691 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
1692 Pattern->AddPlaceholderChunk("expression-or-type");
1693 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
1694 Results.AddResult(Result(Pattern));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001695 break;
1696 }
Douglas Gregord32b0222010-08-24 01:06:58 +00001697
John McCallf312b1e2010-08-26 23:41:50 +00001698 case Sema::PCC_Type:
Douglas Gregord32b0222010-08-24 01:06:58 +00001699 break;
Douglas Gregor01dfea02010-01-10 23:08:15 +00001700 }
1701
Douglas Gregor4710e5b2010-05-28 00:49:12 +00001702 if (WantTypesInContext(CCC, SemaRef.getLangOptions()))
1703 AddTypeSpecifierResults(SemaRef.getLangOptions(), Results);
Douglas Gregor01dfea02010-01-10 23:08:15 +00001704
John McCallf312b1e2010-08-26 23:41:50 +00001705 if (SemaRef.getLangOptions().CPlusPlus && CCC != Sema::PCC_Type)
Douglas Gregora4477812010-01-14 16:01:26 +00001706 Results.AddResult(Result("operator"));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001707}
1708
Douglas Gregorff5ce6e2009-12-18 18:53:37 +00001709/// \brief If the given declaration has an associated type, add it as a result
1710/// type chunk.
1711static void AddResultTypeChunk(ASTContext &Context,
1712 NamedDecl *ND,
1713 CodeCompletionString *Result) {
1714 if (!ND)
1715 return;
1716
1717 // Determine the type of the declaration (if it has a type).
1718 QualType T;
1719 if (FunctionDecl *Function = dyn_cast<FunctionDecl>(ND))
1720 T = Function->getResultType();
1721 else if (ObjCMethodDecl *Method = dyn_cast<ObjCMethodDecl>(ND))
1722 T = Method->getResultType();
1723 else if (FunctionTemplateDecl *FunTmpl = dyn_cast<FunctionTemplateDecl>(ND))
1724 T = FunTmpl->getTemplatedDecl()->getResultType();
1725 else if (EnumConstantDecl *Enumerator = dyn_cast<EnumConstantDecl>(ND))
1726 T = Context.getTypeDeclType(cast<TypeDecl>(Enumerator->getDeclContext()));
1727 else if (isa<UnresolvedUsingValueDecl>(ND)) {
1728 /* Do nothing: ignore unresolved using declarations*/
1729 } else if (ValueDecl *Value = dyn_cast<ValueDecl>(ND))
1730 T = Value->getType();
1731 else if (ObjCPropertyDecl *Property = dyn_cast<ObjCPropertyDecl>(ND))
1732 T = Property->getType();
1733
1734 if (T.isNull() || Context.hasSameType(T, Context.DependentTy))
1735 return;
1736
Douglas Gregor84139d62010-04-05 21:25:31 +00001737 PrintingPolicy Policy(Context.PrintingPolicy);
1738 Policy.AnonymousTagLocations = false;
1739
Douglas Gregorff5ce6e2009-12-18 18:53:37 +00001740 std::string TypeStr;
Douglas Gregor84139d62010-04-05 21:25:31 +00001741 T.getAsStringInternal(TypeStr, Policy);
Douglas Gregorff5ce6e2009-12-18 18:53:37 +00001742 Result->AddResultTypeChunk(TypeStr);
1743}
1744
Douglas Gregoraaa107a2010-08-23 23:51:41 +00001745static void MaybeAddSentinel(ASTContext &Context, NamedDecl *FunctionOrMethod,
1746 CodeCompletionString *Result) {
1747 if (SentinelAttr *Sentinel = FunctionOrMethod->getAttr<SentinelAttr>())
1748 if (Sentinel->getSentinel() == 0) {
1749 if (Context.getLangOptions().ObjC1 &&
1750 Context.Idents.get("nil").hasMacroDefinition())
1751 Result->AddTextChunk(", nil");
1752 else if (Context.Idents.get("NULL").hasMacroDefinition())
1753 Result->AddTextChunk(", NULL");
1754 else
1755 Result->AddTextChunk(", (void*)0");
1756 }
1757}
1758
Douglas Gregor83482d12010-08-24 16:15:59 +00001759static std::string FormatFunctionParameter(ASTContext &Context,
Douglas Gregoraba48082010-08-29 19:47:46 +00001760 ParmVarDecl *Param,
1761 bool SuppressName = false) {
Douglas Gregor83482d12010-08-24 16:15:59 +00001762 bool ObjCMethodParam = isa<ObjCMethodDecl>(Param->getDeclContext());
1763 if (Param->getType()->isDependentType() ||
1764 !Param->getType()->isBlockPointerType()) {
1765 // The argument for a dependent or non-block parameter is a placeholder
1766 // containing that parameter's type.
1767 std::string Result;
1768
Douglas Gregoraba48082010-08-29 19:47:46 +00001769 if (Param->getIdentifier() && !ObjCMethodParam && !SuppressName)
Douglas Gregor83482d12010-08-24 16:15:59 +00001770 Result = Param->getIdentifier()->getName();
1771
1772 Param->getType().getAsStringInternal(Result,
1773 Context.PrintingPolicy);
1774
1775 if (ObjCMethodParam) {
1776 Result = "(" + Result;
1777 Result += ")";
Douglas Gregoraba48082010-08-29 19:47:46 +00001778 if (Param->getIdentifier() && !SuppressName)
Douglas Gregor83482d12010-08-24 16:15:59 +00001779 Result += Param->getIdentifier()->getName();
1780 }
1781 return Result;
1782 }
1783
1784 // The argument for a block pointer parameter is a block literal with
1785 // the appropriate type.
1786 FunctionProtoTypeLoc *Block = 0;
1787 TypeLoc TL;
1788 if (TypeSourceInfo *TSInfo = Param->getTypeSourceInfo()) {
1789 TL = TSInfo->getTypeLoc().getUnqualifiedLoc();
1790 while (true) {
1791 // Look through typedefs.
1792 if (TypedefTypeLoc *TypedefTL = dyn_cast<TypedefTypeLoc>(&TL)) {
1793 if (TypeSourceInfo *InnerTSInfo
1794 = TypedefTL->getTypedefDecl()->getTypeSourceInfo()) {
1795 TL = InnerTSInfo->getTypeLoc().getUnqualifiedLoc();
1796 continue;
1797 }
1798 }
1799
1800 // Look through qualified types
1801 if (QualifiedTypeLoc *QualifiedTL = dyn_cast<QualifiedTypeLoc>(&TL)) {
1802 TL = QualifiedTL->getUnqualifiedLoc();
1803 continue;
1804 }
1805
1806 // Try to get the function prototype behind the block pointer type,
1807 // then we're done.
1808 if (BlockPointerTypeLoc *BlockPtr
1809 = dyn_cast<BlockPointerTypeLoc>(&TL)) {
1810 TL = BlockPtr->getPointeeLoc();
1811 Block = dyn_cast<FunctionProtoTypeLoc>(&TL);
1812 }
1813 break;
1814 }
1815 }
1816
1817 if (!Block) {
1818 // We were unable to find a FunctionProtoTypeLoc with parameter names
1819 // for the block; just use the parameter type as a placeholder.
1820 std::string Result;
1821 Param->getType().getUnqualifiedType().
1822 getAsStringInternal(Result, Context.PrintingPolicy);
1823
1824 if (ObjCMethodParam) {
1825 Result = "(" + Result;
1826 Result += ")";
1827 if (Param->getIdentifier())
1828 Result += Param->getIdentifier()->getName();
1829 }
1830
1831 return Result;
1832 }
1833
1834 // We have the function prototype behind the block pointer type, as it was
1835 // written in the source.
Douglas Gregor38276252010-09-08 22:47:51 +00001836 std::string Result;
1837 QualType ResultType = Block->getTypePtr()->getResultType();
1838 if (!ResultType->isVoidType())
1839 ResultType.getAsStringInternal(Result, Context.PrintingPolicy);
1840
1841 Result = '^' + Result;
1842 if (Block->getNumArgs() == 0) {
1843 if (Block->getTypePtr()->isVariadic())
1844 Result += "(...)";
1845 } else {
1846 Result += "(";
1847 for (unsigned I = 0, N = Block->getNumArgs(); I != N; ++I) {
1848 if (I)
1849 Result += ", ";
1850 Result += FormatFunctionParameter(Context, Block->getArg(I));
1851
1852 if (I == N - 1 && Block->getTypePtr()->isVariadic())
1853 Result += ", ...";
1854 }
1855 Result += ")";
Douglas Gregore17794f2010-08-31 05:13:43 +00001856 }
Douglas Gregor38276252010-09-08 22:47:51 +00001857
Douglas Gregor83482d12010-08-24 16:15:59 +00001858 return Result;
1859}
1860
Douglas Gregor86d9a522009-09-21 16:56:56 +00001861/// \brief Add function parameter chunks to the given code completion string.
1862static void AddFunctionParameterChunks(ASTContext &Context,
1863 FunctionDecl *Function,
1864 CodeCompletionString *Result) {
Douglas Gregor0c8296d2009-11-07 00:00:49 +00001865 typedef CodeCompletionString::Chunk Chunk;
1866
Douglas Gregor86d9a522009-09-21 16:56:56 +00001867 CodeCompletionString *CCStr = Result;
1868
1869 for (unsigned P = 0, N = Function->getNumParams(); P != N; ++P) {
1870 ParmVarDecl *Param = Function->getParamDecl(P);
1871
1872 if (Param->hasDefaultArg()) {
1873 // When we see an optional default argument, put that argument and
1874 // the remaining default arguments into a new, optional string.
1875 CodeCompletionString *Opt = new CodeCompletionString;
1876 CCStr->AddOptionalChunk(std::auto_ptr<CodeCompletionString>(Opt));
1877 CCStr = Opt;
1878 }
1879
1880 if (P != 0)
Douglas Gregor0c8296d2009-11-07 00:00:49 +00001881 CCStr->AddChunk(Chunk(CodeCompletionString::CK_Comma));
Douglas Gregor86d9a522009-09-21 16:56:56 +00001882
1883 // Format the placeholder string.
Douglas Gregor83482d12010-08-24 16:15:59 +00001884 std::string PlaceholderStr = FormatFunctionParameter(Context, Param);
1885
Douglas Gregore17794f2010-08-31 05:13:43 +00001886 if (Function->isVariadic() && P == N - 1)
1887 PlaceholderStr += ", ...";
1888
Douglas Gregor86d9a522009-09-21 16:56:56 +00001889 // Add the placeholder string.
Benjamin Kramer660cc182009-11-29 20:18:50 +00001890 CCStr->AddPlaceholderChunk(PlaceholderStr);
Douglas Gregor86d9a522009-09-21 16:56:56 +00001891 }
Douglas Gregorb3d45252009-09-22 21:42:17 +00001892
1893 if (const FunctionProtoType *Proto
1894 = Function->getType()->getAs<FunctionProtoType>())
Douglas Gregoraaa107a2010-08-23 23:51:41 +00001895 if (Proto->isVariadic()) {
Douglas Gregore17794f2010-08-31 05:13:43 +00001896 if (Proto->getNumArgs() == 0)
1897 CCStr->AddPlaceholderChunk("...");
Douglas Gregoraaa107a2010-08-23 23:51:41 +00001898
1899 MaybeAddSentinel(Context, Function, CCStr);
1900 }
Douglas Gregor86d9a522009-09-21 16:56:56 +00001901}
1902
1903/// \brief Add template parameter chunks to the given code completion string.
1904static void AddTemplateParameterChunks(ASTContext &Context,
1905 TemplateDecl *Template,
1906 CodeCompletionString *Result,
1907 unsigned MaxParameters = 0) {
Douglas Gregor0c8296d2009-11-07 00:00:49 +00001908 typedef CodeCompletionString::Chunk Chunk;
1909
Douglas Gregor86d9a522009-09-21 16:56:56 +00001910 CodeCompletionString *CCStr = Result;
1911 bool FirstParameter = true;
1912
1913 TemplateParameterList *Params = Template->getTemplateParameters();
1914 TemplateParameterList::iterator PEnd = Params->end();
1915 if (MaxParameters)
1916 PEnd = Params->begin() + MaxParameters;
1917 for (TemplateParameterList::iterator P = Params->begin(); P != PEnd; ++P) {
1918 bool HasDefaultArg = false;
1919 std::string PlaceholderStr;
1920 if (TemplateTypeParmDecl *TTP = dyn_cast<TemplateTypeParmDecl>(*P)) {
1921 if (TTP->wasDeclaredWithTypename())
1922 PlaceholderStr = "typename";
1923 else
1924 PlaceholderStr = "class";
1925
1926 if (TTP->getIdentifier()) {
1927 PlaceholderStr += ' ';
1928 PlaceholderStr += TTP->getIdentifier()->getName();
1929 }
1930
1931 HasDefaultArg = TTP->hasDefaultArgument();
1932 } else if (NonTypeTemplateParmDecl *NTTP
1933 = dyn_cast<NonTypeTemplateParmDecl>(*P)) {
1934 if (NTTP->getIdentifier())
1935 PlaceholderStr = NTTP->getIdentifier()->getName();
1936 NTTP->getType().getAsStringInternal(PlaceholderStr,
1937 Context.PrintingPolicy);
1938 HasDefaultArg = NTTP->hasDefaultArgument();
1939 } else {
1940 assert(isa<TemplateTemplateParmDecl>(*P));
1941 TemplateTemplateParmDecl *TTP = cast<TemplateTemplateParmDecl>(*P);
1942
1943 // Since putting the template argument list into the placeholder would
1944 // be very, very long, we just use an abbreviation.
1945 PlaceholderStr = "template<...> class";
1946 if (TTP->getIdentifier()) {
1947 PlaceholderStr += ' ';
1948 PlaceholderStr += TTP->getIdentifier()->getName();
1949 }
1950
1951 HasDefaultArg = TTP->hasDefaultArgument();
1952 }
1953
1954 if (HasDefaultArg) {
1955 // When we see an optional default argument, put that argument and
1956 // the remaining default arguments into a new, optional string.
1957 CodeCompletionString *Opt = new CodeCompletionString;
1958 CCStr->AddOptionalChunk(std::auto_ptr<CodeCompletionString>(Opt));
1959 CCStr = Opt;
1960 }
1961
1962 if (FirstParameter)
1963 FirstParameter = false;
1964 else
Douglas Gregor0c8296d2009-11-07 00:00:49 +00001965 CCStr->AddChunk(Chunk(CodeCompletionString::CK_Comma));
Douglas Gregor86d9a522009-09-21 16:56:56 +00001966
1967 // Add the placeholder string.
Benjamin Kramer660cc182009-11-29 20:18:50 +00001968 CCStr->AddPlaceholderChunk(PlaceholderStr);
Douglas Gregor86d9a522009-09-21 16:56:56 +00001969 }
1970}
1971
Douglas Gregorb9d0ef72009-09-21 19:57:38 +00001972/// \brief Add a qualifier to the given code-completion string, if the
1973/// provided nested-name-specifier is non-NULL.
Douglas Gregora61a8792009-12-11 18:44:16 +00001974static void
1975AddQualifierToCompletionString(CodeCompletionString *Result,
1976 NestedNameSpecifier *Qualifier,
1977 bool QualifierIsInformative,
1978 ASTContext &Context) {
Douglas Gregorb9d0ef72009-09-21 19:57:38 +00001979 if (!Qualifier)
1980 return;
1981
1982 std::string PrintedNNS;
1983 {
1984 llvm::raw_string_ostream OS(PrintedNNS);
1985 Qualifier->print(OS, Context.PrintingPolicy);
1986 }
Douglas Gregor0563c262009-09-22 23:15:58 +00001987 if (QualifierIsInformative)
Benjamin Kramer660cc182009-11-29 20:18:50 +00001988 Result->AddInformativeChunk(PrintedNNS);
Douglas Gregor0563c262009-09-22 23:15:58 +00001989 else
Benjamin Kramer660cc182009-11-29 20:18:50 +00001990 Result->AddTextChunk(PrintedNNS);
Douglas Gregorb9d0ef72009-09-21 19:57:38 +00001991}
1992
Douglas Gregora61a8792009-12-11 18:44:16 +00001993static void AddFunctionTypeQualsToCompletionString(CodeCompletionString *Result,
1994 FunctionDecl *Function) {
1995 const FunctionProtoType *Proto
1996 = Function->getType()->getAs<FunctionProtoType>();
1997 if (!Proto || !Proto->getTypeQuals())
1998 return;
1999
2000 std::string QualsStr;
2001 if (Proto->getTypeQuals() & Qualifiers::Const)
2002 QualsStr += " const";
2003 if (Proto->getTypeQuals() & Qualifiers::Volatile)
2004 QualsStr += " volatile";
2005 if (Proto->getTypeQuals() & Qualifiers::Restrict)
2006 QualsStr += " restrict";
2007 Result->AddInformativeChunk(QualsStr);
2008}
2009
Douglas Gregor86d9a522009-09-21 16:56:56 +00002010/// \brief If possible, create a new code completion string for the given
2011/// result.
2012///
2013/// \returns Either a new, heap-allocated code completion string describing
2014/// how to use this result, or NULL to indicate that the string or name of the
2015/// result is all that is needed.
2016CodeCompletionString *
John McCall0a2c5e22010-08-25 06:19:51 +00002017CodeCompletionResult::CreateCodeCompletionString(Sema &S,
Douglas Gregor1abc6bc2010-08-04 16:47:14 +00002018 CodeCompletionString *Result) {
Douglas Gregor0c8296d2009-11-07 00:00:49 +00002019 typedef CodeCompletionString::Chunk Chunk;
2020
Douglas Gregor2b4074f2009-12-01 05:55:20 +00002021 if (Kind == RK_Pattern)
Douglas Gregor1abc6bc2010-08-04 16:47:14 +00002022 return Pattern->Clone(Result);
Douglas Gregor2b4074f2009-12-01 05:55:20 +00002023
Douglas Gregor1abc6bc2010-08-04 16:47:14 +00002024 if (!Result)
2025 Result = new CodeCompletionString;
Douglas Gregor2b4074f2009-12-01 05:55:20 +00002026
2027 if (Kind == RK_Keyword) {
2028 Result->AddTypedTextChunk(Keyword);
2029 return Result;
2030 }
Douglas Gregor86d9a522009-09-21 16:56:56 +00002031
Douglas Gregor3f7c7f42009-10-30 16:50:04 +00002032 if (Kind == RK_Macro) {
2033 MacroInfo *MI = S.PP.getMacroInfo(Macro);
Douglas Gregor2b4074f2009-12-01 05:55:20 +00002034 assert(MI && "Not a macro?");
2035
2036 Result->AddTypedTextChunk(Macro->getName());
2037
2038 if (!MI->isFunctionLike())
2039 return Result;
Douglas Gregor3f7c7f42009-10-30 16:50:04 +00002040
2041 // Format a function-like macro with placeholders for the arguments.
Douglas Gregor0c8296d2009-11-07 00:00:49 +00002042 Result->AddChunk(Chunk(CodeCompletionString::CK_LeftParen));
Douglas Gregor3f7c7f42009-10-30 16:50:04 +00002043 for (MacroInfo::arg_iterator A = MI->arg_begin(), AEnd = MI->arg_end();
2044 A != AEnd; ++A) {
2045 if (A != MI->arg_begin())
Douglas Gregor0c8296d2009-11-07 00:00:49 +00002046 Result->AddChunk(Chunk(CodeCompletionString::CK_Comma));
Douglas Gregor3f7c7f42009-10-30 16:50:04 +00002047
2048 if (!MI->isVariadic() || A != AEnd - 1) {
2049 // Non-variadic argument.
Benjamin Kramer660cc182009-11-29 20:18:50 +00002050 Result->AddPlaceholderChunk((*A)->getName());
Douglas Gregor3f7c7f42009-10-30 16:50:04 +00002051 continue;
2052 }
2053
2054 // Variadic argument; cope with the different between GNU and C99
2055 // variadic macros, providing a single placeholder for the rest of the
2056 // arguments.
2057 if ((*A)->isStr("__VA_ARGS__"))
2058 Result->AddPlaceholderChunk("...");
2059 else {
2060 std::string Arg = (*A)->getName();
2061 Arg += "...";
Benjamin Kramer660cc182009-11-29 20:18:50 +00002062 Result->AddPlaceholderChunk(Arg);
Douglas Gregor3f7c7f42009-10-30 16:50:04 +00002063 }
2064 }
Douglas Gregor0c8296d2009-11-07 00:00:49 +00002065 Result->AddChunk(Chunk(CodeCompletionString::CK_RightParen));
Douglas Gregor3f7c7f42009-10-30 16:50:04 +00002066 return Result;
2067 }
2068
Douglas Gregord8e8a582010-05-25 21:41:55 +00002069 assert(Kind == RK_Declaration && "Missed a result kind?");
Douglas Gregor86d9a522009-09-21 16:56:56 +00002070 NamedDecl *ND = Declaration;
2071
Douglas Gregor0c8296d2009-11-07 00:00:49 +00002072 if (StartsNestedNameSpecifier) {
Benjamin Kramer660cc182009-11-29 20:18:50 +00002073 Result->AddTypedTextChunk(ND->getNameAsString());
Douglas Gregor0c8296d2009-11-07 00:00:49 +00002074 Result->AddTextChunk("::");
2075 return Result;
2076 }
2077
Douglas Gregorff5ce6e2009-12-18 18:53:37 +00002078 AddResultTypeChunk(S.Context, ND, Result);
2079
Douglas Gregor86d9a522009-09-21 16:56:56 +00002080 if (FunctionDecl *Function = dyn_cast<FunctionDecl>(ND)) {
Douglas Gregor0563c262009-09-22 23:15:58 +00002081 AddQualifierToCompletionString(Result, Qualifier, QualifierIsInformative,
2082 S.Context);
Benjamin Kramer660cc182009-11-29 20:18:50 +00002083 Result->AddTypedTextChunk(Function->getNameAsString());
Douglas Gregor0c8296d2009-11-07 00:00:49 +00002084 Result->AddChunk(Chunk(CodeCompletionString::CK_LeftParen));
Douglas Gregor86d9a522009-09-21 16:56:56 +00002085 AddFunctionParameterChunks(S.Context, Function, Result);
Douglas Gregor0c8296d2009-11-07 00:00:49 +00002086 Result->AddChunk(Chunk(CodeCompletionString::CK_RightParen));
Douglas Gregora61a8792009-12-11 18:44:16 +00002087 AddFunctionTypeQualsToCompletionString(Result, Function);
Douglas Gregor86d9a522009-09-21 16:56:56 +00002088 return Result;
2089 }
2090
2091 if (FunctionTemplateDecl *FunTmpl = dyn_cast<FunctionTemplateDecl>(ND)) {
Douglas Gregor0563c262009-09-22 23:15:58 +00002092 AddQualifierToCompletionString(Result, Qualifier, QualifierIsInformative,
2093 S.Context);
Douglas Gregor86d9a522009-09-21 16:56:56 +00002094 FunctionDecl *Function = FunTmpl->getTemplatedDecl();
Benjamin Kramer660cc182009-11-29 20:18:50 +00002095 Result->AddTypedTextChunk(Function->getNameAsString());
Douglas Gregor86d9a522009-09-21 16:56:56 +00002096
2097 // Figure out which template parameters are deduced (or have default
2098 // arguments).
2099 llvm::SmallVector<bool, 16> Deduced;
2100 S.MarkDeducedTemplateParameters(FunTmpl, Deduced);
2101 unsigned LastDeducibleArgument;
2102 for (LastDeducibleArgument = Deduced.size(); LastDeducibleArgument > 0;
2103 --LastDeducibleArgument) {
2104 if (!Deduced[LastDeducibleArgument - 1]) {
2105 // C++0x: Figure out if the template argument has a default. If so,
2106 // the user doesn't need to type this argument.
2107 // FIXME: We need to abstract template parameters better!
2108 bool HasDefaultArg = false;
2109 NamedDecl *Param = FunTmpl->getTemplateParameters()->getParam(
2110 LastDeducibleArgument - 1);
2111 if (TemplateTypeParmDecl *TTP = dyn_cast<TemplateTypeParmDecl>(Param))
2112 HasDefaultArg = TTP->hasDefaultArgument();
2113 else if (NonTypeTemplateParmDecl *NTTP
2114 = dyn_cast<NonTypeTemplateParmDecl>(Param))
2115 HasDefaultArg = NTTP->hasDefaultArgument();
2116 else {
2117 assert(isa<TemplateTemplateParmDecl>(Param));
2118 HasDefaultArg
Douglas Gregor0c8296d2009-11-07 00:00:49 +00002119 = cast<TemplateTemplateParmDecl>(Param)->hasDefaultArgument();
Douglas Gregor86d9a522009-09-21 16:56:56 +00002120 }
2121
2122 if (!HasDefaultArg)
2123 break;
2124 }
2125 }
2126
2127 if (LastDeducibleArgument) {
2128 // Some of the function template arguments cannot be deduced from a
2129 // function call, so we introduce an explicit template argument list
2130 // containing all of the arguments up to the first deducible argument.
Douglas Gregor0c8296d2009-11-07 00:00:49 +00002131 Result->AddChunk(Chunk(CodeCompletionString::CK_LeftAngle));
Douglas Gregor86d9a522009-09-21 16:56:56 +00002132 AddTemplateParameterChunks(S.Context, FunTmpl, Result,
2133 LastDeducibleArgument);
Douglas Gregor0c8296d2009-11-07 00:00:49 +00002134 Result->AddChunk(Chunk(CodeCompletionString::CK_RightAngle));
Douglas Gregor86d9a522009-09-21 16:56:56 +00002135 }
2136
2137 // Add the function parameters
Douglas Gregor0c8296d2009-11-07 00:00:49 +00002138 Result->AddChunk(Chunk(CodeCompletionString::CK_LeftParen));
Douglas Gregor86d9a522009-09-21 16:56:56 +00002139 AddFunctionParameterChunks(S.Context, Function, Result);
Douglas Gregor0c8296d2009-11-07 00:00:49 +00002140 Result->AddChunk(Chunk(CodeCompletionString::CK_RightParen));
Douglas Gregora61a8792009-12-11 18:44:16 +00002141 AddFunctionTypeQualsToCompletionString(Result, Function);
Douglas Gregor86d9a522009-09-21 16:56:56 +00002142 return Result;
2143 }
2144
2145 if (TemplateDecl *Template = dyn_cast<TemplateDecl>(ND)) {
Douglas Gregor0563c262009-09-22 23:15:58 +00002146 AddQualifierToCompletionString(Result, Qualifier, QualifierIsInformative,
2147 S.Context);
Benjamin Kramer660cc182009-11-29 20:18:50 +00002148 Result->AddTypedTextChunk(Template->getNameAsString());
Douglas Gregor0c8296d2009-11-07 00:00:49 +00002149 Result->AddChunk(Chunk(CodeCompletionString::CK_LeftAngle));
Douglas Gregor86d9a522009-09-21 16:56:56 +00002150 AddTemplateParameterChunks(S.Context, Template, Result);
Douglas Gregor0c8296d2009-11-07 00:00:49 +00002151 Result->AddChunk(Chunk(CodeCompletionString::CK_RightAngle));
Douglas Gregor86d9a522009-09-21 16:56:56 +00002152 return Result;
2153 }
2154
Douglas Gregor9630eb62009-11-17 16:44:22 +00002155 if (ObjCMethodDecl *Method = dyn_cast<ObjCMethodDecl>(ND)) {
Douglas Gregor9630eb62009-11-17 16:44:22 +00002156 Selector Sel = Method->getSelector();
2157 if (Sel.isUnarySelector()) {
2158 Result->AddTypedTextChunk(Sel.getIdentifierInfoForSlot(0)->getName());
2159 return Result;
2160 }
2161
Douglas Gregord3c68542009-11-19 01:08:35 +00002162 std::string SelName = Sel.getIdentifierInfoForSlot(0)->getName().str();
2163 SelName += ':';
2164 if (StartParameter == 0)
2165 Result->AddTypedTextChunk(SelName);
2166 else {
2167 Result->AddInformativeChunk(SelName);
2168
2169 // If there is only one parameter, and we're past it, add an empty
2170 // typed-text chunk since there is nothing to type.
2171 if (Method->param_size() == 1)
2172 Result->AddTypedTextChunk("");
2173 }
Douglas Gregor9630eb62009-11-17 16:44:22 +00002174 unsigned Idx = 0;
2175 for (ObjCMethodDecl::param_iterator P = Method->param_begin(),
2176 PEnd = Method->param_end();
2177 P != PEnd; (void)++P, ++Idx) {
2178 if (Idx > 0) {
Douglas Gregord3c68542009-11-19 01:08:35 +00002179 std::string Keyword;
2180 if (Idx > StartParameter)
Douglas Gregor834389b2010-01-12 06:38:28 +00002181 Result->AddChunk(CodeCompletionString::CK_HorizontalSpace);
Douglas Gregor9630eb62009-11-17 16:44:22 +00002182 if (IdentifierInfo *II = Sel.getIdentifierInfoForSlot(Idx))
2183 Keyword += II->getName().str();
2184 Keyword += ":";
Douglas Gregor1f5537a2010-07-08 23:20:03 +00002185 if (Idx < StartParameter || AllParametersAreInformative)
Douglas Gregord3c68542009-11-19 01:08:35 +00002186 Result->AddInformativeChunk(Keyword);
Douglas Gregor1f5537a2010-07-08 23:20:03 +00002187 else if (Idx == StartParameter)
Douglas Gregord3c68542009-11-19 01:08:35 +00002188 Result->AddTypedTextChunk(Keyword);
2189 else
2190 Result->AddTextChunk(Keyword);
Douglas Gregor9630eb62009-11-17 16:44:22 +00002191 }
Douglas Gregord3c68542009-11-19 01:08:35 +00002192
2193 // If we're before the starting parameter, skip the placeholder.
2194 if (Idx < StartParameter)
2195 continue;
Douglas Gregor9630eb62009-11-17 16:44:22 +00002196
2197 std::string Arg;
Douglas Gregor83482d12010-08-24 16:15:59 +00002198
2199 if ((*P)->getType()->isBlockPointerType() && !DeclaringEntity)
Douglas Gregoraba48082010-08-29 19:47:46 +00002200 Arg = FormatFunctionParameter(S.Context, *P, true);
Douglas Gregor83482d12010-08-24 16:15:59 +00002201 else {
2202 (*P)->getType().getAsStringInternal(Arg, S.Context.PrintingPolicy);
2203 Arg = "(" + Arg + ")";
2204 if (IdentifierInfo *II = (*P)->getIdentifier())
Douglas Gregoraba48082010-08-29 19:47:46 +00002205 if (DeclaringEntity || AllParametersAreInformative)
2206 Arg += II->getName().str();
Douglas Gregor83482d12010-08-24 16:15:59 +00002207 }
2208
Douglas Gregore17794f2010-08-31 05:13:43 +00002209 if (Method->isVariadic() && (P + 1) == PEnd)
2210 Arg += ", ...";
2211
Douglas Gregor1f5537a2010-07-08 23:20:03 +00002212 if (DeclaringEntity)
2213 Result->AddTextChunk(Arg);
2214 else if (AllParametersAreInformative)
Douglas Gregor4ad96852009-11-19 07:41:15 +00002215 Result->AddInformativeChunk(Arg);
2216 else
2217 Result->AddPlaceholderChunk(Arg);
Douglas Gregor9630eb62009-11-17 16:44:22 +00002218 }
2219
Douglas Gregor2a17af02009-12-23 00:21:46 +00002220 if (Method->isVariadic()) {
Douglas Gregore17794f2010-08-31 05:13:43 +00002221 if (Method->param_size() == 0) {
2222 if (DeclaringEntity)
2223 Result->AddTextChunk(", ...");
2224 else if (AllParametersAreInformative)
2225 Result->AddInformativeChunk(", ...");
2226 else
2227 Result->AddPlaceholderChunk(", ...");
2228 }
Douglas Gregoraaa107a2010-08-23 23:51:41 +00002229
2230 MaybeAddSentinel(S.Context, Method, Result);
Douglas Gregor2a17af02009-12-23 00:21:46 +00002231 }
2232
Douglas Gregor9630eb62009-11-17 16:44:22 +00002233 return Result;
2234 }
2235
Douglas Gregor2b4074f2009-12-01 05:55:20 +00002236 if (Qualifier)
Douglas Gregor0563c262009-09-22 23:15:58 +00002237 AddQualifierToCompletionString(Result, Qualifier, QualifierIsInformative,
2238 S.Context);
Douglas Gregor2b4074f2009-12-01 05:55:20 +00002239
2240 Result->AddTypedTextChunk(ND->getNameAsString());
2241 return Result;
Douglas Gregor86d9a522009-09-21 16:56:56 +00002242}
2243
Douglas Gregor86d802e2009-09-23 00:34:09 +00002244CodeCompletionString *
2245CodeCompleteConsumer::OverloadCandidate::CreateSignatureString(
2246 unsigned CurrentArg,
2247 Sema &S) const {
Douglas Gregor0c8296d2009-11-07 00:00:49 +00002248 typedef CodeCompletionString::Chunk Chunk;
2249
Douglas Gregor86d802e2009-09-23 00:34:09 +00002250 CodeCompletionString *Result = new CodeCompletionString;
2251 FunctionDecl *FDecl = getFunction();
Douglas Gregorff5ce6e2009-12-18 18:53:37 +00002252 AddResultTypeChunk(S.Context, FDecl, Result);
Douglas Gregor86d802e2009-09-23 00:34:09 +00002253 const FunctionProtoType *Proto
2254 = dyn_cast<FunctionProtoType>(getFunctionType());
2255 if (!FDecl && !Proto) {
2256 // Function without a prototype. Just give the return type and a
2257 // highlighted ellipsis.
2258 const FunctionType *FT = getFunctionType();
2259 Result->AddTextChunk(
Benjamin Kramer660cc182009-11-29 20:18:50 +00002260 FT->getResultType().getAsString(S.Context.PrintingPolicy));
Douglas Gregor0c8296d2009-11-07 00:00:49 +00002261 Result->AddChunk(Chunk(CodeCompletionString::CK_LeftParen));
2262 Result->AddChunk(Chunk(CodeCompletionString::CK_CurrentParameter, "..."));
2263 Result->AddChunk(Chunk(CodeCompletionString::CK_RightParen));
Douglas Gregor86d802e2009-09-23 00:34:09 +00002264 return Result;
2265 }
2266
2267 if (FDecl)
Benjamin Kramer660cc182009-11-29 20:18:50 +00002268 Result->AddTextChunk(FDecl->getNameAsString());
Douglas Gregor86d802e2009-09-23 00:34:09 +00002269 else
2270 Result->AddTextChunk(
Benjamin Kramer660cc182009-11-29 20:18:50 +00002271 Proto->getResultType().getAsString(S.Context.PrintingPolicy));
Douglas Gregor86d802e2009-09-23 00:34:09 +00002272
Douglas Gregor0c8296d2009-11-07 00:00:49 +00002273 Result->AddChunk(Chunk(CodeCompletionString::CK_LeftParen));
Douglas Gregor86d802e2009-09-23 00:34:09 +00002274 unsigned NumParams = FDecl? FDecl->getNumParams() : Proto->getNumArgs();
2275 for (unsigned I = 0; I != NumParams; ++I) {
2276 if (I)
Douglas Gregor0c8296d2009-11-07 00:00:49 +00002277 Result->AddChunk(Chunk(CodeCompletionString::CK_Comma));
Douglas Gregor86d802e2009-09-23 00:34:09 +00002278
2279 std::string ArgString;
2280 QualType ArgType;
2281
2282 if (FDecl) {
2283 ArgString = FDecl->getParamDecl(I)->getNameAsString();
2284 ArgType = FDecl->getParamDecl(I)->getOriginalType();
2285 } else {
2286 ArgType = Proto->getArgType(I);
2287 }
2288
2289 ArgType.getAsStringInternal(ArgString, S.Context.PrintingPolicy);
2290
2291 if (I == CurrentArg)
Douglas Gregor0c8296d2009-11-07 00:00:49 +00002292 Result->AddChunk(Chunk(CodeCompletionString::CK_CurrentParameter,
Benjamin Kramer660cc182009-11-29 20:18:50 +00002293 ArgString));
Douglas Gregor86d802e2009-09-23 00:34:09 +00002294 else
Benjamin Kramer660cc182009-11-29 20:18:50 +00002295 Result->AddTextChunk(ArgString);
Douglas Gregor86d802e2009-09-23 00:34:09 +00002296 }
2297
2298 if (Proto && Proto->isVariadic()) {
Douglas Gregor0c8296d2009-11-07 00:00:49 +00002299 Result->AddChunk(Chunk(CodeCompletionString::CK_Comma));
Douglas Gregor86d802e2009-09-23 00:34:09 +00002300 if (CurrentArg < NumParams)
2301 Result->AddTextChunk("...");
2302 else
Douglas Gregor0c8296d2009-11-07 00:00:49 +00002303 Result->AddChunk(Chunk(CodeCompletionString::CK_CurrentParameter, "..."));
Douglas Gregor86d802e2009-09-23 00:34:09 +00002304 }
Douglas Gregor0c8296d2009-11-07 00:00:49 +00002305 Result->AddChunk(Chunk(CodeCompletionString::CK_RightParen));
Douglas Gregor86d802e2009-09-23 00:34:09 +00002306
2307 return Result;
2308}
2309
Douglas Gregor1827e102010-08-16 16:18:59 +00002310unsigned clang::getMacroUsagePriority(llvm::StringRef MacroName,
2311 bool PreferredTypeIsPointer) {
2312 unsigned Priority = CCP_Macro;
2313
2314 // Treat the "nil" and "NULL" macros as null pointer constants.
2315 if (MacroName.equals("nil") || MacroName.equals("NULL")) {
2316 Priority = CCP_Constant;
2317 if (PreferredTypeIsPointer)
2318 Priority = Priority / CCF_SimilarTypeMatch;
2319 }
2320
2321 return Priority;
2322}
2323
Douglas Gregore8d7beb2010-09-03 23:30:36 +00002324CXCursorKind clang::getCursorKindForDecl(Decl *D) {
2325 if (!D)
2326 return CXCursor_UnexposedDecl;
2327
2328 switch (D->getKind()) {
2329 case Decl::Enum: return CXCursor_EnumDecl;
2330 case Decl::EnumConstant: return CXCursor_EnumConstantDecl;
2331 case Decl::Field: return CXCursor_FieldDecl;
2332 case Decl::Function:
2333 return CXCursor_FunctionDecl;
2334 case Decl::ObjCCategory: return CXCursor_ObjCCategoryDecl;
2335 case Decl::ObjCCategoryImpl: return CXCursor_ObjCCategoryImplDecl;
2336 case Decl::ObjCClass:
2337 // FIXME
2338 return CXCursor_UnexposedDecl;
2339 case Decl::ObjCForwardProtocol:
2340 // FIXME
2341 return CXCursor_UnexposedDecl;
2342 case Decl::ObjCImplementation: return CXCursor_ObjCImplementationDecl;
2343 case Decl::ObjCInterface: return CXCursor_ObjCInterfaceDecl;
2344 case Decl::ObjCIvar: return CXCursor_ObjCIvarDecl;
2345 case Decl::ObjCMethod:
2346 return cast<ObjCMethodDecl>(D)->isInstanceMethod()
2347 ? CXCursor_ObjCInstanceMethodDecl : CXCursor_ObjCClassMethodDecl;
2348 case Decl::CXXMethod: return CXCursor_CXXMethod;
2349 case Decl::CXXConstructor: return CXCursor_Constructor;
2350 case Decl::CXXDestructor: return CXCursor_Destructor;
2351 case Decl::CXXConversion: return CXCursor_ConversionFunction;
2352 case Decl::ObjCProperty: return CXCursor_ObjCPropertyDecl;
2353 case Decl::ObjCProtocol: return CXCursor_ObjCProtocolDecl;
2354 case Decl::ParmVar: return CXCursor_ParmDecl;
2355 case Decl::Typedef: return CXCursor_TypedefDecl;
2356 case Decl::Var: return CXCursor_VarDecl;
2357 case Decl::Namespace: return CXCursor_Namespace;
2358 case Decl::NamespaceAlias: return CXCursor_NamespaceAlias;
2359 case Decl::TemplateTypeParm: return CXCursor_TemplateTypeParameter;
2360 case Decl::NonTypeTemplateParm:return CXCursor_NonTypeTemplateParameter;
2361 case Decl::TemplateTemplateParm:return CXCursor_TemplateTemplateParameter;
2362 case Decl::FunctionTemplate: return CXCursor_FunctionTemplate;
2363 case Decl::ClassTemplate: return CXCursor_ClassTemplate;
2364 case Decl::ClassTemplatePartialSpecialization:
2365 return CXCursor_ClassTemplatePartialSpecialization;
2366 case Decl::UsingDirective: return CXCursor_UsingDirective;
2367
2368 case Decl::Using:
2369 case Decl::UnresolvedUsingValue:
2370 case Decl::UnresolvedUsingTypename:
2371 return CXCursor_UsingDeclaration;
2372
2373 default:
2374 if (TagDecl *TD = dyn_cast<TagDecl>(D)) {
2375 switch (TD->getTagKind()) {
2376 case TTK_Struct: return CXCursor_StructDecl;
2377 case TTK_Class: return CXCursor_ClassDecl;
2378 case TTK_Union: return CXCursor_UnionDecl;
2379 case TTK_Enum: return CXCursor_EnumDecl;
2380 }
2381 }
2382 }
2383
2384 return CXCursor_UnexposedDecl;
2385}
2386
Douglas Gregor590c7d52010-07-08 20:55:51 +00002387static void AddMacroResults(Preprocessor &PP, ResultBuilder &Results,
2388 bool TargetTypeIsPointer = false) {
John McCall0a2c5e22010-08-25 06:19:51 +00002389 typedef CodeCompletionResult Result;
Douglas Gregor590c7d52010-07-08 20:55:51 +00002390
Douglas Gregor3f7c7f42009-10-30 16:50:04 +00002391 Results.EnterNewScope();
Douglas Gregor0c8296d2009-11-07 00:00:49 +00002392 for (Preprocessor::macro_iterator M = PP.macro_begin(),
2393 MEnd = PP.macro_end();
Douglas Gregor590c7d52010-07-08 20:55:51 +00002394 M != MEnd; ++M) {
Douglas Gregor1827e102010-08-16 16:18:59 +00002395 Results.AddResult(Result(M->first,
2396 getMacroUsagePriority(M->first->getName(),
2397 TargetTypeIsPointer)));
Douglas Gregor590c7d52010-07-08 20:55:51 +00002398 }
Douglas Gregor3f7c7f42009-10-30 16:50:04 +00002399 Results.ExitScope();
2400}
2401
Douglas Gregoraa5f77b2010-08-23 21:54:33 +00002402static void AddPrettyFunctionResults(const LangOptions &LangOpts,
2403 ResultBuilder &Results) {
John McCall0a2c5e22010-08-25 06:19:51 +00002404 typedef CodeCompletionResult Result;
Douglas Gregoraa5f77b2010-08-23 21:54:33 +00002405
2406 Results.EnterNewScope();
2407 Results.AddResult(Result("__PRETTY_FUNCTION__", CCP_Constant));
2408 Results.AddResult(Result("__FUNCTION__", CCP_Constant));
2409 if (LangOpts.C99 || LangOpts.CPlusPlus0x)
2410 Results.AddResult(Result("__func__", CCP_Constant));
2411 Results.ExitScope();
2412}
2413
Daniel Dunbar3a2838d2009-11-13 08:58:20 +00002414static void HandleCodeCompleteResults(Sema *S,
2415 CodeCompleteConsumer *CodeCompleter,
Douglas Gregore6b1bb62010-08-11 21:23:17 +00002416 CodeCompletionContext Context,
John McCall0a2c5e22010-08-25 06:19:51 +00002417 CodeCompletionResult *Results,
Douglas Gregore6b1bb62010-08-11 21:23:17 +00002418 unsigned NumResults) {
Douglas Gregor86d9a522009-09-21 16:56:56 +00002419 if (CodeCompleter)
Douglas Gregore6b1bb62010-08-11 21:23:17 +00002420 CodeCompleter->ProcessCodeCompleteResults(*S, Context, Results, NumResults);
Douglas Gregor54f01612009-11-19 00:01:57 +00002421
2422 for (unsigned I = 0; I != NumResults; ++I)
2423 Results[I].Destroy();
Douglas Gregor86d9a522009-09-21 16:56:56 +00002424}
2425
Douglas Gregore6b1bb62010-08-11 21:23:17 +00002426static enum CodeCompletionContext::Kind mapCodeCompletionContext(Sema &S,
2427 Sema::ParserCompletionContext PCC) {
2428 switch (PCC) {
John McCallf312b1e2010-08-26 23:41:50 +00002429 case Sema::PCC_Namespace:
Douglas Gregore6b1bb62010-08-11 21:23:17 +00002430 return CodeCompletionContext::CCC_TopLevel;
2431
John McCallf312b1e2010-08-26 23:41:50 +00002432 case Sema::PCC_Class:
Douglas Gregore6b1bb62010-08-11 21:23:17 +00002433 return CodeCompletionContext::CCC_ClassStructUnion;
2434
John McCallf312b1e2010-08-26 23:41:50 +00002435 case Sema::PCC_ObjCInterface:
Douglas Gregore6b1bb62010-08-11 21:23:17 +00002436 return CodeCompletionContext::CCC_ObjCInterface;
2437
John McCallf312b1e2010-08-26 23:41:50 +00002438 case Sema::PCC_ObjCImplementation:
Douglas Gregore6b1bb62010-08-11 21:23:17 +00002439 return CodeCompletionContext::CCC_ObjCImplementation;
2440
John McCallf312b1e2010-08-26 23:41:50 +00002441 case Sema::PCC_ObjCInstanceVariableList:
Douglas Gregore6b1bb62010-08-11 21:23:17 +00002442 return CodeCompletionContext::CCC_ObjCIvarList;
2443
John McCallf312b1e2010-08-26 23:41:50 +00002444 case Sema::PCC_Template:
2445 case Sema::PCC_MemberTemplate:
2446 case Sema::PCC_RecoveryInFunction:
Douglas Gregore6b1bb62010-08-11 21:23:17 +00002447 return CodeCompletionContext::CCC_Other;
2448
John McCallf312b1e2010-08-26 23:41:50 +00002449 case Sema::PCC_Expression:
2450 case Sema::PCC_ForInit:
2451 case Sema::PCC_Condition:
Douglas Gregore6b1bb62010-08-11 21:23:17 +00002452 return CodeCompletionContext::CCC_Expression;
2453
John McCallf312b1e2010-08-26 23:41:50 +00002454 case Sema::PCC_Statement:
Douglas Gregore6b1bb62010-08-11 21:23:17 +00002455 return CodeCompletionContext::CCC_Statement;
Douglas Gregor72db1082010-08-24 01:11:00 +00002456
John McCallf312b1e2010-08-26 23:41:50 +00002457 case Sema::PCC_Type:
Douglas Gregor72db1082010-08-24 01:11:00 +00002458 return CodeCompletionContext::CCC_Type;
Douglas Gregor02688102010-09-14 23:59:36 +00002459
2460 case Sema::PCC_ParenthesizedExpression:
2461 return CodeCompletionContext::CCC_ParenthesizedExpression;
Douglas Gregore6b1bb62010-08-11 21:23:17 +00002462 }
2463
2464 return CodeCompletionContext::CCC_Other;
2465}
2466
Douglas Gregorf6961522010-08-27 21:18:54 +00002467/// \brief If we're in a C++ virtual member function, add completion results
2468/// that invoke the functions we override, since it's common to invoke the
2469/// overridden function as well as adding new functionality.
2470///
2471/// \param S The semantic analysis object for which we are generating results.
2472///
2473/// \param InContext This context in which the nested-name-specifier preceding
2474/// the code-completion point
2475static void MaybeAddOverrideCalls(Sema &S, DeclContext *InContext,
2476 ResultBuilder &Results) {
2477 // Look through blocks.
2478 DeclContext *CurContext = S.CurContext;
2479 while (isa<BlockDecl>(CurContext))
2480 CurContext = CurContext->getParent();
2481
2482
2483 CXXMethodDecl *Method = dyn_cast<CXXMethodDecl>(CurContext);
2484 if (!Method || !Method->isVirtual())
2485 return;
2486
2487 // We need to have names for all of the parameters, if we're going to
2488 // generate a forwarding call.
2489 for (CXXMethodDecl::param_iterator P = Method->param_begin(),
2490 PEnd = Method->param_end();
2491 P != PEnd;
2492 ++P) {
2493 if (!(*P)->getDeclName())
2494 return;
2495 }
2496
2497 for (CXXMethodDecl::method_iterator M = Method->begin_overridden_methods(),
2498 MEnd = Method->end_overridden_methods();
2499 M != MEnd; ++M) {
2500 CodeCompletionString *Pattern = new CodeCompletionString;
2501 CXXMethodDecl *Overridden = const_cast<CXXMethodDecl *>(*M);
2502 if (Overridden->getCanonicalDecl() == Method->getCanonicalDecl())
2503 continue;
2504
2505 // If we need a nested-name-specifier, add one now.
2506 if (!InContext) {
2507 NestedNameSpecifier *NNS
2508 = getRequiredQualification(S.Context, CurContext,
2509 Overridden->getDeclContext());
2510 if (NNS) {
2511 std::string Str;
2512 llvm::raw_string_ostream OS(Str);
2513 NNS->print(OS, S.Context.PrintingPolicy);
2514 Pattern->AddTextChunk(OS.str());
2515 }
2516 } else if (!InContext->Equals(Overridden->getDeclContext()))
2517 continue;
2518
2519 Pattern->AddTypedTextChunk(Overridden->getNameAsString());
2520 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
2521 bool FirstParam = true;
2522 for (CXXMethodDecl::param_iterator P = Method->param_begin(),
2523 PEnd = Method->param_end();
2524 P != PEnd; ++P) {
2525 if (FirstParam)
2526 FirstParam = false;
2527 else
2528 Pattern->AddChunk(CodeCompletionString::CK_Comma);
2529
2530 Pattern->AddPlaceholderChunk((*P)->getIdentifier()->getName());
2531 }
2532 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
2533 Results.AddResult(CodeCompletionResult(Pattern,
2534 CCP_SuperCompletion,
2535 CXCursor_CXXMethod));
2536 Results.Ignore(Overridden);
2537 }
2538}
2539
Douglas Gregor01dfea02010-01-10 23:08:15 +00002540void Sema::CodeCompleteOrdinaryName(Scope *S,
Douglas Gregore6b1bb62010-08-11 21:23:17 +00002541 ParserCompletionContext CompletionContext) {
John McCall0a2c5e22010-08-25 06:19:51 +00002542 typedef CodeCompletionResult Result;
Douglas Gregor2ccccb32010-08-23 18:23:48 +00002543 ResultBuilder Results(*this);
Douglas Gregorf6961522010-08-27 21:18:54 +00002544 Results.EnterNewScope();
Douglas Gregor01dfea02010-01-10 23:08:15 +00002545
2546 // Determine how to filter results, e.g., so that the names of
2547 // values (functions, enumerators, function templates, etc.) are
2548 // only allowed where we can have an expression.
2549 switch (CompletionContext) {
Douglas Gregore6b1bb62010-08-11 21:23:17 +00002550 case PCC_Namespace:
2551 case PCC_Class:
2552 case PCC_ObjCInterface:
2553 case PCC_ObjCImplementation:
2554 case PCC_ObjCInstanceVariableList:
2555 case PCC_Template:
2556 case PCC_MemberTemplate:
Douglas Gregor72db1082010-08-24 01:11:00 +00002557 case PCC_Type:
Douglas Gregor01dfea02010-01-10 23:08:15 +00002558 Results.setFilter(&ResultBuilder::IsOrdinaryNonValueName);
2559 break;
2560
Douglas Gregore6b1bb62010-08-11 21:23:17 +00002561 case PCC_Statement:
Douglas Gregoreb0d0142010-08-24 23:58:17 +00002562 // For statements that are expressions, we prefer to call 'void' functions
2563 // rather than functions that return a result, since then the result would
2564 // be ignored.
2565 Results.setPreferredType(Context.VoidTy);
2566 // Fall through
2567
Douglas Gregor02688102010-09-14 23:59:36 +00002568 case PCC_ParenthesizedExpression:
Douglas Gregoreb0d0142010-08-24 23:58:17 +00002569 case PCC_Expression:
Douglas Gregore6b1bb62010-08-11 21:23:17 +00002570 case PCC_ForInit:
2571 case PCC_Condition:
Douglas Gregor4710e5b2010-05-28 00:49:12 +00002572 if (WantTypesInContext(CompletionContext, getLangOptions()))
2573 Results.setFilter(&ResultBuilder::IsOrdinaryName);
2574 else
2575 Results.setFilter(&ResultBuilder::IsOrdinaryNonTypeName);
Douglas Gregorf6961522010-08-27 21:18:54 +00002576
2577 if (getLangOptions().CPlusPlus)
2578 MaybeAddOverrideCalls(*this, /*InContext=*/0, Results);
Douglas Gregor01dfea02010-01-10 23:08:15 +00002579 break;
Douglas Gregordc845342010-05-25 05:58:43 +00002580
Douglas Gregore6b1bb62010-08-11 21:23:17 +00002581 case PCC_RecoveryInFunction:
Douglas Gregordc845342010-05-25 05:58:43 +00002582 // Unfiltered
2583 break;
Douglas Gregor01dfea02010-01-10 23:08:15 +00002584 }
2585
Douglas Gregor3cdee122010-08-26 16:36:48 +00002586 // If we are in a C++ non-static member function, check the qualifiers on
2587 // the member function to filter/prioritize the results list.
2588 if (CXXMethodDecl *CurMethod = dyn_cast<CXXMethodDecl>(CurContext))
2589 if (CurMethod->isInstance())
2590 Results.setObjectTypeQualifiers(
2591 Qualifiers::fromCVRMask(CurMethod->getTypeQualifiers()));
2592
Douglas Gregor1ca6ae82010-01-14 01:09:38 +00002593 CodeCompletionDeclConsumer Consumer(Results, CurContext);
Douglas Gregor8071e422010-08-15 06:18:01 +00002594 LookupVisibleDecls(S, LookupOrdinaryName, Consumer,
2595 CodeCompleter->includeGlobals());
Douglas Gregor2a7925c2009-12-07 09:54:55 +00002596
Douglas Gregorbca403c2010-01-13 23:51:12 +00002597 AddOrdinaryNameResults(CompletionContext, S, *this, Results);
Douglas Gregor2a7925c2009-12-07 09:54:55 +00002598 Results.ExitScope();
2599
Douglas Gregoraa5f77b2010-08-23 21:54:33 +00002600 switch (CompletionContext) {
Douglas Gregor02688102010-09-14 23:59:36 +00002601 case PCC_ParenthesizedExpression:
Douglas Gregor72db1082010-08-24 01:11:00 +00002602 case PCC_Expression:
2603 case PCC_Statement:
2604 case PCC_RecoveryInFunction:
2605 if (S->getFnParent())
2606 AddPrettyFunctionResults(PP.getLangOptions(), Results);
2607 break;
2608
2609 case PCC_Namespace:
2610 case PCC_Class:
2611 case PCC_ObjCInterface:
2612 case PCC_ObjCImplementation:
2613 case PCC_ObjCInstanceVariableList:
2614 case PCC_Template:
2615 case PCC_MemberTemplate:
2616 case PCC_ForInit:
2617 case PCC_Condition:
2618 case PCC_Type:
2619 break;
Douglas Gregoraa5f77b2010-08-23 21:54:33 +00002620 }
2621
Douglas Gregor0c8296d2009-11-07 00:00:49 +00002622 if (CodeCompleter->includeMacros())
Douglas Gregorbca403c2010-01-13 23:51:12 +00002623 AddMacroResults(PP, Results);
Douglas Gregoraa5f77b2010-08-23 21:54:33 +00002624
Douglas Gregore6b1bb62010-08-11 21:23:17 +00002625 HandleCodeCompleteResults(this, CodeCompleter,
2626 mapCodeCompletionContext(*this, CompletionContext),
2627 Results.data(),Results.size());
Douglas Gregor791215b2009-09-21 20:51:25 +00002628}
2629
Douglas Gregorc7b6d882010-09-16 15:14:18 +00002630static void AddClassMessageCompletions(Sema &SemaRef, Scope *S,
2631 ParsedType Receiver,
2632 IdentifierInfo **SelIdents,
2633 unsigned NumSelIdents,
2634 bool IsSuper,
2635 ResultBuilder &Results);
2636
2637void Sema::CodeCompleteDeclSpec(Scope *S, DeclSpec &DS,
2638 bool AllowNonIdentifiers,
2639 bool AllowNestedNameSpecifiers) {
John McCall0a2c5e22010-08-25 06:19:51 +00002640 typedef CodeCompletionResult Result;
Douglas Gregor2ccccb32010-08-23 18:23:48 +00002641 ResultBuilder Results(*this);
2642 Results.EnterNewScope();
2643
2644 // Type qualifiers can come after names.
2645 Results.AddResult(Result("const"));
2646 Results.AddResult(Result("volatile"));
2647 if (getLangOptions().C99)
2648 Results.AddResult(Result("restrict"));
2649
2650 if (getLangOptions().CPlusPlus) {
2651 if (AllowNonIdentifiers) {
2652 Results.AddResult(Result("operator"));
2653 }
2654
2655 // Add nested-name-specifiers.
2656 if (AllowNestedNameSpecifiers) {
2657 Results.allowNestedNameSpecifiers();
2658 CodeCompletionDeclConsumer Consumer(Results, CurContext);
2659 LookupVisibleDecls(S, LookupNestedNameSpecifierName, Consumer,
2660 CodeCompleter->includeGlobals());
2661 }
2662 }
2663 Results.ExitScope();
2664
Douglas Gregorc7b6d882010-09-16 15:14:18 +00002665 // If we're in a context where we might have an expression (rather than a
2666 // declaration), and what we've seen so far is an Objective-C type that could
2667 // be a receiver of a class message, this may be a class message send with
2668 // the initial opening bracket '[' missing. Add appropriate completions.
2669 if (AllowNonIdentifiers && !AllowNestedNameSpecifiers &&
2670 DS.getTypeSpecType() == DeclSpec::TST_typename &&
2671 DS.getStorageClassSpecAsWritten() == DeclSpec::SCS_unspecified &&
2672 !DS.isThreadSpecified() && !DS.isExternInLinkageSpec() &&
2673 DS.getTypeSpecComplex() == DeclSpec::TSC_unspecified &&
2674 DS.getTypeSpecSign() == DeclSpec::TSS_unspecified &&
2675 DS.getTypeQualifiers() == 0 &&
2676 S &&
2677 (S->getFlags() & Scope::DeclScope) != 0 &&
2678 (S->getFlags() & (Scope::ClassScope | Scope::TemplateParamScope |
2679 Scope::FunctionPrototypeScope |
2680 Scope::AtCatchScope)) == 0) {
2681 ParsedType T = DS.getRepAsType();
2682 if (!T.get().isNull() && T.get()->isObjCObjectOrInterfaceType())
2683 AddClassMessageCompletions(*this, S, T, 0, 0, false, Results);
2684 }
2685
Douglas Gregor4497dd42010-08-24 04:59:56 +00002686 // Note that we intentionally suppress macro results here, since we do not
2687 // encourage using macros to produce the names of entities.
2688
Douglas Gregor2ccccb32010-08-23 18:23:48 +00002689 HandleCodeCompleteResults(this, CodeCompleter,
2690 AllowNestedNameSpecifiers
2691 ? CodeCompletionContext::CCC_PotentiallyQualifiedName
2692 : CodeCompletionContext::CCC_Name,
2693 Results.data(), Results.size());
2694}
2695
Douglas Gregorfb629412010-08-23 21:17:50 +00002696struct Sema::CodeCompleteExpressionData {
2697 CodeCompleteExpressionData(QualType PreferredType = QualType())
2698 : PreferredType(PreferredType), IntegralConstantExpression(false),
2699 ObjCCollection(false) { }
2700
2701 QualType PreferredType;
2702 bool IntegralConstantExpression;
2703 bool ObjCCollection;
2704 llvm::SmallVector<Decl *, 4> IgnoreDecls;
2705};
2706
Douglas Gregor5ac3bdb2010-05-30 01:49:25 +00002707/// \brief Perform code-completion in an expression context when we know what
2708/// type we're looking for.
Douglas Gregorf9578432010-07-28 21:50:18 +00002709///
2710/// \param IntegralConstantExpression Only permit integral constant
2711/// expressions.
Douglas Gregorfb629412010-08-23 21:17:50 +00002712void Sema::CodeCompleteExpression(Scope *S,
2713 const CodeCompleteExpressionData &Data) {
John McCall0a2c5e22010-08-25 06:19:51 +00002714 typedef CodeCompletionResult Result;
Douglas Gregor5ac3bdb2010-05-30 01:49:25 +00002715 ResultBuilder Results(*this);
2716
Douglas Gregorfb629412010-08-23 21:17:50 +00002717 if (Data.ObjCCollection)
2718 Results.setFilter(&ResultBuilder::IsObjCCollection);
2719 else if (Data.IntegralConstantExpression)
Douglas Gregorf9578432010-07-28 21:50:18 +00002720 Results.setFilter(&ResultBuilder::IsIntegralConstantValue);
Douglas Gregore6b1bb62010-08-11 21:23:17 +00002721 else if (WantTypesInContext(PCC_Expression, getLangOptions()))
Douglas Gregor5ac3bdb2010-05-30 01:49:25 +00002722 Results.setFilter(&ResultBuilder::IsOrdinaryName);
2723 else
2724 Results.setFilter(&ResultBuilder::IsOrdinaryNonTypeName);
Douglas Gregorfb629412010-08-23 21:17:50 +00002725
2726 if (!Data.PreferredType.isNull())
2727 Results.setPreferredType(Data.PreferredType.getNonReferenceType());
2728
2729 // Ignore any declarations that we were told that we don't care about.
2730 for (unsigned I = 0, N = Data.IgnoreDecls.size(); I != N; ++I)
2731 Results.Ignore(Data.IgnoreDecls[I]);
Douglas Gregor5ac3bdb2010-05-30 01:49:25 +00002732
2733 CodeCompletionDeclConsumer Consumer(Results, CurContext);
Douglas Gregor8071e422010-08-15 06:18:01 +00002734 LookupVisibleDecls(S, LookupOrdinaryName, Consumer,
2735 CodeCompleter->includeGlobals());
Douglas Gregor5ac3bdb2010-05-30 01:49:25 +00002736
2737 Results.EnterNewScope();
Douglas Gregore6b1bb62010-08-11 21:23:17 +00002738 AddOrdinaryNameResults(PCC_Expression, S, *this, Results);
Douglas Gregor5ac3bdb2010-05-30 01:49:25 +00002739 Results.ExitScope();
2740
Douglas Gregor590c7d52010-07-08 20:55:51 +00002741 bool PreferredTypeIsPointer = false;
Douglas Gregorfb629412010-08-23 21:17:50 +00002742 if (!Data.PreferredType.isNull())
2743 PreferredTypeIsPointer = Data.PreferredType->isAnyPointerType()
2744 || Data.PreferredType->isMemberPointerType()
2745 || Data.PreferredType->isBlockPointerType();
Douglas Gregor590c7d52010-07-08 20:55:51 +00002746
Douglas Gregoraa5f77b2010-08-23 21:54:33 +00002747 if (S->getFnParent() &&
2748 !Data.ObjCCollection &&
2749 !Data.IntegralConstantExpression)
2750 AddPrettyFunctionResults(PP.getLangOptions(), Results);
2751
Douglas Gregor5ac3bdb2010-05-30 01:49:25 +00002752 if (CodeCompleter->includeMacros())
Douglas Gregor590c7d52010-07-08 20:55:51 +00002753 AddMacroResults(PP, Results, PreferredTypeIsPointer);
Douglas Gregore6b1bb62010-08-11 21:23:17 +00002754 HandleCodeCompleteResults(this, CodeCompleter,
Douglas Gregorfb629412010-08-23 21:17:50 +00002755 CodeCompletionContext(CodeCompletionContext::CCC_Expression,
2756 Data.PreferredType),
Douglas Gregore6b1bb62010-08-11 21:23:17 +00002757 Results.data(),Results.size());
Douglas Gregor5ac3bdb2010-05-30 01:49:25 +00002758}
2759
Douglas Gregorac5fd842010-09-18 01:28:11 +00002760void Sema::CodeCompletePostfixExpression(Scope *S, ExprResult E) {
2761 if (E.isInvalid())
2762 CodeCompleteOrdinaryName(S, PCC_RecoveryInFunction);
2763 else if (getLangOptions().ObjC1)
2764 CodeCompleteObjCInstanceMessage(S, E.take(), 0, 0, false);
Douglas Gregor78edf512010-09-15 16:23:04 +00002765}
Douglas Gregor5ac3bdb2010-05-30 01:49:25 +00002766
Douglas Gregor95ac6552009-11-18 01:29:26 +00002767static void AddObjCProperties(ObjCContainerDecl *Container,
Douglas Gregor322328b2009-11-18 22:32:06 +00002768 bool AllowCategories,
Douglas Gregor95ac6552009-11-18 01:29:26 +00002769 DeclContext *CurContext,
2770 ResultBuilder &Results) {
John McCall0a2c5e22010-08-25 06:19:51 +00002771 typedef CodeCompletionResult Result;
Douglas Gregor95ac6552009-11-18 01:29:26 +00002772
2773 // Add properties in this container.
2774 for (ObjCContainerDecl::prop_iterator P = Container->prop_begin(),
2775 PEnd = Container->prop_end();
2776 P != PEnd;
2777 ++P)
2778 Results.MaybeAddResult(Result(*P, 0), CurContext);
2779
2780 // Add properties in referenced protocols.
2781 if (ObjCProtocolDecl *Protocol = dyn_cast<ObjCProtocolDecl>(Container)) {
2782 for (ObjCProtocolDecl::protocol_iterator P = Protocol->protocol_begin(),
2783 PEnd = Protocol->protocol_end();
2784 P != PEnd; ++P)
Douglas Gregor322328b2009-11-18 22:32:06 +00002785 AddObjCProperties(*P, AllowCategories, CurContext, Results);
Douglas Gregor95ac6552009-11-18 01:29:26 +00002786 } else if (ObjCInterfaceDecl *IFace = dyn_cast<ObjCInterfaceDecl>(Container)){
Douglas Gregor322328b2009-11-18 22:32:06 +00002787 if (AllowCategories) {
2788 // Look through categories.
2789 for (ObjCCategoryDecl *Category = IFace->getCategoryList();
2790 Category; Category = Category->getNextClassCategory())
2791 AddObjCProperties(Category, AllowCategories, CurContext, Results);
2792 }
Douglas Gregor95ac6552009-11-18 01:29:26 +00002793
2794 // Look through protocols.
Ted Kremenek53b94412010-09-01 01:21:15 +00002795 for (ObjCInterfaceDecl::all_protocol_iterator
2796 I = IFace->all_referenced_protocol_begin(),
2797 E = IFace->all_referenced_protocol_end(); I != E; ++I)
Douglas Gregor322328b2009-11-18 22:32:06 +00002798 AddObjCProperties(*I, AllowCategories, CurContext, Results);
Douglas Gregor95ac6552009-11-18 01:29:26 +00002799
2800 // Look in the superclass.
2801 if (IFace->getSuperClass())
Douglas Gregor322328b2009-11-18 22:32:06 +00002802 AddObjCProperties(IFace->getSuperClass(), AllowCategories, CurContext,
2803 Results);
Douglas Gregor95ac6552009-11-18 01:29:26 +00002804 } else if (const ObjCCategoryDecl *Category
2805 = dyn_cast<ObjCCategoryDecl>(Container)) {
2806 // Look through protocols.
Ted Kremenek53b94412010-09-01 01:21:15 +00002807 for (ObjCCategoryDecl::protocol_iterator P = Category->protocol_begin(),
2808 PEnd = Category->protocol_end();
Douglas Gregor95ac6552009-11-18 01:29:26 +00002809 P != PEnd; ++P)
Douglas Gregor322328b2009-11-18 22:32:06 +00002810 AddObjCProperties(*P, AllowCategories, CurContext, Results);
Douglas Gregor95ac6552009-11-18 01:29:26 +00002811 }
2812}
2813
Douglas Gregor81b747b2009-09-17 21:32:03 +00002814void Sema::CodeCompleteMemberReferenceExpr(Scope *S, ExprTy *BaseE,
2815 SourceLocation OpLoc,
2816 bool IsArrow) {
2817 if (!BaseE || !CodeCompleter)
2818 return;
2819
John McCall0a2c5e22010-08-25 06:19:51 +00002820 typedef CodeCompletionResult Result;
Douglas Gregor86d9a522009-09-21 16:56:56 +00002821
Douglas Gregor81b747b2009-09-17 21:32:03 +00002822 Expr *Base = static_cast<Expr *>(BaseE);
2823 QualType BaseType = Base->getType();
Douglas Gregor86d9a522009-09-21 16:56:56 +00002824
2825 if (IsArrow) {
2826 if (const PointerType *Ptr = BaseType->getAs<PointerType>())
2827 BaseType = Ptr->getPointeeType();
2828 else if (BaseType->isObjCObjectPointerType())
Douglas Gregor3cdee122010-08-26 16:36:48 +00002829 /*Do nothing*/ ;
Douglas Gregor86d9a522009-09-21 16:56:56 +00002830 else
2831 return;
2832 }
2833
Douglas Gregoreb5758b2009-09-23 22:26:46 +00002834 ResultBuilder Results(*this, &ResultBuilder::IsMember);
Douglas Gregor95ac6552009-11-18 01:29:26 +00002835 Results.EnterNewScope();
2836 if (const RecordType *Record = BaseType->getAs<RecordType>()) {
Douglas Gregor3cdee122010-08-26 16:36:48 +00002837 // Indicate that we are performing a member access, and the cv-qualifiers
2838 // for the base object type.
2839 Results.setObjectTypeQualifiers(BaseType.getQualifiers());
2840
Douglas Gregor95ac6552009-11-18 01:29:26 +00002841 // Access to a C/C++ class, struct, or union.
Douglas Gregor45bcd432010-01-14 03:21:49 +00002842 Results.allowNestedNameSpecifiers();
Douglas Gregor0cc84042010-01-14 15:47:35 +00002843 CodeCompletionDeclConsumer Consumer(Results, CurContext);
Douglas Gregor8071e422010-08-15 06:18:01 +00002844 LookupVisibleDecls(Record->getDecl(), LookupMemberName, Consumer,
2845 CodeCompleter->includeGlobals());
Daniel Dunbar3a2838d2009-11-13 08:58:20 +00002846
Douglas Gregor95ac6552009-11-18 01:29:26 +00002847 if (getLangOptions().CPlusPlus) {
2848 if (!Results.empty()) {
2849 // The "template" keyword can follow "->" or "." in the grammar.
2850 // However, we only want to suggest the template keyword if something
2851 // is dependent.
2852 bool IsDependent = BaseType->isDependentType();
2853 if (!IsDependent) {
2854 for (Scope *DepScope = S; DepScope; DepScope = DepScope->getParent())
2855 if (DeclContext *Ctx = (DeclContext *)DepScope->getEntity()) {
2856 IsDependent = Ctx->isDependentContext();
2857 break;
2858 }
2859 }
Daniel Dunbar3a2838d2009-11-13 08:58:20 +00002860
Douglas Gregor95ac6552009-11-18 01:29:26 +00002861 if (IsDependent)
Douglas Gregora4477812010-01-14 16:01:26 +00002862 Results.AddResult(Result("template"));
Daniel Dunbar3a2838d2009-11-13 08:58:20 +00002863 }
Daniel Dunbar3a2838d2009-11-13 08:58:20 +00002864 }
Douglas Gregor95ac6552009-11-18 01:29:26 +00002865 } else if (!IsArrow && BaseType->getAsObjCInterfacePointerType()) {
2866 // Objective-C property reference.
2867
2868 // Add property results based on our interface.
2869 const ObjCObjectPointerType *ObjCPtr
2870 = BaseType->getAsObjCInterfacePointerType();
2871 assert(ObjCPtr && "Non-NULL pointer guaranteed above!");
Douglas Gregor322328b2009-11-18 22:32:06 +00002872 AddObjCProperties(ObjCPtr->getInterfaceDecl(), true, CurContext, Results);
Douglas Gregor95ac6552009-11-18 01:29:26 +00002873
2874 // Add properties from the protocols in a qualified interface.
2875 for (ObjCObjectPointerType::qual_iterator I = ObjCPtr->qual_begin(),
2876 E = ObjCPtr->qual_end();
2877 I != E; ++I)
Douglas Gregor322328b2009-11-18 22:32:06 +00002878 AddObjCProperties(*I, true, CurContext, Results);
Douglas Gregor95ac6552009-11-18 01:29:26 +00002879 } else if ((IsArrow && BaseType->isObjCObjectPointerType()) ||
John McCallc12c5bb2010-05-15 11:32:37 +00002880 (!IsArrow && BaseType->isObjCObjectType())) {
Douglas Gregor95ac6552009-11-18 01:29:26 +00002881 // Objective-C instance variable access.
2882 ObjCInterfaceDecl *Class = 0;
2883 if (const ObjCObjectPointerType *ObjCPtr
2884 = BaseType->getAs<ObjCObjectPointerType>())
2885 Class = ObjCPtr->getInterfaceDecl();
2886 else
John McCallc12c5bb2010-05-15 11:32:37 +00002887 Class = BaseType->getAs<ObjCObjectType>()->getInterface();
Douglas Gregor95ac6552009-11-18 01:29:26 +00002888
2889 // Add all ivars from this class and its superclasses.
Douglas Gregor80f4f4c2010-01-14 16:08:12 +00002890 if (Class) {
2891 CodeCompletionDeclConsumer Consumer(Results, CurContext);
2892 Results.setFilter(&ResultBuilder::IsObjCIvar);
Douglas Gregor8071e422010-08-15 06:18:01 +00002893 LookupVisibleDecls(Class, LookupMemberName, Consumer,
2894 CodeCompleter->includeGlobals());
Douglas Gregor95ac6552009-11-18 01:29:26 +00002895 }
Douglas Gregor86d9a522009-09-21 16:56:56 +00002896 }
Douglas Gregor95ac6552009-11-18 01:29:26 +00002897
2898 // FIXME: How do we cope with isa?
2899
2900 Results.ExitScope();
Daniel Dunbar3a2838d2009-11-13 08:58:20 +00002901
Daniel Dunbar3a2838d2009-11-13 08:58:20 +00002902 // Hand off the results found for code completion.
Douglas Gregore6b1bb62010-08-11 21:23:17 +00002903 HandleCodeCompleteResults(this, CodeCompleter,
2904 CodeCompletionContext(CodeCompletionContext::CCC_MemberAccess,
2905 BaseType),
2906 Results.data(),Results.size());
Douglas Gregor81b747b2009-09-17 21:32:03 +00002907}
2908
Douglas Gregor374929f2009-09-18 15:37:17 +00002909void Sema::CodeCompleteTag(Scope *S, unsigned TagSpec) {
2910 if (!CodeCompleter)
2911 return;
2912
John McCall0a2c5e22010-08-25 06:19:51 +00002913 typedef CodeCompletionResult Result;
Douglas Gregor86d9a522009-09-21 16:56:56 +00002914 ResultBuilder::LookupFilter Filter = 0;
Douglas Gregore6b1bb62010-08-11 21:23:17 +00002915 enum CodeCompletionContext::Kind ContextKind
2916 = CodeCompletionContext::CCC_Other;
Douglas Gregor374929f2009-09-18 15:37:17 +00002917 switch ((DeclSpec::TST)TagSpec) {
2918 case DeclSpec::TST_enum:
Douglas Gregor86d9a522009-09-21 16:56:56 +00002919 Filter = &ResultBuilder::IsEnum;
Douglas Gregore6b1bb62010-08-11 21:23:17 +00002920 ContextKind = CodeCompletionContext::CCC_EnumTag;
Douglas Gregor374929f2009-09-18 15:37:17 +00002921 break;
2922
2923 case DeclSpec::TST_union:
Douglas Gregor86d9a522009-09-21 16:56:56 +00002924 Filter = &ResultBuilder::IsUnion;
Douglas Gregore6b1bb62010-08-11 21:23:17 +00002925 ContextKind = CodeCompletionContext::CCC_UnionTag;
Douglas Gregor374929f2009-09-18 15:37:17 +00002926 break;
2927
2928 case DeclSpec::TST_struct:
Douglas Gregor374929f2009-09-18 15:37:17 +00002929 case DeclSpec::TST_class:
Douglas Gregor86d9a522009-09-21 16:56:56 +00002930 Filter = &ResultBuilder::IsClassOrStruct;
Douglas Gregore6b1bb62010-08-11 21:23:17 +00002931 ContextKind = CodeCompletionContext::CCC_ClassOrStructTag;
Douglas Gregor374929f2009-09-18 15:37:17 +00002932 break;
2933
2934 default:
2935 assert(false && "Unknown type specifier kind in CodeCompleteTag");
2936 return;
2937 }
Douglas Gregor86d9a522009-09-21 16:56:56 +00002938
John McCall0d6b1642010-04-23 18:46:30 +00002939 ResultBuilder Results(*this);
Douglas Gregor5d2fc402010-01-14 03:27:13 +00002940 CodeCompletionDeclConsumer Consumer(Results, CurContext);
John McCall0d6b1642010-04-23 18:46:30 +00002941
2942 // First pass: look for tags.
2943 Results.setFilter(Filter);
Douglas Gregor8071e422010-08-15 06:18:01 +00002944 LookupVisibleDecls(S, LookupTagName, Consumer,
2945 CodeCompleter->includeGlobals());
John McCall0d6b1642010-04-23 18:46:30 +00002946
Douglas Gregor8071e422010-08-15 06:18:01 +00002947 if (CodeCompleter->includeGlobals()) {
2948 // Second pass: look for nested name specifiers.
2949 Results.setFilter(&ResultBuilder::IsNestedNameSpecifier);
2950 LookupVisibleDecls(S, LookupNestedNameSpecifierName, Consumer);
2951 }
Douglas Gregor86d9a522009-09-21 16:56:56 +00002952
Douglas Gregore6b1bb62010-08-11 21:23:17 +00002953 HandleCodeCompleteResults(this, CodeCompleter, ContextKind,
2954 Results.data(),Results.size());
Douglas Gregor374929f2009-09-18 15:37:17 +00002955}
2956
Douglas Gregor1a480c42010-08-27 17:35:51 +00002957void Sema::CodeCompleteTypeQualifiers(DeclSpec &DS) {
2958 ResultBuilder Results(*this);
2959 Results.EnterNewScope();
2960 if (!(DS.getTypeQualifiers() & DeclSpec::TQ_const))
2961 Results.AddResult("const");
2962 if (!(DS.getTypeQualifiers() & DeclSpec::TQ_volatile))
2963 Results.AddResult("volatile");
2964 if (getLangOptions().C99 &&
2965 !(DS.getTypeQualifiers() & DeclSpec::TQ_restrict))
2966 Results.AddResult("restrict");
2967 Results.ExitScope();
2968 HandleCodeCompleteResults(this, CodeCompleter,
2969 CodeCompletionContext::CCC_TypeQualifiers,
2970 Results.data(), Results.size());
2971}
2972
Douglas Gregor3e1005f2009-09-21 18:10:23 +00002973void Sema::CodeCompleteCase(Scope *S) {
John McCall781472f2010-08-25 08:40:02 +00002974 if (getCurFunction()->SwitchStack.empty() || !CodeCompleter)
Douglas Gregor3e1005f2009-09-21 18:10:23 +00002975 return;
2976
John McCall781472f2010-08-25 08:40:02 +00002977 SwitchStmt *Switch = getCurFunction()->SwitchStack.back();
Douglas Gregorf9578432010-07-28 21:50:18 +00002978 if (!Switch->getCond()->getType()->isEnumeralType()) {
Douglas Gregorfb629412010-08-23 21:17:50 +00002979 CodeCompleteExpressionData Data(Switch->getCond()->getType());
2980 Data.IntegralConstantExpression = true;
2981 CodeCompleteExpression(S, Data);
Douglas Gregor3e1005f2009-09-21 18:10:23 +00002982 return;
Douglas Gregorf9578432010-07-28 21:50:18 +00002983 }
Douglas Gregor3e1005f2009-09-21 18:10:23 +00002984
2985 // Code-complete the cases of a switch statement over an enumeration type
2986 // by providing the list of
2987 EnumDecl *Enum = Switch->getCond()->getType()->getAs<EnumType>()->getDecl();
2988
2989 // Determine which enumerators we have already seen in the switch statement.
2990 // FIXME: Ideally, we would also be able to look *past* the code-completion
2991 // token, in case we are code-completing in the middle of the switch and not
2992 // at the end. However, we aren't able to do so at the moment.
2993 llvm::SmallPtrSet<EnumConstantDecl *, 8> EnumeratorsSeen;
Douglas Gregorb9d0ef72009-09-21 19:57:38 +00002994 NestedNameSpecifier *Qualifier = 0;
Douglas Gregor3e1005f2009-09-21 18:10:23 +00002995 for (SwitchCase *SC = Switch->getSwitchCaseList(); SC;
2996 SC = SC->getNextSwitchCase()) {
2997 CaseStmt *Case = dyn_cast<CaseStmt>(SC);
2998 if (!Case)
2999 continue;
3000
3001 Expr *CaseVal = Case->getLHS()->IgnoreParenCasts();
3002 if (DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(CaseVal))
3003 if (EnumConstantDecl *Enumerator
3004 = dyn_cast<EnumConstantDecl>(DRE->getDecl())) {
3005 // We look into the AST of the case statement to determine which
3006 // enumerator was named. Alternatively, we could compute the value of
3007 // the integral constant expression, then compare it against the
3008 // values of each enumerator. However, value-based approach would not
3009 // work as well with C++ templates where enumerators declared within a
3010 // template are type- and value-dependent.
3011 EnumeratorsSeen.insert(Enumerator);
3012
Douglas Gregorb9d0ef72009-09-21 19:57:38 +00003013 // If this is a qualified-id, keep track of the nested-name-specifier
3014 // so that we can reproduce it as part of code completion, e.g.,
Douglas Gregor3e1005f2009-09-21 18:10:23 +00003015 //
3016 // switch (TagD.getKind()) {
3017 // case TagDecl::TK_enum:
3018 // break;
3019 // case XXX
3020 //
Douglas Gregorb9d0ef72009-09-21 19:57:38 +00003021 // At the XXX, our completions are TagDecl::TK_union,
Douglas Gregor3e1005f2009-09-21 18:10:23 +00003022 // TagDecl::TK_struct, and TagDecl::TK_class, rather than TK_union,
3023 // TK_struct, and TK_class.
Douglas Gregora2813ce2009-10-23 18:54:35 +00003024 Qualifier = DRE->getQualifier();
Douglas Gregor3e1005f2009-09-21 18:10:23 +00003025 }
3026 }
3027
Douglas Gregorb9d0ef72009-09-21 19:57:38 +00003028 if (getLangOptions().CPlusPlus && !Qualifier && EnumeratorsSeen.empty()) {
3029 // If there are no prior enumerators in C++, check whether we have to
3030 // qualify the names of the enumerators that we suggest, because they
3031 // may not be visible in this scope.
3032 Qualifier = getRequiredQualification(Context, CurContext,
3033 Enum->getDeclContext());
3034
3035 // FIXME: Scoped enums need to start with "EnumDecl" as the context!
3036 }
3037
Douglas Gregor3e1005f2009-09-21 18:10:23 +00003038 // Add any enumerators that have not yet been mentioned.
3039 ResultBuilder Results(*this);
3040 Results.EnterNewScope();
3041 for (EnumDecl::enumerator_iterator E = Enum->enumerator_begin(),
3042 EEnd = Enum->enumerator_end();
3043 E != EEnd; ++E) {
3044 if (EnumeratorsSeen.count(*E))
3045 continue;
3046
John McCall0a2c5e22010-08-25 06:19:51 +00003047 Results.AddResult(CodeCompletionResult(*E, Qualifier),
Douglas Gregor608300b2010-01-14 16:14:35 +00003048 CurContext, 0, false);
Douglas Gregor3e1005f2009-09-21 18:10:23 +00003049 }
3050 Results.ExitScope();
Douglas Gregor2f880e42010-04-06 20:02:15 +00003051
Douglas Gregor0c8296d2009-11-07 00:00:49 +00003052 if (CodeCompleter->includeMacros())
Douglas Gregorbca403c2010-01-13 23:51:12 +00003053 AddMacroResults(PP, Results);
Douglas Gregore6b1bb62010-08-11 21:23:17 +00003054 HandleCodeCompleteResults(this, CodeCompleter,
3055 CodeCompletionContext::CCC_Expression,
3056 Results.data(),Results.size());
Douglas Gregor3e1005f2009-09-21 18:10:23 +00003057}
3058
Douglas Gregor9c6a0e92009-09-22 15:41:20 +00003059namespace {
3060 struct IsBetterOverloadCandidate {
3061 Sema &S;
John McCall5769d612010-02-08 23:07:23 +00003062 SourceLocation Loc;
Douglas Gregor9c6a0e92009-09-22 15:41:20 +00003063
3064 public:
John McCall5769d612010-02-08 23:07:23 +00003065 explicit IsBetterOverloadCandidate(Sema &S, SourceLocation Loc)
3066 : S(S), Loc(Loc) { }
Douglas Gregor9c6a0e92009-09-22 15:41:20 +00003067
3068 bool
3069 operator()(const OverloadCandidate &X, const OverloadCandidate &Y) const {
John McCall120d63c2010-08-24 20:38:10 +00003070 return isBetterOverloadCandidate(S, X, Y, Loc);
Douglas Gregor9c6a0e92009-09-22 15:41:20 +00003071 }
3072 };
3073}
3074
Douglas Gregord28dcd72010-05-30 06:10:08 +00003075static bool anyNullArguments(Expr **Args, unsigned NumArgs) {
3076 if (NumArgs && !Args)
3077 return true;
3078
3079 for (unsigned I = 0; I != NumArgs; ++I)
3080 if (!Args[I])
3081 return true;
3082
3083 return false;
3084}
3085
Douglas Gregor9c6a0e92009-09-22 15:41:20 +00003086void Sema::CodeCompleteCall(Scope *S, ExprTy *FnIn,
3087 ExprTy **ArgsIn, unsigned NumArgs) {
3088 if (!CodeCompleter)
3089 return;
Douglas Gregoref96eac2009-12-11 19:06:04 +00003090
3091 // When we're code-completing for a call, we fall back to ordinary
3092 // name code-completion whenever we can't produce specific
3093 // results. We may want to revisit this strategy in the future,
3094 // e.g., by merging the two kinds of results.
3095
Douglas Gregor9c6a0e92009-09-22 15:41:20 +00003096 Expr *Fn = (Expr *)FnIn;
3097 Expr **Args = (Expr **)ArgsIn;
Douglas Gregoref96eac2009-12-11 19:06:04 +00003098
Douglas Gregor9c6a0e92009-09-22 15:41:20 +00003099 // Ignore type-dependent call expressions entirely.
Douglas Gregord28dcd72010-05-30 06:10:08 +00003100 if (!Fn || Fn->isTypeDependent() || anyNullArguments(Args, NumArgs) ||
Douglas Gregoref96eac2009-12-11 19:06:04 +00003101 Expr::hasAnyTypeDependentArguments(Args, NumArgs)) {
Douglas Gregore6b1bb62010-08-11 21:23:17 +00003102 CodeCompleteOrdinaryName(S, PCC_Expression);
Douglas Gregor9c6a0e92009-09-22 15:41:20 +00003103 return;
Douglas Gregoref96eac2009-12-11 19:06:04 +00003104 }
Douglas Gregor9c6a0e92009-09-22 15:41:20 +00003105
John McCall3b4294e2009-12-16 12:17:52 +00003106 // Build an overload candidate set based on the functions we find.
John McCall5769d612010-02-08 23:07:23 +00003107 SourceLocation Loc = Fn->getExprLoc();
3108 OverloadCandidateSet CandidateSet(Loc);
John McCall3b4294e2009-12-16 12:17:52 +00003109
Douglas Gregor9c6a0e92009-09-22 15:41:20 +00003110 // FIXME: What if we're calling something that isn't a function declaration?
3111 // FIXME: What if we're calling a pseudo-destructor?
3112 // FIXME: What if we're calling a member function?
3113
Douglas Gregorc0265402010-01-21 15:46:19 +00003114 typedef CodeCompleteConsumer::OverloadCandidate ResultCandidate;
3115 llvm::SmallVector<ResultCandidate, 8> Results;
3116
John McCall3b4294e2009-12-16 12:17:52 +00003117 Expr *NakedFn = Fn->IgnoreParenCasts();
3118 if (UnresolvedLookupExpr *ULE = dyn_cast<UnresolvedLookupExpr>(NakedFn))
3119 AddOverloadedCallCandidates(ULE, Args, NumArgs, CandidateSet,
3120 /*PartialOverloading=*/ true);
3121 else if (DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(NakedFn)) {
3122 FunctionDecl *FDecl = dyn_cast<FunctionDecl>(DRE->getDecl());
Douglas Gregorc0265402010-01-21 15:46:19 +00003123 if (FDecl) {
Douglas Gregord28dcd72010-05-30 06:10:08 +00003124 if (!getLangOptions().CPlusPlus ||
3125 !FDecl->getType()->getAs<FunctionProtoType>())
Douglas Gregorc0265402010-01-21 15:46:19 +00003126 Results.push_back(ResultCandidate(FDecl));
3127 else
John McCall86820f52010-01-26 01:37:31 +00003128 // FIXME: access?
John McCall9aa472c2010-03-19 07:35:19 +00003129 AddOverloadCandidate(FDecl, DeclAccessPair::make(FDecl, AS_none),
3130 Args, NumArgs, CandidateSet,
Douglas Gregorc27d6c52010-04-16 17:41:49 +00003131 false, /*PartialOverloading*/true);
Douglas Gregorc0265402010-01-21 15:46:19 +00003132 }
John McCall3b4294e2009-12-16 12:17:52 +00003133 }
Douglas Gregor9c6a0e92009-09-22 15:41:20 +00003134
Douglas Gregor5ac3bdb2010-05-30 01:49:25 +00003135 QualType ParamType;
3136
Douglas Gregorc0265402010-01-21 15:46:19 +00003137 if (!CandidateSet.empty()) {
3138 // Sort the overload candidate set by placing the best overloads first.
3139 std::stable_sort(CandidateSet.begin(), CandidateSet.end(),
John McCall5769d612010-02-08 23:07:23 +00003140 IsBetterOverloadCandidate(*this, Loc));
Douglas Gregor9c6a0e92009-09-22 15:41:20 +00003141
Douglas Gregorc0265402010-01-21 15:46:19 +00003142 // Add the remaining viable overload candidates as code-completion reslults.
3143 for (OverloadCandidateSet::iterator Cand = CandidateSet.begin(),
3144 CandEnd = CandidateSet.end();
3145 Cand != CandEnd; ++Cand) {
3146 if (Cand->Viable)
3147 Results.push_back(ResultCandidate(Cand->Function));
3148 }
Douglas Gregor5ac3bdb2010-05-30 01:49:25 +00003149
3150 // From the viable candidates, try to determine the type of this parameter.
3151 for (unsigned I = 0, N = Results.size(); I != N; ++I) {
3152 if (const FunctionType *FType = Results[I].getFunctionType())
3153 if (const FunctionProtoType *Proto = dyn_cast<FunctionProtoType>(FType))
3154 if (NumArgs < Proto->getNumArgs()) {
3155 if (ParamType.isNull())
3156 ParamType = Proto->getArgType(NumArgs);
3157 else if (!Context.hasSameUnqualifiedType(
3158 ParamType.getNonReferenceType(),
3159 Proto->getArgType(NumArgs).getNonReferenceType())) {
3160 ParamType = QualType();
3161 break;
3162 }
3163 }
3164 }
3165 } else {
3166 // Try to determine the parameter type from the type of the expression
3167 // being called.
3168 QualType FunctionType = Fn->getType();
3169 if (const PointerType *Ptr = FunctionType->getAs<PointerType>())
3170 FunctionType = Ptr->getPointeeType();
3171 else if (const BlockPointerType *BlockPtr
3172 = FunctionType->getAs<BlockPointerType>())
3173 FunctionType = BlockPtr->getPointeeType();
3174 else if (const MemberPointerType *MemPtr
3175 = FunctionType->getAs<MemberPointerType>())
3176 FunctionType = MemPtr->getPointeeType();
3177
3178 if (const FunctionProtoType *Proto
3179 = FunctionType->getAs<FunctionProtoType>()) {
3180 if (NumArgs < Proto->getNumArgs())
3181 ParamType = Proto->getArgType(NumArgs);
3182 }
Douglas Gregor9c6a0e92009-09-22 15:41:20 +00003183 }
Douglas Gregoref96eac2009-12-11 19:06:04 +00003184
Douglas Gregor5ac3bdb2010-05-30 01:49:25 +00003185 if (ParamType.isNull())
Douglas Gregore6b1bb62010-08-11 21:23:17 +00003186 CodeCompleteOrdinaryName(S, PCC_Expression);
Douglas Gregor5ac3bdb2010-05-30 01:49:25 +00003187 else
3188 CodeCompleteExpression(S, ParamType);
3189
Douglas Gregor2e4c7a52010-04-06 20:19:47 +00003190 if (!Results.empty())
Douglas Gregoref96eac2009-12-11 19:06:04 +00003191 CodeCompleter->ProcessOverloadCandidates(*this, NumArgs, Results.data(),
3192 Results.size());
Douglas Gregor9c6a0e92009-09-22 15:41:20 +00003193}
3194
John McCalld226f652010-08-21 09:40:31 +00003195void Sema::CodeCompleteInitializer(Scope *S, Decl *D) {
3196 ValueDecl *VD = dyn_cast_or_null<ValueDecl>(D);
Douglas Gregor5ac3bdb2010-05-30 01:49:25 +00003197 if (!VD) {
Douglas Gregore6b1bb62010-08-11 21:23:17 +00003198 CodeCompleteOrdinaryName(S, PCC_Expression);
Douglas Gregor5ac3bdb2010-05-30 01:49:25 +00003199 return;
3200 }
3201
3202 CodeCompleteExpression(S, VD->getType());
3203}
3204
3205void Sema::CodeCompleteReturn(Scope *S) {
3206 QualType ResultType;
3207 if (isa<BlockDecl>(CurContext)) {
3208 if (BlockScopeInfo *BSI = getCurBlock())
3209 ResultType = BSI->ReturnType;
3210 } else if (FunctionDecl *Function = dyn_cast<FunctionDecl>(CurContext))
3211 ResultType = Function->getResultType();
3212 else if (ObjCMethodDecl *Method = dyn_cast<ObjCMethodDecl>(CurContext))
3213 ResultType = Method->getResultType();
3214
3215 if (ResultType.isNull())
Douglas Gregore6b1bb62010-08-11 21:23:17 +00003216 CodeCompleteOrdinaryName(S, PCC_Expression);
Douglas Gregor5ac3bdb2010-05-30 01:49:25 +00003217 else
3218 CodeCompleteExpression(S, ResultType);
3219}
3220
3221void Sema::CodeCompleteAssignmentRHS(Scope *S, ExprTy *LHS) {
3222 if (LHS)
3223 CodeCompleteExpression(S, static_cast<Expr *>(LHS)->getType());
3224 else
Douglas Gregore6b1bb62010-08-11 21:23:17 +00003225 CodeCompleteOrdinaryName(S, PCC_Expression);
Douglas Gregor5ac3bdb2010-05-30 01:49:25 +00003226}
3227
Jeffrey Yasskin9ab14542010-04-08 16:38:48 +00003228void Sema::CodeCompleteQualifiedId(Scope *S, CXXScopeSpec &SS,
Douglas Gregor81b747b2009-09-17 21:32:03 +00003229 bool EnteringContext) {
3230 if (!SS.getScopeRep() || !CodeCompleter)
3231 return;
3232
Douglas Gregor86d9a522009-09-21 16:56:56 +00003233 DeclContext *Ctx = computeDeclContext(SS, EnteringContext);
3234 if (!Ctx)
3235 return;
Douglas Gregord1cd31a2009-12-11 18:28:39 +00003236
3237 // Try to instantiate any non-dependent declaration contexts before
3238 // we look in them.
John McCall77bb1aa2010-05-01 00:40:08 +00003239 if (!isDependentScopeSpecifier(SS) && RequireCompleteDeclContext(SS, Ctx))
Douglas Gregord1cd31a2009-12-11 18:28:39 +00003240 return;
3241
Douglas Gregor86d9a522009-09-21 16:56:56 +00003242 ResultBuilder Results(*this);
Douglas Gregor86d9a522009-09-21 16:56:56 +00003243
Douglas Gregorf6961522010-08-27 21:18:54 +00003244 Results.EnterNewScope();
Douglas Gregor86d9a522009-09-21 16:56:56 +00003245 // The "template" keyword can follow "::" in the grammar, but only
3246 // put it into the grammar if the nested-name-specifier is dependent.
3247 NestedNameSpecifier *NNS = (NestedNameSpecifier *)SS.getScopeRep();
3248 if (!Results.empty() && NNS->isDependent())
Douglas Gregora4477812010-01-14 16:01:26 +00003249 Results.AddResult("template");
Douglas Gregorf6961522010-08-27 21:18:54 +00003250
3251 // Add calls to overridden virtual functions, if there are any.
3252 //
3253 // FIXME: This isn't wonderful, because we don't know whether we're actually
3254 // in a context that permits expressions. This is a general issue with
3255 // qualified-id completions.
3256 if (!EnteringContext)
3257 MaybeAddOverrideCalls(*this, Ctx, Results);
3258 Results.ExitScope();
Douglas Gregor86d9a522009-09-21 16:56:56 +00003259
Douglas Gregorf6961522010-08-27 21:18:54 +00003260 CodeCompletionDeclConsumer Consumer(Results, CurContext);
3261 LookupVisibleDecls(Ctx, LookupOrdinaryName, Consumer);
3262
Douglas Gregore6b1bb62010-08-11 21:23:17 +00003263 HandleCodeCompleteResults(this, CodeCompleter,
Douglas Gregorf6961522010-08-27 21:18:54 +00003264 CodeCompletionContext::CCC_Name,
Douglas Gregore6b1bb62010-08-11 21:23:17 +00003265 Results.data(),Results.size());
Douglas Gregor81b747b2009-09-17 21:32:03 +00003266}
Douglas Gregor49f40bd2009-09-18 19:03:04 +00003267
3268void Sema::CodeCompleteUsing(Scope *S) {
3269 if (!CodeCompleter)
3270 return;
3271
Douglas Gregor86d9a522009-09-21 16:56:56 +00003272 ResultBuilder Results(*this, &ResultBuilder::IsNestedNameSpecifier);
Douglas Gregor8e0a0e42009-09-22 23:31:26 +00003273 Results.EnterNewScope();
Douglas Gregor86d9a522009-09-21 16:56:56 +00003274
3275 // If we aren't in class scope, we could see the "namespace" keyword.
3276 if (!S->isClassScope())
John McCall0a2c5e22010-08-25 06:19:51 +00003277 Results.AddResult(CodeCompletionResult("namespace"));
Douglas Gregor86d9a522009-09-21 16:56:56 +00003278
3279 // After "using", we can see anything that would start a
3280 // nested-name-specifier.
Douglas Gregor5d2fc402010-01-14 03:27:13 +00003281 CodeCompletionDeclConsumer Consumer(Results, CurContext);
Douglas Gregor8071e422010-08-15 06:18:01 +00003282 LookupVisibleDecls(S, LookupOrdinaryName, Consumer,
3283 CodeCompleter->includeGlobals());
Douglas Gregor8e0a0e42009-09-22 23:31:26 +00003284 Results.ExitScope();
Douglas Gregor86d9a522009-09-21 16:56:56 +00003285
Douglas Gregore6b1bb62010-08-11 21:23:17 +00003286 HandleCodeCompleteResults(this, CodeCompleter,
3287 CodeCompletionContext::CCC_Other,
3288 Results.data(),Results.size());
Douglas Gregor49f40bd2009-09-18 19:03:04 +00003289}
3290
3291void Sema::CodeCompleteUsingDirective(Scope *S) {
3292 if (!CodeCompleter)
3293 return;
3294
Douglas Gregor86d9a522009-09-21 16:56:56 +00003295 // After "using namespace", we expect to see a namespace name or namespace
3296 // alias.
3297 ResultBuilder Results(*this, &ResultBuilder::IsNamespaceOrAlias);
Douglas Gregor8e0a0e42009-09-22 23:31:26 +00003298 Results.EnterNewScope();
Douglas Gregor5d2fc402010-01-14 03:27:13 +00003299 CodeCompletionDeclConsumer Consumer(Results, CurContext);
Douglas Gregor8071e422010-08-15 06:18:01 +00003300 LookupVisibleDecls(S, LookupOrdinaryName, Consumer,
3301 CodeCompleter->includeGlobals());
Douglas Gregor8e0a0e42009-09-22 23:31:26 +00003302 Results.ExitScope();
Douglas Gregore6b1bb62010-08-11 21:23:17 +00003303 HandleCodeCompleteResults(this, CodeCompleter,
Douglas Gregor8071e422010-08-15 06:18:01 +00003304 CodeCompletionContext::CCC_Namespace,
Douglas Gregore6b1bb62010-08-11 21:23:17 +00003305 Results.data(),Results.size());
Douglas Gregor49f40bd2009-09-18 19:03:04 +00003306}
3307
3308void Sema::CodeCompleteNamespaceDecl(Scope *S) {
3309 if (!CodeCompleter)
3310 return;
3311
Douglas Gregor86d9a522009-09-21 16:56:56 +00003312 ResultBuilder Results(*this, &ResultBuilder::IsNamespace);
3313 DeclContext *Ctx = (DeclContext *)S->getEntity();
3314 if (!S->getParent())
3315 Ctx = Context.getTranslationUnitDecl();
3316
3317 if (Ctx && Ctx->isFileContext()) {
3318 // We only want to see those namespaces that have already been defined
3319 // within this scope, because its likely that the user is creating an
3320 // extended namespace declaration. Keep track of the most recent
3321 // definition of each namespace.
3322 std::map<NamespaceDecl *, NamespaceDecl *> OrigToLatest;
3323 for (DeclContext::specific_decl_iterator<NamespaceDecl>
3324 NS(Ctx->decls_begin()), NSEnd(Ctx->decls_end());
3325 NS != NSEnd; ++NS)
3326 OrigToLatest[NS->getOriginalNamespace()] = *NS;
3327
3328 // Add the most recent definition (or extended definition) of each
3329 // namespace to the list of results.
Douglas Gregor8e0a0e42009-09-22 23:31:26 +00003330 Results.EnterNewScope();
Douglas Gregor86d9a522009-09-21 16:56:56 +00003331 for (std::map<NamespaceDecl *, NamespaceDecl *>::iterator
3332 NS = OrigToLatest.begin(), NSEnd = OrigToLatest.end();
3333 NS != NSEnd; ++NS)
John McCall0a2c5e22010-08-25 06:19:51 +00003334 Results.AddResult(CodeCompletionResult(NS->second, 0),
Douglas Gregor608300b2010-01-14 16:14:35 +00003335 CurContext, 0, false);
Douglas Gregor8e0a0e42009-09-22 23:31:26 +00003336 Results.ExitScope();
Douglas Gregor86d9a522009-09-21 16:56:56 +00003337 }
3338
Douglas Gregore6b1bb62010-08-11 21:23:17 +00003339 HandleCodeCompleteResults(this, CodeCompleter,
3340 CodeCompletionContext::CCC_Other,
3341 Results.data(),Results.size());
Douglas Gregor49f40bd2009-09-18 19:03:04 +00003342}
3343
3344void Sema::CodeCompleteNamespaceAliasDecl(Scope *S) {
3345 if (!CodeCompleter)
3346 return;
3347
Douglas Gregor86d9a522009-09-21 16:56:56 +00003348 // After "namespace", we expect to see a namespace or alias.
3349 ResultBuilder Results(*this, &ResultBuilder::IsNamespaceOrAlias);
Douglas Gregor5d2fc402010-01-14 03:27:13 +00003350 CodeCompletionDeclConsumer Consumer(Results, CurContext);
Douglas Gregor8071e422010-08-15 06:18:01 +00003351 LookupVisibleDecls(S, LookupOrdinaryName, Consumer,
3352 CodeCompleter->includeGlobals());
Douglas Gregore6b1bb62010-08-11 21:23:17 +00003353 HandleCodeCompleteResults(this, CodeCompleter,
Douglas Gregor8071e422010-08-15 06:18:01 +00003354 CodeCompletionContext::CCC_Namespace,
Douglas Gregore6b1bb62010-08-11 21:23:17 +00003355 Results.data(),Results.size());
Douglas Gregor49f40bd2009-09-18 19:03:04 +00003356}
3357
Douglas Gregored8d3222009-09-18 20:05:18 +00003358void Sema::CodeCompleteOperatorName(Scope *S) {
3359 if (!CodeCompleter)
3360 return;
Douglas Gregor86d9a522009-09-21 16:56:56 +00003361
John McCall0a2c5e22010-08-25 06:19:51 +00003362 typedef CodeCompletionResult Result;
Douglas Gregor86d9a522009-09-21 16:56:56 +00003363 ResultBuilder Results(*this, &ResultBuilder::IsType);
Douglas Gregor8e0a0e42009-09-22 23:31:26 +00003364 Results.EnterNewScope();
Douglas Gregored8d3222009-09-18 20:05:18 +00003365
Douglas Gregor86d9a522009-09-21 16:56:56 +00003366 // Add the names of overloadable operators.
3367#define OVERLOADED_OPERATOR(Name,Spelling,Token,Unary,Binary,MemberOnly) \
3368 if (std::strcmp(Spelling, "?")) \
Douglas Gregora4477812010-01-14 16:01:26 +00003369 Results.AddResult(Result(Spelling));
Douglas Gregor86d9a522009-09-21 16:56:56 +00003370#include "clang/Basic/OperatorKinds.def"
3371
3372 // Add any type names visible from the current scope
Douglas Gregor45bcd432010-01-14 03:21:49 +00003373 Results.allowNestedNameSpecifiers();
Douglas Gregor5d2fc402010-01-14 03:27:13 +00003374 CodeCompletionDeclConsumer Consumer(Results, CurContext);
Douglas Gregor8071e422010-08-15 06:18:01 +00003375 LookupVisibleDecls(S, LookupOrdinaryName, Consumer,
3376 CodeCompleter->includeGlobals());
Douglas Gregor86d9a522009-09-21 16:56:56 +00003377
3378 // Add any type specifiers
Douglas Gregorbca403c2010-01-13 23:51:12 +00003379 AddTypeSpecifierResults(getLangOptions(), Results);
Douglas Gregor8e0a0e42009-09-22 23:31:26 +00003380 Results.ExitScope();
Douglas Gregor86d9a522009-09-21 16:56:56 +00003381
Douglas Gregore6b1bb62010-08-11 21:23:17 +00003382 HandleCodeCompleteResults(this, CodeCompleter,
Douglas Gregor8071e422010-08-15 06:18:01 +00003383 CodeCompletionContext::CCC_Type,
Douglas Gregore6b1bb62010-08-11 21:23:17 +00003384 Results.data(),Results.size());
Douglas Gregored8d3222009-09-18 20:05:18 +00003385}
Douglas Gregor49f40bd2009-09-18 19:03:04 +00003386
Douglas Gregor0133f522010-08-28 00:00:50 +00003387void Sema::CodeCompleteConstructorInitializer(Decl *ConstructorD,
3388 CXXBaseOrMemberInitializer** Initializers,
3389 unsigned NumInitializers) {
3390 CXXConstructorDecl *Constructor
3391 = static_cast<CXXConstructorDecl *>(ConstructorD);
3392 if (!Constructor)
3393 return;
3394
3395 ResultBuilder Results(*this);
3396 Results.EnterNewScope();
3397
3398 // Fill in any already-initialized fields or base classes.
3399 llvm::SmallPtrSet<FieldDecl *, 4> InitializedFields;
3400 llvm::SmallPtrSet<CanQualType, 4> InitializedBases;
3401 for (unsigned I = 0; I != NumInitializers; ++I) {
3402 if (Initializers[I]->isBaseInitializer())
3403 InitializedBases.insert(
3404 Context.getCanonicalType(QualType(Initializers[I]->getBaseClass(), 0)));
3405 else
3406 InitializedFields.insert(cast<FieldDecl>(Initializers[I]->getMember()));
3407 }
3408
3409 // Add completions for base classes.
Douglas Gregor0c431c82010-08-29 19:27:27 +00003410 bool SawLastInitializer = (NumInitializers == 0);
Douglas Gregor0133f522010-08-28 00:00:50 +00003411 CXXRecordDecl *ClassDecl = Constructor->getParent();
3412 for (CXXRecordDecl::base_class_iterator Base = ClassDecl->bases_begin(),
3413 BaseEnd = ClassDecl->bases_end();
3414 Base != BaseEnd; ++Base) {
Douglas Gregor0c431c82010-08-29 19:27:27 +00003415 if (!InitializedBases.insert(Context.getCanonicalType(Base->getType()))) {
3416 SawLastInitializer
3417 = NumInitializers > 0 &&
3418 Initializers[NumInitializers - 1]->isBaseInitializer() &&
3419 Context.hasSameUnqualifiedType(Base->getType(),
3420 QualType(Initializers[NumInitializers - 1]->getBaseClass(), 0));
Douglas Gregor0133f522010-08-28 00:00:50 +00003421 continue;
Douglas Gregor0c431c82010-08-29 19:27:27 +00003422 }
Douglas Gregor0133f522010-08-28 00:00:50 +00003423
3424 CodeCompletionString *Pattern = new CodeCompletionString;
3425 Pattern->AddTypedTextChunk(
3426 Base->getType().getAsString(Context.PrintingPolicy));
3427 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
3428 Pattern->AddPlaceholderChunk("args");
3429 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
Douglas Gregor0c431c82010-08-29 19:27:27 +00003430 Results.AddResult(CodeCompletionResult(Pattern,
3431 SawLastInitializer? CCP_NextInitializer
3432 : CCP_MemberDeclaration));
3433 SawLastInitializer = false;
Douglas Gregor0133f522010-08-28 00:00:50 +00003434 }
3435
3436 // Add completions for virtual base classes.
3437 for (CXXRecordDecl::base_class_iterator Base = ClassDecl->vbases_begin(),
3438 BaseEnd = ClassDecl->vbases_end();
3439 Base != BaseEnd; ++Base) {
Douglas Gregor0c431c82010-08-29 19:27:27 +00003440 if (!InitializedBases.insert(Context.getCanonicalType(Base->getType()))) {
3441 SawLastInitializer
3442 = NumInitializers > 0 &&
3443 Initializers[NumInitializers - 1]->isBaseInitializer() &&
3444 Context.hasSameUnqualifiedType(Base->getType(),
3445 QualType(Initializers[NumInitializers - 1]->getBaseClass(), 0));
Douglas Gregor0133f522010-08-28 00:00:50 +00003446 continue;
Douglas Gregor0c431c82010-08-29 19:27:27 +00003447 }
Douglas Gregor0133f522010-08-28 00:00:50 +00003448
3449 CodeCompletionString *Pattern = new CodeCompletionString;
3450 Pattern->AddTypedTextChunk(
3451 Base->getType().getAsString(Context.PrintingPolicy));
3452 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
3453 Pattern->AddPlaceholderChunk("args");
3454 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
Douglas Gregor0c431c82010-08-29 19:27:27 +00003455 Results.AddResult(CodeCompletionResult(Pattern,
3456 SawLastInitializer? CCP_NextInitializer
3457 : CCP_MemberDeclaration));
3458 SawLastInitializer = false;
Douglas Gregor0133f522010-08-28 00:00:50 +00003459 }
3460
3461 // Add completions for members.
3462 for (CXXRecordDecl::field_iterator Field = ClassDecl->field_begin(),
3463 FieldEnd = ClassDecl->field_end();
3464 Field != FieldEnd; ++Field) {
Douglas Gregor0c431c82010-08-29 19:27:27 +00003465 if (!InitializedFields.insert(cast<FieldDecl>(Field->getCanonicalDecl()))) {
3466 SawLastInitializer
3467 = NumInitializers > 0 &&
3468 Initializers[NumInitializers - 1]->isMemberInitializer() &&
3469 Initializers[NumInitializers - 1]->getMember() == *Field;
Douglas Gregor0133f522010-08-28 00:00:50 +00003470 continue;
Douglas Gregor0c431c82010-08-29 19:27:27 +00003471 }
Douglas Gregor0133f522010-08-28 00:00:50 +00003472
3473 if (!Field->getDeclName())
3474 continue;
3475
3476 CodeCompletionString *Pattern = new CodeCompletionString;
3477 Pattern->AddTypedTextChunk(Field->getIdentifier()->getName());
3478 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
3479 Pattern->AddPlaceholderChunk("args");
3480 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
Douglas Gregor0c431c82010-08-29 19:27:27 +00003481 Results.AddResult(CodeCompletionResult(Pattern,
3482 SawLastInitializer? CCP_NextInitializer
Douglas Gregora67e03f2010-09-09 21:42:20 +00003483 : CCP_MemberDeclaration,
3484 CXCursor_MemberRef));
Douglas Gregor0c431c82010-08-29 19:27:27 +00003485 SawLastInitializer = false;
Douglas Gregor0133f522010-08-28 00:00:50 +00003486 }
3487 Results.ExitScope();
3488
3489 HandleCodeCompleteResults(this, CodeCompleter,
3490 CodeCompletionContext::CCC_Name,
3491 Results.data(), Results.size());
3492}
3493
Douglas Gregorb6ac2452010-01-13 21:24:21 +00003494// Macro that expands to @Keyword or Keyword, depending on whether NeedAt is
3495// true or false.
3496#define OBJC_AT_KEYWORD_NAME(NeedAt,Keyword) NeedAt? "@" #Keyword : #Keyword
Douglas Gregorbca403c2010-01-13 23:51:12 +00003497static void AddObjCImplementationResults(const LangOptions &LangOpts,
Douglas Gregorb6ac2452010-01-13 21:24:21 +00003498 ResultBuilder &Results,
3499 bool NeedAt) {
John McCall0a2c5e22010-08-25 06:19:51 +00003500 typedef CodeCompletionResult Result;
Douglas Gregorb6ac2452010-01-13 21:24:21 +00003501 // Since we have an implementation, we can end it.
Douglas Gregora4477812010-01-14 16:01:26 +00003502 Results.AddResult(Result(OBJC_AT_KEYWORD_NAME(NeedAt,end)));
Douglas Gregorb6ac2452010-01-13 21:24:21 +00003503
3504 CodeCompletionString *Pattern = 0;
3505 if (LangOpts.ObjC2) {
3506 // @dynamic
3507 Pattern = new CodeCompletionString;
3508 Pattern->AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt,dynamic));
3509 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
3510 Pattern->AddPlaceholderChunk("property");
Douglas Gregora4477812010-01-14 16:01:26 +00003511 Results.AddResult(Result(Pattern));
Douglas Gregorb6ac2452010-01-13 21:24:21 +00003512
3513 // @synthesize
3514 Pattern = new CodeCompletionString;
3515 Pattern->AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt,synthesize));
3516 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
3517 Pattern->AddPlaceholderChunk("property");
Douglas Gregora4477812010-01-14 16:01:26 +00003518 Results.AddResult(Result(Pattern));
Douglas Gregorb6ac2452010-01-13 21:24:21 +00003519 }
3520}
3521
Douglas Gregorbca403c2010-01-13 23:51:12 +00003522static void AddObjCInterfaceResults(const LangOptions &LangOpts,
Douglas Gregorb6ac2452010-01-13 21:24:21 +00003523 ResultBuilder &Results,
3524 bool NeedAt) {
John McCall0a2c5e22010-08-25 06:19:51 +00003525 typedef CodeCompletionResult Result;
Douglas Gregorb6ac2452010-01-13 21:24:21 +00003526
3527 // Since we have an interface or protocol, we can end it.
Douglas Gregora4477812010-01-14 16:01:26 +00003528 Results.AddResult(Result(OBJC_AT_KEYWORD_NAME(NeedAt,end)));
Douglas Gregorb6ac2452010-01-13 21:24:21 +00003529
3530 if (LangOpts.ObjC2) {
3531 // @property
Douglas Gregora4477812010-01-14 16:01:26 +00003532 Results.AddResult(Result(OBJC_AT_KEYWORD_NAME(NeedAt,property)));
Douglas Gregorb6ac2452010-01-13 21:24:21 +00003533
3534 // @required
Douglas Gregora4477812010-01-14 16:01:26 +00003535 Results.AddResult(Result(OBJC_AT_KEYWORD_NAME(NeedAt,required)));
Douglas Gregorb6ac2452010-01-13 21:24:21 +00003536
3537 // @optional
Douglas Gregora4477812010-01-14 16:01:26 +00003538 Results.AddResult(Result(OBJC_AT_KEYWORD_NAME(NeedAt,optional)));
Douglas Gregorb6ac2452010-01-13 21:24:21 +00003539 }
3540}
3541
Douglas Gregorbca403c2010-01-13 23:51:12 +00003542static void AddObjCTopLevelResults(ResultBuilder &Results, bool NeedAt) {
John McCall0a2c5e22010-08-25 06:19:51 +00003543 typedef CodeCompletionResult Result;
Douglas Gregorb6ac2452010-01-13 21:24:21 +00003544 CodeCompletionString *Pattern = 0;
3545
3546 // @class name ;
3547 Pattern = new CodeCompletionString;
3548 Pattern->AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt,class));
3549 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
Douglas Gregorc8bddde2010-05-28 00:22:41 +00003550 Pattern->AddPlaceholderChunk("name");
Douglas Gregora4477812010-01-14 16:01:26 +00003551 Results.AddResult(Result(Pattern));
Douglas Gregorb6ac2452010-01-13 21:24:21 +00003552
Douglas Gregorc8bddde2010-05-28 00:22:41 +00003553 if (Results.includeCodePatterns()) {
3554 // @interface name
3555 // FIXME: Could introduce the whole pattern, including superclasses and
3556 // such.
3557 Pattern = new CodeCompletionString;
3558 Pattern->AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt,interface));
3559 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
3560 Pattern->AddPlaceholderChunk("class");
3561 Results.AddResult(Result(Pattern));
Douglas Gregorb6ac2452010-01-13 21:24:21 +00003562
Douglas Gregorc8bddde2010-05-28 00:22:41 +00003563 // @protocol name
3564 Pattern = new CodeCompletionString;
3565 Pattern->AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt,protocol));
3566 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
3567 Pattern->AddPlaceholderChunk("protocol");
3568 Results.AddResult(Result(Pattern));
3569
3570 // @implementation name
3571 Pattern = new CodeCompletionString;
3572 Pattern->AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt,implementation));
3573 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
3574 Pattern->AddPlaceholderChunk("class");
3575 Results.AddResult(Result(Pattern));
3576 }
Douglas Gregorb6ac2452010-01-13 21:24:21 +00003577
3578 // @compatibility_alias name
3579 Pattern = new CodeCompletionString;
3580 Pattern->AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt,compatibility_alias));
3581 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
3582 Pattern->AddPlaceholderChunk("alias");
3583 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
3584 Pattern->AddPlaceholderChunk("class");
Douglas Gregora4477812010-01-14 16:01:26 +00003585 Results.AddResult(Result(Pattern));
Douglas Gregorb6ac2452010-01-13 21:24:21 +00003586}
3587
John McCalld226f652010-08-21 09:40:31 +00003588void Sema::CodeCompleteObjCAtDirective(Scope *S, Decl *ObjCImpDecl,
Douglas Gregorc464ae82009-12-07 09:27:33 +00003589 bool InInterface) {
John McCall0a2c5e22010-08-25 06:19:51 +00003590 typedef CodeCompletionResult Result;
Douglas Gregorc464ae82009-12-07 09:27:33 +00003591 ResultBuilder Results(*this);
3592 Results.EnterNewScope();
Douglas Gregorb6ac2452010-01-13 21:24:21 +00003593 if (ObjCImpDecl)
Douglas Gregorbca403c2010-01-13 23:51:12 +00003594 AddObjCImplementationResults(getLangOptions(), Results, false);
Douglas Gregorb6ac2452010-01-13 21:24:21 +00003595 else if (InInterface)
Douglas Gregorbca403c2010-01-13 23:51:12 +00003596 AddObjCInterfaceResults(getLangOptions(), Results, false);
Douglas Gregorb6ac2452010-01-13 21:24:21 +00003597 else
Douglas Gregorbca403c2010-01-13 23:51:12 +00003598 AddObjCTopLevelResults(Results, false);
Douglas Gregorc464ae82009-12-07 09:27:33 +00003599 Results.ExitScope();
Douglas Gregore6b1bb62010-08-11 21:23:17 +00003600 HandleCodeCompleteResults(this, CodeCompleter,
3601 CodeCompletionContext::CCC_Other,
3602 Results.data(),Results.size());
Douglas Gregorc464ae82009-12-07 09:27:33 +00003603}
3604
Douglas Gregorbca403c2010-01-13 23:51:12 +00003605static void AddObjCExpressionResults(ResultBuilder &Results, bool NeedAt) {
John McCall0a2c5e22010-08-25 06:19:51 +00003606 typedef CodeCompletionResult Result;
Douglas Gregor9a0c85e2009-12-07 09:51:25 +00003607 CodeCompletionString *Pattern = 0;
3608
3609 // @encode ( type-name )
3610 Pattern = new CodeCompletionString;
Douglas Gregorb6ac2452010-01-13 21:24:21 +00003611 Pattern->AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt,encode));
Douglas Gregor9a0c85e2009-12-07 09:51:25 +00003612 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
3613 Pattern->AddPlaceholderChunk("type-name");
3614 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
Douglas Gregora4477812010-01-14 16:01:26 +00003615 Results.AddResult(Result(Pattern));
Douglas Gregor9a0c85e2009-12-07 09:51:25 +00003616
3617 // @protocol ( protocol-name )
3618 Pattern = new CodeCompletionString;
Douglas Gregorb6ac2452010-01-13 21:24:21 +00003619 Pattern->AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt,protocol));
Douglas Gregor9a0c85e2009-12-07 09:51:25 +00003620 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
3621 Pattern->AddPlaceholderChunk("protocol-name");
3622 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
Douglas Gregora4477812010-01-14 16:01:26 +00003623 Results.AddResult(Result(Pattern));
Douglas Gregor9a0c85e2009-12-07 09:51:25 +00003624
3625 // @selector ( selector )
3626 Pattern = new CodeCompletionString;
Douglas Gregorb6ac2452010-01-13 21:24:21 +00003627 Pattern->AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt,selector));
Douglas Gregor9a0c85e2009-12-07 09:51:25 +00003628 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
3629 Pattern->AddPlaceholderChunk("selector");
3630 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
Douglas Gregora4477812010-01-14 16:01:26 +00003631 Results.AddResult(Result(Pattern));
Douglas Gregor9a0c85e2009-12-07 09:51:25 +00003632}
3633
Douglas Gregorbca403c2010-01-13 23:51:12 +00003634static void AddObjCStatementResults(ResultBuilder &Results, bool NeedAt) {
John McCall0a2c5e22010-08-25 06:19:51 +00003635 typedef CodeCompletionResult Result;
Douglas Gregor9a0c85e2009-12-07 09:51:25 +00003636 CodeCompletionString *Pattern = 0;
Douglas Gregorb6ac2452010-01-13 21:24:21 +00003637
Douglas Gregorc8bddde2010-05-28 00:22:41 +00003638 if (Results.includeCodePatterns()) {
3639 // @try { statements } @catch ( declaration ) { statements } @finally
3640 // { statements }
3641 Pattern = new CodeCompletionString;
3642 Pattern->AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt,try));
3643 Pattern->AddChunk(CodeCompletionString::CK_LeftBrace);
3644 Pattern->AddPlaceholderChunk("statements");
3645 Pattern->AddChunk(CodeCompletionString::CK_RightBrace);
3646 Pattern->AddTextChunk("@catch");
3647 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
3648 Pattern->AddPlaceholderChunk("parameter");
3649 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
3650 Pattern->AddChunk(CodeCompletionString::CK_LeftBrace);
3651 Pattern->AddPlaceholderChunk("statements");
3652 Pattern->AddChunk(CodeCompletionString::CK_RightBrace);
3653 Pattern->AddTextChunk("@finally");
3654 Pattern->AddChunk(CodeCompletionString::CK_LeftBrace);
3655 Pattern->AddPlaceholderChunk("statements");
3656 Pattern->AddChunk(CodeCompletionString::CK_RightBrace);
3657 Results.AddResult(Result(Pattern));
3658 }
Douglas Gregorb6ac2452010-01-13 21:24:21 +00003659
Douglas Gregor9a0c85e2009-12-07 09:51:25 +00003660 // @throw
3661 Pattern = new CodeCompletionString;
Douglas Gregorb6ac2452010-01-13 21:24:21 +00003662 Pattern->AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt,throw));
Douglas Gregor834389b2010-01-12 06:38:28 +00003663 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
Douglas Gregor9a0c85e2009-12-07 09:51:25 +00003664 Pattern->AddPlaceholderChunk("expression");
Douglas Gregora4477812010-01-14 16:01:26 +00003665 Results.AddResult(Result(Pattern));
Douglas Gregorb6ac2452010-01-13 21:24:21 +00003666
Douglas Gregorc8bddde2010-05-28 00:22:41 +00003667 if (Results.includeCodePatterns()) {
3668 // @synchronized ( expression ) { statements }
3669 Pattern = new CodeCompletionString;
3670 Pattern->AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt,synchronized));
3671 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
3672 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
3673 Pattern->AddPlaceholderChunk("expression");
3674 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
3675 Pattern->AddChunk(CodeCompletionString::CK_LeftBrace);
3676 Pattern->AddPlaceholderChunk("statements");
3677 Pattern->AddChunk(CodeCompletionString::CK_RightBrace);
3678 Results.AddResult(Result(Pattern));
3679 }
Douglas Gregorb6ac2452010-01-13 21:24:21 +00003680}
Douglas Gregor9a0c85e2009-12-07 09:51:25 +00003681
Douglas Gregorbca403c2010-01-13 23:51:12 +00003682static void AddObjCVisibilityResults(const LangOptions &LangOpts,
Douglas Gregorc38c3e12010-01-13 21:54:15 +00003683 ResultBuilder &Results,
3684 bool NeedAt) {
John McCall0a2c5e22010-08-25 06:19:51 +00003685 typedef CodeCompletionResult Result;
Douglas Gregora4477812010-01-14 16:01:26 +00003686 Results.AddResult(Result(OBJC_AT_KEYWORD_NAME(NeedAt,private)));
3687 Results.AddResult(Result(OBJC_AT_KEYWORD_NAME(NeedAt,protected)));
3688 Results.AddResult(Result(OBJC_AT_KEYWORD_NAME(NeedAt,public)));
Douglas Gregorc38c3e12010-01-13 21:54:15 +00003689 if (LangOpts.ObjC2)
Douglas Gregora4477812010-01-14 16:01:26 +00003690 Results.AddResult(Result(OBJC_AT_KEYWORD_NAME(NeedAt,package)));
Douglas Gregorc38c3e12010-01-13 21:54:15 +00003691}
3692
3693void Sema::CodeCompleteObjCAtVisibility(Scope *S) {
3694 ResultBuilder Results(*this);
3695 Results.EnterNewScope();
Douglas Gregorbca403c2010-01-13 23:51:12 +00003696 AddObjCVisibilityResults(getLangOptions(), Results, false);
Douglas Gregorc38c3e12010-01-13 21:54:15 +00003697 Results.ExitScope();
Douglas Gregore6b1bb62010-08-11 21:23:17 +00003698 HandleCodeCompleteResults(this, CodeCompleter,
3699 CodeCompletionContext::CCC_Other,
3700 Results.data(),Results.size());
Douglas Gregorc38c3e12010-01-13 21:54:15 +00003701}
3702
3703void Sema::CodeCompleteObjCAtStatement(Scope *S) {
Douglas Gregorb6ac2452010-01-13 21:24:21 +00003704 ResultBuilder Results(*this);
3705 Results.EnterNewScope();
Douglas Gregorbca403c2010-01-13 23:51:12 +00003706 AddObjCStatementResults(Results, false);
3707 AddObjCExpressionResults(Results, false);
Douglas Gregor9a0c85e2009-12-07 09:51:25 +00003708 Results.ExitScope();
Douglas Gregore6b1bb62010-08-11 21:23:17 +00003709 HandleCodeCompleteResults(this, CodeCompleter,
3710 CodeCompletionContext::CCC_Other,
3711 Results.data(),Results.size());
Douglas Gregor9a0c85e2009-12-07 09:51:25 +00003712}
3713
3714void Sema::CodeCompleteObjCAtExpression(Scope *S) {
3715 ResultBuilder Results(*this);
3716 Results.EnterNewScope();
Douglas Gregorbca403c2010-01-13 23:51:12 +00003717 AddObjCExpressionResults(Results, false);
Douglas Gregor9a0c85e2009-12-07 09:51:25 +00003718 Results.ExitScope();
Douglas Gregore6b1bb62010-08-11 21:23:17 +00003719 HandleCodeCompleteResults(this, CodeCompleter,
3720 CodeCompletionContext::CCC_Other,
3721 Results.data(),Results.size());
Douglas Gregor9a0c85e2009-12-07 09:51:25 +00003722}
3723
Douglas Gregor988358f2009-11-19 00:14:45 +00003724/// \brief Determine whether the addition of the given flag to an Objective-C
3725/// property's attributes will cause a conflict.
3726static bool ObjCPropertyFlagConflicts(unsigned Attributes, unsigned NewFlag) {
3727 // Check if we've already added this flag.
3728 if (Attributes & NewFlag)
3729 return true;
3730
3731 Attributes |= NewFlag;
3732
3733 // Check for collisions with "readonly".
3734 if ((Attributes & ObjCDeclSpec::DQ_PR_readonly) &&
3735 (Attributes & (ObjCDeclSpec::DQ_PR_readwrite |
3736 ObjCDeclSpec::DQ_PR_assign |
3737 ObjCDeclSpec::DQ_PR_copy |
3738 ObjCDeclSpec::DQ_PR_retain)))
3739 return true;
3740
3741 // Check for more than one of { assign, copy, retain }.
3742 unsigned AssignCopyRetMask = Attributes & (ObjCDeclSpec::DQ_PR_assign |
3743 ObjCDeclSpec::DQ_PR_copy |
3744 ObjCDeclSpec::DQ_PR_retain);
3745 if (AssignCopyRetMask &&
3746 AssignCopyRetMask != ObjCDeclSpec::DQ_PR_assign &&
3747 AssignCopyRetMask != ObjCDeclSpec::DQ_PR_copy &&
3748 AssignCopyRetMask != ObjCDeclSpec::DQ_PR_retain)
3749 return true;
3750
3751 return false;
3752}
3753
Douglas Gregora93b1082009-11-18 23:08:07 +00003754void Sema::CodeCompleteObjCPropertyFlags(Scope *S, ObjCDeclSpec &ODS) {
Steve Naroffece8e712009-10-08 21:55:05 +00003755 if (!CodeCompleter)
3756 return;
Douglas Gregord3c68542009-11-19 01:08:35 +00003757
Steve Naroffece8e712009-10-08 21:55:05 +00003758 unsigned Attributes = ODS.getPropertyAttributes();
3759
John McCall0a2c5e22010-08-25 06:19:51 +00003760 typedef CodeCompletionResult Result;
Steve Naroffece8e712009-10-08 21:55:05 +00003761 ResultBuilder Results(*this);
3762 Results.EnterNewScope();
Douglas Gregor988358f2009-11-19 00:14:45 +00003763 if (!ObjCPropertyFlagConflicts(Attributes, ObjCDeclSpec::DQ_PR_readonly))
John McCall0a2c5e22010-08-25 06:19:51 +00003764 Results.AddResult(CodeCompletionResult("readonly"));
Douglas Gregor988358f2009-11-19 00:14:45 +00003765 if (!ObjCPropertyFlagConflicts(Attributes, ObjCDeclSpec::DQ_PR_assign))
John McCall0a2c5e22010-08-25 06:19:51 +00003766 Results.AddResult(CodeCompletionResult("assign"));
Douglas Gregor988358f2009-11-19 00:14:45 +00003767 if (!ObjCPropertyFlagConflicts(Attributes, ObjCDeclSpec::DQ_PR_readwrite))
John McCall0a2c5e22010-08-25 06:19:51 +00003768 Results.AddResult(CodeCompletionResult("readwrite"));
Douglas Gregor988358f2009-11-19 00:14:45 +00003769 if (!ObjCPropertyFlagConflicts(Attributes, ObjCDeclSpec::DQ_PR_retain))
John McCall0a2c5e22010-08-25 06:19:51 +00003770 Results.AddResult(CodeCompletionResult("retain"));
Douglas Gregor988358f2009-11-19 00:14:45 +00003771 if (!ObjCPropertyFlagConflicts(Attributes, ObjCDeclSpec::DQ_PR_copy))
John McCall0a2c5e22010-08-25 06:19:51 +00003772 Results.AddResult(CodeCompletionResult("copy"));
Douglas Gregor988358f2009-11-19 00:14:45 +00003773 if (!ObjCPropertyFlagConflicts(Attributes, ObjCDeclSpec::DQ_PR_nonatomic))
John McCall0a2c5e22010-08-25 06:19:51 +00003774 Results.AddResult(CodeCompletionResult("nonatomic"));
Douglas Gregor988358f2009-11-19 00:14:45 +00003775 if (!ObjCPropertyFlagConflicts(Attributes, ObjCDeclSpec::DQ_PR_setter)) {
Douglas Gregor54f01612009-11-19 00:01:57 +00003776 CodeCompletionString *Setter = new CodeCompletionString;
3777 Setter->AddTypedTextChunk("setter");
3778 Setter->AddTextChunk(" = ");
3779 Setter->AddPlaceholderChunk("method");
John McCall0a2c5e22010-08-25 06:19:51 +00003780 Results.AddResult(CodeCompletionResult(Setter));
Douglas Gregor54f01612009-11-19 00:01:57 +00003781 }
Douglas Gregor988358f2009-11-19 00:14:45 +00003782 if (!ObjCPropertyFlagConflicts(Attributes, ObjCDeclSpec::DQ_PR_getter)) {
Douglas Gregor54f01612009-11-19 00:01:57 +00003783 CodeCompletionString *Getter = new CodeCompletionString;
3784 Getter->AddTypedTextChunk("getter");
3785 Getter->AddTextChunk(" = ");
3786 Getter->AddPlaceholderChunk("method");
John McCall0a2c5e22010-08-25 06:19:51 +00003787 Results.AddResult(CodeCompletionResult(Getter));
Douglas Gregor54f01612009-11-19 00:01:57 +00003788 }
Steve Naroffece8e712009-10-08 21:55:05 +00003789 Results.ExitScope();
Douglas Gregore6b1bb62010-08-11 21:23:17 +00003790 HandleCodeCompleteResults(this, CodeCompleter,
3791 CodeCompletionContext::CCC_Other,
3792 Results.data(),Results.size());
Steve Naroffece8e712009-10-08 21:55:05 +00003793}
Steve Naroffc4df6d22009-11-07 02:08:14 +00003794
Douglas Gregor4ad96852009-11-19 07:41:15 +00003795/// \brief Descripts the kind of Objective-C method that we want to find
3796/// via code completion.
3797enum ObjCMethodKind {
3798 MK_Any, //< Any kind of method, provided it means other specified criteria.
3799 MK_ZeroArgSelector, //< Zero-argument (unary) selector.
3800 MK_OneArgSelector //< One-argument selector.
3801};
3802
Douglas Gregor458433d2010-08-26 15:07:07 +00003803static bool isAcceptableObjCSelector(Selector Sel,
3804 ObjCMethodKind WantKind,
3805 IdentifierInfo **SelIdents,
3806 unsigned NumSelIdents) {
3807 if (NumSelIdents > Sel.getNumArgs())
3808 return false;
3809
3810 switch (WantKind) {
3811 case MK_Any: break;
3812 case MK_ZeroArgSelector: return Sel.isUnarySelector();
3813 case MK_OneArgSelector: return Sel.getNumArgs() == 1;
3814 }
3815
3816 for (unsigned I = 0; I != NumSelIdents; ++I)
3817 if (SelIdents[I] != Sel.getIdentifierInfoForSlot(I))
3818 return false;
3819
3820 return true;
3821}
3822
Douglas Gregor4ad96852009-11-19 07:41:15 +00003823static bool isAcceptableObjCMethod(ObjCMethodDecl *Method,
3824 ObjCMethodKind WantKind,
3825 IdentifierInfo **SelIdents,
3826 unsigned NumSelIdents) {
Douglas Gregor458433d2010-08-26 15:07:07 +00003827 return isAcceptableObjCSelector(Method->getSelector(), WantKind, SelIdents,
3828 NumSelIdents);
Douglas Gregor4ad96852009-11-19 07:41:15 +00003829}
Douglas Gregord36adf52010-09-16 16:06:31 +00003830
3831namespace {
3832 /// \brief A set of selectors, which is used to avoid introducing multiple
3833 /// completions with the same selector into the result set.
3834 typedef llvm::SmallPtrSet<Selector, 16> VisitedSelectorSet;
3835}
3836
Douglas Gregor36ecb042009-11-17 23:22:23 +00003837/// \brief Add all of the Objective-C methods in the given Objective-C
3838/// container to the set of results.
3839///
3840/// The container will be a class, protocol, category, or implementation of
3841/// any of the above. This mether will recurse to include methods from
3842/// the superclasses of classes along with their categories, protocols, and
3843/// implementations.
3844///
3845/// \param Container the container in which we'll look to find methods.
3846///
3847/// \param WantInstance whether to add instance methods (only); if false, this
3848/// routine will add factory methods (only).
3849///
3850/// \param CurContext the context in which we're performing the lookup that
3851/// finds methods.
3852///
3853/// \param Results the structure into which we'll add results.
3854static void AddObjCMethods(ObjCContainerDecl *Container,
3855 bool WantInstanceMethods,
Douglas Gregor4ad96852009-11-19 07:41:15 +00003856 ObjCMethodKind WantKind,
Douglas Gregord3c68542009-11-19 01:08:35 +00003857 IdentifierInfo **SelIdents,
3858 unsigned NumSelIdents,
Douglas Gregor36ecb042009-11-17 23:22:23 +00003859 DeclContext *CurContext,
Douglas Gregord36adf52010-09-16 16:06:31 +00003860 VisitedSelectorSet &Selectors,
Douglas Gregor408be5a2010-08-25 01:08:01 +00003861 ResultBuilder &Results,
3862 bool InOriginalClass = true) {
John McCall0a2c5e22010-08-25 06:19:51 +00003863 typedef CodeCompletionResult Result;
Douglas Gregor36ecb042009-11-17 23:22:23 +00003864 for (ObjCContainerDecl::method_iterator M = Container->meth_begin(),
3865 MEnd = Container->meth_end();
3866 M != MEnd; ++M) {
Douglas Gregord3c68542009-11-19 01:08:35 +00003867 if ((*M)->isInstanceMethod() == WantInstanceMethods) {
3868 // Check whether the selector identifiers we've been given are a
3869 // subset of the identifiers for this particular method.
Douglas Gregor4ad96852009-11-19 07:41:15 +00003870 if (!isAcceptableObjCMethod(*M, WantKind, SelIdents, NumSelIdents))
Douglas Gregord3c68542009-11-19 01:08:35 +00003871 continue;
Douglas Gregor4ad96852009-11-19 07:41:15 +00003872
Douglas Gregord36adf52010-09-16 16:06:31 +00003873 if (!Selectors.insert((*M)->getSelector()))
3874 continue;
3875
Douglas Gregord3c68542009-11-19 01:08:35 +00003876 Result R = Result(*M, 0);
3877 R.StartParameter = NumSelIdents;
Douglas Gregor4ad96852009-11-19 07:41:15 +00003878 R.AllParametersAreInformative = (WantKind != MK_Any);
Douglas Gregor408be5a2010-08-25 01:08:01 +00003879 if (!InOriginalClass)
3880 R.Priority += CCD_InBaseClass;
Douglas Gregord3c68542009-11-19 01:08:35 +00003881 Results.MaybeAddResult(R, CurContext);
3882 }
Douglas Gregor36ecb042009-11-17 23:22:23 +00003883 }
3884
Douglas Gregore396c7b2010-09-16 15:34:59 +00003885 // Visit the protocols of protocols.
3886 if (ObjCProtocolDecl *Protocol = dyn_cast<ObjCProtocolDecl>(Container)) {
3887 const ObjCList<ObjCProtocolDecl> &Protocols
3888 = Protocol->getReferencedProtocols();
3889 for (ObjCList<ObjCProtocolDecl>::iterator I = Protocols.begin(),
3890 E = Protocols.end();
3891 I != E; ++I)
3892 AddObjCMethods(*I, WantInstanceMethods, WantKind, SelIdents, NumSelIdents,
Douglas Gregord36adf52010-09-16 16:06:31 +00003893 CurContext, Selectors, Results, false);
Douglas Gregore396c7b2010-09-16 15:34:59 +00003894 }
3895
Douglas Gregor36ecb042009-11-17 23:22:23 +00003896 ObjCInterfaceDecl *IFace = dyn_cast<ObjCInterfaceDecl>(Container);
3897 if (!IFace)
3898 return;
3899
3900 // Add methods in protocols.
3901 const ObjCList<ObjCProtocolDecl> &Protocols= IFace->getReferencedProtocols();
3902 for (ObjCList<ObjCProtocolDecl>::iterator I = Protocols.begin(),
3903 E = Protocols.end();
3904 I != E; ++I)
Douglas Gregor4ad96852009-11-19 07:41:15 +00003905 AddObjCMethods(*I, WantInstanceMethods, WantKind, SelIdents, NumSelIdents,
Douglas Gregord36adf52010-09-16 16:06:31 +00003906 CurContext, Selectors, Results, false);
Douglas Gregor36ecb042009-11-17 23:22:23 +00003907
3908 // Add methods in categories.
3909 for (ObjCCategoryDecl *CatDecl = IFace->getCategoryList(); CatDecl;
3910 CatDecl = CatDecl->getNextClassCategory()) {
Douglas Gregor4ad96852009-11-19 07:41:15 +00003911 AddObjCMethods(CatDecl, WantInstanceMethods, WantKind, SelIdents,
Douglas Gregord36adf52010-09-16 16:06:31 +00003912 NumSelIdents, CurContext, Selectors, Results,
3913 InOriginalClass);
Douglas Gregor36ecb042009-11-17 23:22:23 +00003914
3915 // Add a categories protocol methods.
3916 const ObjCList<ObjCProtocolDecl> &Protocols
3917 = CatDecl->getReferencedProtocols();
3918 for (ObjCList<ObjCProtocolDecl>::iterator I = Protocols.begin(),
3919 E = Protocols.end();
3920 I != E; ++I)
Douglas Gregor4ad96852009-11-19 07:41:15 +00003921 AddObjCMethods(*I, WantInstanceMethods, WantKind, SelIdents,
Douglas Gregord36adf52010-09-16 16:06:31 +00003922 NumSelIdents, CurContext, Selectors, Results, false);
Douglas Gregor36ecb042009-11-17 23:22:23 +00003923
3924 // Add methods in category implementations.
3925 if (ObjCCategoryImplDecl *Impl = CatDecl->getImplementation())
Douglas Gregor4ad96852009-11-19 07:41:15 +00003926 AddObjCMethods(Impl, WantInstanceMethods, WantKind, SelIdents,
Douglas Gregord36adf52010-09-16 16:06:31 +00003927 NumSelIdents, CurContext, Selectors, Results,
3928 InOriginalClass);
Douglas Gregor36ecb042009-11-17 23:22:23 +00003929 }
3930
3931 // Add methods in superclass.
3932 if (IFace->getSuperClass())
Douglas Gregor4ad96852009-11-19 07:41:15 +00003933 AddObjCMethods(IFace->getSuperClass(), WantInstanceMethods, WantKind,
Douglas Gregord36adf52010-09-16 16:06:31 +00003934 SelIdents, NumSelIdents, CurContext, Selectors, Results,
3935 false);
Douglas Gregor36ecb042009-11-17 23:22:23 +00003936
3937 // Add methods in our implementation, if any.
3938 if (ObjCImplementationDecl *Impl = IFace->getImplementation())
Douglas Gregor4ad96852009-11-19 07:41:15 +00003939 AddObjCMethods(Impl, WantInstanceMethods, WantKind, SelIdents,
Douglas Gregord36adf52010-09-16 16:06:31 +00003940 NumSelIdents, CurContext, Selectors, Results,
3941 InOriginalClass);
Douglas Gregor4ad96852009-11-19 07:41:15 +00003942}
3943
3944
John McCalld226f652010-08-21 09:40:31 +00003945void Sema::CodeCompleteObjCPropertyGetter(Scope *S, Decl *ClassDecl,
3946 Decl **Methods,
Douglas Gregor4ad96852009-11-19 07:41:15 +00003947 unsigned NumMethods) {
John McCall0a2c5e22010-08-25 06:19:51 +00003948 typedef CodeCompletionResult Result;
Douglas Gregor4ad96852009-11-19 07:41:15 +00003949
3950 // Try to find the interface where getters might live.
John McCalld226f652010-08-21 09:40:31 +00003951 ObjCInterfaceDecl *Class = dyn_cast_or_null<ObjCInterfaceDecl>(ClassDecl);
Douglas Gregor4ad96852009-11-19 07:41:15 +00003952 if (!Class) {
3953 if (ObjCCategoryDecl *Category
John McCalld226f652010-08-21 09:40:31 +00003954 = dyn_cast_or_null<ObjCCategoryDecl>(ClassDecl))
Douglas Gregor4ad96852009-11-19 07:41:15 +00003955 Class = Category->getClassInterface();
3956
3957 if (!Class)
3958 return;
3959 }
3960
3961 // Find all of the potential getters.
3962 ResultBuilder Results(*this);
3963 Results.EnterNewScope();
3964
3965 // FIXME: We need to do this because Objective-C methods don't get
3966 // pushed into DeclContexts early enough. Argh!
3967 for (unsigned I = 0; I != NumMethods; ++I) {
3968 if (ObjCMethodDecl *Method
John McCalld226f652010-08-21 09:40:31 +00003969 = dyn_cast_or_null<ObjCMethodDecl>(Methods[I]))
Douglas Gregor4ad96852009-11-19 07:41:15 +00003970 if (Method->isInstanceMethod() &&
3971 isAcceptableObjCMethod(Method, MK_ZeroArgSelector, 0, 0)) {
3972 Result R = Result(Method, 0);
3973 R.AllParametersAreInformative = true;
3974 Results.MaybeAddResult(R, CurContext);
3975 }
3976 }
3977
Douglas Gregord36adf52010-09-16 16:06:31 +00003978 VisitedSelectorSet Selectors;
3979 AddObjCMethods(Class, true, MK_ZeroArgSelector, 0, 0, CurContext, Selectors,
3980 Results);
Douglas Gregor4ad96852009-11-19 07:41:15 +00003981 Results.ExitScope();
Douglas Gregore6b1bb62010-08-11 21:23:17 +00003982 HandleCodeCompleteResults(this, CodeCompleter,
3983 CodeCompletionContext::CCC_Other,
3984 Results.data(),Results.size());
Douglas Gregor4ad96852009-11-19 07:41:15 +00003985}
3986
John McCalld226f652010-08-21 09:40:31 +00003987void Sema::CodeCompleteObjCPropertySetter(Scope *S, Decl *ObjCImplDecl,
3988 Decl **Methods,
Douglas Gregor4ad96852009-11-19 07:41:15 +00003989 unsigned NumMethods) {
John McCall0a2c5e22010-08-25 06:19:51 +00003990 typedef CodeCompletionResult Result;
Douglas Gregor4ad96852009-11-19 07:41:15 +00003991
3992 // Try to find the interface where setters might live.
3993 ObjCInterfaceDecl *Class
John McCalld226f652010-08-21 09:40:31 +00003994 = dyn_cast_or_null<ObjCInterfaceDecl>(ObjCImplDecl);
Douglas Gregor4ad96852009-11-19 07:41:15 +00003995 if (!Class) {
3996 if (ObjCCategoryDecl *Category
John McCalld226f652010-08-21 09:40:31 +00003997 = dyn_cast_or_null<ObjCCategoryDecl>(ObjCImplDecl))
Douglas Gregor4ad96852009-11-19 07:41:15 +00003998 Class = Category->getClassInterface();
3999
4000 if (!Class)
4001 return;
4002 }
4003
4004 // Find all of the potential getters.
4005 ResultBuilder Results(*this);
4006 Results.EnterNewScope();
4007
4008 // FIXME: We need to do this because Objective-C methods don't get
4009 // pushed into DeclContexts early enough. Argh!
4010 for (unsigned I = 0; I != NumMethods; ++I) {
4011 if (ObjCMethodDecl *Method
John McCalld226f652010-08-21 09:40:31 +00004012 = dyn_cast_or_null<ObjCMethodDecl>(Methods[I]))
Douglas Gregor4ad96852009-11-19 07:41:15 +00004013 if (Method->isInstanceMethod() &&
4014 isAcceptableObjCMethod(Method, MK_OneArgSelector, 0, 0)) {
4015 Result R = Result(Method, 0);
4016 R.AllParametersAreInformative = true;
4017 Results.MaybeAddResult(R, CurContext);
4018 }
4019 }
4020
Douglas Gregord36adf52010-09-16 16:06:31 +00004021 VisitedSelectorSet Selectors;
4022 AddObjCMethods(Class, true, MK_OneArgSelector, 0, 0, CurContext,
4023 Selectors, Results);
Douglas Gregor4ad96852009-11-19 07:41:15 +00004024
4025 Results.ExitScope();
Douglas Gregore6b1bb62010-08-11 21:23:17 +00004026 HandleCodeCompleteResults(this, CodeCompleter,
4027 CodeCompletionContext::CCC_Other,
4028 Results.data(),Results.size());
Douglas Gregor36ecb042009-11-17 23:22:23 +00004029}
4030
Douglas Gregord32b0222010-08-24 01:06:58 +00004031void Sema::CodeCompleteObjCPassingType(Scope *S, ObjCDeclSpec &DS) {
John McCall0a2c5e22010-08-25 06:19:51 +00004032 typedef CodeCompletionResult Result;
Douglas Gregord32b0222010-08-24 01:06:58 +00004033 ResultBuilder Results(*this);
4034 Results.EnterNewScope();
4035
4036 // Add context-sensitive, Objective-C parameter-passing keywords.
4037 bool AddedInOut = false;
4038 if ((DS.getObjCDeclQualifier() &
4039 (ObjCDeclSpec::DQ_In | ObjCDeclSpec::DQ_Inout)) == 0) {
4040 Results.AddResult("in");
4041 Results.AddResult("inout");
4042 AddedInOut = true;
4043 }
4044 if ((DS.getObjCDeclQualifier() &
4045 (ObjCDeclSpec::DQ_Out | ObjCDeclSpec::DQ_Inout)) == 0) {
4046 Results.AddResult("out");
4047 if (!AddedInOut)
4048 Results.AddResult("inout");
4049 }
4050 if ((DS.getObjCDeclQualifier() &
4051 (ObjCDeclSpec::DQ_Bycopy | ObjCDeclSpec::DQ_Byref |
4052 ObjCDeclSpec::DQ_Oneway)) == 0) {
4053 Results.AddResult("bycopy");
4054 Results.AddResult("byref");
4055 Results.AddResult("oneway");
4056 }
4057
4058 // Add various builtin type names and specifiers.
4059 AddOrdinaryNameResults(PCC_Type, S, *this, Results);
4060 Results.ExitScope();
4061
4062 // Add the various type names
4063 Results.setFilter(&ResultBuilder::IsOrdinaryNonValueName);
4064 CodeCompletionDeclConsumer Consumer(Results, CurContext);
4065 LookupVisibleDecls(S, LookupOrdinaryName, Consumer,
4066 CodeCompleter->includeGlobals());
4067
4068 if (CodeCompleter->includeMacros())
4069 AddMacroResults(PP, Results);
4070
4071 HandleCodeCompleteResults(this, CodeCompleter,
4072 CodeCompletionContext::CCC_Type,
4073 Results.data(), Results.size());
4074}
4075
Douglas Gregor22f56992010-04-06 19:22:33 +00004076/// \brief When we have an expression with type "id", we may assume
4077/// that it has some more-specific class type based on knowledge of
4078/// common uses of Objective-C. This routine returns that class type,
4079/// or NULL if no better result could be determined.
4080static ObjCInterfaceDecl *GetAssumedMessageSendExprType(Expr *E) {
Douglas Gregor78edf512010-09-15 16:23:04 +00004081 ObjCMessageExpr *Msg = dyn_cast_or_null<ObjCMessageExpr>(E);
Douglas Gregor22f56992010-04-06 19:22:33 +00004082 if (!Msg)
4083 return 0;
4084
4085 Selector Sel = Msg->getSelector();
4086 if (Sel.isNull())
4087 return 0;
4088
4089 IdentifierInfo *Id = Sel.getIdentifierInfoForSlot(0);
4090 if (!Id)
4091 return 0;
4092
4093 ObjCMethodDecl *Method = Msg->getMethodDecl();
4094 if (!Method)
4095 return 0;
4096
4097 // Determine the class that we're sending the message to.
Douglas Gregor04badcf2010-04-21 00:45:42 +00004098 ObjCInterfaceDecl *IFace = 0;
4099 switch (Msg->getReceiverKind()) {
4100 case ObjCMessageExpr::Class:
John McCallc12c5bb2010-05-15 11:32:37 +00004101 if (const ObjCObjectType *ObjType
4102 = Msg->getClassReceiver()->getAs<ObjCObjectType>())
4103 IFace = ObjType->getInterface();
Douglas Gregor04badcf2010-04-21 00:45:42 +00004104 break;
4105
4106 case ObjCMessageExpr::Instance: {
4107 QualType T = Msg->getInstanceReceiver()->getType();
4108 if (const ObjCObjectPointerType *Ptr = T->getAs<ObjCObjectPointerType>())
4109 IFace = Ptr->getInterfaceDecl();
4110 break;
4111 }
4112
4113 case ObjCMessageExpr::SuperInstance:
4114 case ObjCMessageExpr::SuperClass:
4115 break;
Douglas Gregor22f56992010-04-06 19:22:33 +00004116 }
4117
4118 if (!IFace)
4119 return 0;
4120
4121 ObjCInterfaceDecl *Super = IFace->getSuperClass();
4122 if (Method->isInstanceMethod())
4123 return llvm::StringSwitch<ObjCInterfaceDecl *>(Id->getName())
4124 .Case("retain", IFace)
4125 .Case("autorelease", IFace)
4126 .Case("copy", IFace)
4127 .Case("copyWithZone", IFace)
4128 .Case("mutableCopy", IFace)
4129 .Case("mutableCopyWithZone", IFace)
4130 .Case("awakeFromCoder", IFace)
4131 .Case("replacementObjectFromCoder", IFace)
4132 .Case("class", IFace)
4133 .Case("classForCoder", IFace)
4134 .Case("superclass", Super)
4135 .Default(0);
4136
4137 return llvm::StringSwitch<ObjCInterfaceDecl *>(Id->getName())
4138 .Case("new", IFace)
4139 .Case("alloc", IFace)
4140 .Case("allocWithZone", IFace)
4141 .Case("class", IFace)
4142 .Case("superclass", Super)
4143 .Default(0);
4144}
4145
Douglas Gregor03d8aec2010-08-27 15:10:57 +00004146// Add a special completion for a message send to "super", which fills in the
4147// most likely case of forwarding all of our arguments to the superclass
4148// function.
4149///
4150/// \param S The semantic analysis object.
4151///
4152/// \param S NeedSuperKeyword Whether we need to prefix this completion with
4153/// the "super" keyword. Otherwise, we just need to provide the arguments.
4154///
4155/// \param SelIdents The identifiers in the selector that have already been
4156/// provided as arguments for a send to "super".
4157///
4158/// \param NumSelIdents The number of identifiers in \p SelIdents.
4159///
4160/// \param Results The set of results to augment.
4161///
4162/// \returns the Objective-C method declaration that would be invoked by
4163/// this "super" completion. If NULL, no completion was added.
4164static ObjCMethodDecl *AddSuperSendCompletion(Sema &S, bool NeedSuperKeyword,
4165 IdentifierInfo **SelIdents,
4166 unsigned NumSelIdents,
4167 ResultBuilder &Results) {
4168 ObjCMethodDecl *CurMethod = S.getCurMethodDecl();
4169 if (!CurMethod)
4170 return 0;
4171
4172 ObjCInterfaceDecl *Class = CurMethod->getClassInterface();
4173 if (!Class)
4174 return 0;
4175
4176 // Try to find a superclass method with the same selector.
4177 ObjCMethodDecl *SuperMethod = 0;
4178 while ((Class = Class->getSuperClass()) && !SuperMethod)
4179 SuperMethod = Class->getMethod(CurMethod->getSelector(),
4180 CurMethod->isInstanceMethod());
4181
4182 if (!SuperMethod)
4183 return 0;
4184
4185 // Check whether the superclass method has the same signature.
4186 if (CurMethod->param_size() != SuperMethod->param_size() ||
4187 CurMethod->isVariadic() != SuperMethod->isVariadic())
4188 return 0;
4189
4190 for (ObjCMethodDecl::param_iterator CurP = CurMethod->param_begin(),
4191 CurPEnd = CurMethod->param_end(),
4192 SuperP = SuperMethod->param_begin();
4193 CurP != CurPEnd; ++CurP, ++SuperP) {
4194 // Make sure the parameter types are compatible.
4195 if (!S.Context.hasSameUnqualifiedType((*CurP)->getType(),
4196 (*SuperP)->getType()))
4197 return 0;
4198
4199 // Make sure we have a parameter name to forward!
4200 if (!(*CurP)->getIdentifier())
4201 return 0;
4202 }
4203
4204 // We have a superclass method. Now, form the send-to-super completion.
4205 CodeCompletionString *Pattern = new CodeCompletionString;
4206
4207 // Give this completion a return type.
4208 AddResultTypeChunk(S.Context, SuperMethod, Pattern);
4209
4210 // If we need the "super" keyword, add it (plus some spacing).
4211 if (NeedSuperKeyword) {
4212 Pattern->AddTypedTextChunk("super");
4213 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
4214 }
4215
4216 Selector Sel = CurMethod->getSelector();
4217 if (Sel.isUnarySelector()) {
4218 if (NeedSuperKeyword)
4219 Pattern->AddTextChunk(Sel.getIdentifierInfoForSlot(0)->getName());
4220 else
4221 Pattern->AddTypedTextChunk(Sel.getIdentifierInfoForSlot(0)->getName());
4222 } else {
4223 ObjCMethodDecl::param_iterator CurP = CurMethod->param_begin();
4224 for (unsigned I = 0, N = Sel.getNumArgs(); I != N; ++I, ++CurP) {
4225 if (I > NumSelIdents)
4226 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
4227
4228 if (I < NumSelIdents)
4229 Pattern->AddInformativeChunk(
4230 Sel.getIdentifierInfoForSlot(I)->getName().str() + ":");
4231 else if (NeedSuperKeyword || I > NumSelIdents) {
4232 Pattern->AddTextChunk(
4233 Sel.getIdentifierInfoForSlot(I)->getName().str() + ":");
4234 Pattern->AddPlaceholderChunk((*CurP)->getIdentifier()->getName());
4235 } else {
4236 Pattern->AddTypedTextChunk(
4237 Sel.getIdentifierInfoForSlot(I)->getName().str() + ":");
4238 Pattern->AddPlaceholderChunk((*CurP)->getIdentifier()->getName());
4239 }
4240 }
4241 }
4242
4243 Results.AddResult(CodeCompletionResult(Pattern, CCP_SuperCompletion,
4244 SuperMethod->isInstanceMethod()
4245 ? CXCursor_ObjCInstanceMethodDecl
4246 : CXCursor_ObjCClassMethodDecl));
4247 return SuperMethod;
4248}
4249
Douglas Gregor8e254cf2010-05-27 23:06:34 +00004250void Sema::CodeCompleteObjCMessageReceiver(Scope *S) {
John McCall0a2c5e22010-08-25 06:19:51 +00004251 typedef CodeCompletionResult Result;
Douglas Gregor8e254cf2010-05-27 23:06:34 +00004252 ResultBuilder Results(*this);
4253
4254 // Find anything that looks like it could be a message receiver.
4255 Results.setFilter(&ResultBuilder::IsObjCMessageReceiver);
4256 CodeCompletionDeclConsumer Consumer(Results, CurContext);
4257 Results.EnterNewScope();
Douglas Gregor8071e422010-08-15 06:18:01 +00004258 LookupVisibleDecls(S, LookupOrdinaryName, Consumer,
4259 CodeCompleter->includeGlobals());
Douglas Gregor8e254cf2010-05-27 23:06:34 +00004260
4261 // If we are in an Objective-C method inside a class that has a superclass,
4262 // add "super" as an option.
4263 if (ObjCMethodDecl *Method = getCurMethodDecl())
4264 if (ObjCInterfaceDecl *Iface = Method->getClassInterface())
Douglas Gregor03d8aec2010-08-27 15:10:57 +00004265 if (Iface->getSuperClass()) {
Douglas Gregor8e254cf2010-05-27 23:06:34 +00004266 Results.AddResult(Result("super"));
Douglas Gregor03d8aec2010-08-27 15:10:57 +00004267
4268 AddSuperSendCompletion(*this, /*NeedSuperKeyword=*/true, 0, 0, Results);
4269 }
Douglas Gregor8e254cf2010-05-27 23:06:34 +00004270
4271 Results.ExitScope();
4272
4273 if (CodeCompleter->includeMacros())
4274 AddMacroResults(PP, Results);
Douglas Gregore6b1bb62010-08-11 21:23:17 +00004275 HandleCodeCompleteResults(this, CodeCompleter,
4276 CodeCompletionContext::CCC_ObjCMessageReceiver,
4277 Results.data(), Results.size());
Douglas Gregor8e254cf2010-05-27 23:06:34 +00004278
4279}
4280
Douglas Gregor2725ca82010-04-21 19:57:20 +00004281void Sema::CodeCompleteObjCSuperMessage(Scope *S, SourceLocation SuperLoc,
4282 IdentifierInfo **SelIdents,
4283 unsigned NumSelIdents) {
4284 ObjCInterfaceDecl *CDecl = 0;
4285 if (ObjCMethodDecl *CurMethod = getCurMethodDecl()) {
4286 // Figure out which interface we're in.
4287 CDecl = CurMethod->getClassInterface();
4288 if (!CDecl)
4289 return;
4290
4291 // Find the superclass of this class.
4292 CDecl = CDecl->getSuperClass();
4293 if (!CDecl)
4294 return;
4295
4296 if (CurMethod->isInstanceMethod()) {
4297 // We are inside an instance method, which means that the message
4298 // send [super ...] is actually calling an instance method on the
4299 // current object. Build the super expression and handle this like
4300 // an instance method.
4301 QualType SuperTy = Context.getObjCInterfaceType(CDecl);
4302 SuperTy = Context.getObjCObjectPointerType(SuperTy);
John McCall60d7b3a2010-08-24 06:29:42 +00004303 ExprResult Super
Douglas Gregor2725ca82010-04-21 19:57:20 +00004304 = Owned(new (Context) ObjCSuperExpr(SuperLoc, SuperTy));
4305 return CodeCompleteObjCInstanceMessage(S, (Expr *)Super.get(),
Douglas Gregor03d8aec2010-08-27 15:10:57 +00004306 SelIdents, NumSelIdents,
4307 /*IsSuper=*/true);
Douglas Gregor2725ca82010-04-21 19:57:20 +00004308 }
4309
4310 // Fall through to send to the superclass in CDecl.
4311 } else {
4312 // "super" may be the name of a type or variable. Figure out which
4313 // it is.
4314 IdentifierInfo *Super = &Context.Idents.get("super");
4315 NamedDecl *ND = LookupSingleName(S, Super, SuperLoc,
4316 LookupOrdinaryName);
4317 if ((CDecl = dyn_cast_or_null<ObjCInterfaceDecl>(ND))) {
4318 // "super" names an interface. Use it.
4319 } else if (TypeDecl *TD = dyn_cast_or_null<TypeDecl>(ND)) {
John McCallc12c5bb2010-05-15 11:32:37 +00004320 if (const ObjCObjectType *Iface
4321 = Context.getTypeDeclType(TD)->getAs<ObjCObjectType>())
4322 CDecl = Iface->getInterface();
Douglas Gregor2725ca82010-04-21 19:57:20 +00004323 } else if (ND && isa<UnresolvedUsingTypenameDecl>(ND)) {
4324 // "super" names an unresolved type; we can't be more specific.
4325 } else {
4326 // Assume that "super" names some kind of value and parse that way.
4327 CXXScopeSpec SS;
4328 UnqualifiedId id;
4329 id.setIdentifier(Super, SuperLoc);
John McCall60d7b3a2010-08-24 06:29:42 +00004330 ExprResult SuperExpr = ActOnIdExpression(S, SS, id, false, false);
Douglas Gregor2725ca82010-04-21 19:57:20 +00004331 return CodeCompleteObjCInstanceMessage(S, (Expr *)SuperExpr.get(),
4332 SelIdents, NumSelIdents);
4333 }
4334
4335 // Fall through
4336 }
4337
John McCallb3d87482010-08-24 05:47:05 +00004338 ParsedType Receiver;
Douglas Gregor2725ca82010-04-21 19:57:20 +00004339 if (CDecl)
John McCallb3d87482010-08-24 05:47:05 +00004340 Receiver = ParsedType::make(Context.getObjCInterfaceType(CDecl));
Douglas Gregor2725ca82010-04-21 19:57:20 +00004341 return CodeCompleteObjCClassMessage(S, Receiver, SelIdents,
Douglas Gregor03d8aec2010-08-27 15:10:57 +00004342 NumSelIdents, /*IsSuper=*/true);
Douglas Gregor2725ca82010-04-21 19:57:20 +00004343}
4344
Douglas Gregorc7b6d882010-09-16 15:14:18 +00004345static void AddClassMessageCompletions(Sema &SemaRef, Scope *S,
4346 ParsedType Receiver,
4347 IdentifierInfo **SelIdents,
4348 unsigned NumSelIdents,
4349 bool IsSuper,
4350 ResultBuilder &Results) {
John McCall0a2c5e22010-08-25 06:19:51 +00004351 typedef CodeCompletionResult Result;
Douglas Gregor24a069f2009-11-17 17:59:40 +00004352 ObjCInterfaceDecl *CDecl = 0;
Douglas Gregorc7b6d882010-09-16 15:14:18 +00004353
Douglas Gregor24a069f2009-11-17 17:59:40 +00004354 // If the given name refers to an interface type, retrieve the
4355 // corresponding declaration.
Douglas Gregor2725ca82010-04-21 19:57:20 +00004356 if (Receiver) {
Douglas Gregorc7b6d882010-09-16 15:14:18 +00004357 QualType T = SemaRef.GetTypeFromParser(Receiver, 0);
Douglas Gregor2725ca82010-04-21 19:57:20 +00004358 if (!T.isNull())
John McCallc12c5bb2010-05-15 11:32:37 +00004359 if (const ObjCObjectType *Interface = T->getAs<ObjCObjectType>())
4360 CDecl = Interface->getInterface();
Douglas Gregor24a069f2009-11-17 17:59:40 +00004361 }
Douglas Gregorc7b6d882010-09-16 15:14:18 +00004362
Douglas Gregor36ecb042009-11-17 23:22:23 +00004363 // Add all of the factory methods in this Objective-C class, its protocols,
4364 // superclasses, categories, implementation, etc.
Steve Naroffc4df6d22009-11-07 02:08:14 +00004365 Results.EnterNewScope();
Douglas Gregorc7b6d882010-09-16 15:14:18 +00004366
Douglas Gregor03d8aec2010-08-27 15:10:57 +00004367 // If this is a send-to-super, try to add the special "super" send
4368 // completion.
4369 if (IsSuper) {
4370 if (ObjCMethodDecl *SuperMethod
Douglas Gregorc7b6d882010-09-16 15:14:18 +00004371 = AddSuperSendCompletion(SemaRef, false, SelIdents, NumSelIdents,
4372 Results))
Douglas Gregor03d8aec2010-08-27 15:10:57 +00004373 Results.Ignore(SuperMethod);
4374 }
Douglas Gregorc7b6d882010-09-16 15:14:18 +00004375
Douglas Gregor265f7492010-08-27 15:29:55 +00004376 // If we're inside an Objective-C method definition, prefer its selector to
4377 // others.
Douglas Gregorc7b6d882010-09-16 15:14:18 +00004378 if (ObjCMethodDecl *CurMethod = SemaRef.getCurMethodDecl())
Douglas Gregor265f7492010-08-27 15:29:55 +00004379 Results.setPreferredSelector(CurMethod->getSelector());
Douglas Gregorc7b6d882010-09-16 15:14:18 +00004380
Douglas Gregord36adf52010-09-16 16:06:31 +00004381 VisitedSelectorSet Selectors;
Douglas Gregor13438f92010-04-06 16:40:00 +00004382 if (CDecl)
Douglas Gregorc7b6d882010-09-16 15:14:18 +00004383 AddObjCMethods(CDecl, false, MK_Any, SelIdents, NumSelIdents,
Douglas Gregord36adf52010-09-16 16:06:31 +00004384 SemaRef.CurContext, Selectors, Results);
Douglas Gregor2725ca82010-04-21 19:57:20 +00004385 else {
Douglas Gregor13438f92010-04-06 16:40:00 +00004386 // We're messaging "id" as a type; provide all class/factory methods.
Douglas Gregorc7b6d882010-09-16 15:14:18 +00004387
Douglas Gregor719770d2010-04-06 17:30:22 +00004388 // If we have an external source, load the entire class method
Sebastian Redl3c7f4132010-08-18 23:57:06 +00004389 // pool from the AST file.
Douglas Gregorc7b6d882010-09-16 15:14:18 +00004390 if (SemaRef.ExternalSource) {
4391 for (uint32_t I = 0,
4392 N = SemaRef.ExternalSource->GetNumExternalSelectors();
John McCall76bd1f32010-06-01 09:23:16 +00004393 I != N; ++I) {
Douglas Gregorc7b6d882010-09-16 15:14:18 +00004394 Selector Sel = SemaRef.ExternalSource->GetExternalSelector(I);
4395 if (Sel.isNull() || SemaRef.MethodPool.count(Sel))
Douglas Gregor719770d2010-04-06 17:30:22 +00004396 continue;
Douglas Gregorc7b6d882010-09-16 15:14:18 +00004397
4398 SemaRef.ReadMethodPool(Sel);
Douglas Gregor719770d2010-04-06 17:30:22 +00004399 }
4400 }
Douglas Gregorc7b6d882010-09-16 15:14:18 +00004401
4402 for (Sema::GlobalMethodPool::iterator M = SemaRef.MethodPool.begin(),
4403 MEnd = SemaRef.MethodPool.end();
Sebastian Redldb9d2142010-08-02 23:18:59 +00004404 M != MEnd; ++M) {
4405 for (ObjCMethodList *MethList = &M->second.second;
4406 MethList && MethList->Method;
Douglas Gregor13438f92010-04-06 16:40:00 +00004407 MethList = MethList->Next) {
4408 if (!isAcceptableObjCMethod(MethList->Method, MK_Any, SelIdents,
4409 NumSelIdents))
4410 continue;
Douglas Gregorc7b6d882010-09-16 15:14:18 +00004411
Douglas Gregor13438f92010-04-06 16:40:00 +00004412 Result R(MethList->Method, 0);
4413 R.StartParameter = NumSelIdents;
4414 R.AllParametersAreInformative = false;
Douglas Gregorc7b6d882010-09-16 15:14:18 +00004415 Results.MaybeAddResult(R, SemaRef.CurContext);
Douglas Gregor13438f92010-04-06 16:40:00 +00004416 }
4417 }
4418 }
Douglas Gregorc7b6d882010-09-16 15:14:18 +00004419
4420 Results.ExitScope();
4421}
Douglas Gregor13438f92010-04-06 16:40:00 +00004422
Douglas Gregorc7b6d882010-09-16 15:14:18 +00004423void Sema::CodeCompleteObjCClassMessage(Scope *S, ParsedType Receiver,
4424 IdentifierInfo **SelIdents,
4425 unsigned NumSelIdents,
4426 bool IsSuper) {
4427 ResultBuilder Results(*this);
4428 AddClassMessageCompletions(*this, S, Receiver, SelIdents, NumSelIdents, IsSuper,
4429 Results);
Douglas Gregore6b1bb62010-08-11 21:23:17 +00004430 HandleCodeCompleteResults(this, CodeCompleter,
4431 CodeCompletionContext::CCC_Other,
Douglas Gregor03d8aec2010-08-27 15:10:57 +00004432 Results.data(), Results.size());
Steve Naroffc4df6d22009-11-07 02:08:14 +00004433}
4434
Douglas Gregord3c68542009-11-19 01:08:35 +00004435void Sema::CodeCompleteObjCInstanceMessage(Scope *S, ExprTy *Receiver,
4436 IdentifierInfo **SelIdents,
Douglas Gregor03d8aec2010-08-27 15:10:57 +00004437 unsigned NumSelIdents,
4438 bool IsSuper) {
John McCall0a2c5e22010-08-25 06:19:51 +00004439 typedef CodeCompletionResult Result;
Steve Naroffc4df6d22009-11-07 02:08:14 +00004440
4441 Expr *RecExpr = static_cast<Expr *>(Receiver);
Steve Naroffc4df6d22009-11-07 02:08:14 +00004442
Douglas Gregor36ecb042009-11-17 23:22:23 +00004443 // If necessary, apply function/array conversion to the receiver.
4444 // C99 6.7.5.3p[7,8].
Douglas Gregor78edf512010-09-15 16:23:04 +00004445 if (RecExpr)
4446 DefaultFunctionArrayLvalueConversion(RecExpr);
4447 QualType ReceiverType = RecExpr? RecExpr->getType() : Context.getObjCIdType();
Steve Naroffc4df6d22009-11-07 02:08:14 +00004448
Douglas Gregor36ecb042009-11-17 23:22:23 +00004449 // Build the set of methods we can see.
4450 ResultBuilder Results(*this);
4451 Results.EnterNewScope();
Douglas Gregor22f56992010-04-06 19:22:33 +00004452
Douglas Gregor03d8aec2010-08-27 15:10:57 +00004453 // If this is a send-to-super, try to add the special "super" send
4454 // completion.
4455 if (IsSuper) {
4456 if (ObjCMethodDecl *SuperMethod
4457 = AddSuperSendCompletion(*this, false, SelIdents, NumSelIdents,
4458 Results))
4459 Results.Ignore(SuperMethod);
4460 }
4461
Douglas Gregor265f7492010-08-27 15:29:55 +00004462 // If we're inside an Objective-C method definition, prefer its selector to
4463 // others.
4464 if (ObjCMethodDecl *CurMethod = getCurMethodDecl())
4465 Results.setPreferredSelector(CurMethod->getSelector());
4466
Douglas Gregor22f56992010-04-06 19:22:33 +00004467 // If we're messaging an expression with type "id" or "Class", check
4468 // whether we know something special about the receiver that allows
4469 // us to assume a more-specific receiver type.
4470 if (ReceiverType->isObjCIdType() || ReceiverType->isObjCClassType())
4471 if (ObjCInterfaceDecl *IFace = GetAssumedMessageSendExprType(RecExpr))
4472 ReceiverType = Context.getObjCObjectPointerType(
4473 Context.getObjCInterfaceType(IFace));
Douglas Gregor36ecb042009-11-17 23:22:23 +00004474
Douglas Gregord36adf52010-09-16 16:06:31 +00004475 // Keep track of the selectors we've already added.
4476 VisitedSelectorSet Selectors;
4477
Douglas Gregorf74a4192009-11-18 00:06:18 +00004478 // Handle messages to Class. This really isn't a message to an instance
4479 // method, so we treat it the same way we would treat a message send to a
4480 // class method.
4481 if (ReceiverType->isObjCClassType() ||
4482 ReceiverType->isObjCQualifiedClassType()) {
4483 if (ObjCMethodDecl *CurMethod = getCurMethodDecl()) {
4484 if (ObjCInterfaceDecl *ClassDecl = CurMethod->getClassInterface())
Douglas Gregor4ad96852009-11-19 07:41:15 +00004485 AddObjCMethods(ClassDecl, false, MK_Any, SelIdents, NumSelIdents,
Douglas Gregord36adf52010-09-16 16:06:31 +00004486 CurContext, Selectors, Results);
Douglas Gregorf74a4192009-11-18 00:06:18 +00004487 }
4488 }
4489 // Handle messages to a qualified ID ("id<foo>").
4490 else if (const ObjCObjectPointerType *QualID
4491 = ReceiverType->getAsObjCQualifiedIdType()) {
4492 // Search protocols for instance methods.
4493 for (ObjCObjectPointerType::qual_iterator I = QualID->qual_begin(),
4494 E = QualID->qual_end();
4495 I != E; ++I)
Douglas Gregor4ad96852009-11-19 07:41:15 +00004496 AddObjCMethods(*I, true, MK_Any, SelIdents, NumSelIdents, CurContext,
Douglas Gregord36adf52010-09-16 16:06:31 +00004497 Selectors, Results);
Douglas Gregorf74a4192009-11-18 00:06:18 +00004498 }
4499 // Handle messages to a pointer to interface type.
4500 else if (const ObjCObjectPointerType *IFacePtr
4501 = ReceiverType->getAsObjCInterfacePointerType()) {
4502 // Search the class, its superclasses, etc., for instance methods.
Douglas Gregor4ad96852009-11-19 07:41:15 +00004503 AddObjCMethods(IFacePtr->getInterfaceDecl(), true, MK_Any, SelIdents,
Douglas Gregord36adf52010-09-16 16:06:31 +00004504 NumSelIdents, CurContext, Selectors, Results);
Douglas Gregorf74a4192009-11-18 00:06:18 +00004505
4506 // Search protocols for instance methods.
4507 for (ObjCObjectPointerType::qual_iterator I = IFacePtr->qual_begin(),
4508 E = IFacePtr->qual_end();
4509 I != E; ++I)
Douglas Gregor4ad96852009-11-19 07:41:15 +00004510 AddObjCMethods(*I, true, MK_Any, SelIdents, NumSelIdents, CurContext,
Douglas Gregord36adf52010-09-16 16:06:31 +00004511 Selectors, Results);
Douglas Gregorf74a4192009-11-18 00:06:18 +00004512 }
Douglas Gregor13438f92010-04-06 16:40:00 +00004513 // Handle messages to "id".
4514 else if (ReceiverType->isObjCIdType()) {
Douglas Gregor719770d2010-04-06 17:30:22 +00004515 // We're messaging "id", so provide all instance methods we know
4516 // about as code-completion results.
4517
4518 // If we have an external source, load the entire class method
Sebastian Redl3c7f4132010-08-18 23:57:06 +00004519 // pool from the AST file.
Douglas Gregor719770d2010-04-06 17:30:22 +00004520 if (ExternalSource) {
John McCall76bd1f32010-06-01 09:23:16 +00004521 for (uint32_t I = 0, N = ExternalSource->GetNumExternalSelectors();
4522 I != N; ++I) {
4523 Selector Sel = ExternalSource->GetExternalSelector(I);
Sebastian Redldb9d2142010-08-02 23:18:59 +00004524 if (Sel.isNull() || MethodPool.count(Sel))
Douglas Gregor719770d2010-04-06 17:30:22 +00004525 continue;
4526
Sebastian Redldb9d2142010-08-02 23:18:59 +00004527 ReadMethodPool(Sel);
Douglas Gregor719770d2010-04-06 17:30:22 +00004528 }
4529 }
4530
Sebastian Redldb9d2142010-08-02 23:18:59 +00004531 for (GlobalMethodPool::iterator M = MethodPool.begin(),
4532 MEnd = MethodPool.end();
4533 M != MEnd; ++M) {
4534 for (ObjCMethodList *MethList = &M->second.first;
4535 MethList && MethList->Method;
Douglas Gregor13438f92010-04-06 16:40:00 +00004536 MethList = MethList->Next) {
4537 if (!isAcceptableObjCMethod(MethList->Method, MK_Any, SelIdents,
4538 NumSelIdents))
4539 continue;
Douglas Gregord36adf52010-09-16 16:06:31 +00004540
4541 if (!Selectors.insert(MethList->Method->getSelector()))
4542 continue;
4543
Douglas Gregor13438f92010-04-06 16:40:00 +00004544 Result R(MethList->Method, 0);
4545 R.StartParameter = NumSelIdents;
4546 R.AllParametersAreInformative = false;
4547 Results.MaybeAddResult(R, CurContext);
4548 }
4549 }
4550 }
4551
Steve Naroffc4df6d22009-11-07 02:08:14 +00004552 Results.ExitScope();
Douglas Gregore6b1bb62010-08-11 21:23:17 +00004553 HandleCodeCompleteResults(this, CodeCompleter,
4554 CodeCompletionContext::CCC_Other,
4555 Results.data(),Results.size());
Steve Naroffc4df6d22009-11-07 02:08:14 +00004556}
Douglas Gregor55385fe2009-11-18 04:19:12 +00004557
Douglas Gregorfb629412010-08-23 21:17:50 +00004558void Sema::CodeCompleteObjCForCollection(Scope *S,
4559 DeclGroupPtrTy IterationVar) {
4560 CodeCompleteExpressionData Data;
4561 Data.ObjCCollection = true;
4562
4563 if (IterationVar.getAsOpaquePtr()) {
4564 DeclGroupRef DG = IterationVar.getAsVal<DeclGroupRef>();
4565 for (DeclGroupRef::iterator I = DG.begin(), End = DG.end(); I != End; ++I) {
4566 if (*I)
4567 Data.IgnoreDecls.push_back(*I);
4568 }
4569 }
4570
4571 CodeCompleteExpression(S, Data);
4572}
4573
Douglas Gregor458433d2010-08-26 15:07:07 +00004574void Sema::CodeCompleteObjCSelector(Scope *S, IdentifierInfo **SelIdents,
4575 unsigned NumSelIdents) {
4576 // If we have an external source, load the entire class method
4577 // pool from the AST file.
4578 if (ExternalSource) {
4579 for (uint32_t I = 0, N = ExternalSource->GetNumExternalSelectors();
4580 I != N; ++I) {
4581 Selector Sel = ExternalSource->GetExternalSelector(I);
4582 if (Sel.isNull() || MethodPool.count(Sel))
4583 continue;
4584
4585 ReadMethodPool(Sel);
4586 }
4587 }
4588
4589 ResultBuilder Results(*this);
4590 Results.EnterNewScope();
4591 for (GlobalMethodPool::iterator M = MethodPool.begin(),
4592 MEnd = MethodPool.end();
4593 M != MEnd; ++M) {
4594
4595 Selector Sel = M->first;
4596 if (!isAcceptableObjCSelector(Sel, MK_Any, SelIdents, NumSelIdents))
4597 continue;
4598
4599 CodeCompletionString *Pattern = new CodeCompletionString;
4600 if (Sel.isUnarySelector()) {
4601 Pattern->AddTypedTextChunk(Sel.getIdentifierInfoForSlot(0)->getName());
4602 Results.AddResult(Pattern);
4603 continue;
4604 }
4605
Douglas Gregor2d9e21f2010-08-26 16:46:39 +00004606 std::string Accumulator;
Douglas Gregor458433d2010-08-26 15:07:07 +00004607 for (unsigned I = 0, N = Sel.getNumArgs(); I != N; ++I) {
Douglas Gregor2d9e21f2010-08-26 16:46:39 +00004608 if (I == NumSelIdents) {
4609 if (!Accumulator.empty()) {
4610 Pattern->AddInformativeChunk(Accumulator);
4611 Accumulator.clear();
4612 }
4613 }
4614
4615 Accumulator += Sel.getIdentifierInfoForSlot(I)->getName().str();
4616 Accumulator += ':';
Douglas Gregor458433d2010-08-26 15:07:07 +00004617 }
Douglas Gregor2d9e21f2010-08-26 16:46:39 +00004618 Pattern->AddTypedTextChunk(Accumulator);
Douglas Gregor458433d2010-08-26 15:07:07 +00004619 Results.AddResult(Pattern);
4620 }
4621 Results.ExitScope();
4622
4623 HandleCodeCompleteResults(this, CodeCompleter,
4624 CodeCompletionContext::CCC_SelectorName,
4625 Results.data(), Results.size());
4626}
4627
Douglas Gregor55385fe2009-11-18 04:19:12 +00004628/// \brief Add all of the protocol declarations that we find in the given
4629/// (translation unit) context.
4630static void AddProtocolResults(DeclContext *Ctx, DeclContext *CurContext,
Douglas Gregor083128f2009-11-18 04:49:41 +00004631 bool OnlyForwardDeclarations,
Douglas Gregor55385fe2009-11-18 04:19:12 +00004632 ResultBuilder &Results) {
John McCall0a2c5e22010-08-25 06:19:51 +00004633 typedef CodeCompletionResult Result;
Douglas Gregor55385fe2009-11-18 04:19:12 +00004634
4635 for (DeclContext::decl_iterator D = Ctx->decls_begin(),
4636 DEnd = Ctx->decls_end();
4637 D != DEnd; ++D) {
4638 // Record any protocols we find.
4639 if (ObjCProtocolDecl *Proto = dyn_cast<ObjCProtocolDecl>(*D))
Douglas Gregor083128f2009-11-18 04:49:41 +00004640 if (!OnlyForwardDeclarations || Proto->isForwardDecl())
Douglas Gregor608300b2010-01-14 16:14:35 +00004641 Results.AddResult(Result(Proto, 0), CurContext, 0, false);
Douglas Gregor55385fe2009-11-18 04:19:12 +00004642
4643 // Record any forward-declared protocols we find.
4644 if (ObjCForwardProtocolDecl *Forward
4645 = dyn_cast<ObjCForwardProtocolDecl>(*D)) {
4646 for (ObjCForwardProtocolDecl::protocol_iterator
4647 P = Forward->protocol_begin(),
4648 PEnd = Forward->protocol_end();
4649 P != PEnd; ++P)
Douglas Gregor083128f2009-11-18 04:49:41 +00004650 if (!OnlyForwardDeclarations || (*P)->isForwardDecl())
Douglas Gregor608300b2010-01-14 16:14:35 +00004651 Results.AddResult(Result(*P, 0), CurContext, 0, false);
Douglas Gregor55385fe2009-11-18 04:19:12 +00004652 }
4653 }
4654}
4655
4656void Sema::CodeCompleteObjCProtocolReferences(IdentifierLocPair *Protocols,
4657 unsigned NumProtocols) {
4658 ResultBuilder Results(*this);
4659 Results.EnterNewScope();
4660
4661 // Tell the result set to ignore all of the protocols we have
4662 // already seen.
4663 for (unsigned I = 0; I != NumProtocols; ++I)
Douglas Gregorc83c6872010-04-15 22:33:43 +00004664 if (ObjCProtocolDecl *Protocol = LookupProtocol(Protocols[I].first,
4665 Protocols[I].second))
Douglas Gregor55385fe2009-11-18 04:19:12 +00004666 Results.Ignore(Protocol);
4667
4668 // Add all protocols.
Douglas Gregor083128f2009-11-18 04:49:41 +00004669 AddProtocolResults(Context.getTranslationUnitDecl(), CurContext, false,
4670 Results);
4671
4672 Results.ExitScope();
Douglas Gregore6b1bb62010-08-11 21:23:17 +00004673 HandleCodeCompleteResults(this, CodeCompleter,
4674 CodeCompletionContext::CCC_ObjCProtocolName,
4675 Results.data(),Results.size());
Douglas Gregor083128f2009-11-18 04:49:41 +00004676}
4677
4678void Sema::CodeCompleteObjCProtocolDecl(Scope *) {
4679 ResultBuilder Results(*this);
4680 Results.EnterNewScope();
4681
4682 // Add all protocols.
4683 AddProtocolResults(Context.getTranslationUnitDecl(), CurContext, true,
4684 Results);
Douglas Gregor55385fe2009-11-18 04:19:12 +00004685
4686 Results.ExitScope();
Douglas Gregore6b1bb62010-08-11 21:23:17 +00004687 HandleCodeCompleteResults(this, CodeCompleter,
4688 CodeCompletionContext::CCC_ObjCProtocolName,
4689 Results.data(),Results.size());
Douglas Gregor55385fe2009-11-18 04:19:12 +00004690}
Douglas Gregor3b49aca2009-11-18 16:26:39 +00004691
4692/// \brief Add all of the Objective-C interface declarations that we find in
4693/// the given (translation unit) context.
4694static void AddInterfaceResults(DeclContext *Ctx, DeclContext *CurContext,
4695 bool OnlyForwardDeclarations,
4696 bool OnlyUnimplemented,
4697 ResultBuilder &Results) {
John McCall0a2c5e22010-08-25 06:19:51 +00004698 typedef CodeCompletionResult Result;
Douglas Gregor3b49aca2009-11-18 16:26:39 +00004699
4700 for (DeclContext::decl_iterator D = Ctx->decls_begin(),
4701 DEnd = Ctx->decls_end();
4702 D != DEnd; ++D) {
Douglas Gregordeacbdc2010-08-11 12:19:30 +00004703 // Record any interfaces we find.
4704 if (ObjCInterfaceDecl *Class = dyn_cast<ObjCInterfaceDecl>(*D))
4705 if ((!OnlyForwardDeclarations || Class->isForwardDecl()) &&
4706 (!OnlyUnimplemented || !Class->getImplementation()))
4707 Results.AddResult(Result(Class, 0), CurContext, 0, false);
Douglas Gregor3b49aca2009-11-18 16:26:39 +00004708
4709 // Record any forward-declared interfaces we find.
4710 if (ObjCClassDecl *Forward = dyn_cast<ObjCClassDecl>(*D)) {
4711 for (ObjCClassDecl::iterator C = Forward->begin(), CEnd = Forward->end();
Douglas Gregordeacbdc2010-08-11 12:19:30 +00004712 C != CEnd; ++C)
4713 if ((!OnlyForwardDeclarations || C->getInterface()->isForwardDecl()) &&
4714 (!OnlyUnimplemented || !C->getInterface()->getImplementation()))
4715 Results.AddResult(Result(C->getInterface(), 0), CurContext,
Douglas Gregor608300b2010-01-14 16:14:35 +00004716 0, false);
Douglas Gregor3b49aca2009-11-18 16:26:39 +00004717 }
4718 }
4719}
4720
4721void Sema::CodeCompleteObjCInterfaceDecl(Scope *S) {
4722 ResultBuilder Results(*this);
4723 Results.EnterNewScope();
4724
4725 // Add all classes.
4726 AddInterfaceResults(Context.getTranslationUnitDecl(), CurContext, true,
4727 false, Results);
4728
4729 Results.ExitScope();
Douglas Gregore6b1bb62010-08-11 21:23:17 +00004730 HandleCodeCompleteResults(this, CodeCompleter,
4731 CodeCompletionContext::CCC_Other,
4732 Results.data(),Results.size());
Douglas Gregor3b49aca2009-11-18 16:26:39 +00004733}
4734
Douglas Gregorc83c6872010-04-15 22:33:43 +00004735void Sema::CodeCompleteObjCSuperclass(Scope *S, IdentifierInfo *ClassName,
4736 SourceLocation ClassNameLoc) {
Douglas Gregor3b49aca2009-11-18 16:26:39 +00004737 ResultBuilder Results(*this);
4738 Results.EnterNewScope();
4739
4740 // Make sure that we ignore the class we're currently defining.
4741 NamedDecl *CurClass
Douglas Gregorc83c6872010-04-15 22:33:43 +00004742 = LookupSingleName(TUScope, ClassName, ClassNameLoc, LookupOrdinaryName);
Douglas Gregor33ced0b2009-11-18 19:08:43 +00004743 if (CurClass && isa<ObjCInterfaceDecl>(CurClass))
Douglas Gregor3b49aca2009-11-18 16:26:39 +00004744 Results.Ignore(CurClass);
4745
4746 // Add all classes.
4747 AddInterfaceResults(Context.getTranslationUnitDecl(), CurContext, false,
4748 false, Results);
4749
4750 Results.ExitScope();
Douglas Gregore6b1bb62010-08-11 21:23:17 +00004751 HandleCodeCompleteResults(this, CodeCompleter,
4752 CodeCompletionContext::CCC_Other,
4753 Results.data(),Results.size());
Douglas Gregor3b49aca2009-11-18 16:26:39 +00004754}
4755
4756void Sema::CodeCompleteObjCImplementationDecl(Scope *S) {
4757 ResultBuilder Results(*this);
4758 Results.EnterNewScope();
4759
4760 // Add all unimplemented classes.
4761 AddInterfaceResults(Context.getTranslationUnitDecl(), CurContext, false,
4762 true, Results);
4763
4764 Results.ExitScope();
Douglas Gregore6b1bb62010-08-11 21:23:17 +00004765 HandleCodeCompleteResults(this, CodeCompleter,
4766 CodeCompletionContext::CCC_Other,
4767 Results.data(),Results.size());
Douglas Gregor3b49aca2009-11-18 16:26:39 +00004768}
Douglas Gregor33ced0b2009-11-18 19:08:43 +00004769
4770void Sema::CodeCompleteObjCInterfaceCategory(Scope *S,
Douglas Gregorc83c6872010-04-15 22:33:43 +00004771 IdentifierInfo *ClassName,
4772 SourceLocation ClassNameLoc) {
John McCall0a2c5e22010-08-25 06:19:51 +00004773 typedef CodeCompletionResult Result;
Douglas Gregor33ced0b2009-11-18 19:08:43 +00004774
4775 ResultBuilder Results(*this);
4776
4777 // Ignore any categories we find that have already been implemented by this
4778 // interface.
4779 llvm::SmallPtrSet<IdentifierInfo *, 16> CategoryNames;
4780 NamedDecl *CurClass
Douglas Gregorc83c6872010-04-15 22:33:43 +00004781 = LookupSingleName(TUScope, ClassName, ClassNameLoc, LookupOrdinaryName);
Douglas Gregor33ced0b2009-11-18 19:08:43 +00004782 if (ObjCInterfaceDecl *Class = dyn_cast_or_null<ObjCInterfaceDecl>(CurClass))
4783 for (ObjCCategoryDecl *Category = Class->getCategoryList(); Category;
4784 Category = Category->getNextClassCategory())
4785 CategoryNames.insert(Category->getIdentifier());
4786
4787 // Add all of the categories we know about.
4788 Results.EnterNewScope();
4789 TranslationUnitDecl *TU = Context.getTranslationUnitDecl();
4790 for (DeclContext::decl_iterator D = TU->decls_begin(),
4791 DEnd = TU->decls_end();
4792 D != DEnd; ++D)
4793 if (ObjCCategoryDecl *Category = dyn_cast<ObjCCategoryDecl>(*D))
4794 if (CategoryNames.insert(Category->getIdentifier()))
Douglas Gregor608300b2010-01-14 16:14:35 +00004795 Results.AddResult(Result(Category, 0), CurContext, 0, false);
Douglas Gregor33ced0b2009-11-18 19:08:43 +00004796 Results.ExitScope();
4797
Douglas Gregore6b1bb62010-08-11 21:23:17 +00004798 HandleCodeCompleteResults(this, CodeCompleter,
4799 CodeCompletionContext::CCC_Other,
4800 Results.data(),Results.size());
Douglas Gregor33ced0b2009-11-18 19:08:43 +00004801}
4802
4803void Sema::CodeCompleteObjCImplementationCategory(Scope *S,
Douglas Gregorc83c6872010-04-15 22:33:43 +00004804 IdentifierInfo *ClassName,
4805 SourceLocation ClassNameLoc) {
John McCall0a2c5e22010-08-25 06:19:51 +00004806 typedef CodeCompletionResult Result;
Douglas Gregor33ced0b2009-11-18 19:08:43 +00004807
4808 // Find the corresponding interface. If we couldn't find the interface, the
4809 // program itself is ill-formed. However, we'll try to be helpful still by
4810 // providing the list of all of the categories we know about.
4811 NamedDecl *CurClass
Douglas Gregorc83c6872010-04-15 22:33:43 +00004812 = LookupSingleName(TUScope, ClassName, ClassNameLoc, LookupOrdinaryName);
Douglas Gregor33ced0b2009-11-18 19:08:43 +00004813 ObjCInterfaceDecl *Class = dyn_cast_or_null<ObjCInterfaceDecl>(CurClass);
4814 if (!Class)
Douglas Gregorc83c6872010-04-15 22:33:43 +00004815 return CodeCompleteObjCInterfaceCategory(S, ClassName, ClassNameLoc);
Douglas Gregor33ced0b2009-11-18 19:08:43 +00004816
4817 ResultBuilder Results(*this);
4818
4819 // Add all of the categories that have have corresponding interface
4820 // declarations in this class and any of its superclasses, except for
4821 // already-implemented categories in the class itself.
4822 llvm::SmallPtrSet<IdentifierInfo *, 16> CategoryNames;
4823 Results.EnterNewScope();
4824 bool IgnoreImplemented = true;
4825 while (Class) {
4826 for (ObjCCategoryDecl *Category = Class->getCategoryList(); Category;
4827 Category = Category->getNextClassCategory())
4828 if ((!IgnoreImplemented || !Category->getImplementation()) &&
4829 CategoryNames.insert(Category->getIdentifier()))
Douglas Gregor608300b2010-01-14 16:14:35 +00004830 Results.AddResult(Result(Category, 0), CurContext, 0, false);
Douglas Gregor33ced0b2009-11-18 19:08:43 +00004831
4832 Class = Class->getSuperClass();
4833 IgnoreImplemented = false;
4834 }
4835 Results.ExitScope();
4836
Douglas Gregore6b1bb62010-08-11 21:23:17 +00004837 HandleCodeCompleteResults(this, CodeCompleter,
4838 CodeCompletionContext::CCC_Other,
4839 Results.data(),Results.size());
Douglas Gregor33ced0b2009-11-18 19:08:43 +00004840}
Douglas Gregor322328b2009-11-18 22:32:06 +00004841
John McCalld226f652010-08-21 09:40:31 +00004842void Sema::CodeCompleteObjCPropertyDefinition(Scope *S, Decl *ObjCImpDecl) {
John McCall0a2c5e22010-08-25 06:19:51 +00004843 typedef CodeCompletionResult Result;
Douglas Gregor322328b2009-11-18 22:32:06 +00004844 ResultBuilder Results(*this);
4845
4846 // Figure out where this @synthesize lives.
4847 ObjCContainerDecl *Container
John McCalld226f652010-08-21 09:40:31 +00004848 = dyn_cast_or_null<ObjCContainerDecl>(ObjCImpDecl);
Douglas Gregor322328b2009-11-18 22:32:06 +00004849 if (!Container ||
4850 (!isa<ObjCImplementationDecl>(Container) &&
4851 !isa<ObjCCategoryImplDecl>(Container)))
4852 return;
4853
4854 // Ignore any properties that have already been implemented.
4855 for (DeclContext::decl_iterator D = Container->decls_begin(),
4856 DEnd = Container->decls_end();
4857 D != DEnd; ++D)
4858 if (ObjCPropertyImplDecl *PropertyImpl = dyn_cast<ObjCPropertyImplDecl>(*D))
4859 Results.Ignore(PropertyImpl->getPropertyDecl());
4860
4861 // Add any properties that we find.
4862 Results.EnterNewScope();
4863 if (ObjCImplementationDecl *ClassImpl
4864 = dyn_cast<ObjCImplementationDecl>(Container))
4865 AddObjCProperties(ClassImpl->getClassInterface(), false, CurContext,
4866 Results);
4867 else
4868 AddObjCProperties(cast<ObjCCategoryImplDecl>(Container)->getCategoryDecl(),
4869 false, CurContext, Results);
4870 Results.ExitScope();
4871
Douglas Gregore6b1bb62010-08-11 21:23:17 +00004872 HandleCodeCompleteResults(this, CodeCompleter,
4873 CodeCompletionContext::CCC_Other,
4874 Results.data(),Results.size());
Douglas Gregor322328b2009-11-18 22:32:06 +00004875}
4876
4877void Sema::CodeCompleteObjCPropertySynthesizeIvar(Scope *S,
4878 IdentifierInfo *PropertyName,
John McCalld226f652010-08-21 09:40:31 +00004879 Decl *ObjCImpDecl) {
John McCall0a2c5e22010-08-25 06:19:51 +00004880 typedef CodeCompletionResult Result;
Douglas Gregor322328b2009-11-18 22:32:06 +00004881 ResultBuilder Results(*this);
4882
4883 // Figure out where this @synthesize lives.
4884 ObjCContainerDecl *Container
John McCalld226f652010-08-21 09:40:31 +00004885 = dyn_cast_or_null<ObjCContainerDecl>(ObjCImpDecl);
Douglas Gregor322328b2009-11-18 22:32:06 +00004886 if (!Container ||
4887 (!isa<ObjCImplementationDecl>(Container) &&
4888 !isa<ObjCCategoryImplDecl>(Container)))
4889 return;
4890
4891 // Figure out which interface we're looking into.
4892 ObjCInterfaceDecl *Class = 0;
4893 if (ObjCImplementationDecl *ClassImpl
4894 = dyn_cast<ObjCImplementationDecl>(Container))
4895 Class = ClassImpl->getClassInterface();
4896 else
4897 Class = cast<ObjCCategoryImplDecl>(Container)->getCategoryDecl()
4898 ->getClassInterface();
4899
4900 // Add all of the instance variables in this class and its superclasses.
4901 Results.EnterNewScope();
4902 for(; Class; Class = Class->getSuperClass()) {
4903 // FIXME: We could screen the type of each ivar for compatibility with
4904 // the property, but is that being too paternal?
4905 for (ObjCInterfaceDecl::ivar_iterator IVar = Class->ivar_begin(),
4906 IVarEnd = Class->ivar_end();
4907 IVar != IVarEnd; ++IVar)
Douglas Gregor608300b2010-01-14 16:14:35 +00004908 Results.AddResult(Result(*IVar, 0), CurContext, 0, false);
Douglas Gregor322328b2009-11-18 22:32:06 +00004909 }
4910 Results.ExitScope();
4911
Douglas Gregore6b1bb62010-08-11 21:23:17 +00004912 HandleCodeCompleteResults(this, CodeCompleter,
4913 CodeCompletionContext::CCC_Other,
4914 Results.data(),Results.size());
Douglas Gregor322328b2009-11-18 22:32:06 +00004915}
Douglas Gregore8f5a172010-04-07 00:21:17 +00004916
Douglas Gregor408be5a2010-08-25 01:08:01 +00004917// Mapping from selectors to the methods that implement that selector, along
4918// with the "in original class" flag.
4919typedef llvm::DenseMap<Selector, std::pair<ObjCMethodDecl *, bool> >
4920 KnownMethodsMap;
Douglas Gregore8f5a172010-04-07 00:21:17 +00004921
4922/// \brief Find all of the methods that reside in the given container
4923/// (and its superclasses, protocols, etc.) that meet the given
4924/// criteria. Insert those methods into the map of known methods,
4925/// indexed by selector so they can be easily found.
4926static void FindImplementableMethods(ASTContext &Context,
4927 ObjCContainerDecl *Container,
4928 bool WantInstanceMethods,
4929 QualType ReturnType,
4930 bool IsInImplementation,
Douglas Gregor408be5a2010-08-25 01:08:01 +00004931 KnownMethodsMap &KnownMethods,
4932 bool InOriginalClass = true) {
Douglas Gregore8f5a172010-04-07 00:21:17 +00004933 if (ObjCInterfaceDecl *IFace = dyn_cast<ObjCInterfaceDecl>(Container)) {
4934 // Recurse into protocols.
4935 const ObjCList<ObjCProtocolDecl> &Protocols
4936 = IFace->getReferencedProtocols();
4937 for (ObjCList<ObjCProtocolDecl>::iterator I = Protocols.begin(),
4938 E = Protocols.end();
4939 I != E; ++I)
4940 FindImplementableMethods(Context, *I, WantInstanceMethods, ReturnType,
Douglas Gregor408be5a2010-08-25 01:08:01 +00004941 IsInImplementation, KnownMethods,
4942 InOriginalClass);
Douglas Gregore8f5a172010-04-07 00:21:17 +00004943
4944 // If we're not in the implementation of a class, also visit the
4945 // superclass.
4946 if (!IsInImplementation && IFace->getSuperClass())
4947 FindImplementableMethods(Context, IFace->getSuperClass(),
4948 WantInstanceMethods, ReturnType,
Douglas Gregor408be5a2010-08-25 01:08:01 +00004949 IsInImplementation, KnownMethods,
4950 false);
Douglas Gregore8f5a172010-04-07 00:21:17 +00004951
4952 // Add methods from any class extensions (but not from categories;
4953 // those should go into category implementations).
Fariborz Jahanian80aa1cd2010-06-22 23:20:40 +00004954 for (const ObjCCategoryDecl *Cat = IFace->getFirstClassExtension(); Cat;
4955 Cat = Cat->getNextClassExtension())
4956 FindImplementableMethods(Context, const_cast<ObjCCategoryDecl*>(Cat),
4957 WantInstanceMethods, ReturnType,
Douglas Gregor408be5a2010-08-25 01:08:01 +00004958 IsInImplementation, KnownMethods,
4959 InOriginalClass);
Douglas Gregore8f5a172010-04-07 00:21:17 +00004960 }
4961
4962 if (ObjCCategoryDecl *Category = dyn_cast<ObjCCategoryDecl>(Container)) {
4963 // Recurse into protocols.
4964 const ObjCList<ObjCProtocolDecl> &Protocols
4965 = Category->getReferencedProtocols();
4966 for (ObjCList<ObjCProtocolDecl>::iterator I = Protocols.begin(),
4967 E = Protocols.end();
4968 I != E; ++I)
4969 FindImplementableMethods(Context, *I, WantInstanceMethods, ReturnType,
Douglas Gregor408be5a2010-08-25 01:08:01 +00004970 IsInImplementation, KnownMethods,
4971 InOriginalClass);
Douglas Gregore8f5a172010-04-07 00:21:17 +00004972 }
4973
4974 if (ObjCProtocolDecl *Protocol = dyn_cast<ObjCProtocolDecl>(Container)) {
4975 // Recurse into protocols.
4976 const ObjCList<ObjCProtocolDecl> &Protocols
4977 = Protocol->getReferencedProtocols();
4978 for (ObjCList<ObjCProtocolDecl>::iterator I = Protocols.begin(),
4979 E = Protocols.end();
4980 I != E; ++I)
4981 FindImplementableMethods(Context, *I, WantInstanceMethods, ReturnType,
Douglas Gregor408be5a2010-08-25 01:08:01 +00004982 IsInImplementation, KnownMethods, false);
Douglas Gregore8f5a172010-04-07 00:21:17 +00004983 }
4984
4985 // Add methods in this container. This operation occurs last because
4986 // we want the methods from this container to override any methods
4987 // we've previously seen with the same selector.
4988 for (ObjCContainerDecl::method_iterator M = Container->meth_begin(),
4989 MEnd = Container->meth_end();
4990 M != MEnd; ++M) {
4991 if ((*M)->isInstanceMethod() == WantInstanceMethods) {
4992 if (!ReturnType.isNull() &&
4993 !Context.hasSameUnqualifiedType(ReturnType, (*M)->getResultType()))
4994 continue;
4995
Douglas Gregor408be5a2010-08-25 01:08:01 +00004996 KnownMethods[(*M)->getSelector()] = std::make_pair(*M, InOriginalClass);
Douglas Gregore8f5a172010-04-07 00:21:17 +00004997 }
4998 }
4999}
5000
5001void Sema::CodeCompleteObjCMethodDecl(Scope *S,
5002 bool IsInstanceMethod,
John McCallb3d87482010-08-24 05:47:05 +00005003 ParsedType ReturnTy,
John McCalld226f652010-08-21 09:40:31 +00005004 Decl *IDecl) {
Douglas Gregore8f5a172010-04-07 00:21:17 +00005005 // Determine the return type of the method we're declaring, if
5006 // provided.
5007 QualType ReturnType = GetTypeFromParser(ReturnTy);
5008
5009 // Determine where we should start searching for methods, and where we
5010 ObjCContainerDecl *SearchDecl = 0, *CurrentDecl = 0;
5011 bool IsInImplementation = false;
John McCalld226f652010-08-21 09:40:31 +00005012 if (Decl *D = IDecl) {
Douglas Gregore8f5a172010-04-07 00:21:17 +00005013 if (ObjCImplementationDecl *Impl = dyn_cast<ObjCImplementationDecl>(D)) {
5014 SearchDecl = Impl->getClassInterface();
5015 CurrentDecl = Impl;
5016 IsInImplementation = true;
5017 } else if (ObjCCategoryImplDecl *CatImpl
5018 = dyn_cast<ObjCCategoryImplDecl>(D)) {
5019 SearchDecl = CatImpl->getCategoryDecl();
5020 CurrentDecl = CatImpl;
5021 IsInImplementation = true;
5022 } else {
5023 SearchDecl = dyn_cast<ObjCContainerDecl>(D);
5024 CurrentDecl = SearchDecl;
5025 }
5026 }
5027
5028 if (!SearchDecl && S) {
5029 if (DeclContext *DC = static_cast<DeclContext *>(S->getEntity())) {
5030 SearchDecl = dyn_cast<ObjCContainerDecl>(DC);
5031 CurrentDecl = SearchDecl;
5032 }
5033 }
5034
5035 if (!SearchDecl || !CurrentDecl) {
Douglas Gregore6b1bb62010-08-11 21:23:17 +00005036 HandleCodeCompleteResults(this, CodeCompleter,
5037 CodeCompletionContext::CCC_Other,
5038 0, 0);
Douglas Gregore8f5a172010-04-07 00:21:17 +00005039 return;
5040 }
5041
5042 // Find all of the methods that we could declare/implement here.
5043 KnownMethodsMap KnownMethods;
5044 FindImplementableMethods(Context, SearchDecl, IsInstanceMethod,
5045 ReturnType, IsInImplementation, KnownMethods);
5046
5047 // Erase any methods that have already been declared or
5048 // implemented here.
5049 for (ObjCContainerDecl::method_iterator M = CurrentDecl->meth_begin(),
5050 MEnd = CurrentDecl->meth_end();
5051 M != MEnd; ++M) {
5052 if ((*M)->isInstanceMethod() != IsInstanceMethod)
5053 continue;
5054
5055 KnownMethodsMap::iterator Pos = KnownMethods.find((*M)->getSelector());
5056 if (Pos != KnownMethods.end())
5057 KnownMethods.erase(Pos);
5058 }
5059
5060 // Add declarations or definitions for each of the known methods.
John McCall0a2c5e22010-08-25 06:19:51 +00005061 typedef CodeCompletionResult Result;
Douglas Gregore8f5a172010-04-07 00:21:17 +00005062 ResultBuilder Results(*this);
5063 Results.EnterNewScope();
5064 PrintingPolicy Policy(Context.PrintingPolicy);
5065 Policy.AnonymousTagLocations = false;
5066 for (KnownMethodsMap::iterator M = KnownMethods.begin(),
5067 MEnd = KnownMethods.end();
5068 M != MEnd; ++M) {
Douglas Gregor408be5a2010-08-25 01:08:01 +00005069 ObjCMethodDecl *Method = M->second.first;
Douglas Gregore8f5a172010-04-07 00:21:17 +00005070 CodeCompletionString *Pattern = new CodeCompletionString;
5071
5072 // If the result type was not already provided, add it to the
5073 // pattern as (type).
5074 if (ReturnType.isNull()) {
5075 std::string TypeStr;
5076 Method->getResultType().getAsStringInternal(TypeStr, Policy);
5077 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
5078 Pattern->AddTextChunk(TypeStr);
5079 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
5080 }
5081
5082 Selector Sel = Method->getSelector();
5083
5084 // Add the first part of the selector to the pattern.
5085 Pattern->AddTypedTextChunk(Sel.getIdentifierInfoForSlot(0)->getName());
5086
5087 // Add parameters to the pattern.
5088 unsigned I = 0;
5089 for (ObjCMethodDecl::param_iterator P = Method->param_begin(),
5090 PEnd = Method->param_end();
5091 P != PEnd; (void)++P, ++I) {
5092 // Add the part of the selector name.
5093 if (I == 0)
5094 Pattern->AddChunk(CodeCompletionString::CK_Colon);
5095 else if (I < Sel.getNumArgs()) {
5096 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
Douglas Gregor47c03a72010-08-17 15:53:35 +00005097 Pattern->AddTextChunk(Sel.getIdentifierInfoForSlot(I)->getName());
Douglas Gregore8f5a172010-04-07 00:21:17 +00005098 Pattern->AddChunk(CodeCompletionString::CK_Colon);
5099 } else
5100 break;
5101
5102 // Add the parameter type.
5103 std::string TypeStr;
5104 (*P)->getOriginalType().getAsStringInternal(TypeStr, Policy);
5105 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
5106 Pattern->AddTextChunk(TypeStr);
5107 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
5108
5109 if (IdentifierInfo *Id = (*P)->getIdentifier())
Douglas Gregore17794f2010-08-31 05:13:43 +00005110 Pattern->AddTextChunk(Id->getName());
Douglas Gregore8f5a172010-04-07 00:21:17 +00005111 }
5112
5113 if (Method->isVariadic()) {
5114 if (Method->param_size() > 0)
5115 Pattern->AddChunk(CodeCompletionString::CK_Comma);
5116 Pattern->AddTextChunk("...");
Douglas Gregore17794f2010-08-31 05:13:43 +00005117 }
Douglas Gregore8f5a172010-04-07 00:21:17 +00005118
Douglas Gregor447107d2010-05-28 00:57:46 +00005119 if (IsInImplementation && Results.includeCodePatterns()) {
Douglas Gregore8f5a172010-04-07 00:21:17 +00005120 // We will be defining the method here, so add a compound statement.
5121 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
5122 Pattern->AddChunk(CodeCompletionString::CK_LeftBrace);
5123 Pattern->AddChunk(CodeCompletionString::CK_VerticalSpace);
5124 if (!Method->getResultType()->isVoidType()) {
5125 // If the result type is not void, add a return clause.
5126 Pattern->AddTextChunk("return");
5127 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
5128 Pattern->AddPlaceholderChunk("expression");
5129 Pattern->AddChunk(CodeCompletionString::CK_SemiColon);
5130 } else
5131 Pattern->AddPlaceholderChunk("statements");
5132
5133 Pattern->AddChunk(CodeCompletionString::CK_VerticalSpace);
5134 Pattern->AddChunk(CodeCompletionString::CK_RightBrace);
5135 }
5136
Douglas Gregor408be5a2010-08-25 01:08:01 +00005137 unsigned Priority = CCP_CodePattern;
5138 if (!M->second.second)
5139 Priority += CCD_InBaseClass;
5140
5141 Results.AddResult(Result(Pattern, Priority,
Douglas Gregor16ed9ad2010-08-17 16:06:07 +00005142 Method->isInstanceMethod()
5143 ? CXCursor_ObjCInstanceMethodDecl
5144 : CXCursor_ObjCClassMethodDecl));
Douglas Gregore8f5a172010-04-07 00:21:17 +00005145 }
5146
5147 Results.ExitScope();
5148
Douglas Gregore6b1bb62010-08-11 21:23:17 +00005149 HandleCodeCompleteResults(this, CodeCompleter,
5150 CodeCompletionContext::CCC_Other,
5151 Results.data(),Results.size());
Douglas Gregore8f5a172010-04-07 00:21:17 +00005152}
Douglas Gregor1f5537a2010-07-08 23:20:03 +00005153
5154void Sema::CodeCompleteObjCMethodDeclSelector(Scope *S,
5155 bool IsInstanceMethod,
Douglas Gregor40ed9a12010-07-08 23:37:41 +00005156 bool AtParameterName,
John McCallb3d87482010-08-24 05:47:05 +00005157 ParsedType ReturnTy,
Douglas Gregor1f5537a2010-07-08 23:20:03 +00005158 IdentifierInfo **SelIdents,
5159 unsigned NumSelIdents) {
Douglas Gregor1f5537a2010-07-08 23:20:03 +00005160 // If we have an external source, load the entire class method
Sebastian Redl3c7f4132010-08-18 23:57:06 +00005161 // pool from the AST file.
Douglas Gregor1f5537a2010-07-08 23:20:03 +00005162 if (ExternalSource) {
5163 for (uint32_t I = 0, N = ExternalSource->GetNumExternalSelectors();
5164 I != N; ++I) {
5165 Selector Sel = ExternalSource->GetExternalSelector(I);
Sebastian Redldb9d2142010-08-02 23:18:59 +00005166 if (Sel.isNull() || MethodPool.count(Sel))
Douglas Gregor1f5537a2010-07-08 23:20:03 +00005167 continue;
Sebastian Redldb9d2142010-08-02 23:18:59 +00005168
5169 ReadMethodPool(Sel);
Douglas Gregor1f5537a2010-07-08 23:20:03 +00005170 }
5171 }
5172
5173 // Build the set of methods we can see.
John McCall0a2c5e22010-08-25 06:19:51 +00005174 typedef CodeCompletionResult Result;
Douglas Gregor1f5537a2010-07-08 23:20:03 +00005175 ResultBuilder Results(*this);
5176
5177 if (ReturnTy)
5178 Results.setPreferredType(GetTypeFromParser(ReturnTy).getNonReferenceType());
Sebastian Redldb9d2142010-08-02 23:18:59 +00005179
Douglas Gregor1f5537a2010-07-08 23:20:03 +00005180 Results.EnterNewScope();
Sebastian Redldb9d2142010-08-02 23:18:59 +00005181 for (GlobalMethodPool::iterator M = MethodPool.begin(),
5182 MEnd = MethodPool.end();
5183 M != MEnd; ++M) {
5184 for (ObjCMethodList *MethList = IsInstanceMethod ? &M->second.first :
5185 &M->second.second;
5186 MethList && MethList->Method;
Douglas Gregor1f5537a2010-07-08 23:20:03 +00005187 MethList = MethList->Next) {
5188 if (!isAcceptableObjCMethod(MethList->Method, MK_Any, SelIdents,
5189 NumSelIdents))
5190 continue;
5191
Douglas Gregor40ed9a12010-07-08 23:37:41 +00005192 if (AtParameterName) {
5193 // Suggest parameter names we've seen before.
5194 if (NumSelIdents && NumSelIdents <= MethList->Method->param_size()) {
5195 ParmVarDecl *Param = MethList->Method->param_begin()[NumSelIdents-1];
5196 if (Param->getIdentifier()) {
5197 CodeCompletionString *Pattern = new CodeCompletionString;
5198 Pattern->AddTypedTextChunk(Param->getIdentifier()->getName());
5199 Results.AddResult(Pattern);
5200 }
5201 }
5202
5203 continue;
5204 }
5205
Douglas Gregor1f5537a2010-07-08 23:20:03 +00005206 Result R(MethList->Method, 0);
5207 R.StartParameter = NumSelIdents;
5208 R.AllParametersAreInformative = false;
5209 R.DeclaringEntity = true;
5210 Results.MaybeAddResult(R, CurContext);
5211 }
5212 }
5213
5214 Results.ExitScope();
Douglas Gregore6b1bb62010-08-11 21:23:17 +00005215 HandleCodeCompleteResults(this, CodeCompleter,
5216 CodeCompletionContext::CCC_Other,
5217 Results.data(),Results.size());
Douglas Gregor1f5537a2010-07-08 23:20:03 +00005218}
Douglas Gregor87c08a52010-08-13 22:48:40 +00005219
Douglas Gregorf29c5232010-08-24 22:20:20 +00005220void Sema::CodeCompletePreprocessorDirective(bool InConditional) {
Douglas Gregorf44e8542010-08-24 19:08:16 +00005221 ResultBuilder Results(*this);
5222 Results.EnterNewScope();
5223
5224 // #if <condition>
5225 CodeCompletionString *Pattern = new CodeCompletionString;
5226 Pattern->AddTypedTextChunk("if");
5227 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
5228 Pattern->AddPlaceholderChunk("condition");
5229 Results.AddResult(Pattern);
5230
5231 // #ifdef <macro>
5232 Pattern = new CodeCompletionString;
5233 Pattern->AddTypedTextChunk("ifdef");
5234 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
5235 Pattern->AddPlaceholderChunk("macro");
5236 Results.AddResult(Pattern);
5237
5238 // #ifndef <macro>
5239 Pattern = new CodeCompletionString;
5240 Pattern->AddTypedTextChunk("ifndef");
5241 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
5242 Pattern->AddPlaceholderChunk("macro");
5243 Results.AddResult(Pattern);
5244
5245 if (InConditional) {
5246 // #elif <condition>
5247 Pattern = new CodeCompletionString;
5248 Pattern->AddTypedTextChunk("elif");
5249 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
5250 Pattern->AddPlaceholderChunk("condition");
5251 Results.AddResult(Pattern);
5252
5253 // #else
5254 Pattern = new CodeCompletionString;
5255 Pattern->AddTypedTextChunk("else");
5256 Results.AddResult(Pattern);
5257
5258 // #endif
5259 Pattern = new CodeCompletionString;
5260 Pattern->AddTypedTextChunk("endif");
5261 Results.AddResult(Pattern);
5262 }
5263
5264 // #include "header"
5265 Pattern = new CodeCompletionString;
5266 Pattern->AddTypedTextChunk("include");
5267 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
5268 Pattern->AddTextChunk("\"");
5269 Pattern->AddPlaceholderChunk("header");
5270 Pattern->AddTextChunk("\"");
5271 Results.AddResult(Pattern);
5272
5273 // #include <header>
5274 Pattern = new CodeCompletionString;
5275 Pattern->AddTypedTextChunk("include");
5276 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
5277 Pattern->AddTextChunk("<");
5278 Pattern->AddPlaceholderChunk("header");
5279 Pattern->AddTextChunk(">");
5280 Results.AddResult(Pattern);
5281
5282 // #define <macro>
5283 Pattern = new CodeCompletionString;
5284 Pattern->AddTypedTextChunk("define");
5285 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
5286 Pattern->AddPlaceholderChunk("macro");
5287 Results.AddResult(Pattern);
5288
5289 // #define <macro>(<args>)
5290 Pattern = new CodeCompletionString;
5291 Pattern->AddTypedTextChunk("define");
5292 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
5293 Pattern->AddPlaceholderChunk("macro");
5294 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
5295 Pattern->AddPlaceholderChunk("args");
5296 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
5297 Results.AddResult(Pattern);
5298
5299 // #undef <macro>
5300 Pattern = new CodeCompletionString;
5301 Pattern->AddTypedTextChunk("undef");
5302 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
5303 Pattern->AddPlaceholderChunk("macro");
5304 Results.AddResult(Pattern);
5305
5306 // #line <number>
5307 Pattern = new CodeCompletionString;
5308 Pattern->AddTypedTextChunk("line");
5309 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
5310 Pattern->AddPlaceholderChunk("number");
5311 Results.AddResult(Pattern);
5312
5313 // #line <number> "filename"
5314 Pattern = new CodeCompletionString;
5315 Pattern->AddTypedTextChunk("line");
5316 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
5317 Pattern->AddPlaceholderChunk("number");
5318 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
5319 Pattern->AddTextChunk("\"");
5320 Pattern->AddPlaceholderChunk("filename");
5321 Pattern->AddTextChunk("\"");
5322 Results.AddResult(Pattern);
5323
5324 // #error <message>
5325 Pattern = new CodeCompletionString;
5326 Pattern->AddTypedTextChunk("error");
5327 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
5328 Pattern->AddPlaceholderChunk("message");
5329 Results.AddResult(Pattern);
5330
5331 // #pragma <arguments>
5332 Pattern = new CodeCompletionString;
5333 Pattern->AddTypedTextChunk("pragma");
5334 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
5335 Pattern->AddPlaceholderChunk("arguments");
5336 Results.AddResult(Pattern);
5337
5338 if (getLangOptions().ObjC1) {
5339 // #import "header"
5340 Pattern = new CodeCompletionString;
5341 Pattern->AddTypedTextChunk("import");
5342 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
5343 Pattern->AddTextChunk("\"");
5344 Pattern->AddPlaceholderChunk("header");
5345 Pattern->AddTextChunk("\"");
5346 Results.AddResult(Pattern);
5347
5348 // #import <header>
5349 Pattern = new CodeCompletionString;
5350 Pattern->AddTypedTextChunk("import");
5351 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
5352 Pattern->AddTextChunk("<");
5353 Pattern->AddPlaceholderChunk("header");
5354 Pattern->AddTextChunk(">");
5355 Results.AddResult(Pattern);
5356 }
5357
5358 // #include_next "header"
5359 Pattern = new CodeCompletionString;
5360 Pattern->AddTypedTextChunk("include_next");
5361 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
5362 Pattern->AddTextChunk("\"");
5363 Pattern->AddPlaceholderChunk("header");
5364 Pattern->AddTextChunk("\"");
5365 Results.AddResult(Pattern);
5366
5367 // #include_next <header>
5368 Pattern = new CodeCompletionString;
5369 Pattern->AddTypedTextChunk("include_next");
5370 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
5371 Pattern->AddTextChunk("<");
5372 Pattern->AddPlaceholderChunk("header");
5373 Pattern->AddTextChunk(">");
5374 Results.AddResult(Pattern);
5375
5376 // #warning <message>
5377 Pattern = new CodeCompletionString;
5378 Pattern->AddTypedTextChunk("warning");
5379 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
5380 Pattern->AddPlaceholderChunk("message");
5381 Results.AddResult(Pattern);
5382
5383 // Note: #ident and #sccs are such crazy anachronisms that we don't provide
5384 // completions for them. And __include_macros is a Clang-internal extension
5385 // that we don't want to encourage anyone to use.
5386
5387 // FIXME: we don't support #assert or #unassert, so don't suggest them.
5388 Results.ExitScope();
5389
Douglas Gregorf44e8542010-08-24 19:08:16 +00005390 HandleCodeCompleteResults(this, CodeCompleter,
Douglas Gregor721f3592010-08-25 18:41:16 +00005391 CodeCompletionContext::CCC_PreprocessorDirective,
Douglas Gregorf44e8542010-08-24 19:08:16 +00005392 Results.data(), Results.size());
5393}
5394
5395void Sema::CodeCompleteInPreprocessorConditionalExclusion(Scope *S) {
Douglas Gregorf29c5232010-08-24 22:20:20 +00005396 CodeCompleteOrdinaryName(S,
John McCallf312b1e2010-08-26 23:41:50 +00005397 S->getFnParent()? Sema::PCC_RecoveryInFunction
5398 : Sema::PCC_Namespace);
Douglas Gregorf44e8542010-08-24 19:08:16 +00005399}
5400
Douglas Gregorf29c5232010-08-24 22:20:20 +00005401void Sema::CodeCompletePreprocessorMacroName(bool IsDefinition) {
Douglas Gregor1fbb4472010-08-24 20:21:13 +00005402 ResultBuilder Results(*this);
5403 if (!IsDefinition && (!CodeCompleter || CodeCompleter->includeMacros())) {
5404 // Add just the names of macros, not their arguments.
5405 Results.EnterNewScope();
5406 for (Preprocessor::macro_iterator M = PP.macro_begin(),
5407 MEnd = PP.macro_end();
5408 M != MEnd; ++M) {
5409 CodeCompletionString *Pattern = new CodeCompletionString;
5410 Pattern->AddTypedTextChunk(M->first->getName());
5411 Results.AddResult(Pattern);
5412 }
5413 Results.ExitScope();
5414 } else if (IsDefinition) {
5415 // FIXME: Can we detect when the user just wrote an include guard above?
5416 }
5417
5418 HandleCodeCompleteResults(this, CodeCompleter,
5419 IsDefinition? CodeCompletionContext::CCC_MacroName
5420 : CodeCompletionContext::CCC_MacroNameUse,
5421 Results.data(), Results.size());
5422}
5423
Douglas Gregorf29c5232010-08-24 22:20:20 +00005424void Sema::CodeCompletePreprocessorExpression() {
5425 ResultBuilder Results(*this);
5426
5427 if (!CodeCompleter || CodeCompleter->includeMacros())
5428 AddMacroResults(PP, Results);
5429
5430 // defined (<macro>)
5431 Results.EnterNewScope();
5432 CodeCompletionString *Pattern = new CodeCompletionString;
5433 Pattern->AddTypedTextChunk("defined");
5434 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
5435 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
5436 Pattern->AddPlaceholderChunk("macro");
5437 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
5438 Results.AddResult(Pattern);
5439 Results.ExitScope();
5440
5441 HandleCodeCompleteResults(this, CodeCompleter,
5442 CodeCompletionContext::CCC_PreprocessorExpression,
5443 Results.data(), Results.size());
5444}
5445
5446void Sema::CodeCompletePreprocessorMacroArgument(Scope *S,
5447 IdentifierInfo *Macro,
5448 MacroInfo *MacroInfo,
5449 unsigned Argument) {
5450 // FIXME: In the future, we could provide "overload" results, much like we
5451 // do for function calls.
5452
5453 CodeCompleteOrdinaryName(S,
John McCallf312b1e2010-08-26 23:41:50 +00005454 S->getFnParent()? Sema::PCC_RecoveryInFunction
5455 : Sema::PCC_Namespace);
Douglas Gregorf29c5232010-08-24 22:20:20 +00005456}
5457
Douglas Gregor55817af2010-08-25 17:04:25 +00005458void Sema::CodeCompleteNaturalLanguage() {
Douglas Gregor55817af2010-08-25 17:04:25 +00005459 HandleCodeCompleteResults(this, CodeCompleter,
Douglas Gregoraf1c6b52010-08-25 17:10:00 +00005460 CodeCompletionContext::CCC_NaturalLanguage,
Douglas Gregor55817af2010-08-25 17:04:25 +00005461 0, 0);
5462}
5463
Douglas Gregor87c08a52010-08-13 22:48:40 +00005464void Sema::GatherGlobalCodeCompletions(
John McCall0a2c5e22010-08-25 06:19:51 +00005465 llvm::SmallVectorImpl<CodeCompletionResult> &Results) {
Douglas Gregor87c08a52010-08-13 22:48:40 +00005466 ResultBuilder Builder(*this);
5467
Douglas Gregor8071e422010-08-15 06:18:01 +00005468 if (!CodeCompleter || CodeCompleter->includeGlobals()) {
5469 CodeCompletionDeclConsumer Consumer(Builder,
5470 Context.getTranslationUnitDecl());
5471 LookupVisibleDecls(Context.getTranslationUnitDecl(), LookupAnyName,
5472 Consumer);
5473 }
Douglas Gregor87c08a52010-08-13 22:48:40 +00005474
5475 if (!CodeCompleter || CodeCompleter->includeMacros())
5476 AddMacroResults(PP, Builder);
5477
5478 Results.clear();
5479 Results.insert(Results.end(),
5480 Builder.data(), Builder.data() + Builder.size());
5481}