blob: b02f2dd217f5581c9fe6fb2733bea46ca00e5aed [file] [log] [blame]
Douglas Gregor81b747b2009-09-17 21:32:03 +00001//===---------------- SemaCodeComplete.cpp - Code Completion ----*- C++ -*-===//
2//
3// The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9//
10// This file defines the code-completion semantic actions.
11//
12//===----------------------------------------------------------------------===//
John McCall2d887082010-08-25 22:03:47 +000013#include "clang/Sema/SemaInternal.h"
Douglas Gregore737f502010-08-12 20:07:10 +000014#include "clang/Sema/Lookup.h"
John McCall120d63c2010-08-24 20:38:10 +000015#include "clang/Sema/Overload.h"
Douglas Gregor81b747b2009-09-17 21:32:03 +000016#include "clang/Sema/CodeCompleteConsumer.h"
Douglas Gregor719770d2010-04-06 17:30:22 +000017#include "clang/Sema/ExternalSemaSource.h"
John McCall5f1e0942010-08-24 08:50:51 +000018#include "clang/Sema/Scope.h"
John McCall781472f2010-08-25 08:40:02 +000019#include "clang/Sema/ScopeInfo.h"
John McCall7cd088e2010-08-24 07:21:54 +000020#include "clang/AST/DeclObjC.h"
Douglas Gregorb9d0ef72009-09-21 19:57:38 +000021#include "clang/AST/ExprCXX.h"
Douglas Gregor24a069f2009-11-17 17:59:40 +000022#include "clang/AST/ExprObjC.h"
Douglas Gregor3f7c7f42009-10-30 16:50:04 +000023#include "clang/Lex/MacroInfo.h"
24#include "clang/Lex/Preprocessor.h"
Douglas Gregord36adf52010-09-16 16:06:31 +000025#include "llvm/ADT/DenseSet.h"
Douglas Gregor86d9a522009-09-21 16:56:56 +000026#include "llvm/ADT/SmallPtrSet.h"
Douglas Gregor6a684032009-09-28 03:51:44 +000027#include "llvm/ADT/StringExtras.h"
Douglas Gregor22f56992010-04-06 19:22:33 +000028#include "llvm/ADT/StringSwitch.h"
Douglas Gregor458433d2010-08-26 15:07:07 +000029#include "llvm/ADT/Twine.h"
Douglas Gregor86d9a522009-09-21 16:56:56 +000030#include <list>
31#include <map>
32#include <vector>
Douglas Gregor81b747b2009-09-17 21:32:03 +000033
34using namespace clang;
John McCall781472f2010-08-25 08:40:02 +000035using namespace sema;
Douglas Gregor81b747b2009-09-17 21:32:03 +000036
Douglas Gregor86d9a522009-09-21 16:56:56 +000037namespace {
38 /// \brief A container of code-completion results.
39 class ResultBuilder {
40 public:
41 /// \brief The type of a name-lookup filter, which can be provided to the
42 /// name-lookup routines to specify which declarations should be included in
43 /// the result set (when it returns true) and which declarations should be
44 /// filtered out (returns false).
45 typedef bool (ResultBuilder::*LookupFilter)(NamedDecl *) const;
46
John McCall0a2c5e22010-08-25 06:19:51 +000047 typedef CodeCompletionResult Result;
Douglas Gregor86d9a522009-09-21 16:56:56 +000048
49 private:
50 /// \brief The actual results we have found.
51 std::vector<Result> Results;
52
53 /// \brief A record of all of the declarations we have found and placed
54 /// into the result set, used to ensure that no declaration ever gets into
55 /// the result set twice.
56 llvm::SmallPtrSet<Decl*, 16> AllDeclsFound;
57
Douglas Gregorfbcb5d62009-12-06 20:23:50 +000058 typedef std::pair<NamedDecl *, unsigned> DeclIndexPair;
59
60 /// \brief An entry in the shadow map, which is optimized to store
61 /// a single (declaration, index) mapping (the common case) but
62 /// can also store a list of (declaration, index) mappings.
63 class ShadowMapEntry {
64 typedef llvm::SmallVector<DeclIndexPair, 4> DeclIndexPairVector;
65
66 /// \brief Contains either the solitary NamedDecl * or a vector
67 /// of (declaration, index) pairs.
68 llvm::PointerUnion<NamedDecl *, DeclIndexPairVector*> DeclOrVector;
69
70 /// \brief When the entry contains a single declaration, this is
71 /// the index associated with that entry.
72 unsigned SingleDeclIndex;
73
74 public:
75 ShadowMapEntry() : DeclOrVector(), SingleDeclIndex(0) { }
76
77 void Add(NamedDecl *ND, unsigned Index) {
78 if (DeclOrVector.isNull()) {
79 // 0 - > 1 elements: just set the single element information.
80 DeclOrVector = ND;
81 SingleDeclIndex = Index;
82 return;
83 }
84
85 if (NamedDecl *PrevND = DeclOrVector.dyn_cast<NamedDecl *>()) {
86 // 1 -> 2 elements: create the vector of results and push in the
87 // existing declaration.
88 DeclIndexPairVector *Vec = new DeclIndexPairVector;
89 Vec->push_back(DeclIndexPair(PrevND, SingleDeclIndex));
90 DeclOrVector = Vec;
91 }
92
93 // Add the new element to the end of the vector.
94 DeclOrVector.get<DeclIndexPairVector*>()->push_back(
95 DeclIndexPair(ND, Index));
96 }
97
98 void Destroy() {
99 if (DeclIndexPairVector *Vec
100 = DeclOrVector.dyn_cast<DeclIndexPairVector *>()) {
101 delete Vec;
102 DeclOrVector = ((NamedDecl *)0);
103 }
104 }
105
106 // Iteration.
107 class iterator;
108 iterator begin() const;
109 iterator end() const;
110 };
111
Douglas Gregor86d9a522009-09-21 16:56:56 +0000112 /// \brief A mapping from declaration names to the declarations that have
113 /// this name within a particular scope and their index within the list of
114 /// results.
Douglas Gregorfbcb5d62009-12-06 20:23:50 +0000115 typedef llvm::DenseMap<DeclarationName, ShadowMapEntry> ShadowMap;
Douglas Gregor86d9a522009-09-21 16:56:56 +0000116
117 /// \brief The semantic analysis object for which results are being
118 /// produced.
119 Sema &SemaRef;
120
121 /// \brief If non-NULL, a filter function used to remove any code-completion
122 /// results that are not desirable.
123 LookupFilter Filter;
Douglas Gregor45bcd432010-01-14 03:21:49 +0000124
125 /// \brief Whether we should allow declarations as
126 /// nested-name-specifiers that would otherwise be filtered out.
127 bool AllowNestedNameSpecifiers;
128
Douglas Gregor5ac3bdb2010-05-30 01:49:25 +0000129 /// \brief If set, the type that we would prefer our resulting value
130 /// declarations to have.
131 ///
132 /// Closely matching the preferred type gives a boost to a result's
133 /// priority.
134 CanQualType PreferredType;
135
Douglas Gregor86d9a522009-09-21 16:56:56 +0000136 /// \brief A list of shadow maps, which is used to model name hiding at
137 /// different levels of, e.g., the inheritance hierarchy.
138 std::list<ShadowMap> ShadowMaps;
139
Douglas Gregor3cdee122010-08-26 16:36:48 +0000140 /// \brief If we're potentially referring to a C++ member function, the set
141 /// of qualifiers applied to the object type.
142 Qualifiers ObjectTypeQualifiers;
143
144 /// \brief Whether the \p ObjectTypeQualifiers field is active.
145 bool HasObjectTypeQualifiers;
146
Douglas Gregor265f7492010-08-27 15:29:55 +0000147 /// \brief The selector that we prefer.
148 Selector PreferredSelector;
149
Douglas Gregor1f5537a2010-07-08 23:20:03 +0000150 void AdjustResultPriorityForPreferredType(Result &R);
151
Douglas Gregor86d9a522009-09-21 16:56:56 +0000152 public:
153 explicit ResultBuilder(Sema &SemaRef, LookupFilter Filter = 0)
Douglas Gregor3cdee122010-08-26 16:36:48 +0000154 : SemaRef(SemaRef), Filter(Filter), AllowNestedNameSpecifiers(false),
155 HasObjectTypeQualifiers(false) { }
Douglas Gregor86d9a522009-09-21 16:56:56 +0000156
Douglas Gregord8e8a582010-05-25 21:41:55 +0000157 /// \brief Whether we should include code patterns in the completion
158 /// results.
159 bool includeCodePatterns() const {
160 return SemaRef.CodeCompleter &&
Douglas Gregorf6961522010-08-27 21:18:54 +0000161 SemaRef.CodeCompleter->includeCodePatterns();
Douglas Gregord8e8a582010-05-25 21:41:55 +0000162 }
163
Douglas Gregor86d9a522009-09-21 16:56:56 +0000164 /// \brief Set the filter used for code-completion results.
165 void setFilter(LookupFilter Filter) {
166 this->Filter = Filter;
167 }
168
Douglas Gregor86d9a522009-09-21 16:56:56 +0000169 Result *data() { return Results.empty()? 0 : &Results.front(); }
170 unsigned size() const { return Results.size(); }
171 bool empty() const { return Results.empty(); }
172
Douglas Gregor5ac3bdb2010-05-30 01:49:25 +0000173 /// \brief Specify the preferred type.
174 void setPreferredType(QualType T) {
175 PreferredType = SemaRef.Context.getCanonicalType(T);
176 }
177
Douglas Gregor3cdee122010-08-26 16:36:48 +0000178 /// \brief Set the cv-qualifiers on the object type, for us in filtering
179 /// calls to member functions.
180 ///
181 /// When there are qualifiers in this set, they will be used to filter
182 /// out member functions that aren't available (because there will be a
183 /// cv-qualifier mismatch) or prefer functions with an exact qualifier
184 /// match.
185 void setObjectTypeQualifiers(Qualifiers Quals) {
186 ObjectTypeQualifiers = Quals;
187 HasObjectTypeQualifiers = true;
188 }
189
Douglas Gregor265f7492010-08-27 15:29:55 +0000190 /// \brief Set the preferred selector.
191 ///
192 /// When an Objective-C method declaration result is added, and that
193 /// method's selector matches this preferred selector, we give that method
194 /// a slight priority boost.
195 void setPreferredSelector(Selector Sel) {
196 PreferredSelector = Sel;
197 }
198
Douglas Gregor45bcd432010-01-14 03:21:49 +0000199 /// \brief Specify whether nested-name-specifiers are allowed.
200 void allowNestedNameSpecifiers(bool Allow = true) {
201 AllowNestedNameSpecifiers = Allow;
202 }
203
Douglas Gregore495b7f2010-01-14 00:20:49 +0000204 /// \brief Determine whether the given declaration is at all interesting
205 /// as a code-completion result.
Douglas Gregor45bcd432010-01-14 03:21:49 +0000206 ///
207 /// \param ND the declaration that we are inspecting.
208 ///
209 /// \param AsNestedNameSpecifier will be set true if this declaration is
210 /// only interesting when it is a nested-name-specifier.
211 bool isInterestingDecl(NamedDecl *ND, bool &AsNestedNameSpecifier) const;
Douglas Gregor6660d842010-01-14 00:41:07 +0000212
213 /// \brief Check whether the result is hidden by the Hiding declaration.
214 ///
215 /// \returns true if the result is hidden and cannot be found, false if
216 /// the hidden result could still be found. When false, \p R may be
217 /// modified to describe how the result can be found (e.g., via extra
218 /// qualification).
219 bool CheckHiddenResult(Result &R, DeclContext *CurContext,
220 NamedDecl *Hiding);
221
Douglas Gregor86d9a522009-09-21 16:56:56 +0000222 /// \brief Add a new result to this result set (if it isn't already in one
223 /// of the shadow maps), or replace an existing result (for, e.g., a
224 /// redeclaration).
Douglas Gregor456c4a12009-09-21 20:12:40 +0000225 ///
Douglas Gregor1ca6ae82010-01-14 01:09:38 +0000226 /// \param CurContext the result to add (if it is unique).
Douglas Gregor456c4a12009-09-21 20:12:40 +0000227 ///
228 /// \param R the context in which this result will be named.
229 void MaybeAddResult(Result R, DeclContext *CurContext = 0);
Douglas Gregor86d9a522009-09-21 16:56:56 +0000230
Douglas Gregor1ca6ae82010-01-14 01:09:38 +0000231 /// \brief Add a new result to this result set, where we already know
232 /// the hiding declation (if any).
233 ///
234 /// \param R the result to add (if it is unique).
235 ///
236 /// \param CurContext the context in which this result will be named.
237 ///
238 /// \param Hiding the declaration that hides the result.
Douglas Gregor0cc84042010-01-14 15:47:35 +0000239 ///
240 /// \param InBaseClass whether the result was found in a base
241 /// class of the searched context.
242 void AddResult(Result R, DeclContext *CurContext, NamedDecl *Hiding,
243 bool InBaseClass);
Douglas Gregor1ca6ae82010-01-14 01:09:38 +0000244
Douglas Gregora4477812010-01-14 16:01:26 +0000245 /// \brief Add a new non-declaration result to this result set.
246 void AddResult(Result R);
247
Douglas Gregor86d9a522009-09-21 16:56:56 +0000248 /// \brief Enter into a new scope.
249 void EnterNewScope();
250
251 /// \brief Exit from the current scope.
252 void ExitScope();
253
Douglas Gregor55385fe2009-11-18 04:19:12 +0000254 /// \brief Ignore this declaration, if it is seen again.
255 void Ignore(Decl *D) { AllDeclsFound.insert(D->getCanonicalDecl()); }
256
Douglas Gregor86d9a522009-09-21 16:56:56 +0000257 /// \name Name lookup predicates
258 ///
259 /// These predicates can be passed to the name lookup functions to filter the
260 /// results of name lookup. All of the predicates have the same type, so that
261 ///
262 //@{
Douglas Gregor791215b2009-09-21 20:51:25 +0000263 bool IsOrdinaryName(NamedDecl *ND) const;
Douglas Gregor4710e5b2010-05-28 00:49:12 +0000264 bool IsOrdinaryNonTypeName(NamedDecl *ND) const;
Douglas Gregorf9578432010-07-28 21:50:18 +0000265 bool IsIntegralConstantValue(NamedDecl *ND) const;
Douglas Gregor01dfea02010-01-10 23:08:15 +0000266 bool IsOrdinaryNonValueName(NamedDecl *ND) const;
Douglas Gregor86d9a522009-09-21 16:56:56 +0000267 bool IsNestedNameSpecifier(NamedDecl *ND) const;
268 bool IsEnum(NamedDecl *ND) const;
269 bool IsClassOrStruct(NamedDecl *ND) const;
270 bool IsUnion(NamedDecl *ND) const;
271 bool IsNamespace(NamedDecl *ND) const;
272 bool IsNamespaceOrAlias(NamedDecl *ND) const;
273 bool IsType(NamedDecl *ND) const;
Douglas Gregoreb5758b2009-09-23 22:26:46 +0000274 bool IsMember(NamedDecl *ND) const;
Douglas Gregor80f4f4c2010-01-14 16:08:12 +0000275 bool IsObjCIvar(NamedDecl *ND) const;
Douglas Gregor8e254cf2010-05-27 23:06:34 +0000276 bool IsObjCMessageReceiver(NamedDecl *ND) const;
Douglas Gregorfb629412010-08-23 21:17:50 +0000277 bool IsObjCCollection(NamedDecl *ND) const;
Douglas Gregor86d9a522009-09-21 16:56:56 +0000278 //@}
279 };
280}
281
Douglas Gregorfbcb5d62009-12-06 20:23:50 +0000282class ResultBuilder::ShadowMapEntry::iterator {
283 llvm::PointerUnion<NamedDecl*, const DeclIndexPair*> DeclOrIterator;
284 unsigned SingleDeclIndex;
285
286public:
287 typedef DeclIndexPair value_type;
288 typedef value_type reference;
289 typedef std::ptrdiff_t difference_type;
290 typedef std::input_iterator_tag iterator_category;
291
292 class pointer {
293 DeclIndexPair Value;
294
295 public:
296 pointer(const DeclIndexPair &Value) : Value(Value) { }
297
298 const DeclIndexPair *operator->() const {
299 return &Value;
300 }
301 };
302
303 iterator() : DeclOrIterator((NamedDecl *)0), SingleDeclIndex(0) { }
304
305 iterator(NamedDecl *SingleDecl, unsigned Index)
306 : DeclOrIterator(SingleDecl), SingleDeclIndex(Index) { }
307
308 iterator(const DeclIndexPair *Iterator)
309 : DeclOrIterator(Iterator), SingleDeclIndex(0) { }
310
311 iterator &operator++() {
312 if (DeclOrIterator.is<NamedDecl *>()) {
313 DeclOrIterator = (NamedDecl *)0;
314 SingleDeclIndex = 0;
315 return *this;
316 }
317
318 const DeclIndexPair *I = DeclOrIterator.get<const DeclIndexPair*>();
319 ++I;
320 DeclOrIterator = I;
321 return *this;
322 }
323
Chris Lattner66392d42010-09-04 18:12:20 +0000324 /*iterator operator++(int) {
Douglas Gregorfbcb5d62009-12-06 20:23:50 +0000325 iterator tmp(*this);
326 ++(*this);
327 return tmp;
Chris Lattner66392d42010-09-04 18:12:20 +0000328 }*/
Douglas Gregorfbcb5d62009-12-06 20:23:50 +0000329
330 reference operator*() const {
331 if (NamedDecl *ND = DeclOrIterator.dyn_cast<NamedDecl *>())
332 return reference(ND, SingleDeclIndex);
333
Douglas Gregord490f952009-12-06 21:27:58 +0000334 return *DeclOrIterator.get<const DeclIndexPair*>();
Douglas Gregorfbcb5d62009-12-06 20:23:50 +0000335 }
336
337 pointer operator->() const {
338 return pointer(**this);
339 }
340
341 friend bool operator==(const iterator &X, const iterator &Y) {
Douglas Gregord490f952009-12-06 21:27:58 +0000342 return X.DeclOrIterator.getOpaqueValue()
343 == Y.DeclOrIterator.getOpaqueValue() &&
Douglas Gregorfbcb5d62009-12-06 20:23:50 +0000344 X.SingleDeclIndex == Y.SingleDeclIndex;
345 }
346
347 friend bool operator!=(const iterator &X, const iterator &Y) {
Douglas Gregord490f952009-12-06 21:27:58 +0000348 return !(X == Y);
Douglas Gregorfbcb5d62009-12-06 20:23:50 +0000349 }
350};
351
Douglas Gregorfbcb5d62009-12-06 20:23:50 +0000352ResultBuilder::ShadowMapEntry::iterator
353ResultBuilder::ShadowMapEntry::begin() const {
354 if (DeclOrVector.isNull())
355 return iterator();
356
357 if (NamedDecl *ND = DeclOrVector.dyn_cast<NamedDecl *>())
358 return iterator(ND, SingleDeclIndex);
359
360 return iterator(DeclOrVector.get<DeclIndexPairVector *>()->begin());
361}
362
363ResultBuilder::ShadowMapEntry::iterator
364ResultBuilder::ShadowMapEntry::end() const {
365 if (DeclOrVector.is<NamedDecl *>() || DeclOrVector.isNull())
366 return iterator();
367
368 return iterator(DeclOrVector.get<DeclIndexPairVector *>()->end());
369}
370
Douglas Gregor456c4a12009-09-21 20:12:40 +0000371/// \brief Compute the qualification required to get from the current context
372/// (\p CurContext) to the target context (\p TargetContext).
373///
374/// \param Context the AST context in which the qualification will be used.
375///
376/// \param CurContext the context where an entity is being named, which is
377/// typically based on the current scope.
378///
379/// \param TargetContext the context in which the named entity actually
380/// resides.
381///
382/// \returns a nested name specifier that refers into the target context, or
383/// NULL if no qualification is needed.
384static NestedNameSpecifier *
385getRequiredQualification(ASTContext &Context,
386 DeclContext *CurContext,
387 DeclContext *TargetContext) {
388 llvm::SmallVector<DeclContext *, 4> TargetParents;
389
390 for (DeclContext *CommonAncestor = TargetContext;
391 CommonAncestor && !CommonAncestor->Encloses(CurContext);
392 CommonAncestor = CommonAncestor->getLookupParent()) {
393 if (CommonAncestor->isTransparentContext() ||
394 CommonAncestor->isFunctionOrMethod())
395 continue;
396
397 TargetParents.push_back(CommonAncestor);
398 }
399
400 NestedNameSpecifier *Result = 0;
401 while (!TargetParents.empty()) {
402 DeclContext *Parent = TargetParents.back();
403 TargetParents.pop_back();
404
Douglas Gregorfb629412010-08-23 21:17:50 +0000405 if (NamespaceDecl *Namespace = dyn_cast<NamespaceDecl>(Parent)) {
406 if (!Namespace->getIdentifier())
407 continue;
408
Douglas Gregor456c4a12009-09-21 20:12:40 +0000409 Result = NestedNameSpecifier::Create(Context, Result, Namespace);
Douglas Gregorfb629412010-08-23 21:17:50 +0000410 }
Douglas Gregor456c4a12009-09-21 20:12:40 +0000411 else if (TagDecl *TD = dyn_cast<TagDecl>(Parent))
412 Result = NestedNameSpecifier::Create(Context, Result,
413 false,
414 Context.getTypeDeclType(TD).getTypePtr());
Douglas Gregor0c8296d2009-11-07 00:00:49 +0000415 }
Douglas Gregor456c4a12009-09-21 20:12:40 +0000416 return Result;
417}
418
Douglas Gregor45bcd432010-01-14 03:21:49 +0000419bool ResultBuilder::isInterestingDecl(NamedDecl *ND,
420 bool &AsNestedNameSpecifier) const {
421 AsNestedNameSpecifier = false;
422
Douglas Gregore495b7f2010-01-14 00:20:49 +0000423 ND = ND->getUnderlyingDecl();
424 unsigned IDNS = ND->getIdentifierNamespace();
Douglas Gregorf52cede2009-10-09 22:16:47 +0000425
426 // Skip unnamed entities.
Douglas Gregore495b7f2010-01-14 00:20:49 +0000427 if (!ND->getDeclName())
428 return false;
Douglas Gregor86d9a522009-09-21 16:56:56 +0000429
430 // Friend declarations and declarations introduced due to friends are never
431 // added as results.
John McCall92b7f702010-03-11 07:50:04 +0000432 if (IDNS & (Decl::IDNS_OrdinaryFriend | Decl::IDNS_TagFriend))
Douglas Gregore495b7f2010-01-14 00:20:49 +0000433 return false;
434
Douglas Gregor76282942009-12-11 17:31:05 +0000435 // Class template (partial) specializations are never added as results.
Douglas Gregore495b7f2010-01-14 00:20:49 +0000436 if (isa<ClassTemplateSpecializationDecl>(ND) ||
437 isa<ClassTemplatePartialSpecializationDecl>(ND))
438 return false;
Douglas Gregor86d9a522009-09-21 16:56:56 +0000439
Douglas Gregor76282942009-12-11 17:31:05 +0000440 // Using declarations themselves are never added as results.
Douglas Gregore495b7f2010-01-14 00:20:49 +0000441 if (isa<UsingDecl>(ND))
442 return false;
443
444 // Some declarations have reserved names that we don't want to ever show.
445 if (const IdentifierInfo *Id = ND->getIdentifier()) {
Douglas Gregor86d9a522009-09-21 16:56:56 +0000446 // __va_list_tag is a freak of nature. Find it and skip it.
447 if (Id->isStr("__va_list_tag") || Id->isStr("__builtin_va_list"))
Douglas Gregore495b7f2010-01-14 00:20:49 +0000448 return false;
Douglas Gregor86d9a522009-09-21 16:56:56 +0000449
Douglas Gregorf52cede2009-10-09 22:16:47 +0000450 // Filter out names reserved for the implementation (C99 7.1.3,
Douglas Gregor797efb52010-07-14 17:44:04 +0000451 // C++ [lib.global.names]) if they come from a system header.
Daniel Dunbare013d682009-10-18 20:26:12 +0000452 //
453 // FIXME: Add predicate for this.
Douglas Gregorf52cede2009-10-09 22:16:47 +0000454 if (Id->getLength() >= 2) {
Daniel Dunbare013d682009-10-18 20:26:12 +0000455 const char *Name = Id->getNameStart();
Douglas Gregorf52cede2009-10-09 22:16:47 +0000456 if (Name[0] == '_' &&
Douglas Gregor797efb52010-07-14 17:44:04 +0000457 (Name[1] == '_' || (Name[1] >= 'A' && Name[1] <= 'Z')) &&
458 (ND->getLocation().isInvalid() ||
459 SemaRef.SourceMgr.isInSystemHeader(
460 SemaRef.SourceMgr.getSpellingLoc(ND->getLocation()))))
Douglas Gregore495b7f2010-01-14 00:20:49 +0000461 return false;
Douglas Gregorf52cede2009-10-09 22:16:47 +0000462 }
Douglas Gregor86d9a522009-09-21 16:56:56 +0000463 }
Douglas Gregore495b7f2010-01-14 00:20:49 +0000464
Douglas Gregor86d9a522009-09-21 16:56:56 +0000465 // C++ constructors are never found by name lookup.
Douglas Gregore495b7f2010-01-14 00:20:49 +0000466 if (isa<CXXConstructorDecl>(ND))
467 return false;
Douglas Gregor86d9a522009-09-21 16:56:56 +0000468
Douglas Gregora5fb7c32010-08-16 23:05:20 +0000469 if (Filter == &ResultBuilder::IsNestedNameSpecifier ||
470 ((isa<NamespaceDecl>(ND) || isa<NamespaceAliasDecl>(ND)) &&
471 Filter != &ResultBuilder::IsNamespace &&
472 Filter != &ResultBuilder::IsNamespaceOrAlias))
473 AsNestedNameSpecifier = true;
474
Douglas Gregor86d9a522009-09-21 16:56:56 +0000475 // Filter out any unwanted results.
Douglas Gregor45bcd432010-01-14 03:21:49 +0000476 if (Filter && !(this->*Filter)(ND)) {
477 // Check whether it is interesting as a nested-name-specifier.
478 if (AllowNestedNameSpecifiers && SemaRef.getLangOptions().CPlusPlus &&
479 IsNestedNameSpecifier(ND) &&
480 (Filter != &ResultBuilder::IsMember ||
481 (isa<CXXRecordDecl>(ND) &&
482 cast<CXXRecordDecl>(ND)->isInjectedClassName()))) {
483 AsNestedNameSpecifier = true;
484 return true;
485 }
486
Douglas Gregore495b7f2010-01-14 00:20:49 +0000487 return false;
Douglas Gregora5fb7c32010-08-16 23:05:20 +0000488 }
Douglas Gregore495b7f2010-01-14 00:20:49 +0000489 // ... then it must be interesting!
490 return true;
491}
492
Douglas Gregor6660d842010-01-14 00:41:07 +0000493bool ResultBuilder::CheckHiddenResult(Result &R, DeclContext *CurContext,
494 NamedDecl *Hiding) {
495 // In C, there is no way to refer to a hidden name.
496 // FIXME: This isn't true; we can find a tag name hidden by an ordinary
497 // name if we introduce the tag type.
498 if (!SemaRef.getLangOptions().CPlusPlus)
499 return true;
500
Sebastian Redl7a126a42010-08-31 00:36:30 +0000501 DeclContext *HiddenCtx = R.Declaration->getDeclContext()->getRedeclContext();
Douglas Gregor6660d842010-01-14 00:41:07 +0000502
503 // There is no way to qualify a name declared in a function or method.
504 if (HiddenCtx->isFunctionOrMethod())
505 return true;
506
Sebastian Redl7a126a42010-08-31 00:36:30 +0000507 if (HiddenCtx == Hiding->getDeclContext()->getRedeclContext())
Douglas Gregor6660d842010-01-14 00:41:07 +0000508 return true;
509
510 // We can refer to the result with the appropriate qualification. Do it.
511 R.Hidden = true;
512 R.QualifierIsInformative = false;
513
514 if (!R.Qualifier)
515 R.Qualifier = getRequiredQualification(SemaRef.Context,
516 CurContext,
517 R.Declaration->getDeclContext());
518 return false;
519}
520
Douglas Gregor1f5537a2010-07-08 23:20:03 +0000521/// \brief A simplified classification of types used to determine whether two
522/// types are "similar enough" when adjusting priorities.
Douglas Gregor1827e102010-08-16 16:18:59 +0000523SimplifiedTypeClass clang::getSimplifiedTypeClass(CanQualType T) {
Douglas Gregor1f5537a2010-07-08 23:20:03 +0000524 switch (T->getTypeClass()) {
525 case Type::Builtin:
526 switch (cast<BuiltinType>(T)->getKind()) {
527 case BuiltinType::Void:
528 return STC_Void;
529
530 case BuiltinType::NullPtr:
531 return STC_Pointer;
532
533 case BuiltinType::Overload:
534 case BuiltinType::Dependent:
535 case BuiltinType::UndeducedAuto:
536 return STC_Other;
537
538 case BuiltinType::ObjCId:
539 case BuiltinType::ObjCClass:
540 case BuiltinType::ObjCSel:
541 return STC_ObjectiveC;
542
543 default:
544 return STC_Arithmetic;
545 }
546 return STC_Other;
547
548 case Type::Complex:
549 return STC_Arithmetic;
550
551 case Type::Pointer:
552 return STC_Pointer;
553
554 case Type::BlockPointer:
555 return STC_Block;
556
557 case Type::LValueReference:
558 case Type::RValueReference:
559 return getSimplifiedTypeClass(T->getAs<ReferenceType>()->getPointeeType());
560
561 case Type::ConstantArray:
562 case Type::IncompleteArray:
563 case Type::VariableArray:
564 case Type::DependentSizedArray:
565 return STC_Array;
566
567 case Type::DependentSizedExtVector:
568 case Type::Vector:
569 case Type::ExtVector:
570 return STC_Arithmetic;
571
572 case Type::FunctionProto:
573 case Type::FunctionNoProto:
574 return STC_Function;
575
576 case Type::Record:
577 return STC_Record;
578
579 case Type::Enum:
580 return STC_Arithmetic;
581
582 case Type::ObjCObject:
583 case Type::ObjCInterface:
584 case Type::ObjCObjectPointer:
585 return STC_ObjectiveC;
586
587 default:
588 return STC_Other;
589 }
590}
591
592/// \brief Get the type that a given expression will have if this declaration
593/// is used as an expression in its "typical" code-completion form.
Douglas Gregor1827e102010-08-16 16:18:59 +0000594QualType clang::getDeclUsageType(ASTContext &C, NamedDecl *ND) {
Douglas Gregor1f5537a2010-07-08 23:20:03 +0000595 ND = cast<NamedDecl>(ND->getUnderlyingDecl());
596
597 if (TypeDecl *Type = dyn_cast<TypeDecl>(ND))
598 return C.getTypeDeclType(Type);
599 if (ObjCInterfaceDecl *Iface = dyn_cast<ObjCInterfaceDecl>(ND))
600 return C.getObjCInterfaceType(Iface);
601
602 QualType T;
603 if (FunctionDecl *Function = dyn_cast<FunctionDecl>(ND))
Douglas Gregor5291c3c2010-07-13 08:18:22 +0000604 T = Function->getCallResultType();
Douglas Gregor1f5537a2010-07-08 23:20:03 +0000605 else if (ObjCMethodDecl *Method = dyn_cast<ObjCMethodDecl>(ND))
Douglas Gregor5291c3c2010-07-13 08:18:22 +0000606 T = Method->getSendResultType();
Douglas Gregor1f5537a2010-07-08 23:20:03 +0000607 else if (FunctionTemplateDecl *FunTmpl = dyn_cast<FunctionTemplateDecl>(ND))
Douglas Gregor5291c3c2010-07-13 08:18:22 +0000608 T = FunTmpl->getTemplatedDecl()->getCallResultType();
Douglas Gregor1f5537a2010-07-08 23:20:03 +0000609 else if (EnumConstantDecl *Enumerator = dyn_cast<EnumConstantDecl>(ND))
610 T = C.getTypeDeclType(cast<EnumDecl>(Enumerator->getDeclContext()));
611 else if (ObjCPropertyDecl *Property = dyn_cast<ObjCPropertyDecl>(ND))
612 T = Property->getType();
613 else if (ValueDecl *Value = dyn_cast<ValueDecl>(ND))
614 T = Value->getType();
615 else
616 return QualType();
617
618 return T.getNonReferenceType();
619}
620
621void ResultBuilder::AdjustResultPriorityForPreferredType(Result &R) {
622 QualType T = getDeclUsageType(SemaRef.Context, R.Declaration);
623 if (T.isNull())
624 return;
625
626 CanQualType TC = SemaRef.Context.getCanonicalType(T);
627 // Check for exactly-matching types (modulo qualifiers).
Douglas Gregoreb0d0142010-08-24 23:58:17 +0000628 if (SemaRef.Context.hasSameUnqualifiedType(PreferredType, TC)) {
629 if (PreferredType->isVoidType())
630 R.Priority += CCD_VoidMatch;
631 else
632 R.Priority /= CCF_ExactTypeMatch;
633 } // Check for nearly-matching types, based on classification of each.
Douglas Gregor1f5537a2010-07-08 23:20:03 +0000634 else if ((getSimplifiedTypeClass(PreferredType)
635 == getSimplifiedTypeClass(TC)) &&
636 !(PreferredType->isEnumeralType() && TC->isEnumeralType()))
637 R.Priority /= CCF_SimilarTypeMatch;
638}
639
Douglas Gregore495b7f2010-01-14 00:20:49 +0000640void ResultBuilder::MaybeAddResult(Result R, DeclContext *CurContext) {
641 assert(!ShadowMaps.empty() && "Must enter into a results scope");
642
643 if (R.Kind != Result::RK_Declaration) {
644 // For non-declaration results, just add the result.
645 Results.push_back(R);
646 return;
647 }
648
649 // Look through using declarations.
650 if (UsingShadowDecl *Using = dyn_cast<UsingShadowDecl>(R.Declaration)) {
651 MaybeAddResult(Result(Using->getTargetDecl(), R.Qualifier), CurContext);
652 return;
653 }
654
655 Decl *CanonDecl = R.Declaration->getCanonicalDecl();
656 unsigned IDNS = CanonDecl->getIdentifierNamespace();
657
Douglas Gregor45bcd432010-01-14 03:21:49 +0000658 bool AsNestedNameSpecifier = false;
659 if (!isInterestingDecl(R.Declaration, AsNestedNameSpecifier))
Douglas Gregore495b7f2010-01-14 00:20:49 +0000660 return;
661
Douglas Gregor86d9a522009-09-21 16:56:56 +0000662 ShadowMap &SMap = ShadowMaps.back();
Douglas Gregorfbcb5d62009-12-06 20:23:50 +0000663 ShadowMapEntry::iterator I, IEnd;
664 ShadowMap::iterator NamePos = SMap.find(R.Declaration->getDeclName());
665 if (NamePos != SMap.end()) {
666 I = NamePos->second.begin();
667 IEnd = NamePos->second.end();
668 }
669
670 for (; I != IEnd; ++I) {
671 NamedDecl *ND = I->first;
672 unsigned Index = I->second;
Douglas Gregor86d9a522009-09-21 16:56:56 +0000673 if (ND->getCanonicalDecl() == CanonDecl) {
674 // This is a redeclaration. Always pick the newer declaration.
Douglas Gregor86d9a522009-09-21 16:56:56 +0000675 Results[Index].Declaration = R.Declaration;
676
Douglas Gregor86d9a522009-09-21 16:56:56 +0000677 // We're done.
678 return;
679 }
680 }
681
682 // This is a new declaration in this scope. However, check whether this
683 // declaration name is hidden by a similarly-named declaration in an outer
684 // scope.
685 std::list<ShadowMap>::iterator SM, SMEnd = ShadowMaps.end();
686 --SMEnd;
687 for (SM = ShadowMaps.begin(); SM != SMEnd; ++SM) {
Douglas Gregorfbcb5d62009-12-06 20:23:50 +0000688 ShadowMapEntry::iterator I, IEnd;
689 ShadowMap::iterator NamePos = SM->find(R.Declaration->getDeclName());
690 if (NamePos != SM->end()) {
691 I = NamePos->second.begin();
692 IEnd = NamePos->second.end();
693 }
694 for (; I != IEnd; ++I) {
Douglas Gregor86d9a522009-09-21 16:56:56 +0000695 // A tag declaration does not hide a non-tag declaration.
John McCall0d6b1642010-04-23 18:46:30 +0000696 if (I->first->hasTagIdentifierNamespace() &&
Douglas Gregor86d9a522009-09-21 16:56:56 +0000697 (IDNS & (Decl::IDNS_Member | Decl::IDNS_Ordinary |
698 Decl::IDNS_ObjCProtocol)))
699 continue;
700
701 // Protocols are in distinct namespaces from everything else.
Douglas Gregorfbcb5d62009-12-06 20:23:50 +0000702 if (((I->first->getIdentifierNamespace() & Decl::IDNS_ObjCProtocol)
Douglas Gregor86d9a522009-09-21 16:56:56 +0000703 || (IDNS & Decl::IDNS_ObjCProtocol)) &&
Douglas Gregorfbcb5d62009-12-06 20:23:50 +0000704 I->first->getIdentifierNamespace() != IDNS)
Douglas Gregor86d9a522009-09-21 16:56:56 +0000705 continue;
706
707 // The newly-added result is hidden by an entry in the shadow map.
Douglas Gregor6660d842010-01-14 00:41:07 +0000708 if (CheckHiddenResult(R, CurContext, I->first))
Douglas Gregor86d9a522009-09-21 16:56:56 +0000709 return;
Douglas Gregor86d9a522009-09-21 16:56:56 +0000710
711 break;
712 }
713 }
714
715 // Make sure that any given declaration only shows up in the result set once.
716 if (!AllDeclsFound.insert(CanonDecl))
717 return;
Douglas Gregor265f7492010-08-27 15:29:55 +0000718
719 // If this is an Objective-C method declaration whose selector matches our
720 // preferred selector, give it a priority boost.
721 if (!PreferredSelector.isNull())
722 if (ObjCMethodDecl *Method = dyn_cast<ObjCMethodDecl>(R.Declaration))
723 if (PreferredSelector == Method->getSelector())
724 R.Priority += CCD_SelectorMatch;
725
Douglas Gregoreb5758b2009-09-23 22:26:46 +0000726 // If the filter is for nested-name-specifiers, then this result starts a
727 // nested-name-specifier.
Douglas Gregor12e13132010-05-26 22:00:08 +0000728 if (AsNestedNameSpecifier) {
Douglas Gregoreb5758b2009-09-23 22:26:46 +0000729 R.StartsNestedNameSpecifier = true;
Douglas Gregor12e13132010-05-26 22:00:08 +0000730 R.Priority = CCP_NestedNameSpecifier;
Douglas Gregor1f5537a2010-07-08 23:20:03 +0000731 } else if (!PreferredType.isNull())
732 AdjustResultPriorityForPreferredType(R);
Douglas Gregor265f7492010-08-27 15:29:55 +0000733
Douglas Gregor0563c262009-09-22 23:15:58 +0000734 // If this result is supposed to have an informative qualifier, add one.
Douglas Gregoreb5758b2009-09-23 22:26:46 +0000735 if (R.QualifierIsInformative && !R.Qualifier &&
736 !R.StartsNestedNameSpecifier) {
Douglas Gregor0563c262009-09-22 23:15:58 +0000737 DeclContext *Ctx = R.Declaration->getDeclContext();
738 if (NamespaceDecl *Namespace = dyn_cast<NamespaceDecl>(Ctx))
739 R.Qualifier = NestedNameSpecifier::Create(SemaRef.Context, 0, Namespace);
740 else if (TagDecl *Tag = dyn_cast<TagDecl>(Ctx))
741 R.Qualifier = NestedNameSpecifier::Create(SemaRef.Context, 0, false,
742 SemaRef.Context.getTypeDeclType(Tag).getTypePtr());
743 else
744 R.QualifierIsInformative = false;
745 }
Douglas Gregoreb5758b2009-09-23 22:26:46 +0000746
Douglas Gregor86d9a522009-09-21 16:56:56 +0000747 // Insert this result into the set of results and into the current shadow
748 // map.
Douglas Gregorfbcb5d62009-12-06 20:23:50 +0000749 SMap[R.Declaration->getDeclName()].Add(R.Declaration, Results.size());
Douglas Gregor86d9a522009-09-21 16:56:56 +0000750 Results.push_back(R);
751}
752
Douglas Gregor1ca6ae82010-01-14 01:09:38 +0000753void ResultBuilder::AddResult(Result R, DeclContext *CurContext,
Douglas Gregor0cc84042010-01-14 15:47:35 +0000754 NamedDecl *Hiding, bool InBaseClass = false) {
Douglas Gregora4477812010-01-14 16:01:26 +0000755 if (R.Kind != Result::RK_Declaration) {
756 // For non-declaration results, just add the result.
757 Results.push_back(R);
758 return;
759 }
760
Douglas Gregor1ca6ae82010-01-14 01:09:38 +0000761 // Look through using declarations.
762 if (UsingShadowDecl *Using = dyn_cast<UsingShadowDecl>(R.Declaration)) {
763 AddResult(Result(Using->getTargetDecl(), R.Qualifier), CurContext, Hiding);
764 return;
765 }
766
Douglas Gregor45bcd432010-01-14 03:21:49 +0000767 bool AsNestedNameSpecifier = false;
768 if (!isInterestingDecl(R.Declaration, AsNestedNameSpecifier))
Douglas Gregor1ca6ae82010-01-14 01:09:38 +0000769 return;
770
771 if (Hiding && CheckHiddenResult(R, CurContext, Hiding))
772 return;
773
774 // Make sure that any given declaration only shows up in the result set once.
775 if (!AllDeclsFound.insert(R.Declaration->getCanonicalDecl()))
776 return;
777
778 // If the filter is for nested-name-specifiers, then this result starts a
779 // nested-name-specifier.
Douglas Gregor12e13132010-05-26 22:00:08 +0000780 if (AsNestedNameSpecifier) {
Douglas Gregor1ca6ae82010-01-14 01:09:38 +0000781 R.StartsNestedNameSpecifier = true;
Douglas Gregor12e13132010-05-26 22:00:08 +0000782 R.Priority = CCP_NestedNameSpecifier;
783 }
Douglas Gregor0cc84042010-01-14 15:47:35 +0000784 else if (Filter == &ResultBuilder::IsMember && !R.Qualifier && InBaseClass &&
785 isa<CXXRecordDecl>(R.Declaration->getDeclContext()
Sebastian Redl7a126a42010-08-31 00:36:30 +0000786 ->getRedeclContext()))
Douglas Gregor0cc84042010-01-14 15:47:35 +0000787 R.QualifierIsInformative = true;
788
Douglas Gregor1ca6ae82010-01-14 01:09:38 +0000789 // If this result is supposed to have an informative qualifier, add one.
790 if (R.QualifierIsInformative && !R.Qualifier &&
791 !R.StartsNestedNameSpecifier) {
792 DeclContext *Ctx = R.Declaration->getDeclContext();
793 if (NamespaceDecl *Namespace = dyn_cast<NamespaceDecl>(Ctx))
794 R.Qualifier = NestedNameSpecifier::Create(SemaRef.Context, 0, Namespace);
795 else if (TagDecl *Tag = dyn_cast<TagDecl>(Ctx))
796 R.Qualifier = NestedNameSpecifier::Create(SemaRef.Context, 0, false,
Douglas Gregor45bcd432010-01-14 03:21:49 +0000797 SemaRef.Context.getTypeDeclType(Tag).getTypePtr());
Douglas Gregor1ca6ae82010-01-14 01:09:38 +0000798 else
799 R.QualifierIsInformative = false;
800 }
801
Douglas Gregor12e13132010-05-26 22:00:08 +0000802 // Adjust the priority if this result comes from a base class.
803 if (InBaseClass)
804 R.Priority += CCD_InBaseClass;
805
Douglas Gregor265f7492010-08-27 15:29:55 +0000806 // If this is an Objective-C method declaration whose selector matches our
807 // preferred selector, give it a priority boost.
808 if (!PreferredSelector.isNull())
809 if (ObjCMethodDecl *Method = dyn_cast<ObjCMethodDecl>(R.Declaration))
810 if (PreferredSelector == Method->getSelector())
811 R.Priority += CCD_SelectorMatch;
812
Douglas Gregor1f5537a2010-07-08 23:20:03 +0000813 if (!PreferredType.isNull())
814 AdjustResultPriorityForPreferredType(R);
Douglas Gregor5ac3bdb2010-05-30 01:49:25 +0000815
Douglas Gregor3cdee122010-08-26 16:36:48 +0000816 if (HasObjectTypeQualifiers)
817 if (CXXMethodDecl *Method = dyn_cast<CXXMethodDecl>(R.Declaration))
818 if (Method->isInstance()) {
819 Qualifiers MethodQuals
820 = Qualifiers::fromCVRMask(Method->getTypeQualifiers());
821 if (ObjectTypeQualifiers == MethodQuals)
822 R.Priority += CCD_ObjectQualifierMatch;
823 else if (ObjectTypeQualifiers - MethodQuals) {
824 // The method cannot be invoked, because doing so would drop
825 // qualifiers.
826 return;
827 }
828 }
829
Douglas Gregor1ca6ae82010-01-14 01:09:38 +0000830 // Insert this result into the set of results.
831 Results.push_back(R);
832}
833
Douglas Gregora4477812010-01-14 16:01:26 +0000834void ResultBuilder::AddResult(Result R) {
835 assert(R.Kind != Result::RK_Declaration &&
836 "Declaration results need more context");
837 Results.push_back(R);
838}
839
Douglas Gregor86d9a522009-09-21 16:56:56 +0000840/// \brief Enter into a new scope.
841void ResultBuilder::EnterNewScope() {
842 ShadowMaps.push_back(ShadowMap());
843}
844
845/// \brief Exit from the current scope.
846void ResultBuilder::ExitScope() {
Douglas Gregorfbcb5d62009-12-06 20:23:50 +0000847 for (ShadowMap::iterator E = ShadowMaps.back().begin(),
848 EEnd = ShadowMaps.back().end();
849 E != EEnd;
850 ++E)
851 E->second.Destroy();
852
Douglas Gregor86d9a522009-09-21 16:56:56 +0000853 ShadowMaps.pop_back();
854}
855
Douglas Gregor791215b2009-09-21 20:51:25 +0000856/// \brief Determines whether this given declaration will be found by
857/// ordinary name lookup.
858bool ResultBuilder::IsOrdinaryName(NamedDecl *ND) const {
Douglas Gregor4710e5b2010-05-28 00:49:12 +0000859 ND = cast<NamedDecl>(ND->getUnderlyingDecl());
860
Douglas Gregor791215b2009-09-21 20:51:25 +0000861 unsigned IDNS = Decl::IDNS_Ordinary;
862 if (SemaRef.getLangOptions().CPlusPlus)
Douglas Gregor9b30b262010-06-15 20:26:51 +0000863 IDNS |= Decl::IDNS_Tag | Decl::IDNS_Namespace | Decl::IDNS_Member;
Douglas Gregor1ca6ae82010-01-14 01:09:38 +0000864 else if (SemaRef.getLangOptions().ObjC1 && isa<ObjCIvarDecl>(ND))
865 return true;
866
Douglas Gregor791215b2009-09-21 20:51:25 +0000867 return ND->getIdentifierNamespace() & IDNS;
868}
869
Douglas Gregor01dfea02010-01-10 23:08:15 +0000870/// \brief Determines whether this given declaration will be found by
Douglas Gregor4710e5b2010-05-28 00:49:12 +0000871/// ordinary name lookup but is not a type name.
872bool ResultBuilder::IsOrdinaryNonTypeName(NamedDecl *ND) const {
873 ND = cast<NamedDecl>(ND->getUnderlyingDecl());
874 if (isa<TypeDecl>(ND) || isa<ObjCInterfaceDecl>(ND))
875 return false;
876
877 unsigned IDNS = Decl::IDNS_Ordinary;
878 if (SemaRef.getLangOptions().CPlusPlus)
Douglas Gregor9b30b262010-06-15 20:26:51 +0000879 IDNS |= Decl::IDNS_Tag | Decl::IDNS_Namespace | Decl::IDNS_Member;
Douglas Gregor4710e5b2010-05-28 00:49:12 +0000880 else if (SemaRef.getLangOptions().ObjC1 && isa<ObjCIvarDecl>(ND))
881 return true;
882
883 return ND->getIdentifierNamespace() & IDNS;
884}
885
Douglas Gregorf9578432010-07-28 21:50:18 +0000886bool ResultBuilder::IsIntegralConstantValue(NamedDecl *ND) const {
887 if (!IsOrdinaryNonTypeName(ND))
888 return 0;
889
890 if (ValueDecl *VD = dyn_cast<ValueDecl>(ND->getUnderlyingDecl()))
891 if (VD->getType()->isIntegralOrEnumerationType())
892 return true;
893
894 return false;
895}
896
Douglas Gregor4710e5b2010-05-28 00:49:12 +0000897/// \brief Determines whether this given declaration will be found by
Douglas Gregor01dfea02010-01-10 23:08:15 +0000898/// ordinary name lookup.
899bool ResultBuilder::IsOrdinaryNonValueName(NamedDecl *ND) const {
Douglas Gregor4710e5b2010-05-28 00:49:12 +0000900 ND = cast<NamedDecl>(ND->getUnderlyingDecl());
901
Douglas Gregor01dfea02010-01-10 23:08:15 +0000902 unsigned IDNS = Decl::IDNS_Ordinary;
903 if (SemaRef.getLangOptions().CPlusPlus)
John McCall0d6b1642010-04-23 18:46:30 +0000904 IDNS |= Decl::IDNS_Tag | Decl::IDNS_Namespace;
Douglas Gregor01dfea02010-01-10 23:08:15 +0000905
906 return (ND->getIdentifierNamespace() & IDNS) &&
Douglas Gregor4710e5b2010-05-28 00:49:12 +0000907 !isa<ValueDecl>(ND) && !isa<FunctionTemplateDecl>(ND) &&
908 !isa<ObjCPropertyDecl>(ND);
Douglas Gregor01dfea02010-01-10 23:08:15 +0000909}
910
Douglas Gregor86d9a522009-09-21 16:56:56 +0000911/// \brief Determines whether the given declaration is suitable as the
912/// start of a C++ nested-name-specifier, e.g., a class or namespace.
913bool ResultBuilder::IsNestedNameSpecifier(NamedDecl *ND) const {
914 // Allow us to find class templates, too.
915 if (ClassTemplateDecl *ClassTemplate = dyn_cast<ClassTemplateDecl>(ND))
916 ND = ClassTemplate->getTemplatedDecl();
917
918 return SemaRef.isAcceptableNestedNameSpecifier(ND);
919}
920
921/// \brief Determines whether the given declaration is an enumeration.
922bool ResultBuilder::IsEnum(NamedDecl *ND) const {
923 return isa<EnumDecl>(ND);
924}
925
926/// \brief Determines whether the given declaration is a class or struct.
927bool ResultBuilder::IsClassOrStruct(NamedDecl *ND) const {
928 // Allow us to find class templates, too.
929 if (ClassTemplateDecl *ClassTemplate = dyn_cast<ClassTemplateDecl>(ND))
930 ND = ClassTemplate->getTemplatedDecl();
931
932 if (RecordDecl *RD = dyn_cast<RecordDecl>(ND))
Abramo Bagnara465d41b2010-05-11 21:36:43 +0000933 return RD->getTagKind() == TTK_Class ||
934 RD->getTagKind() == TTK_Struct;
Douglas Gregor86d9a522009-09-21 16:56:56 +0000935
936 return false;
937}
938
939/// \brief Determines whether the given declaration is a union.
940bool ResultBuilder::IsUnion(NamedDecl *ND) const {
941 // Allow us to find class templates, too.
942 if (ClassTemplateDecl *ClassTemplate = dyn_cast<ClassTemplateDecl>(ND))
943 ND = ClassTemplate->getTemplatedDecl();
944
945 if (RecordDecl *RD = dyn_cast<RecordDecl>(ND))
Abramo Bagnara465d41b2010-05-11 21:36:43 +0000946 return RD->getTagKind() == TTK_Union;
Douglas Gregor86d9a522009-09-21 16:56:56 +0000947
948 return false;
949}
950
951/// \brief Determines whether the given declaration is a namespace.
952bool ResultBuilder::IsNamespace(NamedDecl *ND) const {
953 return isa<NamespaceDecl>(ND);
954}
955
956/// \brief Determines whether the given declaration is a namespace or
957/// namespace alias.
958bool ResultBuilder::IsNamespaceOrAlias(NamedDecl *ND) const {
959 return isa<NamespaceDecl>(ND) || isa<NamespaceAliasDecl>(ND);
960}
961
Douglas Gregor76282942009-12-11 17:31:05 +0000962/// \brief Determines whether the given declaration is a type.
Douglas Gregor86d9a522009-09-21 16:56:56 +0000963bool ResultBuilder::IsType(NamedDecl *ND) const {
Douglas Gregord32b0222010-08-24 01:06:58 +0000964 if (UsingShadowDecl *Using = dyn_cast<UsingShadowDecl>(ND))
965 ND = Using->getTargetDecl();
966
967 return isa<TypeDecl>(ND) || isa<ObjCInterfaceDecl>(ND);
Douglas Gregor86d9a522009-09-21 16:56:56 +0000968}
969
Douglas Gregor76282942009-12-11 17:31:05 +0000970/// \brief Determines which members of a class should be visible via
971/// "." or "->". Only value declarations, nested name specifiers, and
972/// using declarations thereof should show up.
Douglas Gregoreb5758b2009-09-23 22:26:46 +0000973bool ResultBuilder::IsMember(NamedDecl *ND) const {
Douglas Gregor76282942009-12-11 17:31:05 +0000974 if (UsingShadowDecl *Using = dyn_cast<UsingShadowDecl>(ND))
975 ND = Using->getTargetDecl();
976
Douglas Gregorce821962009-12-11 18:14:22 +0000977 return isa<ValueDecl>(ND) || isa<FunctionTemplateDecl>(ND) ||
978 isa<ObjCPropertyDecl>(ND);
Douglas Gregoreb5758b2009-09-23 22:26:46 +0000979}
980
Douglas Gregor8e254cf2010-05-27 23:06:34 +0000981static bool isObjCReceiverType(ASTContext &C, QualType T) {
982 T = C.getCanonicalType(T);
983 switch (T->getTypeClass()) {
984 case Type::ObjCObject:
985 case Type::ObjCInterface:
986 case Type::ObjCObjectPointer:
987 return true;
988
989 case Type::Builtin:
990 switch (cast<BuiltinType>(T)->getKind()) {
991 case BuiltinType::ObjCId:
992 case BuiltinType::ObjCClass:
993 case BuiltinType::ObjCSel:
994 return true;
995
996 default:
997 break;
998 }
999 return false;
1000
1001 default:
1002 break;
1003 }
1004
1005 if (!C.getLangOptions().CPlusPlus)
1006 return false;
1007
1008 // FIXME: We could perform more analysis here to determine whether a
1009 // particular class type has any conversions to Objective-C types. For now,
1010 // just accept all class types.
1011 return T->isDependentType() || T->isRecordType();
1012}
1013
1014bool ResultBuilder::IsObjCMessageReceiver(NamedDecl *ND) const {
1015 QualType T = getDeclUsageType(SemaRef.Context, ND);
1016 if (T.isNull())
1017 return false;
1018
1019 T = SemaRef.Context.getBaseElementType(T);
1020 return isObjCReceiverType(SemaRef.Context, T);
1021}
1022
Douglas Gregorfb629412010-08-23 21:17:50 +00001023bool ResultBuilder::IsObjCCollection(NamedDecl *ND) const {
1024 if ((SemaRef.getLangOptions().CPlusPlus && !IsOrdinaryName(ND)) ||
1025 (!SemaRef.getLangOptions().CPlusPlus && !IsOrdinaryNonTypeName(ND)))
1026 return false;
1027
1028 QualType T = getDeclUsageType(SemaRef.Context, ND);
1029 if (T.isNull())
1030 return false;
1031
1032 T = SemaRef.Context.getBaseElementType(T);
1033 return T->isObjCObjectType() || T->isObjCObjectPointerType() ||
1034 T->isObjCIdType() ||
1035 (SemaRef.getLangOptions().CPlusPlus && T->isRecordType());
1036}
Douglas Gregor8e254cf2010-05-27 23:06:34 +00001037
Douglas Gregor80f4f4c2010-01-14 16:08:12 +00001038/// \rief Determines whether the given declaration is an Objective-C
1039/// instance variable.
1040bool ResultBuilder::IsObjCIvar(NamedDecl *ND) const {
1041 return isa<ObjCIvarDecl>(ND);
1042}
1043
Douglas Gregor1ca6ae82010-01-14 01:09:38 +00001044namespace {
1045 /// \brief Visible declaration consumer that adds a code-completion result
1046 /// for each visible declaration.
1047 class CodeCompletionDeclConsumer : public VisibleDeclConsumer {
1048 ResultBuilder &Results;
1049 DeclContext *CurContext;
1050
1051 public:
1052 CodeCompletionDeclConsumer(ResultBuilder &Results, DeclContext *CurContext)
1053 : Results(Results), CurContext(CurContext) { }
1054
Douglas Gregor0cc84042010-01-14 15:47:35 +00001055 virtual void FoundDecl(NamedDecl *ND, NamedDecl *Hiding, bool InBaseClass) {
1056 Results.AddResult(ND, CurContext, Hiding, InBaseClass);
Douglas Gregor1ca6ae82010-01-14 01:09:38 +00001057 }
1058 };
1059}
1060
Douglas Gregor86d9a522009-09-21 16:56:56 +00001061/// \brief Add type specifiers for the current language as keyword results.
Douglas Gregorbca403c2010-01-13 23:51:12 +00001062static void AddTypeSpecifierResults(const LangOptions &LangOpts,
Douglas Gregor86d9a522009-09-21 16:56:56 +00001063 ResultBuilder &Results) {
John McCall0a2c5e22010-08-25 06:19:51 +00001064 typedef CodeCompletionResult Result;
Douglas Gregor12e13132010-05-26 22:00:08 +00001065 Results.AddResult(Result("short", CCP_Type));
1066 Results.AddResult(Result("long", CCP_Type));
1067 Results.AddResult(Result("signed", CCP_Type));
1068 Results.AddResult(Result("unsigned", CCP_Type));
1069 Results.AddResult(Result("void", CCP_Type));
1070 Results.AddResult(Result("char", CCP_Type));
1071 Results.AddResult(Result("int", CCP_Type));
1072 Results.AddResult(Result("float", CCP_Type));
1073 Results.AddResult(Result("double", CCP_Type));
1074 Results.AddResult(Result("enum", CCP_Type));
1075 Results.AddResult(Result("struct", CCP_Type));
1076 Results.AddResult(Result("union", CCP_Type));
1077 Results.AddResult(Result("const", CCP_Type));
1078 Results.AddResult(Result("volatile", CCP_Type));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001079
Douglas Gregor86d9a522009-09-21 16:56:56 +00001080 if (LangOpts.C99) {
1081 // C99-specific
Douglas Gregor12e13132010-05-26 22:00:08 +00001082 Results.AddResult(Result("_Complex", CCP_Type));
1083 Results.AddResult(Result("_Imaginary", CCP_Type));
1084 Results.AddResult(Result("_Bool", CCP_Type));
1085 Results.AddResult(Result("restrict", CCP_Type));
Douglas Gregor86d9a522009-09-21 16:56:56 +00001086 }
1087
1088 if (LangOpts.CPlusPlus) {
1089 // C++-specific
Douglas Gregorb05496d2010-09-20 21:11:48 +00001090 Results.AddResult(Result("bool", CCP_Type +
1091 (LangOpts.ObjC1? CCD_bool_in_ObjC : 0)));
Douglas Gregor12e13132010-05-26 22:00:08 +00001092 Results.AddResult(Result("class", CCP_Type));
1093 Results.AddResult(Result("wchar_t", CCP_Type));
Douglas Gregor86d9a522009-09-21 16:56:56 +00001094
Douglas Gregorc8bddde2010-05-28 00:22:41 +00001095 // typename qualified-id
1096 CodeCompletionString *Pattern = new CodeCompletionString;
1097 Pattern->AddTypedTextChunk("typename");
1098 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
1099 Pattern->AddPlaceholderChunk("qualifier");
1100 Pattern->AddTextChunk("::");
1101 Pattern->AddPlaceholderChunk("name");
1102 Results.AddResult(Result(Pattern));
Douglas Gregord8e8a582010-05-25 21:41:55 +00001103
Douglas Gregor86d9a522009-09-21 16:56:56 +00001104 if (LangOpts.CPlusPlus0x) {
Douglas Gregor12e13132010-05-26 22:00:08 +00001105 Results.AddResult(Result("auto", CCP_Type));
1106 Results.AddResult(Result("char16_t", CCP_Type));
1107 Results.AddResult(Result("char32_t", CCP_Type));
Douglas Gregorc8bddde2010-05-28 00:22:41 +00001108
1109 CodeCompletionString *Pattern = new CodeCompletionString;
1110 Pattern->AddTypedTextChunk("decltype");
1111 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
1112 Pattern->AddPlaceholderChunk("expression");
1113 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
1114 Results.AddResult(Result(Pattern));
Douglas Gregor86d9a522009-09-21 16:56:56 +00001115 }
1116 }
1117
1118 // GNU extensions
1119 if (LangOpts.GNUMode) {
1120 // FIXME: Enable when we actually support decimal floating point.
Douglas Gregora4477812010-01-14 16:01:26 +00001121 // Results.AddResult(Result("_Decimal32"));
1122 // Results.AddResult(Result("_Decimal64"));
1123 // Results.AddResult(Result("_Decimal128"));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001124
Douglas Gregorc8bddde2010-05-28 00:22:41 +00001125 CodeCompletionString *Pattern = new CodeCompletionString;
1126 Pattern->AddTypedTextChunk("typeof");
1127 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
1128 Pattern->AddPlaceholderChunk("expression");
1129 Results.AddResult(Result(Pattern));
1130
1131 Pattern = new CodeCompletionString;
1132 Pattern->AddTypedTextChunk("typeof");
1133 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
1134 Pattern->AddPlaceholderChunk("type");
1135 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
1136 Results.AddResult(Result(Pattern));
Douglas Gregor86d9a522009-09-21 16:56:56 +00001137 }
1138}
1139
John McCallf312b1e2010-08-26 23:41:50 +00001140static void AddStorageSpecifiers(Sema::ParserCompletionContext CCC,
Douglas Gregor01dfea02010-01-10 23:08:15 +00001141 const LangOptions &LangOpts,
Douglas Gregor01dfea02010-01-10 23:08:15 +00001142 ResultBuilder &Results) {
John McCall0a2c5e22010-08-25 06:19:51 +00001143 typedef CodeCompletionResult Result;
Douglas Gregor01dfea02010-01-10 23:08:15 +00001144 // Note: we don't suggest either "auto" or "register", because both
1145 // are pointless as storage specifiers. Elsewhere, we suggest "auto"
1146 // in C++0x as a type specifier.
Douglas Gregora4477812010-01-14 16:01:26 +00001147 Results.AddResult(Result("extern"));
1148 Results.AddResult(Result("static"));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001149}
1150
John McCallf312b1e2010-08-26 23:41:50 +00001151static void AddFunctionSpecifiers(Sema::ParserCompletionContext CCC,
Douglas Gregor01dfea02010-01-10 23:08:15 +00001152 const LangOptions &LangOpts,
Douglas Gregor01dfea02010-01-10 23:08:15 +00001153 ResultBuilder &Results) {
John McCall0a2c5e22010-08-25 06:19:51 +00001154 typedef CodeCompletionResult Result;
Douglas Gregor01dfea02010-01-10 23:08:15 +00001155 switch (CCC) {
John McCallf312b1e2010-08-26 23:41:50 +00001156 case Sema::PCC_Class:
1157 case Sema::PCC_MemberTemplate:
Douglas Gregor01dfea02010-01-10 23:08:15 +00001158 if (LangOpts.CPlusPlus) {
Douglas Gregora4477812010-01-14 16:01:26 +00001159 Results.AddResult(Result("explicit"));
1160 Results.AddResult(Result("friend"));
1161 Results.AddResult(Result("mutable"));
1162 Results.AddResult(Result("virtual"));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001163 }
1164 // Fall through
1165
John McCallf312b1e2010-08-26 23:41:50 +00001166 case Sema::PCC_ObjCInterface:
1167 case Sema::PCC_ObjCImplementation:
1168 case Sema::PCC_Namespace:
1169 case Sema::PCC_Template:
Douglas Gregor01dfea02010-01-10 23:08:15 +00001170 if (LangOpts.CPlusPlus || LangOpts.C99)
Douglas Gregora4477812010-01-14 16:01:26 +00001171 Results.AddResult(Result("inline"));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001172 break;
1173
John McCallf312b1e2010-08-26 23:41:50 +00001174 case Sema::PCC_ObjCInstanceVariableList:
1175 case Sema::PCC_Expression:
1176 case Sema::PCC_Statement:
1177 case Sema::PCC_ForInit:
1178 case Sema::PCC_Condition:
1179 case Sema::PCC_RecoveryInFunction:
1180 case Sema::PCC_Type:
Douglas Gregor02688102010-09-14 23:59:36 +00001181 case Sema::PCC_ParenthesizedExpression:
Douglas Gregor01dfea02010-01-10 23:08:15 +00001182 break;
1183 }
1184}
1185
Douglas Gregorbca403c2010-01-13 23:51:12 +00001186static void AddObjCExpressionResults(ResultBuilder &Results, bool NeedAt);
1187static void AddObjCStatementResults(ResultBuilder &Results, bool NeedAt);
1188static void AddObjCVisibilityResults(const LangOptions &LangOpts,
Douglas Gregorc38c3e12010-01-13 21:54:15 +00001189 ResultBuilder &Results,
1190 bool NeedAt);
Douglas Gregorbca403c2010-01-13 23:51:12 +00001191static void AddObjCImplementationResults(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 AddObjCInterfaceResults(const LangOptions &LangOpts,
Douglas Gregorb6ac2452010-01-13 21:24:21 +00001195 ResultBuilder &Results,
1196 bool NeedAt);
Douglas Gregorbca403c2010-01-13 23:51:12 +00001197static void AddObjCTopLevelResults(ResultBuilder &Results, bool NeedAt);
Douglas Gregorb6ac2452010-01-13 21:24:21 +00001198
Douglas Gregorc8bddde2010-05-28 00:22:41 +00001199static void AddTypedefResult(ResultBuilder &Results) {
1200 CodeCompletionString *Pattern = new CodeCompletionString;
1201 Pattern->AddTypedTextChunk("typedef");
1202 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
1203 Pattern->AddPlaceholderChunk("type");
1204 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
1205 Pattern->AddPlaceholderChunk("name");
John McCall0a2c5e22010-08-25 06:19:51 +00001206 Results.AddResult(CodeCompletionResult(Pattern));
Douglas Gregorc8bddde2010-05-28 00:22:41 +00001207}
1208
John McCallf312b1e2010-08-26 23:41:50 +00001209static bool WantTypesInContext(Sema::ParserCompletionContext CCC,
Douglas Gregor4710e5b2010-05-28 00:49:12 +00001210 const LangOptions &LangOpts) {
Douglas Gregor4710e5b2010-05-28 00:49:12 +00001211 switch (CCC) {
John McCallf312b1e2010-08-26 23:41:50 +00001212 case Sema::PCC_Namespace:
1213 case Sema::PCC_Class:
1214 case Sema::PCC_ObjCInstanceVariableList:
1215 case Sema::PCC_Template:
1216 case Sema::PCC_MemberTemplate:
1217 case Sema::PCC_Statement:
1218 case Sema::PCC_RecoveryInFunction:
1219 case Sema::PCC_Type:
Douglas Gregor02688102010-09-14 23:59:36 +00001220 case Sema::PCC_ParenthesizedExpression:
Douglas Gregor4710e5b2010-05-28 00:49:12 +00001221 return true;
1222
John McCallf312b1e2010-08-26 23:41:50 +00001223 case Sema::PCC_Expression:
1224 case Sema::PCC_Condition:
Douglas Gregor02688102010-09-14 23:59:36 +00001225 return LangOpts.CPlusPlus;
1226
1227 case Sema::PCC_ObjCInterface:
1228 case Sema::PCC_ObjCImplementation:
Douglas Gregor4710e5b2010-05-28 00:49:12 +00001229 return false;
1230
John McCallf312b1e2010-08-26 23:41:50 +00001231 case Sema::PCC_ForInit:
Douglas Gregor02688102010-09-14 23:59:36 +00001232 return LangOpts.CPlusPlus || LangOpts.ObjC1 || LangOpts.C99;
Douglas Gregor4710e5b2010-05-28 00:49:12 +00001233 }
1234
1235 return false;
1236}
1237
Douglas Gregor01dfea02010-01-10 23:08:15 +00001238/// \brief Add language constructs that show up for "ordinary" names.
John McCallf312b1e2010-08-26 23:41:50 +00001239static void AddOrdinaryNameResults(Sema::ParserCompletionContext CCC,
Douglas Gregor01dfea02010-01-10 23:08:15 +00001240 Scope *S,
1241 Sema &SemaRef,
Douglas Gregor01dfea02010-01-10 23:08:15 +00001242 ResultBuilder &Results) {
John McCall0a2c5e22010-08-25 06:19:51 +00001243 typedef CodeCompletionResult Result;
Douglas Gregor01dfea02010-01-10 23:08:15 +00001244 switch (CCC) {
John McCallf312b1e2010-08-26 23:41:50 +00001245 case Sema::PCC_Namespace:
Douglas Gregorc8bddde2010-05-28 00:22:41 +00001246 if (SemaRef.getLangOptions().CPlusPlus) {
1247 CodeCompletionString *Pattern = 0;
1248
1249 if (Results.includeCodePatterns()) {
1250 // namespace <identifier> { declarations }
1251 CodeCompletionString *Pattern = new CodeCompletionString;
1252 Pattern->AddTypedTextChunk("namespace");
1253 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
1254 Pattern->AddPlaceholderChunk("identifier");
1255 Pattern->AddChunk(CodeCompletionString::CK_LeftBrace);
1256 Pattern->AddPlaceholderChunk("declarations");
1257 Pattern->AddChunk(CodeCompletionString::CK_VerticalSpace);
1258 Pattern->AddChunk(CodeCompletionString::CK_RightBrace);
1259 Results.AddResult(Result(Pattern));
1260 }
1261
Douglas Gregor01dfea02010-01-10 23:08:15 +00001262 // namespace identifier = identifier ;
1263 Pattern = new CodeCompletionString;
1264 Pattern->AddTypedTextChunk("namespace");
1265 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
Douglas Gregorc8bddde2010-05-28 00:22:41 +00001266 Pattern->AddPlaceholderChunk("name");
Douglas Gregor01dfea02010-01-10 23:08:15 +00001267 Pattern->AddChunk(CodeCompletionString::CK_Equal);
Douglas Gregorc8bddde2010-05-28 00:22:41 +00001268 Pattern->AddPlaceholderChunk("namespace");
Douglas Gregora4477812010-01-14 16:01:26 +00001269 Results.AddResult(Result(Pattern));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001270
1271 // Using directives
1272 Pattern = new CodeCompletionString;
1273 Pattern->AddTypedTextChunk("using");
1274 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
1275 Pattern->AddTextChunk("namespace");
1276 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
1277 Pattern->AddPlaceholderChunk("identifier");
Douglas Gregora4477812010-01-14 16:01:26 +00001278 Results.AddResult(Result(Pattern));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001279
1280 // asm(string-literal)
1281 Pattern = new CodeCompletionString;
1282 Pattern->AddTypedTextChunk("asm");
1283 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
1284 Pattern->AddPlaceholderChunk("string-literal");
1285 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
Douglas Gregora4477812010-01-14 16:01:26 +00001286 Results.AddResult(Result(Pattern));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001287
Douglas Gregorc8bddde2010-05-28 00:22:41 +00001288 if (Results.includeCodePatterns()) {
1289 // Explicit template instantiation
1290 Pattern = new CodeCompletionString;
1291 Pattern->AddTypedTextChunk("template");
1292 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
1293 Pattern->AddPlaceholderChunk("declaration");
1294 Results.AddResult(Result(Pattern));
1295 }
Douglas Gregor01dfea02010-01-10 23:08:15 +00001296 }
Douglas Gregorb6ac2452010-01-13 21:24:21 +00001297
1298 if (SemaRef.getLangOptions().ObjC1)
Douglas Gregorbca403c2010-01-13 23:51:12 +00001299 AddObjCTopLevelResults(Results, true);
Douglas Gregorb6ac2452010-01-13 21:24:21 +00001300
Douglas Gregorc8bddde2010-05-28 00:22:41 +00001301 AddTypedefResult(Results);
Douglas Gregor01dfea02010-01-10 23:08:15 +00001302 // Fall through
1303
John McCallf312b1e2010-08-26 23:41:50 +00001304 case Sema::PCC_Class:
Douglas Gregorc8bddde2010-05-28 00:22:41 +00001305 if (SemaRef.getLangOptions().CPlusPlus) {
Douglas Gregor01dfea02010-01-10 23:08:15 +00001306 // Using declaration
1307 CodeCompletionString *Pattern = new CodeCompletionString;
1308 Pattern->AddTypedTextChunk("using");
1309 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
Douglas Gregorc8bddde2010-05-28 00:22:41 +00001310 Pattern->AddPlaceholderChunk("qualifier");
1311 Pattern->AddTextChunk("::");
1312 Pattern->AddPlaceholderChunk("name");
Douglas Gregora4477812010-01-14 16:01:26 +00001313 Results.AddResult(Result(Pattern));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001314
Douglas Gregorc8bddde2010-05-28 00:22:41 +00001315 // using typename qualifier::name (only in a dependent context)
Douglas Gregor01dfea02010-01-10 23:08:15 +00001316 if (SemaRef.CurContext->isDependentContext()) {
1317 Pattern = new CodeCompletionString;
1318 Pattern->AddTypedTextChunk("using");
1319 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
1320 Pattern->AddTextChunk("typename");
1321 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
Douglas Gregorc8bddde2010-05-28 00:22:41 +00001322 Pattern->AddPlaceholderChunk("qualifier");
1323 Pattern->AddTextChunk("::");
1324 Pattern->AddPlaceholderChunk("name");
Douglas Gregora4477812010-01-14 16:01:26 +00001325 Results.AddResult(Result(Pattern));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001326 }
1327
John McCallf312b1e2010-08-26 23:41:50 +00001328 if (CCC == Sema::PCC_Class) {
Douglas Gregorc8bddde2010-05-28 00:22:41 +00001329 AddTypedefResult(Results);
1330
Douglas Gregor01dfea02010-01-10 23:08:15 +00001331 // public:
1332 Pattern = new CodeCompletionString;
1333 Pattern->AddTypedTextChunk("public");
1334 Pattern->AddChunk(CodeCompletionString::CK_Colon);
Douglas Gregora4477812010-01-14 16:01:26 +00001335 Results.AddResult(Result(Pattern));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001336
1337 // protected:
1338 Pattern = new CodeCompletionString;
1339 Pattern->AddTypedTextChunk("protected");
1340 Pattern->AddChunk(CodeCompletionString::CK_Colon);
Douglas Gregora4477812010-01-14 16:01:26 +00001341 Results.AddResult(Result(Pattern));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001342
1343 // private:
1344 Pattern = new CodeCompletionString;
1345 Pattern->AddTypedTextChunk("private");
1346 Pattern->AddChunk(CodeCompletionString::CK_Colon);
Douglas Gregora4477812010-01-14 16:01:26 +00001347 Results.AddResult(Result(Pattern));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001348 }
1349 }
1350 // Fall through
1351
John McCallf312b1e2010-08-26 23:41:50 +00001352 case Sema::PCC_Template:
1353 case Sema::PCC_MemberTemplate:
Douglas Gregord8e8a582010-05-25 21:41:55 +00001354 if (SemaRef.getLangOptions().CPlusPlus && Results.includeCodePatterns()) {
Douglas Gregor01dfea02010-01-10 23:08:15 +00001355 // template < parameters >
1356 CodeCompletionString *Pattern = new CodeCompletionString;
1357 Pattern->AddTypedTextChunk("template");
1358 Pattern->AddChunk(CodeCompletionString::CK_LeftAngle);
1359 Pattern->AddPlaceholderChunk("parameters");
1360 Pattern->AddChunk(CodeCompletionString::CK_RightAngle);
Douglas Gregora4477812010-01-14 16:01:26 +00001361 Results.AddResult(Result(Pattern));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001362 }
1363
Douglas Gregorbca403c2010-01-13 23:51:12 +00001364 AddStorageSpecifiers(CCC, SemaRef.getLangOptions(), Results);
1365 AddFunctionSpecifiers(CCC, SemaRef.getLangOptions(), Results);
Douglas Gregor01dfea02010-01-10 23:08:15 +00001366 break;
1367
John McCallf312b1e2010-08-26 23:41:50 +00001368 case Sema::PCC_ObjCInterface:
Douglas Gregorbca403c2010-01-13 23:51:12 +00001369 AddObjCInterfaceResults(SemaRef.getLangOptions(), Results, true);
1370 AddStorageSpecifiers(CCC, SemaRef.getLangOptions(), Results);
1371 AddFunctionSpecifiers(CCC, SemaRef.getLangOptions(), Results);
Douglas Gregorb6ac2452010-01-13 21:24:21 +00001372 break;
1373
John McCallf312b1e2010-08-26 23:41:50 +00001374 case Sema::PCC_ObjCImplementation:
Douglas Gregorbca403c2010-01-13 23:51:12 +00001375 AddObjCImplementationResults(SemaRef.getLangOptions(), Results, true);
1376 AddStorageSpecifiers(CCC, SemaRef.getLangOptions(), Results);
1377 AddFunctionSpecifiers(CCC, SemaRef.getLangOptions(), Results);
Douglas Gregorb6ac2452010-01-13 21:24:21 +00001378 break;
1379
John McCallf312b1e2010-08-26 23:41:50 +00001380 case Sema::PCC_ObjCInstanceVariableList:
Douglas Gregorbca403c2010-01-13 23:51:12 +00001381 AddObjCVisibilityResults(SemaRef.getLangOptions(), Results, true);
Douglas Gregorc38c3e12010-01-13 21:54:15 +00001382 break;
1383
John McCallf312b1e2010-08-26 23:41:50 +00001384 case Sema::PCC_RecoveryInFunction:
1385 case Sema::PCC_Statement: {
Douglas Gregorc8bddde2010-05-28 00:22:41 +00001386 AddTypedefResult(Results);
Douglas Gregor01dfea02010-01-10 23:08:15 +00001387
1388 CodeCompletionString *Pattern = 0;
Douglas Gregord8e8a582010-05-25 21:41:55 +00001389 if (SemaRef.getLangOptions().CPlusPlus && Results.includeCodePatterns()) {
Douglas Gregor01dfea02010-01-10 23:08:15 +00001390 Pattern = new CodeCompletionString;
1391 Pattern->AddTypedTextChunk("try");
1392 Pattern->AddChunk(CodeCompletionString::CK_LeftBrace);
1393 Pattern->AddPlaceholderChunk("statements");
1394 Pattern->AddChunk(CodeCompletionString::CK_VerticalSpace);
1395 Pattern->AddChunk(CodeCompletionString::CK_RightBrace);
1396 Pattern->AddTextChunk("catch");
1397 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
1398 Pattern->AddPlaceholderChunk("declaration");
1399 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
1400 Pattern->AddChunk(CodeCompletionString::CK_LeftBrace);
1401 Pattern->AddPlaceholderChunk("statements");
1402 Pattern->AddChunk(CodeCompletionString::CK_VerticalSpace);
1403 Pattern->AddChunk(CodeCompletionString::CK_RightBrace);
Douglas Gregora4477812010-01-14 16:01:26 +00001404 Results.AddResult(Result(Pattern));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001405 }
Douglas Gregorb6ac2452010-01-13 21:24:21 +00001406 if (SemaRef.getLangOptions().ObjC1)
Douglas Gregorbca403c2010-01-13 23:51:12 +00001407 AddObjCStatementResults(Results, true);
Douglas Gregorb6ac2452010-01-13 21:24:21 +00001408
Douglas Gregord8e8a582010-05-25 21:41:55 +00001409 if (Results.includeCodePatterns()) {
1410 // if (condition) { statements }
1411 Pattern = new CodeCompletionString;
1412 Pattern->AddTypedTextChunk("if");
1413 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
1414 if (SemaRef.getLangOptions().CPlusPlus)
1415 Pattern->AddPlaceholderChunk("condition");
1416 else
1417 Pattern->AddPlaceholderChunk("expression");
1418 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
1419 Pattern->AddChunk(CodeCompletionString::CK_LeftBrace);
1420 Pattern->AddPlaceholderChunk("statements");
1421 Pattern->AddChunk(CodeCompletionString::CK_VerticalSpace);
1422 Pattern->AddChunk(CodeCompletionString::CK_RightBrace);
1423 Results.AddResult(Result(Pattern));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001424
Douglas Gregord8e8a582010-05-25 21:41:55 +00001425 // switch (condition) { }
1426 Pattern = new CodeCompletionString;
1427 Pattern->AddTypedTextChunk("switch");
1428 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
1429 if (SemaRef.getLangOptions().CPlusPlus)
1430 Pattern->AddPlaceholderChunk("condition");
1431 else
1432 Pattern->AddPlaceholderChunk("expression");
1433 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
1434 Pattern->AddChunk(CodeCompletionString::CK_LeftBrace);
1435 Pattern->AddChunk(CodeCompletionString::CK_VerticalSpace);
1436 Pattern->AddChunk(CodeCompletionString::CK_RightBrace);
1437 Results.AddResult(Result(Pattern));
1438 }
1439
Douglas Gregor01dfea02010-01-10 23:08:15 +00001440 // Switch-specific statements.
John McCall781472f2010-08-25 08:40:02 +00001441 if (!SemaRef.getCurFunction()->SwitchStack.empty()) {
Douglas Gregor01dfea02010-01-10 23:08:15 +00001442 // case expression:
1443 Pattern = new CodeCompletionString;
1444 Pattern->AddTypedTextChunk("case");
Douglas Gregorc8bddde2010-05-28 00:22:41 +00001445 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
Douglas Gregor01dfea02010-01-10 23:08:15 +00001446 Pattern->AddPlaceholderChunk("expression");
1447 Pattern->AddChunk(CodeCompletionString::CK_Colon);
Douglas Gregora4477812010-01-14 16:01:26 +00001448 Results.AddResult(Result(Pattern));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001449
1450 // default:
1451 Pattern = new CodeCompletionString;
1452 Pattern->AddTypedTextChunk("default");
1453 Pattern->AddChunk(CodeCompletionString::CK_Colon);
Douglas Gregora4477812010-01-14 16:01:26 +00001454 Results.AddResult(Result(Pattern));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001455 }
1456
Douglas Gregord8e8a582010-05-25 21:41:55 +00001457 if (Results.includeCodePatterns()) {
1458 /// while (condition) { statements }
1459 Pattern = new CodeCompletionString;
1460 Pattern->AddTypedTextChunk("while");
1461 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
1462 if (SemaRef.getLangOptions().CPlusPlus)
1463 Pattern->AddPlaceholderChunk("condition");
1464 else
1465 Pattern->AddPlaceholderChunk("expression");
1466 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
1467 Pattern->AddChunk(CodeCompletionString::CK_LeftBrace);
1468 Pattern->AddPlaceholderChunk("statements");
1469 Pattern->AddChunk(CodeCompletionString::CK_VerticalSpace);
1470 Pattern->AddChunk(CodeCompletionString::CK_RightBrace);
1471 Results.AddResult(Result(Pattern));
1472
1473 // do { statements } while ( expression );
1474 Pattern = new CodeCompletionString;
1475 Pattern->AddTypedTextChunk("do");
1476 Pattern->AddChunk(CodeCompletionString::CK_LeftBrace);
1477 Pattern->AddPlaceholderChunk("statements");
1478 Pattern->AddChunk(CodeCompletionString::CK_VerticalSpace);
1479 Pattern->AddChunk(CodeCompletionString::CK_RightBrace);
1480 Pattern->AddTextChunk("while");
1481 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
Douglas Gregor01dfea02010-01-10 23:08:15 +00001482 Pattern->AddPlaceholderChunk("expression");
Douglas Gregord8e8a582010-05-25 21:41:55 +00001483 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
1484 Results.AddResult(Result(Pattern));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001485
Douglas Gregord8e8a582010-05-25 21:41:55 +00001486 // for ( for-init-statement ; condition ; expression ) { statements }
1487 Pattern = new CodeCompletionString;
1488 Pattern->AddTypedTextChunk("for");
1489 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
1490 if (SemaRef.getLangOptions().CPlusPlus || SemaRef.getLangOptions().C99)
1491 Pattern->AddPlaceholderChunk("init-statement");
1492 else
1493 Pattern->AddPlaceholderChunk("init-expression");
1494 Pattern->AddChunk(CodeCompletionString::CK_SemiColon);
1495 Pattern->AddPlaceholderChunk("condition");
1496 Pattern->AddChunk(CodeCompletionString::CK_SemiColon);
1497 Pattern->AddPlaceholderChunk("inc-expression");
1498 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
1499 Pattern->AddChunk(CodeCompletionString::CK_LeftBrace);
1500 Pattern->AddPlaceholderChunk("statements");
1501 Pattern->AddChunk(CodeCompletionString::CK_VerticalSpace);
1502 Pattern->AddChunk(CodeCompletionString::CK_RightBrace);
1503 Results.AddResult(Result(Pattern));
1504 }
Douglas Gregor01dfea02010-01-10 23:08:15 +00001505
1506 if (S->getContinueParent()) {
1507 // continue ;
1508 Pattern = new CodeCompletionString;
1509 Pattern->AddTypedTextChunk("continue");
Douglas Gregora4477812010-01-14 16:01:26 +00001510 Results.AddResult(Result(Pattern));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001511 }
1512
1513 if (S->getBreakParent()) {
1514 // break ;
1515 Pattern = new CodeCompletionString;
1516 Pattern->AddTypedTextChunk("break");
Douglas Gregora4477812010-01-14 16:01:26 +00001517 Results.AddResult(Result(Pattern));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001518 }
1519
1520 // "return expression ;" or "return ;", depending on whether we
1521 // know the function is void or not.
1522 bool isVoid = false;
1523 if (FunctionDecl *Function = dyn_cast<FunctionDecl>(SemaRef.CurContext))
1524 isVoid = Function->getResultType()->isVoidType();
1525 else if (ObjCMethodDecl *Method
1526 = dyn_cast<ObjCMethodDecl>(SemaRef.CurContext))
1527 isVoid = Method->getResultType()->isVoidType();
Douglas Gregor9ea9bdb2010-03-01 23:15:13 +00001528 else if (SemaRef.getCurBlock() &&
1529 !SemaRef.getCurBlock()->ReturnType.isNull())
1530 isVoid = SemaRef.getCurBlock()->ReturnType->isVoidType();
Douglas Gregor01dfea02010-01-10 23:08:15 +00001531 Pattern = new CodeCompletionString;
1532 Pattern->AddTypedTextChunk("return");
Douglas Gregor93298002010-02-18 04:06:48 +00001533 if (!isVoid) {
1534 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
Douglas Gregor01dfea02010-01-10 23:08:15 +00001535 Pattern->AddPlaceholderChunk("expression");
Douglas Gregor93298002010-02-18 04:06:48 +00001536 }
Douglas Gregora4477812010-01-14 16:01:26 +00001537 Results.AddResult(Result(Pattern));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001538
Douglas Gregorc8bddde2010-05-28 00:22:41 +00001539 // goto identifier ;
1540 Pattern = new CodeCompletionString;
1541 Pattern->AddTypedTextChunk("goto");
1542 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
1543 Pattern->AddPlaceholderChunk("label");
1544 Results.AddResult(Result(Pattern));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001545
Douglas Gregorc8bddde2010-05-28 00:22:41 +00001546 // Using directives
1547 Pattern = new CodeCompletionString;
1548 Pattern->AddTypedTextChunk("using");
1549 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
1550 Pattern->AddTextChunk("namespace");
1551 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
1552 Pattern->AddPlaceholderChunk("identifier");
1553 Results.AddResult(Result(Pattern));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001554 }
1555
1556 // Fall through (for statement expressions).
John McCallf312b1e2010-08-26 23:41:50 +00001557 case Sema::PCC_ForInit:
1558 case Sema::PCC_Condition:
Douglas Gregorbca403c2010-01-13 23:51:12 +00001559 AddStorageSpecifiers(CCC, SemaRef.getLangOptions(), Results);
Douglas Gregor01dfea02010-01-10 23:08:15 +00001560 // Fall through: conditions and statements can have expressions.
1561
Douglas Gregor02688102010-09-14 23:59:36 +00001562 case Sema::PCC_ParenthesizedExpression:
John McCallf312b1e2010-08-26 23:41:50 +00001563 case Sema::PCC_Expression: {
Douglas Gregor01dfea02010-01-10 23:08:15 +00001564 CodeCompletionString *Pattern = 0;
1565 if (SemaRef.getLangOptions().CPlusPlus) {
1566 // 'this', if we're in a non-static member function.
1567 if (CXXMethodDecl *Method = dyn_cast<CXXMethodDecl>(SemaRef.CurContext))
1568 if (!Method->isStatic())
Douglas Gregora4477812010-01-14 16:01:26 +00001569 Results.AddResult(Result("this"));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001570
1571 // true, false
Douglas Gregora4477812010-01-14 16:01:26 +00001572 Results.AddResult(Result("true"));
1573 Results.AddResult(Result("false"));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001574
Douglas Gregorc8bddde2010-05-28 00:22:41 +00001575 // dynamic_cast < type-id > ( expression )
1576 Pattern = new CodeCompletionString;
1577 Pattern->AddTypedTextChunk("dynamic_cast");
1578 Pattern->AddChunk(CodeCompletionString::CK_LeftAngle);
1579 Pattern->AddPlaceholderChunk("type");
1580 Pattern->AddChunk(CodeCompletionString::CK_RightAngle);
1581 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
1582 Pattern->AddPlaceholderChunk("expression");
1583 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
1584 Results.AddResult(Result(Pattern));
1585
1586 // static_cast < type-id > ( expression )
1587 Pattern = new CodeCompletionString;
1588 Pattern->AddTypedTextChunk("static_cast");
1589 Pattern->AddChunk(CodeCompletionString::CK_LeftAngle);
1590 Pattern->AddPlaceholderChunk("type");
1591 Pattern->AddChunk(CodeCompletionString::CK_RightAngle);
1592 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
1593 Pattern->AddPlaceholderChunk("expression");
1594 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
1595 Results.AddResult(Result(Pattern));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001596
Douglas Gregorc8bddde2010-05-28 00:22:41 +00001597 // reinterpret_cast < type-id > ( expression )
1598 Pattern = new CodeCompletionString;
1599 Pattern->AddTypedTextChunk("reinterpret_cast");
1600 Pattern->AddChunk(CodeCompletionString::CK_LeftAngle);
1601 Pattern->AddPlaceholderChunk("type");
1602 Pattern->AddChunk(CodeCompletionString::CK_RightAngle);
1603 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
1604 Pattern->AddPlaceholderChunk("expression");
1605 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
1606 Results.AddResult(Result(Pattern));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001607
Douglas Gregorc8bddde2010-05-28 00:22:41 +00001608 // const_cast < type-id > ( expression )
1609 Pattern = new CodeCompletionString;
1610 Pattern->AddTypedTextChunk("const_cast");
1611 Pattern->AddChunk(CodeCompletionString::CK_LeftAngle);
1612 Pattern->AddPlaceholderChunk("type");
1613 Pattern->AddChunk(CodeCompletionString::CK_RightAngle);
1614 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
1615 Pattern->AddPlaceholderChunk("expression");
1616 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
1617 Results.AddResult(Result(Pattern));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001618
Douglas Gregorc8bddde2010-05-28 00:22:41 +00001619 // typeid ( expression-or-type )
1620 Pattern = new CodeCompletionString;
1621 Pattern->AddTypedTextChunk("typeid");
1622 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
1623 Pattern->AddPlaceholderChunk("expression-or-type");
1624 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
1625 Results.AddResult(Result(Pattern));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001626
Douglas Gregorc8bddde2010-05-28 00:22:41 +00001627 // new T ( ... )
1628 Pattern = new CodeCompletionString;
1629 Pattern->AddTypedTextChunk("new");
1630 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
1631 Pattern->AddPlaceholderChunk("type");
1632 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
1633 Pattern->AddPlaceholderChunk("expressions");
1634 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
1635 Results.AddResult(Result(Pattern));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001636
Douglas Gregorc8bddde2010-05-28 00:22:41 +00001637 // new T [ ] ( ... )
1638 Pattern = new CodeCompletionString;
1639 Pattern->AddTypedTextChunk("new");
1640 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
1641 Pattern->AddPlaceholderChunk("type");
1642 Pattern->AddChunk(CodeCompletionString::CK_LeftBracket);
1643 Pattern->AddPlaceholderChunk("size");
1644 Pattern->AddChunk(CodeCompletionString::CK_RightBracket);
1645 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
1646 Pattern->AddPlaceholderChunk("expressions");
1647 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
1648 Results.AddResult(Result(Pattern));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001649
Douglas Gregorc8bddde2010-05-28 00:22:41 +00001650 // delete expression
1651 Pattern = new CodeCompletionString;
1652 Pattern->AddTypedTextChunk("delete");
1653 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
1654 Pattern->AddPlaceholderChunk("expression");
1655 Results.AddResult(Result(Pattern));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001656
Douglas Gregorc8bddde2010-05-28 00:22:41 +00001657 // delete [] expression
1658 Pattern = new CodeCompletionString;
1659 Pattern->AddTypedTextChunk("delete");
1660 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
1661 Pattern->AddChunk(CodeCompletionString::CK_LeftBracket);
1662 Pattern->AddChunk(CodeCompletionString::CK_RightBracket);
1663 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
1664 Pattern->AddPlaceholderChunk("expression");
1665 Results.AddResult(Result(Pattern));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001666
Douglas Gregorc8bddde2010-05-28 00:22:41 +00001667 // throw expression
1668 Pattern = new CodeCompletionString;
1669 Pattern->AddTypedTextChunk("throw");
1670 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
1671 Pattern->AddPlaceholderChunk("expression");
1672 Results.AddResult(Result(Pattern));
Douglas Gregor12e13132010-05-26 22:00:08 +00001673
1674 // FIXME: Rethrow?
Douglas Gregor01dfea02010-01-10 23:08:15 +00001675 }
1676
1677 if (SemaRef.getLangOptions().ObjC1) {
1678 // Add "super", if we're in an Objective-C class with a superclass.
Ted Kremenek681e2562010-05-31 21:43:10 +00001679 if (ObjCMethodDecl *Method = SemaRef.getCurMethodDecl()) {
1680 // The interface can be NULL.
1681 if (ObjCInterfaceDecl *ID = Method->getClassInterface())
1682 if (ID->getSuperClass())
1683 Results.AddResult(Result("super"));
1684 }
1685
Douglas Gregorbca403c2010-01-13 23:51:12 +00001686 AddObjCExpressionResults(Results, true);
Douglas Gregor01dfea02010-01-10 23:08:15 +00001687 }
1688
Douglas Gregorc8bddde2010-05-28 00:22:41 +00001689 // sizeof expression
1690 Pattern = new CodeCompletionString;
1691 Pattern->AddTypedTextChunk("sizeof");
1692 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
1693 Pattern->AddPlaceholderChunk("expression-or-type");
1694 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
1695 Results.AddResult(Result(Pattern));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001696 break;
1697 }
Douglas Gregord32b0222010-08-24 01:06:58 +00001698
John McCallf312b1e2010-08-26 23:41:50 +00001699 case Sema::PCC_Type:
Douglas Gregord32b0222010-08-24 01:06:58 +00001700 break;
Douglas Gregor01dfea02010-01-10 23:08:15 +00001701 }
1702
Douglas Gregor4710e5b2010-05-28 00:49:12 +00001703 if (WantTypesInContext(CCC, SemaRef.getLangOptions()))
1704 AddTypeSpecifierResults(SemaRef.getLangOptions(), Results);
Douglas Gregor01dfea02010-01-10 23:08:15 +00001705
John McCallf312b1e2010-08-26 23:41:50 +00001706 if (SemaRef.getLangOptions().CPlusPlus && CCC != Sema::PCC_Type)
Douglas Gregora4477812010-01-14 16:01:26 +00001707 Results.AddResult(Result("operator"));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001708}
1709
Douglas Gregorff5ce6e2009-12-18 18:53:37 +00001710/// \brief If the given declaration has an associated type, add it as a result
1711/// type chunk.
1712static void AddResultTypeChunk(ASTContext &Context,
1713 NamedDecl *ND,
1714 CodeCompletionString *Result) {
1715 if (!ND)
1716 return;
1717
1718 // Determine the type of the declaration (if it has a type).
1719 QualType T;
1720 if (FunctionDecl *Function = dyn_cast<FunctionDecl>(ND))
1721 T = Function->getResultType();
1722 else if (ObjCMethodDecl *Method = dyn_cast<ObjCMethodDecl>(ND))
1723 T = Method->getResultType();
1724 else if (FunctionTemplateDecl *FunTmpl = dyn_cast<FunctionTemplateDecl>(ND))
1725 T = FunTmpl->getTemplatedDecl()->getResultType();
1726 else if (EnumConstantDecl *Enumerator = dyn_cast<EnumConstantDecl>(ND))
1727 T = Context.getTypeDeclType(cast<TypeDecl>(Enumerator->getDeclContext()));
1728 else if (isa<UnresolvedUsingValueDecl>(ND)) {
1729 /* Do nothing: ignore unresolved using declarations*/
1730 } else if (ValueDecl *Value = dyn_cast<ValueDecl>(ND))
1731 T = Value->getType();
1732 else if (ObjCPropertyDecl *Property = dyn_cast<ObjCPropertyDecl>(ND))
1733 T = Property->getType();
1734
1735 if (T.isNull() || Context.hasSameType(T, Context.DependentTy))
1736 return;
1737
Douglas Gregor84139d62010-04-05 21:25:31 +00001738 PrintingPolicy Policy(Context.PrintingPolicy);
1739 Policy.AnonymousTagLocations = false;
1740
Douglas Gregorff5ce6e2009-12-18 18:53:37 +00001741 std::string TypeStr;
Douglas Gregor84139d62010-04-05 21:25:31 +00001742 T.getAsStringInternal(TypeStr, Policy);
Douglas Gregorff5ce6e2009-12-18 18:53:37 +00001743 Result->AddResultTypeChunk(TypeStr);
1744}
1745
Douglas Gregoraaa107a2010-08-23 23:51:41 +00001746static void MaybeAddSentinel(ASTContext &Context, NamedDecl *FunctionOrMethod,
1747 CodeCompletionString *Result) {
1748 if (SentinelAttr *Sentinel = FunctionOrMethod->getAttr<SentinelAttr>())
1749 if (Sentinel->getSentinel() == 0) {
1750 if (Context.getLangOptions().ObjC1 &&
1751 Context.Idents.get("nil").hasMacroDefinition())
1752 Result->AddTextChunk(", nil");
1753 else if (Context.Idents.get("NULL").hasMacroDefinition())
1754 Result->AddTextChunk(", NULL");
1755 else
1756 Result->AddTextChunk(", (void*)0");
1757 }
1758}
1759
Douglas Gregor83482d12010-08-24 16:15:59 +00001760static std::string FormatFunctionParameter(ASTContext &Context,
Douglas Gregoraba48082010-08-29 19:47:46 +00001761 ParmVarDecl *Param,
1762 bool SuppressName = false) {
Douglas Gregor83482d12010-08-24 16:15:59 +00001763 bool ObjCMethodParam = isa<ObjCMethodDecl>(Param->getDeclContext());
1764 if (Param->getType()->isDependentType() ||
1765 !Param->getType()->isBlockPointerType()) {
1766 // The argument for a dependent or non-block parameter is a placeholder
1767 // containing that parameter's type.
1768 std::string Result;
1769
Douglas Gregoraba48082010-08-29 19:47:46 +00001770 if (Param->getIdentifier() && !ObjCMethodParam && !SuppressName)
Douglas Gregor83482d12010-08-24 16:15:59 +00001771 Result = Param->getIdentifier()->getName();
1772
1773 Param->getType().getAsStringInternal(Result,
1774 Context.PrintingPolicy);
1775
1776 if (ObjCMethodParam) {
1777 Result = "(" + Result;
1778 Result += ")";
Douglas Gregoraba48082010-08-29 19:47:46 +00001779 if (Param->getIdentifier() && !SuppressName)
Douglas Gregor83482d12010-08-24 16:15:59 +00001780 Result += Param->getIdentifier()->getName();
1781 }
1782 return Result;
1783 }
1784
1785 // The argument for a block pointer parameter is a block literal with
1786 // the appropriate type.
1787 FunctionProtoTypeLoc *Block = 0;
1788 TypeLoc TL;
1789 if (TypeSourceInfo *TSInfo = Param->getTypeSourceInfo()) {
1790 TL = TSInfo->getTypeLoc().getUnqualifiedLoc();
1791 while (true) {
1792 // Look through typedefs.
1793 if (TypedefTypeLoc *TypedefTL = dyn_cast<TypedefTypeLoc>(&TL)) {
1794 if (TypeSourceInfo *InnerTSInfo
1795 = TypedefTL->getTypedefDecl()->getTypeSourceInfo()) {
1796 TL = InnerTSInfo->getTypeLoc().getUnqualifiedLoc();
1797 continue;
1798 }
1799 }
1800
1801 // Look through qualified types
1802 if (QualifiedTypeLoc *QualifiedTL = dyn_cast<QualifiedTypeLoc>(&TL)) {
1803 TL = QualifiedTL->getUnqualifiedLoc();
1804 continue;
1805 }
1806
1807 // Try to get the function prototype behind the block pointer type,
1808 // then we're done.
1809 if (BlockPointerTypeLoc *BlockPtr
1810 = dyn_cast<BlockPointerTypeLoc>(&TL)) {
1811 TL = BlockPtr->getPointeeLoc();
1812 Block = dyn_cast<FunctionProtoTypeLoc>(&TL);
1813 }
1814 break;
1815 }
1816 }
1817
1818 if (!Block) {
1819 // We were unable to find a FunctionProtoTypeLoc with parameter names
1820 // for the block; just use the parameter type as a placeholder.
1821 std::string Result;
1822 Param->getType().getUnqualifiedType().
1823 getAsStringInternal(Result, Context.PrintingPolicy);
1824
1825 if (ObjCMethodParam) {
1826 Result = "(" + Result;
1827 Result += ")";
1828 if (Param->getIdentifier())
1829 Result += Param->getIdentifier()->getName();
1830 }
1831
1832 return Result;
1833 }
1834
1835 // We have the function prototype behind the block pointer type, as it was
1836 // written in the source.
Douglas Gregor38276252010-09-08 22:47:51 +00001837 std::string Result;
1838 QualType ResultType = Block->getTypePtr()->getResultType();
1839 if (!ResultType->isVoidType())
1840 ResultType.getAsStringInternal(Result, Context.PrintingPolicy);
1841
1842 Result = '^' + Result;
1843 if (Block->getNumArgs() == 0) {
1844 if (Block->getTypePtr()->isVariadic())
1845 Result += "(...)";
1846 } else {
1847 Result += "(";
1848 for (unsigned I = 0, N = Block->getNumArgs(); I != N; ++I) {
1849 if (I)
1850 Result += ", ";
1851 Result += FormatFunctionParameter(Context, Block->getArg(I));
1852
1853 if (I == N - 1 && Block->getTypePtr()->isVariadic())
1854 Result += ", ...";
1855 }
1856 Result += ")";
Douglas Gregore17794f2010-08-31 05:13:43 +00001857 }
Douglas Gregor38276252010-09-08 22:47:51 +00001858
Douglas Gregor83482d12010-08-24 16:15:59 +00001859 return Result;
1860}
1861
Douglas Gregor86d9a522009-09-21 16:56:56 +00001862/// \brief Add function parameter chunks to the given code completion string.
1863static void AddFunctionParameterChunks(ASTContext &Context,
1864 FunctionDecl *Function,
1865 CodeCompletionString *Result) {
Douglas Gregor0c8296d2009-11-07 00:00:49 +00001866 typedef CodeCompletionString::Chunk Chunk;
1867
Douglas Gregor86d9a522009-09-21 16:56:56 +00001868 CodeCompletionString *CCStr = Result;
1869
1870 for (unsigned P = 0, N = Function->getNumParams(); P != N; ++P) {
1871 ParmVarDecl *Param = Function->getParamDecl(P);
1872
1873 if (Param->hasDefaultArg()) {
1874 // When we see an optional default argument, put that argument and
1875 // the remaining default arguments into a new, optional string.
1876 CodeCompletionString *Opt = new CodeCompletionString;
1877 CCStr->AddOptionalChunk(std::auto_ptr<CodeCompletionString>(Opt));
1878 CCStr = Opt;
1879 }
1880
1881 if (P != 0)
Douglas Gregor0c8296d2009-11-07 00:00:49 +00001882 CCStr->AddChunk(Chunk(CodeCompletionString::CK_Comma));
Douglas Gregor86d9a522009-09-21 16:56:56 +00001883
1884 // Format the placeholder string.
Douglas Gregor83482d12010-08-24 16:15:59 +00001885 std::string PlaceholderStr = FormatFunctionParameter(Context, Param);
1886
Douglas Gregore17794f2010-08-31 05:13:43 +00001887 if (Function->isVariadic() && P == N - 1)
1888 PlaceholderStr += ", ...";
1889
Douglas Gregor86d9a522009-09-21 16:56:56 +00001890 // Add the placeholder string.
Benjamin Kramer660cc182009-11-29 20:18:50 +00001891 CCStr->AddPlaceholderChunk(PlaceholderStr);
Douglas Gregor86d9a522009-09-21 16:56:56 +00001892 }
Douglas Gregorb3d45252009-09-22 21:42:17 +00001893
1894 if (const FunctionProtoType *Proto
1895 = Function->getType()->getAs<FunctionProtoType>())
Douglas Gregoraaa107a2010-08-23 23:51:41 +00001896 if (Proto->isVariadic()) {
Douglas Gregore17794f2010-08-31 05:13:43 +00001897 if (Proto->getNumArgs() == 0)
1898 CCStr->AddPlaceholderChunk("...");
Douglas Gregoraaa107a2010-08-23 23:51:41 +00001899
1900 MaybeAddSentinel(Context, Function, CCStr);
1901 }
Douglas Gregor86d9a522009-09-21 16:56:56 +00001902}
1903
1904/// \brief Add template parameter chunks to the given code completion string.
1905static void AddTemplateParameterChunks(ASTContext &Context,
1906 TemplateDecl *Template,
1907 CodeCompletionString *Result,
1908 unsigned MaxParameters = 0) {
Douglas Gregor0c8296d2009-11-07 00:00:49 +00001909 typedef CodeCompletionString::Chunk Chunk;
1910
Douglas Gregor86d9a522009-09-21 16:56:56 +00001911 CodeCompletionString *CCStr = Result;
1912 bool FirstParameter = true;
1913
1914 TemplateParameterList *Params = Template->getTemplateParameters();
1915 TemplateParameterList::iterator PEnd = Params->end();
1916 if (MaxParameters)
1917 PEnd = Params->begin() + MaxParameters;
1918 for (TemplateParameterList::iterator P = Params->begin(); P != PEnd; ++P) {
1919 bool HasDefaultArg = false;
1920 std::string PlaceholderStr;
1921 if (TemplateTypeParmDecl *TTP = dyn_cast<TemplateTypeParmDecl>(*P)) {
1922 if (TTP->wasDeclaredWithTypename())
1923 PlaceholderStr = "typename";
1924 else
1925 PlaceholderStr = "class";
1926
1927 if (TTP->getIdentifier()) {
1928 PlaceholderStr += ' ';
1929 PlaceholderStr += TTP->getIdentifier()->getName();
1930 }
1931
1932 HasDefaultArg = TTP->hasDefaultArgument();
1933 } else if (NonTypeTemplateParmDecl *NTTP
1934 = dyn_cast<NonTypeTemplateParmDecl>(*P)) {
1935 if (NTTP->getIdentifier())
1936 PlaceholderStr = NTTP->getIdentifier()->getName();
1937 NTTP->getType().getAsStringInternal(PlaceholderStr,
1938 Context.PrintingPolicy);
1939 HasDefaultArg = NTTP->hasDefaultArgument();
1940 } else {
1941 assert(isa<TemplateTemplateParmDecl>(*P));
1942 TemplateTemplateParmDecl *TTP = cast<TemplateTemplateParmDecl>(*P);
1943
1944 // Since putting the template argument list into the placeholder would
1945 // be very, very long, we just use an abbreviation.
1946 PlaceholderStr = "template<...> class";
1947 if (TTP->getIdentifier()) {
1948 PlaceholderStr += ' ';
1949 PlaceholderStr += TTP->getIdentifier()->getName();
1950 }
1951
1952 HasDefaultArg = TTP->hasDefaultArgument();
1953 }
1954
1955 if (HasDefaultArg) {
1956 // When we see an optional default argument, put that argument and
1957 // the remaining default arguments into a new, optional string.
1958 CodeCompletionString *Opt = new CodeCompletionString;
1959 CCStr->AddOptionalChunk(std::auto_ptr<CodeCompletionString>(Opt));
1960 CCStr = Opt;
1961 }
1962
1963 if (FirstParameter)
1964 FirstParameter = false;
1965 else
Douglas Gregor0c8296d2009-11-07 00:00:49 +00001966 CCStr->AddChunk(Chunk(CodeCompletionString::CK_Comma));
Douglas Gregor86d9a522009-09-21 16:56:56 +00001967
1968 // Add the placeholder string.
Benjamin Kramer660cc182009-11-29 20:18:50 +00001969 CCStr->AddPlaceholderChunk(PlaceholderStr);
Douglas Gregor86d9a522009-09-21 16:56:56 +00001970 }
1971}
1972
Douglas Gregorb9d0ef72009-09-21 19:57:38 +00001973/// \brief Add a qualifier to the given code-completion string, if the
1974/// provided nested-name-specifier is non-NULL.
Douglas Gregora61a8792009-12-11 18:44:16 +00001975static void
1976AddQualifierToCompletionString(CodeCompletionString *Result,
1977 NestedNameSpecifier *Qualifier,
1978 bool QualifierIsInformative,
1979 ASTContext &Context) {
Douglas Gregorb9d0ef72009-09-21 19:57:38 +00001980 if (!Qualifier)
1981 return;
1982
1983 std::string PrintedNNS;
1984 {
1985 llvm::raw_string_ostream OS(PrintedNNS);
1986 Qualifier->print(OS, Context.PrintingPolicy);
1987 }
Douglas Gregor0563c262009-09-22 23:15:58 +00001988 if (QualifierIsInformative)
Benjamin Kramer660cc182009-11-29 20:18:50 +00001989 Result->AddInformativeChunk(PrintedNNS);
Douglas Gregor0563c262009-09-22 23:15:58 +00001990 else
Benjamin Kramer660cc182009-11-29 20:18:50 +00001991 Result->AddTextChunk(PrintedNNS);
Douglas Gregorb9d0ef72009-09-21 19:57:38 +00001992}
1993
Douglas Gregora61a8792009-12-11 18:44:16 +00001994static void AddFunctionTypeQualsToCompletionString(CodeCompletionString *Result,
1995 FunctionDecl *Function) {
1996 const FunctionProtoType *Proto
1997 = Function->getType()->getAs<FunctionProtoType>();
1998 if (!Proto || !Proto->getTypeQuals())
1999 return;
2000
2001 std::string QualsStr;
2002 if (Proto->getTypeQuals() & Qualifiers::Const)
2003 QualsStr += " const";
2004 if (Proto->getTypeQuals() & Qualifiers::Volatile)
2005 QualsStr += " volatile";
2006 if (Proto->getTypeQuals() & Qualifiers::Restrict)
2007 QualsStr += " restrict";
2008 Result->AddInformativeChunk(QualsStr);
2009}
2010
Douglas Gregor86d9a522009-09-21 16:56:56 +00002011/// \brief If possible, create a new code completion string for the given
2012/// result.
2013///
2014/// \returns Either a new, heap-allocated code completion string describing
2015/// how to use this result, or NULL to indicate that the string or name of the
2016/// result is all that is needed.
2017CodeCompletionString *
John McCall0a2c5e22010-08-25 06:19:51 +00002018CodeCompletionResult::CreateCodeCompletionString(Sema &S,
Douglas Gregor1abc6bc2010-08-04 16:47:14 +00002019 CodeCompletionString *Result) {
Douglas Gregor0c8296d2009-11-07 00:00:49 +00002020 typedef CodeCompletionString::Chunk Chunk;
2021
Douglas Gregor2b4074f2009-12-01 05:55:20 +00002022 if (Kind == RK_Pattern)
Douglas Gregor1abc6bc2010-08-04 16:47:14 +00002023 return Pattern->Clone(Result);
Douglas Gregor2b4074f2009-12-01 05:55:20 +00002024
Douglas Gregor1abc6bc2010-08-04 16:47:14 +00002025 if (!Result)
2026 Result = new CodeCompletionString;
Douglas Gregor2b4074f2009-12-01 05:55:20 +00002027
2028 if (Kind == RK_Keyword) {
2029 Result->AddTypedTextChunk(Keyword);
2030 return Result;
2031 }
Douglas Gregor86d9a522009-09-21 16:56:56 +00002032
Douglas Gregor3f7c7f42009-10-30 16:50:04 +00002033 if (Kind == RK_Macro) {
2034 MacroInfo *MI = S.PP.getMacroInfo(Macro);
Douglas Gregor2b4074f2009-12-01 05:55:20 +00002035 assert(MI && "Not a macro?");
2036
2037 Result->AddTypedTextChunk(Macro->getName());
2038
2039 if (!MI->isFunctionLike())
2040 return Result;
Douglas Gregor3f7c7f42009-10-30 16:50:04 +00002041
2042 // Format a function-like macro with placeholders for the arguments.
Douglas Gregor0c8296d2009-11-07 00:00:49 +00002043 Result->AddChunk(Chunk(CodeCompletionString::CK_LeftParen));
Douglas Gregor3f7c7f42009-10-30 16:50:04 +00002044 for (MacroInfo::arg_iterator A = MI->arg_begin(), AEnd = MI->arg_end();
2045 A != AEnd; ++A) {
2046 if (A != MI->arg_begin())
Douglas Gregor0c8296d2009-11-07 00:00:49 +00002047 Result->AddChunk(Chunk(CodeCompletionString::CK_Comma));
Douglas Gregor3f7c7f42009-10-30 16:50:04 +00002048
2049 if (!MI->isVariadic() || A != AEnd - 1) {
2050 // Non-variadic argument.
Benjamin Kramer660cc182009-11-29 20:18:50 +00002051 Result->AddPlaceholderChunk((*A)->getName());
Douglas Gregor3f7c7f42009-10-30 16:50:04 +00002052 continue;
2053 }
2054
2055 // Variadic argument; cope with the different between GNU and C99
2056 // variadic macros, providing a single placeholder for the rest of the
2057 // arguments.
2058 if ((*A)->isStr("__VA_ARGS__"))
2059 Result->AddPlaceholderChunk("...");
2060 else {
2061 std::string Arg = (*A)->getName();
2062 Arg += "...";
Benjamin Kramer660cc182009-11-29 20:18:50 +00002063 Result->AddPlaceholderChunk(Arg);
Douglas Gregor3f7c7f42009-10-30 16:50:04 +00002064 }
2065 }
Douglas Gregor0c8296d2009-11-07 00:00:49 +00002066 Result->AddChunk(Chunk(CodeCompletionString::CK_RightParen));
Douglas Gregor3f7c7f42009-10-30 16:50:04 +00002067 return Result;
2068 }
2069
Douglas Gregord8e8a582010-05-25 21:41:55 +00002070 assert(Kind == RK_Declaration && "Missed a result kind?");
Douglas Gregor86d9a522009-09-21 16:56:56 +00002071 NamedDecl *ND = Declaration;
2072
Douglas Gregor0c8296d2009-11-07 00:00:49 +00002073 if (StartsNestedNameSpecifier) {
Benjamin Kramer660cc182009-11-29 20:18:50 +00002074 Result->AddTypedTextChunk(ND->getNameAsString());
Douglas Gregor0c8296d2009-11-07 00:00:49 +00002075 Result->AddTextChunk("::");
2076 return Result;
2077 }
2078
Douglas Gregorff5ce6e2009-12-18 18:53:37 +00002079 AddResultTypeChunk(S.Context, ND, Result);
2080
Douglas Gregor86d9a522009-09-21 16:56:56 +00002081 if (FunctionDecl *Function = dyn_cast<FunctionDecl>(ND)) {
Douglas Gregor0563c262009-09-22 23:15:58 +00002082 AddQualifierToCompletionString(Result, Qualifier, QualifierIsInformative,
2083 S.Context);
Benjamin Kramer660cc182009-11-29 20:18:50 +00002084 Result->AddTypedTextChunk(Function->getNameAsString());
Douglas Gregor0c8296d2009-11-07 00:00:49 +00002085 Result->AddChunk(Chunk(CodeCompletionString::CK_LeftParen));
Douglas Gregor86d9a522009-09-21 16:56:56 +00002086 AddFunctionParameterChunks(S.Context, Function, Result);
Douglas Gregor0c8296d2009-11-07 00:00:49 +00002087 Result->AddChunk(Chunk(CodeCompletionString::CK_RightParen));
Douglas Gregora61a8792009-12-11 18:44:16 +00002088 AddFunctionTypeQualsToCompletionString(Result, Function);
Douglas Gregor86d9a522009-09-21 16:56:56 +00002089 return Result;
2090 }
2091
2092 if (FunctionTemplateDecl *FunTmpl = dyn_cast<FunctionTemplateDecl>(ND)) {
Douglas Gregor0563c262009-09-22 23:15:58 +00002093 AddQualifierToCompletionString(Result, Qualifier, QualifierIsInformative,
2094 S.Context);
Douglas Gregor86d9a522009-09-21 16:56:56 +00002095 FunctionDecl *Function = FunTmpl->getTemplatedDecl();
Benjamin Kramer660cc182009-11-29 20:18:50 +00002096 Result->AddTypedTextChunk(Function->getNameAsString());
Douglas Gregor86d9a522009-09-21 16:56:56 +00002097
2098 // Figure out which template parameters are deduced (or have default
2099 // arguments).
2100 llvm::SmallVector<bool, 16> Deduced;
2101 S.MarkDeducedTemplateParameters(FunTmpl, Deduced);
2102 unsigned LastDeducibleArgument;
2103 for (LastDeducibleArgument = Deduced.size(); LastDeducibleArgument > 0;
2104 --LastDeducibleArgument) {
2105 if (!Deduced[LastDeducibleArgument - 1]) {
2106 // C++0x: Figure out if the template argument has a default. If so,
2107 // the user doesn't need to type this argument.
2108 // FIXME: We need to abstract template parameters better!
2109 bool HasDefaultArg = false;
2110 NamedDecl *Param = FunTmpl->getTemplateParameters()->getParam(
2111 LastDeducibleArgument - 1);
2112 if (TemplateTypeParmDecl *TTP = dyn_cast<TemplateTypeParmDecl>(Param))
2113 HasDefaultArg = TTP->hasDefaultArgument();
2114 else if (NonTypeTemplateParmDecl *NTTP
2115 = dyn_cast<NonTypeTemplateParmDecl>(Param))
2116 HasDefaultArg = NTTP->hasDefaultArgument();
2117 else {
2118 assert(isa<TemplateTemplateParmDecl>(Param));
2119 HasDefaultArg
Douglas Gregor0c8296d2009-11-07 00:00:49 +00002120 = cast<TemplateTemplateParmDecl>(Param)->hasDefaultArgument();
Douglas Gregor86d9a522009-09-21 16:56:56 +00002121 }
2122
2123 if (!HasDefaultArg)
2124 break;
2125 }
2126 }
2127
2128 if (LastDeducibleArgument) {
2129 // Some of the function template arguments cannot be deduced from a
2130 // function call, so we introduce an explicit template argument list
2131 // containing all of the arguments up to the first deducible argument.
Douglas Gregor0c8296d2009-11-07 00:00:49 +00002132 Result->AddChunk(Chunk(CodeCompletionString::CK_LeftAngle));
Douglas Gregor86d9a522009-09-21 16:56:56 +00002133 AddTemplateParameterChunks(S.Context, FunTmpl, Result,
2134 LastDeducibleArgument);
Douglas Gregor0c8296d2009-11-07 00:00:49 +00002135 Result->AddChunk(Chunk(CodeCompletionString::CK_RightAngle));
Douglas Gregor86d9a522009-09-21 16:56:56 +00002136 }
2137
2138 // Add the function parameters
Douglas Gregor0c8296d2009-11-07 00:00:49 +00002139 Result->AddChunk(Chunk(CodeCompletionString::CK_LeftParen));
Douglas Gregor86d9a522009-09-21 16:56:56 +00002140 AddFunctionParameterChunks(S.Context, Function, Result);
Douglas Gregor0c8296d2009-11-07 00:00:49 +00002141 Result->AddChunk(Chunk(CodeCompletionString::CK_RightParen));
Douglas Gregora61a8792009-12-11 18:44:16 +00002142 AddFunctionTypeQualsToCompletionString(Result, Function);
Douglas Gregor86d9a522009-09-21 16:56:56 +00002143 return Result;
2144 }
2145
2146 if (TemplateDecl *Template = dyn_cast<TemplateDecl>(ND)) {
Douglas Gregor0563c262009-09-22 23:15:58 +00002147 AddQualifierToCompletionString(Result, Qualifier, QualifierIsInformative,
2148 S.Context);
Benjamin Kramer660cc182009-11-29 20:18:50 +00002149 Result->AddTypedTextChunk(Template->getNameAsString());
Douglas Gregor0c8296d2009-11-07 00:00:49 +00002150 Result->AddChunk(Chunk(CodeCompletionString::CK_LeftAngle));
Douglas Gregor86d9a522009-09-21 16:56:56 +00002151 AddTemplateParameterChunks(S.Context, Template, Result);
Douglas Gregor0c8296d2009-11-07 00:00:49 +00002152 Result->AddChunk(Chunk(CodeCompletionString::CK_RightAngle));
Douglas Gregor86d9a522009-09-21 16:56:56 +00002153 return Result;
2154 }
2155
Douglas Gregor9630eb62009-11-17 16:44:22 +00002156 if (ObjCMethodDecl *Method = dyn_cast<ObjCMethodDecl>(ND)) {
Douglas Gregor9630eb62009-11-17 16:44:22 +00002157 Selector Sel = Method->getSelector();
2158 if (Sel.isUnarySelector()) {
2159 Result->AddTypedTextChunk(Sel.getIdentifierInfoForSlot(0)->getName());
2160 return Result;
2161 }
2162
Douglas Gregord3c68542009-11-19 01:08:35 +00002163 std::string SelName = Sel.getIdentifierInfoForSlot(0)->getName().str();
2164 SelName += ':';
2165 if (StartParameter == 0)
2166 Result->AddTypedTextChunk(SelName);
2167 else {
2168 Result->AddInformativeChunk(SelName);
2169
2170 // If there is only one parameter, and we're past it, add an empty
2171 // typed-text chunk since there is nothing to type.
2172 if (Method->param_size() == 1)
2173 Result->AddTypedTextChunk("");
2174 }
Douglas Gregor9630eb62009-11-17 16:44:22 +00002175 unsigned Idx = 0;
2176 for (ObjCMethodDecl::param_iterator P = Method->param_begin(),
2177 PEnd = Method->param_end();
2178 P != PEnd; (void)++P, ++Idx) {
2179 if (Idx > 0) {
Douglas Gregord3c68542009-11-19 01:08:35 +00002180 std::string Keyword;
2181 if (Idx > StartParameter)
Douglas Gregor834389b2010-01-12 06:38:28 +00002182 Result->AddChunk(CodeCompletionString::CK_HorizontalSpace);
Douglas Gregor9630eb62009-11-17 16:44:22 +00002183 if (IdentifierInfo *II = Sel.getIdentifierInfoForSlot(Idx))
2184 Keyword += II->getName().str();
2185 Keyword += ":";
Douglas Gregor1f5537a2010-07-08 23:20:03 +00002186 if (Idx < StartParameter || AllParametersAreInformative)
Douglas Gregord3c68542009-11-19 01:08:35 +00002187 Result->AddInformativeChunk(Keyword);
Douglas Gregor1f5537a2010-07-08 23:20:03 +00002188 else if (Idx == StartParameter)
Douglas Gregord3c68542009-11-19 01:08:35 +00002189 Result->AddTypedTextChunk(Keyword);
2190 else
2191 Result->AddTextChunk(Keyword);
Douglas Gregor9630eb62009-11-17 16:44:22 +00002192 }
Douglas Gregord3c68542009-11-19 01:08:35 +00002193
2194 // If we're before the starting parameter, skip the placeholder.
2195 if (Idx < StartParameter)
2196 continue;
Douglas Gregor9630eb62009-11-17 16:44:22 +00002197
2198 std::string Arg;
Douglas Gregor83482d12010-08-24 16:15:59 +00002199
2200 if ((*P)->getType()->isBlockPointerType() && !DeclaringEntity)
Douglas Gregoraba48082010-08-29 19:47:46 +00002201 Arg = FormatFunctionParameter(S.Context, *P, true);
Douglas Gregor83482d12010-08-24 16:15:59 +00002202 else {
2203 (*P)->getType().getAsStringInternal(Arg, S.Context.PrintingPolicy);
2204 Arg = "(" + Arg + ")";
2205 if (IdentifierInfo *II = (*P)->getIdentifier())
Douglas Gregoraba48082010-08-29 19:47:46 +00002206 if (DeclaringEntity || AllParametersAreInformative)
2207 Arg += II->getName().str();
Douglas Gregor83482d12010-08-24 16:15:59 +00002208 }
2209
Douglas Gregore17794f2010-08-31 05:13:43 +00002210 if (Method->isVariadic() && (P + 1) == PEnd)
2211 Arg += ", ...";
2212
Douglas Gregor1f5537a2010-07-08 23:20:03 +00002213 if (DeclaringEntity)
2214 Result->AddTextChunk(Arg);
2215 else if (AllParametersAreInformative)
Douglas Gregor4ad96852009-11-19 07:41:15 +00002216 Result->AddInformativeChunk(Arg);
2217 else
2218 Result->AddPlaceholderChunk(Arg);
Douglas Gregor9630eb62009-11-17 16:44:22 +00002219 }
2220
Douglas Gregor2a17af02009-12-23 00:21:46 +00002221 if (Method->isVariadic()) {
Douglas Gregore17794f2010-08-31 05:13:43 +00002222 if (Method->param_size() == 0) {
2223 if (DeclaringEntity)
2224 Result->AddTextChunk(", ...");
2225 else if (AllParametersAreInformative)
2226 Result->AddInformativeChunk(", ...");
2227 else
2228 Result->AddPlaceholderChunk(", ...");
2229 }
Douglas Gregoraaa107a2010-08-23 23:51:41 +00002230
2231 MaybeAddSentinel(S.Context, Method, Result);
Douglas Gregor2a17af02009-12-23 00:21:46 +00002232 }
2233
Douglas Gregor9630eb62009-11-17 16:44:22 +00002234 return Result;
2235 }
2236
Douglas Gregor2b4074f2009-12-01 05:55:20 +00002237 if (Qualifier)
Douglas Gregor0563c262009-09-22 23:15:58 +00002238 AddQualifierToCompletionString(Result, Qualifier, QualifierIsInformative,
2239 S.Context);
Douglas Gregor2b4074f2009-12-01 05:55:20 +00002240
2241 Result->AddTypedTextChunk(ND->getNameAsString());
2242 return Result;
Douglas Gregor86d9a522009-09-21 16:56:56 +00002243}
2244
Douglas Gregor86d802e2009-09-23 00:34:09 +00002245CodeCompletionString *
2246CodeCompleteConsumer::OverloadCandidate::CreateSignatureString(
2247 unsigned CurrentArg,
2248 Sema &S) const {
Douglas Gregor0c8296d2009-11-07 00:00:49 +00002249 typedef CodeCompletionString::Chunk Chunk;
2250
Douglas Gregor86d802e2009-09-23 00:34:09 +00002251 CodeCompletionString *Result = new CodeCompletionString;
2252 FunctionDecl *FDecl = getFunction();
Douglas Gregorff5ce6e2009-12-18 18:53:37 +00002253 AddResultTypeChunk(S.Context, FDecl, Result);
Douglas Gregor86d802e2009-09-23 00:34:09 +00002254 const FunctionProtoType *Proto
2255 = dyn_cast<FunctionProtoType>(getFunctionType());
2256 if (!FDecl && !Proto) {
2257 // Function without a prototype. Just give the return type and a
2258 // highlighted ellipsis.
2259 const FunctionType *FT = getFunctionType();
2260 Result->AddTextChunk(
Benjamin Kramer660cc182009-11-29 20:18:50 +00002261 FT->getResultType().getAsString(S.Context.PrintingPolicy));
Douglas Gregor0c8296d2009-11-07 00:00:49 +00002262 Result->AddChunk(Chunk(CodeCompletionString::CK_LeftParen));
2263 Result->AddChunk(Chunk(CodeCompletionString::CK_CurrentParameter, "..."));
2264 Result->AddChunk(Chunk(CodeCompletionString::CK_RightParen));
Douglas Gregor86d802e2009-09-23 00:34:09 +00002265 return Result;
2266 }
2267
2268 if (FDecl)
Benjamin Kramer660cc182009-11-29 20:18:50 +00002269 Result->AddTextChunk(FDecl->getNameAsString());
Douglas Gregor86d802e2009-09-23 00:34:09 +00002270 else
2271 Result->AddTextChunk(
Benjamin Kramer660cc182009-11-29 20:18:50 +00002272 Proto->getResultType().getAsString(S.Context.PrintingPolicy));
Douglas Gregor86d802e2009-09-23 00:34:09 +00002273
Douglas Gregor0c8296d2009-11-07 00:00:49 +00002274 Result->AddChunk(Chunk(CodeCompletionString::CK_LeftParen));
Douglas Gregor86d802e2009-09-23 00:34:09 +00002275 unsigned NumParams = FDecl? FDecl->getNumParams() : Proto->getNumArgs();
2276 for (unsigned I = 0; I != NumParams; ++I) {
2277 if (I)
Douglas Gregor0c8296d2009-11-07 00:00:49 +00002278 Result->AddChunk(Chunk(CodeCompletionString::CK_Comma));
Douglas Gregor86d802e2009-09-23 00:34:09 +00002279
2280 std::string ArgString;
2281 QualType ArgType;
2282
2283 if (FDecl) {
2284 ArgString = FDecl->getParamDecl(I)->getNameAsString();
2285 ArgType = FDecl->getParamDecl(I)->getOriginalType();
2286 } else {
2287 ArgType = Proto->getArgType(I);
2288 }
2289
2290 ArgType.getAsStringInternal(ArgString, S.Context.PrintingPolicy);
2291
2292 if (I == CurrentArg)
Douglas Gregor0c8296d2009-11-07 00:00:49 +00002293 Result->AddChunk(Chunk(CodeCompletionString::CK_CurrentParameter,
Benjamin Kramer660cc182009-11-29 20:18:50 +00002294 ArgString));
Douglas Gregor86d802e2009-09-23 00:34:09 +00002295 else
Benjamin Kramer660cc182009-11-29 20:18:50 +00002296 Result->AddTextChunk(ArgString);
Douglas Gregor86d802e2009-09-23 00:34:09 +00002297 }
2298
2299 if (Proto && Proto->isVariadic()) {
Douglas Gregor0c8296d2009-11-07 00:00:49 +00002300 Result->AddChunk(Chunk(CodeCompletionString::CK_Comma));
Douglas Gregor86d802e2009-09-23 00:34:09 +00002301 if (CurrentArg < NumParams)
2302 Result->AddTextChunk("...");
2303 else
Douglas Gregor0c8296d2009-11-07 00:00:49 +00002304 Result->AddChunk(Chunk(CodeCompletionString::CK_CurrentParameter, "..."));
Douglas Gregor86d802e2009-09-23 00:34:09 +00002305 }
Douglas Gregor0c8296d2009-11-07 00:00:49 +00002306 Result->AddChunk(Chunk(CodeCompletionString::CK_RightParen));
Douglas Gregor86d802e2009-09-23 00:34:09 +00002307
2308 return Result;
2309}
2310
Douglas Gregor1827e102010-08-16 16:18:59 +00002311unsigned clang::getMacroUsagePriority(llvm::StringRef MacroName,
Douglas Gregorb05496d2010-09-20 21:11:48 +00002312 const LangOptions &LangOpts,
Douglas Gregor1827e102010-08-16 16:18:59 +00002313 bool PreferredTypeIsPointer) {
2314 unsigned Priority = CCP_Macro;
2315
Douglas Gregorb05496d2010-09-20 21:11:48 +00002316 // Treat the "nil", "Nil" and "NULL" macros as null pointer constants.
2317 if (MacroName.equals("nil") || MacroName.equals("NULL") ||
2318 MacroName.equals("Nil")) {
Douglas Gregor1827e102010-08-16 16:18:59 +00002319 Priority = CCP_Constant;
2320 if (PreferredTypeIsPointer)
2321 Priority = Priority / CCF_SimilarTypeMatch;
Douglas Gregorb05496d2010-09-20 21:11:48 +00002322 }
2323 // Treat "YES", "NO", "true", and "false" as constants.
2324 else if (MacroName.equals("YES") || MacroName.equals("NO") ||
2325 MacroName.equals("true") || MacroName.equals("false"))
2326 Priority = CCP_Constant;
2327 // Treat "bool" as a type.
2328 else if (MacroName.equals("bool"))
2329 Priority = CCP_Type + (LangOpts.ObjC1? CCD_bool_in_ObjC : 0);
2330
Douglas Gregor1827e102010-08-16 16:18:59 +00002331
2332 return Priority;
2333}
2334
Douglas Gregore8d7beb2010-09-03 23:30:36 +00002335CXCursorKind clang::getCursorKindForDecl(Decl *D) {
2336 if (!D)
2337 return CXCursor_UnexposedDecl;
2338
2339 switch (D->getKind()) {
2340 case Decl::Enum: return CXCursor_EnumDecl;
2341 case Decl::EnumConstant: return CXCursor_EnumConstantDecl;
2342 case Decl::Field: return CXCursor_FieldDecl;
2343 case Decl::Function:
2344 return CXCursor_FunctionDecl;
2345 case Decl::ObjCCategory: return CXCursor_ObjCCategoryDecl;
2346 case Decl::ObjCCategoryImpl: return CXCursor_ObjCCategoryImplDecl;
2347 case Decl::ObjCClass:
2348 // FIXME
2349 return CXCursor_UnexposedDecl;
2350 case Decl::ObjCForwardProtocol:
2351 // FIXME
2352 return CXCursor_UnexposedDecl;
2353 case Decl::ObjCImplementation: return CXCursor_ObjCImplementationDecl;
2354 case Decl::ObjCInterface: return CXCursor_ObjCInterfaceDecl;
2355 case Decl::ObjCIvar: return CXCursor_ObjCIvarDecl;
2356 case Decl::ObjCMethod:
2357 return cast<ObjCMethodDecl>(D)->isInstanceMethod()
2358 ? CXCursor_ObjCInstanceMethodDecl : CXCursor_ObjCClassMethodDecl;
2359 case Decl::CXXMethod: return CXCursor_CXXMethod;
2360 case Decl::CXXConstructor: return CXCursor_Constructor;
2361 case Decl::CXXDestructor: return CXCursor_Destructor;
2362 case Decl::CXXConversion: return CXCursor_ConversionFunction;
2363 case Decl::ObjCProperty: return CXCursor_ObjCPropertyDecl;
2364 case Decl::ObjCProtocol: return CXCursor_ObjCProtocolDecl;
2365 case Decl::ParmVar: return CXCursor_ParmDecl;
2366 case Decl::Typedef: return CXCursor_TypedefDecl;
2367 case Decl::Var: return CXCursor_VarDecl;
2368 case Decl::Namespace: return CXCursor_Namespace;
2369 case Decl::NamespaceAlias: return CXCursor_NamespaceAlias;
2370 case Decl::TemplateTypeParm: return CXCursor_TemplateTypeParameter;
2371 case Decl::NonTypeTemplateParm:return CXCursor_NonTypeTemplateParameter;
2372 case Decl::TemplateTemplateParm:return CXCursor_TemplateTemplateParameter;
2373 case Decl::FunctionTemplate: return CXCursor_FunctionTemplate;
2374 case Decl::ClassTemplate: return CXCursor_ClassTemplate;
2375 case Decl::ClassTemplatePartialSpecialization:
2376 return CXCursor_ClassTemplatePartialSpecialization;
2377 case Decl::UsingDirective: return CXCursor_UsingDirective;
2378
2379 case Decl::Using:
2380 case Decl::UnresolvedUsingValue:
2381 case Decl::UnresolvedUsingTypename:
2382 return CXCursor_UsingDeclaration;
2383
2384 default:
2385 if (TagDecl *TD = dyn_cast<TagDecl>(D)) {
2386 switch (TD->getTagKind()) {
2387 case TTK_Struct: return CXCursor_StructDecl;
2388 case TTK_Class: return CXCursor_ClassDecl;
2389 case TTK_Union: return CXCursor_UnionDecl;
2390 case TTK_Enum: return CXCursor_EnumDecl;
2391 }
2392 }
2393 }
2394
2395 return CXCursor_UnexposedDecl;
2396}
2397
Douglas Gregor590c7d52010-07-08 20:55:51 +00002398static void AddMacroResults(Preprocessor &PP, ResultBuilder &Results,
2399 bool TargetTypeIsPointer = false) {
John McCall0a2c5e22010-08-25 06:19:51 +00002400 typedef CodeCompletionResult Result;
Douglas Gregor590c7d52010-07-08 20:55:51 +00002401
Douglas Gregor3f7c7f42009-10-30 16:50:04 +00002402 Results.EnterNewScope();
Douglas Gregor0c8296d2009-11-07 00:00:49 +00002403 for (Preprocessor::macro_iterator M = PP.macro_begin(),
2404 MEnd = PP.macro_end();
Douglas Gregor590c7d52010-07-08 20:55:51 +00002405 M != MEnd; ++M) {
Douglas Gregor1827e102010-08-16 16:18:59 +00002406 Results.AddResult(Result(M->first,
2407 getMacroUsagePriority(M->first->getName(),
Douglas Gregorb05496d2010-09-20 21:11:48 +00002408 PP.getLangOptions(),
Douglas Gregor1827e102010-08-16 16:18:59 +00002409 TargetTypeIsPointer)));
Douglas Gregor590c7d52010-07-08 20:55:51 +00002410 }
Douglas Gregor3f7c7f42009-10-30 16:50:04 +00002411 Results.ExitScope();
2412}
2413
Douglas Gregoraa5f77b2010-08-23 21:54:33 +00002414static void AddPrettyFunctionResults(const LangOptions &LangOpts,
2415 ResultBuilder &Results) {
John McCall0a2c5e22010-08-25 06:19:51 +00002416 typedef CodeCompletionResult Result;
Douglas Gregoraa5f77b2010-08-23 21:54:33 +00002417
2418 Results.EnterNewScope();
2419 Results.AddResult(Result("__PRETTY_FUNCTION__", CCP_Constant));
2420 Results.AddResult(Result("__FUNCTION__", CCP_Constant));
2421 if (LangOpts.C99 || LangOpts.CPlusPlus0x)
2422 Results.AddResult(Result("__func__", CCP_Constant));
2423 Results.ExitScope();
2424}
2425
Daniel Dunbar3a2838d2009-11-13 08:58:20 +00002426static void HandleCodeCompleteResults(Sema *S,
2427 CodeCompleteConsumer *CodeCompleter,
Douglas Gregore6b1bb62010-08-11 21:23:17 +00002428 CodeCompletionContext Context,
John McCall0a2c5e22010-08-25 06:19:51 +00002429 CodeCompletionResult *Results,
Douglas Gregore6b1bb62010-08-11 21:23:17 +00002430 unsigned NumResults) {
Douglas Gregor86d9a522009-09-21 16:56:56 +00002431 if (CodeCompleter)
Douglas Gregore6b1bb62010-08-11 21:23:17 +00002432 CodeCompleter->ProcessCodeCompleteResults(*S, Context, Results, NumResults);
Douglas Gregor54f01612009-11-19 00:01:57 +00002433
2434 for (unsigned I = 0; I != NumResults; ++I)
2435 Results[I].Destroy();
Douglas Gregor86d9a522009-09-21 16:56:56 +00002436}
2437
Douglas Gregore6b1bb62010-08-11 21:23:17 +00002438static enum CodeCompletionContext::Kind mapCodeCompletionContext(Sema &S,
2439 Sema::ParserCompletionContext PCC) {
2440 switch (PCC) {
John McCallf312b1e2010-08-26 23:41:50 +00002441 case Sema::PCC_Namespace:
Douglas Gregore6b1bb62010-08-11 21:23:17 +00002442 return CodeCompletionContext::CCC_TopLevel;
2443
John McCallf312b1e2010-08-26 23:41:50 +00002444 case Sema::PCC_Class:
Douglas Gregore6b1bb62010-08-11 21:23:17 +00002445 return CodeCompletionContext::CCC_ClassStructUnion;
2446
John McCallf312b1e2010-08-26 23:41:50 +00002447 case Sema::PCC_ObjCInterface:
Douglas Gregore6b1bb62010-08-11 21:23:17 +00002448 return CodeCompletionContext::CCC_ObjCInterface;
2449
John McCallf312b1e2010-08-26 23:41:50 +00002450 case Sema::PCC_ObjCImplementation:
Douglas Gregore6b1bb62010-08-11 21:23:17 +00002451 return CodeCompletionContext::CCC_ObjCImplementation;
2452
John McCallf312b1e2010-08-26 23:41:50 +00002453 case Sema::PCC_ObjCInstanceVariableList:
Douglas Gregore6b1bb62010-08-11 21:23:17 +00002454 return CodeCompletionContext::CCC_ObjCIvarList;
2455
John McCallf312b1e2010-08-26 23:41:50 +00002456 case Sema::PCC_Template:
2457 case Sema::PCC_MemberTemplate:
2458 case Sema::PCC_RecoveryInFunction:
Douglas Gregore6b1bb62010-08-11 21:23:17 +00002459 return CodeCompletionContext::CCC_Other;
2460
John McCallf312b1e2010-08-26 23:41:50 +00002461 case Sema::PCC_Expression:
2462 case Sema::PCC_ForInit:
2463 case Sema::PCC_Condition:
Douglas Gregore6b1bb62010-08-11 21:23:17 +00002464 return CodeCompletionContext::CCC_Expression;
2465
John McCallf312b1e2010-08-26 23:41:50 +00002466 case Sema::PCC_Statement:
Douglas Gregore6b1bb62010-08-11 21:23:17 +00002467 return CodeCompletionContext::CCC_Statement;
Douglas Gregor72db1082010-08-24 01:11:00 +00002468
John McCallf312b1e2010-08-26 23:41:50 +00002469 case Sema::PCC_Type:
Douglas Gregor72db1082010-08-24 01:11:00 +00002470 return CodeCompletionContext::CCC_Type;
Douglas Gregor02688102010-09-14 23:59:36 +00002471
2472 case Sema::PCC_ParenthesizedExpression:
2473 return CodeCompletionContext::CCC_ParenthesizedExpression;
Douglas Gregore6b1bb62010-08-11 21:23:17 +00002474 }
2475
2476 return CodeCompletionContext::CCC_Other;
2477}
2478
Douglas Gregorf6961522010-08-27 21:18:54 +00002479/// \brief If we're in a C++ virtual member function, add completion results
2480/// that invoke the functions we override, since it's common to invoke the
2481/// overridden function as well as adding new functionality.
2482///
2483/// \param S The semantic analysis object for which we are generating results.
2484///
2485/// \param InContext This context in which the nested-name-specifier preceding
2486/// the code-completion point
2487static void MaybeAddOverrideCalls(Sema &S, DeclContext *InContext,
2488 ResultBuilder &Results) {
2489 // Look through blocks.
2490 DeclContext *CurContext = S.CurContext;
2491 while (isa<BlockDecl>(CurContext))
2492 CurContext = CurContext->getParent();
2493
2494
2495 CXXMethodDecl *Method = dyn_cast<CXXMethodDecl>(CurContext);
2496 if (!Method || !Method->isVirtual())
2497 return;
2498
2499 // We need to have names for all of the parameters, if we're going to
2500 // generate a forwarding call.
2501 for (CXXMethodDecl::param_iterator P = Method->param_begin(),
2502 PEnd = Method->param_end();
2503 P != PEnd;
2504 ++P) {
2505 if (!(*P)->getDeclName())
2506 return;
2507 }
2508
2509 for (CXXMethodDecl::method_iterator M = Method->begin_overridden_methods(),
2510 MEnd = Method->end_overridden_methods();
2511 M != MEnd; ++M) {
2512 CodeCompletionString *Pattern = new CodeCompletionString;
2513 CXXMethodDecl *Overridden = const_cast<CXXMethodDecl *>(*M);
2514 if (Overridden->getCanonicalDecl() == Method->getCanonicalDecl())
2515 continue;
2516
2517 // If we need a nested-name-specifier, add one now.
2518 if (!InContext) {
2519 NestedNameSpecifier *NNS
2520 = getRequiredQualification(S.Context, CurContext,
2521 Overridden->getDeclContext());
2522 if (NNS) {
2523 std::string Str;
2524 llvm::raw_string_ostream OS(Str);
2525 NNS->print(OS, S.Context.PrintingPolicy);
2526 Pattern->AddTextChunk(OS.str());
2527 }
2528 } else if (!InContext->Equals(Overridden->getDeclContext()))
2529 continue;
2530
2531 Pattern->AddTypedTextChunk(Overridden->getNameAsString());
2532 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
2533 bool FirstParam = true;
2534 for (CXXMethodDecl::param_iterator P = Method->param_begin(),
2535 PEnd = Method->param_end();
2536 P != PEnd; ++P) {
2537 if (FirstParam)
2538 FirstParam = false;
2539 else
2540 Pattern->AddChunk(CodeCompletionString::CK_Comma);
2541
2542 Pattern->AddPlaceholderChunk((*P)->getIdentifier()->getName());
2543 }
2544 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
2545 Results.AddResult(CodeCompletionResult(Pattern,
2546 CCP_SuperCompletion,
2547 CXCursor_CXXMethod));
2548 Results.Ignore(Overridden);
2549 }
2550}
2551
Douglas Gregor01dfea02010-01-10 23:08:15 +00002552void Sema::CodeCompleteOrdinaryName(Scope *S,
Douglas Gregore6b1bb62010-08-11 21:23:17 +00002553 ParserCompletionContext CompletionContext) {
John McCall0a2c5e22010-08-25 06:19:51 +00002554 typedef CodeCompletionResult Result;
Douglas Gregor2ccccb32010-08-23 18:23:48 +00002555 ResultBuilder Results(*this);
Douglas Gregorf6961522010-08-27 21:18:54 +00002556 Results.EnterNewScope();
Douglas Gregor01dfea02010-01-10 23:08:15 +00002557
2558 // Determine how to filter results, e.g., so that the names of
2559 // values (functions, enumerators, function templates, etc.) are
2560 // only allowed where we can have an expression.
2561 switch (CompletionContext) {
Douglas Gregore6b1bb62010-08-11 21:23:17 +00002562 case PCC_Namespace:
2563 case PCC_Class:
2564 case PCC_ObjCInterface:
2565 case PCC_ObjCImplementation:
2566 case PCC_ObjCInstanceVariableList:
2567 case PCC_Template:
2568 case PCC_MemberTemplate:
Douglas Gregor72db1082010-08-24 01:11:00 +00002569 case PCC_Type:
Douglas Gregor01dfea02010-01-10 23:08:15 +00002570 Results.setFilter(&ResultBuilder::IsOrdinaryNonValueName);
2571 break;
2572
Douglas Gregore6b1bb62010-08-11 21:23:17 +00002573 case PCC_Statement:
Douglas Gregoreb0d0142010-08-24 23:58:17 +00002574 // For statements that are expressions, we prefer to call 'void' functions
2575 // rather than functions that return a result, since then the result would
2576 // be ignored.
2577 Results.setPreferredType(Context.VoidTy);
2578 // Fall through
2579
Douglas Gregor02688102010-09-14 23:59:36 +00002580 case PCC_ParenthesizedExpression:
Douglas Gregoreb0d0142010-08-24 23:58:17 +00002581 case PCC_Expression:
Douglas Gregore6b1bb62010-08-11 21:23:17 +00002582 case PCC_ForInit:
2583 case PCC_Condition:
Douglas Gregor4710e5b2010-05-28 00:49:12 +00002584 if (WantTypesInContext(CompletionContext, getLangOptions()))
2585 Results.setFilter(&ResultBuilder::IsOrdinaryName);
2586 else
2587 Results.setFilter(&ResultBuilder::IsOrdinaryNonTypeName);
Douglas Gregorf6961522010-08-27 21:18:54 +00002588
2589 if (getLangOptions().CPlusPlus)
2590 MaybeAddOverrideCalls(*this, /*InContext=*/0, Results);
Douglas Gregor01dfea02010-01-10 23:08:15 +00002591 break;
Douglas Gregordc845342010-05-25 05:58:43 +00002592
Douglas Gregore6b1bb62010-08-11 21:23:17 +00002593 case PCC_RecoveryInFunction:
Douglas Gregordc845342010-05-25 05:58:43 +00002594 // Unfiltered
2595 break;
Douglas Gregor01dfea02010-01-10 23:08:15 +00002596 }
2597
Douglas Gregor3cdee122010-08-26 16:36:48 +00002598 // If we are in a C++ non-static member function, check the qualifiers on
2599 // the member function to filter/prioritize the results list.
2600 if (CXXMethodDecl *CurMethod = dyn_cast<CXXMethodDecl>(CurContext))
2601 if (CurMethod->isInstance())
2602 Results.setObjectTypeQualifiers(
2603 Qualifiers::fromCVRMask(CurMethod->getTypeQualifiers()));
2604
Douglas Gregor1ca6ae82010-01-14 01:09:38 +00002605 CodeCompletionDeclConsumer Consumer(Results, CurContext);
Douglas Gregor8071e422010-08-15 06:18:01 +00002606 LookupVisibleDecls(S, LookupOrdinaryName, Consumer,
2607 CodeCompleter->includeGlobals());
Douglas Gregor2a7925c2009-12-07 09:54:55 +00002608
Douglas Gregorbca403c2010-01-13 23:51:12 +00002609 AddOrdinaryNameResults(CompletionContext, S, *this, Results);
Douglas Gregor2a7925c2009-12-07 09:54:55 +00002610 Results.ExitScope();
2611
Douglas Gregoraa5f77b2010-08-23 21:54:33 +00002612 switch (CompletionContext) {
Douglas Gregor02688102010-09-14 23:59:36 +00002613 case PCC_ParenthesizedExpression:
Douglas Gregor72db1082010-08-24 01:11:00 +00002614 case PCC_Expression:
2615 case PCC_Statement:
2616 case PCC_RecoveryInFunction:
2617 if (S->getFnParent())
2618 AddPrettyFunctionResults(PP.getLangOptions(), Results);
2619 break;
2620
2621 case PCC_Namespace:
2622 case PCC_Class:
2623 case PCC_ObjCInterface:
2624 case PCC_ObjCImplementation:
2625 case PCC_ObjCInstanceVariableList:
2626 case PCC_Template:
2627 case PCC_MemberTemplate:
2628 case PCC_ForInit:
2629 case PCC_Condition:
2630 case PCC_Type:
2631 break;
Douglas Gregoraa5f77b2010-08-23 21:54:33 +00002632 }
2633
Douglas Gregor0c8296d2009-11-07 00:00:49 +00002634 if (CodeCompleter->includeMacros())
Douglas Gregorbca403c2010-01-13 23:51:12 +00002635 AddMacroResults(PP, Results);
Douglas Gregoraa5f77b2010-08-23 21:54:33 +00002636
Douglas Gregore6b1bb62010-08-11 21:23:17 +00002637 HandleCodeCompleteResults(this, CodeCompleter,
2638 mapCodeCompletionContext(*this, CompletionContext),
2639 Results.data(),Results.size());
Douglas Gregor791215b2009-09-21 20:51:25 +00002640}
2641
Douglas Gregorc7b6d882010-09-16 15:14:18 +00002642static void AddClassMessageCompletions(Sema &SemaRef, Scope *S,
2643 ParsedType Receiver,
2644 IdentifierInfo **SelIdents,
2645 unsigned NumSelIdents,
2646 bool IsSuper,
2647 ResultBuilder &Results);
2648
2649void Sema::CodeCompleteDeclSpec(Scope *S, DeclSpec &DS,
2650 bool AllowNonIdentifiers,
2651 bool AllowNestedNameSpecifiers) {
John McCall0a2c5e22010-08-25 06:19:51 +00002652 typedef CodeCompletionResult Result;
Douglas Gregor2ccccb32010-08-23 18:23:48 +00002653 ResultBuilder Results(*this);
2654 Results.EnterNewScope();
2655
2656 // Type qualifiers can come after names.
2657 Results.AddResult(Result("const"));
2658 Results.AddResult(Result("volatile"));
2659 if (getLangOptions().C99)
2660 Results.AddResult(Result("restrict"));
2661
2662 if (getLangOptions().CPlusPlus) {
2663 if (AllowNonIdentifiers) {
2664 Results.AddResult(Result("operator"));
2665 }
2666
2667 // Add nested-name-specifiers.
2668 if (AllowNestedNameSpecifiers) {
2669 Results.allowNestedNameSpecifiers();
2670 CodeCompletionDeclConsumer Consumer(Results, CurContext);
2671 LookupVisibleDecls(S, LookupNestedNameSpecifierName, Consumer,
2672 CodeCompleter->includeGlobals());
2673 }
2674 }
2675 Results.ExitScope();
2676
Douglas Gregorc7b6d882010-09-16 15:14:18 +00002677 // If we're in a context where we might have an expression (rather than a
2678 // declaration), and what we've seen so far is an Objective-C type that could
2679 // be a receiver of a class message, this may be a class message send with
2680 // the initial opening bracket '[' missing. Add appropriate completions.
2681 if (AllowNonIdentifiers && !AllowNestedNameSpecifiers &&
2682 DS.getTypeSpecType() == DeclSpec::TST_typename &&
2683 DS.getStorageClassSpecAsWritten() == DeclSpec::SCS_unspecified &&
2684 !DS.isThreadSpecified() && !DS.isExternInLinkageSpec() &&
2685 DS.getTypeSpecComplex() == DeclSpec::TSC_unspecified &&
2686 DS.getTypeSpecSign() == DeclSpec::TSS_unspecified &&
2687 DS.getTypeQualifiers() == 0 &&
2688 S &&
2689 (S->getFlags() & Scope::DeclScope) != 0 &&
2690 (S->getFlags() & (Scope::ClassScope | Scope::TemplateParamScope |
2691 Scope::FunctionPrototypeScope |
2692 Scope::AtCatchScope)) == 0) {
2693 ParsedType T = DS.getRepAsType();
2694 if (!T.get().isNull() && T.get()->isObjCObjectOrInterfaceType())
2695 AddClassMessageCompletions(*this, S, T, 0, 0, false, Results);
2696 }
2697
Douglas Gregor4497dd42010-08-24 04:59:56 +00002698 // Note that we intentionally suppress macro results here, since we do not
2699 // encourage using macros to produce the names of entities.
2700
Douglas Gregor2ccccb32010-08-23 18:23:48 +00002701 HandleCodeCompleteResults(this, CodeCompleter,
2702 AllowNestedNameSpecifiers
2703 ? CodeCompletionContext::CCC_PotentiallyQualifiedName
2704 : CodeCompletionContext::CCC_Name,
2705 Results.data(), Results.size());
2706}
2707
Douglas Gregorfb629412010-08-23 21:17:50 +00002708struct Sema::CodeCompleteExpressionData {
2709 CodeCompleteExpressionData(QualType PreferredType = QualType())
2710 : PreferredType(PreferredType), IntegralConstantExpression(false),
2711 ObjCCollection(false) { }
2712
2713 QualType PreferredType;
2714 bool IntegralConstantExpression;
2715 bool ObjCCollection;
2716 llvm::SmallVector<Decl *, 4> IgnoreDecls;
2717};
2718
Douglas Gregor5ac3bdb2010-05-30 01:49:25 +00002719/// \brief Perform code-completion in an expression context when we know what
2720/// type we're looking for.
Douglas Gregorf9578432010-07-28 21:50:18 +00002721///
2722/// \param IntegralConstantExpression Only permit integral constant
2723/// expressions.
Douglas Gregorfb629412010-08-23 21:17:50 +00002724void Sema::CodeCompleteExpression(Scope *S,
2725 const CodeCompleteExpressionData &Data) {
John McCall0a2c5e22010-08-25 06:19:51 +00002726 typedef CodeCompletionResult Result;
Douglas Gregor5ac3bdb2010-05-30 01:49:25 +00002727 ResultBuilder Results(*this);
2728
Douglas Gregorfb629412010-08-23 21:17:50 +00002729 if (Data.ObjCCollection)
2730 Results.setFilter(&ResultBuilder::IsObjCCollection);
2731 else if (Data.IntegralConstantExpression)
Douglas Gregorf9578432010-07-28 21:50:18 +00002732 Results.setFilter(&ResultBuilder::IsIntegralConstantValue);
Douglas Gregore6b1bb62010-08-11 21:23:17 +00002733 else if (WantTypesInContext(PCC_Expression, getLangOptions()))
Douglas Gregor5ac3bdb2010-05-30 01:49:25 +00002734 Results.setFilter(&ResultBuilder::IsOrdinaryName);
2735 else
2736 Results.setFilter(&ResultBuilder::IsOrdinaryNonTypeName);
Douglas Gregorfb629412010-08-23 21:17:50 +00002737
2738 if (!Data.PreferredType.isNull())
2739 Results.setPreferredType(Data.PreferredType.getNonReferenceType());
2740
2741 // Ignore any declarations that we were told that we don't care about.
2742 for (unsigned I = 0, N = Data.IgnoreDecls.size(); I != N; ++I)
2743 Results.Ignore(Data.IgnoreDecls[I]);
Douglas Gregor5ac3bdb2010-05-30 01:49:25 +00002744
2745 CodeCompletionDeclConsumer Consumer(Results, CurContext);
Douglas Gregor8071e422010-08-15 06:18:01 +00002746 LookupVisibleDecls(S, LookupOrdinaryName, Consumer,
2747 CodeCompleter->includeGlobals());
Douglas Gregor5ac3bdb2010-05-30 01:49:25 +00002748
2749 Results.EnterNewScope();
Douglas Gregore6b1bb62010-08-11 21:23:17 +00002750 AddOrdinaryNameResults(PCC_Expression, S, *this, Results);
Douglas Gregor5ac3bdb2010-05-30 01:49:25 +00002751 Results.ExitScope();
2752
Douglas Gregor590c7d52010-07-08 20:55:51 +00002753 bool PreferredTypeIsPointer = false;
Douglas Gregorfb629412010-08-23 21:17:50 +00002754 if (!Data.PreferredType.isNull())
2755 PreferredTypeIsPointer = Data.PreferredType->isAnyPointerType()
2756 || Data.PreferredType->isMemberPointerType()
2757 || Data.PreferredType->isBlockPointerType();
Douglas Gregor590c7d52010-07-08 20:55:51 +00002758
Douglas Gregoraa5f77b2010-08-23 21:54:33 +00002759 if (S->getFnParent() &&
2760 !Data.ObjCCollection &&
2761 !Data.IntegralConstantExpression)
2762 AddPrettyFunctionResults(PP.getLangOptions(), Results);
2763
Douglas Gregor5ac3bdb2010-05-30 01:49:25 +00002764 if (CodeCompleter->includeMacros())
Douglas Gregor590c7d52010-07-08 20:55:51 +00002765 AddMacroResults(PP, Results, PreferredTypeIsPointer);
Douglas Gregore6b1bb62010-08-11 21:23:17 +00002766 HandleCodeCompleteResults(this, CodeCompleter,
Douglas Gregorfb629412010-08-23 21:17:50 +00002767 CodeCompletionContext(CodeCompletionContext::CCC_Expression,
2768 Data.PreferredType),
Douglas Gregore6b1bb62010-08-11 21:23:17 +00002769 Results.data(),Results.size());
Douglas Gregor5ac3bdb2010-05-30 01:49:25 +00002770}
2771
Douglas Gregorac5fd842010-09-18 01:28:11 +00002772void Sema::CodeCompletePostfixExpression(Scope *S, ExprResult E) {
2773 if (E.isInvalid())
2774 CodeCompleteOrdinaryName(S, PCC_RecoveryInFunction);
2775 else if (getLangOptions().ObjC1)
2776 CodeCompleteObjCInstanceMessage(S, E.take(), 0, 0, false);
Douglas Gregor78edf512010-09-15 16:23:04 +00002777}
Douglas Gregor5ac3bdb2010-05-30 01:49:25 +00002778
Douglas Gregor95ac6552009-11-18 01:29:26 +00002779static void AddObjCProperties(ObjCContainerDecl *Container,
Douglas Gregor322328b2009-11-18 22:32:06 +00002780 bool AllowCategories,
Douglas Gregor95ac6552009-11-18 01:29:26 +00002781 DeclContext *CurContext,
2782 ResultBuilder &Results) {
John McCall0a2c5e22010-08-25 06:19:51 +00002783 typedef CodeCompletionResult Result;
Douglas Gregor95ac6552009-11-18 01:29:26 +00002784
2785 // Add properties in this container.
2786 for (ObjCContainerDecl::prop_iterator P = Container->prop_begin(),
2787 PEnd = Container->prop_end();
2788 P != PEnd;
2789 ++P)
2790 Results.MaybeAddResult(Result(*P, 0), CurContext);
2791
2792 // Add properties in referenced protocols.
2793 if (ObjCProtocolDecl *Protocol = dyn_cast<ObjCProtocolDecl>(Container)) {
2794 for (ObjCProtocolDecl::protocol_iterator P = Protocol->protocol_begin(),
2795 PEnd = Protocol->protocol_end();
2796 P != PEnd; ++P)
Douglas Gregor322328b2009-11-18 22:32:06 +00002797 AddObjCProperties(*P, AllowCategories, CurContext, Results);
Douglas Gregor95ac6552009-11-18 01:29:26 +00002798 } else if (ObjCInterfaceDecl *IFace = dyn_cast<ObjCInterfaceDecl>(Container)){
Douglas Gregor322328b2009-11-18 22:32:06 +00002799 if (AllowCategories) {
2800 // Look through categories.
2801 for (ObjCCategoryDecl *Category = IFace->getCategoryList();
2802 Category; Category = Category->getNextClassCategory())
2803 AddObjCProperties(Category, AllowCategories, CurContext, Results);
2804 }
Douglas Gregor95ac6552009-11-18 01:29:26 +00002805
2806 // Look through protocols.
Ted Kremenek53b94412010-09-01 01:21:15 +00002807 for (ObjCInterfaceDecl::all_protocol_iterator
2808 I = IFace->all_referenced_protocol_begin(),
2809 E = IFace->all_referenced_protocol_end(); I != E; ++I)
Douglas Gregor322328b2009-11-18 22:32:06 +00002810 AddObjCProperties(*I, AllowCategories, CurContext, Results);
Douglas Gregor95ac6552009-11-18 01:29:26 +00002811
2812 // Look in the superclass.
2813 if (IFace->getSuperClass())
Douglas Gregor322328b2009-11-18 22:32:06 +00002814 AddObjCProperties(IFace->getSuperClass(), AllowCategories, CurContext,
2815 Results);
Douglas Gregor95ac6552009-11-18 01:29:26 +00002816 } else if (const ObjCCategoryDecl *Category
2817 = dyn_cast<ObjCCategoryDecl>(Container)) {
2818 // Look through protocols.
Ted Kremenek53b94412010-09-01 01:21:15 +00002819 for (ObjCCategoryDecl::protocol_iterator P = Category->protocol_begin(),
2820 PEnd = Category->protocol_end();
Douglas Gregor95ac6552009-11-18 01:29:26 +00002821 P != PEnd; ++P)
Douglas Gregor322328b2009-11-18 22:32:06 +00002822 AddObjCProperties(*P, AllowCategories, CurContext, Results);
Douglas Gregor95ac6552009-11-18 01:29:26 +00002823 }
2824}
2825
Douglas Gregor81b747b2009-09-17 21:32:03 +00002826void Sema::CodeCompleteMemberReferenceExpr(Scope *S, ExprTy *BaseE,
2827 SourceLocation OpLoc,
2828 bool IsArrow) {
2829 if (!BaseE || !CodeCompleter)
2830 return;
2831
John McCall0a2c5e22010-08-25 06:19:51 +00002832 typedef CodeCompletionResult Result;
Douglas Gregor86d9a522009-09-21 16:56:56 +00002833
Douglas Gregor81b747b2009-09-17 21:32:03 +00002834 Expr *Base = static_cast<Expr *>(BaseE);
2835 QualType BaseType = Base->getType();
Douglas Gregor86d9a522009-09-21 16:56:56 +00002836
2837 if (IsArrow) {
2838 if (const PointerType *Ptr = BaseType->getAs<PointerType>())
2839 BaseType = Ptr->getPointeeType();
2840 else if (BaseType->isObjCObjectPointerType())
Douglas Gregor3cdee122010-08-26 16:36:48 +00002841 /*Do nothing*/ ;
Douglas Gregor86d9a522009-09-21 16:56:56 +00002842 else
2843 return;
2844 }
2845
Douglas Gregoreb5758b2009-09-23 22:26:46 +00002846 ResultBuilder Results(*this, &ResultBuilder::IsMember);
Douglas Gregor95ac6552009-11-18 01:29:26 +00002847 Results.EnterNewScope();
2848 if (const RecordType *Record = BaseType->getAs<RecordType>()) {
Douglas Gregor3cdee122010-08-26 16:36:48 +00002849 // Indicate that we are performing a member access, and the cv-qualifiers
2850 // for the base object type.
2851 Results.setObjectTypeQualifiers(BaseType.getQualifiers());
2852
Douglas Gregor95ac6552009-11-18 01:29:26 +00002853 // Access to a C/C++ class, struct, or union.
Douglas Gregor45bcd432010-01-14 03:21:49 +00002854 Results.allowNestedNameSpecifiers();
Douglas Gregor0cc84042010-01-14 15:47:35 +00002855 CodeCompletionDeclConsumer Consumer(Results, CurContext);
Douglas Gregor8071e422010-08-15 06:18:01 +00002856 LookupVisibleDecls(Record->getDecl(), LookupMemberName, Consumer,
2857 CodeCompleter->includeGlobals());
Daniel Dunbar3a2838d2009-11-13 08:58:20 +00002858
Douglas Gregor95ac6552009-11-18 01:29:26 +00002859 if (getLangOptions().CPlusPlus) {
2860 if (!Results.empty()) {
2861 // The "template" keyword can follow "->" or "." in the grammar.
2862 // However, we only want to suggest the template keyword if something
2863 // is dependent.
2864 bool IsDependent = BaseType->isDependentType();
2865 if (!IsDependent) {
2866 for (Scope *DepScope = S; DepScope; DepScope = DepScope->getParent())
2867 if (DeclContext *Ctx = (DeclContext *)DepScope->getEntity()) {
2868 IsDependent = Ctx->isDependentContext();
2869 break;
2870 }
2871 }
Daniel Dunbar3a2838d2009-11-13 08:58:20 +00002872
Douglas Gregor95ac6552009-11-18 01:29:26 +00002873 if (IsDependent)
Douglas Gregora4477812010-01-14 16:01:26 +00002874 Results.AddResult(Result("template"));
Daniel Dunbar3a2838d2009-11-13 08:58:20 +00002875 }
Daniel Dunbar3a2838d2009-11-13 08:58:20 +00002876 }
Douglas Gregor95ac6552009-11-18 01:29:26 +00002877 } else if (!IsArrow && BaseType->getAsObjCInterfacePointerType()) {
2878 // Objective-C property reference.
2879
2880 // Add property results based on our interface.
2881 const ObjCObjectPointerType *ObjCPtr
2882 = BaseType->getAsObjCInterfacePointerType();
2883 assert(ObjCPtr && "Non-NULL pointer guaranteed above!");
Douglas Gregor322328b2009-11-18 22:32:06 +00002884 AddObjCProperties(ObjCPtr->getInterfaceDecl(), true, CurContext, Results);
Douglas Gregor95ac6552009-11-18 01:29:26 +00002885
2886 // Add properties from the protocols in a qualified interface.
2887 for (ObjCObjectPointerType::qual_iterator I = ObjCPtr->qual_begin(),
2888 E = ObjCPtr->qual_end();
2889 I != E; ++I)
Douglas Gregor322328b2009-11-18 22:32:06 +00002890 AddObjCProperties(*I, true, CurContext, Results);
Douglas Gregor95ac6552009-11-18 01:29:26 +00002891 } else if ((IsArrow && BaseType->isObjCObjectPointerType()) ||
John McCallc12c5bb2010-05-15 11:32:37 +00002892 (!IsArrow && BaseType->isObjCObjectType())) {
Douglas Gregor95ac6552009-11-18 01:29:26 +00002893 // Objective-C instance variable access.
2894 ObjCInterfaceDecl *Class = 0;
2895 if (const ObjCObjectPointerType *ObjCPtr
2896 = BaseType->getAs<ObjCObjectPointerType>())
2897 Class = ObjCPtr->getInterfaceDecl();
2898 else
John McCallc12c5bb2010-05-15 11:32:37 +00002899 Class = BaseType->getAs<ObjCObjectType>()->getInterface();
Douglas Gregor95ac6552009-11-18 01:29:26 +00002900
2901 // Add all ivars from this class and its superclasses.
Douglas Gregor80f4f4c2010-01-14 16:08:12 +00002902 if (Class) {
2903 CodeCompletionDeclConsumer Consumer(Results, CurContext);
2904 Results.setFilter(&ResultBuilder::IsObjCIvar);
Douglas Gregor8071e422010-08-15 06:18:01 +00002905 LookupVisibleDecls(Class, LookupMemberName, Consumer,
2906 CodeCompleter->includeGlobals());
Douglas Gregor95ac6552009-11-18 01:29:26 +00002907 }
Douglas Gregor86d9a522009-09-21 16:56:56 +00002908 }
Douglas Gregor95ac6552009-11-18 01:29:26 +00002909
2910 // FIXME: How do we cope with isa?
2911
2912 Results.ExitScope();
Daniel Dunbar3a2838d2009-11-13 08:58:20 +00002913
Daniel Dunbar3a2838d2009-11-13 08:58:20 +00002914 // Hand off the results found for code completion.
Douglas Gregore6b1bb62010-08-11 21:23:17 +00002915 HandleCodeCompleteResults(this, CodeCompleter,
2916 CodeCompletionContext(CodeCompletionContext::CCC_MemberAccess,
2917 BaseType),
2918 Results.data(),Results.size());
Douglas Gregor81b747b2009-09-17 21:32:03 +00002919}
2920
Douglas Gregor374929f2009-09-18 15:37:17 +00002921void Sema::CodeCompleteTag(Scope *S, unsigned TagSpec) {
2922 if (!CodeCompleter)
2923 return;
2924
John McCall0a2c5e22010-08-25 06:19:51 +00002925 typedef CodeCompletionResult Result;
Douglas Gregor86d9a522009-09-21 16:56:56 +00002926 ResultBuilder::LookupFilter Filter = 0;
Douglas Gregore6b1bb62010-08-11 21:23:17 +00002927 enum CodeCompletionContext::Kind ContextKind
2928 = CodeCompletionContext::CCC_Other;
Douglas Gregor374929f2009-09-18 15:37:17 +00002929 switch ((DeclSpec::TST)TagSpec) {
2930 case DeclSpec::TST_enum:
Douglas Gregor86d9a522009-09-21 16:56:56 +00002931 Filter = &ResultBuilder::IsEnum;
Douglas Gregore6b1bb62010-08-11 21:23:17 +00002932 ContextKind = CodeCompletionContext::CCC_EnumTag;
Douglas Gregor374929f2009-09-18 15:37:17 +00002933 break;
2934
2935 case DeclSpec::TST_union:
Douglas Gregor86d9a522009-09-21 16:56:56 +00002936 Filter = &ResultBuilder::IsUnion;
Douglas Gregore6b1bb62010-08-11 21:23:17 +00002937 ContextKind = CodeCompletionContext::CCC_UnionTag;
Douglas Gregor374929f2009-09-18 15:37:17 +00002938 break;
2939
2940 case DeclSpec::TST_struct:
Douglas Gregor374929f2009-09-18 15:37:17 +00002941 case DeclSpec::TST_class:
Douglas Gregor86d9a522009-09-21 16:56:56 +00002942 Filter = &ResultBuilder::IsClassOrStruct;
Douglas Gregore6b1bb62010-08-11 21:23:17 +00002943 ContextKind = CodeCompletionContext::CCC_ClassOrStructTag;
Douglas Gregor374929f2009-09-18 15:37:17 +00002944 break;
2945
2946 default:
2947 assert(false && "Unknown type specifier kind in CodeCompleteTag");
2948 return;
2949 }
Douglas Gregor86d9a522009-09-21 16:56:56 +00002950
John McCall0d6b1642010-04-23 18:46:30 +00002951 ResultBuilder Results(*this);
Douglas Gregor5d2fc402010-01-14 03:27:13 +00002952 CodeCompletionDeclConsumer Consumer(Results, CurContext);
John McCall0d6b1642010-04-23 18:46:30 +00002953
2954 // First pass: look for tags.
2955 Results.setFilter(Filter);
Douglas Gregor8071e422010-08-15 06:18:01 +00002956 LookupVisibleDecls(S, LookupTagName, Consumer,
2957 CodeCompleter->includeGlobals());
John McCall0d6b1642010-04-23 18:46:30 +00002958
Douglas Gregor8071e422010-08-15 06:18:01 +00002959 if (CodeCompleter->includeGlobals()) {
2960 // Second pass: look for nested name specifiers.
2961 Results.setFilter(&ResultBuilder::IsNestedNameSpecifier);
2962 LookupVisibleDecls(S, LookupNestedNameSpecifierName, Consumer);
2963 }
Douglas Gregor86d9a522009-09-21 16:56:56 +00002964
Douglas Gregore6b1bb62010-08-11 21:23:17 +00002965 HandleCodeCompleteResults(this, CodeCompleter, ContextKind,
2966 Results.data(),Results.size());
Douglas Gregor374929f2009-09-18 15:37:17 +00002967}
2968
Douglas Gregor1a480c42010-08-27 17:35:51 +00002969void Sema::CodeCompleteTypeQualifiers(DeclSpec &DS) {
2970 ResultBuilder Results(*this);
2971 Results.EnterNewScope();
2972 if (!(DS.getTypeQualifiers() & DeclSpec::TQ_const))
2973 Results.AddResult("const");
2974 if (!(DS.getTypeQualifiers() & DeclSpec::TQ_volatile))
2975 Results.AddResult("volatile");
2976 if (getLangOptions().C99 &&
2977 !(DS.getTypeQualifiers() & DeclSpec::TQ_restrict))
2978 Results.AddResult("restrict");
2979 Results.ExitScope();
2980 HandleCodeCompleteResults(this, CodeCompleter,
2981 CodeCompletionContext::CCC_TypeQualifiers,
2982 Results.data(), Results.size());
2983}
2984
Douglas Gregor3e1005f2009-09-21 18:10:23 +00002985void Sema::CodeCompleteCase(Scope *S) {
John McCall781472f2010-08-25 08:40:02 +00002986 if (getCurFunction()->SwitchStack.empty() || !CodeCompleter)
Douglas Gregor3e1005f2009-09-21 18:10:23 +00002987 return;
2988
John McCall781472f2010-08-25 08:40:02 +00002989 SwitchStmt *Switch = getCurFunction()->SwitchStack.back();
Douglas Gregorf9578432010-07-28 21:50:18 +00002990 if (!Switch->getCond()->getType()->isEnumeralType()) {
Douglas Gregorfb629412010-08-23 21:17:50 +00002991 CodeCompleteExpressionData Data(Switch->getCond()->getType());
2992 Data.IntegralConstantExpression = true;
2993 CodeCompleteExpression(S, Data);
Douglas Gregor3e1005f2009-09-21 18:10:23 +00002994 return;
Douglas Gregorf9578432010-07-28 21:50:18 +00002995 }
Douglas Gregor3e1005f2009-09-21 18:10:23 +00002996
2997 // Code-complete the cases of a switch statement over an enumeration type
2998 // by providing the list of
2999 EnumDecl *Enum = Switch->getCond()->getType()->getAs<EnumType>()->getDecl();
3000
3001 // Determine which enumerators we have already seen in the switch statement.
3002 // FIXME: Ideally, we would also be able to look *past* the code-completion
3003 // token, in case we are code-completing in the middle of the switch and not
3004 // at the end. However, we aren't able to do so at the moment.
3005 llvm::SmallPtrSet<EnumConstantDecl *, 8> EnumeratorsSeen;
Douglas Gregorb9d0ef72009-09-21 19:57:38 +00003006 NestedNameSpecifier *Qualifier = 0;
Douglas Gregor3e1005f2009-09-21 18:10:23 +00003007 for (SwitchCase *SC = Switch->getSwitchCaseList(); SC;
3008 SC = SC->getNextSwitchCase()) {
3009 CaseStmt *Case = dyn_cast<CaseStmt>(SC);
3010 if (!Case)
3011 continue;
3012
3013 Expr *CaseVal = Case->getLHS()->IgnoreParenCasts();
3014 if (DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(CaseVal))
3015 if (EnumConstantDecl *Enumerator
3016 = dyn_cast<EnumConstantDecl>(DRE->getDecl())) {
3017 // We look into the AST of the case statement to determine which
3018 // enumerator was named. Alternatively, we could compute the value of
3019 // the integral constant expression, then compare it against the
3020 // values of each enumerator. However, value-based approach would not
3021 // work as well with C++ templates where enumerators declared within a
3022 // template are type- and value-dependent.
3023 EnumeratorsSeen.insert(Enumerator);
3024
Douglas Gregorb9d0ef72009-09-21 19:57:38 +00003025 // If this is a qualified-id, keep track of the nested-name-specifier
3026 // so that we can reproduce it as part of code completion, e.g.,
Douglas Gregor3e1005f2009-09-21 18:10:23 +00003027 //
3028 // switch (TagD.getKind()) {
3029 // case TagDecl::TK_enum:
3030 // break;
3031 // case XXX
3032 //
Douglas Gregorb9d0ef72009-09-21 19:57:38 +00003033 // At the XXX, our completions are TagDecl::TK_union,
Douglas Gregor3e1005f2009-09-21 18:10:23 +00003034 // TagDecl::TK_struct, and TagDecl::TK_class, rather than TK_union,
3035 // TK_struct, and TK_class.
Douglas Gregora2813ce2009-10-23 18:54:35 +00003036 Qualifier = DRE->getQualifier();
Douglas Gregor3e1005f2009-09-21 18:10:23 +00003037 }
3038 }
3039
Douglas Gregorb9d0ef72009-09-21 19:57:38 +00003040 if (getLangOptions().CPlusPlus && !Qualifier && EnumeratorsSeen.empty()) {
3041 // If there are no prior enumerators in C++, check whether we have to
3042 // qualify the names of the enumerators that we suggest, because they
3043 // may not be visible in this scope.
3044 Qualifier = getRequiredQualification(Context, CurContext,
3045 Enum->getDeclContext());
3046
3047 // FIXME: Scoped enums need to start with "EnumDecl" as the context!
3048 }
3049
Douglas Gregor3e1005f2009-09-21 18:10:23 +00003050 // Add any enumerators that have not yet been mentioned.
3051 ResultBuilder Results(*this);
3052 Results.EnterNewScope();
3053 for (EnumDecl::enumerator_iterator E = Enum->enumerator_begin(),
3054 EEnd = Enum->enumerator_end();
3055 E != EEnd; ++E) {
3056 if (EnumeratorsSeen.count(*E))
3057 continue;
3058
John McCall0a2c5e22010-08-25 06:19:51 +00003059 Results.AddResult(CodeCompletionResult(*E, Qualifier),
Douglas Gregor608300b2010-01-14 16:14:35 +00003060 CurContext, 0, false);
Douglas Gregor3e1005f2009-09-21 18:10:23 +00003061 }
3062 Results.ExitScope();
Douglas Gregor2f880e42010-04-06 20:02:15 +00003063
Douglas Gregor0c8296d2009-11-07 00:00:49 +00003064 if (CodeCompleter->includeMacros())
Douglas Gregorbca403c2010-01-13 23:51:12 +00003065 AddMacroResults(PP, Results);
Douglas Gregore6b1bb62010-08-11 21:23:17 +00003066 HandleCodeCompleteResults(this, CodeCompleter,
3067 CodeCompletionContext::CCC_Expression,
3068 Results.data(),Results.size());
Douglas Gregor3e1005f2009-09-21 18:10:23 +00003069}
3070
Douglas Gregor9c6a0e92009-09-22 15:41:20 +00003071namespace {
3072 struct IsBetterOverloadCandidate {
3073 Sema &S;
John McCall5769d612010-02-08 23:07:23 +00003074 SourceLocation Loc;
Douglas Gregor9c6a0e92009-09-22 15:41:20 +00003075
3076 public:
John McCall5769d612010-02-08 23:07:23 +00003077 explicit IsBetterOverloadCandidate(Sema &S, SourceLocation Loc)
3078 : S(S), Loc(Loc) { }
Douglas Gregor9c6a0e92009-09-22 15:41:20 +00003079
3080 bool
3081 operator()(const OverloadCandidate &X, const OverloadCandidate &Y) const {
John McCall120d63c2010-08-24 20:38:10 +00003082 return isBetterOverloadCandidate(S, X, Y, Loc);
Douglas Gregor9c6a0e92009-09-22 15:41:20 +00003083 }
3084 };
3085}
3086
Douglas Gregord28dcd72010-05-30 06:10:08 +00003087static bool anyNullArguments(Expr **Args, unsigned NumArgs) {
3088 if (NumArgs && !Args)
3089 return true;
3090
3091 for (unsigned I = 0; I != NumArgs; ++I)
3092 if (!Args[I])
3093 return true;
3094
3095 return false;
3096}
3097
Douglas Gregor9c6a0e92009-09-22 15:41:20 +00003098void Sema::CodeCompleteCall(Scope *S, ExprTy *FnIn,
3099 ExprTy **ArgsIn, unsigned NumArgs) {
3100 if (!CodeCompleter)
3101 return;
Douglas Gregoref96eac2009-12-11 19:06:04 +00003102
3103 // When we're code-completing for a call, we fall back to ordinary
3104 // name code-completion whenever we can't produce specific
3105 // results. We may want to revisit this strategy in the future,
3106 // e.g., by merging the two kinds of results.
3107
Douglas Gregor9c6a0e92009-09-22 15:41:20 +00003108 Expr *Fn = (Expr *)FnIn;
3109 Expr **Args = (Expr **)ArgsIn;
Douglas Gregoref96eac2009-12-11 19:06:04 +00003110
Douglas Gregor9c6a0e92009-09-22 15:41:20 +00003111 // Ignore type-dependent call expressions entirely.
Douglas Gregord28dcd72010-05-30 06:10:08 +00003112 if (!Fn || Fn->isTypeDependent() || anyNullArguments(Args, NumArgs) ||
Douglas Gregoref96eac2009-12-11 19:06:04 +00003113 Expr::hasAnyTypeDependentArguments(Args, NumArgs)) {
Douglas Gregore6b1bb62010-08-11 21:23:17 +00003114 CodeCompleteOrdinaryName(S, PCC_Expression);
Douglas Gregor9c6a0e92009-09-22 15:41:20 +00003115 return;
Douglas Gregoref96eac2009-12-11 19:06:04 +00003116 }
Douglas Gregor9c6a0e92009-09-22 15:41:20 +00003117
John McCall3b4294e2009-12-16 12:17:52 +00003118 // Build an overload candidate set based on the functions we find.
John McCall5769d612010-02-08 23:07:23 +00003119 SourceLocation Loc = Fn->getExprLoc();
3120 OverloadCandidateSet CandidateSet(Loc);
John McCall3b4294e2009-12-16 12:17:52 +00003121
Douglas Gregor9c6a0e92009-09-22 15:41:20 +00003122 // FIXME: What if we're calling something that isn't a function declaration?
3123 // FIXME: What if we're calling a pseudo-destructor?
3124 // FIXME: What if we're calling a member function?
3125
Douglas Gregorc0265402010-01-21 15:46:19 +00003126 typedef CodeCompleteConsumer::OverloadCandidate ResultCandidate;
3127 llvm::SmallVector<ResultCandidate, 8> Results;
3128
John McCall3b4294e2009-12-16 12:17:52 +00003129 Expr *NakedFn = Fn->IgnoreParenCasts();
3130 if (UnresolvedLookupExpr *ULE = dyn_cast<UnresolvedLookupExpr>(NakedFn))
3131 AddOverloadedCallCandidates(ULE, Args, NumArgs, CandidateSet,
3132 /*PartialOverloading=*/ true);
3133 else if (DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(NakedFn)) {
3134 FunctionDecl *FDecl = dyn_cast<FunctionDecl>(DRE->getDecl());
Douglas Gregorc0265402010-01-21 15:46:19 +00003135 if (FDecl) {
Douglas Gregord28dcd72010-05-30 06:10:08 +00003136 if (!getLangOptions().CPlusPlus ||
3137 !FDecl->getType()->getAs<FunctionProtoType>())
Douglas Gregorc0265402010-01-21 15:46:19 +00003138 Results.push_back(ResultCandidate(FDecl));
3139 else
John McCall86820f52010-01-26 01:37:31 +00003140 // FIXME: access?
John McCall9aa472c2010-03-19 07:35:19 +00003141 AddOverloadCandidate(FDecl, DeclAccessPair::make(FDecl, AS_none),
3142 Args, NumArgs, CandidateSet,
Douglas Gregorc27d6c52010-04-16 17:41:49 +00003143 false, /*PartialOverloading*/true);
Douglas Gregorc0265402010-01-21 15:46:19 +00003144 }
John McCall3b4294e2009-12-16 12:17:52 +00003145 }
Douglas Gregor9c6a0e92009-09-22 15:41:20 +00003146
Douglas Gregor5ac3bdb2010-05-30 01:49:25 +00003147 QualType ParamType;
3148
Douglas Gregorc0265402010-01-21 15:46:19 +00003149 if (!CandidateSet.empty()) {
3150 // Sort the overload candidate set by placing the best overloads first.
3151 std::stable_sort(CandidateSet.begin(), CandidateSet.end(),
John McCall5769d612010-02-08 23:07:23 +00003152 IsBetterOverloadCandidate(*this, Loc));
Douglas Gregor9c6a0e92009-09-22 15:41:20 +00003153
Douglas Gregorc0265402010-01-21 15:46:19 +00003154 // Add the remaining viable overload candidates as code-completion reslults.
3155 for (OverloadCandidateSet::iterator Cand = CandidateSet.begin(),
3156 CandEnd = CandidateSet.end();
3157 Cand != CandEnd; ++Cand) {
3158 if (Cand->Viable)
3159 Results.push_back(ResultCandidate(Cand->Function));
3160 }
Douglas Gregor5ac3bdb2010-05-30 01:49:25 +00003161
3162 // From the viable candidates, try to determine the type of this parameter.
3163 for (unsigned I = 0, N = Results.size(); I != N; ++I) {
3164 if (const FunctionType *FType = Results[I].getFunctionType())
3165 if (const FunctionProtoType *Proto = dyn_cast<FunctionProtoType>(FType))
3166 if (NumArgs < Proto->getNumArgs()) {
3167 if (ParamType.isNull())
3168 ParamType = Proto->getArgType(NumArgs);
3169 else if (!Context.hasSameUnqualifiedType(
3170 ParamType.getNonReferenceType(),
3171 Proto->getArgType(NumArgs).getNonReferenceType())) {
3172 ParamType = QualType();
3173 break;
3174 }
3175 }
3176 }
3177 } else {
3178 // Try to determine the parameter type from the type of the expression
3179 // being called.
3180 QualType FunctionType = Fn->getType();
3181 if (const PointerType *Ptr = FunctionType->getAs<PointerType>())
3182 FunctionType = Ptr->getPointeeType();
3183 else if (const BlockPointerType *BlockPtr
3184 = FunctionType->getAs<BlockPointerType>())
3185 FunctionType = BlockPtr->getPointeeType();
3186 else if (const MemberPointerType *MemPtr
3187 = FunctionType->getAs<MemberPointerType>())
3188 FunctionType = MemPtr->getPointeeType();
3189
3190 if (const FunctionProtoType *Proto
3191 = FunctionType->getAs<FunctionProtoType>()) {
3192 if (NumArgs < Proto->getNumArgs())
3193 ParamType = Proto->getArgType(NumArgs);
3194 }
Douglas Gregor9c6a0e92009-09-22 15:41:20 +00003195 }
Douglas Gregoref96eac2009-12-11 19:06:04 +00003196
Douglas Gregor5ac3bdb2010-05-30 01:49:25 +00003197 if (ParamType.isNull())
Douglas Gregore6b1bb62010-08-11 21:23:17 +00003198 CodeCompleteOrdinaryName(S, PCC_Expression);
Douglas Gregor5ac3bdb2010-05-30 01:49:25 +00003199 else
3200 CodeCompleteExpression(S, ParamType);
3201
Douglas Gregor2e4c7a52010-04-06 20:19:47 +00003202 if (!Results.empty())
Douglas Gregoref96eac2009-12-11 19:06:04 +00003203 CodeCompleter->ProcessOverloadCandidates(*this, NumArgs, Results.data(),
3204 Results.size());
Douglas Gregor9c6a0e92009-09-22 15:41:20 +00003205}
3206
John McCalld226f652010-08-21 09:40:31 +00003207void Sema::CodeCompleteInitializer(Scope *S, Decl *D) {
3208 ValueDecl *VD = dyn_cast_or_null<ValueDecl>(D);
Douglas Gregor5ac3bdb2010-05-30 01:49:25 +00003209 if (!VD) {
Douglas Gregore6b1bb62010-08-11 21:23:17 +00003210 CodeCompleteOrdinaryName(S, PCC_Expression);
Douglas Gregor5ac3bdb2010-05-30 01:49:25 +00003211 return;
3212 }
3213
3214 CodeCompleteExpression(S, VD->getType());
3215}
3216
3217void Sema::CodeCompleteReturn(Scope *S) {
3218 QualType ResultType;
3219 if (isa<BlockDecl>(CurContext)) {
3220 if (BlockScopeInfo *BSI = getCurBlock())
3221 ResultType = BSI->ReturnType;
3222 } else if (FunctionDecl *Function = dyn_cast<FunctionDecl>(CurContext))
3223 ResultType = Function->getResultType();
3224 else if (ObjCMethodDecl *Method = dyn_cast<ObjCMethodDecl>(CurContext))
3225 ResultType = Method->getResultType();
3226
3227 if (ResultType.isNull())
Douglas Gregore6b1bb62010-08-11 21:23:17 +00003228 CodeCompleteOrdinaryName(S, PCC_Expression);
Douglas Gregor5ac3bdb2010-05-30 01:49:25 +00003229 else
3230 CodeCompleteExpression(S, ResultType);
3231}
3232
3233void Sema::CodeCompleteAssignmentRHS(Scope *S, ExprTy *LHS) {
3234 if (LHS)
3235 CodeCompleteExpression(S, static_cast<Expr *>(LHS)->getType());
3236 else
Douglas Gregore6b1bb62010-08-11 21:23:17 +00003237 CodeCompleteOrdinaryName(S, PCC_Expression);
Douglas Gregor5ac3bdb2010-05-30 01:49:25 +00003238}
3239
Jeffrey Yasskin9ab14542010-04-08 16:38:48 +00003240void Sema::CodeCompleteQualifiedId(Scope *S, CXXScopeSpec &SS,
Douglas Gregor81b747b2009-09-17 21:32:03 +00003241 bool EnteringContext) {
3242 if (!SS.getScopeRep() || !CodeCompleter)
3243 return;
3244
Douglas Gregor86d9a522009-09-21 16:56:56 +00003245 DeclContext *Ctx = computeDeclContext(SS, EnteringContext);
3246 if (!Ctx)
3247 return;
Douglas Gregord1cd31a2009-12-11 18:28:39 +00003248
3249 // Try to instantiate any non-dependent declaration contexts before
3250 // we look in them.
John McCall77bb1aa2010-05-01 00:40:08 +00003251 if (!isDependentScopeSpecifier(SS) && RequireCompleteDeclContext(SS, Ctx))
Douglas Gregord1cd31a2009-12-11 18:28:39 +00003252 return;
3253
Douglas Gregor86d9a522009-09-21 16:56:56 +00003254 ResultBuilder Results(*this);
Douglas Gregor86d9a522009-09-21 16:56:56 +00003255
Douglas Gregorf6961522010-08-27 21:18:54 +00003256 Results.EnterNewScope();
Douglas Gregor86d9a522009-09-21 16:56:56 +00003257 // The "template" keyword can follow "::" in the grammar, but only
3258 // put it into the grammar if the nested-name-specifier is dependent.
3259 NestedNameSpecifier *NNS = (NestedNameSpecifier *)SS.getScopeRep();
3260 if (!Results.empty() && NNS->isDependent())
Douglas Gregora4477812010-01-14 16:01:26 +00003261 Results.AddResult("template");
Douglas Gregorf6961522010-08-27 21:18:54 +00003262
3263 // Add calls to overridden virtual functions, if there are any.
3264 //
3265 // FIXME: This isn't wonderful, because we don't know whether we're actually
3266 // in a context that permits expressions. This is a general issue with
3267 // qualified-id completions.
3268 if (!EnteringContext)
3269 MaybeAddOverrideCalls(*this, Ctx, Results);
3270 Results.ExitScope();
Douglas Gregor86d9a522009-09-21 16:56:56 +00003271
Douglas Gregorf6961522010-08-27 21:18:54 +00003272 CodeCompletionDeclConsumer Consumer(Results, CurContext);
3273 LookupVisibleDecls(Ctx, LookupOrdinaryName, Consumer);
3274
Douglas Gregore6b1bb62010-08-11 21:23:17 +00003275 HandleCodeCompleteResults(this, CodeCompleter,
Douglas Gregorf6961522010-08-27 21:18:54 +00003276 CodeCompletionContext::CCC_Name,
Douglas Gregore6b1bb62010-08-11 21:23:17 +00003277 Results.data(),Results.size());
Douglas Gregor81b747b2009-09-17 21:32:03 +00003278}
Douglas Gregor49f40bd2009-09-18 19:03:04 +00003279
3280void Sema::CodeCompleteUsing(Scope *S) {
3281 if (!CodeCompleter)
3282 return;
3283
Douglas Gregor86d9a522009-09-21 16:56:56 +00003284 ResultBuilder Results(*this, &ResultBuilder::IsNestedNameSpecifier);
Douglas Gregor8e0a0e42009-09-22 23:31:26 +00003285 Results.EnterNewScope();
Douglas Gregor86d9a522009-09-21 16:56:56 +00003286
3287 // If we aren't in class scope, we could see the "namespace" keyword.
3288 if (!S->isClassScope())
John McCall0a2c5e22010-08-25 06:19:51 +00003289 Results.AddResult(CodeCompletionResult("namespace"));
Douglas Gregor86d9a522009-09-21 16:56:56 +00003290
3291 // After "using", we can see anything that would start a
3292 // nested-name-specifier.
Douglas Gregor5d2fc402010-01-14 03:27:13 +00003293 CodeCompletionDeclConsumer Consumer(Results, CurContext);
Douglas Gregor8071e422010-08-15 06:18:01 +00003294 LookupVisibleDecls(S, LookupOrdinaryName, Consumer,
3295 CodeCompleter->includeGlobals());
Douglas Gregor8e0a0e42009-09-22 23:31:26 +00003296 Results.ExitScope();
Douglas Gregor86d9a522009-09-21 16:56:56 +00003297
Douglas Gregore6b1bb62010-08-11 21:23:17 +00003298 HandleCodeCompleteResults(this, CodeCompleter,
3299 CodeCompletionContext::CCC_Other,
3300 Results.data(),Results.size());
Douglas Gregor49f40bd2009-09-18 19:03:04 +00003301}
3302
3303void Sema::CodeCompleteUsingDirective(Scope *S) {
3304 if (!CodeCompleter)
3305 return;
3306
Douglas Gregor86d9a522009-09-21 16:56:56 +00003307 // After "using namespace", we expect to see a namespace name or namespace
3308 // alias.
3309 ResultBuilder Results(*this, &ResultBuilder::IsNamespaceOrAlias);
Douglas Gregor8e0a0e42009-09-22 23:31:26 +00003310 Results.EnterNewScope();
Douglas Gregor5d2fc402010-01-14 03:27:13 +00003311 CodeCompletionDeclConsumer Consumer(Results, CurContext);
Douglas Gregor8071e422010-08-15 06:18:01 +00003312 LookupVisibleDecls(S, LookupOrdinaryName, Consumer,
3313 CodeCompleter->includeGlobals());
Douglas Gregor8e0a0e42009-09-22 23:31:26 +00003314 Results.ExitScope();
Douglas Gregore6b1bb62010-08-11 21:23:17 +00003315 HandleCodeCompleteResults(this, CodeCompleter,
Douglas Gregor8071e422010-08-15 06:18:01 +00003316 CodeCompletionContext::CCC_Namespace,
Douglas Gregore6b1bb62010-08-11 21:23:17 +00003317 Results.data(),Results.size());
Douglas Gregor49f40bd2009-09-18 19:03:04 +00003318}
3319
3320void Sema::CodeCompleteNamespaceDecl(Scope *S) {
3321 if (!CodeCompleter)
3322 return;
3323
Douglas Gregor86d9a522009-09-21 16:56:56 +00003324 ResultBuilder Results(*this, &ResultBuilder::IsNamespace);
3325 DeclContext *Ctx = (DeclContext *)S->getEntity();
3326 if (!S->getParent())
3327 Ctx = Context.getTranslationUnitDecl();
3328
3329 if (Ctx && Ctx->isFileContext()) {
3330 // We only want to see those namespaces that have already been defined
3331 // within this scope, because its likely that the user is creating an
3332 // extended namespace declaration. Keep track of the most recent
3333 // definition of each namespace.
3334 std::map<NamespaceDecl *, NamespaceDecl *> OrigToLatest;
3335 for (DeclContext::specific_decl_iterator<NamespaceDecl>
3336 NS(Ctx->decls_begin()), NSEnd(Ctx->decls_end());
3337 NS != NSEnd; ++NS)
3338 OrigToLatest[NS->getOriginalNamespace()] = *NS;
3339
3340 // Add the most recent definition (or extended definition) of each
3341 // namespace to the list of results.
Douglas Gregor8e0a0e42009-09-22 23:31:26 +00003342 Results.EnterNewScope();
Douglas Gregor86d9a522009-09-21 16:56:56 +00003343 for (std::map<NamespaceDecl *, NamespaceDecl *>::iterator
3344 NS = OrigToLatest.begin(), NSEnd = OrigToLatest.end();
3345 NS != NSEnd; ++NS)
John McCall0a2c5e22010-08-25 06:19:51 +00003346 Results.AddResult(CodeCompletionResult(NS->second, 0),
Douglas Gregor608300b2010-01-14 16:14:35 +00003347 CurContext, 0, false);
Douglas Gregor8e0a0e42009-09-22 23:31:26 +00003348 Results.ExitScope();
Douglas Gregor86d9a522009-09-21 16:56:56 +00003349 }
3350
Douglas Gregore6b1bb62010-08-11 21:23:17 +00003351 HandleCodeCompleteResults(this, CodeCompleter,
3352 CodeCompletionContext::CCC_Other,
3353 Results.data(),Results.size());
Douglas Gregor49f40bd2009-09-18 19:03:04 +00003354}
3355
3356void Sema::CodeCompleteNamespaceAliasDecl(Scope *S) {
3357 if (!CodeCompleter)
3358 return;
3359
Douglas Gregor86d9a522009-09-21 16:56:56 +00003360 // After "namespace", we expect to see a namespace or alias.
3361 ResultBuilder Results(*this, &ResultBuilder::IsNamespaceOrAlias);
Douglas Gregor5d2fc402010-01-14 03:27:13 +00003362 CodeCompletionDeclConsumer Consumer(Results, CurContext);
Douglas Gregor8071e422010-08-15 06:18:01 +00003363 LookupVisibleDecls(S, LookupOrdinaryName, Consumer,
3364 CodeCompleter->includeGlobals());
Douglas Gregore6b1bb62010-08-11 21:23:17 +00003365 HandleCodeCompleteResults(this, CodeCompleter,
Douglas Gregor8071e422010-08-15 06:18:01 +00003366 CodeCompletionContext::CCC_Namespace,
Douglas Gregore6b1bb62010-08-11 21:23:17 +00003367 Results.data(),Results.size());
Douglas Gregor49f40bd2009-09-18 19:03:04 +00003368}
3369
Douglas Gregored8d3222009-09-18 20:05:18 +00003370void Sema::CodeCompleteOperatorName(Scope *S) {
3371 if (!CodeCompleter)
3372 return;
Douglas Gregor86d9a522009-09-21 16:56:56 +00003373
John McCall0a2c5e22010-08-25 06:19:51 +00003374 typedef CodeCompletionResult Result;
Douglas Gregor86d9a522009-09-21 16:56:56 +00003375 ResultBuilder Results(*this, &ResultBuilder::IsType);
Douglas Gregor8e0a0e42009-09-22 23:31:26 +00003376 Results.EnterNewScope();
Douglas Gregored8d3222009-09-18 20:05:18 +00003377
Douglas Gregor86d9a522009-09-21 16:56:56 +00003378 // Add the names of overloadable operators.
3379#define OVERLOADED_OPERATOR(Name,Spelling,Token,Unary,Binary,MemberOnly) \
3380 if (std::strcmp(Spelling, "?")) \
Douglas Gregora4477812010-01-14 16:01:26 +00003381 Results.AddResult(Result(Spelling));
Douglas Gregor86d9a522009-09-21 16:56:56 +00003382#include "clang/Basic/OperatorKinds.def"
3383
3384 // Add any type names visible from the current scope
Douglas Gregor45bcd432010-01-14 03:21:49 +00003385 Results.allowNestedNameSpecifiers();
Douglas Gregor5d2fc402010-01-14 03:27:13 +00003386 CodeCompletionDeclConsumer Consumer(Results, CurContext);
Douglas Gregor8071e422010-08-15 06:18:01 +00003387 LookupVisibleDecls(S, LookupOrdinaryName, Consumer,
3388 CodeCompleter->includeGlobals());
Douglas Gregor86d9a522009-09-21 16:56:56 +00003389
3390 // Add any type specifiers
Douglas Gregorbca403c2010-01-13 23:51:12 +00003391 AddTypeSpecifierResults(getLangOptions(), Results);
Douglas Gregor8e0a0e42009-09-22 23:31:26 +00003392 Results.ExitScope();
Douglas Gregor86d9a522009-09-21 16:56:56 +00003393
Douglas Gregore6b1bb62010-08-11 21:23:17 +00003394 HandleCodeCompleteResults(this, CodeCompleter,
Douglas Gregor8071e422010-08-15 06:18:01 +00003395 CodeCompletionContext::CCC_Type,
Douglas Gregore6b1bb62010-08-11 21:23:17 +00003396 Results.data(),Results.size());
Douglas Gregored8d3222009-09-18 20:05:18 +00003397}
Douglas Gregor49f40bd2009-09-18 19:03:04 +00003398
Douglas Gregor0133f522010-08-28 00:00:50 +00003399void Sema::CodeCompleteConstructorInitializer(Decl *ConstructorD,
3400 CXXBaseOrMemberInitializer** Initializers,
3401 unsigned NumInitializers) {
3402 CXXConstructorDecl *Constructor
3403 = static_cast<CXXConstructorDecl *>(ConstructorD);
3404 if (!Constructor)
3405 return;
3406
3407 ResultBuilder Results(*this);
3408 Results.EnterNewScope();
3409
3410 // Fill in any already-initialized fields or base classes.
3411 llvm::SmallPtrSet<FieldDecl *, 4> InitializedFields;
3412 llvm::SmallPtrSet<CanQualType, 4> InitializedBases;
3413 for (unsigned I = 0; I != NumInitializers; ++I) {
3414 if (Initializers[I]->isBaseInitializer())
3415 InitializedBases.insert(
3416 Context.getCanonicalType(QualType(Initializers[I]->getBaseClass(), 0)));
3417 else
3418 InitializedFields.insert(cast<FieldDecl>(Initializers[I]->getMember()));
3419 }
3420
3421 // Add completions for base classes.
Douglas Gregor0c431c82010-08-29 19:27:27 +00003422 bool SawLastInitializer = (NumInitializers == 0);
Douglas Gregor0133f522010-08-28 00:00:50 +00003423 CXXRecordDecl *ClassDecl = Constructor->getParent();
3424 for (CXXRecordDecl::base_class_iterator Base = ClassDecl->bases_begin(),
3425 BaseEnd = ClassDecl->bases_end();
3426 Base != BaseEnd; ++Base) {
Douglas Gregor0c431c82010-08-29 19:27:27 +00003427 if (!InitializedBases.insert(Context.getCanonicalType(Base->getType()))) {
3428 SawLastInitializer
3429 = NumInitializers > 0 &&
3430 Initializers[NumInitializers - 1]->isBaseInitializer() &&
3431 Context.hasSameUnqualifiedType(Base->getType(),
3432 QualType(Initializers[NumInitializers - 1]->getBaseClass(), 0));
Douglas Gregor0133f522010-08-28 00:00:50 +00003433 continue;
Douglas Gregor0c431c82010-08-29 19:27:27 +00003434 }
Douglas Gregor0133f522010-08-28 00:00:50 +00003435
3436 CodeCompletionString *Pattern = new CodeCompletionString;
3437 Pattern->AddTypedTextChunk(
3438 Base->getType().getAsString(Context.PrintingPolicy));
3439 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
3440 Pattern->AddPlaceholderChunk("args");
3441 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
Douglas Gregor0c431c82010-08-29 19:27:27 +00003442 Results.AddResult(CodeCompletionResult(Pattern,
3443 SawLastInitializer? CCP_NextInitializer
3444 : CCP_MemberDeclaration));
3445 SawLastInitializer = false;
Douglas Gregor0133f522010-08-28 00:00:50 +00003446 }
3447
3448 // Add completions for virtual base classes.
3449 for (CXXRecordDecl::base_class_iterator Base = ClassDecl->vbases_begin(),
3450 BaseEnd = ClassDecl->vbases_end();
3451 Base != BaseEnd; ++Base) {
Douglas Gregor0c431c82010-08-29 19:27:27 +00003452 if (!InitializedBases.insert(Context.getCanonicalType(Base->getType()))) {
3453 SawLastInitializer
3454 = NumInitializers > 0 &&
3455 Initializers[NumInitializers - 1]->isBaseInitializer() &&
3456 Context.hasSameUnqualifiedType(Base->getType(),
3457 QualType(Initializers[NumInitializers - 1]->getBaseClass(), 0));
Douglas Gregor0133f522010-08-28 00:00:50 +00003458 continue;
Douglas Gregor0c431c82010-08-29 19:27:27 +00003459 }
Douglas Gregor0133f522010-08-28 00:00:50 +00003460
3461 CodeCompletionString *Pattern = new CodeCompletionString;
3462 Pattern->AddTypedTextChunk(
3463 Base->getType().getAsString(Context.PrintingPolicy));
3464 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
3465 Pattern->AddPlaceholderChunk("args");
3466 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
Douglas Gregor0c431c82010-08-29 19:27:27 +00003467 Results.AddResult(CodeCompletionResult(Pattern,
3468 SawLastInitializer? CCP_NextInitializer
3469 : CCP_MemberDeclaration));
3470 SawLastInitializer = false;
Douglas Gregor0133f522010-08-28 00:00:50 +00003471 }
3472
3473 // Add completions for members.
3474 for (CXXRecordDecl::field_iterator Field = ClassDecl->field_begin(),
3475 FieldEnd = ClassDecl->field_end();
3476 Field != FieldEnd; ++Field) {
Douglas Gregor0c431c82010-08-29 19:27:27 +00003477 if (!InitializedFields.insert(cast<FieldDecl>(Field->getCanonicalDecl()))) {
3478 SawLastInitializer
3479 = NumInitializers > 0 &&
3480 Initializers[NumInitializers - 1]->isMemberInitializer() &&
3481 Initializers[NumInitializers - 1]->getMember() == *Field;
Douglas Gregor0133f522010-08-28 00:00:50 +00003482 continue;
Douglas Gregor0c431c82010-08-29 19:27:27 +00003483 }
Douglas Gregor0133f522010-08-28 00:00:50 +00003484
3485 if (!Field->getDeclName())
3486 continue;
3487
3488 CodeCompletionString *Pattern = new CodeCompletionString;
3489 Pattern->AddTypedTextChunk(Field->getIdentifier()->getName());
3490 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
3491 Pattern->AddPlaceholderChunk("args");
3492 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
Douglas Gregor0c431c82010-08-29 19:27:27 +00003493 Results.AddResult(CodeCompletionResult(Pattern,
3494 SawLastInitializer? CCP_NextInitializer
Douglas Gregora67e03f2010-09-09 21:42:20 +00003495 : CCP_MemberDeclaration,
3496 CXCursor_MemberRef));
Douglas Gregor0c431c82010-08-29 19:27:27 +00003497 SawLastInitializer = false;
Douglas Gregor0133f522010-08-28 00:00:50 +00003498 }
3499 Results.ExitScope();
3500
3501 HandleCodeCompleteResults(this, CodeCompleter,
3502 CodeCompletionContext::CCC_Name,
3503 Results.data(), Results.size());
3504}
3505
Douglas Gregorb6ac2452010-01-13 21:24:21 +00003506// Macro that expands to @Keyword or Keyword, depending on whether NeedAt is
3507// true or false.
3508#define OBJC_AT_KEYWORD_NAME(NeedAt,Keyword) NeedAt? "@" #Keyword : #Keyword
Douglas Gregorbca403c2010-01-13 23:51:12 +00003509static void AddObjCImplementationResults(const LangOptions &LangOpts,
Douglas Gregorb6ac2452010-01-13 21:24:21 +00003510 ResultBuilder &Results,
3511 bool NeedAt) {
John McCall0a2c5e22010-08-25 06:19:51 +00003512 typedef CodeCompletionResult Result;
Douglas Gregorb6ac2452010-01-13 21:24:21 +00003513 // Since we have an implementation, we can end it.
Douglas Gregora4477812010-01-14 16:01:26 +00003514 Results.AddResult(Result(OBJC_AT_KEYWORD_NAME(NeedAt,end)));
Douglas Gregorb6ac2452010-01-13 21:24:21 +00003515
3516 CodeCompletionString *Pattern = 0;
3517 if (LangOpts.ObjC2) {
3518 // @dynamic
3519 Pattern = new CodeCompletionString;
3520 Pattern->AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt,dynamic));
3521 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
3522 Pattern->AddPlaceholderChunk("property");
Douglas Gregora4477812010-01-14 16:01:26 +00003523 Results.AddResult(Result(Pattern));
Douglas Gregorb6ac2452010-01-13 21:24:21 +00003524
3525 // @synthesize
3526 Pattern = new CodeCompletionString;
3527 Pattern->AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt,synthesize));
3528 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
3529 Pattern->AddPlaceholderChunk("property");
Douglas Gregora4477812010-01-14 16:01:26 +00003530 Results.AddResult(Result(Pattern));
Douglas Gregorb6ac2452010-01-13 21:24:21 +00003531 }
3532}
3533
Douglas Gregorbca403c2010-01-13 23:51:12 +00003534static void AddObjCInterfaceResults(const LangOptions &LangOpts,
Douglas Gregorb6ac2452010-01-13 21:24:21 +00003535 ResultBuilder &Results,
3536 bool NeedAt) {
John McCall0a2c5e22010-08-25 06:19:51 +00003537 typedef CodeCompletionResult Result;
Douglas Gregorb6ac2452010-01-13 21:24:21 +00003538
3539 // Since we have an interface or protocol, we can end it.
Douglas Gregora4477812010-01-14 16:01:26 +00003540 Results.AddResult(Result(OBJC_AT_KEYWORD_NAME(NeedAt,end)));
Douglas Gregorb6ac2452010-01-13 21:24:21 +00003541
3542 if (LangOpts.ObjC2) {
3543 // @property
Douglas Gregora4477812010-01-14 16:01:26 +00003544 Results.AddResult(Result(OBJC_AT_KEYWORD_NAME(NeedAt,property)));
Douglas Gregorb6ac2452010-01-13 21:24:21 +00003545
3546 // @required
Douglas Gregora4477812010-01-14 16:01:26 +00003547 Results.AddResult(Result(OBJC_AT_KEYWORD_NAME(NeedAt,required)));
Douglas Gregorb6ac2452010-01-13 21:24:21 +00003548
3549 // @optional
Douglas Gregora4477812010-01-14 16:01:26 +00003550 Results.AddResult(Result(OBJC_AT_KEYWORD_NAME(NeedAt,optional)));
Douglas Gregorb6ac2452010-01-13 21:24:21 +00003551 }
3552}
3553
Douglas Gregorbca403c2010-01-13 23:51:12 +00003554static void AddObjCTopLevelResults(ResultBuilder &Results, bool NeedAt) {
John McCall0a2c5e22010-08-25 06:19:51 +00003555 typedef CodeCompletionResult Result;
Douglas Gregorb6ac2452010-01-13 21:24:21 +00003556 CodeCompletionString *Pattern = 0;
3557
3558 // @class name ;
3559 Pattern = new CodeCompletionString;
3560 Pattern->AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt,class));
3561 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
Douglas Gregorc8bddde2010-05-28 00:22:41 +00003562 Pattern->AddPlaceholderChunk("name");
Douglas Gregora4477812010-01-14 16:01:26 +00003563 Results.AddResult(Result(Pattern));
Douglas Gregorb6ac2452010-01-13 21:24:21 +00003564
Douglas Gregorc8bddde2010-05-28 00:22:41 +00003565 if (Results.includeCodePatterns()) {
3566 // @interface name
3567 // FIXME: Could introduce the whole pattern, including superclasses and
3568 // such.
3569 Pattern = new CodeCompletionString;
3570 Pattern->AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt,interface));
3571 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
3572 Pattern->AddPlaceholderChunk("class");
3573 Results.AddResult(Result(Pattern));
Douglas Gregorb6ac2452010-01-13 21:24:21 +00003574
Douglas Gregorc8bddde2010-05-28 00:22:41 +00003575 // @protocol name
3576 Pattern = new CodeCompletionString;
3577 Pattern->AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt,protocol));
3578 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
3579 Pattern->AddPlaceholderChunk("protocol");
3580 Results.AddResult(Result(Pattern));
3581
3582 // @implementation name
3583 Pattern = new CodeCompletionString;
3584 Pattern->AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt,implementation));
3585 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
3586 Pattern->AddPlaceholderChunk("class");
3587 Results.AddResult(Result(Pattern));
3588 }
Douglas Gregorb6ac2452010-01-13 21:24:21 +00003589
3590 // @compatibility_alias name
3591 Pattern = new CodeCompletionString;
3592 Pattern->AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt,compatibility_alias));
3593 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
3594 Pattern->AddPlaceholderChunk("alias");
3595 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
3596 Pattern->AddPlaceholderChunk("class");
Douglas Gregora4477812010-01-14 16:01:26 +00003597 Results.AddResult(Result(Pattern));
Douglas Gregorb6ac2452010-01-13 21:24:21 +00003598}
3599
John McCalld226f652010-08-21 09:40:31 +00003600void Sema::CodeCompleteObjCAtDirective(Scope *S, Decl *ObjCImpDecl,
Douglas Gregorc464ae82009-12-07 09:27:33 +00003601 bool InInterface) {
John McCall0a2c5e22010-08-25 06:19:51 +00003602 typedef CodeCompletionResult Result;
Douglas Gregorc464ae82009-12-07 09:27:33 +00003603 ResultBuilder Results(*this);
3604 Results.EnterNewScope();
Douglas Gregorb6ac2452010-01-13 21:24:21 +00003605 if (ObjCImpDecl)
Douglas Gregorbca403c2010-01-13 23:51:12 +00003606 AddObjCImplementationResults(getLangOptions(), Results, false);
Douglas Gregorb6ac2452010-01-13 21:24:21 +00003607 else if (InInterface)
Douglas Gregorbca403c2010-01-13 23:51:12 +00003608 AddObjCInterfaceResults(getLangOptions(), Results, false);
Douglas Gregorb6ac2452010-01-13 21:24:21 +00003609 else
Douglas Gregorbca403c2010-01-13 23:51:12 +00003610 AddObjCTopLevelResults(Results, false);
Douglas Gregorc464ae82009-12-07 09:27:33 +00003611 Results.ExitScope();
Douglas Gregore6b1bb62010-08-11 21:23:17 +00003612 HandleCodeCompleteResults(this, CodeCompleter,
3613 CodeCompletionContext::CCC_Other,
3614 Results.data(),Results.size());
Douglas Gregorc464ae82009-12-07 09:27:33 +00003615}
3616
Douglas Gregorbca403c2010-01-13 23:51:12 +00003617static void AddObjCExpressionResults(ResultBuilder &Results, bool NeedAt) {
John McCall0a2c5e22010-08-25 06:19:51 +00003618 typedef CodeCompletionResult Result;
Douglas Gregor9a0c85e2009-12-07 09:51:25 +00003619 CodeCompletionString *Pattern = 0;
3620
3621 // @encode ( type-name )
3622 Pattern = new CodeCompletionString;
Douglas Gregorb6ac2452010-01-13 21:24:21 +00003623 Pattern->AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt,encode));
Douglas Gregor9a0c85e2009-12-07 09:51:25 +00003624 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
3625 Pattern->AddPlaceholderChunk("type-name");
3626 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
Douglas Gregora4477812010-01-14 16:01:26 +00003627 Results.AddResult(Result(Pattern));
Douglas Gregor9a0c85e2009-12-07 09:51:25 +00003628
3629 // @protocol ( protocol-name )
3630 Pattern = new CodeCompletionString;
Douglas Gregorb6ac2452010-01-13 21:24:21 +00003631 Pattern->AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt,protocol));
Douglas Gregor9a0c85e2009-12-07 09:51:25 +00003632 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
3633 Pattern->AddPlaceholderChunk("protocol-name");
3634 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
Douglas Gregora4477812010-01-14 16:01:26 +00003635 Results.AddResult(Result(Pattern));
Douglas Gregor9a0c85e2009-12-07 09:51:25 +00003636
3637 // @selector ( selector )
3638 Pattern = new CodeCompletionString;
Douglas Gregorb6ac2452010-01-13 21:24:21 +00003639 Pattern->AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt,selector));
Douglas Gregor9a0c85e2009-12-07 09:51:25 +00003640 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
3641 Pattern->AddPlaceholderChunk("selector");
3642 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
Douglas Gregora4477812010-01-14 16:01:26 +00003643 Results.AddResult(Result(Pattern));
Douglas Gregor9a0c85e2009-12-07 09:51:25 +00003644}
3645
Douglas Gregorbca403c2010-01-13 23:51:12 +00003646static void AddObjCStatementResults(ResultBuilder &Results, bool NeedAt) {
John McCall0a2c5e22010-08-25 06:19:51 +00003647 typedef CodeCompletionResult Result;
Douglas Gregor9a0c85e2009-12-07 09:51:25 +00003648 CodeCompletionString *Pattern = 0;
Douglas Gregorb6ac2452010-01-13 21:24:21 +00003649
Douglas Gregorc8bddde2010-05-28 00:22:41 +00003650 if (Results.includeCodePatterns()) {
3651 // @try { statements } @catch ( declaration ) { statements } @finally
3652 // { statements }
3653 Pattern = new CodeCompletionString;
3654 Pattern->AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt,try));
3655 Pattern->AddChunk(CodeCompletionString::CK_LeftBrace);
3656 Pattern->AddPlaceholderChunk("statements");
3657 Pattern->AddChunk(CodeCompletionString::CK_RightBrace);
3658 Pattern->AddTextChunk("@catch");
3659 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
3660 Pattern->AddPlaceholderChunk("parameter");
3661 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
3662 Pattern->AddChunk(CodeCompletionString::CK_LeftBrace);
3663 Pattern->AddPlaceholderChunk("statements");
3664 Pattern->AddChunk(CodeCompletionString::CK_RightBrace);
3665 Pattern->AddTextChunk("@finally");
3666 Pattern->AddChunk(CodeCompletionString::CK_LeftBrace);
3667 Pattern->AddPlaceholderChunk("statements");
3668 Pattern->AddChunk(CodeCompletionString::CK_RightBrace);
3669 Results.AddResult(Result(Pattern));
3670 }
Douglas Gregorb6ac2452010-01-13 21:24:21 +00003671
Douglas Gregor9a0c85e2009-12-07 09:51:25 +00003672 // @throw
3673 Pattern = new CodeCompletionString;
Douglas Gregorb6ac2452010-01-13 21:24:21 +00003674 Pattern->AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt,throw));
Douglas Gregor834389b2010-01-12 06:38:28 +00003675 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
Douglas Gregor9a0c85e2009-12-07 09:51:25 +00003676 Pattern->AddPlaceholderChunk("expression");
Douglas Gregora4477812010-01-14 16:01:26 +00003677 Results.AddResult(Result(Pattern));
Douglas Gregorb6ac2452010-01-13 21:24:21 +00003678
Douglas Gregorc8bddde2010-05-28 00:22:41 +00003679 if (Results.includeCodePatterns()) {
3680 // @synchronized ( expression ) { statements }
3681 Pattern = new CodeCompletionString;
3682 Pattern->AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt,synchronized));
3683 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
3684 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
3685 Pattern->AddPlaceholderChunk("expression");
3686 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
3687 Pattern->AddChunk(CodeCompletionString::CK_LeftBrace);
3688 Pattern->AddPlaceholderChunk("statements");
3689 Pattern->AddChunk(CodeCompletionString::CK_RightBrace);
3690 Results.AddResult(Result(Pattern));
3691 }
Douglas Gregorb6ac2452010-01-13 21:24:21 +00003692}
Douglas Gregor9a0c85e2009-12-07 09:51:25 +00003693
Douglas Gregorbca403c2010-01-13 23:51:12 +00003694static void AddObjCVisibilityResults(const LangOptions &LangOpts,
Douglas Gregorc38c3e12010-01-13 21:54:15 +00003695 ResultBuilder &Results,
3696 bool NeedAt) {
John McCall0a2c5e22010-08-25 06:19:51 +00003697 typedef CodeCompletionResult Result;
Douglas Gregora4477812010-01-14 16:01:26 +00003698 Results.AddResult(Result(OBJC_AT_KEYWORD_NAME(NeedAt,private)));
3699 Results.AddResult(Result(OBJC_AT_KEYWORD_NAME(NeedAt,protected)));
3700 Results.AddResult(Result(OBJC_AT_KEYWORD_NAME(NeedAt,public)));
Douglas Gregorc38c3e12010-01-13 21:54:15 +00003701 if (LangOpts.ObjC2)
Douglas Gregora4477812010-01-14 16:01:26 +00003702 Results.AddResult(Result(OBJC_AT_KEYWORD_NAME(NeedAt,package)));
Douglas Gregorc38c3e12010-01-13 21:54:15 +00003703}
3704
3705void Sema::CodeCompleteObjCAtVisibility(Scope *S) {
3706 ResultBuilder Results(*this);
3707 Results.EnterNewScope();
Douglas Gregorbca403c2010-01-13 23:51:12 +00003708 AddObjCVisibilityResults(getLangOptions(), Results, false);
Douglas Gregorc38c3e12010-01-13 21:54:15 +00003709 Results.ExitScope();
Douglas Gregore6b1bb62010-08-11 21:23:17 +00003710 HandleCodeCompleteResults(this, CodeCompleter,
3711 CodeCompletionContext::CCC_Other,
3712 Results.data(),Results.size());
Douglas Gregorc38c3e12010-01-13 21:54:15 +00003713}
3714
3715void Sema::CodeCompleteObjCAtStatement(Scope *S) {
Douglas Gregorb6ac2452010-01-13 21:24:21 +00003716 ResultBuilder Results(*this);
3717 Results.EnterNewScope();
Douglas Gregorbca403c2010-01-13 23:51:12 +00003718 AddObjCStatementResults(Results, false);
3719 AddObjCExpressionResults(Results, false);
Douglas Gregor9a0c85e2009-12-07 09:51:25 +00003720 Results.ExitScope();
Douglas Gregore6b1bb62010-08-11 21:23:17 +00003721 HandleCodeCompleteResults(this, CodeCompleter,
3722 CodeCompletionContext::CCC_Other,
3723 Results.data(),Results.size());
Douglas Gregor9a0c85e2009-12-07 09:51:25 +00003724}
3725
3726void Sema::CodeCompleteObjCAtExpression(Scope *S) {
3727 ResultBuilder Results(*this);
3728 Results.EnterNewScope();
Douglas Gregorbca403c2010-01-13 23:51:12 +00003729 AddObjCExpressionResults(Results, false);
Douglas Gregor9a0c85e2009-12-07 09:51:25 +00003730 Results.ExitScope();
Douglas Gregore6b1bb62010-08-11 21:23:17 +00003731 HandleCodeCompleteResults(this, CodeCompleter,
3732 CodeCompletionContext::CCC_Other,
3733 Results.data(),Results.size());
Douglas Gregor9a0c85e2009-12-07 09:51:25 +00003734}
3735
Douglas Gregor988358f2009-11-19 00:14:45 +00003736/// \brief Determine whether the addition of the given flag to an Objective-C
3737/// property's attributes will cause a conflict.
3738static bool ObjCPropertyFlagConflicts(unsigned Attributes, unsigned NewFlag) {
3739 // Check if we've already added this flag.
3740 if (Attributes & NewFlag)
3741 return true;
3742
3743 Attributes |= NewFlag;
3744
3745 // Check for collisions with "readonly".
3746 if ((Attributes & ObjCDeclSpec::DQ_PR_readonly) &&
3747 (Attributes & (ObjCDeclSpec::DQ_PR_readwrite |
3748 ObjCDeclSpec::DQ_PR_assign |
3749 ObjCDeclSpec::DQ_PR_copy |
3750 ObjCDeclSpec::DQ_PR_retain)))
3751 return true;
3752
3753 // Check for more than one of { assign, copy, retain }.
3754 unsigned AssignCopyRetMask = Attributes & (ObjCDeclSpec::DQ_PR_assign |
3755 ObjCDeclSpec::DQ_PR_copy |
3756 ObjCDeclSpec::DQ_PR_retain);
3757 if (AssignCopyRetMask &&
3758 AssignCopyRetMask != ObjCDeclSpec::DQ_PR_assign &&
3759 AssignCopyRetMask != ObjCDeclSpec::DQ_PR_copy &&
3760 AssignCopyRetMask != ObjCDeclSpec::DQ_PR_retain)
3761 return true;
3762
3763 return false;
3764}
3765
Douglas Gregora93b1082009-11-18 23:08:07 +00003766void Sema::CodeCompleteObjCPropertyFlags(Scope *S, ObjCDeclSpec &ODS) {
Steve Naroffece8e712009-10-08 21:55:05 +00003767 if (!CodeCompleter)
3768 return;
Douglas Gregord3c68542009-11-19 01:08:35 +00003769
Steve Naroffece8e712009-10-08 21:55:05 +00003770 unsigned Attributes = ODS.getPropertyAttributes();
3771
John McCall0a2c5e22010-08-25 06:19:51 +00003772 typedef CodeCompletionResult Result;
Steve Naroffece8e712009-10-08 21:55:05 +00003773 ResultBuilder Results(*this);
3774 Results.EnterNewScope();
Douglas Gregor988358f2009-11-19 00:14:45 +00003775 if (!ObjCPropertyFlagConflicts(Attributes, ObjCDeclSpec::DQ_PR_readonly))
John McCall0a2c5e22010-08-25 06:19:51 +00003776 Results.AddResult(CodeCompletionResult("readonly"));
Douglas Gregor988358f2009-11-19 00:14:45 +00003777 if (!ObjCPropertyFlagConflicts(Attributes, ObjCDeclSpec::DQ_PR_assign))
John McCall0a2c5e22010-08-25 06:19:51 +00003778 Results.AddResult(CodeCompletionResult("assign"));
Douglas Gregor988358f2009-11-19 00:14:45 +00003779 if (!ObjCPropertyFlagConflicts(Attributes, ObjCDeclSpec::DQ_PR_readwrite))
John McCall0a2c5e22010-08-25 06:19:51 +00003780 Results.AddResult(CodeCompletionResult("readwrite"));
Douglas Gregor988358f2009-11-19 00:14:45 +00003781 if (!ObjCPropertyFlagConflicts(Attributes, ObjCDeclSpec::DQ_PR_retain))
John McCall0a2c5e22010-08-25 06:19:51 +00003782 Results.AddResult(CodeCompletionResult("retain"));
Douglas Gregor988358f2009-11-19 00:14:45 +00003783 if (!ObjCPropertyFlagConflicts(Attributes, ObjCDeclSpec::DQ_PR_copy))
John McCall0a2c5e22010-08-25 06:19:51 +00003784 Results.AddResult(CodeCompletionResult("copy"));
Douglas Gregor988358f2009-11-19 00:14:45 +00003785 if (!ObjCPropertyFlagConflicts(Attributes, ObjCDeclSpec::DQ_PR_nonatomic))
John McCall0a2c5e22010-08-25 06:19:51 +00003786 Results.AddResult(CodeCompletionResult("nonatomic"));
Douglas Gregor988358f2009-11-19 00:14:45 +00003787 if (!ObjCPropertyFlagConflicts(Attributes, ObjCDeclSpec::DQ_PR_setter)) {
Douglas Gregor54f01612009-11-19 00:01:57 +00003788 CodeCompletionString *Setter = new CodeCompletionString;
3789 Setter->AddTypedTextChunk("setter");
3790 Setter->AddTextChunk(" = ");
3791 Setter->AddPlaceholderChunk("method");
John McCall0a2c5e22010-08-25 06:19:51 +00003792 Results.AddResult(CodeCompletionResult(Setter));
Douglas Gregor54f01612009-11-19 00:01:57 +00003793 }
Douglas Gregor988358f2009-11-19 00:14:45 +00003794 if (!ObjCPropertyFlagConflicts(Attributes, ObjCDeclSpec::DQ_PR_getter)) {
Douglas Gregor54f01612009-11-19 00:01:57 +00003795 CodeCompletionString *Getter = new CodeCompletionString;
3796 Getter->AddTypedTextChunk("getter");
3797 Getter->AddTextChunk(" = ");
3798 Getter->AddPlaceholderChunk("method");
John McCall0a2c5e22010-08-25 06:19:51 +00003799 Results.AddResult(CodeCompletionResult(Getter));
Douglas Gregor54f01612009-11-19 00:01:57 +00003800 }
Steve Naroffece8e712009-10-08 21:55:05 +00003801 Results.ExitScope();
Douglas Gregore6b1bb62010-08-11 21:23:17 +00003802 HandleCodeCompleteResults(this, CodeCompleter,
3803 CodeCompletionContext::CCC_Other,
3804 Results.data(),Results.size());
Steve Naroffece8e712009-10-08 21:55:05 +00003805}
Steve Naroffc4df6d22009-11-07 02:08:14 +00003806
Douglas Gregor4ad96852009-11-19 07:41:15 +00003807/// \brief Descripts the kind of Objective-C method that we want to find
3808/// via code completion.
3809enum ObjCMethodKind {
3810 MK_Any, //< Any kind of method, provided it means other specified criteria.
3811 MK_ZeroArgSelector, //< Zero-argument (unary) selector.
3812 MK_OneArgSelector //< One-argument selector.
3813};
3814
Douglas Gregor458433d2010-08-26 15:07:07 +00003815static bool isAcceptableObjCSelector(Selector Sel,
3816 ObjCMethodKind WantKind,
3817 IdentifierInfo **SelIdents,
3818 unsigned NumSelIdents) {
3819 if (NumSelIdents > Sel.getNumArgs())
3820 return false;
3821
3822 switch (WantKind) {
3823 case MK_Any: break;
3824 case MK_ZeroArgSelector: return Sel.isUnarySelector();
3825 case MK_OneArgSelector: return Sel.getNumArgs() == 1;
3826 }
3827
3828 for (unsigned I = 0; I != NumSelIdents; ++I)
3829 if (SelIdents[I] != Sel.getIdentifierInfoForSlot(I))
3830 return false;
3831
3832 return true;
3833}
3834
Douglas Gregor4ad96852009-11-19 07:41:15 +00003835static bool isAcceptableObjCMethod(ObjCMethodDecl *Method,
3836 ObjCMethodKind WantKind,
3837 IdentifierInfo **SelIdents,
3838 unsigned NumSelIdents) {
Douglas Gregor458433d2010-08-26 15:07:07 +00003839 return isAcceptableObjCSelector(Method->getSelector(), WantKind, SelIdents,
3840 NumSelIdents);
Douglas Gregor4ad96852009-11-19 07:41:15 +00003841}
Douglas Gregord36adf52010-09-16 16:06:31 +00003842
3843namespace {
3844 /// \brief A set of selectors, which is used to avoid introducing multiple
3845 /// completions with the same selector into the result set.
3846 typedef llvm::SmallPtrSet<Selector, 16> VisitedSelectorSet;
3847}
3848
Douglas Gregor36ecb042009-11-17 23:22:23 +00003849/// \brief Add all of the Objective-C methods in the given Objective-C
3850/// container to the set of results.
3851///
3852/// The container will be a class, protocol, category, or implementation of
3853/// any of the above. This mether will recurse to include methods from
3854/// the superclasses of classes along with their categories, protocols, and
3855/// implementations.
3856///
3857/// \param Container the container in which we'll look to find methods.
3858///
3859/// \param WantInstance whether to add instance methods (only); if false, this
3860/// routine will add factory methods (only).
3861///
3862/// \param CurContext the context in which we're performing the lookup that
3863/// finds methods.
3864///
3865/// \param Results the structure into which we'll add results.
3866static void AddObjCMethods(ObjCContainerDecl *Container,
3867 bool WantInstanceMethods,
Douglas Gregor4ad96852009-11-19 07:41:15 +00003868 ObjCMethodKind WantKind,
Douglas Gregord3c68542009-11-19 01:08:35 +00003869 IdentifierInfo **SelIdents,
3870 unsigned NumSelIdents,
Douglas Gregor36ecb042009-11-17 23:22:23 +00003871 DeclContext *CurContext,
Douglas Gregord36adf52010-09-16 16:06:31 +00003872 VisitedSelectorSet &Selectors,
Douglas Gregor408be5a2010-08-25 01:08:01 +00003873 ResultBuilder &Results,
3874 bool InOriginalClass = true) {
John McCall0a2c5e22010-08-25 06:19:51 +00003875 typedef CodeCompletionResult Result;
Douglas Gregor36ecb042009-11-17 23:22:23 +00003876 for (ObjCContainerDecl::method_iterator M = Container->meth_begin(),
3877 MEnd = Container->meth_end();
3878 M != MEnd; ++M) {
Douglas Gregord3c68542009-11-19 01:08:35 +00003879 if ((*M)->isInstanceMethod() == WantInstanceMethods) {
3880 // Check whether the selector identifiers we've been given are a
3881 // subset of the identifiers for this particular method.
Douglas Gregor4ad96852009-11-19 07:41:15 +00003882 if (!isAcceptableObjCMethod(*M, WantKind, SelIdents, NumSelIdents))
Douglas Gregord3c68542009-11-19 01:08:35 +00003883 continue;
Douglas Gregor4ad96852009-11-19 07:41:15 +00003884
Douglas Gregord36adf52010-09-16 16:06:31 +00003885 if (!Selectors.insert((*M)->getSelector()))
3886 continue;
3887
Douglas Gregord3c68542009-11-19 01:08:35 +00003888 Result R = Result(*M, 0);
3889 R.StartParameter = NumSelIdents;
Douglas Gregor4ad96852009-11-19 07:41:15 +00003890 R.AllParametersAreInformative = (WantKind != MK_Any);
Douglas Gregor408be5a2010-08-25 01:08:01 +00003891 if (!InOriginalClass)
3892 R.Priority += CCD_InBaseClass;
Douglas Gregord3c68542009-11-19 01:08:35 +00003893 Results.MaybeAddResult(R, CurContext);
3894 }
Douglas Gregor36ecb042009-11-17 23:22:23 +00003895 }
3896
Douglas Gregore396c7b2010-09-16 15:34:59 +00003897 // Visit the protocols of protocols.
3898 if (ObjCProtocolDecl *Protocol = dyn_cast<ObjCProtocolDecl>(Container)) {
3899 const ObjCList<ObjCProtocolDecl> &Protocols
3900 = Protocol->getReferencedProtocols();
3901 for (ObjCList<ObjCProtocolDecl>::iterator I = Protocols.begin(),
3902 E = Protocols.end();
3903 I != E; ++I)
3904 AddObjCMethods(*I, WantInstanceMethods, WantKind, SelIdents, NumSelIdents,
Douglas Gregord36adf52010-09-16 16:06:31 +00003905 CurContext, Selectors, Results, false);
Douglas Gregore396c7b2010-09-16 15:34:59 +00003906 }
3907
Douglas Gregor36ecb042009-11-17 23:22:23 +00003908 ObjCInterfaceDecl *IFace = dyn_cast<ObjCInterfaceDecl>(Container);
3909 if (!IFace)
3910 return;
3911
3912 // Add methods in protocols.
3913 const ObjCList<ObjCProtocolDecl> &Protocols= IFace->getReferencedProtocols();
3914 for (ObjCList<ObjCProtocolDecl>::iterator I = Protocols.begin(),
3915 E = Protocols.end();
3916 I != E; ++I)
Douglas Gregor4ad96852009-11-19 07:41:15 +00003917 AddObjCMethods(*I, WantInstanceMethods, WantKind, SelIdents, NumSelIdents,
Douglas Gregord36adf52010-09-16 16:06:31 +00003918 CurContext, Selectors, Results, false);
Douglas Gregor36ecb042009-11-17 23:22:23 +00003919
3920 // Add methods in categories.
3921 for (ObjCCategoryDecl *CatDecl = IFace->getCategoryList(); CatDecl;
3922 CatDecl = CatDecl->getNextClassCategory()) {
Douglas Gregor4ad96852009-11-19 07:41:15 +00003923 AddObjCMethods(CatDecl, WantInstanceMethods, WantKind, SelIdents,
Douglas Gregord36adf52010-09-16 16:06:31 +00003924 NumSelIdents, CurContext, Selectors, Results,
3925 InOriginalClass);
Douglas Gregor36ecb042009-11-17 23:22:23 +00003926
3927 // Add a categories protocol methods.
3928 const ObjCList<ObjCProtocolDecl> &Protocols
3929 = CatDecl->getReferencedProtocols();
3930 for (ObjCList<ObjCProtocolDecl>::iterator I = Protocols.begin(),
3931 E = Protocols.end();
3932 I != E; ++I)
Douglas Gregor4ad96852009-11-19 07:41:15 +00003933 AddObjCMethods(*I, WantInstanceMethods, WantKind, SelIdents,
Douglas Gregord36adf52010-09-16 16:06:31 +00003934 NumSelIdents, CurContext, Selectors, Results, false);
Douglas Gregor36ecb042009-11-17 23:22:23 +00003935
3936 // Add methods in category implementations.
3937 if (ObjCCategoryImplDecl *Impl = CatDecl->getImplementation())
Douglas Gregor4ad96852009-11-19 07:41:15 +00003938 AddObjCMethods(Impl, WantInstanceMethods, WantKind, SelIdents,
Douglas Gregord36adf52010-09-16 16:06:31 +00003939 NumSelIdents, CurContext, Selectors, Results,
3940 InOriginalClass);
Douglas Gregor36ecb042009-11-17 23:22:23 +00003941 }
3942
3943 // Add methods in superclass.
3944 if (IFace->getSuperClass())
Douglas Gregor4ad96852009-11-19 07:41:15 +00003945 AddObjCMethods(IFace->getSuperClass(), WantInstanceMethods, WantKind,
Douglas Gregord36adf52010-09-16 16:06:31 +00003946 SelIdents, NumSelIdents, CurContext, Selectors, Results,
3947 false);
Douglas Gregor36ecb042009-11-17 23:22:23 +00003948
3949 // Add methods in our implementation, if any.
3950 if (ObjCImplementationDecl *Impl = IFace->getImplementation())
Douglas Gregor4ad96852009-11-19 07:41:15 +00003951 AddObjCMethods(Impl, WantInstanceMethods, WantKind, SelIdents,
Douglas Gregord36adf52010-09-16 16:06:31 +00003952 NumSelIdents, CurContext, Selectors, Results,
3953 InOriginalClass);
Douglas Gregor4ad96852009-11-19 07:41:15 +00003954}
3955
3956
John McCalld226f652010-08-21 09:40:31 +00003957void Sema::CodeCompleteObjCPropertyGetter(Scope *S, Decl *ClassDecl,
3958 Decl **Methods,
Douglas Gregor4ad96852009-11-19 07:41:15 +00003959 unsigned NumMethods) {
John McCall0a2c5e22010-08-25 06:19:51 +00003960 typedef CodeCompletionResult Result;
Douglas Gregor4ad96852009-11-19 07:41:15 +00003961
3962 // Try to find the interface where getters might live.
John McCalld226f652010-08-21 09:40:31 +00003963 ObjCInterfaceDecl *Class = dyn_cast_or_null<ObjCInterfaceDecl>(ClassDecl);
Douglas Gregor4ad96852009-11-19 07:41:15 +00003964 if (!Class) {
3965 if (ObjCCategoryDecl *Category
John McCalld226f652010-08-21 09:40:31 +00003966 = dyn_cast_or_null<ObjCCategoryDecl>(ClassDecl))
Douglas Gregor4ad96852009-11-19 07:41:15 +00003967 Class = Category->getClassInterface();
3968
3969 if (!Class)
3970 return;
3971 }
3972
3973 // Find all of the potential getters.
3974 ResultBuilder Results(*this);
3975 Results.EnterNewScope();
3976
3977 // FIXME: We need to do this because Objective-C methods don't get
3978 // pushed into DeclContexts early enough. Argh!
3979 for (unsigned I = 0; I != NumMethods; ++I) {
3980 if (ObjCMethodDecl *Method
John McCalld226f652010-08-21 09:40:31 +00003981 = dyn_cast_or_null<ObjCMethodDecl>(Methods[I]))
Douglas Gregor4ad96852009-11-19 07:41:15 +00003982 if (Method->isInstanceMethod() &&
3983 isAcceptableObjCMethod(Method, MK_ZeroArgSelector, 0, 0)) {
3984 Result R = Result(Method, 0);
3985 R.AllParametersAreInformative = true;
3986 Results.MaybeAddResult(R, CurContext);
3987 }
3988 }
3989
Douglas Gregord36adf52010-09-16 16:06:31 +00003990 VisitedSelectorSet Selectors;
3991 AddObjCMethods(Class, true, MK_ZeroArgSelector, 0, 0, CurContext, Selectors,
3992 Results);
Douglas Gregor4ad96852009-11-19 07:41:15 +00003993 Results.ExitScope();
Douglas Gregore6b1bb62010-08-11 21:23:17 +00003994 HandleCodeCompleteResults(this, CodeCompleter,
3995 CodeCompletionContext::CCC_Other,
3996 Results.data(),Results.size());
Douglas Gregor4ad96852009-11-19 07:41:15 +00003997}
3998
John McCalld226f652010-08-21 09:40:31 +00003999void Sema::CodeCompleteObjCPropertySetter(Scope *S, Decl *ObjCImplDecl,
4000 Decl **Methods,
Douglas Gregor4ad96852009-11-19 07:41:15 +00004001 unsigned NumMethods) {
John McCall0a2c5e22010-08-25 06:19:51 +00004002 typedef CodeCompletionResult Result;
Douglas Gregor4ad96852009-11-19 07:41:15 +00004003
4004 // Try to find the interface where setters might live.
4005 ObjCInterfaceDecl *Class
John McCalld226f652010-08-21 09:40:31 +00004006 = dyn_cast_or_null<ObjCInterfaceDecl>(ObjCImplDecl);
Douglas Gregor4ad96852009-11-19 07:41:15 +00004007 if (!Class) {
4008 if (ObjCCategoryDecl *Category
John McCalld226f652010-08-21 09:40:31 +00004009 = dyn_cast_or_null<ObjCCategoryDecl>(ObjCImplDecl))
Douglas Gregor4ad96852009-11-19 07:41:15 +00004010 Class = Category->getClassInterface();
4011
4012 if (!Class)
4013 return;
4014 }
4015
4016 // Find all of the potential getters.
4017 ResultBuilder Results(*this);
4018 Results.EnterNewScope();
4019
4020 // FIXME: We need to do this because Objective-C methods don't get
4021 // pushed into DeclContexts early enough. Argh!
4022 for (unsigned I = 0; I != NumMethods; ++I) {
4023 if (ObjCMethodDecl *Method
John McCalld226f652010-08-21 09:40:31 +00004024 = dyn_cast_or_null<ObjCMethodDecl>(Methods[I]))
Douglas Gregor4ad96852009-11-19 07:41:15 +00004025 if (Method->isInstanceMethod() &&
4026 isAcceptableObjCMethod(Method, MK_OneArgSelector, 0, 0)) {
4027 Result R = Result(Method, 0);
4028 R.AllParametersAreInformative = true;
4029 Results.MaybeAddResult(R, CurContext);
4030 }
4031 }
4032
Douglas Gregord36adf52010-09-16 16:06:31 +00004033 VisitedSelectorSet Selectors;
4034 AddObjCMethods(Class, true, MK_OneArgSelector, 0, 0, CurContext,
4035 Selectors, Results);
Douglas Gregor4ad96852009-11-19 07:41:15 +00004036
4037 Results.ExitScope();
Douglas Gregore6b1bb62010-08-11 21:23:17 +00004038 HandleCodeCompleteResults(this, CodeCompleter,
4039 CodeCompletionContext::CCC_Other,
4040 Results.data(),Results.size());
Douglas Gregor36ecb042009-11-17 23:22:23 +00004041}
4042
Douglas Gregord32b0222010-08-24 01:06:58 +00004043void Sema::CodeCompleteObjCPassingType(Scope *S, ObjCDeclSpec &DS) {
John McCall0a2c5e22010-08-25 06:19:51 +00004044 typedef CodeCompletionResult Result;
Douglas Gregord32b0222010-08-24 01:06:58 +00004045 ResultBuilder Results(*this);
4046 Results.EnterNewScope();
4047
4048 // Add context-sensitive, Objective-C parameter-passing keywords.
4049 bool AddedInOut = false;
4050 if ((DS.getObjCDeclQualifier() &
4051 (ObjCDeclSpec::DQ_In | ObjCDeclSpec::DQ_Inout)) == 0) {
4052 Results.AddResult("in");
4053 Results.AddResult("inout");
4054 AddedInOut = true;
4055 }
4056 if ((DS.getObjCDeclQualifier() &
4057 (ObjCDeclSpec::DQ_Out | ObjCDeclSpec::DQ_Inout)) == 0) {
4058 Results.AddResult("out");
4059 if (!AddedInOut)
4060 Results.AddResult("inout");
4061 }
4062 if ((DS.getObjCDeclQualifier() &
4063 (ObjCDeclSpec::DQ_Bycopy | ObjCDeclSpec::DQ_Byref |
4064 ObjCDeclSpec::DQ_Oneway)) == 0) {
4065 Results.AddResult("bycopy");
4066 Results.AddResult("byref");
4067 Results.AddResult("oneway");
4068 }
4069
4070 // Add various builtin type names and specifiers.
4071 AddOrdinaryNameResults(PCC_Type, S, *this, Results);
4072 Results.ExitScope();
4073
4074 // Add the various type names
4075 Results.setFilter(&ResultBuilder::IsOrdinaryNonValueName);
4076 CodeCompletionDeclConsumer Consumer(Results, CurContext);
4077 LookupVisibleDecls(S, LookupOrdinaryName, Consumer,
4078 CodeCompleter->includeGlobals());
4079
4080 if (CodeCompleter->includeMacros())
4081 AddMacroResults(PP, Results);
4082
4083 HandleCodeCompleteResults(this, CodeCompleter,
4084 CodeCompletionContext::CCC_Type,
4085 Results.data(), Results.size());
4086}
4087
Douglas Gregor22f56992010-04-06 19:22:33 +00004088/// \brief When we have an expression with type "id", we may assume
4089/// that it has some more-specific class type based on knowledge of
4090/// common uses of Objective-C. This routine returns that class type,
4091/// or NULL if no better result could be determined.
4092static ObjCInterfaceDecl *GetAssumedMessageSendExprType(Expr *E) {
Douglas Gregor78edf512010-09-15 16:23:04 +00004093 ObjCMessageExpr *Msg = dyn_cast_or_null<ObjCMessageExpr>(E);
Douglas Gregor22f56992010-04-06 19:22:33 +00004094 if (!Msg)
4095 return 0;
4096
4097 Selector Sel = Msg->getSelector();
4098 if (Sel.isNull())
4099 return 0;
4100
4101 IdentifierInfo *Id = Sel.getIdentifierInfoForSlot(0);
4102 if (!Id)
4103 return 0;
4104
4105 ObjCMethodDecl *Method = Msg->getMethodDecl();
4106 if (!Method)
4107 return 0;
4108
4109 // Determine the class that we're sending the message to.
Douglas Gregor04badcf2010-04-21 00:45:42 +00004110 ObjCInterfaceDecl *IFace = 0;
4111 switch (Msg->getReceiverKind()) {
4112 case ObjCMessageExpr::Class:
John McCallc12c5bb2010-05-15 11:32:37 +00004113 if (const ObjCObjectType *ObjType
4114 = Msg->getClassReceiver()->getAs<ObjCObjectType>())
4115 IFace = ObjType->getInterface();
Douglas Gregor04badcf2010-04-21 00:45:42 +00004116 break;
4117
4118 case ObjCMessageExpr::Instance: {
4119 QualType T = Msg->getInstanceReceiver()->getType();
4120 if (const ObjCObjectPointerType *Ptr = T->getAs<ObjCObjectPointerType>())
4121 IFace = Ptr->getInterfaceDecl();
4122 break;
4123 }
4124
4125 case ObjCMessageExpr::SuperInstance:
4126 case ObjCMessageExpr::SuperClass:
4127 break;
Douglas Gregor22f56992010-04-06 19:22:33 +00004128 }
4129
4130 if (!IFace)
4131 return 0;
4132
4133 ObjCInterfaceDecl *Super = IFace->getSuperClass();
4134 if (Method->isInstanceMethod())
4135 return llvm::StringSwitch<ObjCInterfaceDecl *>(Id->getName())
4136 .Case("retain", IFace)
4137 .Case("autorelease", IFace)
4138 .Case("copy", IFace)
4139 .Case("copyWithZone", IFace)
4140 .Case("mutableCopy", IFace)
4141 .Case("mutableCopyWithZone", IFace)
4142 .Case("awakeFromCoder", IFace)
4143 .Case("replacementObjectFromCoder", IFace)
4144 .Case("class", IFace)
4145 .Case("classForCoder", IFace)
4146 .Case("superclass", Super)
4147 .Default(0);
4148
4149 return llvm::StringSwitch<ObjCInterfaceDecl *>(Id->getName())
4150 .Case("new", IFace)
4151 .Case("alloc", IFace)
4152 .Case("allocWithZone", IFace)
4153 .Case("class", IFace)
4154 .Case("superclass", Super)
4155 .Default(0);
4156}
4157
Douglas Gregor03d8aec2010-08-27 15:10:57 +00004158// Add a special completion for a message send to "super", which fills in the
4159// most likely case of forwarding all of our arguments to the superclass
4160// function.
4161///
4162/// \param S The semantic analysis object.
4163///
4164/// \param S NeedSuperKeyword Whether we need to prefix this completion with
4165/// the "super" keyword. Otherwise, we just need to provide the arguments.
4166///
4167/// \param SelIdents The identifiers in the selector that have already been
4168/// provided as arguments for a send to "super".
4169///
4170/// \param NumSelIdents The number of identifiers in \p SelIdents.
4171///
4172/// \param Results The set of results to augment.
4173///
4174/// \returns the Objective-C method declaration that would be invoked by
4175/// this "super" completion. If NULL, no completion was added.
4176static ObjCMethodDecl *AddSuperSendCompletion(Sema &S, bool NeedSuperKeyword,
4177 IdentifierInfo **SelIdents,
4178 unsigned NumSelIdents,
4179 ResultBuilder &Results) {
4180 ObjCMethodDecl *CurMethod = S.getCurMethodDecl();
4181 if (!CurMethod)
4182 return 0;
4183
4184 ObjCInterfaceDecl *Class = CurMethod->getClassInterface();
4185 if (!Class)
4186 return 0;
4187
4188 // Try to find a superclass method with the same selector.
4189 ObjCMethodDecl *SuperMethod = 0;
4190 while ((Class = Class->getSuperClass()) && !SuperMethod)
4191 SuperMethod = Class->getMethod(CurMethod->getSelector(),
4192 CurMethod->isInstanceMethod());
4193
4194 if (!SuperMethod)
4195 return 0;
4196
4197 // Check whether the superclass method has the same signature.
4198 if (CurMethod->param_size() != SuperMethod->param_size() ||
4199 CurMethod->isVariadic() != SuperMethod->isVariadic())
4200 return 0;
4201
4202 for (ObjCMethodDecl::param_iterator CurP = CurMethod->param_begin(),
4203 CurPEnd = CurMethod->param_end(),
4204 SuperP = SuperMethod->param_begin();
4205 CurP != CurPEnd; ++CurP, ++SuperP) {
4206 // Make sure the parameter types are compatible.
4207 if (!S.Context.hasSameUnqualifiedType((*CurP)->getType(),
4208 (*SuperP)->getType()))
4209 return 0;
4210
4211 // Make sure we have a parameter name to forward!
4212 if (!(*CurP)->getIdentifier())
4213 return 0;
4214 }
4215
4216 // We have a superclass method. Now, form the send-to-super completion.
4217 CodeCompletionString *Pattern = new CodeCompletionString;
4218
4219 // Give this completion a return type.
4220 AddResultTypeChunk(S.Context, SuperMethod, Pattern);
4221
4222 // If we need the "super" keyword, add it (plus some spacing).
4223 if (NeedSuperKeyword) {
4224 Pattern->AddTypedTextChunk("super");
4225 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
4226 }
4227
4228 Selector Sel = CurMethod->getSelector();
4229 if (Sel.isUnarySelector()) {
4230 if (NeedSuperKeyword)
4231 Pattern->AddTextChunk(Sel.getIdentifierInfoForSlot(0)->getName());
4232 else
4233 Pattern->AddTypedTextChunk(Sel.getIdentifierInfoForSlot(0)->getName());
4234 } else {
4235 ObjCMethodDecl::param_iterator CurP = CurMethod->param_begin();
4236 for (unsigned I = 0, N = Sel.getNumArgs(); I != N; ++I, ++CurP) {
4237 if (I > NumSelIdents)
4238 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
4239
4240 if (I < NumSelIdents)
4241 Pattern->AddInformativeChunk(
4242 Sel.getIdentifierInfoForSlot(I)->getName().str() + ":");
4243 else if (NeedSuperKeyword || I > NumSelIdents) {
4244 Pattern->AddTextChunk(
4245 Sel.getIdentifierInfoForSlot(I)->getName().str() + ":");
4246 Pattern->AddPlaceholderChunk((*CurP)->getIdentifier()->getName());
4247 } else {
4248 Pattern->AddTypedTextChunk(
4249 Sel.getIdentifierInfoForSlot(I)->getName().str() + ":");
4250 Pattern->AddPlaceholderChunk((*CurP)->getIdentifier()->getName());
4251 }
4252 }
4253 }
4254
4255 Results.AddResult(CodeCompletionResult(Pattern, CCP_SuperCompletion,
4256 SuperMethod->isInstanceMethod()
4257 ? CXCursor_ObjCInstanceMethodDecl
4258 : CXCursor_ObjCClassMethodDecl));
4259 return SuperMethod;
4260}
4261
Douglas Gregor8e254cf2010-05-27 23:06:34 +00004262void Sema::CodeCompleteObjCMessageReceiver(Scope *S) {
John McCall0a2c5e22010-08-25 06:19:51 +00004263 typedef CodeCompletionResult Result;
Douglas Gregor8e254cf2010-05-27 23:06:34 +00004264 ResultBuilder Results(*this);
4265
4266 // Find anything that looks like it could be a message receiver.
4267 Results.setFilter(&ResultBuilder::IsObjCMessageReceiver);
4268 CodeCompletionDeclConsumer Consumer(Results, CurContext);
4269 Results.EnterNewScope();
Douglas Gregor8071e422010-08-15 06:18:01 +00004270 LookupVisibleDecls(S, LookupOrdinaryName, Consumer,
4271 CodeCompleter->includeGlobals());
Douglas Gregor8e254cf2010-05-27 23:06:34 +00004272
4273 // If we are in an Objective-C method inside a class that has a superclass,
4274 // add "super" as an option.
4275 if (ObjCMethodDecl *Method = getCurMethodDecl())
4276 if (ObjCInterfaceDecl *Iface = Method->getClassInterface())
Douglas Gregor03d8aec2010-08-27 15:10:57 +00004277 if (Iface->getSuperClass()) {
Douglas Gregor8e254cf2010-05-27 23:06:34 +00004278 Results.AddResult(Result("super"));
Douglas Gregor03d8aec2010-08-27 15:10:57 +00004279
4280 AddSuperSendCompletion(*this, /*NeedSuperKeyword=*/true, 0, 0, Results);
4281 }
Douglas Gregor8e254cf2010-05-27 23:06:34 +00004282
4283 Results.ExitScope();
4284
4285 if (CodeCompleter->includeMacros())
4286 AddMacroResults(PP, Results);
Douglas Gregore6b1bb62010-08-11 21:23:17 +00004287 HandleCodeCompleteResults(this, CodeCompleter,
4288 CodeCompletionContext::CCC_ObjCMessageReceiver,
4289 Results.data(), Results.size());
Douglas Gregor8e254cf2010-05-27 23:06:34 +00004290
4291}
4292
Douglas Gregor2725ca82010-04-21 19:57:20 +00004293void Sema::CodeCompleteObjCSuperMessage(Scope *S, SourceLocation SuperLoc,
4294 IdentifierInfo **SelIdents,
4295 unsigned NumSelIdents) {
4296 ObjCInterfaceDecl *CDecl = 0;
4297 if (ObjCMethodDecl *CurMethod = getCurMethodDecl()) {
4298 // Figure out which interface we're in.
4299 CDecl = CurMethod->getClassInterface();
4300 if (!CDecl)
4301 return;
4302
4303 // Find the superclass of this class.
4304 CDecl = CDecl->getSuperClass();
4305 if (!CDecl)
4306 return;
4307
4308 if (CurMethod->isInstanceMethod()) {
4309 // We are inside an instance method, which means that the message
4310 // send [super ...] is actually calling an instance method on the
4311 // current object. Build the super expression and handle this like
4312 // an instance method.
4313 QualType SuperTy = Context.getObjCInterfaceType(CDecl);
4314 SuperTy = Context.getObjCObjectPointerType(SuperTy);
John McCall60d7b3a2010-08-24 06:29:42 +00004315 ExprResult Super
Douglas Gregor2725ca82010-04-21 19:57:20 +00004316 = Owned(new (Context) ObjCSuperExpr(SuperLoc, SuperTy));
4317 return CodeCompleteObjCInstanceMessage(S, (Expr *)Super.get(),
Douglas Gregor03d8aec2010-08-27 15:10:57 +00004318 SelIdents, NumSelIdents,
4319 /*IsSuper=*/true);
Douglas Gregor2725ca82010-04-21 19:57:20 +00004320 }
4321
4322 // Fall through to send to the superclass in CDecl.
4323 } else {
4324 // "super" may be the name of a type or variable. Figure out which
4325 // it is.
4326 IdentifierInfo *Super = &Context.Idents.get("super");
4327 NamedDecl *ND = LookupSingleName(S, Super, SuperLoc,
4328 LookupOrdinaryName);
4329 if ((CDecl = dyn_cast_or_null<ObjCInterfaceDecl>(ND))) {
4330 // "super" names an interface. Use it.
4331 } else if (TypeDecl *TD = dyn_cast_or_null<TypeDecl>(ND)) {
John McCallc12c5bb2010-05-15 11:32:37 +00004332 if (const ObjCObjectType *Iface
4333 = Context.getTypeDeclType(TD)->getAs<ObjCObjectType>())
4334 CDecl = Iface->getInterface();
Douglas Gregor2725ca82010-04-21 19:57:20 +00004335 } else if (ND && isa<UnresolvedUsingTypenameDecl>(ND)) {
4336 // "super" names an unresolved type; we can't be more specific.
4337 } else {
4338 // Assume that "super" names some kind of value and parse that way.
4339 CXXScopeSpec SS;
4340 UnqualifiedId id;
4341 id.setIdentifier(Super, SuperLoc);
John McCall60d7b3a2010-08-24 06:29:42 +00004342 ExprResult SuperExpr = ActOnIdExpression(S, SS, id, false, false);
Douglas Gregor2725ca82010-04-21 19:57:20 +00004343 return CodeCompleteObjCInstanceMessage(S, (Expr *)SuperExpr.get(),
4344 SelIdents, NumSelIdents);
4345 }
4346
4347 // Fall through
4348 }
4349
John McCallb3d87482010-08-24 05:47:05 +00004350 ParsedType Receiver;
Douglas Gregor2725ca82010-04-21 19:57:20 +00004351 if (CDecl)
John McCallb3d87482010-08-24 05:47:05 +00004352 Receiver = ParsedType::make(Context.getObjCInterfaceType(CDecl));
Douglas Gregor2725ca82010-04-21 19:57:20 +00004353 return CodeCompleteObjCClassMessage(S, Receiver, SelIdents,
Douglas Gregor03d8aec2010-08-27 15:10:57 +00004354 NumSelIdents, /*IsSuper=*/true);
Douglas Gregor2725ca82010-04-21 19:57:20 +00004355}
4356
Douglas Gregorc7b6d882010-09-16 15:14:18 +00004357static void AddClassMessageCompletions(Sema &SemaRef, Scope *S,
4358 ParsedType Receiver,
4359 IdentifierInfo **SelIdents,
4360 unsigned NumSelIdents,
4361 bool IsSuper,
4362 ResultBuilder &Results) {
John McCall0a2c5e22010-08-25 06:19:51 +00004363 typedef CodeCompletionResult Result;
Douglas Gregor24a069f2009-11-17 17:59:40 +00004364 ObjCInterfaceDecl *CDecl = 0;
Douglas Gregorc7b6d882010-09-16 15:14:18 +00004365
Douglas Gregor24a069f2009-11-17 17:59:40 +00004366 // If the given name refers to an interface type, retrieve the
4367 // corresponding declaration.
Douglas Gregor2725ca82010-04-21 19:57:20 +00004368 if (Receiver) {
Douglas Gregorc7b6d882010-09-16 15:14:18 +00004369 QualType T = SemaRef.GetTypeFromParser(Receiver, 0);
Douglas Gregor2725ca82010-04-21 19:57:20 +00004370 if (!T.isNull())
John McCallc12c5bb2010-05-15 11:32:37 +00004371 if (const ObjCObjectType *Interface = T->getAs<ObjCObjectType>())
4372 CDecl = Interface->getInterface();
Douglas Gregor24a069f2009-11-17 17:59:40 +00004373 }
Douglas Gregorc7b6d882010-09-16 15:14:18 +00004374
Douglas Gregor36ecb042009-11-17 23:22:23 +00004375 // Add all of the factory methods in this Objective-C class, its protocols,
4376 // superclasses, categories, implementation, etc.
Steve Naroffc4df6d22009-11-07 02:08:14 +00004377 Results.EnterNewScope();
Douglas Gregorc7b6d882010-09-16 15:14:18 +00004378
Douglas Gregor03d8aec2010-08-27 15:10:57 +00004379 // If this is a send-to-super, try to add the special "super" send
4380 // completion.
4381 if (IsSuper) {
4382 if (ObjCMethodDecl *SuperMethod
Douglas Gregorc7b6d882010-09-16 15:14:18 +00004383 = AddSuperSendCompletion(SemaRef, false, SelIdents, NumSelIdents,
4384 Results))
Douglas Gregor03d8aec2010-08-27 15:10:57 +00004385 Results.Ignore(SuperMethod);
4386 }
Douglas Gregorc7b6d882010-09-16 15:14:18 +00004387
Douglas Gregor265f7492010-08-27 15:29:55 +00004388 // If we're inside an Objective-C method definition, prefer its selector to
4389 // others.
Douglas Gregorc7b6d882010-09-16 15:14:18 +00004390 if (ObjCMethodDecl *CurMethod = SemaRef.getCurMethodDecl())
Douglas Gregor265f7492010-08-27 15:29:55 +00004391 Results.setPreferredSelector(CurMethod->getSelector());
Douglas Gregorc7b6d882010-09-16 15:14:18 +00004392
Douglas Gregord36adf52010-09-16 16:06:31 +00004393 VisitedSelectorSet Selectors;
Douglas Gregor13438f92010-04-06 16:40:00 +00004394 if (CDecl)
Douglas Gregorc7b6d882010-09-16 15:14:18 +00004395 AddObjCMethods(CDecl, false, MK_Any, SelIdents, NumSelIdents,
Douglas Gregord36adf52010-09-16 16:06:31 +00004396 SemaRef.CurContext, Selectors, Results);
Douglas Gregor2725ca82010-04-21 19:57:20 +00004397 else {
Douglas Gregor13438f92010-04-06 16:40:00 +00004398 // We're messaging "id" as a type; provide all class/factory methods.
Douglas Gregorc7b6d882010-09-16 15:14:18 +00004399
Douglas Gregor719770d2010-04-06 17:30:22 +00004400 // If we have an external source, load the entire class method
Sebastian Redl3c7f4132010-08-18 23:57:06 +00004401 // pool from the AST file.
Douglas Gregorc7b6d882010-09-16 15:14:18 +00004402 if (SemaRef.ExternalSource) {
4403 for (uint32_t I = 0,
4404 N = SemaRef.ExternalSource->GetNumExternalSelectors();
John McCall76bd1f32010-06-01 09:23:16 +00004405 I != N; ++I) {
Douglas Gregorc7b6d882010-09-16 15:14:18 +00004406 Selector Sel = SemaRef.ExternalSource->GetExternalSelector(I);
4407 if (Sel.isNull() || SemaRef.MethodPool.count(Sel))
Douglas Gregor719770d2010-04-06 17:30:22 +00004408 continue;
Douglas Gregorc7b6d882010-09-16 15:14:18 +00004409
4410 SemaRef.ReadMethodPool(Sel);
Douglas Gregor719770d2010-04-06 17:30:22 +00004411 }
4412 }
Douglas Gregorc7b6d882010-09-16 15:14:18 +00004413
4414 for (Sema::GlobalMethodPool::iterator M = SemaRef.MethodPool.begin(),
4415 MEnd = SemaRef.MethodPool.end();
Sebastian Redldb9d2142010-08-02 23:18:59 +00004416 M != MEnd; ++M) {
4417 for (ObjCMethodList *MethList = &M->second.second;
4418 MethList && MethList->Method;
Douglas Gregor13438f92010-04-06 16:40:00 +00004419 MethList = MethList->Next) {
4420 if (!isAcceptableObjCMethod(MethList->Method, MK_Any, SelIdents,
4421 NumSelIdents))
4422 continue;
Douglas Gregorc7b6d882010-09-16 15:14:18 +00004423
Douglas Gregor13438f92010-04-06 16:40:00 +00004424 Result R(MethList->Method, 0);
4425 R.StartParameter = NumSelIdents;
4426 R.AllParametersAreInformative = false;
Douglas Gregorc7b6d882010-09-16 15:14:18 +00004427 Results.MaybeAddResult(R, SemaRef.CurContext);
Douglas Gregor13438f92010-04-06 16:40:00 +00004428 }
4429 }
4430 }
Douglas Gregorc7b6d882010-09-16 15:14:18 +00004431
4432 Results.ExitScope();
4433}
Douglas Gregor13438f92010-04-06 16:40:00 +00004434
Douglas Gregorc7b6d882010-09-16 15:14:18 +00004435void Sema::CodeCompleteObjCClassMessage(Scope *S, ParsedType Receiver,
4436 IdentifierInfo **SelIdents,
4437 unsigned NumSelIdents,
4438 bool IsSuper) {
4439 ResultBuilder Results(*this);
4440 AddClassMessageCompletions(*this, S, Receiver, SelIdents, NumSelIdents, IsSuper,
4441 Results);
Douglas Gregore6b1bb62010-08-11 21:23:17 +00004442 HandleCodeCompleteResults(this, CodeCompleter,
4443 CodeCompletionContext::CCC_Other,
Douglas Gregor03d8aec2010-08-27 15:10:57 +00004444 Results.data(), Results.size());
Steve Naroffc4df6d22009-11-07 02:08:14 +00004445}
4446
Douglas Gregord3c68542009-11-19 01:08:35 +00004447void Sema::CodeCompleteObjCInstanceMessage(Scope *S, ExprTy *Receiver,
4448 IdentifierInfo **SelIdents,
Douglas Gregor03d8aec2010-08-27 15:10:57 +00004449 unsigned NumSelIdents,
4450 bool IsSuper) {
John McCall0a2c5e22010-08-25 06:19:51 +00004451 typedef CodeCompletionResult Result;
Steve Naroffc4df6d22009-11-07 02:08:14 +00004452
4453 Expr *RecExpr = static_cast<Expr *>(Receiver);
Steve Naroffc4df6d22009-11-07 02:08:14 +00004454
Douglas Gregor36ecb042009-11-17 23:22:23 +00004455 // If necessary, apply function/array conversion to the receiver.
4456 // C99 6.7.5.3p[7,8].
Douglas Gregor78edf512010-09-15 16:23:04 +00004457 if (RecExpr)
4458 DefaultFunctionArrayLvalueConversion(RecExpr);
4459 QualType ReceiverType = RecExpr? RecExpr->getType() : Context.getObjCIdType();
Steve Naroffc4df6d22009-11-07 02:08:14 +00004460
Douglas Gregor36ecb042009-11-17 23:22:23 +00004461 // Build the set of methods we can see.
4462 ResultBuilder Results(*this);
4463 Results.EnterNewScope();
Douglas Gregor22f56992010-04-06 19:22:33 +00004464
Douglas Gregor03d8aec2010-08-27 15:10:57 +00004465 // If this is a send-to-super, try to add the special "super" send
4466 // completion.
4467 if (IsSuper) {
4468 if (ObjCMethodDecl *SuperMethod
4469 = AddSuperSendCompletion(*this, false, SelIdents, NumSelIdents,
4470 Results))
4471 Results.Ignore(SuperMethod);
4472 }
4473
Douglas Gregor265f7492010-08-27 15:29:55 +00004474 // If we're inside an Objective-C method definition, prefer its selector to
4475 // others.
4476 if (ObjCMethodDecl *CurMethod = getCurMethodDecl())
4477 Results.setPreferredSelector(CurMethod->getSelector());
4478
Douglas Gregor22f56992010-04-06 19:22:33 +00004479 // If we're messaging an expression with type "id" or "Class", check
4480 // whether we know something special about the receiver that allows
4481 // us to assume a more-specific receiver type.
4482 if (ReceiverType->isObjCIdType() || ReceiverType->isObjCClassType())
4483 if (ObjCInterfaceDecl *IFace = GetAssumedMessageSendExprType(RecExpr))
4484 ReceiverType = Context.getObjCObjectPointerType(
4485 Context.getObjCInterfaceType(IFace));
Douglas Gregor36ecb042009-11-17 23:22:23 +00004486
Douglas Gregord36adf52010-09-16 16:06:31 +00004487 // Keep track of the selectors we've already added.
4488 VisitedSelectorSet Selectors;
4489
Douglas Gregorf74a4192009-11-18 00:06:18 +00004490 // Handle messages to Class. This really isn't a message to an instance
4491 // method, so we treat it the same way we would treat a message send to a
4492 // class method.
4493 if (ReceiverType->isObjCClassType() ||
4494 ReceiverType->isObjCQualifiedClassType()) {
4495 if (ObjCMethodDecl *CurMethod = getCurMethodDecl()) {
4496 if (ObjCInterfaceDecl *ClassDecl = CurMethod->getClassInterface())
Douglas Gregor4ad96852009-11-19 07:41:15 +00004497 AddObjCMethods(ClassDecl, false, MK_Any, SelIdents, NumSelIdents,
Douglas Gregord36adf52010-09-16 16:06:31 +00004498 CurContext, Selectors, Results);
Douglas Gregorf74a4192009-11-18 00:06:18 +00004499 }
4500 }
4501 // Handle messages to a qualified ID ("id<foo>").
4502 else if (const ObjCObjectPointerType *QualID
4503 = ReceiverType->getAsObjCQualifiedIdType()) {
4504 // Search protocols for instance methods.
4505 for (ObjCObjectPointerType::qual_iterator I = QualID->qual_begin(),
4506 E = QualID->qual_end();
4507 I != E; ++I)
Douglas Gregor4ad96852009-11-19 07:41:15 +00004508 AddObjCMethods(*I, true, MK_Any, SelIdents, NumSelIdents, CurContext,
Douglas Gregord36adf52010-09-16 16:06:31 +00004509 Selectors, Results);
Douglas Gregorf74a4192009-11-18 00:06:18 +00004510 }
4511 // Handle messages to a pointer to interface type.
4512 else if (const ObjCObjectPointerType *IFacePtr
4513 = ReceiverType->getAsObjCInterfacePointerType()) {
4514 // Search the class, its superclasses, etc., for instance methods.
Douglas Gregor4ad96852009-11-19 07:41:15 +00004515 AddObjCMethods(IFacePtr->getInterfaceDecl(), true, MK_Any, SelIdents,
Douglas Gregord36adf52010-09-16 16:06:31 +00004516 NumSelIdents, CurContext, Selectors, Results);
Douglas Gregorf74a4192009-11-18 00:06:18 +00004517
4518 // Search protocols for instance methods.
4519 for (ObjCObjectPointerType::qual_iterator I = IFacePtr->qual_begin(),
4520 E = IFacePtr->qual_end();
4521 I != E; ++I)
Douglas Gregor4ad96852009-11-19 07:41:15 +00004522 AddObjCMethods(*I, true, MK_Any, SelIdents, NumSelIdents, CurContext,
Douglas Gregord36adf52010-09-16 16:06:31 +00004523 Selectors, Results);
Douglas Gregorf74a4192009-11-18 00:06:18 +00004524 }
Douglas Gregor13438f92010-04-06 16:40:00 +00004525 // Handle messages to "id".
4526 else if (ReceiverType->isObjCIdType()) {
Douglas Gregor719770d2010-04-06 17:30:22 +00004527 // We're messaging "id", so provide all instance methods we know
4528 // about as code-completion results.
4529
4530 // If we have an external source, load the entire class method
Sebastian Redl3c7f4132010-08-18 23:57:06 +00004531 // pool from the AST file.
Douglas Gregor719770d2010-04-06 17:30:22 +00004532 if (ExternalSource) {
John McCall76bd1f32010-06-01 09:23:16 +00004533 for (uint32_t I = 0, N = ExternalSource->GetNumExternalSelectors();
4534 I != N; ++I) {
4535 Selector Sel = ExternalSource->GetExternalSelector(I);
Sebastian Redldb9d2142010-08-02 23:18:59 +00004536 if (Sel.isNull() || MethodPool.count(Sel))
Douglas Gregor719770d2010-04-06 17:30:22 +00004537 continue;
4538
Sebastian Redldb9d2142010-08-02 23:18:59 +00004539 ReadMethodPool(Sel);
Douglas Gregor719770d2010-04-06 17:30:22 +00004540 }
4541 }
4542
Sebastian Redldb9d2142010-08-02 23:18:59 +00004543 for (GlobalMethodPool::iterator M = MethodPool.begin(),
4544 MEnd = MethodPool.end();
4545 M != MEnd; ++M) {
4546 for (ObjCMethodList *MethList = &M->second.first;
4547 MethList && MethList->Method;
Douglas Gregor13438f92010-04-06 16:40:00 +00004548 MethList = MethList->Next) {
4549 if (!isAcceptableObjCMethod(MethList->Method, MK_Any, SelIdents,
4550 NumSelIdents))
4551 continue;
Douglas Gregord36adf52010-09-16 16:06:31 +00004552
4553 if (!Selectors.insert(MethList->Method->getSelector()))
4554 continue;
4555
Douglas Gregor13438f92010-04-06 16:40:00 +00004556 Result R(MethList->Method, 0);
4557 R.StartParameter = NumSelIdents;
4558 R.AllParametersAreInformative = false;
4559 Results.MaybeAddResult(R, CurContext);
4560 }
4561 }
4562 }
4563
Steve Naroffc4df6d22009-11-07 02:08:14 +00004564 Results.ExitScope();
Douglas Gregore6b1bb62010-08-11 21:23:17 +00004565 HandleCodeCompleteResults(this, CodeCompleter,
4566 CodeCompletionContext::CCC_Other,
4567 Results.data(),Results.size());
Steve Naroffc4df6d22009-11-07 02:08:14 +00004568}
Douglas Gregor55385fe2009-11-18 04:19:12 +00004569
Douglas Gregorfb629412010-08-23 21:17:50 +00004570void Sema::CodeCompleteObjCForCollection(Scope *S,
4571 DeclGroupPtrTy IterationVar) {
4572 CodeCompleteExpressionData Data;
4573 Data.ObjCCollection = true;
4574
4575 if (IterationVar.getAsOpaquePtr()) {
4576 DeclGroupRef DG = IterationVar.getAsVal<DeclGroupRef>();
4577 for (DeclGroupRef::iterator I = DG.begin(), End = DG.end(); I != End; ++I) {
4578 if (*I)
4579 Data.IgnoreDecls.push_back(*I);
4580 }
4581 }
4582
4583 CodeCompleteExpression(S, Data);
4584}
4585
Douglas Gregor458433d2010-08-26 15:07:07 +00004586void Sema::CodeCompleteObjCSelector(Scope *S, IdentifierInfo **SelIdents,
4587 unsigned NumSelIdents) {
4588 // If we have an external source, load the entire class method
4589 // pool from the AST file.
4590 if (ExternalSource) {
4591 for (uint32_t I = 0, N = ExternalSource->GetNumExternalSelectors();
4592 I != N; ++I) {
4593 Selector Sel = ExternalSource->GetExternalSelector(I);
4594 if (Sel.isNull() || MethodPool.count(Sel))
4595 continue;
4596
4597 ReadMethodPool(Sel);
4598 }
4599 }
4600
4601 ResultBuilder Results(*this);
4602 Results.EnterNewScope();
4603 for (GlobalMethodPool::iterator M = MethodPool.begin(),
4604 MEnd = MethodPool.end();
4605 M != MEnd; ++M) {
4606
4607 Selector Sel = M->first;
4608 if (!isAcceptableObjCSelector(Sel, MK_Any, SelIdents, NumSelIdents))
4609 continue;
4610
4611 CodeCompletionString *Pattern = new CodeCompletionString;
4612 if (Sel.isUnarySelector()) {
4613 Pattern->AddTypedTextChunk(Sel.getIdentifierInfoForSlot(0)->getName());
4614 Results.AddResult(Pattern);
4615 continue;
4616 }
4617
Douglas Gregor2d9e21f2010-08-26 16:46:39 +00004618 std::string Accumulator;
Douglas Gregor458433d2010-08-26 15:07:07 +00004619 for (unsigned I = 0, N = Sel.getNumArgs(); I != N; ++I) {
Douglas Gregor2d9e21f2010-08-26 16:46:39 +00004620 if (I == NumSelIdents) {
4621 if (!Accumulator.empty()) {
4622 Pattern->AddInformativeChunk(Accumulator);
4623 Accumulator.clear();
4624 }
4625 }
4626
4627 Accumulator += Sel.getIdentifierInfoForSlot(I)->getName().str();
4628 Accumulator += ':';
Douglas Gregor458433d2010-08-26 15:07:07 +00004629 }
Douglas Gregor2d9e21f2010-08-26 16:46:39 +00004630 Pattern->AddTypedTextChunk(Accumulator);
Douglas Gregor458433d2010-08-26 15:07:07 +00004631 Results.AddResult(Pattern);
4632 }
4633 Results.ExitScope();
4634
4635 HandleCodeCompleteResults(this, CodeCompleter,
4636 CodeCompletionContext::CCC_SelectorName,
4637 Results.data(), Results.size());
4638}
4639
Douglas Gregor55385fe2009-11-18 04:19:12 +00004640/// \brief Add all of the protocol declarations that we find in the given
4641/// (translation unit) context.
4642static void AddProtocolResults(DeclContext *Ctx, DeclContext *CurContext,
Douglas Gregor083128f2009-11-18 04:49:41 +00004643 bool OnlyForwardDeclarations,
Douglas Gregor55385fe2009-11-18 04:19:12 +00004644 ResultBuilder &Results) {
John McCall0a2c5e22010-08-25 06:19:51 +00004645 typedef CodeCompletionResult Result;
Douglas Gregor55385fe2009-11-18 04:19:12 +00004646
4647 for (DeclContext::decl_iterator D = Ctx->decls_begin(),
4648 DEnd = Ctx->decls_end();
4649 D != DEnd; ++D) {
4650 // Record any protocols we find.
4651 if (ObjCProtocolDecl *Proto = dyn_cast<ObjCProtocolDecl>(*D))
Douglas Gregor083128f2009-11-18 04:49:41 +00004652 if (!OnlyForwardDeclarations || Proto->isForwardDecl())
Douglas Gregor608300b2010-01-14 16:14:35 +00004653 Results.AddResult(Result(Proto, 0), CurContext, 0, false);
Douglas Gregor55385fe2009-11-18 04:19:12 +00004654
4655 // Record any forward-declared protocols we find.
4656 if (ObjCForwardProtocolDecl *Forward
4657 = dyn_cast<ObjCForwardProtocolDecl>(*D)) {
4658 for (ObjCForwardProtocolDecl::protocol_iterator
4659 P = Forward->protocol_begin(),
4660 PEnd = Forward->protocol_end();
4661 P != PEnd; ++P)
Douglas Gregor083128f2009-11-18 04:49:41 +00004662 if (!OnlyForwardDeclarations || (*P)->isForwardDecl())
Douglas Gregor608300b2010-01-14 16:14:35 +00004663 Results.AddResult(Result(*P, 0), CurContext, 0, false);
Douglas Gregor55385fe2009-11-18 04:19:12 +00004664 }
4665 }
4666}
4667
4668void Sema::CodeCompleteObjCProtocolReferences(IdentifierLocPair *Protocols,
4669 unsigned NumProtocols) {
4670 ResultBuilder Results(*this);
4671 Results.EnterNewScope();
4672
4673 // Tell the result set to ignore all of the protocols we have
4674 // already seen.
4675 for (unsigned I = 0; I != NumProtocols; ++I)
Douglas Gregorc83c6872010-04-15 22:33:43 +00004676 if (ObjCProtocolDecl *Protocol = LookupProtocol(Protocols[I].first,
4677 Protocols[I].second))
Douglas Gregor55385fe2009-11-18 04:19:12 +00004678 Results.Ignore(Protocol);
4679
4680 // Add all protocols.
Douglas Gregor083128f2009-11-18 04:49:41 +00004681 AddProtocolResults(Context.getTranslationUnitDecl(), CurContext, false,
4682 Results);
4683
4684 Results.ExitScope();
Douglas Gregore6b1bb62010-08-11 21:23:17 +00004685 HandleCodeCompleteResults(this, CodeCompleter,
4686 CodeCompletionContext::CCC_ObjCProtocolName,
4687 Results.data(),Results.size());
Douglas Gregor083128f2009-11-18 04:49:41 +00004688}
4689
4690void Sema::CodeCompleteObjCProtocolDecl(Scope *) {
4691 ResultBuilder Results(*this);
4692 Results.EnterNewScope();
4693
4694 // Add all protocols.
4695 AddProtocolResults(Context.getTranslationUnitDecl(), CurContext, true,
4696 Results);
Douglas Gregor55385fe2009-11-18 04:19:12 +00004697
4698 Results.ExitScope();
Douglas Gregore6b1bb62010-08-11 21:23:17 +00004699 HandleCodeCompleteResults(this, CodeCompleter,
4700 CodeCompletionContext::CCC_ObjCProtocolName,
4701 Results.data(),Results.size());
Douglas Gregor55385fe2009-11-18 04:19:12 +00004702}
Douglas Gregor3b49aca2009-11-18 16:26:39 +00004703
4704/// \brief Add all of the Objective-C interface declarations that we find in
4705/// the given (translation unit) context.
4706static void AddInterfaceResults(DeclContext *Ctx, DeclContext *CurContext,
4707 bool OnlyForwardDeclarations,
4708 bool OnlyUnimplemented,
4709 ResultBuilder &Results) {
John McCall0a2c5e22010-08-25 06:19:51 +00004710 typedef CodeCompletionResult Result;
Douglas Gregor3b49aca2009-11-18 16:26:39 +00004711
4712 for (DeclContext::decl_iterator D = Ctx->decls_begin(),
4713 DEnd = Ctx->decls_end();
4714 D != DEnd; ++D) {
Douglas Gregordeacbdc2010-08-11 12:19:30 +00004715 // Record any interfaces we find.
4716 if (ObjCInterfaceDecl *Class = dyn_cast<ObjCInterfaceDecl>(*D))
4717 if ((!OnlyForwardDeclarations || Class->isForwardDecl()) &&
4718 (!OnlyUnimplemented || !Class->getImplementation()))
4719 Results.AddResult(Result(Class, 0), CurContext, 0, false);
Douglas Gregor3b49aca2009-11-18 16:26:39 +00004720
4721 // Record any forward-declared interfaces we find.
4722 if (ObjCClassDecl *Forward = dyn_cast<ObjCClassDecl>(*D)) {
4723 for (ObjCClassDecl::iterator C = Forward->begin(), CEnd = Forward->end();
Douglas Gregordeacbdc2010-08-11 12:19:30 +00004724 C != CEnd; ++C)
4725 if ((!OnlyForwardDeclarations || C->getInterface()->isForwardDecl()) &&
4726 (!OnlyUnimplemented || !C->getInterface()->getImplementation()))
4727 Results.AddResult(Result(C->getInterface(), 0), CurContext,
Douglas Gregor608300b2010-01-14 16:14:35 +00004728 0, false);
Douglas Gregor3b49aca2009-11-18 16:26:39 +00004729 }
4730 }
4731}
4732
4733void Sema::CodeCompleteObjCInterfaceDecl(Scope *S) {
4734 ResultBuilder Results(*this);
4735 Results.EnterNewScope();
4736
4737 // Add all classes.
4738 AddInterfaceResults(Context.getTranslationUnitDecl(), CurContext, true,
4739 false, Results);
4740
4741 Results.ExitScope();
Douglas Gregore6b1bb62010-08-11 21:23:17 +00004742 HandleCodeCompleteResults(this, CodeCompleter,
4743 CodeCompletionContext::CCC_Other,
4744 Results.data(),Results.size());
Douglas Gregor3b49aca2009-11-18 16:26:39 +00004745}
4746
Douglas Gregorc83c6872010-04-15 22:33:43 +00004747void Sema::CodeCompleteObjCSuperclass(Scope *S, IdentifierInfo *ClassName,
4748 SourceLocation ClassNameLoc) {
Douglas Gregor3b49aca2009-11-18 16:26:39 +00004749 ResultBuilder Results(*this);
4750 Results.EnterNewScope();
4751
4752 // Make sure that we ignore the class we're currently defining.
4753 NamedDecl *CurClass
Douglas Gregorc83c6872010-04-15 22:33:43 +00004754 = LookupSingleName(TUScope, ClassName, ClassNameLoc, LookupOrdinaryName);
Douglas Gregor33ced0b2009-11-18 19:08:43 +00004755 if (CurClass && isa<ObjCInterfaceDecl>(CurClass))
Douglas Gregor3b49aca2009-11-18 16:26:39 +00004756 Results.Ignore(CurClass);
4757
4758 // Add all classes.
4759 AddInterfaceResults(Context.getTranslationUnitDecl(), CurContext, false,
4760 false, Results);
4761
4762 Results.ExitScope();
Douglas Gregore6b1bb62010-08-11 21:23:17 +00004763 HandleCodeCompleteResults(this, CodeCompleter,
4764 CodeCompletionContext::CCC_Other,
4765 Results.data(),Results.size());
Douglas Gregor3b49aca2009-11-18 16:26:39 +00004766}
4767
4768void Sema::CodeCompleteObjCImplementationDecl(Scope *S) {
4769 ResultBuilder Results(*this);
4770 Results.EnterNewScope();
4771
4772 // Add all unimplemented classes.
4773 AddInterfaceResults(Context.getTranslationUnitDecl(), CurContext, false,
4774 true, Results);
4775
4776 Results.ExitScope();
Douglas Gregore6b1bb62010-08-11 21:23:17 +00004777 HandleCodeCompleteResults(this, CodeCompleter,
4778 CodeCompletionContext::CCC_Other,
4779 Results.data(),Results.size());
Douglas Gregor3b49aca2009-11-18 16:26:39 +00004780}
Douglas Gregor33ced0b2009-11-18 19:08:43 +00004781
4782void Sema::CodeCompleteObjCInterfaceCategory(Scope *S,
Douglas Gregorc83c6872010-04-15 22:33:43 +00004783 IdentifierInfo *ClassName,
4784 SourceLocation ClassNameLoc) {
John McCall0a2c5e22010-08-25 06:19:51 +00004785 typedef CodeCompletionResult Result;
Douglas Gregor33ced0b2009-11-18 19:08:43 +00004786
4787 ResultBuilder Results(*this);
4788
4789 // Ignore any categories we find that have already been implemented by this
4790 // interface.
4791 llvm::SmallPtrSet<IdentifierInfo *, 16> CategoryNames;
4792 NamedDecl *CurClass
Douglas Gregorc83c6872010-04-15 22:33:43 +00004793 = LookupSingleName(TUScope, ClassName, ClassNameLoc, LookupOrdinaryName);
Douglas Gregor33ced0b2009-11-18 19:08:43 +00004794 if (ObjCInterfaceDecl *Class = dyn_cast_or_null<ObjCInterfaceDecl>(CurClass))
4795 for (ObjCCategoryDecl *Category = Class->getCategoryList(); Category;
4796 Category = Category->getNextClassCategory())
4797 CategoryNames.insert(Category->getIdentifier());
4798
4799 // Add all of the categories we know about.
4800 Results.EnterNewScope();
4801 TranslationUnitDecl *TU = Context.getTranslationUnitDecl();
4802 for (DeclContext::decl_iterator D = TU->decls_begin(),
4803 DEnd = TU->decls_end();
4804 D != DEnd; ++D)
4805 if (ObjCCategoryDecl *Category = dyn_cast<ObjCCategoryDecl>(*D))
4806 if (CategoryNames.insert(Category->getIdentifier()))
Douglas Gregor608300b2010-01-14 16:14:35 +00004807 Results.AddResult(Result(Category, 0), CurContext, 0, false);
Douglas Gregor33ced0b2009-11-18 19:08:43 +00004808 Results.ExitScope();
4809
Douglas Gregore6b1bb62010-08-11 21:23:17 +00004810 HandleCodeCompleteResults(this, CodeCompleter,
4811 CodeCompletionContext::CCC_Other,
4812 Results.data(),Results.size());
Douglas Gregor33ced0b2009-11-18 19:08:43 +00004813}
4814
4815void Sema::CodeCompleteObjCImplementationCategory(Scope *S,
Douglas Gregorc83c6872010-04-15 22:33:43 +00004816 IdentifierInfo *ClassName,
4817 SourceLocation ClassNameLoc) {
John McCall0a2c5e22010-08-25 06:19:51 +00004818 typedef CodeCompletionResult Result;
Douglas Gregor33ced0b2009-11-18 19:08:43 +00004819
4820 // Find the corresponding interface. If we couldn't find the interface, the
4821 // program itself is ill-formed. However, we'll try to be helpful still by
4822 // providing the list of all of the categories we know about.
4823 NamedDecl *CurClass
Douglas Gregorc83c6872010-04-15 22:33:43 +00004824 = LookupSingleName(TUScope, ClassName, ClassNameLoc, LookupOrdinaryName);
Douglas Gregor33ced0b2009-11-18 19:08:43 +00004825 ObjCInterfaceDecl *Class = dyn_cast_or_null<ObjCInterfaceDecl>(CurClass);
4826 if (!Class)
Douglas Gregorc83c6872010-04-15 22:33:43 +00004827 return CodeCompleteObjCInterfaceCategory(S, ClassName, ClassNameLoc);
Douglas Gregor33ced0b2009-11-18 19:08:43 +00004828
4829 ResultBuilder Results(*this);
4830
4831 // Add all of the categories that have have corresponding interface
4832 // declarations in this class and any of its superclasses, except for
4833 // already-implemented categories in the class itself.
4834 llvm::SmallPtrSet<IdentifierInfo *, 16> CategoryNames;
4835 Results.EnterNewScope();
4836 bool IgnoreImplemented = true;
4837 while (Class) {
4838 for (ObjCCategoryDecl *Category = Class->getCategoryList(); Category;
4839 Category = Category->getNextClassCategory())
4840 if ((!IgnoreImplemented || !Category->getImplementation()) &&
4841 CategoryNames.insert(Category->getIdentifier()))
Douglas Gregor608300b2010-01-14 16:14:35 +00004842 Results.AddResult(Result(Category, 0), CurContext, 0, false);
Douglas Gregor33ced0b2009-11-18 19:08:43 +00004843
4844 Class = Class->getSuperClass();
4845 IgnoreImplemented = false;
4846 }
4847 Results.ExitScope();
4848
Douglas Gregore6b1bb62010-08-11 21:23:17 +00004849 HandleCodeCompleteResults(this, CodeCompleter,
4850 CodeCompletionContext::CCC_Other,
4851 Results.data(),Results.size());
Douglas Gregor33ced0b2009-11-18 19:08:43 +00004852}
Douglas Gregor322328b2009-11-18 22:32:06 +00004853
John McCalld226f652010-08-21 09:40:31 +00004854void Sema::CodeCompleteObjCPropertyDefinition(Scope *S, Decl *ObjCImpDecl) {
John McCall0a2c5e22010-08-25 06:19:51 +00004855 typedef CodeCompletionResult Result;
Douglas Gregor322328b2009-11-18 22:32:06 +00004856 ResultBuilder Results(*this);
4857
4858 // Figure out where this @synthesize lives.
4859 ObjCContainerDecl *Container
John McCalld226f652010-08-21 09:40:31 +00004860 = dyn_cast_or_null<ObjCContainerDecl>(ObjCImpDecl);
Douglas Gregor322328b2009-11-18 22:32:06 +00004861 if (!Container ||
4862 (!isa<ObjCImplementationDecl>(Container) &&
4863 !isa<ObjCCategoryImplDecl>(Container)))
4864 return;
4865
4866 // Ignore any properties that have already been implemented.
4867 for (DeclContext::decl_iterator D = Container->decls_begin(),
4868 DEnd = Container->decls_end();
4869 D != DEnd; ++D)
4870 if (ObjCPropertyImplDecl *PropertyImpl = dyn_cast<ObjCPropertyImplDecl>(*D))
4871 Results.Ignore(PropertyImpl->getPropertyDecl());
4872
4873 // Add any properties that we find.
4874 Results.EnterNewScope();
4875 if (ObjCImplementationDecl *ClassImpl
4876 = dyn_cast<ObjCImplementationDecl>(Container))
4877 AddObjCProperties(ClassImpl->getClassInterface(), false, CurContext,
4878 Results);
4879 else
4880 AddObjCProperties(cast<ObjCCategoryImplDecl>(Container)->getCategoryDecl(),
4881 false, CurContext, Results);
4882 Results.ExitScope();
4883
Douglas Gregore6b1bb62010-08-11 21:23:17 +00004884 HandleCodeCompleteResults(this, CodeCompleter,
4885 CodeCompletionContext::CCC_Other,
4886 Results.data(),Results.size());
Douglas Gregor322328b2009-11-18 22:32:06 +00004887}
4888
4889void Sema::CodeCompleteObjCPropertySynthesizeIvar(Scope *S,
4890 IdentifierInfo *PropertyName,
John McCalld226f652010-08-21 09:40:31 +00004891 Decl *ObjCImpDecl) {
John McCall0a2c5e22010-08-25 06:19:51 +00004892 typedef CodeCompletionResult Result;
Douglas Gregor322328b2009-11-18 22:32:06 +00004893 ResultBuilder Results(*this);
4894
4895 // Figure out where this @synthesize lives.
4896 ObjCContainerDecl *Container
John McCalld226f652010-08-21 09:40:31 +00004897 = dyn_cast_or_null<ObjCContainerDecl>(ObjCImpDecl);
Douglas Gregor322328b2009-11-18 22:32:06 +00004898 if (!Container ||
4899 (!isa<ObjCImplementationDecl>(Container) &&
4900 !isa<ObjCCategoryImplDecl>(Container)))
4901 return;
4902
4903 // Figure out which interface we're looking into.
4904 ObjCInterfaceDecl *Class = 0;
4905 if (ObjCImplementationDecl *ClassImpl
4906 = dyn_cast<ObjCImplementationDecl>(Container))
4907 Class = ClassImpl->getClassInterface();
4908 else
4909 Class = cast<ObjCCategoryImplDecl>(Container)->getCategoryDecl()
4910 ->getClassInterface();
4911
4912 // Add all of the instance variables in this class and its superclasses.
4913 Results.EnterNewScope();
4914 for(; Class; Class = Class->getSuperClass()) {
4915 // FIXME: We could screen the type of each ivar for compatibility with
4916 // the property, but is that being too paternal?
4917 for (ObjCInterfaceDecl::ivar_iterator IVar = Class->ivar_begin(),
4918 IVarEnd = Class->ivar_end();
4919 IVar != IVarEnd; ++IVar)
Douglas Gregor608300b2010-01-14 16:14:35 +00004920 Results.AddResult(Result(*IVar, 0), CurContext, 0, false);
Douglas Gregor322328b2009-11-18 22:32:06 +00004921 }
4922 Results.ExitScope();
4923
Douglas Gregore6b1bb62010-08-11 21:23:17 +00004924 HandleCodeCompleteResults(this, CodeCompleter,
4925 CodeCompletionContext::CCC_Other,
4926 Results.data(),Results.size());
Douglas Gregor322328b2009-11-18 22:32:06 +00004927}
Douglas Gregore8f5a172010-04-07 00:21:17 +00004928
Douglas Gregor408be5a2010-08-25 01:08:01 +00004929// Mapping from selectors to the methods that implement that selector, along
4930// with the "in original class" flag.
4931typedef llvm::DenseMap<Selector, std::pair<ObjCMethodDecl *, bool> >
4932 KnownMethodsMap;
Douglas Gregore8f5a172010-04-07 00:21:17 +00004933
4934/// \brief Find all of the methods that reside in the given container
4935/// (and its superclasses, protocols, etc.) that meet the given
4936/// criteria. Insert those methods into the map of known methods,
4937/// indexed by selector so they can be easily found.
4938static void FindImplementableMethods(ASTContext &Context,
4939 ObjCContainerDecl *Container,
4940 bool WantInstanceMethods,
4941 QualType ReturnType,
4942 bool IsInImplementation,
Douglas Gregor408be5a2010-08-25 01:08:01 +00004943 KnownMethodsMap &KnownMethods,
4944 bool InOriginalClass = true) {
Douglas Gregore8f5a172010-04-07 00:21:17 +00004945 if (ObjCInterfaceDecl *IFace = dyn_cast<ObjCInterfaceDecl>(Container)) {
4946 // Recurse into protocols.
4947 const ObjCList<ObjCProtocolDecl> &Protocols
4948 = IFace->getReferencedProtocols();
4949 for (ObjCList<ObjCProtocolDecl>::iterator I = Protocols.begin(),
4950 E = Protocols.end();
4951 I != E; ++I)
4952 FindImplementableMethods(Context, *I, WantInstanceMethods, ReturnType,
Douglas Gregor408be5a2010-08-25 01:08:01 +00004953 IsInImplementation, KnownMethods,
4954 InOriginalClass);
Douglas Gregore8f5a172010-04-07 00:21:17 +00004955
4956 // If we're not in the implementation of a class, also visit the
4957 // superclass.
4958 if (!IsInImplementation && IFace->getSuperClass())
4959 FindImplementableMethods(Context, IFace->getSuperClass(),
4960 WantInstanceMethods, ReturnType,
Douglas Gregor408be5a2010-08-25 01:08:01 +00004961 IsInImplementation, KnownMethods,
4962 false);
Douglas Gregore8f5a172010-04-07 00:21:17 +00004963
4964 // Add methods from any class extensions (but not from categories;
4965 // those should go into category implementations).
Fariborz Jahanian80aa1cd2010-06-22 23:20:40 +00004966 for (const ObjCCategoryDecl *Cat = IFace->getFirstClassExtension(); Cat;
4967 Cat = Cat->getNextClassExtension())
4968 FindImplementableMethods(Context, const_cast<ObjCCategoryDecl*>(Cat),
4969 WantInstanceMethods, ReturnType,
Douglas Gregor408be5a2010-08-25 01:08:01 +00004970 IsInImplementation, KnownMethods,
4971 InOriginalClass);
Douglas Gregore8f5a172010-04-07 00:21:17 +00004972 }
4973
4974 if (ObjCCategoryDecl *Category = dyn_cast<ObjCCategoryDecl>(Container)) {
4975 // Recurse into protocols.
4976 const ObjCList<ObjCProtocolDecl> &Protocols
4977 = Category->getReferencedProtocols();
4978 for (ObjCList<ObjCProtocolDecl>::iterator I = Protocols.begin(),
4979 E = Protocols.end();
4980 I != E; ++I)
4981 FindImplementableMethods(Context, *I, WantInstanceMethods, ReturnType,
Douglas Gregor408be5a2010-08-25 01:08:01 +00004982 IsInImplementation, KnownMethods,
4983 InOriginalClass);
Douglas Gregore8f5a172010-04-07 00:21:17 +00004984 }
4985
4986 if (ObjCProtocolDecl *Protocol = dyn_cast<ObjCProtocolDecl>(Container)) {
4987 // Recurse into protocols.
4988 const ObjCList<ObjCProtocolDecl> &Protocols
4989 = Protocol->getReferencedProtocols();
4990 for (ObjCList<ObjCProtocolDecl>::iterator I = Protocols.begin(),
4991 E = Protocols.end();
4992 I != E; ++I)
4993 FindImplementableMethods(Context, *I, WantInstanceMethods, ReturnType,
Douglas Gregor408be5a2010-08-25 01:08:01 +00004994 IsInImplementation, KnownMethods, false);
Douglas Gregore8f5a172010-04-07 00:21:17 +00004995 }
4996
4997 // Add methods in this container. This operation occurs last because
4998 // we want the methods from this container to override any methods
4999 // we've previously seen with the same selector.
5000 for (ObjCContainerDecl::method_iterator M = Container->meth_begin(),
5001 MEnd = Container->meth_end();
5002 M != MEnd; ++M) {
5003 if ((*M)->isInstanceMethod() == WantInstanceMethods) {
5004 if (!ReturnType.isNull() &&
5005 !Context.hasSameUnqualifiedType(ReturnType, (*M)->getResultType()))
5006 continue;
5007
Douglas Gregor408be5a2010-08-25 01:08:01 +00005008 KnownMethods[(*M)->getSelector()] = std::make_pair(*M, InOriginalClass);
Douglas Gregore8f5a172010-04-07 00:21:17 +00005009 }
5010 }
5011}
5012
5013void Sema::CodeCompleteObjCMethodDecl(Scope *S,
5014 bool IsInstanceMethod,
John McCallb3d87482010-08-24 05:47:05 +00005015 ParsedType ReturnTy,
John McCalld226f652010-08-21 09:40:31 +00005016 Decl *IDecl) {
Douglas Gregore8f5a172010-04-07 00:21:17 +00005017 // Determine the return type of the method we're declaring, if
5018 // provided.
5019 QualType ReturnType = GetTypeFromParser(ReturnTy);
5020
5021 // Determine where we should start searching for methods, and where we
5022 ObjCContainerDecl *SearchDecl = 0, *CurrentDecl = 0;
5023 bool IsInImplementation = false;
John McCalld226f652010-08-21 09:40:31 +00005024 if (Decl *D = IDecl) {
Douglas Gregore8f5a172010-04-07 00:21:17 +00005025 if (ObjCImplementationDecl *Impl = dyn_cast<ObjCImplementationDecl>(D)) {
5026 SearchDecl = Impl->getClassInterface();
5027 CurrentDecl = Impl;
5028 IsInImplementation = true;
5029 } else if (ObjCCategoryImplDecl *CatImpl
5030 = dyn_cast<ObjCCategoryImplDecl>(D)) {
5031 SearchDecl = CatImpl->getCategoryDecl();
5032 CurrentDecl = CatImpl;
5033 IsInImplementation = true;
5034 } else {
5035 SearchDecl = dyn_cast<ObjCContainerDecl>(D);
5036 CurrentDecl = SearchDecl;
5037 }
5038 }
5039
5040 if (!SearchDecl && S) {
5041 if (DeclContext *DC = static_cast<DeclContext *>(S->getEntity())) {
5042 SearchDecl = dyn_cast<ObjCContainerDecl>(DC);
5043 CurrentDecl = SearchDecl;
5044 }
5045 }
5046
5047 if (!SearchDecl || !CurrentDecl) {
Douglas Gregore6b1bb62010-08-11 21:23:17 +00005048 HandleCodeCompleteResults(this, CodeCompleter,
5049 CodeCompletionContext::CCC_Other,
5050 0, 0);
Douglas Gregore8f5a172010-04-07 00:21:17 +00005051 return;
5052 }
5053
5054 // Find all of the methods that we could declare/implement here.
5055 KnownMethodsMap KnownMethods;
5056 FindImplementableMethods(Context, SearchDecl, IsInstanceMethod,
5057 ReturnType, IsInImplementation, KnownMethods);
5058
5059 // Erase any methods that have already been declared or
5060 // implemented here.
5061 for (ObjCContainerDecl::method_iterator M = CurrentDecl->meth_begin(),
5062 MEnd = CurrentDecl->meth_end();
5063 M != MEnd; ++M) {
5064 if ((*M)->isInstanceMethod() != IsInstanceMethod)
5065 continue;
5066
5067 KnownMethodsMap::iterator Pos = KnownMethods.find((*M)->getSelector());
5068 if (Pos != KnownMethods.end())
5069 KnownMethods.erase(Pos);
5070 }
5071
5072 // Add declarations or definitions for each of the known methods.
John McCall0a2c5e22010-08-25 06:19:51 +00005073 typedef CodeCompletionResult Result;
Douglas Gregore8f5a172010-04-07 00:21:17 +00005074 ResultBuilder Results(*this);
5075 Results.EnterNewScope();
5076 PrintingPolicy Policy(Context.PrintingPolicy);
5077 Policy.AnonymousTagLocations = false;
5078 for (KnownMethodsMap::iterator M = KnownMethods.begin(),
5079 MEnd = KnownMethods.end();
5080 M != MEnd; ++M) {
Douglas Gregor408be5a2010-08-25 01:08:01 +00005081 ObjCMethodDecl *Method = M->second.first;
Douglas Gregore8f5a172010-04-07 00:21:17 +00005082 CodeCompletionString *Pattern = new CodeCompletionString;
5083
5084 // If the result type was not already provided, add it to the
5085 // pattern as (type).
5086 if (ReturnType.isNull()) {
5087 std::string TypeStr;
5088 Method->getResultType().getAsStringInternal(TypeStr, Policy);
5089 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
5090 Pattern->AddTextChunk(TypeStr);
5091 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
5092 }
5093
5094 Selector Sel = Method->getSelector();
5095
5096 // Add the first part of the selector to the pattern.
5097 Pattern->AddTypedTextChunk(Sel.getIdentifierInfoForSlot(0)->getName());
5098
5099 // Add parameters to the pattern.
5100 unsigned I = 0;
5101 for (ObjCMethodDecl::param_iterator P = Method->param_begin(),
5102 PEnd = Method->param_end();
5103 P != PEnd; (void)++P, ++I) {
5104 // Add the part of the selector name.
5105 if (I == 0)
5106 Pattern->AddChunk(CodeCompletionString::CK_Colon);
5107 else if (I < Sel.getNumArgs()) {
5108 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
Douglas Gregor47c03a72010-08-17 15:53:35 +00005109 Pattern->AddTextChunk(Sel.getIdentifierInfoForSlot(I)->getName());
Douglas Gregore8f5a172010-04-07 00:21:17 +00005110 Pattern->AddChunk(CodeCompletionString::CK_Colon);
5111 } else
5112 break;
5113
5114 // Add the parameter type.
5115 std::string TypeStr;
5116 (*P)->getOriginalType().getAsStringInternal(TypeStr, Policy);
5117 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
5118 Pattern->AddTextChunk(TypeStr);
5119 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
5120
5121 if (IdentifierInfo *Id = (*P)->getIdentifier())
Douglas Gregore17794f2010-08-31 05:13:43 +00005122 Pattern->AddTextChunk(Id->getName());
Douglas Gregore8f5a172010-04-07 00:21:17 +00005123 }
5124
5125 if (Method->isVariadic()) {
5126 if (Method->param_size() > 0)
5127 Pattern->AddChunk(CodeCompletionString::CK_Comma);
5128 Pattern->AddTextChunk("...");
Douglas Gregore17794f2010-08-31 05:13:43 +00005129 }
Douglas Gregore8f5a172010-04-07 00:21:17 +00005130
Douglas Gregor447107d2010-05-28 00:57:46 +00005131 if (IsInImplementation && Results.includeCodePatterns()) {
Douglas Gregore8f5a172010-04-07 00:21:17 +00005132 // We will be defining the method here, so add a compound statement.
5133 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
5134 Pattern->AddChunk(CodeCompletionString::CK_LeftBrace);
5135 Pattern->AddChunk(CodeCompletionString::CK_VerticalSpace);
5136 if (!Method->getResultType()->isVoidType()) {
5137 // If the result type is not void, add a return clause.
5138 Pattern->AddTextChunk("return");
5139 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
5140 Pattern->AddPlaceholderChunk("expression");
5141 Pattern->AddChunk(CodeCompletionString::CK_SemiColon);
5142 } else
5143 Pattern->AddPlaceholderChunk("statements");
5144
5145 Pattern->AddChunk(CodeCompletionString::CK_VerticalSpace);
5146 Pattern->AddChunk(CodeCompletionString::CK_RightBrace);
5147 }
5148
Douglas Gregor408be5a2010-08-25 01:08:01 +00005149 unsigned Priority = CCP_CodePattern;
5150 if (!M->second.second)
5151 Priority += CCD_InBaseClass;
5152
5153 Results.AddResult(Result(Pattern, Priority,
Douglas Gregor16ed9ad2010-08-17 16:06:07 +00005154 Method->isInstanceMethod()
5155 ? CXCursor_ObjCInstanceMethodDecl
5156 : CXCursor_ObjCClassMethodDecl));
Douglas Gregore8f5a172010-04-07 00:21:17 +00005157 }
5158
5159 Results.ExitScope();
5160
Douglas Gregore6b1bb62010-08-11 21:23:17 +00005161 HandleCodeCompleteResults(this, CodeCompleter,
5162 CodeCompletionContext::CCC_Other,
5163 Results.data(),Results.size());
Douglas Gregore8f5a172010-04-07 00:21:17 +00005164}
Douglas Gregor1f5537a2010-07-08 23:20:03 +00005165
5166void Sema::CodeCompleteObjCMethodDeclSelector(Scope *S,
5167 bool IsInstanceMethod,
Douglas Gregor40ed9a12010-07-08 23:37:41 +00005168 bool AtParameterName,
John McCallb3d87482010-08-24 05:47:05 +00005169 ParsedType ReturnTy,
Douglas Gregor1f5537a2010-07-08 23:20:03 +00005170 IdentifierInfo **SelIdents,
5171 unsigned NumSelIdents) {
Douglas Gregor1f5537a2010-07-08 23:20:03 +00005172 // If we have an external source, load the entire class method
Sebastian Redl3c7f4132010-08-18 23:57:06 +00005173 // pool from the AST file.
Douglas Gregor1f5537a2010-07-08 23:20:03 +00005174 if (ExternalSource) {
5175 for (uint32_t I = 0, N = ExternalSource->GetNumExternalSelectors();
5176 I != N; ++I) {
5177 Selector Sel = ExternalSource->GetExternalSelector(I);
Sebastian Redldb9d2142010-08-02 23:18:59 +00005178 if (Sel.isNull() || MethodPool.count(Sel))
Douglas Gregor1f5537a2010-07-08 23:20:03 +00005179 continue;
Sebastian Redldb9d2142010-08-02 23:18:59 +00005180
5181 ReadMethodPool(Sel);
Douglas Gregor1f5537a2010-07-08 23:20:03 +00005182 }
5183 }
5184
5185 // Build the set of methods we can see.
John McCall0a2c5e22010-08-25 06:19:51 +00005186 typedef CodeCompletionResult Result;
Douglas Gregor1f5537a2010-07-08 23:20:03 +00005187 ResultBuilder Results(*this);
5188
5189 if (ReturnTy)
5190 Results.setPreferredType(GetTypeFromParser(ReturnTy).getNonReferenceType());
Sebastian Redldb9d2142010-08-02 23:18:59 +00005191
Douglas Gregor1f5537a2010-07-08 23:20:03 +00005192 Results.EnterNewScope();
Sebastian Redldb9d2142010-08-02 23:18:59 +00005193 for (GlobalMethodPool::iterator M = MethodPool.begin(),
5194 MEnd = MethodPool.end();
5195 M != MEnd; ++M) {
5196 for (ObjCMethodList *MethList = IsInstanceMethod ? &M->second.first :
5197 &M->second.second;
5198 MethList && MethList->Method;
Douglas Gregor1f5537a2010-07-08 23:20:03 +00005199 MethList = MethList->Next) {
5200 if (!isAcceptableObjCMethod(MethList->Method, MK_Any, SelIdents,
5201 NumSelIdents))
5202 continue;
5203
Douglas Gregor40ed9a12010-07-08 23:37:41 +00005204 if (AtParameterName) {
5205 // Suggest parameter names we've seen before.
5206 if (NumSelIdents && NumSelIdents <= MethList->Method->param_size()) {
5207 ParmVarDecl *Param = MethList->Method->param_begin()[NumSelIdents-1];
5208 if (Param->getIdentifier()) {
5209 CodeCompletionString *Pattern = new CodeCompletionString;
5210 Pattern->AddTypedTextChunk(Param->getIdentifier()->getName());
5211 Results.AddResult(Pattern);
5212 }
5213 }
5214
5215 continue;
5216 }
5217
Douglas Gregor1f5537a2010-07-08 23:20:03 +00005218 Result R(MethList->Method, 0);
5219 R.StartParameter = NumSelIdents;
5220 R.AllParametersAreInformative = false;
5221 R.DeclaringEntity = true;
5222 Results.MaybeAddResult(R, CurContext);
5223 }
5224 }
5225
5226 Results.ExitScope();
Douglas Gregore6b1bb62010-08-11 21:23:17 +00005227 HandleCodeCompleteResults(this, CodeCompleter,
5228 CodeCompletionContext::CCC_Other,
5229 Results.data(),Results.size());
Douglas Gregor1f5537a2010-07-08 23:20:03 +00005230}
Douglas Gregor87c08a52010-08-13 22:48:40 +00005231
Douglas Gregorf29c5232010-08-24 22:20:20 +00005232void Sema::CodeCompletePreprocessorDirective(bool InConditional) {
Douglas Gregorf44e8542010-08-24 19:08:16 +00005233 ResultBuilder Results(*this);
5234 Results.EnterNewScope();
5235
5236 // #if <condition>
5237 CodeCompletionString *Pattern = new CodeCompletionString;
5238 Pattern->AddTypedTextChunk("if");
5239 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
5240 Pattern->AddPlaceholderChunk("condition");
5241 Results.AddResult(Pattern);
5242
5243 // #ifdef <macro>
5244 Pattern = new CodeCompletionString;
5245 Pattern->AddTypedTextChunk("ifdef");
5246 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
5247 Pattern->AddPlaceholderChunk("macro");
5248 Results.AddResult(Pattern);
5249
5250 // #ifndef <macro>
5251 Pattern = new CodeCompletionString;
5252 Pattern->AddTypedTextChunk("ifndef");
5253 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
5254 Pattern->AddPlaceholderChunk("macro");
5255 Results.AddResult(Pattern);
5256
5257 if (InConditional) {
5258 // #elif <condition>
5259 Pattern = new CodeCompletionString;
5260 Pattern->AddTypedTextChunk("elif");
5261 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
5262 Pattern->AddPlaceholderChunk("condition");
5263 Results.AddResult(Pattern);
5264
5265 // #else
5266 Pattern = new CodeCompletionString;
5267 Pattern->AddTypedTextChunk("else");
5268 Results.AddResult(Pattern);
5269
5270 // #endif
5271 Pattern = new CodeCompletionString;
5272 Pattern->AddTypedTextChunk("endif");
5273 Results.AddResult(Pattern);
5274 }
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 // #include <header>
5286 Pattern = new CodeCompletionString;
5287 Pattern->AddTypedTextChunk("include");
5288 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
5289 Pattern->AddTextChunk("<");
5290 Pattern->AddPlaceholderChunk("header");
5291 Pattern->AddTextChunk(">");
5292 Results.AddResult(Pattern);
5293
5294 // #define <macro>
5295 Pattern = new CodeCompletionString;
5296 Pattern->AddTypedTextChunk("define");
5297 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
5298 Pattern->AddPlaceholderChunk("macro");
5299 Results.AddResult(Pattern);
5300
5301 // #define <macro>(<args>)
5302 Pattern = new CodeCompletionString;
5303 Pattern->AddTypedTextChunk("define");
5304 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
5305 Pattern->AddPlaceholderChunk("macro");
5306 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
5307 Pattern->AddPlaceholderChunk("args");
5308 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
5309 Results.AddResult(Pattern);
5310
5311 // #undef <macro>
5312 Pattern = new CodeCompletionString;
5313 Pattern->AddTypedTextChunk("undef");
5314 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
5315 Pattern->AddPlaceholderChunk("macro");
5316 Results.AddResult(Pattern);
5317
5318 // #line <number>
5319 Pattern = new CodeCompletionString;
5320 Pattern->AddTypedTextChunk("line");
5321 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
5322 Pattern->AddPlaceholderChunk("number");
5323 Results.AddResult(Pattern);
5324
5325 // #line <number> "filename"
5326 Pattern = new CodeCompletionString;
5327 Pattern->AddTypedTextChunk("line");
5328 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
5329 Pattern->AddPlaceholderChunk("number");
5330 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
5331 Pattern->AddTextChunk("\"");
5332 Pattern->AddPlaceholderChunk("filename");
5333 Pattern->AddTextChunk("\"");
5334 Results.AddResult(Pattern);
5335
5336 // #error <message>
5337 Pattern = new CodeCompletionString;
5338 Pattern->AddTypedTextChunk("error");
5339 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
5340 Pattern->AddPlaceholderChunk("message");
5341 Results.AddResult(Pattern);
5342
5343 // #pragma <arguments>
5344 Pattern = new CodeCompletionString;
5345 Pattern->AddTypedTextChunk("pragma");
5346 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
5347 Pattern->AddPlaceholderChunk("arguments");
5348 Results.AddResult(Pattern);
5349
5350 if (getLangOptions().ObjC1) {
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 // #import <header>
5361 Pattern = new CodeCompletionString;
5362 Pattern->AddTypedTextChunk("import");
5363 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
5364 Pattern->AddTextChunk("<");
5365 Pattern->AddPlaceholderChunk("header");
5366 Pattern->AddTextChunk(">");
5367 Results.AddResult(Pattern);
5368 }
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 // #include_next <header>
5380 Pattern = new CodeCompletionString;
5381 Pattern->AddTypedTextChunk("include_next");
5382 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
5383 Pattern->AddTextChunk("<");
5384 Pattern->AddPlaceholderChunk("header");
5385 Pattern->AddTextChunk(">");
5386 Results.AddResult(Pattern);
5387
5388 // #warning <message>
5389 Pattern = new CodeCompletionString;
5390 Pattern->AddTypedTextChunk("warning");
5391 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
5392 Pattern->AddPlaceholderChunk("message");
5393 Results.AddResult(Pattern);
5394
5395 // Note: #ident and #sccs are such crazy anachronisms that we don't provide
5396 // completions for them. And __include_macros is a Clang-internal extension
5397 // that we don't want to encourage anyone to use.
5398
5399 // FIXME: we don't support #assert or #unassert, so don't suggest them.
5400 Results.ExitScope();
5401
Douglas Gregorf44e8542010-08-24 19:08:16 +00005402 HandleCodeCompleteResults(this, CodeCompleter,
Douglas Gregor721f3592010-08-25 18:41:16 +00005403 CodeCompletionContext::CCC_PreprocessorDirective,
Douglas Gregorf44e8542010-08-24 19:08:16 +00005404 Results.data(), Results.size());
5405}
5406
5407void Sema::CodeCompleteInPreprocessorConditionalExclusion(Scope *S) {
Douglas Gregorf29c5232010-08-24 22:20:20 +00005408 CodeCompleteOrdinaryName(S,
John McCallf312b1e2010-08-26 23:41:50 +00005409 S->getFnParent()? Sema::PCC_RecoveryInFunction
5410 : Sema::PCC_Namespace);
Douglas Gregorf44e8542010-08-24 19:08:16 +00005411}
5412
Douglas Gregorf29c5232010-08-24 22:20:20 +00005413void Sema::CodeCompletePreprocessorMacroName(bool IsDefinition) {
Douglas Gregor1fbb4472010-08-24 20:21:13 +00005414 ResultBuilder Results(*this);
5415 if (!IsDefinition && (!CodeCompleter || CodeCompleter->includeMacros())) {
5416 // Add just the names of macros, not their arguments.
5417 Results.EnterNewScope();
5418 for (Preprocessor::macro_iterator M = PP.macro_begin(),
5419 MEnd = PP.macro_end();
5420 M != MEnd; ++M) {
5421 CodeCompletionString *Pattern = new CodeCompletionString;
5422 Pattern->AddTypedTextChunk(M->first->getName());
5423 Results.AddResult(Pattern);
5424 }
5425 Results.ExitScope();
5426 } else if (IsDefinition) {
5427 // FIXME: Can we detect when the user just wrote an include guard above?
5428 }
5429
5430 HandleCodeCompleteResults(this, CodeCompleter,
5431 IsDefinition? CodeCompletionContext::CCC_MacroName
5432 : CodeCompletionContext::CCC_MacroNameUse,
5433 Results.data(), Results.size());
5434}
5435
Douglas Gregorf29c5232010-08-24 22:20:20 +00005436void Sema::CodeCompletePreprocessorExpression() {
5437 ResultBuilder Results(*this);
5438
5439 if (!CodeCompleter || CodeCompleter->includeMacros())
5440 AddMacroResults(PP, Results);
5441
5442 // defined (<macro>)
5443 Results.EnterNewScope();
5444 CodeCompletionString *Pattern = new CodeCompletionString;
5445 Pattern->AddTypedTextChunk("defined");
5446 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
5447 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
5448 Pattern->AddPlaceholderChunk("macro");
5449 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
5450 Results.AddResult(Pattern);
5451 Results.ExitScope();
5452
5453 HandleCodeCompleteResults(this, CodeCompleter,
5454 CodeCompletionContext::CCC_PreprocessorExpression,
5455 Results.data(), Results.size());
5456}
5457
5458void Sema::CodeCompletePreprocessorMacroArgument(Scope *S,
5459 IdentifierInfo *Macro,
5460 MacroInfo *MacroInfo,
5461 unsigned Argument) {
5462 // FIXME: In the future, we could provide "overload" results, much like we
5463 // do for function calls.
5464
5465 CodeCompleteOrdinaryName(S,
John McCallf312b1e2010-08-26 23:41:50 +00005466 S->getFnParent()? Sema::PCC_RecoveryInFunction
5467 : Sema::PCC_Namespace);
Douglas Gregorf29c5232010-08-24 22:20:20 +00005468}
5469
Douglas Gregor55817af2010-08-25 17:04:25 +00005470void Sema::CodeCompleteNaturalLanguage() {
Douglas Gregor55817af2010-08-25 17:04:25 +00005471 HandleCodeCompleteResults(this, CodeCompleter,
Douglas Gregoraf1c6b52010-08-25 17:10:00 +00005472 CodeCompletionContext::CCC_NaturalLanguage,
Douglas Gregor55817af2010-08-25 17:04:25 +00005473 0, 0);
5474}
5475
Douglas Gregor87c08a52010-08-13 22:48:40 +00005476void Sema::GatherGlobalCodeCompletions(
John McCall0a2c5e22010-08-25 06:19:51 +00005477 llvm::SmallVectorImpl<CodeCompletionResult> &Results) {
Douglas Gregor87c08a52010-08-13 22:48:40 +00005478 ResultBuilder Builder(*this);
5479
Douglas Gregor8071e422010-08-15 06:18:01 +00005480 if (!CodeCompleter || CodeCompleter->includeGlobals()) {
5481 CodeCompletionDeclConsumer Consumer(Builder,
5482 Context.getTranslationUnitDecl());
5483 LookupVisibleDecls(Context.getTranslationUnitDecl(), LookupAnyName,
5484 Consumer);
5485 }
Douglas Gregor87c08a52010-08-13 22:48:40 +00005486
5487 if (!CodeCompleter || CodeCompleter->includeMacros())
5488 AddMacroResults(PP, Builder);
5489
5490 Results.clear();
5491 Results.insert(Results.end(),
5492 Builder.data(), Builder.data() + Builder.size());
5493}