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