blob: 86c79c7dd9c663636c3fd3936ff4882b80e94c99 [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 Gregord475aad2010-09-20 21:25:19 +0000628 if (SemaRef.Context.hasSameUnqualifiedType(PreferredType, TC))
629 R.Priority /= CCF_ExactTypeMatch;
630 // Check for nearly-matching types, based on classification of each.
Douglas Gregor1f5537a2010-07-08 23:20:03 +0000631 else if ((getSimplifiedTypeClass(PreferredType)
632 == getSimplifiedTypeClass(TC)) &&
633 !(PreferredType->isEnumeralType() && TC->isEnumeralType()))
634 R.Priority /= CCF_SimilarTypeMatch;
635}
636
Douglas Gregore495b7f2010-01-14 00:20:49 +0000637void ResultBuilder::MaybeAddResult(Result R, DeclContext *CurContext) {
638 assert(!ShadowMaps.empty() && "Must enter into a results scope");
639
640 if (R.Kind != Result::RK_Declaration) {
641 // For non-declaration results, just add the result.
642 Results.push_back(R);
643 return;
644 }
645
646 // Look through using declarations.
647 if (UsingShadowDecl *Using = dyn_cast<UsingShadowDecl>(R.Declaration)) {
648 MaybeAddResult(Result(Using->getTargetDecl(), R.Qualifier), CurContext);
649 return;
650 }
651
652 Decl *CanonDecl = R.Declaration->getCanonicalDecl();
653 unsigned IDNS = CanonDecl->getIdentifierNamespace();
654
Douglas Gregor45bcd432010-01-14 03:21:49 +0000655 bool AsNestedNameSpecifier = false;
656 if (!isInterestingDecl(R.Declaration, AsNestedNameSpecifier))
Douglas Gregore495b7f2010-01-14 00:20:49 +0000657 return;
658
Douglas Gregor86d9a522009-09-21 16:56:56 +0000659 ShadowMap &SMap = ShadowMaps.back();
Douglas Gregorfbcb5d62009-12-06 20:23:50 +0000660 ShadowMapEntry::iterator I, IEnd;
661 ShadowMap::iterator NamePos = SMap.find(R.Declaration->getDeclName());
662 if (NamePos != SMap.end()) {
663 I = NamePos->second.begin();
664 IEnd = NamePos->second.end();
665 }
666
667 for (; I != IEnd; ++I) {
668 NamedDecl *ND = I->first;
669 unsigned Index = I->second;
Douglas Gregor86d9a522009-09-21 16:56:56 +0000670 if (ND->getCanonicalDecl() == CanonDecl) {
671 // This is a redeclaration. Always pick the newer declaration.
Douglas Gregor86d9a522009-09-21 16:56:56 +0000672 Results[Index].Declaration = R.Declaration;
673
Douglas Gregor86d9a522009-09-21 16:56:56 +0000674 // We're done.
675 return;
676 }
677 }
678
679 // This is a new declaration in this scope. However, check whether this
680 // declaration name is hidden by a similarly-named declaration in an outer
681 // scope.
682 std::list<ShadowMap>::iterator SM, SMEnd = ShadowMaps.end();
683 --SMEnd;
684 for (SM = ShadowMaps.begin(); SM != SMEnd; ++SM) {
Douglas Gregorfbcb5d62009-12-06 20:23:50 +0000685 ShadowMapEntry::iterator I, IEnd;
686 ShadowMap::iterator NamePos = SM->find(R.Declaration->getDeclName());
687 if (NamePos != SM->end()) {
688 I = NamePos->second.begin();
689 IEnd = NamePos->second.end();
690 }
691 for (; I != IEnd; ++I) {
Douglas Gregor86d9a522009-09-21 16:56:56 +0000692 // A tag declaration does not hide a non-tag declaration.
John McCall0d6b1642010-04-23 18:46:30 +0000693 if (I->first->hasTagIdentifierNamespace() &&
Douglas Gregor86d9a522009-09-21 16:56:56 +0000694 (IDNS & (Decl::IDNS_Member | Decl::IDNS_Ordinary |
695 Decl::IDNS_ObjCProtocol)))
696 continue;
697
698 // Protocols are in distinct namespaces from everything else.
Douglas Gregorfbcb5d62009-12-06 20:23:50 +0000699 if (((I->first->getIdentifierNamespace() & Decl::IDNS_ObjCProtocol)
Douglas Gregor86d9a522009-09-21 16:56:56 +0000700 || (IDNS & Decl::IDNS_ObjCProtocol)) &&
Douglas Gregorfbcb5d62009-12-06 20:23:50 +0000701 I->first->getIdentifierNamespace() != IDNS)
Douglas Gregor86d9a522009-09-21 16:56:56 +0000702 continue;
703
704 // The newly-added result is hidden by an entry in the shadow map.
Douglas Gregor6660d842010-01-14 00:41:07 +0000705 if (CheckHiddenResult(R, CurContext, I->first))
Douglas Gregor86d9a522009-09-21 16:56:56 +0000706 return;
Douglas Gregor86d9a522009-09-21 16:56:56 +0000707
708 break;
709 }
710 }
711
712 // Make sure that any given declaration only shows up in the result set once.
713 if (!AllDeclsFound.insert(CanonDecl))
714 return;
Douglas Gregor265f7492010-08-27 15:29:55 +0000715
716 // If this is an Objective-C method declaration whose selector matches our
717 // preferred selector, give it a priority boost.
718 if (!PreferredSelector.isNull())
719 if (ObjCMethodDecl *Method = dyn_cast<ObjCMethodDecl>(R.Declaration))
720 if (PreferredSelector == Method->getSelector())
721 R.Priority += CCD_SelectorMatch;
722
Douglas Gregoreb5758b2009-09-23 22:26:46 +0000723 // If the filter is for nested-name-specifiers, then this result starts a
724 // nested-name-specifier.
Douglas Gregor12e13132010-05-26 22:00:08 +0000725 if (AsNestedNameSpecifier) {
Douglas Gregoreb5758b2009-09-23 22:26:46 +0000726 R.StartsNestedNameSpecifier = true;
Douglas Gregor12e13132010-05-26 22:00:08 +0000727 R.Priority = CCP_NestedNameSpecifier;
Douglas Gregor1f5537a2010-07-08 23:20:03 +0000728 } else if (!PreferredType.isNull())
729 AdjustResultPriorityForPreferredType(R);
Douglas Gregor265f7492010-08-27 15:29:55 +0000730
Douglas Gregor0563c262009-09-22 23:15:58 +0000731 // If this result is supposed to have an informative qualifier, add one.
Douglas Gregoreb5758b2009-09-23 22:26:46 +0000732 if (R.QualifierIsInformative && !R.Qualifier &&
733 !R.StartsNestedNameSpecifier) {
Douglas Gregor0563c262009-09-22 23:15:58 +0000734 DeclContext *Ctx = R.Declaration->getDeclContext();
735 if (NamespaceDecl *Namespace = dyn_cast<NamespaceDecl>(Ctx))
736 R.Qualifier = NestedNameSpecifier::Create(SemaRef.Context, 0, Namespace);
737 else if (TagDecl *Tag = dyn_cast<TagDecl>(Ctx))
738 R.Qualifier = NestedNameSpecifier::Create(SemaRef.Context, 0, false,
739 SemaRef.Context.getTypeDeclType(Tag).getTypePtr());
740 else
741 R.QualifierIsInformative = false;
742 }
Douglas Gregoreb5758b2009-09-23 22:26:46 +0000743
Douglas Gregor86d9a522009-09-21 16:56:56 +0000744 // Insert this result into the set of results and into the current shadow
745 // map.
Douglas Gregorfbcb5d62009-12-06 20:23:50 +0000746 SMap[R.Declaration->getDeclName()].Add(R.Declaration, Results.size());
Douglas Gregor86d9a522009-09-21 16:56:56 +0000747 Results.push_back(R);
748}
749
Douglas Gregor1ca6ae82010-01-14 01:09:38 +0000750void ResultBuilder::AddResult(Result R, DeclContext *CurContext,
Douglas Gregor0cc84042010-01-14 15:47:35 +0000751 NamedDecl *Hiding, bool InBaseClass = false) {
Douglas Gregora4477812010-01-14 16:01:26 +0000752 if (R.Kind != Result::RK_Declaration) {
753 // For non-declaration results, just add the result.
754 Results.push_back(R);
755 return;
756 }
757
Douglas Gregor1ca6ae82010-01-14 01:09:38 +0000758 // Look through using declarations.
759 if (UsingShadowDecl *Using = dyn_cast<UsingShadowDecl>(R.Declaration)) {
760 AddResult(Result(Using->getTargetDecl(), R.Qualifier), CurContext, Hiding);
761 return;
762 }
763
Douglas Gregor45bcd432010-01-14 03:21:49 +0000764 bool AsNestedNameSpecifier = false;
765 if (!isInterestingDecl(R.Declaration, AsNestedNameSpecifier))
Douglas Gregor1ca6ae82010-01-14 01:09:38 +0000766 return;
767
768 if (Hiding && CheckHiddenResult(R, CurContext, Hiding))
769 return;
770
771 // Make sure that any given declaration only shows up in the result set once.
772 if (!AllDeclsFound.insert(R.Declaration->getCanonicalDecl()))
773 return;
774
775 // If the filter is for nested-name-specifiers, then this result starts a
776 // nested-name-specifier.
Douglas Gregor12e13132010-05-26 22:00:08 +0000777 if (AsNestedNameSpecifier) {
Douglas Gregor1ca6ae82010-01-14 01:09:38 +0000778 R.StartsNestedNameSpecifier = true;
Douglas Gregor12e13132010-05-26 22:00:08 +0000779 R.Priority = CCP_NestedNameSpecifier;
780 }
Douglas Gregor0cc84042010-01-14 15:47:35 +0000781 else if (Filter == &ResultBuilder::IsMember && !R.Qualifier && InBaseClass &&
782 isa<CXXRecordDecl>(R.Declaration->getDeclContext()
Sebastian Redl7a126a42010-08-31 00:36:30 +0000783 ->getRedeclContext()))
Douglas Gregor0cc84042010-01-14 15:47:35 +0000784 R.QualifierIsInformative = true;
785
Douglas Gregor1ca6ae82010-01-14 01:09:38 +0000786 // If this result is supposed to have an informative qualifier, add one.
787 if (R.QualifierIsInformative && !R.Qualifier &&
788 !R.StartsNestedNameSpecifier) {
789 DeclContext *Ctx = R.Declaration->getDeclContext();
790 if (NamespaceDecl *Namespace = dyn_cast<NamespaceDecl>(Ctx))
791 R.Qualifier = NestedNameSpecifier::Create(SemaRef.Context, 0, Namespace);
792 else if (TagDecl *Tag = dyn_cast<TagDecl>(Ctx))
793 R.Qualifier = NestedNameSpecifier::Create(SemaRef.Context, 0, false,
Douglas Gregor45bcd432010-01-14 03:21:49 +0000794 SemaRef.Context.getTypeDeclType(Tag).getTypePtr());
Douglas Gregor1ca6ae82010-01-14 01:09:38 +0000795 else
796 R.QualifierIsInformative = false;
797 }
798
Douglas Gregor12e13132010-05-26 22:00:08 +0000799 // Adjust the priority if this result comes from a base class.
800 if (InBaseClass)
801 R.Priority += CCD_InBaseClass;
802
Douglas Gregor265f7492010-08-27 15:29:55 +0000803 // If this is an Objective-C method declaration whose selector matches our
804 // preferred selector, give it a priority boost.
805 if (!PreferredSelector.isNull())
806 if (ObjCMethodDecl *Method = dyn_cast<ObjCMethodDecl>(R.Declaration))
807 if (PreferredSelector == Method->getSelector())
808 R.Priority += CCD_SelectorMatch;
809
Douglas Gregor1f5537a2010-07-08 23:20:03 +0000810 if (!PreferredType.isNull())
811 AdjustResultPriorityForPreferredType(R);
Douglas Gregor5ac3bdb2010-05-30 01:49:25 +0000812
Douglas Gregor3cdee122010-08-26 16:36:48 +0000813 if (HasObjectTypeQualifiers)
814 if (CXXMethodDecl *Method = dyn_cast<CXXMethodDecl>(R.Declaration))
815 if (Method->isInstance()) {
816 Qualifiers MethodQuals
817 = Qualifiers::fromCVRMask(Method->getTypeQualifiers());
818 if (ObjectTypeQualifiers == MethodQuals)
819 R.Priority += CCD_ObjectQualifierMatch;
820 else if (ObjectTypeQualifiers - MethodQuals) {
821 // The method cannot be invoked, because doing so would drop
822 // qualifiers.
823 return;
824 }
825 }
826
Douglas Gregor1ca6ae82010-01-14 01:09:38 +0000827 // Insert this result into the set of results.
828 Results.push_back(R);
829}
830
Douglas Gregora4477812010-01-14 16:01:26 +0000831void ResultBuilder::AddResult(Result R) {
832 assert(R.Kind != Result::RK_Declaration &&
833 "Declaration results need more context");
834 Results.push_back(R);
835}
836
Douglas Gregor86d9a522009-09-21 16:56:56 +0000837/// \brief Enter into a new scope.
838void ResultBuilder::EnterNewScope() {
839 ShadowMaps.push_back(ShadowMap());
840}
841
842/// \brief Exit from the current scope.
843void ResultBuilder::ExitScope() {
Douglas Gregorfbcb5d62009-12-06 20:23:50 +0000844 for (ShadowMap::iterator E = ShadowMaps.back().begin(),
845 EEnd = ShadowMaps.back().end();
846 E != EEnd;
847 ++E)
848 E->second.Destroy();
849
Douglas Gregor86d9a522009-09-21 16:56:56 +0000850 ShadowMaps.pop_back();
851}
852
Douglas Gregor791215b2009-09-21 20:51:25 +0000853/// \brief Determines whether this given declaration will be found by
854/// ordinary name lookup.
855bool ResultBuilder::IsOrdinaryName(NamedDecl *ND) const {
Douglas Gregor4710e5b2010-05-28 00:49:12 +0000856 ND = cast<NamedDecl>(ND->getUnderlyingDecl());
857
Douglas Gregor791215b2009-09-21 20:51:25 +0000858 unsigned IDNS = Decl::IDNS_Ordinary;
859 if (SemaRef.getLangOptions().CPlusPlus)
Douglas Gregor9b30b262010-06-15 20:26:51 +0000860 IDNS |= Decl::IDNS_Tag | Decl::IDNS_Namespace | Decl::IDNS_Member;
Douglas Gregor1ca6ae82010-01-14 01:09:38 +0000861 else if (SemaRef.getLangOptions().ObjC1 && isa<ObjCIvarDecl>(ND))
862 return true;
863
Douglas Gregor791215b2009-09-21 20:51:25 +0000864 return ND->getIdentifierNamespace() & IDNS;
865}
866
Douglas Gregor01dfea02010-01-10 23:08:15 +0000867/// \brief Determines whether this given declaration will be found by
Douglas Gregor4710e5b2010-05-28 00:49:12 +0000868/// ordinary name lookup but is not a type name.
869bool ResultBuilder::IsOrdinaryNonTypeName(NamedDecl *ND) const {
870 ND = cast<NamedDecl>(ND->getUnderlyingDecl());
871 if (isa<TypeDecl>(ND) || isa<ObjCInterfaceDecl>(ND))
872 return false;
873
874 unsigned IDNS = Decl::IDNS_Ordinary;
875 if (SemaRef.getLangOptions().CPlusPlus)
Douglas Gregor9b30b262010-06-15 20:26:51 +0000876 IDNS |= Decl::IDNS_Tag | Decl::IDNS_Namespace | Decl::IDNS_Member;
Douglas Gregor4710e5b2010-05-28 00:49:12 +0000877 else if (SemaRef.getLangOptions().ObjC1 && isa<ObjCIvarDecl>(ND))
878 return true;
879
880 return ND->getIdentifierNamespace() & IDNS;
881}
882
Douglas Gregorf9578432010-07-28 21:50:18 +0000883bool ResultBuilder::IsIntegralConstantValue(NamedDecl *ND) const {
884 if (!IsOrdinaryNonTypeName(ND))
885 return 0;
886
887 if (ValueDecl *VD = dyn_cast<ValueDecl>(ND->getUnderlyingDecl()))
888 if (VD->getType()->isIntegralOrEnumerationType())
889 return true;
890
891 return false;
892}
893
Douglas Gregor4710e5b2010-05-28 00:49:12 +0000894/// \brief Determines whether this given declaration will be found by
Douglas Gregor01dfea02010-01-10 23:08:15 +0000895/// ordinary name lookup.
896bool ResultBuilder::IsOrdinaryNonValueName(NamedDecl *ND) const {
Douglas Gregor4710e5b2010-05-28 00:49:12 +0000897 ND = cast<NamedDecl>(ND->getUnderlyingDecl());
898
Douglas Gregor01dfea02010-01-10 23:08:15 +0000899 unsigned IDNS = Decl::IDNS_Ordinary;
900 if (SemaRef.getLangOptions().CPlusPlus)
John McCall0d6b1642010-04-23 18:46:30 +0000901 IDNS |= Decl::IDNS_Tag | Decl::IDNS_Namespace;
Douglas Gregor01dfea02010-01-10 23:08:15 +0000902
903 return (ND->getIdentifierNamespace() & IDNS) &&
Douglas Gregor4710e5b2010-05-28 00:49:12 +0000904 !isa<ValueDecl>(ND) && !isa<FunctionTemplateDecl>(ND) &&
905 !isa<ObjCPropertyDecl>(ND);
Douglas Gregor01dfea02010-01-10 23:08:15 +0000906}
907
Douglas Gregor86d9a522009-09-21 16:56:56 +0000908/// \brief Determines whether the given declaration is suitable as the
909/// start of a C++ nested-name-specifier, e.g., a class or namespace.
910bool ResultBuilder::IsNestedNameSpecifier(NamedDecl *ND) const {
911 // Allow us to find class templates, too.
912 if (ClassTemplateDecl *ClassTemplate = dyn_cast<ClassTemplateDecl>(ND))
913 ND = ClassTemplate->getTemplatedDecl();
914
915 return SemaRef.isAcceptableNestedNameSpecifier(ND);
916}
917
918/// \brief Determines whether the given declaration is an enumeration.
919bool ResultBuilder::IsEnum(NamedDecl *ND) const {
920 return isa<EnumDecl>(ND);
921}
922
923/// \brief Determines whether the given declaration is a class or struct.
924bool ResultBuilder::IsClassOrStruct(NamedDecl *ND) const {
925 // Allow us to find class templates, too.
926 if (ClassTemplateDecl *ClassTemplate = dyn_cast<ClassTemplateDecl>(ND))
927 ND = ClassTemplate->getTemplatedDecl();
928
929 if (RecordDecl *RD = dyn_cast<RecordDecl>(ND))
Abramo Bagnara465d41b2010-05-11 21:36:43 +0000930 return RD->getTagKind() == TTK_Class ||
931 RD->getTagKind() == TTK_Struct;
Douglas Gregor86d9a522009-09-21 16:56:56 +0000932
933 return false;
934}
935
936/// \brief Determines whether the given declaration is a union.
937bool ResultBuilder::IsUnion(NamedDecl *ND) const {
938 // Allow us to find class templates, too.
939 if (ClassTemplateDecl *ClassTemplate = dyn_cast<ClassTemplateDecl>(ND))
940 ND = ClassTemplate->getTemplatedDecl();
941
942 if (RecordDecl *RD = dyn_cast<RecordDecl>(ND))
Abramo Bagnara465d41b2010-05-11 21:36:43 +0000943 return RD->getTagKind() == TTK_Union;
Douglas Gregor86d9a522009-09-21 16:56:56 +0000944
945 return false;
946}
947
948/// \brief Determines whether the given declaration is a namespace.
949bool ResultBuilder::IsNamespace(NamedDecl *ND) const {
950 return isa<NamespaceDecl>(ND);
951}
952
953/// \brief Determines whether the given declaration is a namespace or
954/// namespace alias.
955bool ResultBuilder::IsNamespaceOrAlias(NamedDecl *ND) const {
956 return isa<NamespaceDecl>(ND) || isa<NamespaceAliasDecl>(ND);
957}
958
Douglas Gregor76282942009-12-11 17:31:05 +0000959/// \brief Determines whether the given declaration is a type.
Douglas Gregor86d9a522009-09-21 16:56:56 +0000960bool ResultBuilder::IsType(NamedDecl *ND) const {
Douglas Gregord32b0222010-08-24 01:06:58 +0000961 if (UsingShadowDecl *Using = dyn_cast<UsingShadowDecl>(ND))
962 ND = Using->getTargetDecl();
963
964 return isa<TypeDecl>(ND) || isa<ObjCInterfaceDecl>(ND);
Douglas Gregor86d9a522009-09-21 16:56:56 +0000965}
966
Douglas Gregor76282942009-12-11 17:31:05 +0000967/// \brief Determines which members of a class should be visible via
968/// "." or "->". Only value declarations, nested name specifiers, and
969/// using declarations thereof should show up.
Douglas Gregoreb5758b2009-09-23 22:26:46 +0000970bool ResultBuilder::IsMember(NamedDecl *ND) const {
Douglas Gregor76282942009-12-11 17:31:05 +0000971 if (UsingShadowDecl *Using = dyn_cast<UsingShadowDecl>(ND))
972 ND = Using->getTargetDecl();
973
Douglas Gregorce821962009-12-11 18:14:22 +0000974 return isa<ValueDecl>(ND) || isa<FunctionTemplateDecl>(ND) ||
975 isa<ObjCPropertyDecl>(ND);
Douglas Gregoreb5758b2009-09-23 22:26:46 +0000976}
977
Douglas Gregor8e254cf2010-05-27 23:06:34 +0000978static bool isObjCReceiverType(ASTContext &C, QualType T) {
979 T = C.getCanonicalType(T);
980 switch (T->getTypeClass()) {
981 case Type::ObjCObject:
982 case Type::ObjCInterface:
983 case Type::ObjCObjectPointer:
984 return true;
985
986 case Type::Builtin:
987 switch (cast<BuiltinType>(T)->getKind()) {
988 case BuiltinType::ObjCId:
989 case BuiltinType::ObjCClass:
990 case BuiltinType::ObjCSel:
991 return true;
992
993 default:
994 break;
995 }
996 return false;
997
998 default:
999 break;
1000 }
1001
1002 if (!C.getLangOptions().CPlusPlus)
1003 return false;
1004
1005 // FIXME: We could perform more analysis here to determine whether a
1006 // particular class type has any conversions to Objective-C types. For now,
1007 // just accept all class types.
1008 return T->isDependentType() || T->isRecordType();
1009}
1010
1011bool ResultBuilder::IsObjCMessageReceiver(NamedDecl *ND) const {
1012 QualType T = getDeclUsageType(SemaRef.Context, ND);
1013 if (T.isNull())
1014 return false;
1015
1016 T = SemaRef.Context.getBaseElementType(T);
1017 return isObjCReceiverType(SemaRef.Context, T);
1018}
1019
Douglas Gregorfb629412010-08-23 21:17:50 +00001020bool ResultBuilder::IsObjCCollection(NamedDecl *ND) const {
1021 if ((SemaRef.getLangOptions().CPlusPlus && !IsOrdinaryName(ND)) ||
1022 (!SemaRef.getLangOptions().CPlusPlus && !IsOrdinaryNonTypeName(ND)))
1023 return false;
1024
1025 QualType T = getDeclUsageType(SemaRef.Context, ND);
1026 if (T.isNull())
1027 return false;
1028
1029 T = SemaRef.Context.getBaseElementType(T);
1030 return T->isObjCObjectType() || T->isObjCObjectPointerType() ||
1031 T->isObjCIdType() ||
1032 (SemaRef.getLangOptions().CPlusPlus && T->isRecordType());
1033}
Douglas Gregor8e254cf2010-05-27 23:06:34 +00001034
Douglas Gregor80f4f4c2010-01-14 16:08:12 +00001035/// \rief Determines whether the given declaration is an Objective-C
1036/// instance variable.
1037bool ResultBuilder::IsObjCIvar(NamedDecl *ND) const {
1038 return isa<ObjCIvarDecl>(ND);
1039}
1040
Douglas Gregor1ca6ae82010-01-14 01:09:38 +00001041namespace {
1042 /// \brief Visible declaration consumer that adds a code-completion result
1043 /// for each visible declaration.
1044 class CodeCompletionDeclConsumer : public VisibleDeclConsumer {
1045 ResultBuilder &Results;
1046 DeclContext *CurContext;
1047
1048 public:
1049 CodeCompletionDeclConsumer(ResultBuilder &Results, DeclContext *CurContext)
1050 : Results(Results), CurContext(CurContext) { }
1051
Douglas Gregor0cc84042010-01-14 15:47:35 +00001052 virtual void FoundDecl(NamedDecl *ND, NamedDecl *Hiding, bool InBaseClass) {
1053 Results.AddResult(ND, CurContext, Hiding, InBaseClass);
Douglas Gregor1ca6ae82010-01-14 01:09:38 +00001054 }
1055 };
1056}
1057
Douglas Gregor86d9a522009-09-21 16:56:56 +00001058/// \brief Add type specifiers for the current language as keyword results.
Douglas Gregorbca403c2010-01-13 23:51:12 +00001059static void AddTypeSpecifierResults(const LangOptions &LangOpts,
Douglas Gregor86d9a522009-09-21 16:56:56 +00001060 ResultBuilder &Results) {
John McCall0a2c5e22010-08-25 06:19:51 +00001061 typedef CodeCompletionResult Result;
Douglas Gregor12e13132010-05-26 22:00:08 +00001062 Results.AddResult(Result("short", CCP_Type));
1063 Results.AddResult(Result("long", CCP_Type));
1064 Results.AddResult(Result("signed", CCP_Type));
1065 Results.AddResult(Result("unsigned", CCP_Type));
1066 Results.AddResult(Result("void", CCP_Type));
1067 Results.AddResult(Result("char", CCP_Type));
1068 Results.AddResult(Result("int", CCP_Type));
1069 Results.AddResult(Result("float", CCP_Type));
1070 Results.AddResult(Result("double", CCP_Type));
1071 Results.AddResult(Result("enum", CCP_Type));
1072 Results.AddResult(Result("struct", CCP_Type));
1073 Results.AddResult(Result("union", CCP_Type));
1074 Results.AddResult(Result("const", CCP_Type));
1075 Results.AddResult(Result("volatile", CCP_Type));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001076
Douglas Gregor86d9a522009-09-21 16:56:56 +00001077 if (LangOpts.C99) {
1078 // C99-specific
Douglas Gregor12e13132010-05-26 22:00:08 +00001079 Results.AddResult(Result("_Complex", CCP_Type));
1080 Results.AddResult(Result("_Imaginary", CCP_Type));
1081 Results.AddResult(Result("_Bool", CCP_Type));
1082 Results.AddResult(Result("restrict", CCP_Type));
Douglas Gregor86d9a522009-09-21 16:56:56 +00001083 }
1084
1085 if (LangOpts.CPlusPlus) {
1086 // C++-specific
Douglas Gregorb05496d2010-09-20 21:11:48 +00001087 Results.AddResult(Result("bool", CCP_Type +
1088 (LangOpts.ObjC1? CCD_bool_in_ObjC : 0)));
Douglas Gregor12e13132010-05-26 22:00:08 +00001089 Results.AddResult(Result("class", CCP_Type));
1090 Results.AddResult(Result("wchar_t", CCP_Type));
Douglas Gregor86d9a522009-09-21 16:56:56 +00001091
Douglas Gregorc8bddde2010-05-28 00:22:41 +00001092 // typename qualified-id
1093 CodeCompletionString *Pattern = new CodeCompletionString;
1094 Pattern->AddTypedTextChunk("typename");
1095 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
1096 Pattern->AddPlaceholderChunk("qualifier");
1097 Pattern->AddTextChunk("::");
1098 Pattern->AddPlaceholderChunk("name");
1099 Results.AddResult(Result(Pattern));
Douglas Gregord8e8a582010-05-25 21:41:55 +00001100
Douglas Gregor86d9a522009-09-21 16:56:56 +00001101 if (LangOpts.CPlusPlus0x) {
Douglas Gregor12e13132010-05-26 22:00:08 +00001102 Results.AddResult(Result("auto", CCP_Type));
1103 Results.AddResult(Result("char16_t", CCP_Type));
1104 Results.AddResult(Result("char32_t", CCP_Type));
Douglas Gregorc8bddde2010-05-28 00:22:41 +00001105
1106 CodeCompletionString *Pattern = new CodeCompletionString;
1107 Pattern->AddTypedTextChunk("decltype");
1108 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
1109 Pattern->AddPlaceholderChunk("expression");
1110 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
1111 Results.AddResult(Result(Pattern));
Douglas Gregor86d9a522009-09-21 16:56:56 +00001112 }
1113 }
1114
1115 // GNU extensions
1116 if (LangOpts.GNUMode) {
1117 // FIXME: Enable when we actually support decimal floating point.
Douglas Gregora4477812010-01-14 16:01:26 +00001118 // Results.AddResult(Result("_Decimal32"));
1119 // Results.AddResult(Result("_Decimal64"));
1120 // Results.AddResult(Result("_Decimal128"));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001121
Douglas Gregorc8bddde2010-05-28 00:22:41 +00001122 CodeCompletionString *Pattern = new CodeCompletionString;
1123 Pattern->AddTypedTextChunk("typeof");
1124 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
1125 Pattern->AddPlaceholderChunk("expression");
1126 Results.AddResult(Result(Pattern));
1127
1128 Pattern = new CodeCompletionString;
1129 Pattern->AddTypedTextChunk("typeof");
1130 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
1131 Pattern->AddPlaceholderChunk("type");
1132 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
1133 Results.AddResult(Result(Pattern));
Douglas Gregor86d9a522009-09-21 16:56:56 +00001134 }
1135}
1136
John McCallf312b1e2010-08-26 23:41:50 +00001137static void AddStorageSpecifiers(Sema::ParserCompletionContext CCC,
Douglas Gregor01dfea02010-01-10 23:08:15 +00001138 const LangOptions &LangOpts,
Douglas Gregor01dfea02010-01-10 23:08:15 +00001139 ResultBuilder &Results) {
John McCall0a2c5e22010-08-25 06:19:51 +00001140 typedef CodeCompletionResult Result;
Douglas Gregor01dfea02010-01-10 23:08:15 +00001141 // Note: we don't suggest either "auto" or "register", because both
1142 // are pointless as storage specifiers. Elsewhere, we suggest "auto"
1143 // in C++0x as a type specifier.
Douglas Gregora4477812010-01-14 16:01:26 +00001144 Results.AddResult(Result("extern"));
1145 Results.AddResult(Result("static"));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001146}
1147
John McCallf312b1e2010-08-26 23:41:50 +00001148static void AddFunctionSpecifiers(Sema::ParserCompletionContext CCC,
Douglas Gregor01dfea02010-01-10 23:08:15 +00001149 const LangOptions &LangOpts,
Douglas Gregor01dfea02010-01-10 23:08:15 +00001150 ResultBuilder &Results) {
John McCall0a2c5e22010-08-25 06:19:51 +00001151 typedef CodeCompletionResult Result;
Douglas Gregor01dfea02010-01-10 23:08:15 +00001152 switch (CCC) {
John McCallf312b1e2010-08-26 23:41:50 +00001153 case Sema::PCC_Class:
1154 case Sema::PCC_MemberTemplate:
Douglas Gregor01dfea02010-01-10 23:08:15 +00001155 if (LangOpts.CPlusPlus) {
Douglas Gregora4477812010-01-14 16:01:26 +00001156 Results.AddResult(Result("explicit"));
1157 Results.AddResult(Result("friend"));
1158 Results.AddResult(Result("mutable"));
1159 Results.AddResult(Result("virtual"));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001160 }
1161 // Fall through
1162
John McCallf312b1e2010-08-26 23:41:50 +00001163 case Sema::PCC_ObjCInterface:
1164 case Sema::PCC_ObjCImplementation:
1165 case Sema::PCC_Namespace:
1166 case Sema::PCC_Template:
Douglas Gregor01dfea02010-01-10 23:08:15 +00001167 if (LangOpts.CPlusPlus || LangOpts.C99)
Douglas Gregora4477812010-01-14 16:01:26 +00001168 Results.AddResult(Result("inline"));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001169 break;
1170
John McCallf312b1e2010-08-26 23:41:50 +00001171 case Sema::PCC_ObjCInstanceVariableList:
1172 case Sema::PCC_Expression:
1173 case Sema::PCC_Statement:
1174 case Sema::PCC_ForInit:
1175 case Sema::PCC_Condition:
1176 case Sema::PCC_RecoveryInFunction:
1177 case Sema::PCC_Type:
Douglas Gregor02688102010-09-14 23:59:36 +00001178 case Sema::PCC_ParenthesizedExpression:
Douglas Gregor01dfea02010-01-10 23:08:15 +00001179 break;
1180 }
1181}
1182
Douglas Gregorbca403c2010-01-13 23:51:12 +00001183static void AddObjCExpressionResults(ResultBuilder &Results, bool NeedAt);
1184static void AddObjCStatementResults(ResultBuilder &Results, bool NeedAt);
1185static void AddObjCVisibilityResults(const LangOptions &LangOpts,
Douglas Gregorc38c3e12010-01-13 21:54:15 +00001186 ResultBuilder &Results,
1187 bool NeedAt);
Douglas Gregorbca403c2010-01-13 23:51:12 +00001188static void AddObjCImplementationResults(const LangOptions &LangOpts,
Douglas Gregorb6ac2452010-01-13 21:24:21 +00001189 ResultBuilder &Results,
1190 bool NeedAt);
Douglas Gregorbca403c2010-01-13 23:51:12 +00001191static void AddObjCInterfaceResults(const LangOptions &LangOpts,
Douglas Gregorb6ac2452010-01-13 21:24:21 +00001192 ResultBuilder &Results,
1193 bool NeedAt);
Douglas Gregorbca403c2010-01-13 23:51:12 +00001194static void AddObjCTopLevelResults(ResultBuilder &Results, bool NeedAt);
Douglas Gregorb6ac2452010-01-13 21:24:21 +00001195
Douglas Gregorc8bddde2010-05-28 00:22:41 +00001196static void AddTypedefResult(ResultBuilder &Results) {
1197 CodeCompletionString *Pattern = new CodeCompletionString;
1198 Pattern->AddTypedTextChunk("typedef");
1199 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
1200 Pattern->AddPlaceholderChunk("type");
1201 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
1202 Pattern->AddPlaceholderChunk("name");
John McCall0a2c5e22010-08-25 06:19:51 +00001203 Results.AddResult(CodeCompletionResult(Pattern));
Douglas Gregorc8bddde2010-05-28 00:22:41 +00001204}
1205
John McCallf312b1e2010-08-26 23:41:50 +00001206static bool WantTypesInContext(Sema::ParserCompletionContext CCC,
Douglas Gregor4710e5b2010-05-28 00:49:12 +00001207 const LangOptions &LangOpts) {
Douglas Gregor4710e5b2010-05-28 00:49:12 +00001208 switch (CCC) {
John McCallf312b1e2010-08-26 23:41:50 +00001209 case Sema::PCC_Namespace:
1210 case Sema::PCC_Class:
1211 case Sema::PCC_ObjCInstanceVariableList:
1212 case Sema::PCC_Template:
1213 case Sema::PCC_MemberTemplate:
1214 case Sema::PCC_Statement:
1215 case Sema::PCC_RecoveryInFunction:
1216 case Sema::PCC_Type:
Douglas Gregor02688102010-09-14 23:59:36 +00001217 case Sema::PCC_ParenthesizedExpression:
Douglas Gregor4710e5b2010-05-28 00:49:12 +00001218 return true;
1219
John McCallf312b1e2010-08-26 23:41:50 +00001220 case Sema::PCC_Expression:
1221 case Sema::PCC_Condition:
Douglas Gregor02688102010-09-14 23:59:36 +00001222 return LangOpts.CPlusPlus;
1223
1224 case Sema::PCC_ObjCInterface:
1225 case Sema::PCC_ObjCImplementation:
Douglas Gregor4710e5b2010-05-28 00:49:12 +00001226 return false;
1227
John McCallf312b1e2010-08-26 23:41:50 +00001228 case Sema::PCC_ForInit:
Douglas Gregor02688102010-09-14 23:59:36 +00001229 return LangOpts.CPlusPlus || LangOpts.ObjC1 || LangOpts.C99;
Douglas Gregor4710e5b2010-05-28 00:49:12 +00001230 }
1231
1232 return false;
1233}
1234
Douglas Gregor01dfea02010-01-10 23:08:15 +00001235/// \brief Add language constructs that show up for "ordinary" names.
John McCallf312b1e2010-08-26 23:41:50 +00001236static void AddOrdinaryNameResults(Sema::ParserCompletionContext CCC,
Douglas Gregor01dfea02010-01-10 23:08:15 +00001237 Scope *S,
1238 Sema &SemaRef,
Douglas Gregor01dfea02010-01-10 23:08:15 +00001239 ResultBuilder &Results) {
John McCall0a2c5e22010-08-25 06:19:51 +00001240 typedef CodeCompletionResult Result;
Douglas Gregor01dfea02010-01-10 23:08:15 +00001241 switch (CCC) {
John McCallf312b1e2010-08-26 23:41:50 +00001242 case Sema::PCC_Namespace:
Douglas Gregorc8bddde2010-05-28 00:22:41 +00001243 if (SemaRef.getLangOptions().CPlusPlus) {
1244 CodeCompletionString *Pattern = 0;
1245
1246 if (Results.includeCodePatterns()) {
1247 // namespace <identifier> { declarations }
1248 CodeCompletionString *Pattern = new CodeCompletionString;
1249 Pattern->AddTypedTextChunk("namespace");
1250 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
1251 Pattern->AddPlaceholderChunk("identifier");
1252 Pattern->AddChunk(CodeCompletionString::CK_LeftBrace);
1253 Pattern->AddPlaceholderChunk("declarations");
1254 Pattern->AddChunk(CodeCompletionString::CK_VerticalSpace);
1255 Pattern->AddChunk(CodeCompletionString::CK_RightBrace);
1256 Results.AddResult(Result(Pattern));
1257 }
1258
Douglas Gregor01dfea02010-01-10 23:08:15 +00001259 // namespace identifier = identifier ;
1260 Pattern = new CodeCompletionString;
1261 Pattern->AddTypedTextChunk("namespace");
1262 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
Douglas Gregorc8bddde2010-05-28 00:22:41 +00001263 Pattern->AddPlaceholderChunk("name");
Douglas Gregor01dfea02010-01-10 23:08:15 +00001264 Pattern->AddChunk(CodeCompletionString::CK_Equal);
Douglas Gregorc8bddde2010-05-28 00:22:41 +00001265 Pattern->AddPlaceholderChunk("namespace");
Douglas Gregora4477812010-01-14 16:01:26 +00001266 Results.AddResult(Result(Pattern));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001267
1268 // Using directives
1269 Pattern = new CodeCompletionString;
1270 Pattern->AddTypedTextChunk("using");
1271 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
1272 Pattern->AddTextChunk("namespace");
1273 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
1274 Pattern->AddPlaceholderChunk("identifier");
Douglas Gregora4477812010-01-14 16:01:26 +00001275 Results.AddResult(Result(Pattern));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001276
1277 // asm(string-literal)
1278 Pattern = new CodeCompletionString;
1279 Pattern->AddTypedTextChunk("asm");
1280 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
1281 Pattern->AddPlaceholderChunk("string-literal");
1282 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
Douglas Gregora4477812010-01-14 16:01:26 +00001283 Results.AddResult(Result(Pattern));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001284
Douglas Gregorc8bddde2010-05-28 00:22:41 +00001285 if (Results.includeCodePatterns()) {
1286 // Explicit template instantiation
1287 Pattern = new CodeCompletionString;
1288 Pattern->AddTypedTextChunk("template");
1289 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
1290 Pattern->AddPlaceholderChunk("declaration");
1291 Results.AddResult(Result(Pattern));
1292 }
Douglas Gregor01dfea02010-01-10 23:08:15 +00001293 }
Douglas Gregorb6ac2452010-01-13 21:24:21 +00001294
1295 if (SemaRef.getLangOptions().ObjC1)
Douglas Gregorbca403c2010-01-13 23:51:12 +00001296 AddObjCTopLevelResults(Results, true);
Douglas Gregorb6ac2452010-01-13 21:24:21 +00001297
Douglas Gregorc8bddde2010-05-28 00:22:41 +00001298 AddTypedefResult(Results);
Douglas Gregor01dfea02010-01-10 23:08:15 +00001299 // Fall through
1300
John McCallf312b1e2010-08-26 23:41:50 +00001301 case Sema::PCC_Class:
Douglas Gregorc8bddde2010-05-28 00:22:41 +00001302 if (SemaRef.getLangOptions().CPlusPlus) {
Douglas Gregor01dfea02010-01-10 23:08:15 +00001303 // Using declaration
1304 CodeCompletionString *Pattern = new CodeCompletionString;
1305 Pattern->AddTypedTextChunk("using");
1306 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
Douglas Gregorc8bddde2010-05-28 00:22:41 +00001307 Pattern->AddPlaceholderChunk("qualifier");
1308 Pattern->AddTextChunk("::");
1309 Pattern->AddPlaceholderChunk("name");
Douglas Gregora4477812010-01-14 16:01:26 +00001310 Results.AddResult(Result(Pattern));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001311
Douglas Gregorc8bddde2010-05-28 00:22:41 +00001312 // using typename qualifier::name (only in a dependent context)
Douglas Gregor01dfea02010-01-10 23:08:15 +00001313 if (SemaRef.CurContext->isDependentContext()) {
1314 Pattern = new CodeCompletionString;
1315 Pattern->AddTypedTextChunk("using");
1316 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
1317 Pattern->AddTextChunk("typename");
1318 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
Douglas Gregorc8bddde2010-05-28 00:22:41 +00001319 Pattern->AddPlaceholderChunk("qualifier");
1320 Pattern->AddTextChunk("::");
1321 Pattern->AddPlaceholderChunk("name");
Douglas Gregora4477812010-01-14 16:01:26 +00001322 Results.AddResult(Result(Pattern));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001323 }
1324
John McCallf312b1e2010-08-26 23:41:50 +00001325 if (CCC == Sema::PCC_Class) {
Douglas Gregorc8bddde2010-05-28 00:22:41 +00001326 AddTypedefResult(Results);
1327
Douglas Gregor01dfea02010-01-10 23:08:15 +00001328 // public:
1329 Pattern = new CodeCompletionString;
1330 Pattern->AddTypedTextChunk("public");
1331 Pattern->AddChunk(CodeCompletionString::CK_Colon);
Douglas Gregora4477812010-01-14 16:01:26 +00001332 Results.AddResult(Result(Pattern));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001333
1334 // protected:
1335 Pattern = new CodeCompletionString;
1336 Pattern->AddTypedTextChunk("protected");
1337 Pattern->AddChunk(CodeCompletionString::CK_Colon);
Douglas Gregora4477812010-01-14 16:01:26 +00001338 Results.AddResult(Result(Pattern));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001339
1340 // private:
1341 Pattern = new CodeCompletionString;
1342 Pattern->AddTypedTextChunk("private");
1343 Pattern->AddChunk(CodeCompletionString::CK_Colon);
Douglas Gregora4477812010-01-14 16:01:26 +00001344 Results.AddResult(Result(Pattern));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001345 }
1346 }
1347 // Fall through
1348
John McCallf312b1e2010-08-26 23:41:50 +00001349 case Sema::PCC_Template:
1350 case Sema::PCC_MemberTemplate:
Douglas Gregord8e8a582010-05-25 21:41:55 +00001351 if (SemaRef.getLangOptions().CPlusPlus && Results.includeCodePatterns()) {
Douglas Gregor01dfea02010-01-10 23:08:15 +00001352 // template < parameters >
1353 CodeCompletionString *Pattern = new CodeCompletionString;
1354 Pattern->AddTypedTextChunk("template");
1355 Pattern->AddChunk(CodeCompletionString::CK_LeftAngle);
1356 Pattern->AddPlaceholderChunk("parameters");
1357 Pattern->AddChunk(CodeCompletionString::CK_RightAngle);
Douglas Gregora4477812010-01-14 16:01:26 +00001358 Results.AddResult(Result(Pattern));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001359 }
1360
Douglas Gregorbca403c2010-01-13 23:51:12 +00001361 AddStorageSpecifiers(CCC, SemaRef.getLangOptions(), Results);
1362 AddFunctionSpecifiers(CCC, SemaRef.getLangOptions(), Results);
Douglas Gregor01dfea02010-01-10 23:08:15 +00001363 break;
1364
John McCallf312b1e2010-08-26 23:41:50 +00001365 case Sema::PCC_ObjCInterface:
Douglas Gregorbca403c2010-01-13 23:51:12 +00001366 AddObjCInterfaceResults(SemaRef.getLangOptions(), Results, true);
1367 AddStorageSpecifiers(CCC, SemaRef.getLangOptions(), Results);
1368 AddFunctionSpecifiers(CCC, SemaRef.getLangOptions(), Results);
Douglas Gregorb6ac2452010-01-13 21:24:21 +00001369 break;
1370
John McCallf312b1e2010-08-26 23:41:50 +00001371 case Sema::PCC_ObjCImplementation:
Douglas Gregorbca403c2010-01-13 23:51:12 +00001372 AddObjCImplementationResults(SemaRef.getLangOptions(), Results, true);
1373 AddStorageSpecifiers(CCC, SemaRef.getLangOptions(), Results);
1374 AddFunctionSpecifiers(CCC, SemaRef.getLangOptions(), Results);
Douglas Gregorb6ac2452010-01-13 21:24:21 +00001375 break;
1376
John McCallf312b1e2010-08-26 23:41:50 +00001377 case Sema::PCC_ObjCInstanceVariableList:
Douglas Gregorbca403c2010-01-13 23:51:12 +00001378 AddObjCVisibilityResults(SemaRef.getLangOptions(), Results, true);
Douglas Gregorc38c3e12010-01-13 21:54:15 +00001379 break;
1380
John McCallf312b1e2010-08-26 23:41:50 +00001381 case Sema::PCC_RecoveryInFunction:
1382 case Sema::PCC_Statement: {
Douglas Gregorc8bddde2010-05-28 00:22:41 +00001383 AddTypedefResult(Results);
Douglas Gregor01dfea02010-01-10 23:08:15 +00001384
1385 CodeCompletionString *Pattern = 0;
Douglas Gregord8e8a582010-05-25 21:41:55 +00001386 if (SemaRef.getLangOptions().CPlusPlus && Results.includeCodePatterns()) {
Douglas Gregor01dfea02010-01-10 23:08:15 +00001387 Pattern = new CodeCompletionString;
1388 Pattern->AddTypedTextChunk("try");
1389 Pattern->AddChunk(CodeCompletionString::CK_LeftBrace);
1390 Pattern->AddPlaceholderChunk("statements");
1391 Pattern->AddChunk(CodeCompletionString::CK_VerticalSpace);
1392 Pattern->AddChunk(CodeCompletionString::CK_RightBrace);
1393 Pattern->AddTextChunk("catch");
1394 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
1395 Pattern->AddPlaceholderChunk("declaration");
1396 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
1397 Pattern->AddChunk(CodeCompletionString::CK_LeftBrace);
1398 Pattern->AddPlaceholderChunk("statements");
1399 Pattern->AddChunk(CodeCompletionString::CK_VerticalSpace);
1400 Pattern->AddChunk(CodeCompletionString::CK_RightBrace);
Douglas Gregora4477812010-01-14 16:01:26 +00001401 Results.AddResult(Result(Pattern));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001402 }
Douglas Gregorb6ac2452010-01-13 21:24:21 +00001403 if (SemaRef.getLangOptions().ObjC1)
Douglas Gregorbca403c2010-01-13 23:51:12 +00001404 AddObjCStatementResults(Results, true);
Douglas Gregorb6ac2452010-01-13 21:24:21 +00001405
Douglas Gregord8e8a582010-05-25 21:41:55 +00001406 if (Results.includeCodePatterns()) {
1407 // if (condition) { statements }
1408 Pattern = new CodeCompletionString;
1409 Pattern->AddTypedTextChunk("if");
1410 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
1411 if (SemaRef.getLangOptions().CPlusPlus)
1412 Pattern->AddPlaceholderChunk("condition");
1413 else
1414 Pattern->AddPlaceholderChunk("expression");
1415 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
1416 Pattern->AddChunk(CodeCompletionString::CK_LeftBrace);
1417 Pattern->AddPlaceholderChunk("statements");
1418 Pattern->AddChunk(CodeCompletionString::CK_VerticalSpace);
1419 Pattern->AddChunk(CodeCompletionString::CK_RightBrace);
1420 Results.AddResult(Result(Pattern));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001421
Douglas Gregord8e8a582010-05-25 21:41:55 +00001422 // switch (condition) { }
1423 Pattern = new CodeCompletionString;
1424 Pattern->AddTypedTextChunk("switch");
1425 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
1426 if (SemaRef.getLangOptions().CPlusPlus)
1427 Pattern->AddPlaceholderChunk("condition");
1428 else
1429 Pattern->AddPlaceholderChunk("expression");
1430 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
1431 Pattern->AddChunk(CodeCompletionString::CK_LeftBrace);
1432 Pattern->AddChunk(CodeCompletionString::CK_VerticalSpace);
1433 Pattern->AddChunk(CodeCompletionString::CK_RightBrace);
1434 Results.AddResult(Result(Pattern));
1435 }
1436
Douglas Gregor01dfea02010-01-10 23:08:15 +00001437 // Switch-specific statements.
John McCall781472f2010-08-25 08:40:02 +00001438 if (!SemaRef.getCurFunction()->SwitchStack.empty()) {
Douglas Gregor01dfea02010-01-10 23:08:15 +00001439 // case expression:
1440 Pattern = new CodeCompletionString;
1441 Pattern->AddTypedTextChunk("case");
Douglas Gregorc8bddde2010-05-28 00:22:41 +00001442 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
Douglas Gregor01dfea02010-01-10 23:08:15 +00001443 Pattern->AddPlaceholderChunk("expression");
1444 Pattern->AddChunk(CodeCompletionString::CK_Colon);
Douglas Gregora4477812010-01-14 16:01:26 +00001445 Results.AddResult(Result(Pattern));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001446
1447 // default:
1448 Pattern = new CodeCompletionString;
1449 Pattern->AddTypedTextChunk("default");
1450 Pattern->AddChunk(CodeCompletionString::CK_Colon);
Douglas Gregora4477812010-01-14 16:01:26 +00001451 Results.AddResult(Result(Pattern));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001452 }
1453
Douglas Gregord8e8a582010-05-25 21:41:55 +00001454 if (Results.includeCodePatterns()) {
1455 /// while (condition) { statements }
1456 Pattern = new CodeCompletionString;
1457 Pattern->AddTypedTextChunk("while");
1458 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
1459 if (SemaRef.getLangOptions().CPlusPlus)
1460 Pattern->AddPlaceholderChunk("condition");
1461 else
1462 Pattern->AddPlaceholderChunk("expression");
1463 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
1464 Pattern->AddChunk(CodeCompletionString::CK_LeftBrace);
1465 Pattern->AddPlaceholderChunk("statements");
1466 Pattern->AddChunk(CodeCompletionString::CK_VerticalSpace);
1467 Pattern->AddChunk(CodeCompletionString::CK_RightBrace);
1468 Results.AddResult(Result(Pattern));
1469
1470 // do { statements } while ( expression );
1471 Pattern = new CodeCompletionString;
1472 Pattern->AddTypedTextChunk("do");
1473 Pattern->AddChunk(CodeCompletionString::CK_LeftBrace);
1474 Pattern->AddPlaceholderChunk("statements");
1475 Pattern->AddChunk(CodeCompletionString::CK_VerticalSpace);
1476 Pattern->AddChunk(CodeCompletionString::CK_RightBrace);
1477 Pattern->AddTextChunk("while");
1478 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
Douglas Gregor01dfea02010-01-10 23:08:15 +00001479 Pattern->AddPlaceholderChunk("expression");
Douglas Gregord8e8a582010-05-25 21:41:55 +00001480 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
1481 Results.AddResult(Result(Pattern));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001482
Douglas Gregord8e8a582010-05-25 21:41:55 +00001483 // for ( for-init-statement ; condition ; expression ) { statements }
1484 Pattern = new CodeCompletionString;
1485 Pattern->AddTypedTextChunk("for");
1486 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
1487 if (SemaRef.getLangOptions().CPlusPlus || SemaRef.getLangOptions().C99)
1488 Pattern->AddPlaceholderChunk("init-statement");
1489 else
1490 Pattern->AddPlaceholderChunk("init-expression");
1491 Pattern->AddChunk(CodeCompletionString::CK_SemiColon);
1492 Pattern->AddPlaceholderChunk("condition");
1493 Pattern->AddChunk(CodeCompletionString::CK_SemiColon);
1494 Pattern->AddPlaceholderChunk("inc-expression");
1495 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
1496 Pattern->AddChunk(CodeCompletionString::CK_LeftBrace);
1497 Pattern->AddPlaceholderChunk("statements");
1498 Pattern->AddChunk(CodeCompletionString::CK_VerticalSpace);
1499 Pattern->AddChunk(CodeCompletionString::CK_RightBrace);
1500 Results.AddResult(Result(Pattern));
1501 }
Douglas Gregor01dfea02010-01-10 23:08:15 +00001502
1503 if (S->getContinueParent()) {
1504 // continue ;
1505 Pattern = new CodeCompletionString;
1506 Pattern->AddTypedTextChunk("continue");
Douglas Gregora4477812010-01-14 16:01:26 +00001507 Results.AddResult(Result(Pattern));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001508 }
1509
1510 if (S->getBreakParent()) {
1511 // break ;
1512 Pattern = new CodeCompletionString;
1513 Pattern->AddTypedTextChunk("break");
Douglas Gregora4477812010-01-14 16:01:26 +00001514 Results.AddResult(Result(Pattern));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001515 }
1516
1517 // "return expression ;" or "return ;", depending on whether we
1518 // know the function is void or not.
1519 bool isVoid = false;
1520 if (FunctionDecl *Function = dyn_cast<FunctionDecl>(SemaRef.CurContext))
1521 isVoid = Function->getResultType()->isVoidType();
1522 else if (ObjCMethodDecl *Method
1523 = dyn_cast<ObjCMethodDecl>(SemaRef.CurContext))
1524 isVoid = Method->getResultType()->isVoidType();
Douglas Gregor9ea9bdb2010-03-01 23:15:13 +00001525 else if (SemaRef.getCurBlock() &&
1526 !SemaRef.getCurBlock()->ReturnType.isNull())
1527 isVoid = SemaRef.getCurBlock()->ReturnType->isVoidType();
Douglas Gregor01dfea02010-01-10 23:08:15 +00001528 Pattern = new CodeCompletionString;
1529 Pattern->AddTypedTextChunk("return");
Douglas Gregor93298002010-02-18 04:06:48 +00001530 if (!isVoid) {
1531 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
Douglas Gregor01dfea02010-01-10 23:08:15 +00001532 Pattern->AddPlaceholderChunk("expression");
Douglas Gregor93298002010-02-18 04:06:48 +00001533 }
Douglas Gregora4477812010-01-14 16:01:26 +00001534 Results.AddResult(Result(Pattern));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001535
Douglas Gregorc8bddde2010-05-28 00:22:41 +00001536 // goto identifier ;
1537 Pattern = new CodeCompletionString;
1538 Pattern->AddTypedTextChunk("goto");
1539 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
1540 Pattern->AddPlaceholderChunk("label");
1541 Results.AddResult(Result(Pattern));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001542
Douglas Gregorc8bddde2010-05-28 00:22:41 +00001543 // Using directives
1544 Pattern = new CodeCompletionString;
1545 Pattern->AddTypedTextChunk("using");
1546 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
1547 Pattern->AddTextChunk("namespace");
1548 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
1549 Pattern->AddPlaceholderChunk("identifier");
1550 Results.AddResult(Result(Pattern));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001551 }
1552
1553 // Fall through (for statement expressions).
John McCallf312b1e2010-08-26 23:41:50 +00001554 case Sema::PCC_ForInit:
1555 case Sema::PCC_Condition:
Douglas Gregorbca403c2010-01-13 23:51:12 +00001556 AddStorageSpecifiers(CCC, SemaRef.getLangOptions(), Results);
Douglas Gregor01dfea02010-01-10 23:08:15 +00001557 // Fall through: conditions and statements can have expressions.
1558
Douglas Gregor02688102010-09-14 23:59:36 +00001559 case Sema::PCC_ParenthesizedExpression:
John McCallf312b1e2010-08-26 23:41:50 +00001560 case Sema::PCC_Expression: {
Douglas Gregor01dfea02010-01-10 23:08:15 +00001561 CodeCompletionString *Pattern = 0;
1562 if (SemaRef.getLangOptions().CPlusPlus) {
1563 // 'this', if we're in a non-static member function.
1564 if (CXXMethodDecl *Method = dyn_cast<CXXMethodDecl>(SemaRef.CurContext))
1565 if (!Method->isStatic())
Douglas Gregora4477812010-01-14 16:01:26 +00001566 Results.AddResult(Result("this"));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001567
1568 // true, false
Douglas Gregora4477812010-01-14 16:01:26 +00001569 Results.AddResult(Result("true"));
1570 Results.AddResult(Result("false"));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001571
Douglas Gregorc8bddde2010-05-28 00:22:41 +00001572 // dynamic_cast < type-id > ( expression )
1573 Pattern = new CodeCompletionString;
1574 Pattern->AddTypedTextChunk("dynamic_cast");
1575 Pattern->AddChunk(CodeCompletionString::CK_LeftAngle);
1576 Pattern->AddPlaceholderChunk("type");
1577 Pattern->AddChunk(CodeCompletionString::CK_RightAngle);
1578 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
1579 Pattern->AddPlaceholderChunk("expression");
1580 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
1581 Results.AddResult(Result(Pattern));
1582
1583 // static_cast < type-id > ( expression )
1584 Pattern = new CodeCompletionString;
1585 Pattern->AddTypedTextChunk("static_cast");
1586 Pattern->AddChunk(CodeCompletionString::CK_LeftAngle);
1587 Pattern->AddPlaceholderChunk("type");
1588 Pattern->AddChunk(CodeCompletionString::CK_RightAngle);
1589 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
1590 Pattern->AddPlaceholderChunk("expression");
1591 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
1592 Results.AddResult(Result(Pattern));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001593
Douglas Gregorc8bddde2010-05-28 00:22:41 +00001594 // reinterpret_cast < type-id > ( expression )
1595 Pattern = new CodeCompletionString;
1596 Pattern->AddTypedTextChunk("reinterpret_cast");
1597 Pattern->AddChunk(CodeCompletionString::CK_LeftAngle);
1598 Pattern->AddPlaceholderChunk("type");
1599 Pattern->AddChunk(CodeCompletionString::CK_RightAngle);
1600 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
1601 Pattern->AddPlaceholderChunk("expression");
1602 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
1603 Results.AddResult(Result(Pattern));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001604
Douglas Gregorc8bddde2010-05-28 00:22:41 +00001605 // const_cast < type-id > ( expression )
1606 Pattern = new CodeCompletionString;
1607 Pattern->AddTypedTextChunk("const_cast");
1608 Pattern->AddChunk(CodeCompletionString::CK_LeftAngle);
1609 Pattern->AddPlaceholderChunk("type");
1610 Pattern->AddChunk(CodeCompletionString::CK_RightAngle);
1611 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
1612 Pattern->AddPlaceholderChunk("expression");
1613 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
1614 Results.AddResult(Result(Pattern));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001615
Douglas Gregorc8bddde2010-05-28 00:22:41 +00001616 // typeid ( expression-or-type )
1617 Pattern = new CodeCompletionString;
1618 Pattern->AddTypedTextChunk("typeid");
1619 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
1620 Pattern->AddPlaceholderChunk("expression-or-type");
1621 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
1622 Results.AddResult(Result(Pattern));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001623
Douglas Gregorc8bddde2010-05-28 00:22:41 +00001624 // new T ( ... )
1625 Pattern = new CodeCompletionString;
1626 Pattern->AddTypedTextChunk("new");
1627 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
1628 Pattern->AddPlaceholderChunk("type");
1629 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
1630 Pattern->AddPlaceholderChunk("expressions");
1631 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
1632 Results.AddResult(Result(Pattern));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001633
Douglas Gregorc8bddde2010-05-28 00:22:41 +00001634 // new T [ ] ( ... )
1635 Pattern = new CodeCompletionString;
1636 Pattern->AddTypedTextChunk("new");
1637 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
1638 Pattern->AddPlaceholderChunk("type");
1639 Pattern->AddChunk(CodeCompletionString::CK_LeftBracket);
1640 Pattern->AddPlaceholderChunk("size");
1641 Pattern->AddChunk(CodeCompletionString::CK_RightBracket);
1642 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
1643 Pattern->AddPlaceholderChunk("expressions");
1644 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
1645 Results.AddResult(Result(Pattern));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001646
Douglas Gregorc8bddde2010-05-28 00:22:41 +00001647 // delete expression
1648 Pattern = new CodeCompletionString;
1649 Pattern->AddTypedTextChunk("delete");
1650 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
1651 Pattern->AddPlaceholderChunk("expression");
1652 Results.AddResult(Result(Pattern));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001653
Douglas Gregorc8bddde2010-05-28 00:22:41 +00001654 // delete [] expression
1655 Pattern = new CodeCompletionString;
1656 Pattern->AddTypedTextChunk("delete");
1657 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
1658 Pattern->AddChunk(CodeCompletionString::CK_LeftBracket);
1659 Pattern->AddChunk(CodeCompletionString::CK_RightBracket);
1660 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
1661 Pattern->AddPlaceholderChunk("expression");
1662 Results.AddResult(Result(Pattern));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001663
Douglas Gregorc8bddde2010-05-28 00:22:41 +00001664 // throw expression
1665 Pattern = new CodeCompletionString;
1666 Pattern->AddTypedTextChunk("throw");
1667 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
1668 Pattern->AddPlaceholderChunk("expression");
1669 Results.AddResult(Result(Pattern));
Douglas Gregor12e13132010-05-26 22:00:08 +00001670
1671 // FIXME: Rethrow?
Douglas Gregor01dfea02010-01-10 23:08:15 +00001672 }
1673
1674 if (SemaRef.getLangOptions().ObjC1) {
1675 // Add "super", if we're in an Objective-C class with a superclass.
Ted Kremenek681e2562010-05-31 21:43:10 +00001676 if (ObjCMethodDecl *Method = SemaRef.getCurMethodDecl()) {
1677 // The interface can be NULL.
1678 if (ObjCInterfaceDecl *ID = Method->getClassInterface())
1679 if (ID->getSuperClass())
1680 Results.AddResult(Result("super"));
1681 }
1682
Douglas Gregorbca403c2010-01-13 23:51:12 +00001683 AddObjCExpressionResults(Results, true);
Douglas Gregor01dfea02010-01-10 23:08:15 +00001684 }
1685
Douglas Gregorc8bddde2010-05-28 00:22:41 +00001686 // sizeof expression
1687 Pattern = new CodeCompletionString;
1688 Pattern->AddTypedTextChunk("sizeof");
1689 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
1690 Pattern->AddPlaceholderChunk("expression-or-type");
1691 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
1692 Results.AddResult(Result(Pattern));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001693 break;
1694 }
Douglas Gregord32b0222010-08-24 01:06:58 +00001695
John McCallf312b1e2010-08-26 23:41:50 +00001696 case Sema::PCC_Type:
Douglas Gregord32b0222010-08-24 01:06:58 +00001697 break;
Douglas Gregor01dfea02010-01-10 23:08:15 +00001698 }
1699
Douglas Gregor4710e5b2010-05-28 00:49:12 +00001700 if (WantTypesInContext(CCC, SemaRef.getLangOptions()))
1701 AddTypeSpecifierResults(SemaRef.getLangOptions(), Results);
Douglas Gregor01dfea02010-01-10 23:08:15 +00001702
John McCallf312b1e2010-08-26 23:41:50 +00001703 if (SemaRef.getLangOptions().CPlusPlus && CCC != Sema::PCC_Type)
Douglas Gregora4477812010-01-14 16:01:26 +00001704 Results.AddResult(Result("operator"));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001705}
1706
Douglas Gregorff5ce6e2009-12-18 18:53:37 +00001707/// \brief If the given declaration has an associated type, add it as a result
1708/// type chunk.
1709static void AddResultTypeChunk(ASTContext &Context,
1710 NamedDecl *ND,
1711 CodeCompletionString *Result) {
1712 if (!ND)
1713 return;
1714
1715 // Determine the type of the declaration (if it has a type).
1716 QualType T;
1717 if (FunctionDecl *Function = dyn_cast<FunctionDecl>(ND))
1718 T = Function->getResultType();
1719 else if (ObjCMethodDecl *Method = dyn_cast<ObjCMethodDecl>(ND))
1720 T = Method->getResultType();
1721 else if (FunctionTemplateDecl *FunTmpl = dyn_cast<FunctionTemplateDecl>(ND))
1722 T = FunTmpl->getTemplatedDecl()->getResultType();
1723 else if (EnumConstantDecl *Enumerator = dyn_cast<EnumConstantDecl>(ND))
1724 T = Context.getTypeDeclType(cast<TypeDecl>(Enumerator->getDeclContext()));
1725 else if (isa<UnresolvedUsingValueDecl>(ND)) {
1726 /* Do nothing: ignore unresolved using declarations*/
1727 } else if (ValueDecl *Value = dyn_cast<ValueDecl>(ND))
1728 T = Value->getType();
1729 else if (ObjCPropertyDecl *Property = dyn_cast<ObjCPropertyDecl>(ND))
1730 T = Property->getType();
1731
1732 if (T.isNull() || Context.hasSameType(T, Context.DependentTy))
1733 return;
1734
Douglas Gregor84139d62010-04-05 21:25:31 +00001735 PrintingPolicy Policy(Context.PrintingPolicy);
1736 Policy.AnonymousTagLocations = false;
1737
Douglas Gregorff5ce6e2009-12-18 18:53:37 +00001738 std::string TypeStr;
Douglas Gregor84139d62010-04-05 21:25:31 +00001739 T.getAsStringInternal(TypeStr, Policy);
Douglas Gregorff5ce6e2009-12-18 18:53:37 +00001740 Result->AddResultTypeChunk(TypeStr);
1741}
1742
Douglas Gregoraaa107a2010-08-23 23:51:41 +00001743static void MaybeAddSentinel(ASTContext &Context, NamedDecl *FunctionOrMethod,
1744 CodeCompletionString *Result) {
1745 if (SentinelAttr *Sentinel = FunctionOrMethod->getAttr<SentinelAttr>())
1746 if (Sentinel->getSentinel() == 0) {
1747 if (Context.getLangOptions().ObjC1 &&
1748 Context.Idents.get("nil").hasMacroDefinition())
1749 Result->AddTextChunk(", nil");
1750 else if (Context.Idents.get("NULL").hasMacroDefinition())
1751 Result->AddTextChunk(", NULL");
1752 else
1753 Result->AddTextChunk(", (void*)0");
1754 }
1755}
1756
Douglas Gregor83482d12010-08-24 16:15:59 +00001757static std::string FormatFunctionParameter(ASTContext &Context,
Douglas Gregoraba48082010-08-29 19:47:46 +00001758 ParmVarDecl *Param,
1759 bool SuppressName = false) {
Douglas Gregor83482d12010-08-24 16:15:59 +00001760 bool ObjCMethodParam = isa<ObjCMethodDecl>(Param->getDeclContext());
1761 if (Param->getType()->isDependentType() ||
1762 !Param->getType()->isBlockPointerType()) {
1763 // The argument for a dependent or non-block parameter is a placeholder
1764 // containing that parameter's type.
1765 std::string Result;
1766
Douglas Gregoraba48082010-08-29 19:47:46 +00001767 if (Param->getIdentifier() && !ObjCMethodParam && !SuppressName)
Douglas Gregor83482d12010-08-24 16:15:59 +00001768 Result = Param->getIdentifier()->getName();
1769
1770 Param->getType().getAsStringInternal(Result,
1771 Context.PrintingPolicy);
1772
1773 if (ObjCMethodParam) {
1774 Result = "(" + Result;
1775 Result += ")";
Douglas Gregoraba48082010-08-29 19:47:46 +00001776 if (Param->getIdentifier() && !SuppressName)
Douglas Gregor83482d12010-08-24 16:15:59 +00001777 Result += Param->getIdentifier()->getName();
1778 }
1779 return Result;
1780 }
1781
1782 // The argument for a block pointer parameter is a block literal with
1783 // the appropriate type.
1784 FunctionProtoTypeLoc *Block = 0;
1785 TypeLoc TL;
1786 if (TypeSourceInfo *TSInfo = Param->getTypeSourceInfo()) {
1787 TL = TSInfo->getTypeLoc().getUnqualifiedLoc();
1788 while (true) {
1789 // Look through typedefs.
1790 if (TypedefTypeLoc *TypedefTL = dyn_cast<TypedefTypeLoc>(&TL)) {
1791 if (TypeSourceInfo *InnerTSInfo
1792 = TypedefTL->getTypedefDecl()->getTypeSourceInfo()) {
1793 TL = InnerTSInfo->getTypeLoc().getUnqualifiedLoc();
1794 continue;
1795 }
1796 }
1797
1798 // Look through qualified types
1799 if (QualifiedTypeLoc *QualifiedTL = dyn_cast<QualifiedTypeLoc>(&TL)) {
1800 TL = QualifiedTL->getUnqualifiedLoc();
1801 continue;
1802 }
1803
1804 // Try to get the function prototype behind the block pointer type,
1805 // then we're done.
1806 if (BlockPointerTypeLoc *BlockPtr
1807 = dyn_cast<BlockPointerTypeLoc>(&TL)) {
1808 TL = BlockPtr->getPointeeLoc();
1809 Block = dyn_cast<FunctionProtoTypeLoc>(&TL);
1810 }
1811 break;
1812 }
1813 }
1814
1815 if (!Block) {
1816 // We were unable to find a FunctionProtoTypeLoc with parameter names
1817 // for the block; just use the parameter type as a placeholder.
1818 std::string Result;
1819 Param->getType().getUnqualifiedType().
1820 getAsStringInternal(Result, Context.PrintingPolicy);
1821
1822 if (ObjCMethodParam) {
1823 Result = "(" + Result;
1824 Result += ")";
1825 if (Param->getIdentifier())
1826 Result += Param->getIdentifier()->getName();
1827 }
1828
1829 return Result;
1830 }
1831
1832 // We have the function prototype behind the block pointer type, as it was
1833 // written in the source.
Douglas Gregor38276252010-09-08 22:47:51 +00001834 std::string Result;
1835 QualType ResultType = Block->getTypePtr()->getResultType();
1836 if (!ResultType->isVoidType())
1837 ResultType.getAsStringInternal(Result, Context.PrintingPolicy);
1838
1839 Result = '^' + Result;
1840 if (Block->getNumArgs() == 0) {
1841 if (Block->getTypePtr()->isVariadic())
1842 Result += "(...)";
1843 } else {
1844 Result += "(";
1845 for (unsigned I = 0, N = Block->getNumArgs(); I != N; ++I) {
1846 if (I)
1847 Result += ", ";
1848 Result += FormatFunctionParameter(Context, Block->getArg(I));
1849
1850 if (I == N - 1 && Block->getTypePtr()->isVariadic())
1851 Result += ", ...";
1852 }
1853 Result += ")";
Douglas Gregore17794f2010-08-31 05:13:43 +00001854 }
Douglas Gregor38276252010-09-08 22:47:51 +00001855
Douglas Gregor83482d12010-08-24 16:15:59 +00001856 return Result;
1857}
1858
Douglas Gregor86d9a522009-09-21 16:56:56 +00001859/// \brief Add function parameter chunks to the given code completion string.
1860static void AddFunctionParameterChunks(ASTContext &Context,
1861 FunctionDecl *Function,
1862 CodeCompletionString *Result) {
Douglas Gregor0c8296d2009-11-07 00:00:49 +00001863 typedef CodeCompletionString::Chunk Chunk;
1864
Douglas Gregor86d9a522009-09-21 16:56:56 +00001865 CodeCompletionString *CCStr = Result;
1866
1867 for (unsigned P = 0, N = Function->getNumParams(); P != N; ++P) {
1868 ParmVarDecl *Param = Function->getParamDecl(P);
1869
1870 if (Param->hasDefaultArg()) {
1871 // When we see an optional default argument, put that argument and
1872 // the remaining default arguments into a new, optional string.
1873 CodeCompletionString *Opt = new CodeCompletionString;
1874 CCStr->AddOptionalChunk(std::auto_ptr<CodeCompletionString>(Opt));
1875 CCStr = Opt;
1876 }
1877
1878 if (P != 0)
Douglas Gregor0c8296d2009-11-07 00:00:49 +00001879 CCStr->AddChunk(Chunk(CodeCompletionString::CK_Comma));
Douglas Gregor86d9a522009-09-21 16:56:56 +00001880
1881 // Format the placeholder string.
Douglas Gregor83482d12010-08-24 16:15:59 +00001882 std::string PlaceholderStr = FormatFunctionParameter(Context, Param);
1883
Douglas Gregore17794f2010-08-31 05:13:43 +00001884 if (Function->isVariadic() && P == N - 1)
1885 PlaceholderStr += ", ...";
1886
Douglas Gregor86d9a522009-09-21 16:56:56 +00001887 // Add the placeholder string.
Benjamin Kramer660cc182009-11-29 20:18:50 +00001888 CCStr->AddPlaceholderChunk(PlaceholderStr);
Douglas Gregor86d9a522009-09-21 16:56:56 +00001889 }
Douglas Gregorb3d45252009-09-22 21:42:17 +00001890
1891 if (const FunctionProtoType *Proto
1892 = Function->getType()->getAs<FunctionProtoType>())
Douglas Gregoraaa107a2010-08-23 23:51:41 +00001893 if (Proto->isVariadic()) {
Douglas Gregore17794f2010-08-31 05:13:43 +00001894 if (Proto->getNumArgs() == 0)
1895 CCStr->AddPlaceholderChunk("...");
Douglas Gregoraaa107a2010-08-23 23:51:41 +00001896
1897 MaybeAddSentinel(Context, Function, CCStr);
1898 }
Douglas Gregor86d9a522009-09-21 16:56:56 +00001899}
1900
1901/// \brief Add template parameter chunks to the given code completion string.
1902static void AddTemplateParameterChunks(ASTContext &Context,
1903 TemplateDecl *Template,
1904 CodeCompletionString *Result,
1905 unsigned MaxParameters = 0) {
Douglas Gregor0c8296d2009-11-07 00:00:49 +00001906 typedef CodeCompletionString::Chunk Chunk;
1907
Douglas Gregor86d9a522009-09-21 16:56:56 +00001908 CodeCompletionString *CCStr = Result;
1909 bool FirstParameter = true;
1910
1911 TemplateParameterList *Params = Template->getTemplateParameters();
1912 TemplateParameterList::iterator PEnd = Params->end();
1913 if (MaxParameters)
1914 PEnd = Params->begin() + MaxParameters;
1915 for (TemplateParameterList::iterator P = Params->begin(); P != PEnd; ++P) {
1916 bool HasDefaultArg = false;
1917 std::string PlaceholderStr;
1918 if (TemplateTypeParmDecl *TTP = dyn_cast<TemplateTypeParmDecl>(*P)) {
1919 if (TTP->wasDeclaredWithTypename())
1920 PlaceholderStr = "typename";
1921 else
1922 PlaceholderStr = "class";
1923
1924 if (TTP->getIdentifier()) {
1925 PlaceholderStr += ' ';
1926 PlaceholderStr += TTP->getIdentifier()->getName();
1927 }
1928
1929 HasDefaultArg = TTP->hasDefaultArgument();
1930 } else if (NonTypeTemplateParmDecl *NTTP
1931 = dyn_cast<NonTypeTemplateParmDecl>(*P)) {
1932 if (NTTP->getIdentifier())
1933 PlaceholderStr = NTTP->getIdentifier()->getName();
1934 NTTP->getType().getAsStringInternal(PlaceholderStr,
1935 Context.PrintingPolicy);
1936 HasDefaultArg = NTTP->hasDefaultArgument();
1937 } else {
1938 assert(isa<TemplateTemplateParmDecl>(*P));
1939 TemplateTemplateParmDecl *TTP = cast<TemplateTemplateParmDecl>(*P);
1940
1941 // Since putting the template argument list into the placeholder would
1942 // be very, very long, we just use an abbreviation.
1943 PlaceholderStr = "template<...> class";
1944 if (TTP->getIdentifier()) {
1945 PlaceholderStr += ' ';
1946 PlaceholderStr += TTP->getIdentifier()->getName();
1947 }
1948
1949 HasDefaultArg = TTP->hasDefaultArgument();
1950 }
1951
1952 if (HasDefaultArg) {
1953 // When we see an optional default argument, put that argument and
1954 // the remaining default arguments into a new, optional string.
1955 CodeCompletionString *Opt = new CodeCompletionString;
1956 CCStr->AddOptionalChunk(std::auto_ptr<CodeCompletionString>(Opt));
1957 CCStr = Opt;
1958 }
1959
1960 if (FirstParameter)
1961 FirstParameter = false;
1962 else
Douglas Gregor0c8296d2009-11-07 00:00:49 +00001963 CCStr->AddChunk(Chunk(CodeCompletionString::CK_Comma));
Douglas Gregor86d9a522009-09-21 16:56:56 +00001964
1965 // Add the placeholder string.
Benjamin Kramer660cc182009-11-29 20:18:50 +00001966 CCStr->AddPlaceholderChunk(PlaceholderStr);
Douglas Gregor86d9a522009-09-21 16:56:56 +00001967 }
1968}
1969
Douglas Gregorb9d0ef72009-09-21 19:57:38 +00001970/// \brief Add a qualifier to the given code-completion string, if the
1971/// provided nested-name-specifier is non-NULL.
Douglas Gregora61a8792009-12-11 18:44:16 +00001972static void
1973AddQualifierToCompletionString(CodeCompletionString *Result,
1974 NestedNameSpecifier *Qualifier,
1975 bool QualifierIsInformative,
1976 ASTContext &Context) {
Douglas Gregorb9d0ef72009-09-21 19:57:38 +00001977 if (!Qualifier)
1978 return;
1979
1980 std::string PrintedNNS;
1981 {
1982 llvm::raw_string_ostream OS(PrintedNNS);
1983 Qualifier->print(OS, Context.PrintingPolicy);
1984 }
Douglas Gregor0563c262009-09-22 23:15:58 +00001985 if (QualifierIsInformative)
Benjamin Kramer660cc182009-11-29 20:18:50 +00001986 Result->AddInformativeChunk(PrintedNNS);
Douglas Gregor0563c262009-09-22 23:15:58 +00001987 else
Benjamin Kramer660cc182009-11-29 20:18:50 +00001988 Result->AddTextChunk(PrintedNNS);
Douglas Gregorb9d0ef72009-09-21 19:57:38 +00001989}
1990
Douglas Gregora61a8792009-12-11 18:44:16 +00001991static void AddFunctionTypeQualsToCompletionString(CodeCompletionString *Result,
1992 FunctionDecl *Function) {
1993 const FunctionProtoType *Proto
1994 = Function->getType()->getAs<FunctionProtoType>();
1995 if (!Proto || !Proto->getTypeQuals())
1996 return;
1997
1998 std::string QualsStr;
1999 if (Proto->getTypeQuals() & Qualifiers::Const)
2000 QualsStr += " const";
2001 if (Proto->getTypeQuals() & Qualifiers::Volatile)
2002 QualsStr += " volatile";
2003 if (Proto->getTypeQuals() & Qualifiers::Restrict)
2004 QualsStr += " restrict";
2005 Result->AddInformativeChunk(QualsStr);
2006}
2007
Douglas Gregor86d9a522009-09-21 16:56:56 +00002008/// \brief If possible, create a new code completion string for the given
2009/// result.
2010///
2011/// \returns Either a new, heap-allocated code completion string describing
2012/// how to use this result, or NULL to indicate that the string or name of the
2013/// result is all that is needed.
2014CodeCompletionString *
John McCall0a2c5e22010-08-25 06:19:51 +00002015CodeCompletionResult::CreateCodeCompletionString(Sema &S,
Douglas Gregor1abc6bc2010-08-04 16:47:14 +00002016 CodeCompletionString *Result) {
Douglas Gregor0c8296d2009-11-07 00:00:49 +00002017 typedef CodeCompletionString::Chunk Chunk;
2018
Douglas Gregor2b4074f2009-12-01 05:55:20 +00002019 if (Kind == RK_Pattern)
Douglas Gregor1abc6bc2010-08-04 16:47:14 +00002020 return Pattern->Clone(Result);
Douglas Gregor2b4074f2009-12-01 05:55:20 +00002021
Douglas Gregor1abc6bc2010-08-04 16:47:14 +00002022 if (!Result)
2023 Result = new CodeCompletionString;
Douglas Gregor2b4074f2009-12-01 05:55:20 +00002024
2025 if (Kind == RK_Keyword) {
2026 Result->AddTypedTextChunk(Keyword);
2027 return Result;
2028 }
Douglas Gregor86d9a522009-09-21 16:56:56 +00002029
Douglas Gregor3f7c7f42009-10-30 16:50:04 +00002030 if (Kind == RK_Macro) {
2031 MacroInfo *MI = S.PP.getMacroInfo(Macro);
Douglas Gregor2b4074f2009-12-01 05:55:20 +00002032 assert(MI && "Not a macro?");
2033
2034 Result->AddTypedTextChunk(Macro->getName());
2035
2036 if (!MI->isFunctionLike())
2037 return Result;
Douglas Gregor3f7c7f42009-10-30 16:50:04 +00002038
2039 // Format a function-like macro with placeholders for the arguments.
Douglas Gregor0c8296d2009-11-07 00:00:49 +00002040 Result->AddChunk(Chunk(CodeCompletionString::CK_LeftParen));
Douglas Gregor3f7c7f42009-10-30 16:50:04 +00002041 for (MacroInfo::arg_iterator A = MI->arg_begin(), AEnd = MI->arg_end();
2042 A != AEnd; ++A) {
2043 if (A != MI->arg_begin())
Douglas Gregor0c8296d2009-11-07 00:00:49 +00002044 Result->AddChunk(Chunk(CodeCompletionString::CK_Comma));
Douglas Gregor3f7c7f42009-10-30 16:50:04 +00002045
2046 if (!MI->isVariadic() || A != AEnd - 1) {
2047 // Non-variadic argument.
Benjamin Kramer660cc182009-11-29 20:18:50 +00002048 Result->AddPlaceholderChunk((*A)->getName());
Douglas Gregor3f7c7f42009-10-30 16:50:04 +00002049 continue;
2050 }
2051
2052 // Variadic argument; cope with the different between GNU and C99
2053 // variadic macros, providing a single placeholder for the rest of the
2054 // arguments.
2055 if ((*A)->isStr("__VA_ARGS__"))
2056 Result->AddPlaceholderChunk("...");
2057 else {
2058 std::string Arg = (*A)->getName();
2059 Arg += "...";
Benjamin Kramer660cc182009-11-29 20:18:50 +00002060 Result->AddPlaceholderChunk(Arg);
Douglas Gregor3f7c7f42009-10-30 16:50:04 +00002061 }
2062 }
Douglas Gregor0c8296d2009-11-07 00:00:49 +00002063 Result->AddChunk(Chunk(CodeCompletionString::CK_RightParen));
Douglas Gregor3f7c7f42009-10-30 16:50:04 +00002064 return Result;
2065 }
2066
Douglas Gregord8e8a582010-05-25 21:41:55 +00002067 assert(Kind == RK_Declaration && "Missed a result kind?");
Douglas Gregor86d9a522009-09-21 16:56:56 +00002068 NamedDecl *ND = Declaration;
2069
Douglas Gregor0c8296d2009-11-07 00:00:49 +00002070 if (StartsNestedNameSpecifier) {
Benjamin Kramer660cc182009-11-29 20:18:50 +00002071 Result->AddTypedTextChunk(ND->getNameAsString());
Douglas Gregor0c8296d2009-11-07 00:00:49 +00002072 Result->AddTextChunk("::");
2073 return Result;
2074 }
2075
Douglas Gregorff5ce6e2009-12-18 18:53:37 +00002076 AddResultTypeChunk(S.Context, ND, Result);
2077
Douglas Gregor86d9a522009-09-21 16:56:56 +00002078 if (FunctionDecl *Function = dyn_cast<FunctionDecl>(ND)) {
Douglas Gregor0563c262009-09-22 23:15:58 +00002079 AddQualifierToCompletionString(Result, Qualifier, QualifierIsInformative,
2080 S.Context);
Benjamin Kramer660cc182009-11-29 20:18:50 +00002081 Result->AddTypedTextChunk(Function->getNameAsString());
Douglas Gregor0c8296d2009-11-07 00:00:49 +00002082 Result->AddChunk(Chunk(CodeCompletionString::CK_LeftParen));
Douglas Gregor86d9a522009-09-21 16:56:56 +00002083 AddFunctionParameterChunks(S.Context, Function, Result);
Douglas Gregor0c8296d2009-11-07 00:00:49 +00002084 Result->AddChunk(Chunk(CodeCompletionString::CK_RightParen));
Douglas Gregora61a8792009-12-11 18:44:16 +00002085 AddFunctionTypeQualsToCompletionString(Result, Function);
Douglas Gregor86d9a522009-09-21 16:56:56 +00002086 return Result;
2087 }
2088
2089 if (FunctionTemplateDecl *FunTmpl = dyn_cast<FunctionTemplateDecl>(ND)) {
Douglas Gregor0563c262009-09-22 23:15:58 +00002090 AddQualifierToCompletionString(Result, Qualifier, QualifierIsInformative,
2091 S.Context);
Douglas Gregor86d9a522009-09-21 16:56:56 +00002092 FunctionDecl *Function = FunTmpl->getTemplatedDecl();
Benjamin Kramer660cc182009-11-29 20:18:50 +00002093 Result->AddTypedTextChunk(Function->getNameAsString());
Douglas Gregor86d9a522009-09-21 16:56:56 +00002094
2095 // Figure out which template parameters are deduced (or have default
2096 // arguments).
2097 llvm::SmallVector<bool, 16> Deduced;
2098 S.MarkDeducedTemplateParameters(FunTmpl, Deduced);
2099 unsigned LastDeducibleArgument;
2100 for (LastDeducibleArgument = Deduced.size(); LastDeducibleArgument > 0;
2101 --LastDeducibleArgument) {
2102 if (!Deduced[LastDeducibleArgument - 1]) {
2103 // C++0x: Figure out if the template argument has a default. If so,
2104 // the user doesn't need to type this argument.
2105 // FIXME: We need to abstract template parameters better!
2106 bool HasDefaultArg = false;
2107 NamedDecl *Param = FunTmpl->getTemplateParameters()->getParam(
2108 LastDeducibleArgument - 1);
2109 if (TemplateTypeParmDecl *TTP = dyn_cast<TemplateTypeParmDecl>(Param))
2110 HasDefaultArg = TTP->hasDefaultArgument();
2111 else if (NonTypeTemplateParmDecl *NTTP
2112 = dyn_cast<NonTypeTemplateParmDecl>(Param))
2113 HasDefaultArg = NTTP->hasDefaultArgument();
2114 else {
2115 assert(isa<TemplateTemplateParmDecl>(Param));
2116 HasDefaultArg
Douglas Gregor0c8296d2009-11-07 00:00:49 +00002117 = cast<TemplateTemplateParmDecl>(Param)->hasDefaultArgument();
Douglas Gregor86d9a522009-09-21 16:56:56 +00002118 }
2119
2120 if (!HasDefaultArg)
2121 break;
2122 }
2123 }
2124
2125 if (LastDeducibleArgument) {
2126 // Some of the function template arguments cannot be deduced from a
2127 // function call, so we introduce an explicit template argument list
2128 // containing all of the arguments up to the first deducible argument.
Douglas Gregor0c8296d2009-11-07 00:00:49 +00002129 Result->AddChunk(Chunk(CodeCompletionString::CK_LeftAngle));
Douglas Gregor86d9a522009-09-21 16:56:56 +00002130 AddTemplateParameterChunks(S.Context, FunTmpl, Result,
2131 LastDeducibleArgument);
Douglas Gregor0c8296d2009-11-07 00:00:49 +00002132 Result->AddChunk(Chunk(CodeCompletionString::CK_RightAngle));
Douglas Gregor86d9a522009-09-21 16:56:56 +00002133 }
2134
2135 // Add the function parameters
Douglas Gregor0c8296d2009-11-07 00:00:49 +00002136 Result->AddChunk(Chunk(CodeCompletionString::CK_LeftParen));
Douglas Gregor86d9a522009-09-21 16:56:56 +00002137 AddFunctionParameterChunks(S.Context, Function, Result);
Douglas Gregor0c8296d2009-11-07 00:00:49 +00002138 Result->AddChunk(Chunk(CodeCompletionString::CK_RightParen));
Douglas Gregora61a8792009-12-11 18:44:16 +00002139 AddFunctionTypeQualsToCompletionString(Result, Function);
Douglas Gregor86d9a522009-09-21 16:56:56 +00002140 return Result;
2141 }
2142
2143 if (TemplateDecl *Template = dyn_cast<TemplateDecl>(ND)) {
Douglas Gregor0563c262009-09-22 23:15:58 +00002144 AddQualifierToCompletionString(Result, Qualifier, QualifierIsInformative,
2145 S.Context);
Benjamin Kramer660cc182009-11-29 20:18:50 +00002146 Result->AddTypedTextChunk(Template->getNameAsString());
Douglas Gregor0c8296d2009-11-07 00:00:49 +00002147 Result->AddChunk(Chunk(CodeCompletionString::CK_LeftAngle));
Douglas Gregor86d9a522009-09-21 16:56:56 +00002148 AddTemplateParameterChunks(S.Context, Template, Result);
Douglas Gregor0c8296d2009-11-07 00:00:49 +00002149 Result->AddChunk(Chunk(CodeCompletionString::CK_RightAngle));
Douglas Gregor86d9a522009-09-21 16:56:56 +00002150 return Result;
2151 }
2152
Douglas Gregor9630eb62009-11-17 16:44:22 +00002153 if (ObjCMethodDecl *Method = dyn_cast<ObjCMethodDecl>(ND)) {
Douglas Gregor9630eb62009-11-17 16:44:22 +00002154 Selector Sel = Method->getSelector();
2155 if (Sel.isUnarySelector()) {
2156 Result->AddTypedTextChunk(Sel.getIdentifierInfoForSlot(0)->getName());
2157 return Result;
2158 }
2159
Douglas Gregord3c68542009-11-19 01:08:35 +00002160 std::string SelName = Sel.getIdentifierInfoForSlot(0)->getName().str();
2161 SelName += ':';
2162 if (StartParameter == 0)
2163 Result->AddTypedTextChunk(SelName);
2164 else {
2165 Result->AddInformativeChunk(SelName);
2166
2167 // If there is only one parameter, and we're past it, add an empty
2168 // typed-text chunk since there is nothing to type.
2169 if (Method->param_size() == 1)
2170 Result->AddTypedTextChunk("");
2171 }
Douglas Gregor9630eb62009-11-17 16:44:22 +00002172 unsigned Idx = 0;
2173 for (ObjCMethodDecl::param_iterator P = Method->param_begin(),
2174 PEnd = Method->param_end();
2175 P != PEnd; (void)++P, ++Idx) {
2176 if (Idx > 0) {
Douglas Gregord3c68542009-11-19 01:08:35 +00002177 std::string Keyword;
2178 if (Idx > StartParameter)
Douglas Gregor834389b2010-01-12 06:38:28 +00002179 Result->AddChunk(CodeCompletionString::CK_HorizontalSpace);
Douglas Gregor9630eb62009-11-17 16:44:22 +00002180 if (IdentifierInfo *II = Sel.getIdentifierInfoForSlot(Idx))
2181 Keyword += II->getName().str();
2182 Keyword += ":";
Douglas Gregor1f5537a2010-07-08 23:20:03 +00002183 if (Idx < StartParameter || AllParametersAreInformative)
Douglas Gregord3c68542009-11-19 01:08:35 +00002184 Result->AddInformativeChunk(Keyword);
Douglas Gregor1f5537a2010-07-08 23:20:03 +00002185 else if (Idx == StartParameter)
Douglas Gregord3c68542009-11-19 01:08:35 +00002186 Result->AddTypedTextChunk(Keyword);
2187 else
2188 Result->AddTextChunk(Keyword);
Douglas Gregor9630eb62009-11-17 16:44:22 +00002189 }
Douglas Gregord3c68542009-11-19 01:08:35 +00002190
2191 // If we're before the starting parameter, skip the placeholder.
2192 if (Idx < StartParameter)
2193 continue;
Douglas Gregor9630eb62009-11-17 16:44:22 +00002194
2195 std::string Arg;
Douglas Gregor83482d12010-08-24 16:15:59 +00002196
2197 if ((*P)->getType()->isBlockPointerType() && !DeclaringEntity)
Douglas Gregoraba48082010-08-29 19:47:46 +00002198 Arg = FormatFunctionParameter(S.Context, *P, true);
Douglas Gregor83482d12010-08-24 16:15:59 +00002199 else {
2200 (*P)->getType().getAsStringInternal(Arg, S.Context.PrintingPolicy);
2201 Arg = "(" + Arg + ")";
2202 if (IdentifierInfo *II = (*P)->getIdentifier())
Douglas Gregoraba48082010-08-29 19:47:46 +00002203 if (DeclaringEntity || AllParametersAreInformative)
2204 Arg += II->getName().str();
Douglas Gregor83482d12010-08-24 16:15:59 +00002205 }
2206
Douglas Gregore17794f2010-08-31 05:13:43 +00002207 if (Method->isVariadic() && (P + 1) == PEnd)
2208 Arg += ", ...";
2209
Douglas Gregor1f5537a2010-07-08 23:20:03 +00002210 if (DeclaringEntity)
2211 Result->AddTextChunk(Arg);
2212 else if (AllParametersAreInformative)
Douglas Gregor4ad96852009-11-19 07:41:15 +00002213 Result->AddInformativeChunk(Arg);
2214 else
2215 Result->AddPlaceholderChunk(Arg);
Douglas Gregor9630eb62009-11-17 16:44:22 +00002216 }
2217
Douglas Gregor2a17af02009-12-23 00:21:46 +00002218 if (Method->isVariadic()) {
Douglas Gregore17794f2010-08-31 05:13:43 +00002219 if (Method->param_size() == 0) {
2220 if (DeclaringEntity)
2221 Result->AddTextChunk(", ...");
2222 else if (AllParametersAreInformative)
2223 Result->AddInformativeChunk(", ...");
2224 else
2225 Result->AddPlaceholderChunk(", ...");
2226 }
Douglas Gregoraaa107a2010-08-23 23:51:41 +00002227
2228 MaybeAddSentinel(S.Context, Method, Result);
Douglas Gregor2a17af02009-12-23 00:21:46 +00002229 }
2230
Douglas Gregor9630eb62009-11-17 16:44:22 +00002231 return Result;
2232 }
2233
Douglas Gregor2b4074f2009-12-01 05:55:20 +00002234 if (Qualifier)
Douglas Gregor0563c262009-09-22 23:15:58 +00002235 AddQualifierToCompletionString(Result, Qualifier, QualifierIsInformative,
2236 S.Context);
Douglas Gregor2b4074f2009-12-01 05:55:20 +00002237
2238 Result->AddTypedTextChunk(ND->getNameAsString());
2239 return Result;
Douglas Gregor86d9a522009-09-21 16:56:56 +00002240}
2241
Douglas Gregor86d802e2009-09-23 00:34:09 +00002242CodeCompletionString *
2243CodeCompleteConsumer::OverloadCandidate::CreateSignatureString(
2244 unsigned CurrentArg,
2245 Sema &S) const {
Douglas Gregor0c8296d2009-11-07 00:00:49 +00002246 typedef CodeCompletionString::Chunk Chunk;
2247
Douglas Gregor86d802e2009-09-23 00:34:09 +00002248 CodeCompletionString *Result = new CodeCompletionString;
2249 FunctionDecl *FDecl = getFunction();
Douglas Gregorff5ce6e2009-12-18 18:53:37 +00002250 AddResultTypeChunk(S.Context, FDecl, Result);
Douglas Gregor86d802e2009-09-23 00:34:09 +00002251 const FunctionProtoType *Proto
2252 = dyn_cast<FunctionProtoType>(getFunctionType());
2253 if (!FDecl && !Proto) {
2254 // Function without a prototype. Just give the return type and a
2255 // highlighted ellipsis.
2256 const FunctionType *FT = getFunctionType();
2257 Result->AddTextChunk(
Benjamin Kramer660cc182009-11-29 20:18:50 +00002258 FT->getResultType().getAsString(S.Context.PrintingPolicy));
Douglas Gregor0c8296d2009-11-07 00:00:49 +00002259 Result->AddChunk(Chunk(CodeCompletionString::CK_LeftParen));
2260 Result->AddChunk(Chunk(CodeCompletionString::CK_CurrentParameter, "..."));
2261 Result->AddChunk(Chunk(CodeCompletionString::CK_RightParen));
Douglas Gregor86d802e2009-09-23 00:34:09 +00002262 return Result;
2263 }
2264
2265 if (FDecl)
Benjamin Kramer660cc182009-11-29 20:18:50 +00002266 Result->AddTextChunk(FDecl->getNameAsString());
Douglas Gregor86d802e2009-09-23 00:34:09 +00002267 else
2268 Result->AddTextChunk(
Benjamin Kramer660cc182009-11-29 20:18:50 +00002269 Proto->getResultType().getAsString(S.Context.PrintingPolicy));
Douglas Gregor86d802e2009-09-23 00:34:09 +00002270
Douglas Gregor0c8296d2009-11-07 00:00:49 +00002271 Result->AddChunk(Chunk(CodeCompletionString::CK_LeftParen));
Douglas Gregor86d802e2009-09-23 00:34:09 +00002272 unsigned NumParams = FDecl? FDecl->getNumParams() : Proto->getNumArgs();
2273 for (unsigned I = 0; I != NumParams; ++I) {
2274 if (I)
Douglas Gregor0c8296d2009-11-07 00:00:49 +00002275 Result->AddChunk(Chunk(CodeCompletionString::CK_Comma));
Douglas Gregor86d802e2009-09-23 00:34:09 +00002276
2277 std::string ArgString;
2278 QualType ArgType;
2279
2280 if (FDecl) {
2281 ArgString = FDecl->getParamDecl(I)->getNameAsString();
2282 ArgType = FDecl->getParamDecl(I)->getOriginalType();
2283 } else {
2284 ArgType = Proto->getArgType(I);
2285 }
2286
2287 ArgType.getAsStringInternal(ArgString, S.Context.PrintingPolicy);
2288
2289 if (I == CurrentArg)
Douglas Gregor0c8296d2009-11-07 00:00:49 +00002290 Result->AddChunk(Chunk(CodeCompletionString::CK_CurrentParameter,
Benjamin Kramer660cc182009-11-29 20:18:50 +00002291 ArgString));
Douglas Gregor86d802e2009-09-23 00:34:09 +00002292 else
Benjamin Kramer660cc182009-11-29 20:18:50 +00002293 Result->AddTextChunk(ArgString);
Douglas Gregor86d802e2009-09-23 00:34:09 +00002294 }
2295
2296 if (Proto && Proto->isVariadic()) {
Douglas Gregor0c8296d2009-11-07 00:00:49 +00002297 Result->AddChunk(Chunk(CodeCompletionString::CK_Comma));
Douglas Gregor86d802e2009-09-23 00:34:09 +00002298 if (CurrentArg < NumParams)
2299 Result->AddTextChunk("...");
2300 else
Douglas Gregor0c8296d2009-11-07 00:00:49 +00002301 Result->AddChunk(Chunk(CodeCompletionString::CK_CurrentParameter, "..."));
Douglas Gregor86d802e2009-09-23 00:34:09 +00002302 }
Douglas Gregor0c8296d2009-11-07 00:00:49 +00002303 Result->AddChunk(Chunk(CodeCompletionString::CK_RightParen));
Douglas Gregor86d802e2009-09-23 00:34:09 +00002304
2305 return Result;
2306}
2307
Douglas Gregor1827e102010-08-16 16:18:59 +00002308unsigned clang::getMacroUsagePriority(llvm::StringRef MacroName,
Douglas Gregorb05496d2010-09-20 21:11:48 +00002309 const LangOptions &LangOpts,
Douglas Gregor1827e102010-08-16 16:18:59 +00002310 bool PreferredTypeIsPointer) {
2311 unsigned Priority = CCP_Macro;
2312
Douglas Gregorb05496d2010-09-20 21:11:48 +00002313 // Treat the "nil", "Nil" and "NULL" macros as null pointer constants.
2314 if (MacroName.equals("nil") || MacroName.equals("NULL") ||
2315 MacroName.equals("Nil")) {
Douglas Gregor1827e102010-08-16 16:18:59 +00002316 Priority = CCP_Constant;
2317 if (PreferredTypeIsPointer)
2318 Priority = Priority / CCF_SimilarTypeMatch;
Douglas Gregorb05496d2010-09-20 21:11:48 +00002319 }
2320 // Treat "YES", "NO", "true", and "false" as constants.
2321 else if (MacroName.equals("YES") || MacroName.equals("NO") ||
2322 MacroName.equals("true") || MacroName.equals("false"))
2323 Priority = CCP_Constant;
2324 // Treat "bool" as a type.
2325 else if (MacroName.equals("bool"))
2326 Priority = CCP_Type + (LangOpts.ObjC1? CCD_bool_in_ObjC : 0);
2327
Douglas Gregor1827e102010-08-16 16:18:59 +00002328
2329 return Priority;
2330}
2331
Douglas Gregore8d7beb2010-09-03 23:30:36 +00002332CXCursorKind clang::getCursorKindForDecl(Decl *D) {
2333 if (!D)
2334 return CXCursor_UnexposedDecl;
2335
2336 switch (D->getKind()) {
2337 case Decl::Enum: return CXCursor_EnumDecl;
2338 case Decl::EnumConstant: return CXCursor_EnumConstantDecl;
2339 case Decl::Field: return CXCursor_FieldDecl;
2340 case Decl::Function:
2341 return CXCursor_FunctionDecl;
2342 case Decl::ObjCCategory: return CXCursor_ObjCCategoryDecl;
2343 case Decl::ObjCCategoryImpl: return CXCursor_ObjCCategoryImplDecl;
2344 case Decl::ObjCClass:
2345 // FIXME
2346 return CXCursor_UnexposedDecl;
2347 case Decl::ObjCForwardProtocol:
2348 // FIXME
2349 return CXCursor_UnexposedDecl;
2350 case Decl::ObjCImplementation: return CXCursor_ObjCImplementationDecl;
2351 case Decl::ObjCInterface: return CXCursor_ObjCInterfaceDecl;
2352 case Decl::ObjCIvar: return CXCursor_ObjCIvarDecl;
2353 case Decl::ObjCMethod:
2354 return cast<ObjCMethodDecl>(D)->isInstanceMethod()
2355 ? CXCursor_ObjCInstanceMethodDecl : CXCursor_ObjCClassMethodDecl;
2356 case Decl::CXXMethod: return CXCursor_CXXMethod;
2357 case Decl::CXXConstructor: return CXCursor_Constructor;
2358 case Decl::CXXDestructor: return CXCursor_Destructor;
2359 case Decl::CXXConversion: return CXCursor_ConversionFunction;
2360 case Decl::ObjCProperty: return CXCursor_ObjCPropertyDecl;
2361 case Decl::ObjCProtocol: return CXCursor_ObjCProtocolDecl;
2362 case Decl::ParmVar: return CXCursor_ParmDecl;
2363 case Decl::Typedef: return CXCursor_TypedefDecl;
2364 case Decl::Var: return CXCursor_VarDecl;
2365 case Decl::Namespace: return CXCursor_Namespace;
2366 case Decl::NamespaceAlias: return CXCursor_NamespaceAlias;
2367 case Decl::TemplateTypeParm: return CXCursor_TemplateTypeParameter;
2368 case Decl::NonTypeTemplateParm:return CXCursor_NonTypeTemplateParameter;
2369 case Decl::TemplateTemplateParm:return CXCursor_TemplateTemplateParameter;
2370 case Decl::FunctionTemplate: return CXCursor_FunctionTemplate;
2371 case Decl::ClassTemplate: return CXCursor_ClassTemplate;
2372 case Decl::ClassTemplatePartialSpecialization:
2373 return CXCursor_ClassTemplatePartialSpecialization;
2374 case Decl::UsingDirective: return CXCursor_UsingDirective;
2375
2376 case Decl::Using:
2377 case Decl::UnresolvedUsingValue:
2378 case Decl::UnresolvedUsingTypename:
2379 return CXCursor_UsingDeclaration;
2380
2381 default:
2382 if (TagDecl *TD = dyn_cast<TagDecl>(D)) {
2383 switch (TD->getTagKind()) {
2384 case TTK_Struct: return CXCursor_StructDecl;
2385 case TTK_Class: return CXCursor_ClassDecl;
2386 case TTK_Union: return CXCursor_UnionDecl;
2387 case TTK_Enum: return CXCursor_EnumDecl;
2388 }
2389 }
2390 }
2391
2392 return CXCursor_UnexposedDecl;
2393}
2394
Douglas Gregor590c7d52010-07-08 20:55:51 +00002395static void AddMacroResults(Preprocessor &PP, ResultBuilder &Results,
2396 bool TargetTypeIsPointer = false) {
John McCall0a2c5e22010-08-25 06:19:51 +00002397 typedef CodeCompletionResult Result;
Douglas Gregor590c7d52010-07-08 20:55:51 +00002398
Douglas Gregor3f7c7f42009-10-30 16:50:04 +00002399 Results.EnterNewScope();
Douglas Gregor0c8296d2009-11-07 00:00:49 +00002400 for (Preprocessor::macro_iterator M = PP.macro_begin(),
2401 MEnd = PP.macro_end();
Douglas Gregor590c7d52010-07-08 20:55:51 +00002402 M != MEnd; ++M) {
Douglas Gregor1827e102010-08-16 16:18:59 +00002403 Results.AddResult(Result(M->first,
2404 getMacroUsagePriority(M->first->getName(),
Douglas Gregorb05496d2010-09-20 21:11:48 +00002405 PP.getLangOptions(),
Douglas Gregor1827e102010-08-16 16:18:59 +00002406 TargetTypeIsPointer)));
Douglas Gregor590c7d52010-07-08 20:55:51 +00002407 }
Douglas Gregor3f7c7f42009-10-30 16:50:04 +00002408 Results.ExitScope();
2409}
2410
Douglas Gregoraa5f77b2010-08-23 21:54:33 +00002411static void AddPrettyFunctionResults(const LangOptions &LangOpts,
2412 ResultBuilder &Results) {
John McCall0a2c5e22010-08-25 06:19:51 +00002413 typedef CodeCompletionResult Result;
Douglas Gregoraa5f77b2010-08-23 21:54:33 +00002414
2415 Results.EnterNewScope();
2416 Results.AddResult(Result("__PRETTY_FUNCTION__", CCP_Constant));
2417 Results.AddResult(Result("__FUNCTION__", CCP_Constant));
2418 if (LangOpts.C99 || LangOpts.CPlusPlus0x)
2419 Results.AddResult(Result("__func__", CCP_Constant));
2420 Results.ExitScope();
2421}
2422
Daniel Dunbar3a2838d2009-11-13 08:58:20 +00002423static void HandleCodeCompleteResults(Sema *S,
2424 CodeCompleteConsumer *CodeCompleter,
Douglas Gregore6b1bb62010-08-11 21:23:17 +00002425 CodeCompletionContext Context,
John McCall0a2c5e22010-08-25 06:19:51 +00002426 CodeCompletionResult *Results,
Douglas Gregore6b1bb62010-08-11 21:23:17 +00002427 unsigned NumResults) {
Douglas Gregor86d9a522009-09-21 16:56:56 +00002428 if (CodeCompleter)
Douglas Gregore6b1bb62010-08-11 21:23:17 +00002429 CodeCompleter->ProcessCodeCompleteResults(*S, Context, Results, NumResults);
Douglas Gregor54f01612009-11-19 00:01:57 +00002430
2431 for (unsigned I = 0; I != NumResults; ++I)
2432 Results[I].Destroy();
Douglas Gregor86d9a522009-09-21 16:56:56 +00002433}
2434
Douglas Gregore6b1bb62010-08-11 21:23:17 +00002435static enum CodeCompletionContext::Kind mapCodeCompletionContext(Sema &S,
2436 Sema::ParserCompletionContext PCC) {
2437 switch (PCC) {
John McCallf312b1e2010-08-26 23:41:50 +00002438 case Sema::PCC_Namespace:
Douglas Gregore6b1bb62010-08-11 21:23:17 +00002439 return CodeCompletionContext::CCC_TopLevel;
2440
John McCallf312b1e2010-08-26 23:41:50 +00002441 case Sema::PCC_Class:
Douglas Gregore6b1bb62010-08-11 21:23:17 +00002442 return CodeCompletionContext::CCC_ClassStructUnion;
2443
John McCallf312b1e2010-08-26 23:41:50 +00002444 case Sema::PCC_ObjCInterface:
Douglas Gregore6b1bb62010-08-11 21:23:17 +00002445 return CodeCompletionContext::CCC_ObjCInterface;
2446
John McCallf312b1e2010-08-26 23:41:50 +00002447 case Sema::PCC_ObjCImplementation:
Douglas Gregore6b1bb62010-08-11 21:23:17 +00002448 return CodeCompletionContext::CCC_ObjCImplementation;
2449
John McCallf312b1e2010-08-26 23:41:50 +00002450 case Sema::PCC_ObjCInstanceVariableList:
Douglas Gregore6b1bb62010-08-11 21:23:17 +00002451 return CodeCompletionContext::CCC_ObjCIvarList;
2452
John McCallf312b1e2010-08-26 23:41:50 +00002453 case Sema::PCC_Template:
2454 case Sema::PCC_MemberTemplate:
2455 case Sema::PCC_RecoveryInFunction:
Douglas Gregore6b1bb62010-08-11 21:23:17 +00002456 return CodeCompletionContext::CCC_Other;
2457
John McCallf312b1e2010-08-26 23:41:50 +00002458 case Sema::PCC_Expression:
2459 case Sema::PCC_ForInit:
2460 case Sema::PCC_Condition:
Douglas Gregore6b1bb62010-08-11 21:23:17 +00002461 return CodeCompletionContext::CCC_Expression;
2462
John McCallf312b1e2010-08-26 23:41:50 +00002463 case Sema::PCC_Statement:
Douglas Gregore6b1bb62010-08-11 21:23:17 +00002464 return CodeCompletionContext::CCC_Statement;
Douglas Gregor72db1082010-08-24 01:11:00 +00002465
John McCallf312b1e2010-08-26 23:41:50 +00002466 case Sema::PCC_Type:
Douglas Gregor72db1082010-08-24 01:11:00 +00002467 return CodeCompletionContext::CCC_Type;
Douglas Gregor02688102010-09-14 23:59:36 +00002468
2469 case Sema::PCC_ParenthesizedExpression:
2470 return CodeCompletionContext::CCC_ParenthesizedExpression;
Douglas Gregore6b1bb62010-08-11 21:23:17 +00002471 }
2472
2473 return CodeCompletionContext::CCC_Other;
2474}
2475
Douglas Gregorf6961522010-08-27 21:18:54 +00002476/// \brief If we're in a C++ virtual member function, add completion results
2477/// that invoke the functions we override, since it's common to invoke the
2478/// overridden function as well as adding new functionality.
2479///
2480/// \param S The semantic analysis object for which we are generating results.
2481///
2482/// \param InContext This context in which the nested-name-specifier preceding
2483/// the code-completion point
2484static void MaybeAddOverrideCalls(Sema &S, DeclContext *InContext,
2485 ResultBuilder &Results) {
2486 // Look through blocks.
2487 DeclContext *CurContext = S.CurContext;
2488 while (isa<BlockDecl>(CurContext))
2489 CurContext = CurContext->getParent();
2490
2491
2492 CXXMethodDecl *Method = dyn_cast<CXXMethodDecl>(CurContext);
2493 if (!Method || !Method->isVirtual())
2494 return;
2495
2496 // We need to have names for all of the parameters, if we're going to
2497 // generate a forwarding call.
2498 for (CXXMethodDecl::param_iterator P = Method->param_begin(),
2499 PEnd = Method->param_end();
2500 P != PEnd;
2501 ++P) {
2502 if (!(*P)->getDeclName())
2503 return;
2504 }
2505
2506 for (CXXMethodDecl::method_iterator M = Method->begin_overridden_methods(),
2507 MEnd = Method->end_overridden_methods();
2508 M != MEnd; ++M) {
2509 CodeCompletionString *Pattern = new CodeCompletionString;
2510 CXXMethodDecl *Overridden = const_cast<CXXMethodDecl *>(*M);
2511 if (Overridden->getCanonicalDecl() == Method->getCanonicalDecl())
2512 continue;
2513
2514 // If we need a nested-name-specifier, add one now.
2515 if (!InContext) {
2516 NestedNameSpecifier *NNS
2517 = getRequiredQualification(S.Context, CurContext,
2518 Overridden->getDeclContext());
2519 if (NNS) {
2520 std::string Str;
2521 llvm::raw_string_ostream OS(Str);
2522 NNS->print(OS, S.Context.PrintingPolicy);
2523 Pattern->AddTextChunk(OS.str());
2524 }
2525 } else if (!InContext->Equals(Overridden->getDeclContext()))
2526 continue;
2527
2528 Pattern->AddTypedTextChunk(Overridden->getNameAsString());
2529 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
2530 bool FirstParam = true;
2531 for (CXXMethodDecl::param_iterator P = Method->param_begin(),
2532 PEnd = Method->param_end();
2533 P != PEnd; ++P) {
2534 if (FirstParam)
2535 FirstParam = false;
2536 else
2537 Pattern->AddChunk(CodeCompletionString::CK_Comma);
2538
2539 Pattern->AddPlaceholderChunk((*P)->getIdentifier()->getName());
2540 }
2541 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
2542 Results.AddResult(CodeCompletionResult(Pattern,
2543 CCP_SuperCompletion,
2544 CXCursor_CXXMethod));
2545 Results.Ignore(Overridden);
2546 }
2547}
2548
Douglas Gregor01dfea02010-01-10 23:08:15 +00002549void Sema::CodeCompleteOrdinaryName(Scope *S,
Douglas Gregore6b1bb62010-08-11 21:23:17 +00002550 ParserCompletionContext CompletionContext) {
John McCall0a2c5e22010-08-25 06:19:51 +00002551 typedef CodeCompletionResult Result;
Douglas Gregor2ccccb32010-08-23 18:23:48 +00002552 ResultBuilder Results(*this);
Douglas Gregorf6961522010-08-27 21:18:54 +00002553 Results.EnterNewScope();
Douglas Gregor01dfea02010-01-10 23:08:15 +00002554
2555 // Determine how to filter results, e.g., so that the names of
2556 // values (functions, enumerators, function templates, etc.) are
2557 // only allowed where we can have an expression.
2558 switch (CompletionContext) {
Douglas Gregore6b1bb62010-08-11 21:23:17 +00002559 case PCC_Namespace:
2560 case PCC_Class:
2561 case PCC_ObjCInterface:
2562 case PCC_ObjCImplementation:
2563 case PCC_ObjCInstanceVariableList:
2564 case PCC_Template:
2565 case PCC_MemberTemplate:
Douglas Gregor72db1082010-08-24 01:11:00 +00002566 case PCC_Type:
Douglas Gregor01dfea02010-01-10 23:08:15 +00002567 Results.setFilter(&ResultBuilder::IsOrdinaryNonValueName);
2568 break;
2569
Douglas Gregore6b1bb62010-08-11 21:23:17 +00002570 case PCC_Statement:
Douglas Gregor02688102010-09-14 23:59:36 +00002571 case PCC_ParenthesizedExpression:
Douglas Gregoreb0d0142010-08-24 23:58:17 +00002572 case PCC_Expression:
Douglas Gregore6b1bb62010-08-11 21:23:17 +00002573 case PCC_ForInit:
2574 case PCC_Condition:
Douglas Gregor4710e5b2010-05-28 00:49:12 +00002575 if (WantTypesInContext(CompletionContext, getLangOptions()))
2576 Results.setFilter(&ResultBuilder::IsOrdinaryName);
2577 else
2578 Results.setFilter(&ResultBuilder::IsOrdinaryNonTypeName);
Douglas Gregorf6961522010-08-27 21:18:54 +00002579
2580 if (getLangOptions().CPlusPlus)
2581 MaybeAddOverrideCalls(*this, /*InContext=*/0, Results);
Douglas Gregor01dfea02010-01-10 23:08:15 +00002582 break;
Douglas Gregordc845342010-05-25 05:58:43 +00002583
Douglas Gregore6b1bb62010-08-11 21:23:17 +00002584 case PCC_RecoveryInFunction:
Douglas Gregordc845342010-05-25 05:58:43 +00002585 // Unfiltered
2586 break;
Douglas Gregor01dfea02010-01-10 23:08:15 +00002587 }
2588
Douglas Gregor3cdee122010-08-26 16:36:48 +00002589 // If we are in a C++ non-static member function, check the qualifiers on
2590 // the member function to filter/prioritize the results list.
2591 if (CXXMethodDecl *CurMethod = dyn_cast<CXXMethodDecl>(CurContext))
2592 if (CurMethod->isInstance())
2593 Results.setObjectTypeQualifiers(
2594 Qualifiers::fromCVRMask(CurMethod->getTypeQualifiers()));
2595
Douglas Gregor1ca6ae82010-01-14 01:09:38 +00002596 CodeCompletionDeclConsumer Consumer(Results, CurContext);
Douglas Gregor8071e422010-08-15 06:18:01 +00002597 LookupVisibleDecls(S, LookupOrdinaryName, Consumer,
2598 CodeCompleter->includeGlobals());
Douglas Gregor2a7925c2009-12-07 09:54:55 +00002599
Douglas Gregorbca403c2010-01-13 23:51:12 +00002600 AddOrdinaryNameResults(CompletionContext, S, *this, Results);
Douglas Gregor2a7925c2009-12-07 09:54:55 +00002601 Results.ExitScope();
2602
Douglas Gregoraa5f77b2010-08-23 21:54:33 +00002603 switch (CompletionContext) {
Douglas Gregor02688102010-09-14 23:59:36 +00002604 case PCC_ParenthesizedExpression:
Douglas Gregor72db1082010-08-24 01:11:00 +00002605 case PCC_Expression:
2606 case PCC_Statement:
2607 case PCC_RecoveryInFunction:
2608 if (S->getFnParent())
2609 AddPrettyFunctionResults(PP.getLangOptions(), Results);
2610 break;
2611
2612 case PCC_Namespace:
2613 case PCC_Class:
2614 case PCC_ObjCInterface:
2615 case PCC_ObjCImplementation:
2616 case PCC_ObjCInstanceVariableList:
2617 case PCC_Template:
2618 case PCC_MemberTemplate:
2619 case PCC_ForInit:
2620 case PCC_Condition:
2621 case PCC_Type:
2622 break;
Douglas Gregoraa5f77b2010-08-23 21:54:33 +00002623 }
2624
Douglas Gregor0c8296d2009-11-07 00:00:49 +00002625 if (CodeCompleter->includeMacros())
Douglas Gregorbca403c2010-01-13 23:51:12 +00002626 AddMacroResults(PP, Results);
Douglas Gregoraa5f77b2010-08-23 21:54:33 +00002627
Douglas Gregore6b1bb62010-08-11 21:23:17 +00002628 HandleCodeCompleteResults(this, CodeCompleter,
2629 mapCodeCompletionContext(*this, CompletionContext),
2630 Results.data(),Results.size());
Douglas Gregor791215b2009-09-21 20:51:25 +00002631}
2632
Douglas Gregorc7b6d882010-09-16 15:14:18 +00002633static void AddClassMessageCompletions(Sema &SemaRef, Scope *S,
2634 ParsedType Receiver,
2635 IdentifierInfo **SelIdents,
2636 unsigned NumSelIdents,
2637 bool IsSuper,
2638 ResultBuilder &Results);
2639
2640void Sema::CodeCompleteDeclSpec(Scope *S, DeclSpec &DS,
2641 bool AllowNonIdentifiers,
2642 bool AllowNestedNameSpecifiers) {
John McCall0a2c5e22010-08-25 06:19:51 +00002643 typedef CodeCompletionResult Result;
Douglas Gregor2ccccb32010-08-23 18:23:48 +00002644 ResultBuilder Results(*this);
2645 Results.EnterNewScope();
2646
2647 // Type qualifiers can come after names.
2648 Results.AddResult(Result("const"));
2649 Results.AddResult(Result("volatile"));
2650 if (getLangOptions().C99)
2651 Results.AddResult(Result("restrict"));
2652
2653 if (getLangOptions().CPlusPlus) {
2654 if (AllowNonIdentifiers) {
2655 Results.AddResult(Result("operator"));
2656 }
2657
2658 // Add nested-name-specifiers.
2659 if (AllowNestedNameSpecifiers) {
2660 Results.allowNestedNameSpecifiers();
2661 CodeCompletionDeclConsumer Consumer(Results, CurContext);
2662 LookupVisibleDecls(S, LookupNestedNameSpecifierName, Consumer,
2663 CodeCompleter->includeGlobals());
2664 }
2665 }
2666 Results.ExitScope();
2667
Douglas Gregorc7b6d882010-09-16 15:14:18 +00002668 // If we're in a context where we might have an expression (rather than a
2669 // declaration), and what we've seen so far is an Objective-C type that could
2670 // be a receiver of a class message, this may be a class message send with
2671 // the initial opening bracket '[' missing. Add appropriate completions.
2672 if (AllowNonIdentifiers && !AllowNestedNameSpecifiers &&
2673 DS.getTypeSpecType() == DeclSpec::TST_typename &&
2674 DS.getStorageClassSpecAsWritten() == DeclSpec::SCS_unspecified &&
2675 !DS.isThreadSpecified() && !DS.isExternInLinkageSpec() &&
2676 DS.getTypeSpecComplex() == DeclSpec::TSC_unspecified &&
2677 DS.getTypeSpecSign() == DeclSpec::TSS_unspecified &&
2678 DS.getTypeQualifiers() == 0 &&
2679 S &&
2680 (S->getFlags() & Scope::DeclScope) != 0 &&
2681 (S->getFlags() & (Scope::ClassScope | Scope::TemplateParamScope |
2682 Scope::FunctionPrototypeScope |
2683 Scope::AtCatchScope)) == 0) {
2684 ParsedType T = DS.getRepAsType();
2685 if (!T.get().isNull() && T.get()->isObjCObjectOrInterfaceType())
2686 AddClassMessageCompletions(*this, S, T, 0, 0, false, Results);
2687 }
2688
Douglas Gregor4497dd42010-08-24 04:59:56 +00002689 // Note that we intentionally suppress macro results here, since we do not
2690 // encourage using macros to produce the names of entities.
2691
Douglas Gregor2ccccb32010-08-23 18:23:48 +00002692 HandleCodeCompleteResults(this, CodeCompleter,
2693 AllowNestedNameSpecifiers
2694 ? CodeCompletionContext::CCC_PotentiallyQualifiedName
2695 : CodeCompletionContext::CCC_Name,
2696 Results.data(), Results.size());
2697}
2698
Douglas Gregorfb629412010-08-23 21:17:50 +00002699struct Sema::CodeCompleteExpressionData {
2700 CodeCompleteExpressionData(QualType PreferredType = QualType())
2701 : PreferredType(PreferredType), IntegralConstantExpression(false),
2702 ObjCCollection(false) { }
2703
2704 QualType PreferredType;
2705 bool IntegralConstantExpression;
2706 bool ObjCCollection;
2707 llvm::SmallVector<Decl *, 4> IgnoreDecls;
2708};
2709
Douglas Gregor5ac3bdb2010-05-30 01:49:25 +00002710/// \brief Perform code-completion in an expression context when we know what
2711/// type we're looking for.
Douglas Gregorf9578432010-07-28 21:50:18 +00002712///
2713/// \param IntegralConstantExpression Only permit integral constant
2714/// expressions.
Douglas Gregorfb629412010-08-23 21:17:50 +00002715void Sema::CodeCompleteExpression(Scope *S,
2716 const CodeCompleteExpressionData &Data) {
John McCall0a2c5e22010-08-25 06:19:51 +00002717 typedef CodeCompletionResult Result;
Douglas Gregor5ac3bdb2010-05-30 01:49:25 +00002718 ResultBuilder Results(*this);
2719
Douglas Gregorfb629412010-08-23 21:17:50 +00002720 if (Data.ObjCCollection)
2721 Results.setFilter(&ResultBuilder::IsObjCCollection);
2722 else if (Data.IntegralConstantExpression)
Douglas Gregorf9578432010-07-28 21:50:18 +00002723 Results.setFilter(&ResultBuilder::IsIntegralConstantValue);
Douglas Gregore6b1bb62010-08-11 21:23:17 +00002724 else if (WantTypesInContext(PCC_Expression, getLangOptions()))
Douglas Gregor5ac3bdb2010-05-30 01:49:25 +00002725 Results.setFilter(&ResultBuilder::IsOrdinaryName);
2726 else
2727 Results.setFilter(&ResultBuilder::IsOrdinaryNonTypeName);
Douglas Gregorfb629412010-08-23 21:17:50 +00002728
2729 if (!Data.PreferredType.isNull())
2730 Results.setPreferredType(Data.PreferredType.getNonReferenceType());
2731
2732 // Ignore any declarations that we were told that we don't care about.
2733 for (unsigned I = 0, N = Data.IgnoreDecls.size(); I != N; ++I)
2734 Results.Ignore(Data.IgnoreDecls[I]);
Douglas Gregor5ac3bdb2010-05-30 01:49:25 +00002735
2736 CodeCompletionDeclConsumer Consumer(Results, CurContext);
Douglas Gregor8071e422010-08-15 06:18:01 +00002737 LookupVisibleDecls(S, LookupOrdinaryName, Consumer,
2738 CodeCompleter->includeGlobals());
Douglas Gregor5ac3bdb2010-05-30 01:49:25 +00002739
2740 Results.EnterNewScope();
Douglas Gregore6b1bb62010-08-11 21:23:17 +00002741 AddOrdinaryNameResults(PCC_Expression, S, *this, Results);
Douglas Gregor5ac3bdb2010-05-30 01:49:25 +00002742 Results.ExitScope();
2743
Douglas Gregor590c7d52010-07-08 20:55:51 +00002744 bool PreferredTypeIsPointer = false;
Douglas Gregorfb629412010-08-23 21:17:50 +00002745 if (!Data.PreferredType.isNull())
2746 PreferredTypeIsPointer = Data.PreferredType->isAnyPointerType()
2747 || Data.PreferredType->isMemberPointerType()
2748 || Data.PreferredType->isBlockPointerType();
Douglas Gregor590c7d52010-07-08 20:55:51 +00002749
Douglas Gregoraa5f77b2010-08-23 21:54:33 +00002750 if (S->getFnParent() &&
2751 !Data.ObjCCollection &&
2752 !Data.IntegralConstantExpression)
2753 AddPrettyFunctionResults(PP.getLangOptions(), Results);
2754
Douglas Gregor5ac3bdb2010-05-30 01:49:25 +00002755 if (CodeCompleter->includeMacros())
Douglas Gregor590c7d52010-07-08 20:55:51 +00002756 AddMacroResults(PP, Results, PreferredTypeIsPointer);
Douglas Gregore6b1bb62010-08-11 21:23:17 +00002757 HandleCodeCompleteResults(this, CodeCompleter,
Douglas Gregorfb629412010-08-23 21:17:50 +00002758 CodeCompletionContext(CodeCompletionContext::CCC_Expression,
2759 Data.PreferredType),
Douglas Gregore6b1bb62010-08-11 21:23:17 +00002760 Results.data(),Results.size());
Douglas Gregor5ac3bdb2010-05-30 01:49:25 +00002761}
2762
Douglas Gregorac5fd842010-09-18 01:28:11 +00002763void Sema::CodeCompletePostfixExpression(Scope *S, ExprResult E) {
2764 if (E.isInvalid())
2765 CodeCompleteOrdinaryName(S, PCC_RecoveryInFunction);
2766 else if (getLangOptions().ObjC1)
2767 CodeCompleteObjCInstanceMessage(S, E.take(), 0, 0, false);
Douglas Gregor78edf512010-09-15 16:23:04 +00002768}
Douglas Gregor5ac3bdb2010-05-30 01:49:25 +00002769
Douglas Gregor95ac6552009-11-18 01:29:26 +00002770static void AddObjCProperties(ObjCContainerDecl *Container,
Douglas Gregor322328b2009-11-18 22:32:06 +00002771 bool AllowCategories,
Douglas Gregor95ac6552009-11-18 01:29:26 +00002772 DeclContext *CurContext,
2773 ResultBuilder &Results) {
John McCall0a2c5e22010-08-25 06:19:51 +00002774 typedef CodeCompletionResult Result;
Douglas Gregor95ac6552009-11-18 01:29:26 +00002775
2776 // Add properties in this container.
2777 for (ObjCContainerDecl::prop_iterator P = Container->prop_begin(),
2778 PEnd = Container->prop_end();
2779 P != PEnd;
2780 ++P)
2781 Results.MaybeAddResult(Result(*P, 0), CurContext);
2782
2783 // Add properties in referenced protocols.
2784 if (ObjCProtocolDecl *Protocol = dyn_cast<ObjCProtocolDecl>(Container)) {
2785 for (ObjCProtocolDecl::protocol_iterator P = Protocol->protocol_begin(),
2786 PEnd = Protocol->protocol_end();
2787 P != PEnd; ++P)
Douglas Gregor322328b2009-11-18 22:32:06 +00002788 AddObjCProperties(*P, AllowCategories, CurContext, Results);
Douglas Gregor95ac6552009-11-18 01:29:26 +00002789 } else if (ObjCInterfaceDecl *IFace = dyn_cast<ObjCInterfaceDecl>(Container)){
Douglas Gregor322328b2009-11-18 22:32:06 +00002790 if (AllowCategories) {
2791 // Look through categories.
2792 for (ObjCCategoryDecl *Category = IFace->getCategoryList();
2793 Category; Category = Category->getNextClassCategory())
2794 AddObjCProperties(Category, AllowCategories, CurContext, Results);
2795 }
Douglas Gregor95ac6552009-11-18 01:29:26 +00002796
2797 // Look through protocols.
Ted Kremenek53b94412010-09-01 01:21:15 +00002798 for (ObjCInterfaceDecl::all_protocol_iterator
2799 I = IFace->all_referenced_protocol_begin(),
2800 E = IFace->all_referenced_protocol_end(); I != E; ++I)
Douglas Gregor322328b2009-11-18 22:32:06 +00002801 AddObjCProperties(*I, AllowCategories, CurContext, Results);
Douglas Gregor95ac6552009-11-18 01:29:26 +00002802
2803 // Look in the superclass.
2804 if (IFace->getSuperClass())
Douglas Gregor322328b2009-11-18 22:32:06 +00002805 AddObjCProperties(IFace->getSuperClass(), AllowCategories, CurContext,
2806 Results);
Douglas Gregor95ac6552009-11-18 01:29:26 +00002807 } else if (const ObjCCategoryDecl *Category
2808 = dyn_cast<ObjCCategoryDecl>(Container)) {
2809 // Look through protocols.
Ted Kremenek53b94412010-09-01 01:21:15 +00002810 for (ObjCCategoryDecl::protocol_iterator P = Category->protocol_begin(),
2811 PEnd = Category->protocol_end();
Douglas Gregor95ac6552009-11-18 01:29:26 +00002812 P != PEnd; ++P)
Douglas Gregor322328b2009-11-18 22:32:06 +00002813 AddObjCProperties(*P, AllowCategories, CurContext, Results);
Douglas Gregor95ac6552009-11-18 01:29:26 +00002814 }
2815}
2816
Douglas Gregor81b747b2009-09-17 21:32:03 +00002817void Sema::CodeCompleteMemberReferenceExpr(Scope *S, ExprTy *BaseE,
2818 SourceLocation OpLoc,
2819 bool IsArrow) {
2820 if (!BaseE || !CodeCompleter)
2821 return;
2822
John McCall0a2c5e22010-08-25 06:19:51 +00002823 typedef CodeCompletionResult Result;
Douglas Gregor86d9a522009-09-21 16:56:56 +00002824
Douglas Gregor81b747b2009-09-17 21:32:03 +00002825 Expr *Base = static_cast<Expr *>(BaseE);
2826 QualType BaseType = Base->getType();
Douglas Gregor86d9a522009-09-21 16:56:56 +00002827
2828 if (IsArrow) {
2829 if (const PointerType *Ptr = BaseType->getAs<PointerType>())
2830 BaseType = Ptr->getPointeeType();
2831 else if (BaseType->isObjCObjectPointerType())
Douglas Gregor3cdee122010-08-26 16:36:48 +00002832 /*Do nothing*/ ;
Douglas Gregor86d9a522009-09-21 16:56:56 +00002833 else
2834 return;
2835 }
2836
Douglas Gregoreb5758b2009-09-23 22:26:46 +00002837 ResultBuilder Results(*this, &ResultBuilder::IsMember);
Douglas Gregor95ac6552009-11-18 01:29:26 +00002838 Results.EnterNewScope();
2839 if (const RecordType *Record = BaseType->getAs<RecordType>()) {
Douglas Gregor3cdee122010-08-26 16:36:48 +00002840 // Indicate that we are performing a member access, and the cv-qualifiers
2841 // for the base object type.
2842 Results.setObjectTypeQualifiers(BaseType.getQualifiers());
2843
Douglas Gregor95ac6552009-11-18 01:29:26 +00002844 // Access to a C/C++ class, struct, or union.
Douglas Gregor45bcd432010-01-14 03:21:49 +00002845 Results.allowNestedNameSpecifiers();
Douglas Gregor0cc84042010-01-14 15:47:35 +00002846 CodeCompletionDeclConsumer Consumer(Results, CurContext);
Douglas Gregor8071e422010-08-15 06:18:01 +00002847 LookupVisibleDecls(Record->getDecl(), LookupMemberName, Consumer,
2848 CodeCompleter->includeGlobals());
Daniel Dunbar3a2838d2009-11-13 08:58:20 +00002849
Douglas Gregor95ac6552009-11-18 01:29:26 +00002850 if (getLangOptions().CPlusPlus) {
2851 if (!Results.empty()) {
2852 // The "template" keyword can follow "->" or "." in the grammar.
2853 // However, we only want to suggest the template keyword if something
2854 // is dependent.
2855 bool IsDependent = BaseType->isDependentType();
2856 if (!IsDependent) {
2857 for (Scope *DepScope = S; DepScope; DepScope = DepScope->getParent())
2858 if (DeclContext *Ctx = (DeclContext *)DepScope->getEntity()) {
2859 IsDependent = Ctx->isDependentContext();
2860 break;
2861 }
2862 }
Daniel Dunbar3a2838d2009-11-13 08:58:20 +00002863
Douglas Gregor95ac6552009-11-18 01:29:26 +00002864 if (IsDependent)
Douglas Gregora4477812010-01-14 16:01:26 +00002865 Results.AddResult(Result("template"));
Daniel Dunbar3a2838d2009-11-13 08:58:20 +00002866 }
Daniel Dunbar3a2838d2009-11-13 08:58:20 +00002867 }
Douglas Gregor95ac6552009-11-18 01:29:26 +00002868 } else if (!IsArrow && BaseType->getAsObjCInterfacePointerType()) {
2869 // Objective-C property reference.
2870
2871 // Add property results based on our interface.
2872 const ObjCObjectPointerType *ObjCPtr
2873 = BaseType->getAsObjCInterfacePointerType();
2874 assert(ObjCPtr && "Non-NULL pointer guaranteed above!");
Douglas Gregor322328b2009-11-18 22:32:06 +00002875 AddObjCProperties(ObjCPtr->getInterfaceDecl(), true, CurContext, Results);
Douglas Gregor95ac6552009-11-18 01:29:26 +00002876
2877 // Add properties from the protocols in a qualified interface.
2878 for (ObjCObjectPointerType::qual_iterator I = ObjCPtr->qual_begin(),
2879 E = ObjCPtr->qual_end();
2880 I != E; ++I)
Douglas Gregor322328b2009-11-18 22:32:06 +00002881 AddObjCProperties(*I, true, CurContext, Results);
Douglas Gregor95ac6552009-11-18 01:29:26 +00002882 } else if ((IsArrow && BaseType->isObjCObjectPointerType()) ||
John McCallc12c5bb2010-05-15 11:32:37 +00002883 (!IsArrow && BaseType->isObjCObjectType())) {
Douglas Gregor95ac6552009-11-18 01:29:26 +00002884 // Objective-C instance variable access.
2885 ObjCInterfaceDecl *Class = 0;
2886 if (const ObjCObjectPointerType *ObjCPtr
2887 = BaseType->getAs<ObjCObjectPointerType>())
2888 Class = ObjCPtr->getInterfaceDecl();
2889 else
John McCallc12c5bb2010-05-15 11:32:37 +00002890 Class = BaseType->getAs<ObjCObjectType>()->getInterface();
Douglas Gregor95ac6552009-11-18 01:29:26 +00002891
2892 // Add all ivars from this class and its superclasses.
Douglas Gregor80f4f4c2010-01-14 16:08:12 +00002893 if (Class) {
2894 CodeCompletionDeclConsumer Consumer(Results, CurContext);
2895 Results.setFilter(&ResultBuilder::IsObjCIvar);
Douglas Gregor8071e422010-08-15 06:18:01 +00002896 LookupVisibleDecls(Class, LookupMemberName, Consumer,
2897 CodeCompleter->includeGlobals());
Douglas Gregor95ac6552009-11-18 01:29:26 +00002898 }
Douglas Gregor86d9a522009-09-21 16:56:56 +00002899 }
Douglas Gregor95ac6552009-11-18 01:29:26 +00002900
2901 // FIXME: How do we cope with isa?
2902
2903 Results.ExitScope();
Daniel Dunbar3a2838d2009-11-13 08:58:20 +00002904
Daniel Dunbar3a2838d2009-11-13 08:58:20 +00002905 // Hand off the results found for code completion.
Douglas Gregore6b1bb62010-08-11 21:23:17 +00002906 HandleCodeCompleteResults(this, CodeCompleter,
2907 CodeCompletionContext(CodeCompletionContext::CCC_MemberAccess,
2908 BaseType),
2909 Results.data(),Results.size());
Douglas Gregor81b747b2009-09-17 21:32:03 +00002910}
2911
Douglas Gregor374929f2009-09-18 15:37:17 +00002912void Sema::CodeCompleteTag(Scope *S, unsigned TagSpec) {
2913 if (!CodeCompleter)
2914 return;
2915
John McCall0a2c5e22010-08-25 06:19:51 +00002916 typedef CodeCompletionResult Result;
Douglas Gregor86d9a522009-09-21 16:56:56 +00002917 ResultBuilder::LookupFilter Filter = 0;
Douglas Gregore6b1bb62010-08-11 21:23:17 +00002918 enum CodeCompletionContext::Kind ContextKind
2919 = CodeCompletionContext::CCC_Other;
Douglas Gregor374929f2009-09-18 15:37:17 +00002920 switch ((DeclSpec::TST)TagSpec) {
2921 case DeclSpec::TST_enum:
Douglas Gregor86d9a522009-09-21 16:56:56 +00002922 Filter = &ResultBuilder::IsEnum;
Douglas Gregore6b1bb62010-08-11 21:23:17 +00002923 ContextKind = CodeCompletionContext::CCC_EnumTag;
Douglas Gregor374929f2009-09-18 15:37:17 +00002924 break;
2925
2926 case DeclSpec::TST_union:
Douglas Gregor86d9a522009-09-21 16:56:56 +00002927 Filter = &ResultBuilder::IsUnion;
Douglas Gregore6b1bb62010-08-11 21:23:17 +00002928 ContextKind = CodeCompletionContext::CCC_UnionTag;
Douglas Gregor374929f2009-09-18 15:37:17 +00002929 break;
2930
2931 case DeclSpec::TST_struct:
Douglas Gregor374929f2009-09-18 15:37:17 +00002932 case DeclSpec::TST_class:
Douglas Gregor86d9a522009-09-21 16:56:56 +00002933 Filter = &ResultBuilder::IsClassOrStruct;
Douglas Gregore6b1bb62010-08-11 21:23:17 +00002934 ContextKind = CodeCompletionContext::CCC_ClassOrStructTag;
Douglas Gregor374929f2009-09-18 15:37:17 +00002935 break;
2936
2937 default:
2938 assert(false && "Unknown type specifier kind in CodeCompleteTag");
2939 return;
2940 }
Douglas Gregor86d9a522009-09-21 16:56:56 +00002941
John McCall0d6b1642010-04-23 18:46:30 +00002942 ResultBuilder Results(*this);
Douglas Gregor5d2fc402010-01-14 03:27:13 +00002943 CodeCompletionDeclConsumer Consumer(Results, CurContext);
John McCall0d6b1642010-04-23 18:46:30 +00002944
2945 // First pass: look for tags.
2946 Results.setFilter(Filter);
Douglas Gregor8071e422010-08-15 06:18:01 +00002947 LookupVisibleDecls(S, LookupTagName, Consumer,
2948 CodeCompleter->includeGlobals());
John McCall0d6b1642010-04-23 18:46:30 +00002949
Douglas Gregor8071e422010-08-15 06:18:01 +00002950 if (CodeCompleter->includeGlobals()) {
2951 // Second pass: look for nested name specifiers.
2952 Results.setFilter(&ResultBuilder::IsNestedNameSpecifier);
2953 LookupVisibleDecls(S, LookupNestedNameSpecifierName, Consumer);
2954 }
Douglas Gregor86d9a522009-09-21 16:56:56 +00002955
Douglas Gregore6b1bb62010-08-11 21:23:17 +00002956 HandleCodeCompleteResults(this, CodeCompleter, ContextKind,
2957 Results.data(),Results.size());
Douglas Gregor374929f2009-09-18 15:37:17 +00002958}
2959
Douglas Gregor1a480c42010-08-27 17:35:51 +00002960void Sema::CodeCompleteTypeQualifiers(DeclSpec &DS) {
2961 ResultBuilder Results(*this);
2962 Results.EnterNewScope();
2963 if (!(DS.getTypeQualifiers() & DeclSpec::TQ_const))
2964 Results.AddResult("const");
2965 if (!(DS.getTypeQualifiers() & DeclSpec::TQ_volatile))
2966 Results.AddResult("volatile");
2967 if (getLangOptions().C99 &&
2968 !(DS.getTypeQualifiers() & DeclSpec::TQ_restrict))
2969 Results.AddResult("restrict");
2970 Results.ExitScope();
2971 HandleCodeCompleteResults(this, CodeCompleter,
2972 CodeCompletionContext::CCC_TypeQualifiers,
2973 Results.data(), Results.size());
2974}
2975
Douglas Gregor3e1005f2009-09-21 18:10:23 +00002976void Sema::CodeCompleteCase(Scope *S) {
John McCall781472f2010-08-25 08:40:02 +00002977 if (getCurFunction()->SwitchStack.empty() || !CodeCompleter)
Douglas Gregor3e1005f2009-09-21 18:10:23 +00002978 return;
2979
John McCall781472f2010-08-25 08:40:02 +00002980 SwitchStmt *Switch = getCurFunction()->SwitchStack.back();
Douglas Gregorf9578432010-07-28 21:50:18 +00002981 if (!Switch->getCond()->getType()->isEnumeralType()) {
Douglas Gregorfb629412010-08-23 21:17:50 +00002982 CodeCompleteExpressionData Data(Switch->getCond()->getType());
2983 Data.IntegralConstantExpression = true;
2984 CodeCompleteExpression(S, Data);
Douglas Gregor3e1005f2009-09-21 18:10:23 +00002985 return;
Douglas Gregorf9578432010-07-28 21:50:18 +00002986 }
Douglas Gregor3e1005f2009-09-21 18:10:23 +00002987
2988 // Code-complete the cases of a switch statement over an enumeration type
2989 // by providing the list of
2990 EnumDecl *Enum = Switch->getCond()->getType()->getAs<EnumType>()->getDecl();
2991
2992 // Determine which enumerators we have already seen in the switch statement.
2993 // FIXME: Ideally, we would also be able to look *past* the code-completion
2994 // token, in case we are code-completing in the middle of the switch and not
2995 // at the end. However, we aren't able to do so at the moment.
2996 llvm::SmallPtrSet<EnumConstantDecl *, 8> EnumeratorsSeen;
Douglas Gregorb9d0ef72009-09-21 19:57:38 +00002997 NestedNameSpecifier *Qualifier = 0;
Douglas Gregor3e1005f2009-09-21 18:10:23 +00002998 for (SwitchCase *SC = Switch->getSwitchCaseList(); SC;
2999 SC = SC->getNextSwitchCase()) {
3000 CaseStmt *Case = dyn_cast<CaseStmt>(SC);
3001 if (!Case)
3002 continue;
3003
3004 Expr *CaseVal = Case->getLHS()->IgnoreParenCasts();
3005 if (DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(CaseVal))
3006 if (EnumConstantDecl *Enumerator
3007 = dyn_cast<EnumConstantDecl>(DRE->getDecl())) {
3008 // We look into the AST of the case statement to determine which
3009 // enumerator was named. Alternatively, we could compute the value of
3010 // the integral constant expression, then compare it against the
3011 // values of each enumerator. However, value-based approach would not
3012 // work as well with C++ templates where enumerators declared within a
3013 // template are type- and value-dependent.
3014 EnumeratorsSeen.insert(Enumerator);
3015
Douglas Gregorb9d0ef72009-09-21 19:57:38 +00003016 // If this is a qualified-id, keep track of the nested-name-specifier
3017 // so that we can reproduce it as part of code completion, e.g.,
Douglas Gregor3e1005f2009-09-21 18:10:23 +00003018 //
3019 // switch (TagD.getKind()) {
3020 // case TagDecl::TK_enum:
3021 // break;
3022 // case XXX
3023 //
Douglas Gregorb9d0ef72009-09-21 19:57:38 +00003024 // At the XXX, our completions are TagDecl::TK_union,
Douglas Gregor3e1005f2009-09-21 18:10:23 +00003025 // TagDecl::TK_struct, and TagDecl::TK_class, rather than TK_union,
3026 // TK_struct, and TK_class.
Douglas Gregora2813ce2009-10-23 18:54:35 +00003027 Qualifier = DRE->getQualifier();
Douglas Gregor3e1005f2009-09-21 18:10:23 +00003028 }
3029 }
3030
Douglas Gregorb9d0ef72009-09-21 19:57:38 +00003031 if (getLangOptions().CPlusPlus && !Qualifier && EnumeratorsSeen.empty()) {
3032 // If there are no prior enumerators in C++, check whether we have to
3033 // qualify the names of the enumerators that we suggest, because they
3034 // may not be visible in this scope.
3035 Qualifier = getRequiredQualification(Context, CurContext,
3036 Enum->getDeclContext());
3037
3038 // FIXME: Scoped enums need to start with "EnumDecl" as the context!
3039 }
3040
Douglas Gregor3e1005f2009-09-21 18:10:23 +00003041 // Add any enumerators that have not yet been mentioned.
3042 ResultBuilder Results(*this);
3043 Results.EnterNewScope();
3044 for (EnumDecl::enumerator_iterator E = Enum->enumerator_begin(),
3045 EEnd = Enum->enumerator_end();
3046 E != EEnd; ++E) {
3047 if (EnumeratorsSeen.count(*E))
3048 continue;
3049
John McCall0a2c5e22010-08-25 06:19:51 +00003050 Results.AddResult(CodeCompletionResult(*E, Qualifier),
Douglas Gregor608300b2010-01-14 16:14:35 +00003051 CurContext, 0, false);
Douglas Gregor3e1005f2009-09-21 18:10:23 +00003052 }
3053 Results.ExitScope();
Douglas Gregor2f880e42010-04-06 20:02:15 +00003054
Douglas Gregor0c8296d2009-11-07 00:00:49 +00003055 if (CodeCompleter->includeMacros())
Douglas Gregorbca403c2010-01-13 23:51:12 +00003056 AddMacroResults(PP, Results);
Douglas Gregore6b1bb62010-08-11 21:23:17 +00003057 HandleCodeCompleteResults(this, CodeCompleter,
3058 CodeCompletionContext::CCC_Expression,
3059 Results.data(),Results.size());
Douglas Gregor3e1005f2009-09-21 18:10:23 +00003060}
3061
Douglas Gregor9c6a0e92009-09-22 15:41:20 +00003062namespace {
3063 struct IsBetterOverloadCandidate {
3064 Sema &S;
John McCall5769d612010-02-08 23:07:23 +00003065 SourceLocation Loc;
Douglas Gregor9c6a0e92009-09-22 15:41:20 +00003066
3067 public:
John McCall5769d612010-02-08 23:07:23 +00003068 explicit IsBetterOverloadCandidate(Sema &S, SourceLocation Loc)
3069 : S(S), Loc(Loc) { }
Douglas Gregor9c6a0e92009-09-22 15:41:20 +00003070
3071 bool
3072 operator()(const OverloadCandidate &X, const OverloadCandidate &Y) const {
John McCall120d63c2010-08-24 20:38:10 +00003073 return isBetterOverloadCandidate(S, X, Y, Loc);
Douglas Gregor9c6a0e92009-09-22 15:41:20 +00003074 }
3075 };
3076}
3077
Douglas Gregord28dcd72010-05-30 06:10:08 +00003078static bool anyNullArguments(Expr **Args, unsigned NumArgs) {
3079 if (NumArgs && !Args)
3080 return true;
3081
3082 for (unsigned I = 0; I != NumArgs; ++I)
3083 if (!Args[I])
3084 return true;
3085
3086 return false;
3087}
3088
Douglas Gregor9c6a0e92009-09-22 15:41:20 +00003089void Sema::CodeCompleteCall(Scope *S, ExprTy *FnIn,
3090 ExprTy **ArgsIn, unsigned NumArgs) {
3091 if (!CodeCompleter)
3092 return;
Douglas Gregoref96eac2009-12-11 19:06:04 +00003093
3094 // When we're code-completing for a call, we fall back to ordinary
3095 // name code-completion whenever we can't produce specific
3096 // results. We may want to revisit this strategy in the future,
3097 // e.g., by merging the two kinds of results.
3098
Douglas Gregor9c6a0e92009-09-22 15:41:20 +00003099 Expr *Fn = (Expr *)FnIn;
3100 Expr **Args = (Expr **)ArgsIn;
Douglas Gregoref96eac2009-12-11 19:06:04 +00003101
Douglas Gregor9c6a0e92009-09-22 15:41:20 +00003102 // Ignore type-dependent call expressions entirely.
Douglas Gregord28dcd72010-05-30 06:10:08 +00003103 if (!Fn || Fn->isTypeDependent() || anyNullArguments(Args, NumArgs) ||
Douglas Gregoref96eac2009-12-11 19:06:04 +00003104 Expr::hasAnyTypeDependentArguments(Args, NumArgs)) {
Douglas Gregore6b1bb62010-08-11 21:23:17 +00003105 CodeCompleteOrdinaryName(S, PCC_Expression);
Douglas Gregor9c6a0e92009-09-22 15:41:20 +00003106 return;
Douglas Gregoref96eac2009-12-11 19:06:04 +00003107 }
Douglas Gregor9c6a0e92009-09-22 15:41:20 +00003108
John McCall3b4294e2009-12-16 12:17:52 +00003109 // Build an overload candidate set based on the functions we find.
John McCall5769d612010-02-08 23:07:23 +00003110 SourceLocation Loc = Fn->getExprLoc();
3111 OverloadCandidateSet CandidateSet(Loc);
John McCall3b4294e2009-12-16 12:17:52 +00003112
Douglas Gregor9c6a0e92009-09-22 15:41:20 +00003113 // FIXME: What if we're calling something that isn't a function declaration?
3114 // FIXME: What if we're calling a pseudo-destructor?
3115 // FIXME: What if we're calling a member function?
3116
Douglas Gregorc0265402010-01-21 15:46:19 +00003117 typedef CodeCompleteConsumer::OverloadCandidate ResultCandidate;
3118 llvm::SmallVector<ResultCandidate, 8> Results;
3119
John McCall3b4294e2009-12-16 12:17:52 +00003120 Expr *NakedFn = Fn->IgnoreParenCasts();
3121 if (UnresolvedLookupExpr *ULE = dyn_cast<UnresolvedLookupExpr>(NakedFn))
3122 AddOverloadedCallCandidates(ULE, Args, NumArgs, CandidateSet,
3123 /*PartialOverloading=*/ true);
3124 else if (DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(NakedFn)) {
3125 FunctionDecl *FDecl = dyn_cast<FunctionDecl>(DRE->getDecl());
Douglas Gregorc0265402010-01-21 15:46:19 +00003126 if (FDecl) {
Douglas Gregord28dcd72010-05-30 06:10:08 +00003127 if (!getLangOptions().CPlusPlus ||
3128 !FDecl->getType()->getAs<FunctionProtoType>())
Douglas Gregorc0265402010-01-21 15:46:19 +00003129 Results.push_back(ResultCandidate(FDecl));
3130 else
John McCall86820f52010-01-26 01:37:31 +00003131 // FIXME: access?
John McCall9aa472c2010-03-19 07:35:19 +00003132 AddOverloadCandidate(FDecl, DeclAccessPair::make(FDecl, AS_none),
3133 Args, NumArgs, CandidateSet,
Douglas Gregorc27d6c52010-04-16 17:41:49 +00003134 false, /*PartialOverloading*/true);
Douglas Gregorc0265402010-01-21 15:46:19 +00003135 }
John McCall3b4294e2009-12-16 12:17:52 +00003136 }
Douglas Gregor9c6a0e92009-09-22 15:41:20 +00003137
Douglas Gregor5ac3bdb2010-05-30 01:49:25 +00003138 QualType ParamType;
3139
Douglas Gregorc0265402010-01-21 15:46:19 +00003140 if (!CandidateSet.empty()) {
3141 // Sort the overload candidate set by placing the best overloads first.
3142 std::stable_sort(CandidateSet.begin(), CandidateSet.end(),
John McCall5769d612010-02-08 23:07:23 +00003143 IsBetterOverloadCandidate(*this, Loc));
Douglas Gregor9c6a0e92009-09-22 15:41:20 +00003144
Douglas Gregorc0265402010-01-21 15:46:19 +00003145 // Add the remaining viable overload candidates as code-completion reslults.
3146 for (OverloadCandidateSet::iterator Cand = CandidateSet.begin(),
3147 CandEnd = CandidateSet.end();
3148 Cand != CandEnd; ++Cand) {
3149 if (Cand->Viable)
3150 Results.push_back(ResultCandidate(Cand->Function));
3151 }
Douglas Gregor5ac3bdb2010-05-30 01:49:25 +00003152
3153 // From the viable candidates, try to determine the type of this parameter.
3154 for (unsigned I = 0, N = Results.size(); I != N; ++I) {
3155 if (const FunctionType *FType = Results[I].getFunctionType())
3156 if (const FunctionProtoType *Proto = dyn_cast<FunctionProtoType>(FType))
3157 if (NumArgs < Proto->getNumArgs()) {
3158 if (ParamType.isNull())
3159 ParamType = Proto->getArgType(NumArgs);
3160 else if (!Context.hasSameUnqualifiedType(
3161 ParamType.getNonReferenceType(),
3162 Proto->getArgType(NumArgs).getNonReferenceType())) {
3163 ParamType = QualType();
3164 break;
3165 }
3166 }
3167 }
3168 } else {
3169 // Try to determine the parameter type from the type of the expression
3170 // being called.
3171 QualType FunctionType = Fn->getType();
3172 if (const PointerType *Ptr = FunctionType->getAs<PointerType>())
3173 FunctionType = Ptr->getPointeeType();
3174 else if (const BlockPointerType *BlockPtr
3175 = FunctionType->getAs<BlockPointerType>())
3176 FunctionType = BlockPtr->getPointeeType();
3177 else if (const MemberPointerType *MemPtr
3178 = FunctionType->getAs<MemberPointerType>())
3179 FunctionType = MemPtr->getPointeeType();
3180
3181 if (const FunctionProtoType *Proto
3182 = FunctionType->getAs<FunctionProtoType>()) {
3183 if (NumArgs < Proto->getNumArgs())
3184 ParamType = Proto->getArgType(NumArgs);
3185 }
Douglas Gregor9c6a0e92009-09-22 15:41:20 +00003186 }
Douglas Gregoref96eac2009-12-11 19:06:04 +00003187
Douglas Gregor5ac3bdb2010-05-30 01:49:25 +00003188 if (ParamType.isNull())
Douglas Gregore6b1bb62010-08-11 21:23:17 +00003189 CodeCompleteOrdinaryName(S, PCC_Expression);
Douglas Gregor5ac3bdb2010-05-30 01:49:25 +00003190 else
3191 CodeCompleteExpression(S, ParamType);
3192
Douglas Gregor2e4c7a52010-04-06 20:19:47 +00003193 if (!Results.empty())
Douglas Gregoref96eac2009-12-11 19:06:04 +00003194 CodeCompleter->ProcessOverloadCandidates(*this, NumArgs, Results.data(),
3195 Results.size());
Douglas Gregor9c6a0e92009-09-22 15:41:20 +00003196}
3197
John McCalld226f652010-08-21 09:40:31 +00003198void Sema::CodeCompleteInitializer(Scope *S, Decl *D) {
3199 ValueDecl *VD = dyn_cast_or_null<ValueDecl>(D);
Douglas Gregor5ac3bdb2010-05-30 01:49:25 +00003200 if (!VD) {
Douglas Gregore6b1bb62010-08-11 21:23:17 +00003201 CodeCompleteOrdinaryName(S, PCC_Expression);
Douglas Gregor5ac3bdb2010-05-30 01:49:25 +00003202 return;
3203 }
3204
3205 CodeCompleteExpression(S, VD->getType());
3206}
3207
3208void Sema::CodeCompleteReturn(Scope *S) {
3209 QualType ResultType;
3210 if (isa<BlockDecl>(CurContext)) {
3211 if (BlockScopeInfo *BSI = getCurBlock())
3212 ResultType = BSI->ReturnType;
3213 } else if (FunctionDecl *Function = dyn_cast<FunctionDecl>(CurContext))
3214 ResultType = Function->getResultType();
3215 else if (ObjCMethodDecl *Method = dyn_cast<ObjCMethodDecl>(CurContext))
3216 ResultType = Method->getResultType();
3217
3218 if (ResultType.isNull())
Douglas Gregore6b1bb62010-08-11 21:23:17 +00003219 CodeCompleteOrdinaryName(S, PCC_Expression);
Douglas Gregor5ac3bdb2010-05-30 01:49:25 +00003220 else
3221 CodeCompleteExpression(S, ResultType);
3222}
3223
3224void Sema::CodeCompleteAssignmentRHS(Scope *S, ExprTy *LHS) {
3225 if (LHS)
3226 CodeCompleteExpression(S, static_cast<Expr *>(LHS)->getType());
3227 else
Douglas Gregore6b1bb62010-08-11 21:23:17 +00003228 CodeCompleteOrdinaryName(S, PCC_Expression);
Douglas Gregor5ac3bdb2010-05-30 01:49:25 +00003229}
3230
Jeffrey Yasskin9ab14542010-04-08 16:38:48 +00003231void Sema::CodeCompleteQualifiedId(Scope *S, CXXScopeSpec &SS,
Douglas Gregor81b747b2009-09-17 21:32:03 +00003232 bool EnteringContext) {
3233 if (!SS.getScopeRep() || !CodeCompleter)
3234 return;
3235
Douglas Gregor86d9a522009-09-21 16:56:56 +00003236 DeclContext *Ctx = computeDeclContext(SS, EnteringContext);
3237 if (!Ctx)
3238 return;
Douglas Gregord1cd31a2009-12-11 18:28:39 +00003239
3240 // Try to instantiate any non-dependent declaration contexts before
3241 // we look in them.
John McCall77bb1aa2010-05-01 00:40:08 +00003242 if (!isDependentScopeSpecifier(SS) && RequireCompleteDeclContext(SS, Ctx))
Douglas Gregord1cd31a2009-12-11 18:28:39 +00003243 return;
3244
Douglas Gregor86d9a522009-09-21 16:56:56 +00003245 ResultBuilder Results(*this);
Douglas Gregor86d9a522009-09-21 16:56:56 +00003246
Douglas Gregorf6961522010-08-27 21:18:54 +00003247 Results.EnterNewScope();
Douglas Gregor86d9a522009-09-21 16:56:56 +00003248 // The "template" keyword can follow "::" in the grammar, but only
3249 // put it into the grammar if the nested-name-specifier is dependent.
3250 NestedNameSpecifier *NNS = (NestedNameSpecifier *)SS.getScopeRep();
3251 if (!Results.empty() && NNS->isDependent())
Douglas Gregora4477812010-01-14 16:01:26 +00003252 Results.AddResult("template");
Douglas Gregorf6961522010-08-27 21:18:54 +00003253
3254 // Add calls to overridden virtual functions, if there are any.
3255 //
3256 // FIXME: This isn't wonderful, because we don't know whether we're actually
3257 // in a context that permits expressions. This is a general issue with
3258 // qualified-id completions.
3259 if (!EnteringContext)
3260 MaybeAddOverrideCalls(*this, Ctx, Results);
3261 Results.ExitScope();
Douglas Gregor86d9a522009-09-21 16:56:56 +00003262
Douglas Gregorf6961522010-08-27 21:18:54 +00003263 CodeCompletionDeclConsumer Consumer(Results, CurContext);
3264 LookupVisibleDecls(Ctx, LookupOrdinaryName, Consumer);
3265
Douglas Gregore6b1bb62010-08-11 21:23:17 +00003266 HandleCodeCompleteResults(this, CodeCompleter,
Douglas Gregorf6961522010-08-27 21:18:54 +00003267 CodeCompletionContext::CCC_Name,
Douglas Gregore6b1bb62010-08-11 21:23:17 +00003268 Results.data(),Results.size());
Douglas Gregor81b747b2009-09-17 21:32:03 +00003269}
Douglas Gregor49f40bd2009-09-18 19:03:04 +00003270
3271void Sema::CodeCompleteUsing(Scope *S) {
3272 if (!CodeCompleter)
3273 return;
3274
Douglas Gregor86d9a522009-09-21 16:56:56 +00003275 ResultBuilder Results(*this, &ResultBuilder::IsNestedNameSpecifier);
Douglas Gregor8e0a0e42009-09-22 23:31:26 +00003276 Results.EnterNewScope();
Douglas Gregor86d9a522009-09-21 16:56:56 +00003277
3278 // If we aren't in class scope, we could see the "namespace" keyword.
3279 if (!S->isClassScope())
John McCall0a2c5e22010-08-25 06:19:51 +00003280 Results.AddResult(CodeCompletionResult("namespace"));
Douglas Gregor86d9a522009-09-21 16:56:56 +00003281
3282 // After "using", we can see anything that would start a
3283 // nested-name-specifier.
Douglas Gregor5d2fc402010-01-14 03:27:13 +00003284 CodeCompletionDeclConsumer Consumer(Results, CurContext);
Douglas Gregor8071e422010-08-15 06:18:01 +00003285 LookupVisibleDecls(S, LookupOrdinaryName, Consumer,
3286 CodeCompleter->includeGlobals());
Douglas Gregor8e0a0e42009-09-22 23:31:26 +00003287 Results.ExitScope();
Douglas Gregor86d9a522009-09-21 16:56:56 +00003288
Douglas Gregore6b1bb62010-08-11 21:23:17 +00003289 HandleCodeCompleteResults(this, CodeCompleter,
3290 CodeCompletionContext::CCC_Other,
3291 Results.data(),Results.size());
Douglas Gregor49f40bd2009-09-18 19:03:04 +00003292}
3293
3294void Sema::CodeCompleteUsingDirective(Scope *S) {
3295 if (!CodeCompleter)
3296 return;
3297
Douglas Gregor86d9a522009-09-21 16:56:56 +00003298 // After "using namespace", we expect to see a namespace name or namespace
3299 // alias.
3300 ResultBuilder Results(*this, &ResultBuilder::IsNamespaceOrAlias);
Douglas Gregor8e0a0e42009-09-22 23:31:26 +00003301 Results.EnterNewScope();
Douglas Gregor5d2fc402010-01-14 03:27:13 +00003302 CodeCompletionDeclConsumer Consumer(Results, CurContext);
Douglas Gregor8071e422010-08-15 06:18:01 +00003303 LookupVisibleDecls(S, LookupOrdinaryName, Consumer,
3304 CodeCompleter->includeGlobals());
Douglas Gregor8e0a0e42009-09-22 23:31:26 +00003305 Results.ExitScope();
Douglas Gregore6b1bb62010-08-11 21:23:17 +00003306 HandleCodeCompleteResults(this, CodeCompleter,
Douglas Gregor8071e422010-08-15 06:18:01 +00003307 CodeCompletionContext::CCC_Namespace,
Douglas Gregore6b1bb62010-08-11 21:23:17 +00003308 Results.data(),Results.size());
Douglas Gregor49f40bd2009-09-18 19:03:04 +00003309}
3310
3311void Sema::CodeCompleteNamespaceDecl(Scope *S) {
3312 if (!CodeCompleter)
3313 return;
3314
Douglas Gregor86d9a522009-09-21 16:56:56 +00003315 ResultBuilder Results(*this, &ResultBuilder::IsNamespace);
3316 DeclContext *Ctx = (DeclContext *)S->getEntity();
3317 if (!S->getParent())
3318 Ctx = Context.getTranslationUnitDecl();
3319
3320 if (Ctx && Ctx->isFileContext()) {
3321 // We only want to see those namespaces that have already been defined
3322 // within this scope, because its likely that the user is creating an
3323 // extended namespace declaration. Keep track of the most recent
3324 // definition of each namespace.
3325 std::map<NamespaceDecl *, NamespaceDecl *> OrigToLatest;
3326 for (DeclContext::specific_decl_iterator<NamespaceDecl>
3327 NS(Ctx->decls_begin()), NSEnd(Ctx->decls_end());
3328 NS != NSEnd; ++NS)
3329 OrigToLatest[NS->getOriginalNamespace()] = *NS;
3330
3331 // Add the most recent definition (or extended definition) of each
3332 // namespace to the list of results.
Douglas Gregor8e0a0e42009-09-22 23:31:26 +00003333 Results.EnterNewScope();
Douglas Gregor86d9a522009-09-21 16:56:56 +00003334 for (std::map<NamespaceDecl *, NamespaceDecl *>::iterator
3335 NS = OrigToLatest.begin(), NSEnd = OrigToLatest.end();
3336 NS != NSEnd; ++NS)
John McCall0a2c5e22010-08-25 06:19:51 +00003337 Results.AddResult(CodeCompletionResult(NS->second, 0),
Douglas Gregor608300b2010-01-14 16:14:35 +00003338 CurContext, 0, false);
Douglas Gregor8e0a0e42009-09-22 23:31:26 +00003339 Results.ExitScope();
Douglas Gregor86d9a522009-09-21 16:56:56 +00003340 }
3341
Douglas Gregore6b1bb62010-08-11 21:23:17 +00003342 HandleCodeCompleteResults(this, CodeCompleter,
3343 CodeCompletionContext::CCC_Other,
3344 Results.data(),Results.size());
Douglas Gregor49f40bd2009-09-18 19:03:04 +00003345}
3346
3347void Sema::CodeCompleteNamespaceAliasDecl(Scope *S) {
3348 if (!CodeCompleter)
3349 return;
3350
Douglas Gregor86d9a522009-09-21 16:56:56 +00003351 // After "namespace", we expect to see a namespace or alias.
3352 ResultBuilder Results(*this, &ResultBuilder::IsNamespaceOrAlias);
Douglas Gregor5d2fc402010-01-14 03:27:13 +00003353 CodeCompletionDeclConsumer Consumer(Results, CurContext);
Douglas Gregor8071e422010-08-15 06:18:01 +00003354 LookupVisibleDecls(S, LookupOrdinaryName, Consumer,
3355 CodeCompleter->includeGlobals());
Douglas Gregore6b1bb62010-08-11 21:23:17 +00003356 HandleCodeCompleteResults(this, CodeCompleter,
Douglas Gregor8071e422010-08-15 06:18:01 +00003357 CodeCompletionContext::CCC_Namespace,
Douglas Gregore6b1bb62010-08-11 21:23:17 +00003358 Results.data(),Results.size());
Douglas Gregor49f40bd2009-09-18 19:03:04 +00003359}
3360
Douglas Gregored8d3222009-09-18 20:05:18 +00003361void Sema::CodeCompleteOperatorName(Scope *S) {
3362 if (!CodeCompleter)
3363 return;
Douglas Gregor86d9a522009-09-21 16:56:56 +00003364
John McCall0a2c5e22010-08-25 06:19:51 +00003365 typedef CodeCompletionResult Result;
Douglas Gregor86d9a522009-09-21 16:56:56 +00003366 ResultBuilder Results(*this, &ResultBuilder::IsType);
Douglas Gregor8e0a0e42009-09-22 23:31:26 +00003367 Results.EnterNewScope();
Douglas Gregored8d3222009-09-18 20:05:18 +00003368
Douglas Gregor86d9a522009-09-21 16:56:56 +00003369 // Add the names of overloadable operators.
3370#define OVERLOADED_OPERATOR(Name,Spelling,Token,Unary,Binary,MemberOnly) \
3371 if (std::strcmp(Spelling, "?")) \
Douglas Gregora4477812010-01-14 16:01:26 +00003372 Results.AddResult(Result(Spelling));
Douglas Gregor86d9a522009-09-21 16:56:56 +00003373#include "clang/Basic/OperatorKinds.def"
3374
3375 // Add any type names visible from the current scope
Douglas Gregor45bcd432010-01-14 03:21:49 +00003376 Results.allowNestedNameSpecifiers();
Douglas Gregor5d2fc402010-01-14 03:27:13 +00003377 CodeCompletionDeclConsumer Consumer(Results, CurContext);
Douglas Gregor8071e422010-08-15 06:18:01 +00003378 LookupVisibleDecls(S, LookupOrdinaryName, Consumer,
3379 CodeCompleter->includeGlobals());
Douglas Gregor86d9a522009-09-21 16:56:56 +00003380
3381 // Add any type specifiers
Douglas Gregorbca403c2010-01-13 23:51:12 +00003382 AddTypeSpecifierResults(getLangOptions(), Results);
Douglas Gregor8e0a0e42009-09-22 23:31:26 +00003383 Results.ExitScope();
Douglas Gregor86d9a522009-09-21 16:56:56 +00003384
Douglas Gregore6b1bb62010-08-11 21:23:17 +00003385 HandleCodeCompleteResults(this, CodeCompleter,
Douglas Gregor8071e422010-08-15 06:18:01 +00003386 CodeCompletionContext::CCC_Type,
Douglas Gregore6b1bb62010-08-11 21:23:17 +00003387 Results.data(),Results.size());
Douglas Gregored8d3222009-09-18 20:05:18 +00003388}
Douglas Gregor49f40bd2009-09-18 19:03:04 +00003389
Douglas Gregor0133f522010-08-28 00:00:50 +00003390void Sema::CodeCompleteConstructorInitializer(Decl *ConstructorD,
3391 CXXBaseOrMemberInitializer** Initializers,
3392 unsigned NumInitializers) {
3393 CXXConstructorDecl *Constructor
3394 = static_cast<CXXConstructorDecl *>(ConstructorD);
3395 if (!Constructor)
3396 return;
3397
3398 ResultBuilder Results(*this);
3399 Results.EnterNewScope();
3400
3401 // Fill in any already-initialized fields or base classes.
3402 llvm::SmallPtrSet<FieldDecl *, 4> InitializedFields;
3403 llvm::SmallPtrSet<CanQualType, 4> InitializedBases;
3404 for (unsigned I = 0; I != NumInitializers; ++I) {
3405 if (Initializers[I]->isBaseInitializer())
3406 InitializedBases.insert(
3407 Context.getCanonicalType(QualType(Initializers[I]->getBaseClass(), 0)));
3408 else
3409 InitializedFields.insert(cast<FieldDecl>(Initializers[I]->getMember()));
3410 }
3411
3412 // Add completions for base classes.
Douglas Gregor0c431c82010-08-29 19:27:27 +00003413 bool SawLastInitializer = (NumInitializers == 0);
Douglas Gregor0133f522010-08-28 00:00:50 +00003414 CXXRecordDecl *ClassDecl = Constructor->getParent();
3415 for (CXXRecordDecl::base_class_iterator Base = ClassDecl->bases_begin(),
3416 BaseEnd = ClassDecl->bases_end();
3417 Base != BaseEnd; ++Base) {
Douglas Gregor0c431c82010-08-29 19:27:27 +00003418 if (!InitializedBases.insert(Context.getCanonicalType(Base->getType()))) {
3419 SawLastInitializer
3420 = NumInitializers > 0 &&
3421 Initializers[NumInitializers - 1]->isBaseInitializer() &&
3422 Context.hasSameUnqualifiedType(Base->getType(),
3423 QualType(Initializers[NumInitializers - 1]->getBaseClass(), 0));
Douglas Gregor0133f522010-08-28 00:00:50 +00003424 continue;
Douglas Gregor0c431c82010-08-29 19:27:27 +00003425 }
Douglas Gregor0133f522010-08-28 00:00:50 +00003426
3427 CodeCompletionString *Pattern = new CodeCompletionString;
3428 Pattern->AddTypedTextChunk(
3429 Base->getType().getAsString(Context.PrintingPolicy));
3430 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
3431 Pattern->AddPlaceholderChunk("args");
3432 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
Douglas Gregor0c431c82010-08-29 19:27:27 +00003433 Results.AddResult(CodeCompletionResult(Pattern,
3434 SawLastInitializer? CCP_NextInitializer
3435 : CCP_MemberDeclaration));
3436 SawLastInitializer = false;
Douglas Gregor0133f522010-08-28 00:00:50 +00003437 }
3438
3439 // Add completions for virtual base classes.
3440 for (CXXRecordDecl::base_class_iterator Base = ClassDecl->vbases_begin(),
3441 BaseEnd = ClassDecl->vbases_end();
3442 Base != BaseEnd; ++Base) {
Douglas Gregor0c431c82010-08-29 19:27:27 +00003443 if (!InitializedBases.insert(Context.getCanonicalType(Base->getType()))) {
3444 SawLastInitializer
3445 = NumInitializers > 0 &&
3446 Initializers[NumInitializers - 1]->isBaseInitializer() &&
3447 Context.hasSameUnqualifiedType(Base->getType(),
3448 QualType(Initializers[NumInitializers - 1]->getBaseClass(), 0));
Douglas Gregor0133f522010-08-28 00:00:50 +00003449 continue;
Douglas Gregor0c431c82010-08-29 19:27:27 +00003450 }
Douglas Gregor0133f522010-08-28 00:00:50 +00003451
3452 CodeCompletionString *Pattern = new CodeCompletionString;
3453 Pattern->AddTypedTextChunk(
3454 Base->getType().getAsString(Context.PrintingPolicy));
3455 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
3456 Pattern->AddPlaceholderChunk("args");
3457 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
Douglas Gregor0c431c82010-08-29 19:27:27 +00003458 Results.AddResult(CodeCompletionResult(Pattern,
3459 SawLastInitializer? CCP_NextInitializer
3460 : CCP_MemberDeclaration));
3461 SawLastInitializer = false;
Douglas Gregor0133f522010-08-28 00:00:50 +00003462 }
3463
3464 // Add completions for members.
3465 for (CXXRecordDecl::field_iterator Field = ClassDecl->field_begin(),
3466 FieldEnd = ClassDecl->field_end();
3467 Field != FieldEnd; ++Field) {
Douglas Gregor0c431c82010-08-29 19:27:27 +00003468 if (!InitializedFields.insert(cast<FieldDecl>(Field->getCanonicalDecl()))) {
3469 SawLastInitializer
3470 = NumInitializers > 0 &&
3471 Initializers[NumInitializers - 1]->isMemberInitializer() &&
3472 Initializers[NumInitializers - 1]->getMember() == *Field;
Douglas Gregor0133f522010-08-28 00:00:50 +00003473 continue;
Douglas Gregor0c431c82010-08-29 19:27:27 +00003474 }
Douglas Gregor0133f522010-08-28 00:00:50 +00003475
3476 if (!Field->getDeclName())
3477 continue;
3478
3479 CodeCompletionString *Pattern = new CodeCompletionString;
3480 Pattern->AddTypedTextChunk(Field->getIdentifier()->getName());
3481 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
3482 Pattern->AddPlaceholderChunk("args");
3483 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
Douglas Gregor0c431c82010-08-29 19:27:27 +00003484 Results.AddResult(CodeCompletionResult(Pattern,
3485 SawLastInitializer? CCP_NextInitializer
Douglas Gregora67e03f2010-09-09 21:42:20 +00003486 : CCP_MemberDeclaration,
3487 CXCursor_MemberRef));
Douglas Gregor0c431c82010-08-29 19:27:27 +00003488 SawLastInitializer = false;
Douglas Gregor0133f522010-08-28 00:00:50 +00003489 }
3490 Results.ExitScope();
3491
3492 HandleCodeCompleteResults(this, CodeCompleter,
3493 CodeCompletionContext::CCC_Name,
3494 Results.data(), Results.size());
3495}
3496
Douglas Gregorb6ac2452010-01-13 21:24:21 +00003497// Macro that expands to @Keyword or Keyword, depending on whether NeedAt is
3498// true or false.
3499#define OBJC_AT_KEYWORD_NAME(NeedAt,Keyword) NeedAt? "@" #Keyword : #Keyword
Douglas Gregorbca403c2010-01-13 23:51:12 +00003500static void AddObjCImplementationResults(const LangOptions &LangOpts,
Douglas Gregorb6ac2452010-01-13 21:24:21 +00003501 ResultBuilder &Results,
3502 bool NeedAt) {
John McCall0a2c5e22010-08-25 06:19:51 +00003503 typedef CodeCompletionResult Result;
Douglas Gregorb6ac2452010-01-13 21:24:21 +00003504 // Since we have an implementation, we can end it.
Douglas Gregora4477812010-01-14 16:01:26 +00003505 Results.AddResult(Result(OBJC_AT_KEYWORD_NAME(NeedAt,end)));
Douglas Gregorb6ac2452010-01-13 21:24:21 +00003506
3507 CodeCompletionString *Pattern = 0;
3508 if (LangOpts.ObjC2) {
3509 // @dynamic
3510 Pattern = new CodeCompletionString;
3511 Pattern->AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt,dynamic));
3512 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
3513 Pattern->AddPlaceholderChunk("property");
Douglas Gregora4477812010-01-14 16:01:26 +00003514 Results.AddResult(Result(Pattern));
Douglas Gregorb6ac2452010-01-13 21:24:21 +00003515
3516 // @synthesize
3517 Pattern = new CodeCompletionString;
3518 Pattern->AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt,synthesize));
3519 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
3520 Pattern->AddPlaceholderChunk("property");
Douglas Gregora4477812010-01-14 16:01:26 +00003521 Results.AddResult(Result(Pattern));
Douglas Gregorb6ac2452010-01-13 21:24:21 +00003522 }
3523}
3524
Douglas Gregorbca403c2010-01-13 23:51:12 +00003525static void AddObjCInterfaceResults(const LangOptions &LangOpts,
Douglas Gregorb6ac2452010-01-13 21:24:21 +00003526 ResultBuilder &Results,
3527 bool NeedAt) {
John McCall0a2c5e22010-08-25 06:19:51 +00003528 typedef CodeCompletionResult Result;
Douglas Gregorb6ac2452010-01-13 21:24:21 +00003529
3530 // Since we have an interface or protocol, we can end it.
Douglas Gregora4477812010-01-14 16:01:26 +00003531 Results.AddResult(Result(OBJC_AT_KEYWORD_NAME(NeedAt,end)));
Douglas Gregorb6ac2452010-01-13 21:24:21 +00003532
3533 if (LangOpts.ObjC2) {
3534 // @property
Douglas Gregora4477812010-01-14 16:01:26 +00003535 Results.AddResult(Result(OBJC_AT_KEYWORD_NAME(NeedAt,property)));
Douglas Gregorb6ac2452010-01-13 21:24:21 +00003536
3537 // @required
Douglas Gregora4477812010-01-14 16:01:26 +00003538 Results.AddResult(Result(OBJC_AT_KEYWORD_NAME(NeedAt,required)));
Douglas Gregorb6ac2452010-01-13 21:24:21 +00003539
3540 // @optional
Douglas Gregora4477812010-01-14 16:01:26 +00003541 Results.AddResult(Result(OBJC_AT_KEYWORD_NAME(NeedAt,optional)));
Douglas Gregorb6ac2452010-01-13 21:24:21 +00003542 }
3543}
3544
Douglas Gregorbca403c2010-01-13 23:51:12 +00003545static void AddObjCTopLevelResults(ResultBuilder &Results, bool NeedAt) {
John McCall0a2c5e22010-08-25 06:19:51 +00003546 typedef CodeCompletionResult Result;
Douglas Gregorb6ac2452010-01-13 21:24:21 +00003547 CodeCompletionString *Pattern = 0;
3548
3549 // @class name ;
3550 Pattern = new CodeCompletionString;
3551 Pattern->AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt,class));
3552 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
Douglas Gregorc8bddde2010-05-28 00:22:41 +00003553 Pattern->AddPlaceholderChunk("name");
Douglas Gregora4477812010-01-14 16:01:26 +00003554 Results.AddResult(Result(Pattern));
Douglas Gregorb6ac2452010-01-13 21:24:21 +00003555
Douglas Gregorc8bddde2010-05-28 00:22:41 +00003556 if (Results.includeCodePatterns()) {
3557 // @interface name
3558 // FIXME: Could introduce the whole pattern, including superclasses and
3559 // such.
3560 Pattern = new CodeCompletionString;
3561 Pattern->AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt,interface));
3562 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
3563 Pattern->AddPlaceholderChunk("class");
3564 Results.AddResult(Result(Pattern));
Douglas Gregorb6ac2452010-01-13 21:24:21 +00003565
Douglas Gregorc8bddde2010-05-28 00:22:41 +00003566 // @protocol name
3567 Pattern = new CodeCompletionString;
3568 Pattern->AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt,protocol));
3569 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
3570 Pattern->AddPlaceholderChunk("protocol");
3571 Results.AddResult(Result(Pattern));
3572
3573 // @implementation name
3574 Pattern = new CodeCompletionString;
3575 Pattern->AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt,implementation));
3576 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
3577 Pattern->AddPlaceholderChunk("class");
3578 Results.AddResult(Result(Pattern));
3579 }
Douglas Gregorb6ac2452010-01-13 21:24:21 +00003580
3581 // @compatibility_alias name
3582 Pattern = new CodeCompletionString;
3583 Pattern->AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt,compatibility_alias));
3584 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
3585 Pattern->AddPlaceholderChunk("alias");
3586 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
3587 Pattern->AddPlaceholderChunk("class");
Douglas Gregora4477812010-01-14 16:01:26 +00003588 Results.AddResult(Result(Pattern));
Douglas Gregorb6ac2452010-01-13 21:24:21 +00003589}
3590
John McCalld226f652010-08-21 09:40:31 +00003591void Sema::CodeCompleteObjCAtDirective(Scope *S, Decl *ObjCImpDecl,
Douglas Gregorc464ae82009-12-07 09:27:33 +00003592 bool InInterface) {
John McCall0a2c5e22010-08-25 06:19:51 +00003593 typedef CodeCompletionResult Result;
Douglas Gregorc464ae82009-12-07 09:27:33 +00003594 ResultBuilder Results(*this);
3595 Results.EnterNewScope();
Douglas Gregorb6ac2452010-01-13 21:24:21 +00003596 if (ObjCImpDecl)
Douglas Gregorbca403c2010-01-13 23:51:12 +00003597 AddObjCImplementationResults(getLangOptions(), Results, false);
Douglas Gregorb6ac2452010-01-13 21:24:21 +00003598 else if (InInterface)
Douglas Gregorbca403c2010-01-13 23:51:12 +00003599 AddObjCInterfaceResults(getLangOptions(), Results, false);
Douglas Gregorb6ac2452010-01-13 21:24:21 +00003600 else
Douglas Gregorbca403c2010-01-13 23:51:12 +00003601 AddObjCTopLevelResults(Results, false);
Douglas Gregorc464ae82009-12-07 09:27:33 +00003602 Results.ExitScope();
Douglas Gregore6b1bb62010-08-11 21:23:17 +00003603 HandleCodeCompleteResults(this, CodeCompleter,
3604 CodeCompletionContext::CCC_Other,
3605 Results.data(),Results.size());
Douglas Gregorc464ae82009-12-07 09:27:33 +00003606}
3607
Douglas Gregorbca403c2010-01-13 23:51:12 +00003608static void AddObjCExpressionResults(ResultBuilder &Results, bool NeedAt) {
John McCall0a2c5e22010-08-25 06:19:51 +00003609 typedef CodeCompletionResult Result;
Douglas Gregor9a0c85e2009-12-07 09:51:25 +00003610 CodeCompletionString *Pattern = 0;
3611
3612 // @encode ( type-name )
3613 Pattern = new CodeCompletionString;
Douglas Gregorb6ac2452010-01-13 21:24:21 +00003614 Pattern->AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt,encode));
Douglas Gregor9a0c85e2009-12-07 09:51:25 +00003615 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
3616 Pattern->AddPlaceholderChunk("type-name");
3617 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
Douglas Gregora4477812010-01-14 16:01:26 +00003618 Results.AddResult(Result(Pattern));
Douglas Gregor9a0c85e2009-12-07 09:51:25 +00003619
3620 // @protocol ( protocol-name )
3621 Pattern = new CodeCompletionString;
Douglas Gregorb6ac2452010-01-13 21:24:21 +00003622 Pattern->AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt,protocol));
Douglas Gregor9a0c85e2009-12-07 09:51:25 +00003623 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
3624 Pattern->AddPlaceholderChunk("protocol-name");
3625 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
Douglas Gregora4477812010-01-14 16:01:26 +00003626 Results.AddResult(Result(Pattern));
Douglas Gregor9a0c85e2009-12-07 09:51:25 +00003627
3628 // @selector ( selector )
3629 Pattern = new CodeCompletionString;
Douglas Gregorb6ac2452010-01-13 21:24:21 +00003630 Pattern->AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt,selector));
Douglas Gregor9a0c85e2009-12-07 09:51:25 +00003631 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
3632 Pattern->AddPlaceholderChunk("selector");
3633 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
Douglas Gregora4477812010-01-14 16:01:26 +00003634 Results.AddResult(Result(Pattern));
Douglas Gregor9a0c85e2009-12-07 09:51:25 +00003635}
3636
Douglas Gregorbca403c2010-01-13 23:51:12 +00003637static void AddObjCStatementResults(ResultBuilder &Results, bool NeedAt) {
John McCall0a2c5e22010-08-25 06:19:51 +00003638 typedef CodeCompletionResult Result;
Douglas Gregor9a0c85e2009-12-07 09:51:25 +00003639 CodeCompletionString *Pattern = 0;
Douglas Gregorb6ac2452010-01-13 21:24:21 +00003640
Douglas Gregorc8bddde2010-05-28 00:22:41 +00003641 if (Results.includeCodePatterns()) {
3642 // @try { statements } @catch ( declaration ) { statements } @finally
3643 // { statements }
3644 Pattern = new CodeCompletionString;
3645 Pattern->AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt,try));
3646 Pattern->AddChunk(CodeCompletionString::CK_LeftBrace);
3647 Pattern->AddPlaceholderChunk("statements");
3648 Pattern->AddChunk(CodeCompletionString::CK_RightBrace);
3649 Pattern->AddTextChunk("@catch");
3650 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
3651 Pattern->AddPlaceholderChunk("parameter");
3652 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
3653 Pattern->AddChunk(CodeCompletionString::CK_LeftBrace);
3654 Pattern->AddPlaceholderChunk("statements");
3655 Pattern->AddChunk(CodeCompletionString::CK_RightBrace);
3656 Pattern->AddTextChunk("@finally");
3657 Pattern->AddChunk(CodeCompletionString::CK_LeftBrace);
3658 Pattern->AddPlaceholderChunk("statements");
3659 Pattern->AddChunk(CodeCompletionString::CK_RightBrace);
3660 Results.AddResult(Result(Pattern));
3661 }
Douglas Gregorb6ac2452010-01-13 21:24:21 +00003662
Douglas Gregor9a0c85e2009-12-07 09:51:25 +00003663 // @throw
3664 Pattern = new CodeCompletionString;
Douglas Gregorb6ac2452010-01-13 21:24:21 +00003665 Pattern->AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt,throw));
Douglas Gregor834389b2010-01-12 06:38:28 +00003666 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
Douglas Gregor9a0c85e2009-12-07 09:51:25 +00003667 Pattern->AddPlaceholderChunk("expression");
Douglas Gregora4477812010-01-14 16:01:26 +00003668 Results.AddResult(Result(Pattern));
Douglas Gregorb6ac2452010-01-13 21:24:21 +00003669
Douglas Gregorc8bddde2010-05-28 00:22:41 +00003670 if (Results.includeCodePatterns()) {
3671 // @synchronized ( expression ) { statements }
3672 Pattern = new CodeCompletionString;
3673 Pattern->AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt,synchronized));
3674 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
3675 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
3676 Pattern->AddPlaceholderChunk("expression");
3677 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
3678 Pattern->AddChunk(CodeCompletionString::CK_LeftBrace);
3679 Pattern->AddPlaceholderChunk("statements");
3680 Pattern->AddChunk(CodeCompletionString::CK_RightBrace);
3681 Results.AddResult(Result(Pattern));
3682 }
Douglas Gregorb6ac2452010-01-13 21:24:21 +00003683}
Douglas Gregor9a0c85e2009-12-07 09:51:25 +00003684
Douglas Gregorbca403c2010-01-13 23:51:12 +00003685static void AddObjCVisibilityResults(const LangOptions &LangOpts,
Douglas Gregorc38c3e12010-01-13 21:54:15 +00003686 ResultBuilder &Results,
3687 bool NeedAt) {
John McCall0a2c5e22010-08-25 06:19:51 +00003688 typedef CodeCompletionResult Result;
Douglas Gregora4477812010-01-14 16:01:26 +00003689 Results.AddResult(Result(OBJC_AT_KEYWORD_NAME(NeedAt,private)));
3690 Results.AddResult(Result(OBJC_AT_KEYWORD_NAME(NeedAt,protected)));
3691 Results.AddResult(Result(OBJC_AT_KEYWORD_NAME(NeedAt,public)));
Douglas Gregorc38c3e12010-01-13 21:54:15 +00003692 if (LangOpts.ObjC2)
Douglas Gregora4477812010-01-14 16:01:26 +00003693 Results.AddResult(Result(OBJC_AT_KEYWORD_NAME(NeedAt,package)));
Douglas Gregorc38c3e12010-01-13 21:54:15 +00003694}
3695
3696void Sema::CodeCompleteObjCAtVisibility(Scope *S) {
3697 ResultBuilder Results(*this);
3698 Results.EnterNewScope();
Douglas Gregorbca403c2010-01-13 23:51:12 +00003699 AddObjCVisibilityResults(getLangOptions(), Results, false);
Douglas Gregorc38c3e12010-01-13 21:54:15 +00003700 Results.ExitScope();
Douglas Gregore6b1bb62010-08-11 21:23:17 +00003701 HandleCodeCompleteResults(this, CodeCompleter,
3702 CodeCompletionContext::CCC_Other,
3703 Results.data(),Results.size());
Douglas Gregorc38c3e12010-01-13 21:54:15 +00003704}
3705
3706void Sema::CodeCompleteObjCAtStatement(Scope *S) {
Douglas Gregorb6ac2452010-01-13 21:24:21 +00003707 ResultBuilder Results(*this);
3708 Results.EnterNewScope();
Douglas Gregorbca403c2010-01-13 23:51:12 +00003709 AddObjCStatementResults(Results, false);
3710 AddObjCExpressionResults(Results, false);
Douglas Gregor9a0c85e2009-12-07 09:51:25 +00003711 Results.ExitScope();
Douglas Gregore6b1bb62010-08-11 21:23:17 +00003712 HandleCodeCompleteResults(this, CodeCompleter,
3713 CodeCompletionContext::CCC_Other,
3714 Results.data(),Results.size());
Douglas Gregor9a0c85e2009-12-07 09:51:25 +00003715}
3716
3717void Sema::CodeCompleteObjCAtExpression(Scope *S) {
3718 ResultBuilder Results(*this);
3719 Results.EnterNewScope();
Douglas Gregorbca403c2010-01-13 23:51:12 +00003720 AddObjCExpressionResults(Results, false);
Douglas Gregor9a0c85e2009-12-07 09:51:25 +00003721 Results.ExitScope();
Douglas Gregore6b1bb62010-08-11 21:23:17 +00003722 HandleCodeCompleteResults(this, CodeCompleter,
3723 CodeCompletionContext::CCC_Other,
3724 Results.data(),Results.size());
Douglas Gregor9a0c85e2009-12-07 09:51:25 +00003725}
3726
Douglas Gregor988358f2009-11-19 00:14:45 +00003727/// \brief Determine whether the addition of the given flag to an Objective-C
3728/// property's attributes will cause a conflict.
3729static bool ObjCPropertyFlagConflicts(unsigned Attributes, unsigned NewFlag) {
3730 // Check if we've already added this flag.
3731 if (Attributes & NewFlag)
3732 return true;
3733
3734 Attributes |= NewFlag;
3735
3736 // Check for collisions with "readonly".
3737 if ((Attributes & ObjCDeclSpec::DQ_PR_readonly) &&
3738 (Attributes & (ObjCDeclSpec::DQ_PR_readwrite |
3739 ObjCDeclSpec::DQ_PR_assign |
3740 ObjCDeclSpec::DQ_PR_copy |
3741 ObjCDeclSpec::DQ_PR_retain)))
3742 return true;
3743
3744 // Check for more than one of { assign, copy, retain }.
3745 unsigned AssignCopyRetMask = Attributes & (ObjCDeclSpec::DQ_PR_assign |
3746 ObjCDeclSpec::DQ_PR_copy |
3747 ObjCDeclSpec::DQ_PR_retain);
3748 if (AssignCopyRetMask &&
3749 AssignCopyRetMask != ObjCDeclSpec::DQ_PR_assign &&
3750 AssignCopyRetMask != ObjCDeclSpec::DQ_PR_copy &&
3751 AssignCopyRetMask != ObjCDeclSpec::DQ_PR_retain)
3752 return true;
3753
3754 return false;
3755}
3756
Douglas Gregora93b1082009-11-18 23:08:07 +00003757void Sema::CodeCompleteObjCPropertyFlags(Scope *S, ObjCDeclSpec &ODS) {
Steve Naroffece8e712009-10-08 21:55:05 +00003758 if (!CodeCompleter)
3759 return;
Douglas Gregord3c68542009-11-19 01:08:35 +00003760
Steve Naroffece8e712009-10-08 21:55:05 +00003761 unsigned Attributes = ODS.getPropertyAttributes();
3762
John McCall0a2c5e22010-08-25 06:19:51 +00003763 typedef CodeCompletionResult Result;
Steve Naroffece8e712009-10-08 21:55:05 +00003764 ResultBuilder Results(*this);
3765 Results.EnterNewScope();
Douglas Gregor988358f2009-11-19 00:14:45 +00003766 if (!ObjCPropertyFlagConflicts(Attributes, ObjCDeclSpec::DQ_PR_readonly))
John McCall0a2c5e22010-08-25 06:19:51 +00003767 Results.AddResult(CodeCompletionResult("readonly"));
Douglas Gregor988358f2009-11-19 00:14:45 +00003768 if (!ObjCPropertyFlagConflicts(Attributes, ObjCDeclSpec::DQ_PR_assign))
John McCall0a2c5e22010-08-25 06:19:51 +00003769 Results.AddResult(CodeCompletionResult("assign"));
Douglas Gregor988358f2009-11-19 00:14:45 +00003770 if (!ObjCPropertyFlagConflicts(Attributes, ObjCDeclSpec::DQ_PR_readwrite))
John McCall0a2c5e22010-08-25 06:19:51 +00003771 Results.AddResult(CodeCompletionResult("readwrite"));
Douglas Gregor988358f2009-11-19 00:14:45 +00003772 if (!ObjCPropertyFlagConflicts(Attributes, ObjCDeclSpec::DQ_PR_retain))
John McCall0a2c5e22010-08-25 06:19:51 +00003773 Results.AddResult(CodeCompletionResult("retain"));
Douglas Gregor988358f2009-11-19 00:14:45 +00003774 if (!ObjCPropertyFlagConflicts(Attributes, ObjCDeclSpec::DQ_PR_copy))
John McCall0a2c5e22010-08-25 06:19:51 +00003775 Results.AddResult(CodeCompletionResult("copy"));
Douglas Gregor988358f2009-11-19 00:14:45 +00003776 if (!ObjCPropertyFlagConflicts(Attributes, ObjCDeclSpec::DQ_PR_nonatomic))
John McCall0a2c5e22010-08-25 06:19:51 +00003777 Results.AddResult(CodeCompletionResult("nonatomic"));
Douglas Gregor988358f2009-11-19 00:14:45 +00003778 if (!ObjCPropertyFlagConflicts(Attributes, ObjCDeclSpec::DQ_PR_setter)) {
Douglas Gregor54f01612009-11-19 00:01:57 +00003779 CodeCompletionString *Setter = new CodeCompletionString;
3780 Setter->AddTypedTextChunk("setter");
3781 Setter->AddTextChunk(" = ");
3782 Setter->AddPlaceholderChunk("method");
John McCall0a2c5e22010-08-25 06:19:51 +00003783 Results.AddResult(CodeCompletionResult(Setter));
Douglas Gregor54f01612009-11-19 00:01:57 +00003784 }
Douglas Gregor988358f2009-11-19 00:14:45 +00003785 if (!ObjCPropertyFlagConflicts(Attributes, ObjCDeclSpec::DQ_PR_getter)) {
Douglas Gregor54f01612009-11-19 00:01:57 +00003786 CodeCompletionString *Getter = new CodeCompletionString;
3787 Getter->AddTypedTextChunk("getter");
3788 Getter->AddTextChunk(" = ");
3789 Getter->AddPlaceholderChunk("method");
John McCall0a2c5e22010-08-25 06:19:51 +00003790 Results.AddResult(CodeCompletionResult(Getter));
Douglas Gregor54f01612009-11-19 00:01:57 +00003791 }
Steve Naroffece8e712009-10-08 21:55:05 +00003792 Results.ExitScope();
Douglas Gregore6b1bb62010-08-11 21:23:17 +00003793 HandleCodeCompleteResults(this, CodeCompleter,
3794 CodeCompletionContext::CCC_Other,
3795 Results.data(),Results.size());
Steve Naroffece8e712009-10-08 21:55:05 +00003796}
Steve Naroffc4df6d22009-11-07 02:08:14 +00003797
Douglas Gregor4ad96852009-11-19 07:41:15 +00003798/// \brief Descripts the kind of Objective-C method that we want to find
3799/// via code completion.
3800enum ObjCMethodKind {
3801 MK_Any, //< Any kind of method, provided it means other specified criteria.
3802 MK_ZeroArgSelector, //< Zero-argument (unary) selector.
3803 MK_OneArgSelector //< One-argument selector.
3804};
3805
Douglas Gregor458433d2010-08-26 15:07:07 +00003806static bool isAcceptableObjCSelector(Selector Sel,
3807 ObjCMethodKind WantKind,
3808 IdentifierInfo **SelIdents,
3809 unsigned NumSelIdents) {
3810 if (NumSelIdents > Sel.getNumArgs())
3811 return false;
3812
3813 switch (WantKind) {
3814 case MK_Any: break;
3815 case MK_ZeroArgSelector: return Sel.isUnarySelector();
3816 case MK_OneArgSelector: return Sel.getNumArgs() == 1;
3817 }
3818
3819 for (unsigned I = 0; I != NumSelIdents; ++I)
3820 if (SelIdents[I] != Sel.getIdentifierInfoForSlot(I))
3821 return false;
3822
3823 return true;
3824}
3825
Douglas Gregor4ad96852009-11-19 07:41:15 +00003826static bool isAcceptableObjCMethod(ObjCMethodDecl *Method,
3827 ObjCMethodKind WantKind,
3828 IdentifierInfo **SelIdents,
3829 unsigned NumSelIdents) {
Douglas Gregor458433d2010-08-26 15:07:07 +00003830 return isAcceptableObjCSelector(Method->getSelector(), WantKind, SelIdents,
3831 NumSelIdents);
Douglas Gregor4ad96852009-11-19 07:41:15 +00003832}
Douglas Gregord36adf52010-09-16 16:06:31 +00003833
3834namespace {
3835 /// \brief A set of selectors, which is used to avoid introducing multiple
3836 /// completions with the same selector into the result set.
3837 typedef llvm::SmallPtrSet<Selector, 16> VisitedSelectorSet;
3838}
3839
Douglas Gregor36ecb042009-11-17 23:22:23 +00003840/// \brief Add all of the Objective-C methods in the given Objective-C
3841/// container to the set of results.
3842///
3843/// The container will be a class, protocol, category, or implementation of
3844/// any of the above. This mether will recurse to include methods from
3845/// the superclasses of classes along with their categories, protocols, and
3846/// implementations.
3847///
3848/// \param Container the container in which we'll look to find methods.
3849///
3850/// \param WantInstance whether to add instance methods (only); if false, this
3851/// routine will add factory methods (only).
3852///
3853/// \param CurContext the context in which we're performing the lookup that
3854/// finds methods.
3855///
3856/// \param Results the structure into which we'll add results.
3857static void AddObjCMethods(ObjCContainerDecl *Container,
3858 bool WantInstanceMethods,
Douglas Gregor4ad96852009-11-19 07:41:15 +00003859 ObjCMethodKind WantKind,
Douglas Gregord3c68542009-11-19 01:08:35 +00003860 IdentifierInfo **SelIdents,
3861 unsigned NumSelIdents,
Douglas Gregor36ecb042009-11-17 23:22:23 +00003862 DeclContext *CurContext,
Douglas Gregord36adf52010-09-16 16:06:31 +00003863 VisitedSelectorSet &Selectors,
Douglas Gregor408be5a2010-08-25 01:08:01 +00003864 ResultBuilder &Results,
3865 bool InOriginalClass = true) {
John McCall0a2c5e22010-08-25 06:19:51 +00003866 typedef CodeCompletionResult Result;
Douglas Gregor36ecb042009-11-17 23:22:23 +00003867 for (ObjCContainerDecl::method_iterator M = Container->meth_begin(),
3868 MEnd = Container->meth_end();
3869 M != MEnd; ++M) {
Douglas Gregord3c68542009-11-19 01:08:35 +00003870 if ((*M)->isInstanceMethod() == WantInstanceMethods) {
3871 // Check whether the selector identifiers we've been given are a
3872 // subset of the identifiers for this particular method.
Douglas Gregor4ad96852009-11-19 07:41:15 +00003873 if (!isAcceptableObjCMethod(*M, WantKind, SelIdents, NumSelIdents))
Douglas Gregord3c68542009-11-19 01:08:35 +00003874 continue;
Douglas Gregor4ad96852009-11-19 07:41:15 +00003875
Douglas Gregord36adf52010-09-16 16:06:31 +00003876 if (!Selectors.insert((*M)->getSelector()))
3877 continue;
3878
Douglas Gregord3c68542009-11-19 01:08:35 +00003879 Result R = Result(*M, 0);
3880 R.StartParameter = NumSelIdents;
Douglas Gregor4ad96852009-11-19 07:41:15 +00003881 R.AllParametersAreInformative = (WantKind != MK_Any);
Douglas Gregor408be5a2010-08-25 01:08:01 +00003882 if (!InOriginalClass)
3883 R.Priority += CCD_InBaseClass;
Douglas Gregord3c68542009-11-19 01:08:35 +00003884 Results.MaybeAddResult(R, CurContext);
3885 }
Douglas Gregor36ecb042009-11-17 23:22:23 +00003886 }
3887
Douglas Gregore396c7b2010-09-16 15:34:59 +00003888 // Visit the protocols of protocols.
3889 if (ObjCProtocolDecl *Protocol = dyn_cast<ObjCProtocolDecl>(Container)) {
3890 const ObjCList<ObjCProtocolDecl> &Protocols
3891 = Protocol->getReferencedProtocols();
3892 for (ObjCList<ObjCProtocolDecl>::iterator I = Protocols.begin(),
3893 E = Protocols.end();
3894 I != E; ++I)
3895 AddObjCMethods(*I, WantInstanceMethods, WantKind, SelIdents, NumSelIdents,
Douglas Gregord36adf52010-09-16 16:06:31 +00003896 CurContext, Selectors, Results, false);
Douglas Gregore396c7b2010-09-16 15:34:59 +00003897 }
3898
Douglas Gregor36ecb042009-11-17 23:22:23 +00003899 ObjCInterfaceDecl *IFace = dyn_cast<ObjCInterfaceDecl>(Container);
3900 if (!IFace)
3901 return;
3902
3903 // Add methods in protocols.
3904 const ObjCList<ObjCProtocolDecl> &Protocols= IFace->getReferencedProtocols();
3905 for (ObjCList<ObjCProtocolDecl>::iterator I = Protocols.begin(),
3906 E = Protocols.end();
3907 I != E; ++I)
Douglas Gregor4ad96852009-11-19 07:41:15 +00003908 AddObjCMethods(*I, WantInstanceMethods, WantKind, SelIdents, NumSelIdents,
Douglas Gregord36adf52010-09-16 16:06:31 +00003909 CurContext, Selectors, Results, false);
Douglas Gregor36ecb042009-11-17 23:22:23 +00003910
3911 // Add methods in categories.
3912 for (ObjCCategoryDecl *CatDecl = IFace->getCategoryList(); CatDecl;
3913 CatDecl = CatDecl->getNextClassCategory()) {
Douglas Gregor4ad96852009-11-19 07:41:15 +00003914 AddObjCMethods(CatDecl, WantInstanceMethods, WantKind, SelIdents,
Douglas Gregord36adf52010-09-16 16:06:31 +00003915 NumSelIdents, CurContext, Selectors, Results,
3916 InOriginalClass);
Douglas Gregor36ecb042009-11-17 23:22:23 +00003917
3918 // Add a categories protocol methods.
3919 const ObjCList<ObjCProtocolDecl> &Protocols
3920 = CatDecl->getReferencedProtocols();
3921 for (ObjCList<ObjCProtocolDecl>::iterator I = Protocols.begin(),
3922 E = Protocols.end();
3923 I != E; ++I)
Douglas Gregor4ad96852009-11-19 07:41:15 +00003924 AddObjCMethods(*I, WantInstanceMethods, WantKind, SelIdents,
Douglas Gregord36adf52010-09-16 16:06:31 +00003925 NumSelIdents, CurContext, Selectors, Results, false);
Douglas Gregor36ecb042009-11-17 23:22:23 +00003926
3927 // Add methods in category implementations.
3928 if (ObjCCategoryImplDecl *Impl = CatDecl->getImplementation())
Douglas Gregor4ad96852009-11-19 07:41:15 +00003929 AddObjCMethods(Impl, WantInstanceMethods, WantKind, SelIdents,
Douglas Gregord36adf52010-09-16 16:06:31 +00003930 NumSelIdents, CurContext, Selectors, Results,
3931 InOriginalClass);
Douglas Gregor36ecb042009-11-17 23:22:23 +00003932 }
3933
3934 // Add methods in superclass.
3935 if (IFace->getSuperClass())
Douglas Gregor4ad96852009-11-19 07:41:15 +00003936 AddObjCMethods(IFace->getSuperClass(), WantInstanceMethods, WantKind,
Douglas Gregord36adf52010-09-16 16:06:31 +00003937 SelIdents, NumSelIdents, CurContext, Selectors, Results,
3938 false);
Douglas Gregor36ecb042009-11-17 23:22:23 +00003939
3940 // Add methods in our implementation, if any.
3941 if (ObjCImplementationDecl *Impl = IFace->getImplementation())
Douglas Gregor4ad96852009-11-19 07:41:15 +00003942 AddObjCMethods(Impl, WantInstanceMethods, WantKind, SelIdents,
Douglas Gregord36adf52010-09-16 16:06:31 +00003943 NumSelIdents, CurContext, Selectors, Results,
3944 InOriginalClass);
Douglas Gregor4ad96852009-11-19 07:41:15 +00003945}
3946
3947
John McCalld226f652010-08-21 09:40:31 +00003948void Sema::CodeCompleteObjCPropertyGetter(Scope *S, Decl *ClassDecl,
3949 Decl **Methods,
Douglas Gregor4ad96852009-11-19 07:41:15 +00003950 unsigned NumMethods) {
John McCall0a2c5e22010-08-25 06:19:51 +00003951 typedef CodeCompletionResult Result;
Douglas Gregor4ad96852009-11-19 07:41:15 +00003952
3953 // Try to find the interface where getters might live.
John McCalld226f652010-08-21 09:40:31 +00003954 ObjCInterfaceDecl *Class = dyn_cast_or_null<ObjCInterfaceDecl>(ClassDecl);
Douglas Gregor4ad96852009-11-19 07:41:15 +00003955 if (!Class) {
3956 if (ObjCCategoryDecl *Category
John McCalld226f652010-08-21 09:40:31 +00003957 = dyn_cast_or_null<ObjCCategoryDecl>(ClassDecl))
Douglas Gregor4ad96852009-11-19 07:41:15 +00003958 Class = Category->getClassInterface();
3959
3960 if (!Class)
3961 return;
3962 }
3963
3964 // Find all of the potential getters.
3965 ResultBuilder Results(*this);
3966 Results.EnterNewScope();
3967
3968 // FIXME: We need to do this because Objective-C methods don't get
3969 // pushed into DeclContexts early enough. Argh!
3970 for (unsigned I = 0; I != NumMethods; ++I) {
3971 if (ObjCMethodDecl *Method
John McCalld226f652010-08-21 09:40:31 +00003972 = dyn_cast_or_null<ObjCMethodDecl>(Methods[I]))
Douglas Gregor4ad96852009-11-19 07:41:15 +00003973 if (Method->isInstanceMethod() &&
3974 isAcceptableObjCMethod(Method, MK_ZeroArgSelector, 0, 0)) {
3975 Result R = Result(Method, 0);
3976 R.AllParametersAreInformative = true;
3977 Results.MaybeAddResult(R, CurContext);
3978 }
3979 }
3980
Douglas Gregord36adf52010-09-16 16:06:31 +00003981 VisitedSelectorSet Selectors;
3982 AddObjCMethods(Class, true, MK_ZeroArgSelector, 0, 0, CurContext, Selectors,
3983 Results);
Douglas Gregor4ad96852009-11-19 07:41:15 +00003984 Results.ExitScope();
Douglas Gregore6b1bb62010-08-11 21:23:17 +00003985 HandleCodeCompleteResults(this, CodeCompleter,
3986 CodeCompletionContext::CCC_Other,
3987 Results.data(),Results.size());
Douglas Gregor4ad96852009-11-19 07:41:15 +00003988}
3989
John McCalld226f652010-08-21 09:40:31 +00003990void Sema::CodeCompleteObjCPropertySetter(Scope *S, Decl *ObjCImplDecl,
3991 Decl **Methods,
Douglas Gregor4ad96852009-11-19 07:41:15 +00003992 unsigned NumMethods) {
John McCall0a2c5e22010-08-25 06:19:51 +00003993 typedef CodeCompletionResult Result;
Douglas Gregor4ad96852009-11-19 07:41:15 +00003994
3995 // Try to find the interface where setters might live.
3996 ObjCInterfaceDecl *Class
John McCalld226f652010-08-21 09:40:31 +00003997 = dyn_cast_or_null<ObjCInterfaceDecl>(ObjCImplDecl);
Douglas Gregor4ad96852009-11-19 07:41:15 +00003998 if (!Class) {
3999 if (ObjCCategoryDecl *Category
John McCalld226f652010-08-21 09:40:31 +00004000 = dyn_cast_or_null<ObjCCategoryDecl>(ObjCImplDecl))
Douglas Gregor4ad96852009-11-19 07:41:15 +00004001 Class = Category->getClassInterface();
4002
4003 if (!Class)
4004 return;
4005 }
4006
4007 // Find all of the potential getters.
4008 ResultBuilder Results(*this);
4009 Results.EnterNewScope();
4010
4011 // FIXME: We need to do this because Objective-C methods don't get
4012 // pushed into DeclContexts early enough. Argh!
4013 for (unsigned I = 0; I != NumMethods; ++I) {
4014 if (ObjCMethodDecl *Method
John McCalld226f652010-08-21 09:40:31 +00004015 = dyn_cast_or_null<ObjCMethodDecl>(Methods[I]))
Douglas Gregor4ad96852009-11-19 07:41:15 +00004016 if (Method->isInstanceMethod() &&
4017 isAcceptableObjCMethod(Method, MK_OneArgSelector, 0, 0)) {
4018 Result R = Result(Method, 0);
4019 R.AllParametersAreInformative = true;
4020 Results.MaybeAddResult(R, CurContext);
4021 }
4022 }
4023
Douglas Gregord36adf52010-09-16 16:06:31 +00004024 VisitedSelectorSet Selectors;
4025 AddObjCMethods(Class, true, MK_OneArgSelector, 0, 0, CurContext,
4026 Selectors, Results);
Douglas Gregor4ad96852009-11-19 07:41:15 +00004027
4028 Results.ExitScope();
Douglas Gregore6b1bb62010-08-11 21:23:17 +00004029 HandleCodeCompleteResults(this, CodeCompleter,
4030 CodeCompletionContext::CCC_Other,
4031 Results.data(),Results.size());
Douglas Gregor36ecb042009-11-17 23:22:23 +00004032}
4033
Douglas Gregord32b0222010-08-24 01:06:58 +00004034void Sema::CodeCompleteObjCPassingType(Scope *S, ObjCDeclSpec &DS) {
John McCall0a2c5e22010-08-25 06:19:51 +00004035 typedef CodeCompletionResult Result;
Douglas Gregord32b0222010-08-24 01:06:58 +00004036 ResultBuilder Results(*this);
4037 Results.EnterNewScope();
4038
4039 // Add context-sensitive, Objective-C parameter-passing keywords.
4040 bool AddedInOut = false;
4041 if ((DS.getObjCDeclQualifier() &
4042 (ObjCDeclSpec::DQ_In | ObjCDeclSpec::DQ_Inout)) == 0) {
4043 Results.AddResult("in");
4044 Results.AddResult("inout");
4045 AddedInOut = true;
4046 }
4047 if ((DS.getObjCDeclQualifier() &
4048 (ObjCDeclSpec::DQ_Out | ObjCDeclSpec::DQ_Inout)) == 0) {
4049 Results.AddResult("out");
4050 if (!AddedInOut)
4051 Results.AddResult("inout");
4052 }
4053 if ((DS.getObjCDeclQualifier() &
4054 (ObjCDeclSpec::DQ_Bycopy | ObjCDeclSpec::DQ_Byref |
4055 ObjCDeclSpec::DQ_Oneway)) == 0) {
4056 Results.AddResult("bycopy");
4057 Results.AddResult("byref");
4058 Results.AddResult("oneway");
4059 }
4060
4061 // Add various builtin type names and specifiers.
4062 AddOrdinaryNameResults(PCC_Type, S, *this, Results);
4063 Results.ExitScope();
4064
4065 // Add the various type names
4066 Results.setFilter(&ResultBuilder::IsOrdinaryNonValueName);
4067 CodeCompletionDeclConsumer Consumer(Results, CurContext);
4068 LookupVisibleDecls(S, LookupOrdinaryName, Consumer,
4069 CodeCompleter->includeGlobals());
4070
4071 if (CodeCompleter->includeMacros())
4072 AddMacroResults(PP, Results);
4073
4074 HandleCodeCompleteResults(this, CodeCompleter,
4075 CodeCompletionContext::CCC_Type,
4076 Results.data(), Results.size());
4077}
4078
Douglas Gregor22f56992010-04-06 19:22:33 +00004079/// \brief When we have an expression with type "id", we may assume
4080/// that it has some more-specific class type based on knowledge of
4081/// common uses of Objective-C. This routine returns that class type,
4082/// or NULL if no better result could be determined.
4083static ObjCInterfaceDecl *GetAssumedMessageSendExprType(Expr *E) {
Douglas Gregor78edf512010-09-15 16:23:04 +00004084 ObjCMessageExpr *Msg = dyn_cast_or_null<ObjCMessageExpr>(E);
Douglas Gregor22f56992010-04-06 19:22:33 +00004085 if (!Msg)
4086 return 0;
4087
4088 Selector Sel = Msg->getSelector();
4089 if (Sel.isNull())
4090 return 0;
4091
4092 IdentifierInfo *Id = Sel.getIdentifierInfoForSlot(0);
4093 if (!Id)
4094 return 0;
4095
4096 ObjCMethodDecl *Method = Msg->getMethodDecl();
4097 if (!Method)
4098 return 0;
4099
4100 // Determine the class that we're sending the message to.
Douglas Gregor04badcf2010-04-21 00:45:42 +00004101 ObjCInterfaceDecl *IFace = 0;
4102 switch (Msg->getReceiverKind()) {
4103 case ObjCMessageExpr::Class:
John McCallc12c5bb2010-05-15 11:32:37 +00004104 if (const ObjCObjectType *ObjType
4105 = Msg->getClassReceiver()->getAs<ObjCObjectType>())
4106 IFace = ObjType->getInterface();
Douglas Gregor04badcf2010-04-21 00:45:42 +00004107 break;
4108
4109 case ObjCMessageExpr::Instance: {
4110 QualType T = Msg->getInstanceReceiver()->getType();
4111 if (const ObjCObjectPointerType *Ptr = T->getAs<ObjCObjectPointerType>())
4112 IFace = Ptr->getInterfaceDecl();
4113 break;
4114 }
4115
4116 case ObjCMessageExpr::SuperInstance:
4117 case ObjCMessageExpr::SuperClass:
4118 break;
Douglas Gregor22f56992010-04-06 19:22:33 +00004119 }
4120
4121 if (!IFace)
4122 return 0;
4123
4124 ObjCInterfaceDecl *Super = IFace->getSuperClass();
4125 if (Method->isInstanceMethod())
4126 return llvm::StringSwitch<ObjCInterfaceDecl *>(Id->getName())
4127 .Case("retain", IFace)
4128 .Case("autorelease", IFace)
4129 .Case("copy", IFace)
4130 .Case("copyWithZone", IFace)
4131 .Case("mutableCopy", IFace)
4132 .Case("mutableCopyWithZone", IFace)
4133 .Case("awakeFromCoder", IFace)
4134 .Case("replacementObjectFromCoder", IFace)
4135 .Case("class", IFace)
4136 .Case("classForCoder", IFace)
4137 .Case("superclass", Super)
4138 .Default(0);
4139
4140 return llvm::StringSwitch<ObjCInterfaceDecl *>(Id->getName())
4141 .Case("new", IFace)
4142 .Case("alloc", IFace)
4143 .Case("allocWithZone", IFace)
4144 .Case("class", IFace)
4145 .Case("superclass", Super)
4146 .Default(0);
4147}
4148
Douglas Gregor03d8aec2010-08-27 15:10:57 +00004149// Add a special completion for a message send to "super", which fills in the
4150// most likely case of forwarding all of our arguments to the superclass
4151// function.
4152///
4153/// \param S The semantic analysis object.
4154///
4155/// \param S NeedSuperKeyword Whether we need to prefix this completion with
4156/// the "super" keyword. Otherwise, we just need to provide the arguments.
4157///
4158/// \param SelIdents The identifiers in the selector that have already been
4159/// provided as arguments for a send to "super".
4160///
4161/// \param NumSelIdents The number of identifiers in \p SelIdents.
4162///
4163/// \param Results The set of results to augment.
4164///
4165/// \returns the Objective-C method declaration that would be invoked by
4166/// this "super" completion. If NULL, no completion was added.
4167static ObjCMethodDecl *AddSuperSendCompletion(Sema &S, bool NeedSuperKeyword,
4168 IdentifierInfo **SelIdents,
4169 unsigned NumSelIdents,
4170 ResultBuilder &Results) {
4171 ObjCMethodDecl *CurMethod = S.getCurMethodDecl();
4172 if (!CurMethod)
4173 return 0;
4174
4175 ObjCInterfaceDecl *Class = CurMethod->getClassInterface();
4176 if (!Class)
4177 return 0;
4178
4179 // Try to find a superclass method with the same selector.
4180 ObjCMethodDecl *SuperMethod = 0;
4181 while ((Class = Class->getSuperClass()) && !SuperMethod)
4182 SuperMethod = Class->getMethod(CurMethod->getSelector(),
4183 CurMethod->isInstanceMethod());
4184
4185 if (!SuperMethod)
4186 return 0;
4187
4188 // Check whether the superclass method has the same signature.
4189 if (CurMethod->param_size() != SuperMethod->param_size() ||
4190 CurMethod->isVariadic() != SuperMethod->isVariadic())
4191 return 0;
4192
4193 for (ObjCMethodDecl::param_iterator CurP = CurMethod->param_begin(),
4194 CurPEnd = CurMethod->param_end(),
4195 SuperP = SuperMethod->param_begin();
4196 CurP != CurPEnd; ++CurP, ++SuperP) {
4197 // Make sure the parameter types are compatible.
4198 if (!S.Context.hasSameUnqualifiedType((*CurP)->getType(),
4199 (*SuperP)->getType()))
4200 return 0;
4201
4202 // Make sure we have a parameter name to forward!
4203 if (!(*CurP)->getIdentifier())
4204 return 0;
4205 }
4206
4207 // We have a superclass method. Now, form the send-to-super completion.
4208 CodeCompletionString *Pattern = new CodeCompletionString;
4209
4210 // Give this completion a return type.
4211 AddResultTypeChunk(S.Context, SuperMethod, Pattern);
4212
4213 // If we need the "super" keyword, add it (plus some spacing).
4214 if (NeedSuperKeyword) {
4215 Pattern->AddTypedTextChunk("super");
4216 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
4217 }
4218
4219 Selector Sel = CurMethod->getSelector();
4220 if (Sel.isUnarySelector()) {
4221 if (NeedSuperKeyword)
4222 Pattern->AddTextChunk(Sel.getIdentifierInfoForSlot(0)->getName());
4223 else
4224 Pattern->AddTypedTextChunk(Sel.getIdentifierInfoForSlot(0)->getName());
4225 } else {
4226 ObjCMethodDecl::param_iterator CurP = CurMethod->param_begin();
4227 for (unsigned I = 0, N = Sel.getNumArgs(); I != N; ++I, ++CurP) {
4228 if (I > NumSelIdents)
4229 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
4230
4231 if (I < NumSelIdents)
4232 Pattern->AddInformativeChunk(
4233 Sel.getIdentifierInfoForSlot(I)->getName().str() + ":");
4234 else if (NeedSuperKeyword || I > NumSelIdents) {
4235 Pattern->AddTextChunk(
4236 Sel.getIdentifierInfoForSlot(I)->getName().str() + ":");
4237 Pattern->AddPlaceholderChunk((*CurP)->getIdentifier()->getName());
4238 } else {
4239 Pattern->AddTypedTextChunk(
4240 Sel.getIdentifierInfoForSlot(I)->getName().str() + ":");
4241 Pattern->AddPlaceholderChunk((*CurP)->getIdentifier()->getName());
4242 }
4243 }
4244 }
4245
4246 Results.AddResult(CodeCompletionResult(Pattern, CCP_SuperCompletion,
4247 SuperMethod->isInstanceMethod()
4248 ? CXCursor_ObjCInstanceMethodDecl
4249 : CXCursor_ObjCClassMethodDecl));
4250 return SuperMethod;
4251}
4252
Douglas Gregor8e254cf2010-05-27 23:06:34 +00004253void Sema::CodeCompleteObjCMessageReceiver(Scope *S) {
John McCall0a2c5e22010-08-25 06:19:51 +00004254 typedef CodeCompletionResult Result;
Douglas Gregor8e254cf2010-05-27 23:06:34 +00004255 ResultBuilder Results(*this);
4256
4257 // Find anything that looks like it could be a message receiver.
4258 Results.setFilter(&ResultBuilder::IsObjCMessageReceiver);
4259 CodeCompletionDeclConsumer Consumer(Results, CurContext);
4260 Results.EnterNewScope();
Douglas Gregor8071e422010-08-15 06:18:01 +00004261 LookupVisibleDecls(S, LookupOrdinaryName, Consumer,
4262 CodeCompleter->includeGlobals());
Douglas Gregor8e254cf2010-05-27 23:06:34 +00004263
4264 // If we are in an Objective-C method inside a class that has a superclass,
4265 // add "super" as an option.
4266 if (ObjCMethodDecl *Method = getCurMethodDecl())
4267 if (ObjCInterfaceDecl *Iface = Method->getClassInterface())
Douglas Gregor03d8aec2010-08-27 15:10:57 +00004268 if (Iface->getSuperClass()) {
Douglas Gregor8e254cf2010-05-27 23:06:34 +00004269 Results.AddResult(Result("super"));
Douglas Gregor03d8aec2010-08-27 15:10:57 +00004270
4271 AddSuperSendCompletion(*this, /*NeedSuperKeyword=*/true, 0, 0, Results);
4272 }
Douglas Gregor8e254cf2010-05-27 23:06:34 +00004273
4274 Results.ExitScope();
4275
4276 if (CodeCompleter->includeMacros())
4277 AddMacroResults(PP, Results);
Douglas Gregore6b1bb62010-08-11 21:23:17 +00004278 HandleCodeCompleteResults(this, CodeCompleter,
4279 CodeCompletionContext::CCC_ObjCMessageReceiver,
4280 Results.data(), Results.size());
Douglas Gregor8e254cf2010-05-27 23:06:34 +00004281
4282}
4283
Douglas Gregor2725ca82010-04-21 19:57:20 +00004284void Sema::CodeCompleteObjCSuperMessage(Scope *S, SourceLocation SuperLoc,
4285 IdentifierInfo **SelIdents,
4286 unsigned NumSelIdents) {
4287 ObjCInterfaceDecl *CDecl = 0;
4288 if (ObjCMethodDecl *CurMethod = getCurMethodDecl()) {
4289 // Figure out which interface we're in.
4290 CDecl = CurMethod->getClassInterface();
4291 if (!CDecl)
4292 return;
4293
4294 // Find the superclass of this class.
4295 CDecl = CDecl->getSuperClass();
4296 if (!CDecl)
4297 return;
4298
4299 if (CurMethod->isInstanceMethod()) {
4300 // We are inside an instance method, which means that the message
4301 // send [super ...] is actually calling an instance method on the
4302 // current object. Build the super expression and handle this like
4303 // an instance method.
4304 QualType SuperTy = Context.getObjCInterfaceType(CDecl);
4305 SuperTy = Context.getObjCObjectPointerType(SuperTy);
John McCall60d7b3a2010-08-24 06:29:42 +00004306 ExprResult Super
Douglas Gregor2725ca82010-04-21 19:57:20 +00004307 = Owned(new (Context) ObjCSuperExpr(SuperLoc, SuperTy));
4308 return CodeCompleteObjCInstanceMessage(S, (Expr *)Super.get(),
Douglas Gregor03d8aec2010-08-27 15:10:57 +00004309 SelIdents, NumSelIdents,
4310 /*IsSuper=*/true);
Douglas Gregor2725ca82010-04-21 19:57:20 +00004311 }
4312
4313 // Fall through to send to the superclass in CDecl.
4314 } else {
4315 // "super" may be the name of a type or variable. Figure out which
4316 // it is.
4317 IdentifierInfo *Super = &Context.Idents.get("super");
4318 NamedDecl *ND = LookupSingleName(S, Super, SuperLoc,
4319 LookupOrdinaryName);
4320 if ((CDecl = dyn_cast_or_null<ObjCInterfaceDecl>(ND))) {
4321 // "super" names an interface. Use it.
4322 } else if (TypeDecl *TD = dyn_cast_or_null<TypeDecl>(ND)) {
John McCallc12c5bb2010-05-15 11:32:37 +00004323 if (const ObjCObjectType *Iface
4324 = Context.getTypeDeclType(TD)->getAs<ObjCObjectType>())
4325 CDecl = Iface->getInterface();
Douglas Gregor2725ca82010-04-21 19:57:20 +00004326 } else if (ND && isa<UnresolvedUsingTypenameDecl>(ND)) {
4327 // "super" names an unresolved type; we can't be more specific.
4328 } else {
4329 // Assume that "super" names some kind of value and parse that way.
4330 CXXScopeSpec SS;
4331 UnqualifiedId id;
4332 id.setIdentifier(Super, SuperLoc);
John McCall60d7b3a2010-08-24 06:29:42 +00004333 ExprResult SuperExpr = ActOnIdExpression(S, SS, id, false, false);
Douglas Gregor2725ca82010-04-21 19:57:20 +00004334 return CodeCompleteObjCInstanceMessage(S, (Expr *)SuperExpr.get(),
4335 SelIdents, NumSelIdents);
4336 }
4337
4338 // Fall through
4339 }
4340
John McCallb3d87482010-08-24 05:47:05 +00004341 ParsedType Receiver;
Douglas Gregor2725ca82010-04-21 19:57:20 +00004342 if (CDecl)
John McCallb3d87482010-08-24 05:47:05 +00004343 Receiver = ParsedType::make(Context.getObjCInterfaceType(CDecl));
Douglas Gregor2725ca82010-04-21 19:57:20 +00004344 return CodeCompleteObjCClassMessage(S, Receiver, SelIdents,
Douglas Gregor03d8aec2010-08-27 15:10:57 +00004345 NumSelIdents, /*IsSuper=*/true);
Douglas Gregor2725ca82010-04-21 19:57:20 +00004346}
4347
Douglas Gregorc7b6d882010-09-16 15:14:18 +00004348static void AddClassMessageCompletions(Sema &SemaRef, Scope *S,
4349 ParsedType Receiver,
4350 IdentifierInfo **SelIdents,
4351 unsigned NumSelIdents,
4352 bool IsSuper,
4353 ResultBuilder &Results) {
John McCall0a2c5e22010-08-25 06:19:51 +00004354 typedef CodeCompletionResult Result;
Douglas Gregor24a069f2009-11-17 17:59:40 +00004355 ObjCInterfaceDecl *CDecl = 0;
Douglas Gregorc7b6d882010-09-16 15:14:18 +00004356
Douglas Gregor24a069f2009-11-17 17:59:40 +00004357 // If the given name refers to an interface type, retrieve the
4358 // corresponding declaration.
Douglas Gregor2725ca82010-04-21 19:57:20 +00004359 if (Receiver) {
Douglas Gregorc7b6d882010-09-16 15:14:18 +00004360 QualType T = SemaRef.GetTypeFromParser(Receiver, 0);
Douglas Gregor2725ca82010-04-21 19:57:20 +00004361 if (!T.isNull())
John McCallc12c5bb2010-05-15 11:32:37 +00004362 if (const ObjCObjectType *Interface = T->getAs<ObjCObjectType>())
4363 CDecl = Interface->getInterface();
Douglas Gregor24a069f2009-11-17 17:59:40 +00004364 }
Douglas Gregorc7b6d882010-09-16 15:14:18 +00004365
Douglas Gregor36ecb042009-11-17 23:22:23 +00004366 // Add all of the factory methods in this Objective-C class, its protocols,
4367 // superclasses, categories, implementation, etc.
Steve Naroffc4df6d22009-11-07 02:08:14 +00004368 Results.EnterNewScope();
Douglas Gregorc7b6d882010-09-16 15:14:18 +00004369
Douglas Gregor03d8aec2010-08-27 15:10:57 +00004370 // If this is a send-to-super, try to add the special "super" send
4371 // completion.
4372 if (IsSuper) {
4373 if (ObjCMethodDecl *SuperMethod
Douglas Gregorc7b6d882010-09-16 15:14:18 +00004374 = AddSuperSendCompletion(SemaRef, false, SelIdents, NumSelIdents,
4375 Results))
Douglas Gregor03d8aec2010-08-27 15:10:57 +00004376 Results.Ignore(SuperMethod);
4377 }
Douglas Gregorc7b6d882010-09-16 15:14:18 +00004378
Douglas Gregor265f7492010-08-27 15:29:55 +00004379 // If we're inside an Objective-C method definition, prefer its selector to
4380 // others.
Douglas Gregorc7b6d882010-09-16 15:14:18 +00004381 if (ObjCMethodDecl *CurMethod = SemaRef.getCurMethodDecl())
Douglas Gregor265f7492010-08-27 15:29:55 +00004382 Results.setPreferredSelector(CurMethod->getSelector());
Douglas Gregorc7b6d882010-09-16 15:14:18 +00004383
Douglas Gregord36adf52010-09-16 16:06:31 +00004384 VisitedSelectorSet Selectors;
Douglas Gregor13438f92010-04-06 16:40:00 +00004385 if (CDecl)
Douglas Gregorc7b6d882010-09-16 15:14:18 +00004386 AddObjCMethods(CDecl, false, MK_Any, SelIdents, NumSelIdents,
Douglas Gregord36adf52010-09-16 16:06:31 +00004387 SemaRef.CurContext, Selectors, Results);
Douglas Gregor2725ca82010-04-21 19:57:20 +00004388 else {
Douglas Gregor13438f92010-04-06 16:40:00 +00004389 // We're messaging "id" as a type; provide all class/factory methods.
Douglas Gregorc7b6d882010-09-16 15:14:18 +00004390
Douglas Gregor719770d2010-04-06 17:30:22 +00004391 // If we have an external source, load the entire class method
Sebastian Redl3c7f4132010-08-18 23:57:06 +00004392 // pool from the AST file.
Douglas Gregorc7b6d882010-09-16 15:14:18 +00004393 if (SemaRef.ExternalSource) {
4394 for (uint32_t I = 0,
4395 N = SemaRef.ExternalSource->GetNumExternalSelectors();
John McCall76bd1f32010-06-01 09:23:16 +00004396 I != N; ++I) {
Douglas Gregorc7b6d882010-09-16 15:14:18 +00004397 Selector Sel = SemaRef.ExternalSource->GetExternalSelector(I);
4398 if (Sel.isNull() || SemaRef.MethodPool.count(Sel))
Douglas Gregor719770d2010-04-06 17:30:22 +00004399 continue;
Douglas Gregorc7b6d882010-09-16 15:14:18 +00004400
4401 SemaRef.ReadMethodPool(Sel);
Douglas Gregor719770d2010-04-06 17:30:22 +00004402 }
4403 }
Douglas Gregorc7b6d882010-09-16 15:14:18 +00004404
4405 for (Sema::GlobalMethodPool::iterator M = SemaRef.MethodPool.begin(),
4406 MEnd = SemaRef.MethodPool.end();
Sebastian Redldb9d2142010-08-02 23:18:59 +00004407 M != MEnd; ++M) {
4408 for (ObjCMethodList *MethList = &M->second.second;
4409 MethList && MethList->Method;
Douglas Gregor13438f92010-04-06 16:40:00 +00004410 MethList = MethList->Next) {
4411 if (!isAcceptableObjCMethod(MethList->Method, MK_Any, SelIdents,
4412 NumSelIdents))
4413 continue;
Douglas Gregorc7b6d882010-09-16 15:14:18 +00004414
Douglas Gregor13438f92010-04-06 16:40:00 +00004415 Result R(MethList->Method, 0);
4416 R.StartParameter = NumSelIdents;
4417 R.AllParametersAreInformative = false;
Douglas Gregorc7b6d882010-09-16 15:14:18 +00004418 Results.MaybeAddResult(R, SemaRef.CurContext);
Douglas Gregor13438f92010-04-06 16:40:00 +00004419 }
4420 }
4421 }
Douglas Gregorc7b6d882010-09-16 15:14:18 +00004422
4423 Results.ExitScope();
4424}
Douglas Gregor13438f92010-04-06 16:40:00 +00004425
Douglas Gregorc7b6d882010-09-16 15:14:18 +00004426void Sema::CodeCompleteObjCClassMessage(Scope *S, ParsedType Receiver,
4427 IdentifierInfo **SelIdents,
4428 unsigned NumSelIdents,
4429 bool IsSuper) {
4430 ResultBuilder Results(*this);
4431 AddClassMessageCompletions(*this, S, Receiver, SelIdents, NumSelIdents, IsSuper,
4432 Results);
Douglas Gregore6b1bb62010-08-11 21:23:17 +00004433 HandleCodeCompleteResults(this, CodeCompleter,
4434 CodeCompletionContext::CCC_Other,
Douglas Gregor03d8aec2010-08-27 15:10:57 +00004435 Results.data(), Results.size());
Steve Naroffc4df6d22009-11-07 02:08:14 +00004436}
4437
Douglas Gregord3c68542009-11-19 01:08:35 +00004438void Sema::CodeCompleteObjCInstanceMessage(Scope *S, ExprTy *Receiver,
4439 IdentifierInfo **SelIdents,
Douglas Gregor03d8aec2010-08-27 15:10:57 +00004440 unsigned NumSelIdents,
4441 bool IsSuper) {
John McCall0a2c5e22010-08-25 06:19:51 +00004442 typedef CodeCompletionResult Result;
Steve Naroffc4df6d22009-11-07 02:08:14 +00004443
4444 Expr *RecExpr = static_cast<Expr *>(Receiver);
Steve Naroffc4df6d22009-11-07 02:08:14 +00004445
Douglas Gregor36ecb042009-11-17 23:22:23 +00004446 // If necessary, apply function/array conversion to the receiver.
4447 // C99 6.7.5.3p[7,8].
Douglas Gregor78edf512010-09-15 16:23:04 +00004448 if (RecExpr)
4449 DefaultFunctionArrayLvalueConversion(RecExpr);
4450 QualType ReceiverType = RecExpr? RecExpr->getType() : Context.getObjCIdType();
Steve Naroffc4df6d22009-11-07 02:08:14 +00004451
Douglas Gregor36ecb042009-11-17 23:22:23 +00004452 // Build the set of methods we can see.
4453 ResultBuilder Results(*this);
4454 Results.EnterNewScope();
Douglas Gregor22f56992010-04-06 19:22:33 +00004455
Douglas Gregor03d8aec2010-08-27 15:10:57 +00004456 // If this is a send-to-super, try to add the special "super" send
4457 // completion.
4458 if (IsSuper) {
4459 if (ObjCMethodDecl *SuperMethod
4460 = AddSuperSendCompletion(*this, false, SelIdents, NumSelIdents,
4461 Results))
4462 Results.Ignore(SuperMethod);
4463 }
4464
Douglas Gregor265f7492010-08-27 15:29:55 +00004465 // If we're inside an Objective-C method definition, prefer its selector to
4466 // others.
4467 if (ObjCMethodDecl *CurMethod = getCurMethodDecl())
4468 Results.setPreferredSelector(CurMethod->getSelector());
4469
Douglas Gregor22f56992010-04-06 19:22:33 +00004470 // If we're messaging an expression with type "id" or "Class", check
4471 // whether we know something special about the receiver that allows
4472 // us to assume a more-specific receiver type.
4473 if (ReceiverType->isObjCIdType() || ReceiverType->isObjCClassType())
4474 if (ObjCInterfaceDecl *IFace = GetAssumedMessageSendExprType(RecExpr))
4475 ReceiverType = Context.getObjCObjectPointerType(
4476 Context.getObjCInterfaceType(IFace));
Douglas Gregor36ecb042009-11-17 23:22:23 +00004477
Douglas Gregord36adf52010-09-16 16:06:31 +00004478 // Keep track of the selectors we've already added.
4479 VisitedSelectorSet Selectors;
4480
Douglas Gregorf74a4192009-11-18 00:06:18 +00004481 // Handle messages to Class. This really isn't a message to an instance
4482 // method, so we treat it the same way we would treat a message send to a
4483 // class method.
4484 if (ReceiverType->isObjCClassType() ||
4485 ReceiverType->isObjCQualifiedClassType()) {
4486 if (ObjCMethodDecl *CurMethod = getCurMethodDecl()) {
4487 if (ObjCInterfaceDecl *ClassDecl = CurMethod->getClassInterface())
Douglas Gregor4ad96852009-11-19 07:41:15 +00004488 AddObjCMethods(ClassDecl, false, MK_Any, SelIdents, NumSelIdents,
Douglas Gregord36adf52010-09-16 16:06:31 +00004489 CurContext, Selectors, Results);
Douglas Gregorf74a4192009-11-18 00:06:18 +00004490 }
4491 }
4492 // Handle messages to a qualified ID ("id<foo>").
4493 else if (const ObjCObjectPointerType *QualID
4494 = ReceiverType->getAsObjCQualifiedIdType()) {
4495 // Search protocols for instance methods.
4496 for (ObjCObjectPointerType::qual_iterator I = QualID->qual_begin(),
4497 E = QualID->qual_end();
4498 I != E; ++I)
Douglas Gregor4ad96852009-11-19 07:41:15 +00004499 AddObjCMethods(*I, true, MK_Any, SelIdents, NumSelIdents, CurContext,
Douglas Gregord36adf52010-09-16 16:06:31 +00004500 Selectors, Results);
Douglas Gregorf74a4192009-11-18 00:06:18 +00004501 }
4502 // Handle messages to a pointer to interface type.
4503 else if (const ObjCObjectPointerType *IFacePtr
4504 = ReceiverType->getAsObjCInterfacePointerType()) {
4505 // Search the class, its superclasses, etc., for instance methods.
Douglas Gregor4ad96852009-11-19 07:41:15 +00004506 AddObjCMethods(IFacePtr->getInterfaceDecl(), true, MK_Any, SelIdents,
Douglas Gregord36adf52010-09-16 16:06:31 +00004507 NumSelIdents, CurContext, Selectors, Results);
Douglas Gregorf74a4192009-11-18 00:06:18 +00004508
4509 // Search protocols for instance methods.
4510 for (ObjCObjectPointerType::qual_iterator I = IFacePtr->qual_begin(),
4511 E = IFacePtr->qual_end();
4512 I != E; ++I)
Douglas Gregor4ad96852009-11-19 07:41:15 +00004513 AddObjCMethods(*I, true, MK_Any, SelIdents, NumSelIdents, CurContext,
Douglas Gregord36adf52010-09-16 16:06:31 +00004514 Selectors, Results);
Douglas Gregorf74a4192009-11-18 00:06:18 +00004515 }
Douglas Gregor13438f92010-04-06 16:40:00 +00004516 // Handle messages to "id".
4517 else if (ReceiverType->isObjCIdType()) {
Douglas Gregor719770d2010-04-06 17:30:22 +00004518 // We're messaging "id", so provide all instance methods we know
4519 // about as code-completion results.
4520
4521 // If we have an external source, load the entire class method
Sebastian Redl3c7f4132010-08-18 23:57:06 +00004522 // pool from the AST file.
Douglas Gregor719770d2010-04-06 17:30:22 +00004523 if (ExternalSource) {
John McCall76bd1f32010-06-01 09:23:16 +00004524 for (uint32_t I = 0, N = ExternalSource->GetNumExternalSelectors();
4525 I != N; ++I) {
4526 Selector Sel = ExternalSource->GetExternalSelector(I);
Sebastian Redldb9d2142010-08-02 23:18:59 +00004527 if (Sel.isNull() || MethodPool.count(Sel))
Douglas Gregor719770d2010-04-06 17:30:22 +00004528 continue;
4529
Sebastian Redldb9d2142010-08-02 23:18:59 +00004530 ReadMethodPool(Sel);
Douglas Gregor719770d2010-04-06 17:30:22 +00004531 }
4532 }
4533
Sebastian Redldb9d2142010-08-02 23:18:59 +00004534 for (GlobalMethodPool::iterator M = MethodPool.begin(),
4535 MEnd = MethodPool.end();
4536 M != MEnd; ++M) {
4537 for (ObjCMethodList *MethList = &M->second.first;
4538 MethList && MethList->Method;
Douglas Gregor13438f92010-04-06 16:40:00 +00004539 MethList = MethList->Next) {
4540 if (!isAcceptableObjCMethod(MethList->Method, MK_Any, SelIdents,
4541 NumSelIdents))
4542 continue;
Douglas Gregord36adf52010-09-16 16:06:31 +00004543
4544 if (!Selectors.insert(MethList->Method->getSelector()))
4545 continue;
4546
Douglas Gregor13438f92010-04-06 16:40:00 +00004547 Result R(MethList->Method, 0);
4548 R.StartParameter = NumSelIdents;
4549 R.AllParametersAreInformative = false;
4550 Results.MaybeAddResult(R, CurContext);
4551 }
4552 }
4553 }
4554
Steve Naroffc4df6d22009-11-07 02:08:14 +00004555 Results.ExitScope();
Douglas Gregore6b1bb62010-08-11 21:23:17 +00004556 HandleCodeCompleteResults(this, CodeCompleter,
4557 CodeCompletionContext::CCC_Other,
4558 Results.data(),Results.size());
Steve Naroffc4df6d22009-11-07 02:08:14 +00004559}
Douglas Gregor55385fe2009-11-18 04:19:12 +00004560
Douglas Gregorfb629412010-08-23 21:17:50 +00004561void Sema::CodeCompleteObjCForCollection(Scope *S,
4562 DeclGroupPtrTy IterationVar) {
4563 CodeCompleteExpressionData Data;
4564 Data.ObjCCollection = true;
4565
4566 if (IterationVar.getAsOpaquePtr()) {
4567 DeclGroupRef DG = IterationVar.getAsVal<DeclGroupRef>();
4568 for (DeclGroupRef::iterator I = DG.begin(), End = DG.end(); I != End; ++I) {
4569 if (*I)
4570 Data.IgnoreDecls.push_back(*I);
4571 }
4572 }
4573
4574 CodeCompleteExpression(S, Data);
4575}
4576
Douglas Gregor458433d2010-08-26 15:07:07 +00004577void Sema::CodeCompleteObjCSelector(Scope *S, IdentifierInfo **SelIdents,
4578 unsigned NumSelIdents) {
4579 // If we have an external source, load the entire class method
4580 // pool from the AST file.
4581 if (ExternalSource) {
4582 for (uint32_t I = 0, N = ExternalSource->GetNumExternalSelectors();
4583 I != N; ++I) {
4584 Selector Sel = ExternalSource->GetExternalSelector(I);
4585 if (Sel.isNull() || MethodPool.count(Sel))
4586 continue;
4587
4588 ReadMethodPool(Sel);
4589 }
4590 }
4591
4592 ResultBuilder Results(*this);
4593 Results.EnterNewScope();
4594 for (GlobalMethodPool::iterator M = MethodPool.begin(),
4595 MEnd = MethodPool.end();
4596 M != MEnd; ++M) {
4597
4598 Selector Sel = M->first;
4599 if (!isAcceptableObjCSelector(Sel, MK_Any, SelIdents, NumSelIdents))
4600 continue;
4601
4602 CodeCompletionString *Pattern = new CodeCompletionString;
4603 if (Sel.isUnarySelector()) {
4604 Pattern->AddTypedTextChunk(Sel.getIdentifierInfoForSlot(0)->getName());
4605 Results.AddResult(Pattern);
4606 continue;
4607 }
4608
Douglas Gregor2d9e21f2010-08-26 16:46:39 +00004609 std::string Accumulator;
Douglas Gregor458433d2010-08-26 15:07:07 +00004610 for (unsigned I = 0, N = Sel.getNumArgs(); I != N; ++I) {
Douglas Gregor2d9e21f2010-08-26 16:46:39 +00004611 if (I == NumSelIdents) {
4612 if (!Accumulator.empty()) {
4613 Pattern->AddInformativeChunk(Accumulator);
4614 Accumulator.clear();
4615 }
4616 }
4617
4618 Accumulator += Sel.getIdentifierInfoForSlot(I)->getName().str();
4619 Accumulator += ':';
Douglas Gregor458433d2010-08-26 15:07:07 +00004620 }
Douglas Gregor2d9e21f2010-08-26 16:46:39 +00004621 Pattern->AddTypedTextChunk(Accumulator);
Douglas Gregor458433d2010-08-26 15:07:07 +00004622 Results.AddResult(Pattern);
4623 }
4624 Results.ExitScope();
4625
4626 HandleCodeCompleteResults(this, CodeCompleter,
4627 CodeCompletionContext::CCC_SelectorName,
4628 Results.data(), Results.size());
4629}
4630
Douglas Gregor55385fe2009-11-18 04:19:12 +00004631/// \brief Add all of the protocol declarations that we find in the given
4632/// (translation unit) context.
4633static void AddProtocolResults(DeclContext *Ctx, DeclContext *CurContext,
Douglas Gregor083128f2009-11-18 04:49:41 +00004634 bool OnlyForwardDeclarations,
Douglas Gregor55385fe2009-11-18 04:19:12 +00004635 ResultBuilder &Results) {
John McCall0a2c5e22010-08-25 06:19:51 +00004636 typedef CodeCompletionResult Result;
Douglas Gregor55385fe2009-11-18 04:19:12 +00004637
4638 for (DeclContext::decl_iterator D = Ctx->decls_begin(),
4639 DEnd = Ctx->decls_end();
4640 D != DEnd; ++D) {
4641 // Record any protocols we find.
4642 if (ObjCProtocolDecl *Proto = dyn_cast<ObjCProtocolDecl>(*D))
Douglas Gregor083128f2009-11-18 04:49:41 +00004643 if (!OnlyForwardDeclarations || Proto->isForwardDecl())
Douglas Gregor608300b2010-01-14 16:14:35 +00004644 Results.AddResult(Result(Proto, 0), CurContext, 0, false);
Douglas Gregor55385fe2009-11-18 04:19:12 +00004645
4646 // Record any forward-declared protocols we find.
4647 if (ObjCForwardProtocolDecl *Forward
4648 = dyn_cast<ObjCForwardProtocolDecl>(*D)) {
4649 for (ObjCForwardProtocolDecl::protocol_iterator
4650 P = Forward->protocol_begin(),
4651 PEnd = Forward->protocol_end();
4652 P != PEnd; ++P)
Douglas Gregor083128f2009-11-18 04:49:41 +00004653 if (!OnlyForwardDeclarations || (*P)->isForwardDecl())
Douglas Gregor608300b2010-01-14 16:14:35 +00004654 Results.AddResult(Result(*P, 0), CurContext, 0, false);
Douglas Gregor55385fe2009-11-18 04:19:12 +00004655 }
4656 }
4657}
4658
4659void Sema::CodeCompleteObjCProtocolReferences(IdentifierLocPair *Protocols,
4660 unsigned NumProtocols) {
4661 ResultBuilder Results(*this);
4662 Results.EnterNewScope();
4663
4664 // Tell the result set to ignore all of the protocols we have
4665 // already seen.
4666 for (unsigned I = 0; I != NumProtocols; ++I)
Douglas Gregorc83c6872010-04-15 22:33:43 +00004667 if (ObjCProtocolDecl *Protocol = LookupProtocol(Protocols[I].first,
4668 Protocols[I].second))
Douglas Gregor55385fe2009-11-18 04:19:12 +00004669 Results.Ignore(Protocol);
4670
4671 // Add all protocols.
Douglas Gregor083128f2009-11-18 04:49:41 +00004672 AddProtocolResults(Context.getTranslationUnitDecl(), CurContext, false,
4673 Results);
4674
4675 Results.ExitScope();
Douglas Gregore6b1bb62010-08-11 21:23:17 +00004676 HandleCodeCompleteResults(this, CodeCompleter,
4677 CodeCompletionContext::CCC_ObjCProtocolName,
4678 Results.data(),Results.size());
Douglas Gregor083128f2009-11-18 04:49:41 +00004679}
4680
4681void Sema::CodeCompleteObjCProtocolDecl(Scope *) {
4682 ResultBuilder Results(*this);
4683 Results.EnterNewScope();
4684
4685 // Add all protocols.
4686 AddProtocolResults(Context.getTranslationUnitDecl(), CurContext, true,
4687 Results);
Douglas Gregor55385fe2009-11-18 04:19:12 +00004688
4689 Results.ExitScope();
Douglas Gregore6b1bb62010-08-11 21:23:17 +00004690 HandleCodeCompleteResults(this, CodeCompleter,
4691 CodeCompletionContext::CCC_ObjCProtocolName,
4692 Results.data(),Results.size());
Douglas Gregor55385fe2009-11-18 04:19:12 +00004693}
Douglas Gregor3b49aca2009-11-18 16:26:39 +00004694
4695/// \brief Add all of the Objective-C interface declarations that we find in
4696/// the given (translation unit) context.
4697static void AddInterfaceResults(DeclContext *Ctx, DeclContext *CurContext,
4698 bool OnlyForwardDeclarations,
4699 bool OnlyUnimplemented,
4700 ResultBuilder &Results) {
John McCall0a2c5e22010-08-25 06:19:51 +00004701 typedef CodeCompletionResult Result;
Douglas Gregor3b49aca2009-11-18 16:26:39 +00004702
4703 for (DeclContext::decl_iterator D = Ctx->decls_begin(),
4704 DEnd = Ctx->decls_end();
4705 D != DEnd; ++D) {
Douglas Gregordeacbdc2010-08-11 12:19:30 +00004706 // Record any interfaces we find.
4707 if (ObjCInterfaceDecl *Class = dyn_cast<ObjCInterfaceDecl>(*D))
4708 if ((!OnlyForwardDeclarations || Class->isForwardDecl()) &&
4709 (!OnlyUnimplemented || !Class->getImplementation()))
4710 Results.AddResult(Result(Class, 0), CurContext, 0, false);
Douglas Gregor3b49aca2009-11-18 16:26:39 +00004711
4712 // Record any forward-declared interfaces we find.
4713 if (ObjCClassDecl *Forward = dyn_cast<ObjCClassDecl>(*D)) {
4714 for (ObjCClassDecl::iterator C = Forward->begin(), CEnd = Forward->end();
Douglas Gregordeacbdc2010-08-11 12:19:30 +00004715 C != CEnd; ++C)
4716 if ((!OnlyForwardDeclarations || C->getInterface()->isForwardDecl()) &&
4717 (!OnlyUnimplemented || !C->getInterface()->getImplementation()))
4718 Results.AddResult(Result(C->getInterface(), 0), CurContext,
Douglas Gregor608300b2010-01-14 16:14:35 +00004719 0, false);
Douglas Gregor3b49aca2009-11-18 16:26:39 +00004720 }
4721 }
4722}
4723
4724void Sema::CodeCompleteObjCInterfaceDecl(Scope *S) {
4725 ResultBuilder Results(*this);
4726 Results.EnterNewScope();
4727
4728 // Add all classes.
4729 AddInterfaceResults(Context.getTranslationUnitDecl(), CurContext, true,
4730 false, Results);
4731
4732 Results.ExitScope();
Douglas Gregore6b1bb62010-08-11 21:23:17 +00004733 HandleCodeCompleteResults(this, CodeCompleter,
4734 CodeCompletionContext::CCC_Other,
4735 Results.data(),Results.size());
Douglas Gregor3b49aca2009-11-18 16:26:39 +00004736}
4737
Douglas Gregorc83c6872010-04-15 22:33:43 +00004738void Sema::CodeCompleteObjCSuperclass(Scope *S, IdentifierInfo *ClassName,
4739 SourceLocation ClassNameLoc) {
Douglas Gregor3b49aca2009-11-18 16:26:39 +00004740 ResultBuilder Results(*this);
4741 Results.EnterNewScope();
4742
4743 // Make sure that we ignore the class we're currently defining.
4744 NamedDecl *CurClass
Douglas Gregorc83c6872010-04-15 22:33:43 +00004745 = LookupSingleName(TUScope, ClassName, ClassNameLoc, LookupOrdinaryName);
Douglas Gregor33ced0b2009-11-18 19:08:43 +00004746 if (CurClass && isa<ObjCInterfaceDecl>(CurClass))
Douglas Gregor3b49aca2009-11-18 16:26:39 +00004747 Results.Ignore(CurClass);
4748
4749 // Add all classes.
4750 AddInterfaceResults(Context.getTranslationUnitDecl(), CurContext, false,
4751 false, Results);
4752
4753 Results.ExitScope();
Douglas Gregore6b1bb62010-08-11 21:23:17 +00004754 HandleCodeCompleteResults(this, CodeCompleter,
4755 CodeCompletionContext::CCC_Other,
4756 Results.data(),Results.size());
Douglas Gregor3b49aca2009-11-18 16:26:39 +00004757}
4758
4759void Sema::CodeCompleteObjCImplementationDecl(Scope *S) {
4760 ResultBuilder Results(*this);
4761 Results.EnterNewScope();
4762
4763 // Add all unimplemented classes.
4764 AddInterfaceResults(Context.getTranslationUnitDecl(), CurContext, false,
4765 true, Results);
4766
4767 Results.ExitScope();
Douglas Gregore6b1bb62010-08-11 21:23:17 +00004768 HandleCodeCompleteResults(this, CodeCompleter,
4769 CodeCompletionContext::CCC_Other,
4770 Results.data(),Results.size());
Douglas Gregor3b49aca2009-11-18 16:26:39 +00004771}
Douglas Gregor33ced0b2009-11-18 19:08:43 +00004772
4773void Sema::CodeCompleteObjCInterfaceCategory(Scope *S,
Douglas Gregorc83c6872010-04-15 22:33:43 +00004774 IdentifierInfo *ClassName,
4775 SourceLocation ClassNameLoc) {
John McCall0a2c5e22010-08-25 06:19:51 +00004776 typedef CodeCompletionResult Result;
Douglas Gregor33ced0b2009-11-18 19:08:43 +00004777
4778 ResultBuilder Results(*this);
4779
4780 // Ignore any categories we find that have already been implemented by this
4781 // interface.
4782 llvm::SmallPtrSet<IdentifierInfo *, 16> CategoryNames;
4783 NamedDecl *CurClass
Douglas Gregorc83c6872010-04-15 22:33:43 +00004784 = LookupSingleName(TUScope, ClassName, ClassNameLoc, LookupOrdinaryName);
Douglas Gregor33ced0b2009-11-18 19:08:43 +00004785 if (ObjCInterfaceDecl *Class = dyn_cast_or_null<ObjCInterfaceDecl>(CurClass))
4786 for (ObjCCategoryDecl *Category = Class->getCategoryList(); Category;
4787 Category = Category->getNextClassCategory())
4788 CategoryNames.insert(Category->getIdentifier());
4789
4790 // Add all of the categories we know about.
4791 Results.EnterNewScope();
4792 TranslationUnitDecl *TU = Context.getTranslationUnitDecl();
4793 for (DeclContext::decl_iterator D = TU->decls_begin(),
4794 DEnd = TU->decls_end();
4795 D != DEnd; ++D)
4796 if (ObjCCategoryDecl *Category = dyn_cast<ObjCCategoryDecl>(*D))
4797 if (CategoryNames.insert(Category->getIdentifier()))
Douglas Gregor608300b2010-01-14 16:14:35 +00004798 Results.AddResult(Result(Category, 0), CurContext, 0, false);
Douglas Gregor33ced0b2009-11-18 19:08:43 +00004799 Results.ExitScope();
4800
Douglas Gregore6b1bb62010-08-11 21:23:17 +00004801 HandleCodeCompleteResults(this, CodeCompleter,
4802 CodeCompletionContext::CCC_Other,
4803 Results.data(),Results.size());
Douglas Gregor33ced0b2009-11-18 19:08:43 +00004804}
4805
4806void Sema::CodeCompleteObjCImplementationCategory(Scope *S,
Douglas Gregorc83c6872010-04-15 22:33:43 +00004807 IdentifierInfo *ClassName,
4808 SourceLocation ClassNameLoc) {
John McCall0a2c5e22010-08-25 06:19:51 +00004809 typedef CodeCompletionResult Result;
Douglas Gregor33ced0b2009-11-18 19:08:43 +00004810
4811 // Find the corresponding interface. If we couldn't find the interface, the
4812 // program itself is ill-formed. However, we'll try to be helpful still by
4813 // providing the list of all of the categories we know about.
4814 NamedDecl *CurClass
Douglas Gregorc83c6872010-04-15 22:33:43 +00004815 = LookupSingleName(TUScope, ClassName, ClassNameLoc, LookupOrdinaryName);
Douglas Gregor33ced0b2009-11-18 19:08:43 +00004816 ObjCInterfaceDecl *Class = dyn_cast_or_null<ObjCInterfaceDecl>(CurClass);
4817 if (!Class)
Douglas Gregorc83c6872010-04-15 22:33:43 +00004818 return CodeCompleteObjCInterfaceCategory(S, ClassName, ClassNameLoc);
Douglas Gregor33ced0b2009-11-18 19:08:43 +00004819
4820 ResultBuilder Results(*this);
4821
4822 // Add all of the categories that have have corresponding interface
4823 // declarations in this class and any of its superclasses, except for
4824 // already-implemented categories in the class itself.
4825 llvm::SmallPtrSet<IdentifierInfo *, 16> CategoryNames;
4826 Results.EnterNewScope();
4827 bool IgnoreImplemented = true;
4828 while (Class) {
4829 for (ObjCCategoryDecl *Category = Class->getCategoryList(); Category;
4830 Category = Category->getNextClassCategory())
4831 if ((!IgnoreImplemented || !Category->getImplementation()) &&
4832 CategoryNames.insert(Category->getIdentifier()))
Douglas Gregor608300b2010-01-14 16:14:35 +00004833 Results.AddResult(Result(Category, 0), CurContext, 0, false);
Douglas Gregor33ced0b2009-11-18 19:08:43 +00004834
4835 Class = Class->getSuperClass();
4836 IgnoreImplemented = false;
4837 }
4838 Results.ExitScope();
4839
Douglas Gregore6b1bb62010-08-11 21:23:17 +00004840 HandleCodeCompleteResults(this, CodeCompleter,
4841 CodeCompletionContext::CCC_Other,
4842 Results.data(),Results.size());
Douglas Gregor33ced0b2009-11-18 19:08:43 +00004843}
Douglas Gregor322328b2009-11-18 22:32:06 +00004844
John McCalld226f652010-08-21 09:40:31 +00004845void Sema::CodeCompleteObjCPropertyDefinition(Scope *S, Decl *ObjCImpDecl) {
John McCall0a2c5e22010-08-25 06:19:51 +00004846 typedef CodeCompletionResult Result;
Douglas Gregor322328b2009-11-18 22:32:06 +00004847 ResultBuilder Results(*this);
4848
4849 // Figure out where this @synthesize lives.
4850 ObjCContainerDecl *Container
John McCalld226f652010-08-21 09:40:31 +00004851 = dyn_cast_or_null<ObjCContainerDecl>(ObjCImpDecl);
Douglas Gregor322328b2009-11-18 22:32:06 +00004852 if (!Container ||
4853 (!isa<ObjCImplementationDecl>(Container) &&
4854 !isa<ObjCCategoryImplDecl>(Container)))
4855 return;
4856
4857 // Ignore any properties that have already been implemented.
4858 for (DeclContext::decl_iterator D = Container->decls_begin(),
4859 DEnd = Container->decls_end();
4860 D != DEnd; ++D)
4861 if (ObjCPropertyImplDecl *PropertyImpl = dyn_cast<ObjCPropertyImplDecl>(*D))
4862 Results.Ignore(PropertyImpl->getPropertyDecl());
4863
4864 // Add any properties that we find.
4865 Results.EnterNewScope();
4866 if (ObjCImplementationDecl *ClassImpl
4867 = dyn_cast<ObjCImplementationDecl>(Container))
4868 AddObjCProperties(ClassImpl->getClassInterface(), false, CurContext,
4869 Results);
4870 else
4871 AddObjCProperties(cast<ObjCCategoryImplDecl>(Container)->getCategoryDecl(),
4872 false, CurContext, Results);
4873 Results.ExitScope();
4874
Douglas Gregore6b1bb62010-08-11 21:23:17 +00004875 HandleCodeCompleteResults(this, CodeCompleter,
4876 CodeCompletionContext::CCC_Other,
4877 Results.data(),Results.size());
Douglas Gregor322328b2009-11-18 22:32:06 +00004878}
4879
4880void Sema::CodeCompleteObjCPropertySynthesizeIvar(Scope *S,
4881 IdentifierInfo *PropertyName,
John McCalld226f652010-08-21 09:40:31 +00004882 Decl *ObjCImpDecl) {
John McCall0a2c5e22010-08-25 06:19:51 +00004883 typedef CodeCompletionResult Result;
Douglas Gregor322328b2009-11-18 22:32:06 +00004884 ResultBuilder Results(*this);
4885
4886 // Figure out where this @synthesize lives.
4887 ObjCContainerDecl *Container
John McCalld226f652010-08-21 09:40:31 +00004888 = dyn_cast_or_null<ObjCContainerDecl>(ObjCImpDecl);
Douglas Gregor322328b2009-11-18 22:32:06 +00004889 if (!Container ||
4890 (!isa<ObjCImplementationDecl>(Container) &&
4891 !isa<ObjCCategoryImplDecl>(Container)))
4892 return;
4893
4894 // Figure out which interface we're looking into.
4895 ObjCInterfaceDecl *Class = 0;
4896 if (ObjCImplementationDecl *ClassImpl
4897 = dyn_cast<ObjCImplementationDecl>(Container))
4898 Class = ClassImpl->getClassInterface();
4899 else
4900 Class = cast<ObjCCategoryImplDecl>(Container)->getCategoryDecl()
4901 ->getClassInterface();
4902
4903 // Add all of the instance variables in this class and its superclasses.
4904 Results.EnterNewScope();
4905 for(; Class; Class = Class->getSuperClass()) {
4906 // FIXME: We could screen the type of each ivar for compatibility with
4907 // the property, but is that being too paternal?
4908 for (ObjCInterfaceDecl::ivar_iterator IVar = Class->ivar_begin(),
4909 IVarEnd = Class->ivar_end();
4910 IVar != IVarEnd; ++IVar)
Douglas Gregor608300b2010-01-14 16:14:35 +00004911 Results.AddResult(Result(*IVar, 0), CurContext, 0, false);
Douglas Gregor322328b2009-11-18 22:32:06 +00004912 }
4913 Results.ExitScope();
4914
Douglas Gregore6b1bb62010-08-11 21:23:17 +00004915 HandleCodeCompleteResults(this, CodeCompleter,
4916 CodeCompletionContext::CCC_Other,
4917 Results.data(),Results.size());
Douglas Gregor322328b2009-11-18 22:32:06 +00004918}
Douglas Gregore8f5a172010-04-07 00:21:17 +00004919
Douglas Gregor408be5a2010-08-25 01:08:01 +00004920// Mapping from selectors to the methods that implement that selector, along
4921// with the "in original class" flag.
4922typedef llvm::DenseMap<Selector, std::pair<ObjCMethodDecl *, bool> >
4923 KnownMethodsMap;
Douglas Gregore8f5a172010-04-07 00:21:17 +00004924
4925/// \brief Find all of the methods that reside in the given container
4926/// (and its superclasses, protocols, etc.) that meet the given
4927/// criteria. Insert those methods into the map of known methods,
4928/// indexed by selector so they can be easily found.
4929static void FindImplementableMethods(ASTContext &Context,
4930 ObjCContainerDecl *Container,
4931 bool WantInstanceMethods,
4932 QualType ReturnType,
4933 bool IsInImplementation,
Douglas Gregor408be5a2010-08-25 01:08:01 +00004934 KnownMethodsMap &KnownMethods,
4935 bool InOriginalClass = true) {
Douglas Gregore8f5a172010-04-07 00:21:17 +00004936 if (ObjCInterfaceDecl *IFace = dyn_cast<ObjCInterfaceDecl>(Container)) {
4937 // Recurse into protocols.
4938 const ObjCList<ObjCProtocolDecl> &Protocols
4939 = IFace->getReferencedProtocols();
4940 for (ObjCList<ObjCProtocolDecl>::iterator I = Protocols.begin(),
4941 E = Protocols.end();
4942 I != E; ++I)
4943 FindImplementableMethods(Context, *I, WantInstanceMethods, ReturnType,
Douglas Gregor408be5a2010-08-25 01:08:01 +00004944 IsInImplementation, KnownMethods,
4945 InOriginalClass);
Douglas Gregore8f5a172010-04-07 00:21:17 +00004946
4947 // If we're not in the implementation of a class, also visit the
4948 // superclass.
4949 if (!IsInImplementation && IFace->getSuperClass())
4950 FindImplementableMethods(Context, IFace->getSuperClass(),
4951 WantInstanceMethods, ReturnType,
Douglas Gregor408be5a2010-08-25 01:08:01 +00004952 IsInImplementation, KnownMethods,
4953 false);
Douglas Gregore8f5a172010-04-07 00:21:17 +00004954
4955 // Add methods from any class extensions (but not from categories;
4956 // those should go into category implementations).
Fariborz Jahanian80aa1cd2010-06-22 23:20:40 +00004957 for (const ObjCCategoryDecl *Cat = IFace->getFirstClassExtension(); Cat;
4958 Cat = Cat->getNextClassExtension())
4959 FindImplementableMethods(Context, const_cast<ObjCCategoryDecl*>(Cat),
4960 WantInstanceMethods, ReturnType,
Douglas Gregor408be5a2010-08-25 01:08:01 +00004961 IsInImplementation, KnownMethods,
4962 InOriginalClass);
Douglas Gregore8f5a172010-04-07 00:21:17 +00004963 }
4964
4965 if (ObjCCategoryDecl *Category = dyn_cast<ObjCCategoryDecl>(Container)) {
4966 // Recurse into protocols.
4967 const ObjCList<ObjCProtocolDecl> &Protocols
4968 = Category->getReferencedProtocols();
4969 for (ObjCList<ObjCProtocolDecl>::iterator I = Protocols.begin(),
4970 E = Protocols.end();
4971 I != E; ++I)
4972 FindImplementableMethods(Context, *I, WantInstanceMethods, ReturnType,
Douglas Gregor408be5a2010-08-25 01:08:01 +00004973 IsInImplementation, KnownMethods,
4974 InOriginalClass);
Douglas Gregore8f5a172010-04-07 00:21:17 +00004975 }
4976
4977 if (ObjCProtocolDecl *Protocol = dyn_cast<ObjCProtocolDecl>(Container)) {
4978 // Recurse into protocols.
4979 const ObjCList<ObjCProtocolDecl> &Protocols
4980 = Protocol->getReferencedProtocols();
4981 for (ObjCList<ObjCProtocolDecl>::iterator I = Protocols.begin(),
4982 E = Protocols.end();
4983 I != E; ++I)
4984 FindImplementableMethods(Context, *I, WantInstanceMethods, ReturnType,
Douglas Gregor408be5a2010-08-25 01:08:01 +00004985 IsInImplementation, KnownMethods, false);
Douglas Gregore8f5a172010-04-07 00:21:17 +00004986 }
4987
4988 // Add methods in this container. This operation occurs last because
4989 // we want the methods from this container to override any methods
4990 // we've previously seen with the same selector.
4991 for (ObjCContainerDecl::method_iterator M = Container->meth_begin(),
4992 MEnd = Container->meth_end();
4993 M != MEnd; ++M) {
4994 if ((*M)->isInstanceMethod() == WantInstanceMethods) {
4995 if (!ReturnType.isNull() &&
4996 !Context.hasSameUnqualifiedType(ReturnType, (*M)->getResultType()))
4997 continue;
4998
Douglas Gregor408be5a2010-08-25 01:08:01 +00004999 KnownMethods[(*M)->getSelector()] = std::make_pair(*M, InOriginalClass);
Douglas Gregore8f5a172010-04-07 00:21:17 +00005000 }
5001 }
5002}
5003
5004void Sema::CodeCompleteObjCMethodDecl(Scope *S,
5005 bool IsInstanceMethod,
John McCallb3d87482010-08-24 05:47:05 +00005006 ParsedType ReturnTy,
John McCalld226f652010-08-21 09:40:31 +00005007 Decl *IDecl) {
Douglas Gregore8f5a172010-04-07 00:21:17 +00005008 // Determine the return type of the method we're declaring, if
5009 // provided.
5010 QualType ReturnType = GetTypeFromParser(ReturnTy);
5011
5012 // Determine where we should start searching for methods, and where we
5013 ObjCContainerDecl *SearchDecl = 0, *CurrentDecl = 0;
5014 bool IsInImplementation = false;
John McCalld226f652010-08-21 09:40:31 +00005015 if (Decl *D = IDecl) {
Douglas Gregore8f5a172010-04-07 00:21:17 +00005016 if (ObjCImplementationDecl *Impl = dyn_cast<ObjCImplementationDecl>(D)) {
5017 SearchDecl = Impl->getClassInterface();
5018 CurrentDecl = Impl;
5019 IsInImplementation = true;
5020 } else if (ObjCCategoryImplDecl *CatImpl
5021 = dyn_cast<ObjCCategoryImplDecl>(D)) {
5022 SearchDecl = CatImpl->getCategoryDecl();
5023 CurrentDecl = CatImpl;
5024 IsInImplementation = true;
5025 } else {
5026 SearchDecl = dyn_cast<ObjCContainerDecl>(D);
5027 CurrentDecl = SearchDecl;
5028 }
5029 }
5030
5031 if (!SearchDecl && S) {
5032 if (DeclContext *DC = static_cast<DeclContext *>(S->getEntity())) {
5033 SearchDecl = dyn_cast<ObjCContainerDecl>(DC);
5034 CurrentDecl = SearchDecl;
5035 }
5036 }
5037
5038 if (!SearchDecl || !CurrentDecl) {
Douglas Gregore6b1bb62010-08-11 21:23:17 +00005039 HandleCodeCompleteResults(this, CodeCompleter,
5040 CodeCompletionContext::CCC_Other,
5041 0, 0);
Douglas Gregore8f5a172010-04-07 00:21:17 +00005042 return;
5043 }
5044
5045 // Find all of the methods that we could declare/implement here.
5046 KnownMethodsMap KnownMethods;
5047 FindImplementableMethods(Context, SearchDecl, IsInstanceMethod,
5048 ReturnType, IsInImplementation, KnownMethods);
5049
5050 // Erase any methods that have already been declared or
5051 // implemented here.
5052 for (ObjCContainerDecl::method_iterator M = CurrentDecl->meth_begin(),
5053 MEnd = CurrentDecl->meth_end();
5054 M != MEnd; ++M) {
5055 if ((*M)->isInstanceMethod() != IsInstanceMethod)
5056 continue;
5057
5058 KnownMethodsMap::iterator Pos = KnownMethods.find((*M)->getSelector());
5059 if (Pos != KnownMethods.end())
5060 KnownMethods.erase(Pos);
5061 }
5062
5063 // Add declarations or definitions for each of the known methods.
John McCall0a2c5e22010-08-25 06:19:51 +00005064 typedef CodeCompletionResult Result;
Douglas Gregore8f5a172010-04-07 00:21:17 +00005065 ResultBuilder Results(*this);
5066 Results.EnterNewScope();
5067 PrintingPolicy Policy(Context.PrintingPolicy);
5068 Policy.AnonymousTagLocations = false;
5069 for (KnownMethodsMap::iterator M = KnownMethods.begin(),
5070 MEnd = KnownMethods.end();
5071 M != MEnd; ++M) {
Douglas Gregor408be5a2010-08-25 01:08:01 +00005072 ObjCMethodDecl *Method = M->second.first;
Douglas Gregore8f5a172010-04-07 00:21:17 +00005073 CodeCompletionString *Pattern = new CodeCompletionString;
5074
5075 // If the result type was not already provided, add it to the
5076 // pattern as (type).
5077 if (ReturnType.isNull()) {
5078 std::string TypeStr;
5079 Method->getResultType().getAsStringInternal(TypeStr, Policy);
5080 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
5081 Pattern->AddTextChunk(TypeStr);
5082 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
5083 }
5084
5085 Selector Sel = Method->getSelector();
5086
5087 // Add the first part of the selector to the pattern.
5088 Pattern->AddTypedTextChunk(Sel.getIdentifierInfoForSlot(0)->getName());
5089
5090 // Add parameters to the pattern.
5091 unsigned I = 0;
5092 for (ObjCMethodDecl::param_iterator P = Method->param_begin(),
5093 PEnd = Method->param_end();
5094 P != PEnd; (void)++P, ++I) {
5095 // Add the part of the selector name.
5096 if (I == 0)
5097 Pattern->AddChunk(CodeCompletionString::CK_Colon);
5098 else if (I < Sel.getNumArgs()) {
5099 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
Douglas Gregor47c03a72010-08-17 15:53:35 +00005100 Pattern->AddTextChunk(Sel.getIdentifierInfoForSlot(I)->getName());
Douglas Gregore8f5a172010-04-07 00:21:17 +00005101 Pattern->AddChunk(CodeCompletionString::CK_Colon);
5102 } else
5103 break;
5104
5105 // Add the parameter type.
5106 std::string TypeStr;
5107 (*P)->getOriginalType().getAsStringInternal(TypeStr, Policy);
5108 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
5109 Pattern->AddTextChunk(TypeStr);
5110 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
5111
5112 if (IdentifierInfo *Id = (*P)->getIdentifier())
Douglas Gregore17794f2010-08-31 05:13:43 +00005113 Pattern->AddTextChunk(Id->getName());
Douglas Gregore8f5a172010-04-07 00:21:17 +00005114 }
5115
5116 if (Method->isVariadic()) {
5117 if (Method->param_size() > 0)
5118 Pattern->AddChunk(CodeCompletionString::CK_Comma);
5119 Pattern->AddTextChunk("...");
Douglas Gregore17794f2010-08-31 05:13:43 +00005120 }
Douglas Gregore8f5a172010-04-07 00:21:17 +00005121
Douglas Gregor447107d2010-05-28 00:57:46 +00005122 if (IsInImplementation && Results.includeCodePatterns()) {
Douglas Gregore8f5a172010-04-07 00:21:17 +00005123 // We will be defining the method here, so add a compound statement.
5124 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
5125 Pattern->AddChunk(CodeCompletionString::CK_LeftBrace);
5126 Pattern->AddChunk(CodeCompletionString::CK_VerticalSpace);
5127 if (!Method->getResultType()->isVoidType()) {
5128 // If the result type is not void, add a return clause.
5129 Pattern->AddTextChunk("return");
5130 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
5131 Pattern->AddPlaceholderChunk("expression");
5132 Pattern->AddChunk(CodeCompletionString::CK_SemiColon);
5133 } else
5134 Pattern->AddPlaceholderChunk("statements");
5135
5136 Pattern->AddChunk(CodeCompletionString::CK_VerticalSpace);
5137 Pattern->AddChunk(CodeCompletionString::CK_RightBrace);
5138 }
5139
Douglas Gregor408be5a2010-08-25 01:08:01 +00005140 unsigned Priority = CCP_CodePattern;
5141 if (!M->second.second)
5142 Priority += CCD_InBaseClass;
5143
5144 Results.AddResult(Result(Pattern, Priority,
Douglas Gregor16ed9ad2010-08-17 16:06:07 +00005145 Method->isInstanceMethod()
5146 ? CXCursor_ObjCInstanceMethodDecl
5147 : CXCursor_ObjCClassMethodDecl));
Douglas Gregore8f5a172010-04-07 00:21:17 +00005148 }
5149
5150 Results.ExitScope();
5151
Douglas Gregore6b1bb62010-08-11 21:23:17 +00005152 HandleCodeCompleteResults(this, CodeCompleter,
5153 CodeCompletionContext::CCC_Other,
5154 Results.data(),Results.size());
Douglas Gregore8f5a172010-04-07 00:21:17 +00005155}
Douglas Gregor1f5537a2010-07-08 23:20:03 +00005156
5157void Sema::CodeCompleteObjCMethodDeclSelector(Scope *S,
5158 bool IsInstanceMethod,
Douglas Gregor40ed9a12010-07-08 23:37:41 +00005159 bool AtParameterName,
John McCallb3d87482010-08-24 05:47:05 +00005160 ParsedType ReturnTy,
Douglas Gregor1f5537a2010-07-08 23:20:03 +00005161 IdentifierInfo **SelIdents,
5162 unsigned NumSelIdents) {
Douglas Gregor1f5537a2010-07-08 23:20:03 +00005163 // If we have an external source, load the entire class method
Sebastian Redl3c7f4132010-08-18 23:57:06 +00005164 // pool from the AST file.
Douglas Gregor1f5537a2010-07-08 23:20:03 +00005165 if (ExternalSource) {
5166 for (uint32_t I = 0, N = ExternalSource->GetNumExternalSelectors();
5167 I != N; ++I) {
5168 Selector Sel = ExternalSource->GetExternalSelector(I);
Sebastian Redldb9d2142010-08-02 23:18:59 +00005169 if (Sel.isNull() || MethodPool.count(Sel))
Douglas Gregor1f5537a2010-07-08 23:20:03 +00005170 continue;
Sebastian Redldb9d2142010-08-02 23:18:59 +00005171
5172 ReadMethodPool(Sel);
Douglas Gregor1f5537a2010-07-08 23:20:03 +00005173 }
5174 }
5175
5176 // Build the set of methods we can see.
John McCall0a2c5e22010-08-25 06:19:51 +00005177 typedef CodeCompletionResult Result;
Douglas Gregor1f5537a2010-07-08 23:20:03 +00005178 ResultBuilder Results(*this);
5179
5180 if (ReturnTy)
5181 Results.setPreferredType(GetTypeFromParser(ReturnTy).getNonReferenceType());
Sebastian Redldb9d2142010-08-02 23:18:59 +00005182
Douglas Gregor1f5537a2010-07-08 23:20:03 +00005183 Results.EnterNewScope();
Sebastian Redldb9d2142010-08-02 23:18:59 +00005184 for (GlobalMethodPool::iterator M = MethodPool.begin(),
5185 MEnd = MethodPool.end();
5186 M != MEnd; ++M) {
5187 for (ObjCMethodList *MethList = IsInstanceMethod ? &M->second.first :
5188 &M->second.second;
5189 MethList && MethList->Method;
Douglas Gregor1f5537a2010-07-08 23:20:03 +00005190 MethList = MethList->Next) {
5191 if (!isAcceptableObjCMethod(MethList->Method, MK_Any, SelIdents,
5192 NumSelIdents))
5193 continue;
5194
Douglas Gregor40ed9a12010-07-08 23:37:41 +00005195 if (AtParameterName) {
5196 // Suggest parameter names we've seen before.
5197 if (NumSelIdents && NumSelIdents <= MethList->Method->param_size()) {
5198 ParmVarDecl *Param = MethList->Method->param_begin()[NumSelIdents-1];
5199 if (Param->getIdentifier()) {
5200 CodeCompletionString *Pattern = new CodeCompletionString;
5201 Pattern->AddTypedTextChunk(Param->getIdentifier()->getName());
5202 Results.AddResult(Pattern);
5203 }
5204 }
5205
5206 continue;
5207 }
5208
Douglas Gregor1f5537a2010-07-08 23:20:03 +00005209 Result R(MethList->Method, 0);
5210 R.StartParameter = NumSelIdents;
5211 R.AllParametersAreInformative = false;
5212 R.DeclaringEntity = true;
5213 Results.MaybeAddResult(R, CurContext);
5214 }
5215 }
5216
5217 Results.ExitScope();
Douglas Gregore6b1bb62010-08-11 21:23:17 +00005218 HandleCodeCompleteResults(this, CodeCompleter,
5219 CodeCompletionContext::CCC_Other,
5220 Results.data(),Results.size());
Douglas Gregor1f5537a2010-07-08 23:20:03 +00005221}
Douglas Gregor87c08a52010-08-13 22:48:40 +00005222
Douglas Gregorf29c5232010-08-24 22:20:20 +00005223void Sema::CodeCompletePreprocessorDirective(bool InConditional) {
Douglas Gregorf44e8542010-08-24 19:08:16 +00005224 ResultBuilder Results(*this);
5225 Results.EnterNewScope();
5226
5227 // #if <condition>
5228 CodeCompletionString *Pattern = new CodeCompletionString;
5229 Pattern->AddTypedTextChunk("if");
5230 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
5231 Pattern->AddPlaceholderChunk("condition");
5232 Results.AddResult(Pattern);
5233
5234 // #ifdef <macro>
5235 Pattern = new CodeCompletionString;
5236 Pattern->AddTypedTextChunk("ifdef");
5237 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
5238 Pattern->AddPlaceholderChunk("macro");
5239 Results.AddResult(Pattern);
5240
5241 // #ifndef <macro>
5242 Pattern = new CodeCompletionString;
5243 Pattern->AddTypedTextChunk("ifndef");
5244 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
5245 Pattern->AddPlaceholderChunk("macro");
5246 Results.AddResult(Pattern);
5247
5248 if (InConditional) {
5249 // #elif <condition>
5250 Pattern = new CodeCompletionString;
5251 Pattern->AddTypedTextChunk("elif");
5252 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
5253 Pattern->AddPlaceholderChunk("condition");
5254 Results.AddResult(Pattern);
5255
5256 // #else
5257 Pattern = new CodeCompletionString;
5258 Pattern->AddTypedTextChunk("else");
5259 Results.AddResult(Pattern);
5260
5261 // #endif
5262 Pattern = new CodeCompletionString;
5263 Pattern->AddTypedTextChunk("endif");
5264 Results.AddResult(Pattern);
5265 }
5266
5267 // #include "header"
5268 Pattern = new CodeCompletionString;
5269 Pattern->AddTypedTextChunk("include");
5270 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
5271 Pattern->AddTextChunk("\"");
5272 Pattern->AddPlaceholderChunk("header");
5273 Pattern->AddTextChunk("\"");
5274 Results.AddResult(Pattern);
5275
5276 // #include <header>
5277 Pattern = new CodeCompletionString;
5278 Pattern->AddTypedTextChunk("include");
5279 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
5280 Pattern->AddTextChunk("<");
5281 Pattern->AddPlaceholderChunk("header");
5282 Pattern->AddTextChunk(">");
5283 Results.AddResult(Pattern);
5284
5285 // #define <macro>
5286 Pattern = new CodeCompletionString;
5287 Pattern->AddTypedTextChunk("define");
5288 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
5289 Pattern->AddPlaceholderChunk("macro");
5290 Results.AddResult(Pattern);
5291
5292 // #define <macro>(<args>)
5293 Pattern = new CodeCompletionString;
5294 Pattern->AddTypedTextChunk("define");
5295 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
5296 Pattern->AddPlaceholderChunk("macro");
5297 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
5298 Pattern->AddPlaceholderChunk("args");
5299 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
5300 Results.AddResult(Pattern);
5301
5302 // #undef <macro>
5303 Pattern = new CodeCompletionString;
5304 Pattern->AddTypedTextChunk("undef");
5305 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
5306 Pattern->AddPlaceholderChunk("macro");
5307 Results.AddResult(Pattern);
5308
5309 // #line <number>
5310 Pattern = new CodeCompletionString;
5311 Pattern->AddTypedTextChunk("line");
5312 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
5313 Pattern->AddPlaceholderChunk("number");
5314 Results.AddResult(Pattern);
5315
5316 // #line <number> "filename"
5317 Pattern = new CodeCompletionString;
5318 Pattern->AddTypedTextChunk("line");
5319 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
5320 Pattern->AddPlaceholderChunk("number");
5321 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
5322 Pattern->AddTextChunk("\"");
5323 Pattern->AddPlaceholderChunk("filename");
5324 Pattern->AddTextChunk("\"");
5325 Results.AddResult(Pattern);
5326
5327 // #error <message>
5328 Pattern = new CodeCompletionString;
5329 Pattern->AddTypedTextChunk("error");
5330 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
5331 Pattern->AddPlaceholderChunk("message");
5332 Results.AddResult(Pattern);
5333
5334 // #pragma <arguments>
5335 Pattern = new CodeCompletionString;
5336 Pattern->AddTypedTextChunk("pragma");
5337 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
5338 Pattern->AddPlaceholderChunk("arguments");
5339 Results.AddResult(Pattern);
5340
5341 if (getLangOptions().ObjC1) {
5342 // #import "header"
5343 Pattern = new CodeCompletionString;
5344 Pattern->AddTypedTextChunk("import");
5345 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
5346 Pattern->AddTextChunk("\"");
5347 Pattern->AddPlaceholderChunk("header");
5348 Pattern->AddTextChunk("\"");
5349 Results.AddResult(Pattern);
5350
5351 // #import <header>
5352 Pattern = new CodeCompletionString;
5353 Pattern->AddTypedTextChunk("import");
5354 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
5355 Pattern->AddTextChunk("<");
5356 Pattern->AddPlaceholderChunk("header");
5357 Pattern->AddTextChunk(">");
5358 Results.AddResult(Pattern);
5359 }
5360
5361 // #include_next "header"
5362 Pattern = new CodeCompletionString;
5363 Pattern->AddTypedTextChunk("include_next");
5364 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
5365 Pattern->AddTextChunk("\"");
5366 Pattern->AddPlaceholderChunk("header");
5367 Pattern->AddTextChunk("\"");
5368 Results.AddResult(Pattern);
5369
5370 // #include_next <header>
5371 Pattern = new CodeCompletionString;
5372 Pattern->AddTypedTextChunk("include_next");
5373 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
5374 Pattern->AddTextChunk("<");
5375 Pattern->AddPlaceholderChunk("header");
5376 Pattern->AddTextChunk(">");
5377 Results.AddResult(Pattern);
5378
5379 // #warning <message>
5380 Pattern = new CodeCompletionString;
5381 Pattern->AddTypedTextChunk("warning");
5382 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
5383 Pattern->AddPlaceholderChunk("message");
5384 Results.AddResult(Pattern);
5385
5386 // Note: #ident and #sccs are such crazy anachronisms that we don't provide
5387 // completions for them. And __include_macros is a Clang-internal extension
5388 // that we don't want to encourage anyone to use.
5389
5390 // FIXME: we don't support #assert or #unassert, so don't suggest them.
5391 Results.ExitScope();
5392
Douglas Gregorf44e8542010-08-24 19:08:16 +00005393 HandleCodeCompleteResults(this, CodeCompleter,
Douglas Gregor721f3592010-08-25 18:41:16 +00005394 CodeCompletionContext::CCC_PreprocessorDirective,
Douglas Gregorf44e8542010-08-24 19:08:16 +00005395 Results.data(), Results.size());
5396}
5397
5398void Sema::CodeCompleteInPreprocessorConditionalExclusion(Scope *S) {
Douglas Gregorf29c5232010-08-24 22:20:20 +00005399 CodeCompleteOrdinaryName(S,
John McCallf312b1e2010-08-26 23:41:50 +00005400 S->getFnParent()? Sema::PCC_RecoveryInFunction
5401 : Sema::PCC_Namespace);
Douglas Gregorf44e8542010-08-24 19:08:16 +00005402}
5403
Douglas Gregorf29c5232010-08-24 22:20:20 +00005404void Sema::CodeCompletePreprocessorMacroName(bool IsDefinition) {
Douglas Gregor1fbb4472010-08-24 20:21:13 +00005405 ResultBuilder Results(*this);
5406 if (!IsDefinition && (!CodeCompleter || CodeCompleter->includeMacros())) {
5407 // Add just the names of macros, not their arguments.
5408 Results.EnterNewScope();
5409 for (Preprocessor::macro_iterator M = PP.macro_begin(),
5410 MEnd = PP.macro_end();
5411 M != MEnd; ++M) {
5412 CodeCompletionString *Pattern = new CodeCompletionString;
5413 Pattern->AddTypedTextChunk(M->first->getName());
5414 Results.AddResult(Pattern);
5415 }
5416 Results.ExitScope();
5417 } else if (IsDefinition) {
5418 // FIXME: Can we detect when the user just wrote an include guard above?
5419 }
5420
5421 HandleCodeCompleteResults(this, CodeCompleter,
5422 IsDefinition? CodeCompletionContext::CCC_MacroName
5423 : CodeCompletionContext::CCC_MacroNameUse,
5424 Results.data(), Results.size());
5425}
5426
Douglas Gregorf29c5232010-08-24 22:20:20 +00005427void Sema::CodeCompletePreprocessorExpression() {
5428 ResultBuilder Results(*this);
5429
5430 if (!CodeCompleter || CodeCompleter->includeMacros())
5431 AddMacroResults(PP, Results);
5432
5433 // defined (<macro>)
5434 Results.EnterNewScope();
5435 CodeCompletionString *Pattern = new CodeCompletionString;
5436 Pattern->AddTypedTextChunk("defined");
5437 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
5438 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
5439 Pattern->AddPlaceholderChunk("macro");
5440 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
5441 Results.AddResult(Pattern);
5442 Results.ExitScope();
5443
5444 HandleCodeCompleteResults(this, CodeCompleter,
5445 CodeCompletionContext::CCC_PreprocessorExpression,
5446 Results.data(), Results.size());
5447}
5448
5449void Sema::CodeCompletePreprocessorMacroArgument(Scope *S,
5450 IdentifierInfo *Macro,
5451 MacroInfo *MacroInfo,
5452 unsigned Argument) {
5453 // FIXME: In the future, we could provide "overload" results, much like we
5454 // do for function calls.
5455
5456 CodeCompleteOrdinaryName(S,
John McCallf312b1e2010-08-26 23:41:50 +00005457 S->getFnParent()? Sema::PCC_RecoveryInFunction
5458 : Sema::PCC_Namespace);
Douglas Gregorf29c5232010-08-24 22:20:20 +00005459}
5460
Douglas Gregor55817af2010-08-25 17:04:25 +00005461void Sema::CodeCompleteNaturalLanguage() {
Douglas Gregor55817af2010-08-25 17:04:25 +00005462 HandleCodeCompleteResults(this, CodeCompleter,
Douglas Gregoraf1c6b52010-08-25 17:10:00 +00005463 CodeCompletionContext::CCC_NaturalLanguage,
Douglas Gregor55817af2010-08-25 17:04:25 +00005464 0, 0);
5465}
5466
Douglas Gregor87c08a52010-08-13 22:48:40 +00005467void Sema::GatherGlobalCodeCompletions(
John McCall0a2c5e22010-08-25 06:19:51 +00005468 llvm::SmallVectorImpl<CodeCompletionResult> &Results) {
Douglas Gregor87c08a52010-08-13 22:48:40 +00005469 ResultBuilder Builder(*this);
5470
Douglas Gregor8071e422010-08-15 06:18:01 +00005471 if (!CodeCompleter || CodeCompleter->includeGlobals()) {
5472 CodeCompletionDeclConsumer Consumer(Builder,
5473 Context.getTranslationUnitDecl());
5474 LookupVisibleDecls(Context.getTranslationUnitDecl(), LookupAnyName,
5475 Consumer);
5476 }
Douglas Gregor87c08a52010-08-13 22:48:40 +00005477
5478 if (!CodeCompleter || CodeCompleter->includeMacros())
5479 AddMacroResults(PP, Builder);
5480
5481 Results.clear();
5482 Results.insert(Results.end(),
5483 Builder.data(), Builder.data() + Builder.size());
5484}