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