blob: 87474952d5167680e8e6201deaab1c2ab5a6ab14 [file] [log] [blame]
Douglas Gregor81b747b2009-09-17 21:32:03 +00001//===---------------- SemaCodeComplete.cpp - Code Completion ----*- C++ -*-===//
2//
3// The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9//
10// This file defines the code-completion semantic actions.
11//
12//===----------------------------------------------------------------------===//
John McCall2d887082010-08-25 22:03:47 +000013#include "clang/Sema/SemaInternal.h"
Douglas Gregore737f502010-08-12 20:07:10 +000014#include "clang/Sema/Lookup.h"
John McCall120d63c2010-08-24 20:38:10 +000015#include "clang/Sema/Overload.h"
Douglas Gregor81b747b2009-09-17 21:32:03 +000016#include "clang/Sema/CodeCompleteConsumer.h"
Douglas Gregor719770d2010-04-06 17:30:22 +000017#include "clang/Sema/ExternalSemaSource.h"
John McCall5f1e0942010-08-24 08:50:51 +000018#include "clang/Sema/Scope.h"
John McCall781472f2010-08-25 08:40:02 +000019#include "clang/Sema/ScopeInfo.h"
John McCall7cd088e2010-08-24 07:21:54 +000020#include "clang/AST/DeclObjC.h"
Douglas Gregorb9d0ef72009-09-21 19:57:38 +000021#include "clang/AST/ExprCXX.h"
Douglas Gregor24a069f2009-11-17 17:59:40 +000022#include "clang/AST/ExprObjC.h"
Douglas Gregor3f7c7f42009-10-30 16:50:04 +000023#include "clang/Lex/MacroInfo.h"
24#include "clang/Lex/Preprocessor.h"
Douglas Gregord36adf52010-09-16 16:06:31 +000025#include "llvm/ADT/DenseSet.h"
Douglas Gregor86d9a522009-09-21 16:56:56 +000026#include "llvm/ADT/SmallPtrSet.h"
Douglas Gregor6a684032009-09-28 03:51:44 +000027#include "llvm/ADT/StringExtras.h"
Douglas Gregor22f56992010-04-06 19:22:33 +000028#include "llvm/ADT/StringSwitch.h"
Douglas Gregor458433d2010-08-26 15:07:07 +000029#include "llvm/ADT/Twine.h"
Douglas Gregor86d9a522009-09-21 16:56:56 +000030#include <list>
31#include <map>
32#include <vector>
Douglas Gregor81b747b2009-09-17 21:32:03 +000033
34using namespace clang;
John McCall781472f2010-08-25 08:40:02 +000035using namespace sema;
Douglas Gregor81b747b2009-09-17 21:32:03 +000036
Douglas Gregor86d9a522009-09-21 16:56:56 +000037namespace {
38 /// \brief A container of code-completion results.
39 class ResultBuilder {
40 public:
41 /// \brief The type of a name-lookup filter, which can be provided to the
42 /// name-lookup routines to specify which declarations should be included in
43 /// the result set (when it returns true) and which declarations should be
44 /// filtered out (returns false).
45 typedef bool (ResultBuilder::*LookupFilter)(NamedDecl *) const;
46
John McCall0a2c5e22010-08-25 06:19:51 +000047 typedef CodeCompletionResult Result;
Douglas Gregor86d9a522009-09-21 16:56:56 +000048
49 private:
50 /// \brief The actual results we have found.
51 std::vector<Result> Results;
52
53 /// \brief A record of all of the declarations we have found and placed
54 /// into the result set, used to ensure that no declaration ever gets into
55 /// the result set twice.
56 llvm::SmallPtrSet<Decl*, 16> AllDeclsFound;
57
Douglas Gregorfbcb5d62009-12-06 20:23:50 +000058 typedef std::pair<NamedDecl *, unsigned> DeclIndexPair;
59
60 /// \brief An entry in the shadow map, which is optimized to store
61 /// a single (declaration, index) mapping (the common case) but
62 /// can also store a list of (declaration, index) mappings.
63 class ShadowMapEntry {
64 typedef llvm::SmallVector<DeclIndexPair, 4> DeclIndexPairVector;
65
66 /// \brief Contains either the solitary NamedDecl * or a vector
67 /// of (declaration, index) pairs.
68 llvm::PointerUnion<NamedDecl *, DeclIndexPairVector*> DeclOrVector;
69
70 /// \brief When the entry contains a single declaration, this is
71 /// the index associated with that entry.
72 unsigned SingleDeclIndex;
73
74 public:
75 ShadowMapEntry() : DeclOrVector(), SingleDeclIndex(0) { }
76
77 void Add(NamedDecl *ND, unsigned Index) {
78 if (DeclOrVector.isNull()) {
79 // 0 - > 1 elements: just set the single element information.
80 DeclOrVector = ND;
81 SingleDeclIndex = Index;
82 return;
83 }
84
85 if (NamedDecl *PrevND = DeclOrVector.dyn_cast<NamedDecl *>()) {
86 // 1 -> 2 elements: create the vector of results and push in the
87 // existing declaration.
88 DeclIndexPairVector *Vec = new DeclIndexPairVector;
89 Vec->push_back(DeclIndexPair(PrevND, SingleDeclIndex));
90 DeclOrVector = Vec;
91 }
92
93 // Add the new element to the end of the vector.
94 DeclOrVector.get<DeclIndexPairVector*>()->push_back(
95 DeclIndexPair(ND, Index));
96 }
97
98 void Destroy() {
99 if (DeclIndexPairVector *Vec
100 = DeclOrVector.dyn_cast<DeclIndexPairVector *>()) {
101 delete Vec;
102 DeclOrVector = ((NamedDecl *)0);
103 }
104 }
105
106 // Iteration.
107 class iterator;
108 iterator begin() const;
109 iterator end() const;
110 };
111
Douglas Gregor86d9a522009-09-21 16:56:56 +0000112 /// \brief A mapping from declaration names to the declarations that have
113 /// this name within a particular scope and their index within the list of
114 /// results.
Douglas Gregorfbcb5d62009-12-06 20:23:50 +0000115 typedef llvm::DenseMap<DeclarationName, ShadowMapEntry> ShadowMap;
Douglas Gregor86d9a522009-09-21 16:56:56 +0000116
117 /// \brief The semantic analysis object for which results are being
118 /// produced.
119 Sema &SemaRef;
120
121 /// \brief If non-NULL, a filter function used to remove any code-completion
122 /// results that are not desirable.
123 LookupFilter Filter;
Douglas Gregor45bcd432010-01-14 03:21:49 +0000124
125 /// \brief Whether we should allow declarations as
126 /// nested-name-specifiers that would otherwise be filtered out.
127 bool AllowNestedNameSpecifiers;
128
Douglas Gregor5ac3bdb2010-05-30 01:49:25 +0000129 /// \brief If set, the type that we would prefer our resulting value
130 /// declarations to have.
131 ///
132 /// Closely matching the preferred type gives a boost to a result's
133 /// priority.
134 CanQualType PreferredType;
135
Douglas Gregor86d9a522009-09-21 16:56:56 +0000136 /// \brief A list of shadow maps, which is used to model name hiding at
137 /// different levels of, e.g., the inheritance hierarchy.
138 std::list<ShadowMap> ShadowMaps;
139
Douglas Gregor3cdee122010-08-26 16:36:48 +0000140 /// \brief If we're potentially referring to a C++ member function, the set
141 /// of qualifiers applied to the object type.
142 Qualifiers ObjectTypeQualifiers;
143
144 /// \brief Whether the \p ObjectTypeQualifiers field is active.
145 bool HasObjectTypeQualifiers;
146
Douglas Gregor265f7492010-08-27 15:29:55 +0000147 /// \brief The selector that we prefer.
148 Selector PreferredSelector;
149
Douglas Gregorcee9ff12010-09-20 22:39:41 +0000150 /// \brief The completion context in which
151 CodeCompletionContext CompletionContext;
152
153 void AdjustResultPriorityForDecl(Result &R);
Douglas Gregor1f5537a2010-07-08 23:20:03 +0000154
Douglas Gregor6f942b22010-09-21 16:06:22 +0000155 void MaybeAddConstructorResults(Result R);
156
Douglas Gregor86d9a522009-09-21 16:56:56 +0000157 public:
158 explicit ResultBuilder(Sema &SemaRef, LookupFilter Filter = 0)
Douglas Gregor3cdee122010-08-26 16:36:48 +0000159 : SemaRef(SemaRef), Filter(Filter), AllowNestedNameSpecifiers(false),
Douglas Gregorcee9ff12010-09-20 22:39:41 +0000160 HasObjectTypeQualifiers(false),
161 CompletionContext(CodeCompletionContext::CCC_Other) { }
Douglas Gregor86d9a522009-09-21 16:56:56 +0000162
Douglas Gregord8e8a582010-05-25 21:41:55 +0000163 /// \brief Whether we should include code patterns in the completion
164 /// results.
165 bool includeCodePatterns() const {
166 return SemaRef.CodeCompleter &&
Douglas Gregorf6961522010-08-27 21:18:54 +0000167 SemaRef.CodeCompleter->includeCodePatterns();
Douglas Gregord8e8a582010-05-25 21:41:55 +0000168 }
169
Douglas Gregor86d9a522009-09-21 16:56:56 +0000170 /// \brief Set the filter used for code-completion results.
171 void setFilter(LookupFilter Filter) {
172 this->Filter = Filter;
173 }
174
Douglas Gregor86d9a522009-09-21 16:56:56 +0000175 Result *data() { return Results.empty()? 0 : &Results.front(); }
176 unsigned size() const { return Results.size(); }
177 bool empty() const { return Results.empty(); }
178
Douglas Gregor5ac3bdb2010-05-30 01:49:25 +0000179 /// \brief Specify the preferred type.
180 void setPreferredType(QualType T) {
181 PreferredType = SemaRef.Context.getCanonicalType(T);
182 }
183
Douglas Gregor3cdee122010-08-26 16:36:48 +0000184 /// \brief Set the cv-qualifiers on the object type, for us in filtering
185 /// calls to member functions.
186 ///
187 /// When there are qualifiers in this set, they will be used to filter
188 /// out member functions that aren't available (because there will be a
189 /// cv-qualifier mismatch) or prefer functions with an exact qualifier
190 /// match.
191 void setObjectTypeQualifiers(Qualifiers Quals) {
192 ObjectTypeQualifiers = Quals;
193 HasObjectTypeQualifiers = true;
194 }
195
Douglas Gregor265f7492010-08-27 15:29:55 +0000196 /// \brief Set the preferred selector.
197 ///
198 /// When an Objective-C method declaration result is added, and that
199 /// method's selector matches this preferred selector, we give that method
200 /// a slight priority boost.
201 void setPreferredSelector(Selector Sel) {
202 PreferredSelector = Sel;
203 }
204
Douglas Gregorcee9ff12010-09-20 22:39:41 +0000205 /// \brief Retrieve the code-completion context for which results are
206 /// being collected.
207 const CodeCompletionContext &getCompletionContext() const {
208 return CompletionContext;
209 }
210
211 /// \brief Set the code-completion context.
212 void setCompletionContext(const CodeCompletionContext &CompletionContext) {
213 this->CompletionContext = CompletionContext;
214 }
215
Douglas Gregor45bcd432010-01-14 03:21:49 +0000216 /// \brief Specify whether nested-name-specifiers are allowed.
217 void allowNestedNameSpecifiers(bool Allow = true) {
218 AllowNestedNameSpecifiers = Allow;
219 }
220
Douglas Gregorb9d77572010-09-21 00:03:25 +0000221 /// \brief Return the semantic analysis object for which we are collecting
222 /// code completion results.
223 Sema &getSema() const { return SemaRef; }
224
Douglas Gregore495b7f2010-01-14 00:20:49 +0000225 /// \brief Determine whether the given declaration is at all interesting
226 /// as a code-completion result.
Douglas Gregor45bcd432010-01-14 03:21:49 +0000227 ///
228 /// \param ND the declaration that we are inspecting.
229 ///
230 /// \param AsNestedNameSpecifier will be set true if this declaration is
231 /// only interesting when it is a nested-name-specifier.
232 bool isInterestingDecl(NamedDecl *ND, bool &AsNestedNameSpecifier) const;
Douglas Gregor6660d842010-01-14 00:41:07 +0000233
234 /// \brief Check whether the result is hidden by the Hiding declaration.
235 ///
236 /// \returns true if the result is hidden and cannot be found, false if
237 /// the hidden result could still be found. When false, \p R may be
238 /// modified to describe how the result can be found (e.g., via extra
239 /// qualification).
240 bool CheckHiddenResult(Result &R, DeclContext *CurContext,
241 NamedDecl *Hiding);
242
Douglas Gregor86d9a522009-09-21 16:56:56 +0000243 /// \brief Add a new result to this result set (if it isn't already in one
244 /// of the shadow maps), or replace an existing result (for, e.g., a
245 /// redeclaration).
Douglas Gregor456c4a12009-09-21 20:12:40 +0000246 ///
Douglas Gregor1ca6ae82010-01-14 01:09:38 +0000247 /// \param CurContext the result to add (if it is unique).
Douglas Gregor456c4a12009-09-21 20:12:40 +0000248 ///
249 /// \param R the context in which this result will be named.
250 void MaybeAddResult(Result R, DeclContext *CurContext = 0);
Douglas Gregor86d9a522009-09-21 16:56:56 +0000251
Douglas Gregor1ca6ae82010-01-14 01:09:38 +0000252 /// \brief Add a new result to this result set, where we already know
253 /// the hiding declation (if any).
254 ///
255 /// \param R the result to add (if it is unique).
256 ///
257 /// \param CurContext the context in which this result will be named.
258 ///
259 /// \param Hiding the declaration that hides the result.
Douglas Gregor0cc84042010-01-14 15:47:35 +0000260 ///
261 /// \param InBaseClass whether the result was found in a base
262 /// class of the searched context.
263 void AddResult(Result R, DeclContext *CurContext, NamedDecl *Hiding,
264 bool InBaseClass);
Douglas Gregor1ca6ae82010-01-14 01:09:38 +0000265
Douglas Gregora4477812010-01-14 16:01:26 +0000266 /// \brief Add a new non-declaration result to this result set.
267 void AddResult(Result R);
268
Douglas Gregor86d9a522009-09-21 16:56:56 +0000269 /// \brief Enter into a new scope.
270 void EnterNewScope();
271
272 /// \brief Exit from the current scope.
273 void ExitScope();
274
Douglas Gregor55385fe2009-11-18 04:19:12 +0000275 /// \brief Ignore this declaration, if it is seen again.
276 void Ignore(Decl *D) { AllDeclsFound.insert(D->getCanonicalDecl()); }
277
Douglas Gregor86d9a522009-09-21 16:56:56 +0000278 /// \name Name lookup predicates
279 ///
280 /// These predicates can be passed to the name lookup functions to filter the
281 /// results of name lookup. All of the predicates have the same type, so that
282 ///
283 //@{
Douglas Gregor791215b2009-09-21 20:51:25 +0000284 bool IsOrdinaryName(NamedDecl *ND) const;
Douglas Gregor4710e5b2010-05-28 00:49:12 +0000285 bool IsOrdinaryNonTypeName(NamedDecl *ND) const;
Douglas Gregorf9578432010-07-28 21:50:18 +0000286 bool IsIntegralConstantValue(NamedDecl *ND) const;
Douglas Gregor01dfea02010-01-10 23:08:15 +0000287 bool IsOrdinaryNonValueName(NamedDecl *ND) const;
Douglas Gregor86d9a522009-09-21 16:56:56 +0000288 bool IsNestedNameSpecifier(NamedDecl *ND) const;
289 bool IsEnum(NamedDecl *ND) const;
290 bool IsClassOrStruct(NamedDecl *ND) const;
291 bool IsUnion(NamedDecl *ND) const;
292 bool IsNamespace(NamedDecl *ND) const;
293 bool IsNamespaceOrAlias(NamedDecl *ND) const;
294 bool IsType(NamedDecl *ND) const;
Douglas Gregoreb5758b2009-09-23 22:26:46 +0000295 bool IsMember(NamedDecl *ND) const;
Douglas Gregor80f4f4c2010-01-14 16:08:12 +0000296 bool IsObjCIvar(NamedDecl *ND) const;
Douglas Gregor8e254cf2010-05-27 23:06:34 +0000297 bool IsObjCMessageReceiver(NamedDecl *ND) const;
Douglas Gregorfb629412010-08-23 21:17:50 +0000298 bool IsObjCCollection(NamedDecl *ND) const;
Douglas Gregor86d9a522009-09-21 16:56:56 +0000299 //@}
300 };
301}
302
Douglas Gregorfbcb5d62009-12-06 20:23:50 +0000303class ResultBuilder::ShadowMapEntry::iterator {
304 llvm::PointerUnion<NamedDecl*, const DeclIndexPair*> DeclOrIterator;
305 unsigned SingleDeclIndex;
306
307public:
308 typedef DeclIndexPair value_type;
309 typedef value_type reference;
310 typedef std::ptrdiff_t difference_type;
311 typedef std::input_iterator_tag iterator_category;
312
313 class pointer {
314 DeclIndexPair Value;
315
316 public:
317 pointer(const DeclIndexPair &Value) : Value(Value) { }
318
319 const DeclIndexPair *operator->() const {
320 return &Value;
321 }
322 };
323
324 iterator() : DeclOrIterator((NamedDecl *)0), SingleDeclIndex(0) { }
325
326 iterator(NamedDecl *SingleDecl, unsigned Index)
327 : DeclOrIterator(SingleDecl), SingleDeclIndex(Index) { }
328
329 iterator(const DeclIndexPair *Iterator)
330 : DeclOrIterator(Iterator), SingleDeclIndex(0) { }
331
332 iterator &operator++() {
333 if (DeclOrIterator.is<NamedDecl *>()) {
334 DeclOrIterator = (NamedDecl *)0;
335 SingleDeclIndex = 0;
336 return *this;
337 }
338
339 const DeclIndexPair *I = DeclOrIterator.get<const DeclIndexPair*>();
340 ++I;
341 DeclOrIterator = I;
342 return *this;
343 }
344
Chris Lattner66392d42010-09-04 18:12:20 +0000345 /*iterator operator++(int) {
Douglas Gregorfbcb5d62009-12-06 20:23:50 +0000346 iterator tmp(*this);
347 ++(*this);
348 return tmp;
Chris Lattner66392d42010-09-04 18:12:20 +0000349 }*/
Douglas Gregorfbcb5d62009-12-06 20:23:50 +0000350
351 reference operator*() const {
352 if (NamedDecl *ND = DeclOrIterator.dyn_cast<NamedDecl *>())
353 return reference(ND, SingleDeclIndex);
354
Douglas Gregord490f952009-12-06 21:27:58 +0000355 return *DeclOrIterator.get<const DeclIndexPair*>();
Douglas Gregorfbcb5d62009-12-06 20:23:50 +0000356 }
357
358 pointer operator->() const {
359 return pointer(**this);
360 }
361
362 friend bool operator==(const iterator &X, const iterator &Y) {
Douglas Gregord490f952009-12-06 21:27:58 +0000363 return X.DeclOrIterator.getOpaqueValue()
364 == Y.DeclOrIterator.getOpaqueValue() &&
Douglas Gregorfbcb5d62009-12-06 20:23:50 +0000365 X.SingleDeclIndex == Y.SingleDeclIndex;
366 }
367
368 friend bool operator!=(const iterator &X, const iterator &Y) {
Douglas Gregord490f952009-12-06 21:27:58 +0000369 return !(X == Y);
Douglas Gregorfbcb5d62009-12-06 20:23:50 +0000370 }
371};
372
Douglas Gregorfbcb5d62009-12-06 20:23:50 +0000373ResultBuilder::ShadowMapEntry::iterator
374ResultBuilder::ShadowMapEntry::begin() const {
375 if (DeclOrVector.isNull())
376 return iterator();
377
378 if (NamedDecl *ND = DeclOrVector.dyn_cast<NamedDecl *>())
379 return iterator(ND, SingleDeclIndex);
380
381 return iterator(DeclOrVector.get<DeclIndexPairVector *>()->begin());
382}
383
384ResultBuilder::ShadowMapEntry::iterator
385ResultBuilder::ShadowMapEntry::end() const {
386 if (DeclOrVector.is<NamedDecl *>() || DeclOrVector.isNull())
387 return iterator();
388
389 return iterator(DeclOrVector.get<DeclIndexPairVector *>()->end());
390}
391
Douglas Gregor456c4a12009-09-21 20:12:40 +0000392/// \brief Compute the qualification required to get from the current context
393/// (\p CurContext) to the target context (\p TargetContext).
394///
395/// \param Context the AST context in which the qualification will be used.
396///
397/// \param CurContext the context where an entity is being named, which is
398/// typically based on the current scope.
399///
400/// \param TargetContext the context in which the named entity actually
401/// resides.
402///
403/// \returns a nested name specifier that refers into the target context, or
404/// NULL if no qualification is needed.
405static NestedNameSpecifier *
406getRequiredQualification(ASTContext &Context,
407 DeclContext *CurContext,
408 DeclContext *TargetContext) {
409 llvm::SmallVector<DeclContext *, 4> TargetParents;
410
411 for (DeclContext *CommonAncestor = TargetContext;
412 CommonAncestor && !CommonAncestor->Encloses(CurContext);
413 CommonAncestor = CommonAncestor->getLookupParent()) {
414 if (CommonAncestor->isTransparentContext() ||
415 CommonAncestor->isFunctionOrMethod())
416 continue;
417
418 TargetParents.push_back(CommonAncestor);
419 }
420
421 NestedNameSpecifier *Result = 0;
422 while (!TargetParents.empty()) {
423 DeclContext *Parent = TargetParents.back();
424 TargetParents.pop_back();
425
Douglas Gregorfb629412010-08-23 21:17:50 +0000426 if (NamespaceDecl *Namespace = dyn_cast<NamespaceDecl>(Parent)) {
427 if (!Namespace->getIdentifier())
428 continue;
429
Douglas Gregor456c4a12009-09-21 20:12:40 +0000430 Result = NestedNameSpecifier::Create(Context, Result, Namespace);
Douglas Gregorfb629412010-08-23 21:17:50 +0000431 }
Douglas Gregor456c4a12009-09-21 20:12:40 +0000432 else if (TagDecl *TD = dyn_cast<TagDecl>(Parent))
433 Result = NestedNameSpecifier::Create(Context, Result,
434 false,
435 Context.getTypeDeclType(TD).getTypePtr());
Douglas Gregor0c8296d2009-11-07 00:00:49 +0000436 }
Douglas Gregor456c4a12009-09-21 20:12:40 +0000437 return Result;
438}
439
Douglas Gregor45bcd432010-01-14 03:21:49 +0000440bool ResultBuilder::isInterestingDecl(NamedDecl *ND,
441 bool &AsNestedNameSpecifier) const {
442 AsNestedNameSpecifier = false;
443
Douglas Gregore495b7f2010-01-14 00:20:49 +0000444 ND = ND->getUnderlyingDecl();
445 unsigned IDNS = ND->getIdentifierNamespace();
Douglas Gregorf52cede2009-10-09 22:16:47 +0000446
447 // Skip unnamed entities.
Douglas Gregore495b7f2010-01-14 00:20:49 +0000448 if (!ND->getDeclName())
449 return false;
Douglas Gregor86d9a522009-09-21 16:56:56 +0000450
451 // Friend declarations and declarations introduced due to friends are never
452 // added as results.
John McCall92b7f702010-03-11 07:50:04 +0000453 if (IDNS & (Decl::IDNS_OrdinaryFriend | Decl::IDNS_TagFriend))
Douglas Gregore495b7f2010-01-14 00:20:49 +0000454 return false;
455
Douglas Gregor76282942009-12-11 17:31:05 +0000456 // Class template (partial) specializations are never added as results.
Douglas Gregore495b7f2010-01-14 00:20:49 +0000457 if (isa<ClassTemplateSpecializationDecl>(ND) ||
458 isa<ClassTemplatePartialSpecializationDecl>(ND))
459 return false;
Douglas Gregor86d9a522009-09-21 16:56:56 +0000460
Douglas Gregor76282942009-12-11 17:31:05 +0000461 // Using declarations themselves are never added as results.
Douglas Gregore495b7f2010-01-14 00:20:49 +0000462 if (isa<UsingDecl>(ND))
463 return false;
464
465 // Some declarations have reserved names that we don't want to ever show.
466 if (const IdentifierInfo *Id = ND->getIdentifier()) {
Douglas Gregor86d9a522009-09-21 16:56:56 +0000467 // __va_list_tag is a freak of nature. Find it and skip it.
468 if (Id->isStr("__va_list_tag") || Id->isStr("__builtin_va_list"))
Douglas Gregore495b7f2010-01-14 00:20:49 +0000469 return false;
Douglas Gregor86d9a522009-09-21 16:56:56 +0000470
Douglas Gregorf52cede2009-10-09 22:16:47 +0000471 // Filter out names reserved for the implementation (C99 7.1.3,
Douglas Gregor797efb52010-07-14 17:44:04 +0000472 // C++ [lib.global.names]) if they come from a system header.
Daniel Dunbare013d682009-10-18 20:26:12 +0000473 //
474 // FIXME: Add predicate for this.
Douglas Gregorf52cede2009-10-09 22:16:47 +0000475 if (Id->getLength() >= 2) {
Daniel Dunbare013d682009-10-18 20:26:12 +0000476 const char *Name = Id->getNameStart();
Douglas Gregorf52cede2009-10-09 22:16:47 +0000477 if (Name[0] == '_' &&
Douglas Gregor797efb52010-07-14 17:44:04 +0000478 (Name[1] == '_' || (Name[1] >= 'A' && Name[1] <= 'Z')) &&
479 (ND->getLocation().isInvalid() ||
480 SemaRef.SourceMgr.isInSystemHeader(
481 SemaRef.SourceMgr.getSpellingLoc(ND->getLocation()))))
Douglas Gregore495b7f2010-01-14 00:20:49 +0000482 return false;
Douglas Gregorf52cede2009-10-09 22:16:47 +0000483 }
Douglas Gregor86d9a522009-09-21 16:56:56 +0000484 }
Douglas Gregor6f942b22010-09-21 16:06:22 +0000485
Douglas Gregora5fb7c32010-08-16 23:05:20 +0000486 if (Filter == &ResultBuilder::IsNestedNameSpecifier ||
487 ((isa<NamespaceDecl>(ND) || isa<NamespaceAliasDecl>(ND)) &&
488 Filter != &ResultBuilder::IsNamespace &&
489 Filter != &ResultBuilder::IsNamespaceOrAlias))
490 AsNestedNameSpecifier = true;
491
Douglas Gregor86d9a522009-09-21 16:56:56 +0000492 // Filter out any unwanted results.
Douglas Gregor45bcd432010-01-14 03:21:49 +0000493 if (Filter && !(this->*Filter)(ND)) {
494 // Check whether it is interesting as a nested-name-specifier.
495 if (AllowNestedNameSpecifiers && SemaRef.getLangOptions().CPlusPlus &&
496 IsNestedNameSpecifier(ND) &&
497 (Filter != &ResultBuilder::IsMember ||
498 (isa<CXXRecordDecl>(ND) &&
499 cast<CXXRecordDecl>(ND)->isInjectedClassName()))) {
500 AsNestedNameSpecifier = true;
501 return true;
502 }
503
Douglas Gregore495b7f2010-01-14 00:20:49 +0000504 return false;
Douglas Gregora5fb7c32010-08-16 23:05:20 +0000505 }
Douglas Gregore495b7f2010-01-14 00:20:49 +0000506 // ... then it must be interesting!
507 return true;
508}
509
Douglas Gregor6660d842010-01-14 00:41:07 +0000510bool ResultBuilder::CheckHiddenResult(Result &R, DeclContext *CurContext,
511 NamedDecl *Hiding) {
512 // In C, there is no way to refer to a hidden name.
513 // FIXME: This isn't true; we can find a tag name hidden by an ordinary
514 // name if we introduce the tag type.
515 if (!SemaRef.getLangOptions().CPlusPlus)
516 return true;
517
Sebastian Redl7a126a42010-08-31 00:36:30 +0000518 DeclContext *HiddenCtx = R.Declaration->getDeclContext()->getRedeclContext();
Douglas Gregor6660d842010-01-14 00:41:07 +0000519
520 // There is no way to qualify a name declared in a function or method.
521 if (HiddenCtx->isFunctionOrMethod())
522 return true;
523
Sebastian Redl7a126a42010-08-31 00:36:30 +0000524 if (HiddenCtx == Hiding->getDeclContext()->getRedeclContext())
Douglas Gregor6660d842010-01-14 00:41:07 +0000525 return true;
526
527 // We can refer to the result with the appropriate qualification. Do it.
528 R.Hidden = true;
529 R.QualifierIsInformative = false;
530
531 if (!R.Qualifier)
532 R.Qualifier = getRequiredQualification(SemaRef.Context,
533 CurContext,
534 R.Declaration->getDeclContext());
535 return false;
536}
537
Douglas Gregor1f5537a2010-07-08 23:20:03 +0000538/// \brief A simplified classification of types used to determine whether two
539/// types are "similar enough" when adjusting priorities.
Douglas Gregor1827e102010-08-16 16:18:59 +0000540SimplifiedTypeClass clang::getSimplifiedTypeClass(CanQualType T) {
Douglas Gregor1f5537a2010-07-08 23:20:03 +0000541 switch (T->getTypeClass()) {
542 case Type::Builtin:
543 switch (cast<BuiltinType>(T)->getKind()) {
544 case BuiltinType::Void:
545 return STC_Void;
546
547 case BuiltinType::NullPtr:
548 return STC_Pointer;
549
550 case BuiltinType::Overload:
551 case BuiltinType::Dependent:
552 case BuiltinType::UndeducedAuto:
553 return STC_Other;
554
555 case BuiltinType::ObjCId:
556 case BuiltinType::ObjCClass:
557 case BuiltinType::ObjCSel:
558 return STC_ObjectiveC;
559
560 default:
561 return STC_Arithmetic;
562 }
563 return STC_Other;
564
565 case Type::Complex:
566 return STC_Arithmetic;
567
568 case Type::Pointer:
569 return STC_Pointer;
570
571 case Type::BlockPointer:
572 return STC_Block;
573
574 case Type::LValueReference:
575 case Type::RValueReference:
576 return getSimplifiedTypeClass(T->getAs<ReferenceType>()->getPointeeType());
577
578 case Type::ConstantArray:
579 case Type::IncompleteArray:
580 case Type::VariableArray:
581 case Type::DependentSizedArray:
582 return STC_Array;
583
584 case Type::DependentSizedExtVector:
585 case Type::Vector:
586 case Type::ExtVector:
587 return STC_Arithmetic;
588
589 case Type::FunctionProto:
590 case Type::FunctionNoProto:
591 return STC_Function;
592
593 case Type::Record:
594 return STC_Record;
595
596 case Type::Enum:
597 return STC_Arithmetic;
598
599 case Type::ObjCObject:
600 case Type::ObjCInterface:
601 case Type::ObjCObjectPointer:
602 return STC_ObjectiveC;
603
604 default:
605 return STC_Other;
606 }
607}
608
609/// \brief Get the type that a given expression will have if this declaration
610/// is used as an expression in its "typical" code-completion form.
Douglas Gregor1827e102010-08-16 16:18:59 +0000611QualType clang::getDeclUsageType(ASTContext &C, NamedDecl *ND) {
Douglas Gregor1f5537a2010-07-08 23:20:03 +0000612 ND = cast<NamedDecl>(ND->getUnderlyingDecl());
613
614 if (TypeDecl *Type = dyn_cast<TypeDecl>(ND))
615 return C.getTypeDeclType(Type);
616 if (ObjCInterfaceDecl *Iface = dyn_cast<ObjCInterfaceDecl>(ND))
617 return C.getObjCInterfaceType(Iface);
618
619 QualType T;
620 if (FunctionDecl *Function = dyn_cast<FunctionDecl>(ND))
Douglas Gregor5291c3c2010-07-13 08:18:22 +0000621 T = Function->getCallResultType();
Douglas Gregor1f5537a2010-07-08 23:20:03 +0000622 else if (ObjCMethodDecl *Method = dyn_cast<ObjCMethodDecl>(ND))
Douglas Gregor5291c3c2010-07-13 08:18:22 +0000623 T = Method->getSendResultType();
Douglas Gregor1f5537a2010-07-08 23:20:03 +0000624 else if (FunctionTemplateDecl *FunTmpl = dyn_cast<FunctionTemplateDecl>(ND))
Douglas Gregor5291c3c2010-07-13 08:18:22 +0000625 T = FunTmpl->getTemplatedDecl()->getCallResultType();
Douglas Gregor1f5537a2010-07-08 23:20:03 +0000626 else if (EnumConstantDecl *Enumerator = dyn_cast<EnumConstantDecl>(ND))
627 T = C.getTypeDeclType(cast<EnumDecl>(Enumerator->getDeclContext()));
628 else if (ObjCPropertyDecl *Property = dyn_cast<ObjCPropertyDecl>(ND))
629 T = Property->getType();
630 else if (ValueDecl *Value = dyn_cast<ValueDecl>(ND))
631 T = Value->getType();
632 else
633 return QualType();
634
635 return T.getNonReferenceType();
636}
637
Douglas Gregorcee9ff12010-09-20 22:39:41 +0000638void ResultBuilder::AdjustResultPriorityForDecl(Result &R) {
639 // If this is an Objective-C method declaration whose selector matches our
640 // preferred selector, give it a priority boost.
641 if (!PreferredSelector.isNull())
642 if (ObjCMethodDecl *Method = dyn_cast<ObjCMethodDecl>(R.Declaration))
643 if (PreferredSelector == Method->getSelector())
644 R.Priority += CCD_SelectorMatch;
Douglas Gregor08f43cd2010-09-20 23:11:55 +0000645
Douglas Gregorcee9ff12010-09-20 22:39:41 +0000646 // If we have a preferred type, adjust the priority for results with exactly-
647 // matching or nearly-matching types.
648 if (!PreferredType.isNull()) {
649 QualType T = getDeclUsageType(SemaRef.Context, R.Declaration);
650 if (!T.isNull()) {
651 CanQualType TC = SemaRef.Context.getCanonicalType(T);
652 // Check for exactly-matching types (modulo qualifiers).
653 if (SemaRef.Context.hasSameUnqualifiedType(PreferredType, TC))
654 R.Priority /= CCF_ExactTypeMatch;
655 // Check for nearly-matching types, based on classification of each.
656 else if ((getSimplifiedTypeClass(PreferredType)
Douglas Gregor1f5537a2010-07-08 23:20:03 +0000657 == getSimplifiedTypeClass(TC)) &&
Douglas Gregorcee9ff12010-09-20 22:39:41 +0000658 !(PreferredType->isEnumeralType() && TC->isEnumeralType()))
659 R.Priority /= CCF_SimilarTypeMatch;
660 }
661 }
Douglas Gregor1f5537a2010-07-08 23:20:03 +0000662}
663
Douglas Gregor6f942b22010-09-21 16:06:22 +0000664void ResultBuilder::MaybeAddConstructorResults(Result R) {
665 if (!SemaRef.getLangOptions().CPlusPlus || !R.Declaration ||
666 !CompletionContext.wantConstructorResults())
667 return;
668
669 ASTContext &Context = SemaRef.Context;
670 NamedDecl *D = R.Declaration;
671 CXXRecordDecl *Record = 0;
672 if (ClassTemplateDecl *ClassTemplate = dyn_cast<ClassTemplateDecl>(D))
673 Record = ClassTemplate->getTemplatedDecl();
674 else if ((Record = dyn_cast<CXXRecordDecl>(D))) {
675 // Skip specializations and partial specializations.
676 if (isa<ClassTemplateSpecializationDecl>(Record))
677 return;
678 } else {
679 // There are no constructors here.
680 return;
681 }
682
683 Record = Record->getDefinition();
684 if (!Record)
685 return;
686
687
688 QualType RecordTy = Context.getTypeDeclType(Record);
689 DeclarationName ConstructorName
690 = Context.DeclarationNames.getCXXConstructorName(
691 Context.getCanonicalType(RecordTy));
692 for (DeclContext::lookup_result Ctors = Record->lookup(ConstructorName);
693 Ctors.first != Ctors.second; ++Ctors.first) {
694 R.Declaration = *Ctors.first;
695 R.CursorKind = getCursorKindForDecl(R.Declaration);
696 Results.push_back(R);
697 }
698}
699
Douglas Gregore495b7f2010-01-14 00:20:49 +0000700void ResultBuilder::MaybeAddResult(Result R, DeclContext *CurContext) {
701 assert(!ShadowMaps.empty() && "Must enter into a results scope");
702
703 if (R.Kind != Result::RK_Declaration) {
704 // For non-declaration results, just add the result.
705 Results.push_back(R);
706 return;
707 }
708
709 // Look through using declarations.
710 if (UsingShadowDecl *Using = dyn_cast<UsingShadowDecl>(R.Declaration)) {
711 MaybeAddResult(Result(Using->getTargetDecl(), R.Qualifier), CurContext);
712 return;
713 }
714
715 Decl *CanonDecl = R.Declaration->getCanonicalDecl();
716 unsigned IDNS = CanonDecl->getIdentifierNamespace();
717
Douglas Gregor45bcd432010-01-14 03:21:49 +0000718 bool AsNestedNameSpecifier = false;
719 if (!isInterestingDecl(R.Declaration, AsNestedNameSpecifier))
Douglas Gregore495b7f2010-01-14 00:20:49 +0000720 return;
721
Douglas Gregor6f942b22010-09-21 16:06:22 +0000722 // C++ constructors are never found by name lookup.
723 if (isa<CXXConstructorDecl>(R.Declaration))
724 return;
725
Douglas Gregor86d9a522009-09-21 16:56:56 +0000726 ShadowMap &SMap = ShadowMaps.back();
Douglas Gregorfbcb5d62009-12-06 20:23:50 +0000727 ShadowMapEntry::iterator I, IEnd;
728 ShadowMap::iterator NamePos = SMap.find(R.Declaration->getDeclName());
729 if (NamePos != SMap.end()) {
730 I = NamePos->second.begin();
731 IEnd = NamePos->second.end();
732 }
733
734 for (; I != IEnd; ++I) {
735 NamedDecl *ND = I->first;
736 unsigned Index = I->second;
Douglas Gregor86d9a522009-09-21 16:56:56 +0000737 if (ND->getCanonicalDecl() == CanonDecl) {
738 // This is a redeclaration. Always pick the newer declaration.
Douglas Gregor86d9a522009-09-21 16:56:56 +0000739 Results[Index].Declaration = R.Declaration;
740
Douglas Gregor86d9a522009-09-21 16:56:56 +0000741 // We're done.
742 return;
743 }
744 }
745
746 // This is a new declaration in this scope. However, check whether this
747 // declaration name is hidden by a similarly-named declaration in an outer
748 // scope.
749 std::list<ShadowMap>::iterator SM, SMEnd = ShadowMaps.end();
750 --SMEnd;
751 for (SM = ShadowMaps.begin(); SM != SMEnd; ++SM) {
Douglas Gregorfbcb5d62009-12-06 20:23:50 +0000752 ShadowMapEntry::iterator I, IEnd;
753 ShadowMap::iterator NamePos = SM->find(R.Declaration->getDeclName());
754 if (NamePos != SM->end()) {
755 I = NamePos->second.begin();
756 IEnd = NamePos->second.end();
757 }
758 for (; I != IEnd; ++I) {
Douglas Gregor86d9a522009-09-21 16:56:56 +0000759 // A tag declaration does not hide a non-tag declaration.
John McCall0d6b1642010-04-23 18:46:30 +0000760 if (I->first->hasTagIdentifierNamespace() &&
Douglas Gregor86d9a522009-09-21 16:56:56 +0000761 (IDNS & (Decl::IDNS_Member | Decl::IDNS_Ordinary |
762 Decl::IDNS_ObjCProtocol)))
763 continue;
764
765 // Protocols are in distinct namespaces from everything else.
Douglas Gregorfbcb5d62009-12-06 20:23:50 +0000766 if (((I->first->getIdentifierNamespace() & Decl::IDNS_ObjCProtocol)
Douglas Gregor86d9a522009-09-21 16:56:56 +0000767 || (IDNS & Decl::IDNS_ObjCProtocol)) &&
Douglas Gregorfbcb5d62009-12-06 20:23:50 +0000768 I->first->getIdentifierNamespace() != IDNS)
Douglas Gregor86d9a522009-09-21 16:56:56 +0000769 continue;
770
771 // The newly-added result is hidden by an entry in the shadow map.
Douglas Gregor6660d842010-01-14 00:41:07 +0000772 if (CheckHiddenResult(R, CurContext, I->first))
Douglas Gregor86d9a522009-09-21 16:56:56 +0000773 return;
Douglas Gregor86d9a522009-09-21 16:56:56 +0000774
775 break;
776 }
777 }
778
779 // Make sure that any given declaration only shows up in the result set once.
780 if (!AllDeclsFound.insert(CanonDecl))
781 return;
Douglas Gregor265f7492010-08-27 15:29:55 +0000782
Douglas Gregoreb5758b2009-09-23 22:26:46 +0000783 // If the filter is for nested-name-specifiers, then this result starts a
784 // nested-name-specifier.
Douglas Gregor12e13132010-05-26 22:00:08 +0000785 if (AsNestedNameSpecifier) {
Douglas Gregoreb5758b2009-09-23 22:26:46 +0000786 R.StartsNestedNameSpecifier = true;
Douglas Gregor12e13132010-05-26 22:00:08 +0000787 R.Priority = CCP_NestedNameSpecifier;
Douglas Gregorcee9ff12010-09-20 22:39:41 +0000788 } else
789 AdjustResultPriorityForDecl(R);
Douglas Gregor265f7492010-08-27 15:29:55 +0000790
Douglas Gregor0563c262009-09-22 23:15:58 +0000791 // If this result is supposed to have an informative qualifier, add one.
Douglas Gregoreb5758b2009-09-23 22:26:46 +0000792 if (R.QualifierIsInformative && !R.Qualifier &&
793 !R.StartsNestedNameSpecifier) {
Douglas Gregor0563c262009-09-22 23:15:58 +0000794 DeclContext *Ctx = R.Declaration->getDeclContext();
795 if (NamespaceDecl *Namespace = dyn_cast<NamespaceDecl>(Ctx))
796 R.Qualifier = NestedNameSpecifier::Create(SemaRef.Context, 0, Namespace);
797 else if (TagDecl *Tag = dyn_cast<TagDecl>(Ctx))
798 R.Qualifier = NestedNameSpecifier::Create(SemaRef.Context, 0, false,
799 SemaRef.Context.getTypeDeclType(Tag).getTypePtr());
800 else
801 R.QualifierIsInformative = false;
802 }
Douglas Gregoreb5758b2009-09-23 22:26:46 +0000803
Douglas Gregor86d9a522009-09-21 16:56:56 +0000804 // Insert this result into the set of results and into the current shadow
805 // map.
Douglas Gregorfbcb5d62009-12-06 20:23:50 +0000806 SMap[R.Declaration->getDeclName()].Add(R.Declaration, Results.size());
Douglas Gregor86d9a522009-09-21 16:56:56 +0000807 Results.push_back(R);
Douglas Gregor6f942b22010-09-21 16:06:22 +0000808
809 if (!AsNestedNameSpecifier)
810 MaybeAddConstructorResults(R);
Douglas Gregor86d9a522009-09-21 16:56:56 +0000811}
812
Douglas Gregor1ca6ae82010-01-14 01:09:38 +0000813void ResultBuilder::AddResult(Result R, DeclContext *CurContext,
Douglas Gregor0cc84042010-01-14 15:47:35 +0000814 NamedDecl *Hiding, bool InBaseClass = false) {
Douglas Gregora4477812010-01-14 16:01:26 +0000815 if (R.Kind != Result::RK_Declaration) {
816 // For non-declaration results, just add the result.
817 Results.push_back(R);
818 return;
819 }
820
Douglas Gregor1ca6ae82010-01-14 01:09:38 +0000821 // Look through using declarations.
822 if (UsingShadowDecl *Using = dyn_cast<UsingShadowDecl>(R.Declaration)) {
823 AddResult(Result(Using->getTargetDecl(), R.Qualifier), CurContext, Hiding);
824 return;
825 }
826
Douglas Gregor45bcd432010-01-14 03:21:49 +0000827 bool AsNestedNameSpecifier = false;
828 if (!isInterestingDecl(R.Declaration, AsNestedNameSpecifier))
Douglas Gregor1ca6ae82010-01-14 01:09:38 +0000829 return;
830
Douglas Gregor6f942b22010-09-21 16:06:22 +0000831 // C++ constructors are never found by name lookup.
832 if (isa<CXXConstructorDecl>(R.Declaration))
833 return;
834
Douglas Gregor1ca6ae82010-01-14 01:09:38 +0000835 if (Hiding && CheckHiddenResult(R, CurContext, Hiding))
836 return;
837
838 // Make sure that any given declaration only shows up in the result set once.
839 if (!AllDeclsFound.insert(R.Declaration->getCanonicalDecl()))
840 return;
841
842 // If the filter is for nested-name-specifiers, then this result starts a
843 // nested-name-specifier.
Douglas Gregor12e13132010-05-26 22:00:08 +0000844 if (AsNestedNameSpecifier) {
Douglas Gregor1ca6ae82010-01-14 01:09:38 +0000845 R.StartsNestedNameSpecifier = true;
Douglas Gregor12e13132010-05-26 22:00:08 +0000846 R.Priority = CCP_NestedNameSpecifier;
847 }
Douglas Gregor0cc84042010-01-14 15:47:35 +0000848 else if (Filter == &ResultBuilder::IsMember && !R.Qualifier && InBaseClass &&
849 isa<CXXRecordDecl>(R.Declaration->getDeclContext()
Sebastian Redl7a126a42010-08-31 00:36:30 +0000850 ->getRedeclContext()))
Douglas Gregor0cc84042010-01-14 15:47:35 +0000851 R.QualifierIsInformative = true;
852
Douglas Gregor1ca6ae82010-01-14 01:09:38 +0000853 // If this result is supposed to have an informative qualifier, add one.
854 if (R.QualifierIsInformative && !R.Qualifier &&
855 !R.StartsNestedNameSpecifier) {
856 DeclContext *Ctx = R.Declaration->getDeclContext();
857 if (NamespaceDecl *Namespace = dyn_cast<NamespaceDecl>(Ctx))
858 R.Qualifier = NestedNameSpecifier::Create(SemaRef.Context, 0, Namespace);
859 else if (TagDecl *Tag = dyn_cast<TagDecl>(Ctx))
860 R.Qualifier = NestedNameSpecifier::Create(SemaRef.Context, 0, false,
Douglas Gregor45bcd432010-01-14 03:21:49 +0000861 SemaRef.Context.getTypeDeclType(Tag).getTypePtr());
Douglas Gregor1ca6ae82010-01-14 01:09:38 +0000862 else
863 R.QualifierIsInformative = false;
864 }
865
Douglas Gregor12e13132010-05-26 22:00:08 +0000866 // Adjust the priority if this result comes from a base class.
867 if (InBaseClass)
868 R.Priority += CCD_InBaseClass;
869
Douglas Gregorcee9ff12010-09-20 22:39:41 +0000870 AdjustResultPriorityForDecl(R);
Douglas Gregor5ac3bdb2010-05-30 01:49:25 +0000871
Douglas Gregor3cdee122010-08-26 16:36:48 +0000872 if (HasObjectTypeQualifiers)
873 if (CXXMethodDecl *Method = dyn_cast<CXXMethodDecl>(R.Declaration))
874 if (Method->isInstance()) {
875 Qualifiers MethodQuals
876 = Qualifiers::fromCVRMask(Method->getTypeQualifiers());
877 if (ObjectTypeQualifiers == MethodQuals)
878 R.Priority += CCD_ObjectQualifierMatch;
879 else if (ObjectTypeQualifiers - MethodQuals) {
880 // The method cannot be invoked, because doing so would drop
881 // qualifiers.
882 return;
883 }
884 }
885
Douglas Gregor1ca6ae82010-01-14 01:09:38 +0000886 // Insert this result into the set of results.
887 Results.push_back(R);
Douglas Gregor6f942b22010-09-21 16:06:22 +0000888
889 if (!AsNestedNameSpecifier)
890 MaybeAddConstructorResults(R);
Douglas Gregor1ca6ae82010-01-14 01:09:38 +0000891}
892
Douglas Gregora4477812010-01-14 16:01:26 +0000893void ResultBuilder::AddResult(Result R) {
894 assert(R.Kind != Result::RK_Declaration &&
895 "Declaration results need more context");
896 Results.push_back(R);
897}
898
Douglas Gregor86d9a522009-09-21 16:56:56 +0000899/// \brief Enter into a new scope.
900void ResultBuilder::EnterNewScope() {
901 ShadowMaps.push_back(ShadowMap());
902}
903
904/// \brief Exit from the current scope.
905void ResultBuilder::ExitScope() {
Douglas Gregorfbcb5d62009-12-06 20:23:50 +0000906 for (ShadowMap::iterator E = ShadowMaps.back().begin(),
907 EEnd = ShadowMaps.back().end();
908 E != EEnd;
909 ++E)
910 E->second.Destroy();
911
Douglas Gregor86d9a522009-09-21 16:56:56 +0000912 ShadowMaps.pop_back();
913}
914
Douglas Gregor791215b2009-09-21 20:51:25 +0000915/// \brief Determines whether this given declaration will be found by
916/// ordinary name lookup.
917bool ResultBuilder::IsOrdinaryName(NamedDecl *ND) const {
Douglas Gregor4710e5b2010-05-28 00:49:12 +0000918 ND = cast<NamedDecl>(ND->getUnderlyingDecl());
919
Douglas Gregor791215b2009-09-21 20:51:25 +0000920 unsigned IDNS = Decl::IDNS_Ordinary;
921 if (SemaRef.getLangOptions().CPlusPlus)
Douglas Gregor9b30b262010-06-15 20:26:51 +0000922 IDNS |= Decl::IDNS_Tag | Decl::IDNS_Namespace | Decl::IDNS_Member;
Douglas Gregor1ca6ae82010-01-14 01:09:38 +0000923 else if (SemaRef.getLangOptions().ObjC1 && isa<ObjCIvarDecl>(ND))
924 return true;
925
Douglas Gregor791215b2009-09-21 20:51:25 +0000926 return ND->getIdentifierNamespace() & IDNS;
927}
928
Douglas Gregor01dfea02010-01-10 23:08:15 +0000929/// \brief Determines whether this given declaration will be found by
Douglas Gregor4710e5b2010-05-28 00:49:12 +0000930/// ordinary name lookup but is not a type name.
931bool ResultBuilder::IsOrdinaryNonTypeName(NamedDecl *ND) const {
932 ND = cast<NamedDecl>(ND->getUnderlyingDecl());
933 if (isa<TypeDecl>(ND) || isa<ObjCInterfaceDecl>(ND))
934 return false;
935
936 unsigned IDNS = Decl::IDNS_Ordinary;
937 if (SemaRef.getLangOptions().CPlusPlus)
Douglas Gregor9b30b262010-06-15 20:26:51 +0000938 IDNS |= Decl::IDNS_Tag | Decl::IDNS_Namespace | Decl::IDNS_Member;
Douglas Gregor4710e5b2010-05-28 00:49:12 +0000939 else if (SemaRef.getLangOptions().ObjC1 && isa<ObjCIvarDecl>(ND))
940 return true;
941
942 return ND->getIdentifierNamespace() & IDNS;
943}
944
Douglas Gregorf9578432010-07-28 21:50:18 +0000945bool ResultBuilder::IsIntegralConstantValue(NamedDecl *ND) const {
946 if (!IsOrdinaryNonTypeName(ND))
947 return 0;
948
949 if (ValueDecl *VD = dyn_cast<ValueDecl>(ND->getUnderlyingDecl()))
950 if (VD->getType()->isIntegralOrEnumerationType())
951 return true;
952
953 return false;
954}
955
Douglas Gregor4710e5b2010-05-28 00:49:12 +0000956/// \brief Determines whether this given declaration will be found by
Douglas Gregor01dfea02010-01-10 23:08:15 +0000957/// ordinary name lookup.
958bool ResultBuilder::IsOrdinaryNonValueName(NamedDecl *ND) const {
Douglas Gregor4710e5b2010-05-28 00:49:12 +0000959 ND = cast<NamedDecl>(ND->getUnderlyingDecl());
960
Douglas Gregor01dfea02010-01-10 23:08:15 +0000961 unsigned IDNS = Decl::IDNS_Ordinary;
962 if (SemaRef.getLangOptions().CPlusPlus)
John McCall0d6b1642010-04-23 18:46:30 +0000963 IDNS |= Decl::IDNS_Tag | Decl::IDNS_Namespace;
Douglas Gregor01dfea02010-01-10 23:08:15 +0000964
965 return (ND->getIdentifierNamespace() & IDNS) &&
Douglas Gregor4710e5b2010-05-28 00:49:12 +0000966 !isa<ValueDecl>(ND) && !isa<FunctionTemplateDecl>(ND) &&
967 !isa<ObjCPropertyDecl>(ND);
Douglas Gregor01dfea02010-01-10 23:08:15 +0000968}
969
Douglas Gregor86d9a522009-09-21 16:56:56 +0000970/// \brief Determines whether the given declaration is suitable as the
971/// start of a C++ nested-name-specifier, e.g., a class or namespace.
972bool ResultBuilder::IsNestedNameSpecifier(NamedDecl *ND) const {
973 // Allow us to find class templates, too.
974 if (ClassTemplateDecl *ClassTemplate = dyn_cast<ClassTemplateDecl>(ND))
975 ND = ClassTemplate->getTemplatedDecl();
976
977 return SemaRef.isAcceptableNestedNameSpecifier(ND);
978}
979
980/// \brief Determines whether the given declaration is an enumeration.
981bool ResultBuilder::IsEnum(NamedDecl *ND) const {
982 return isa<EnumDecl>(ND);
983}
984
985/// \brief Determines whether the given declaration is a class or struct.
986bool ResultBuilder::IsClassOrStruct(NamedDecl *ND) const {
987 // Allow us to find class templates, too.
988 if (ClassTemplateDecl *ClassTemplate = dyn_cast<ClassTemplateDecl>(ND))
989 ND = ClassTemplate->getTemplatedDecl();
990
991 if (RecordDecl *RD = dyn_cast<RecordDecl>(ND))
Abramo Bagnara465d41b2010-05-11 21:36:43 +0000992 return RD->getTagKind() == TTK_Class ||
993 RD->getTagKind() == TTK_Struct;
Douglas Gregor86d9a522009-09-21 16:56:56 +0000994
995 return false;
996}
997
998/// \brief Determines whether the given declaration is a union.
999bool ResultBuilder::IsUnion(NamedDecl *ND) const {
1000 // Allow us to find class templates, too.
1001 if (ClassTemplateDecl *ClassTemplate = dyn_cast<ClassTemplateDecl>(ND))
1002 ND = ClassTemplate->getTemplatedDecl();
1003
1004 if (RecordDecl *RD = dyn_cast<RecordDecl>(ND))
Abramo Bagnara465d41b2010-05-11 21:36:43 +00001005 return RD->getTagKind() == TTK_Union;
Douglas Gregor86d9a522009-09-21 16:56:56 +00001006
1007 return false;
1008}
1009
1010/// \brief Determines whether the given declaration is a namespace.
1011bool ResultBuilder::IsNamespace(NamedDecl *ND) const {
1012 return isa<NamespaceDecl>(ND);
1013}
1014
1015/// \brief Determines whether the given declaration is a namespace or
1016/// namespace alias.
1017bool ResultBuilder::IsNamespaceOrAlias(NamedDecl *ND) const {
1018 return isa<NamespaceDecl>(ND) || isa<NamespaceAliasDecl>(ND);
1019}
1020
Douglas Gregor76282942009-12-11 17:31:05 +00001021/// \brief Determines whether the given declaration is a type.
Douglas Gregor86d9a522009-09-21 16:56:56 +00001022bool ResultBuilder::IsType(NamedDecl *ND) const {
Douglas Gregord32b0222010-08-24 01:06:58 +00001023 if (UsingShadowDecl *Using = dyn_cast<UsingShadowDecl>(ND))
1024 ND = Using->getTargetDecl();
1025
1026 return isa<TypeDecl>(ND) || isa<ObjCInterfaceDecl>(ND);
Douglas Gregor86d9a522009-09-21 16:56:56 +00001027}
1028
Douglas Gregor76282942009-12-11 17:31:05 +00001029/// \brief Determines which members of a class should be visible via
1030/// "." or "->". Only value declarations, nested name specifiers, and
1031/// using declarations thereof should show up.
Douglas Gregoreb5758b2009-09-23 22:26:46 +00001032bool ResultBuilder::IsMember(NamedDecl *ND) const {
Douglas Gregor76282942009-12-11 17:31:05 +00001033 if (UsingShadowDecl *Using = dyn_cast<UsingShadowDecl>(ND))
1034 ND = Using->getTargetDecl();
1035
Douglas Gregorce821962009-12-11 18:14:22 +00001036 return isa<ValueDecl>(ND) || isa<FunctionTemplateDecl>(ND) ||
1037 isa<ObjCPropertyDecl>(ND);
Douglas Gregoreb5758b2009-09-23 22:26:46 +00001038}
1039
Douglas Gregor8e254cf2010-05-27 23:06:34 +00001040static bool isObjCReceiverType(ASTContext &C, QualType T) {
1041 T = C.getCanonicalType(T);
1042 switch (T->getTypeClass()) {
1043 case Type::ObjCObject:
1044 case Type::ObjCInterface:
1045 case Type::ObjCObjectPointer:
1046 return true;
1047
1048 case Type::Builtin:
1049 switch (cast<BuiltinType>(T)->getKind()) {
1050 case BuiltinType::ObjCId:
1051 case BuiltinType::ObjCClass:
1052 case BuiltinType::ObjCSel:
1053 return true;
1054
1055 default:
1056 break;
1057 }
1058 return false;
1059
1060 default:
1061 break;
1062 }
1063
1064 if (!C.getLangOptions().CPlusPlus)
1065 return false;
1066
1067 // FIXME: We could perform more analysis here to determine whether a
1068 // particular class type has any conversions to Objective-C types. For now,
1069 // just accept all class types.
1070 return T->isDependentType() || T->isRecordType();
1071}
1072
1073bool ResultBuilder::IsObjCMessageReceiver(NamedDecl *ND) const {
1074 QualType T = getDeclUsageType(SemaRef.Context, ND);
1075 if (T.isNull())
1076 return false;
1077
1078 T = SemaRef.Context.getBaseElementType(T);
1079 return isObjCReceiverType(SemaRef.Context, T);
1080}
1081
Douglas Gregorfb629412010-08-23 21:17:50 +00001082bool ResultBuilder::IsObjCCollection(NamedDecl *ND) const {
1083 if ((SemaRef.getLangOptions().CPlusPlus && !IsOrdinaryName(ND)) ||
1084 (!SemaRef.getLangOptions().CPlusPlus && !IsOrdinaryNonTypeName(ND)))
1085 return false;
1086
1087 QualType T = getDeclUsageType(SemaRef.Context, ND);
1088 if (T.isNull())
1089 return false;
1090
1091 T = SemaRef.Context.getBaseElementType(T);
1092 return T->isObjCObjectType() || T->isObjCObjectPointerType() ||
1093 T->isObjCIdType() ||
1094 (SemaRef.getLangOptions().CPlusPlus && T->isRecordType());
1095}
Douglas Gregor8e254cf2010-05-27 23:06:34 +00001096
Douglas Gregor80f4f4c2010-01-14 16:08:12 +00001097/// \rief Determines whether the given declaration is an Objective-C
1098/// instance variable.
1099bool ResultBuilder::IsObjCIvar(NamedDecl *ND) const {
1100 return isa<ObjCIvarDecl>(ND);
1101}
1102
Douglas Gregor1ca6ae82010-01-14 01:09:38 +00001103namespace {
1104 /// \brief Visible declaration consumer that adds a code-completion result
1105 /// for each visible declaration.
1106 class CodeCompletionDeclConsumer : public VisibleDeclConsumer {
1107 ResultBuilder &Results;
1108 DeclContext *CurContext;
1109
1110 public:
1111 CodeCompletionDeclConsumer(ResultBuilder &Results, DeclContext *CurContext)
1112 : Results(Results), CurContext(CurContext) { }
1113
Douglas Gregor0cc84042010-01-14 15:47:35 +00001114 virtual void FoundDecl(NamedDecl *ND, NamedDecl *Hiding, bool InBaseClass) {
1115 Results.AddResult(ND, CurContext, Hiding, InBaseClass);
Douglas Gregor1ca6ae82010-01-14 01:09:38 +00001116 }
1117 };
1118}
1119
Douglas Gregor86d9a522009-09-21 16:56:56 +00001120/// \brief Add type specifiers for the current language as keyword results.
Douglas Gregorbca403c2010-01-13 23:51:12 +00001121static void AddTypeSpecifierResults(const LangOptions &LangOpts,
Douglas Gregor86d9a522009-09-21 16:56:56 +00001122 ResultBuilder &Results) {
John McCall0a2c5e22010-08-25 06:19:51 +00001123 typedef CodeCompletionResult Result;
Douglas Gregor12e13132010-05-26 22:00:08 +00001124 Results.AddResult(Result("short", CCP_Type));
1125 Results.AddResult(Result("long", CCP_Type));
1126 Results.AddResult(Result("signed", CCP_Type));
1127 Results.AddResult(Result("unsigned", CCP_Type));
1128 Results.AddResult(Result("void", CCP_Type));
1129 Results.AddResult(Result("char", CCP_Type));
1130 Results.AddResult(Result("int", CCP_Type));
1131 Results.AddResult(Result("float", CCP_Type));
1132 Results.AddResult(Result("double", CCP_Type));
1133 Results.AddResult(Result("enum", CCP_Type));
1134 Results.AddResult(Result("struct", CCP_Type));
1135 Results.AddResult(Result("union", CCP_Type));
1136 Results.AddResult(Result("const", CCP_Type));
1137 Results.AddResult(Result("volatile", CCP_Type));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001138
Douglas Gregor86d9a522009-09-21 16:56:56 +00001139 if (LangOpts.C99) {
1140 // C99-specific
Douglas Gregor12e13132010-05-26 22:00:08 +00001141 Results.AddResult(Result("_Complex", CCP_Type));
1142 Results.AddResult(Result("_Imaginary", CCP_Type));
1143 Results.AddResult(Result("_Bool", CCP_Type));
1144 Results.AddResult(Result("restrict", CCP_Type));
Douglas Gregor86d9a522009-09-21 16:56:56 +00001145 }
1146
1147 if (LangOpts.CPlusPlus) {
1148 // C++-specific
Douglas Gregorb05496d2010-09-20 21:11:48 +00001149 Results.AddResult(Result("bool", CCP_Type +
1150 (LangOpts.ObjC1? CCD_bool_in_ObjC : 0)));
Douglas Gregor12e13132010-05-26 22:00:08 +00001151 Results.AddResult(Result("class", CCP_Type));
1152 Results.AddResult(Result("wchar_t", CCP_Type));
Douglas Gregor86d9a522009-09-21 16:56:56 +00001153
Douglas Gregorc8bddde2010-05-28 00:22:41 +00001154 // typename qualified-id
1155 CodeCompletionString *Pattern = new CodeCompletionString;
1156 Pattern->AddTypedTextChunk("typename");
1157 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
1158 Pattern->AddPlaceholderChunk("qualifier");
1159 Pattern->AddTextChunk("::");
1160 Pattern->AddPlaceholderChunk("name");
1161 Results.AddResult(Result(Pattern));
Douglas Gregord8e8a582010-05-25 21:41:55 +00001162
Douglas Gregor86d9a522009-09-21 16:56:56 +00001163 if (LangOpts.CPlusPlus0x) {
Douglas Gregor12e13132010-05-26 22:00:08 +00001164 Results.AddResult(Result("auto", CCP_Type));
1165 Results.AddResult(Result("char16_t", CCP_Type));
1166 Results.AddResult(Result("char32_t", CCP_Type));
Douglas Gregorc8bddde2010-05-28 00:22:41 +00001167
1168 CodeCompletionString *Pattern = new CodeCompletionString;
1169 Pattern->AddTypedTextChunk("decltype");
1170 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
1171 Pattern->AddPlaceholderChunk("expression");
1172 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
1173 Results.AddResult(Result(Pattern));
Douglas Gregor86d9a522009-09-21 16:56:56 +00001174 }
1175 }
1176
1177 // GNU extensions
1178 if (LangOpts.GNUMode) {
1179 // FIXME: Enable when we actually support decimal floating point.
Douglas Gregora4477812010-01-14 16:01:26 +00001180 // Results.AddResult(Result("_Decimal32"));
1181 // Results.AddResult(Result("_Decimal64"));
1182 // Results.AddResult(Result("_Decimal128"));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001183
Douglas Gregorc8bddde2010-05-28 00:22:41 +00001184 CodeCompletionString *Pattern = new CodeCompletionString;
1185 Pattern->AddTypedTextChunk("typeof");
1186 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
1187 Pattern->AddPlaceholderChunk("expression");
1188 Results.AddResult(Result(Pattern));
1189
1190 Pattern = new CodeCompletionString;
1191 Pattern->AddTypedTextChunk("typeof");
1192 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
1193 Pattern->AddPlaceholderChunk("type");
1194 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
1195 Results.AddResult(Result(Pattern));
Douglas Gregor86d9a522009-09-21 16:56:56 +00001196 }
1197}
1198
John McCallf312b1e2010-08-26 23:41:50 +00001199static void AddStorageSpecifiers(Sema::ParserCompletionContext CCC,
Douglas Gregor01dfea02010-01-10 23:08:15 +00001200 const LangOptions &LangOpts,
Douglas Gregor01dfea02010-01-10 23:08:15 +00001201 ResultBuilder &Results) {
John McCall0a2c5e22010-08-25 06:19:51 +00001202 typedef CodeCompletionResult Result;
Douglas Gregor01dfea02010-01-10 23:08:15 +00001203 // Note: we don't suggest either "auto" or "register", because both
1204 // are pointless as storage specifiers. Elsewhere, we suggest "auto"
1205 // in C++0x as a type specifier.
Douglas Gregora4477812010-01-14 16:01:26 +00001206 Results.AddResult(Result("extern"));
1207 Results.AddResult(Result("static"));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001208}
1209
John McCallf312b1e2010-08-26 23:41:50 +00001210static void AddFunctionSpecifiers(Sema::ParserCompletionContext CCC,
Douglas Gregor01dfea02010-01-10 23:08:15 +00001211 const LangOptions &LangOpts,
Douglas Gregor01dfea02010-01-10 23:08:15 +00001212 ResultBuilder &Results) {
John McCall0a2c5e22010-08-25 06:19:51 +00001213 typedef CodeCompletionResult Result;
Douglas Gregor01dfea02010-01-10 23:08:15 +00001214 switch (CCC) {
John McCallf312b1e2010-08-26 23:41:50 +00001215 case Sema::PCC_Class:
1216 case Sema::PCC_MemberTemplate:
Douglas Gregor01dfea02010-01-10 23:08:15 +00001217 if (LangOpts.CPlusPlus) {
Douglas Gregora4477812010-01-14 16:01:26 +00001218 Results.AddResult(Result("explicit"));
1219 Results.AddResult(Result("friend"));
1220 Results.AddResult(Result("mutable"));
1221 Results.AddResult(Result("virtual"));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001222 }
1223 // Fall through
1224
John McCallf312b1e2010-08-26 23:41:50 +00001225 case Sema::PCC_ObjCInterface:
1226 case Sema::PCC_ObjCImplementation:
1227 case Sema::PCC_Namespace:
1228 case Sema::PCC_Template:
Douglas Gregor01dfea02010-01-10 23:08:15 +00001229 if (LangOpts.CPlusPlus || LangOpts.C99)
Douglas Gregora4477812010-01-14 16:01:26 +00001230 Results.AddResult(Result("inline"));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001231 break;
1232
John McCallf312b1e2010-08-26 23:41:50 +00001233 case Sema::PCC_ObjCInstanceVariableList:
1234 case Sema::PCC_Expression:
1235 case Sema::PCC_Statement:
1236 case Sema::PCC_ForInit:
1237 case Sema::PCC_Condition:
1238 case Sema::PCC_RecoveryInFunction:
1239 case Sema::PCC_Type:
Douglas Gregor02688102010-09-14 23:59:36 +00001240 case Sema::PCC_ParenthesizedExpression:
Douglas Gregor01dfea02010-01-10 23:08:15 +00001241 break;
1242 }
1243}
1244
Douglas Gregorbca403c2010-01-13 23:51:12 +00001245static void AddObjCExpressionResults(ResultBuilder &Results, bool NeedAt);
1246static void AddObjCStatementResults(ResultBuilder &Results, bool NeedAt);
1247static void AddObjCVisibilityResults(const LangOptions &LangOpts,
Douglas Gregorc38c3e12010-01-13 21:54:15 +00001248 ResultBuilder &Results,
1249 bool NeedAt);
Douglas Gregorbca403c2010-01-13 23:51:12 +00001250static void AddObjCImplementationResults(const LangOptions &LangOpts,
Douglas Gregorb6ac2452010-01-13 21:24:21 +00001251 ResultBuilder &Results,
1252 bool NeedAt);
Douglas Gregorbca403c2010-01-13 23:51:12 +00001253static void AddObjCInterfaceResults(const LangOptions &LangOpts,
Douglas Gregorb6ac2452010-01-13 21:24:21 +00001254 ResultBuilder &Results,
1255 bool NeedAt);
Douglas Gregorbca403c2010-01-13 23:51:12 +00001256static void AddObjCTopLevelResults(ResultBuilder &Results, bool NeedAt);
Douglas Gregorb6ac2452010-01-13 21:24:21 +00001257
Douglas Gregorc8bddde2010-05-28 00:22:41 +00001258static void AddTypedefResult(ResultBuilder &Results) {
1259 CodeCompletionString *Pattern = new CodeCompletionString;
1260 Pattern->AddTypedTextChunk("typedef");
1261 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
1262 Pattern->AddPlaceholderChunk("type");
1263 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
1264 Pattern->AddPlaceholderChunk("name");
John McCall0a2c5e22010-08-25 06:19:51 +00001265 Results.AddResult(CodeCompletionResult(Pattern));
Douglas Gregorc8bddde2010-05-28 00:22:41 +00001266}
1267
John McCallf312b1e2010-08-26 23:41:50 +00001268static bool WantTypesInContext(Sema::ParserCompletionContext CCC,
Douglas Gregor4710e5b2010-05-28 00:49:12 +00001269 const LangOptions &LangOpts) {
Douglas Gregor4710e5b2010-05-28 00:49:12 +00001270 switch (CCC) {
John McCallf312b1e2010-08-26 23:41:50 +00001271 case Sema::PCC_Namespace:
1272 case Sema::PCC_Class:
1273 case Sema::PCC_ObjCInstanceVariableList:
1274 case Sema::PCC_Template:
1275 case Sema::PCC_MemberTemplate:
1276 case Sema::PCC_Statement:
1277 case Sema::PCC_RecoveryInFunction:
1278 case Sema::PCC_Type:
Douglas Gregor02688102010-09-14 23:59:36 +00001279 case Sema::PCC_ParenthesizedExpression:
Douglas Gregor4710e5b2010-05-28 00:49:12 +00001280 return true;
1281
John McCallf312b1e2010-08-26 23:41:50 +00001282 case Sema::PCC_Expression:
1283 case Sema::PCC_Condition:
Douglas Gregor02688102010-09-14 23:59:36 +00001284 return LangOpts.CPlusPlus;
1285
1286 case Sema::PCC_ObjCInterface:
1287 case Sema::PCC_ObjCImplementation:
Douglas Gregor4710e5b2010-05-28 00:49:12 +00001288 return false;
1289
John McCallf312b1e2010-08-26 23:41:50 +00001290 case Sema::PCC_ForInit:
Douglas Gregor02688102010-09-14 23:59:36 +00001291 return LangOpts.CPlusPlus || LangOpts.ObjC1 || LangOpts.C99;
Douglas Gregor4710e5b2010-05-28 00:49:12 +00001292 }
1293
1294 return false;
1295}
1296
Douglas Gregor01dfea02010-01-10 23:08:15 +00001297/// \brief Add language constructs that show up for "ordinary" names.
John McCallf312b1e2010-08-26 23:41:50 +00001298static void AddOrdinaryNameResults(Sema::ParserCompletionContext CCC,
Douglas Gregor01dfea02010-01-10 23:08:15 +00001299 Scope *S,
1300 Sema &SemaRef,
Douglas Gregor01dfea02010-01-10 23:08:15 +00001301 ResultBuilder &Results) {
John McCall0a2c5e22010-08-25 06:19:51 +00001302 typedef CodeCompletionResult Result;
Douglas Gregor01dfea02010-01-10 23:08:15 +00001303 switch (CCC) {
John McCallf312b1e2010-08-26 23:41:50 +00001304 case Sema::PCC_Namespace:
Douglas Gregorc8bddde2010-05-28 00:22:41 +00001305 if (SemaRef.getLangOptions().CPlusPlus) {
1306 CodeCompletionString *Pattern = 0;
1307
1308 if (Results.includeCodePatterns()) {
1309 // namespace <identifier> { declarations }
1310 CodeCompletionString *Pattern = new CodeCompletionString;
1311 Pattern->AddTypedTextChunk("namespace");
1312 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
1313 Pattern->AddPlaceholderChunk("identifier");
1314 Pattern->AddChunk(CodeCompletionString::CK_LeftBrace);
1315 Pattern->AddPlaceholderChunk("declarations");
1316 Pattern->AddChunk(CodeCompletionString::CK_VerticalSpace);
1317 Pattern->AddChunk(CodeCompletionString::CK_RightBrace);
1318 Results.AddResult(Result(Pattern));
1319 }
1320
Douglas Gregor01dfea02010-01-10 23:08:15 +00001321 // namespace identifier = identifier ;
1322 Pattern = new CodeCompletionString;
1323 Pattern->AddTypedTextChunk("namespace");
1324 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
Douglas Gregorc8bddde2010-05-28 00:22:41 +00001325 Pattern->AddPlaceholderChunk("name");
Douglas Gregor01dfea02010-01-10 23:08:15 +00001326 Pattern->AddChunk(CodeCompletionString::CK_Equal);
Douglas Gregorc8bddde2010-05-28 00:22:41 +00001327 Pattern->AddPlaceholderChunk("namespace");
Douglas Gregora4477812010-01-14 16:01:26 +00001328 Results.AddResult(Result(Pattern));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001329
1330 // Using directives
1331 Pattern = new CodeCompletionString;
1332 Pattern->AddTypedTextChunk("using");
1333 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
1334 Pattern->AddTextChunk("namespace");
1335 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
1336 Pattern->AddPlaceholderChunk("identifier");
Douglas Gregora4477812010-01-14 16:01:26 +00001337 Results.AddResult(Result(Pattern));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001338
1339 // asm(string-literal)
1340 Pattern = new CodeCompletionString;
1341 Pattern->AddTypedTextChunk("asm");
1342 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
1343 Pattern->AddPlaceholderChunk("string-literal");
1344 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
Douglas Gregora4477812010-01-14 16:01:26 +00001345 Results.AddResult(Result(Pattern));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001346
Douglas Gregorc8bddde2010-05-28 00:22:41 +00001347 if (Results.includeCodePatterns()) {
1348 // Explicit template instantiation
1349 Pattern = new CodeCompletionString;
1350 Pattern->AddTypedTextChunk("template");
1351 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
1352 Pattern->AddPlaceholderChunk("declaration");
1353 Results.AddResult(Result(Pattern));
1354 }
Douglas Gregor01dfea02010-01-10 23:08:15 +00001355 }
Douglas Gregorb6ac2452010-01-13 21:24:21 +00001356
1357 if (SemaRef.getLangOptions().ObjC1)
Douglas Gregorbca403c2010-01-13 23:51:12 +00001358 AddObjCTopLevelResults(Results, true);
Douglas Gregorb6ac2452010-01-13 21:24:21 +00001359
Douglas Gregorc8bddde2010-05-28 00:22:41 +00001360 AddTypedefResult(Results);
Douglas Gregor01dfea02010-01-10 23:08:15 +00001361 // Fall through
1362
John McCallf312b1e2010-08-26 23:41:50 +00001363 case Sema::PCC_Class:
Douglas Gregorc8bddde2010-05-28 00:22:41 +00001364 if (SemaRef.getLangOptions().CPlusPlus) {
Douglas Gregor01dfea02010-01-10 23:08:15 +00001365 // Using declaration
1366 CodeCompletionString *Pattern = new CodeCompletionString;
1367 Pattern->AddTypedTextChunk("using");
1368 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
Douglas Gregorc8bddde2010-05-28 00:22:41 +00001369 Pattern->AddPlaceholderChunk("qualifier");
1370 Pattern->AddTextChunk("::");
1371 Pattern->AddPlaceholderChunk("name");
Douglas Gregora4477812010-01-14 16:01:26 +00001372 Results.AddResult(Result(Pattern));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001373
Douglas Gregorc8bddde2010-05-28 00:22:41 +00001374 // using typename qualifier::name (only in a dependent context)
Douglas Gregor01dfea02010-01-10 23:08:15 +00001375 if (SemaRef.CurContext->isDependentContext()) {
1376 Pattern = new CodeCompletionString;
1377 Pattern->AddTypedTextChunk("using");
1378 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
1379 Pattern->AddTextChunk("typename");
1380 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
Douglas Gregorc8bddde2010-05-28 00:22:41 +00001381 Pattern->AddPlaceholderChunk("qualifier");
1382 Pattern->AddTextChunk("::");
1383 Pattern->AddPlaceholderChunk("name");
Douglas Gregora4477812010-01-14 16:01:26 +00001384 Results.AddResult(Result(Pattern));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001385 }
1386
John McCallf312b1e2010-08-26 23:41:50 +00001387 if (CCC == Sema::PCC_Class) {
Douglas Gregorc8bddde2010-05-28 00:22:41 +00001388 AddTypedefResult(Results);
1389
Douglas Gregor01dfea02010-01-10 23:08:15 +00001390 // public:
1391 Pattern = new CodeCompletionString;
1392 Pattern->AddTypedTextChunk("public");
1393 Pattern->AddChunk(CodeCompletionString::CK_Colon);
Douglas Gregora4477812010-01-14 16:01:26 +00001394 Results.AddResult(Result(Pattern));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001395
1396 // protected:
1397 Pattern = new CodeCompletionString;
1398 Pattern->AddTypedTextChunk("protected");
1399 Pattern->AddChunk(CodeCompletionString::CK_Colon);
Douglas Gregora4477812010-01-14 16:01:26 +00001400 Results.AddResult(Result(Pattern));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001401
1402 // private:
1403 Pattern = new CodeCompletionString;
1404 Pattern->AddTypedTextChunk("private");
1405 Pattern->AddChunk(CodeCompletionString::CK_Colon);
Douglas Gregora4477812010-01-14 16:01:26 +00001406 Results.AddResult(Result(Pattern));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001407 }
1408 }
1409 // Fall through
1410
John McCallf312b1e2010-08-26 23:41:50 +00001411 case Sema::PCC_Template:
1412 case Sema::PCC_MemberTemplate:
Douglas Gregord8e8a582010-05-25 21:41:55 +00001413 if (SemaRef.getLangOptions().CPlusPlus && Results.includeCodePatterns()) {
Douglas Gregor01dfea02010-01-10 23:08:15 +00001414 // template < parameters >
1415 CodeCompletionString *Pattern = new CodeCompletionString;
1416 Pattern->AddTypedTextChunk("template");
1417 Pattern->AddChunk(CodeCompletionString::CK_LeftAngle);
1418 Pattern->AddPlaceholderChunk("parameters");
1419 Pattern->AddChunk(CodeCompletionString::CK_RightAngle);
Douglas Gregora4477812010-01-14 16:01:26 +00001420 Results.AddResult(Result(Pattern));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001421 }
1422
Douglas Gregorbca403c2010-01-13 23:51:12 +00001423 AddStorageSpecifiers(CCC, SemaRef.getLangOptions(), Results);
1424 AddFunctionSpecifiers(CCC, SemaRef.getLangOptions(), Results);
Douglas Gregor01dfea02010-01-10 23:08:15 +00001425 break;
1426
John McCallf312b1e2010-08-26 23:41:50 +00001427 case Sema::PCC_ObjCInterface:
Douglas Gregorbca403c2010-01-13 23:51:12 +00001428 AddObjCInterfaceResults(SemaRef.getLangOptions(), Results, true);
1429 AddStorageSpecifiers(CCC, SemaRef.getLangOptions(), Results);
1430 AddFunctionSpecifiers(CCC, SemaRef.getLangOptions(), Results);
Douglas Gregorb6ac2452010-01-13 21:24:21 +00001431 break;
1432
John McCallf312b1e2010-08-26 23:41:50 +00001433 case Sema::PCC_ObjCImplementation:
Douglas Gregorbca403c2010-01-13 23:51:12 +00001434 AddObjCImplementationResults(SemaRef.getLangOptions(), Results, true);
1435 AddStorageSpecifiers(CCC, SemaRef.getLangOptions(), Results);
1436 AddFunctionSpecifiers(CCC, SemaRef.getLangOptions(), Results);
Douglas Gregorb6ac2452010-01-13 21:24:21 +00001437 break;
1438
John McCallf312b1e2010-08-26 23:41:50 +00001439 case Sema::PCC_ObjCInstanceVariableList:
Douglas Gregorbca403c2010-01-13 23:51:12 +00001440 AddObjCVisibilityResults(SemaRef.getLangOptions(), Results, true);
Douglas Gregorc38c3e12010-01-13 21:54:15 +00001441 break;
1442
John McCallf312b1e2010-08-26 23:41:50 +00001443 case Sema::PCC_RecoveryInFunction:
1444 case Sema::PCC_Statement: {
Douglas Gregorc8bddde2010-05-28 00:22:41 +00001445 AddTypedefResult(Results);
Douglas Gregor01dfea02010-01-10 23:08:15 +00001446
1447 CodeCompletionString *Pattern = 0;
Douglas Gregord8e8a582010-05-25 21:41:55 +00001448 if (SemaRef.getLangOptions().CPlusPlus && Results.includeCodePatterns()) {
Douglas Gregor01dfea02010-01-10 23:08:15 +00001449 Pattern = new CodeCompletionString;
1450 Pattern->AddTypedTextChunk("try");
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("catch");
1456 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
1457 Pattern->AddPlaceholderChunk("declaration");
1458 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
1459 Pattern->AddChunk(CodeCompletionString::CK_LeftBrace);
1460 Pattern->AddPlaceholderChunk("statements");
1461 Pattern->AddChunk(CodeCompletionString::CK_VerticalSpace);
1462 Pattern->AddChunk(CodeCompletionString::CK_RightBrace);
Douglas Gregora4477812010-01-14 16:01:26 +00001463 Results.AddResult(Result(Pattern));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001464 }
Douglas Gregorb6ac2452010-01-13 21:24:21 +00001465 if (SemaRef.getLangOptions().ObjC1)
Douglas Gregorbca403c2010-01-13 23:51:12 +00001466 AddObjCStatementResults(Results, true);
Douglas Gregorb6ac2452010-01-13 21:24:21 +00001467
Douglas Gregord8e8a582010-05-25 21:41:55 +00001468 if (Results.includeCodePatterns()) {
1469 // if (condition) { statements }
1470 Pattern = new CodeCompletionString;
1471 Pattern->AddTypedTextChunk("if");
1472 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
1473 if (SemaRef.getLangOptions().CPlusPlus)
1474 Pattern->AddPlaceholderChunk("condition");
1475 else
1476 Pattern->AddPlaceholderChunk("expression");
1477 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
1478 Pattern->AddChunk(CodeCompletionString::CK_LeftBrace);
1479 Pattern->AddPlaceholderChunk("statements");
1480 Pattern->AddChunk(CodeCompletionString::CK_VerticalSpace);
1481 Pattern->AddChunk(CodeCompletionString::CK_RightBrace);
1482 Results.AddResult(Result(Pattern));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001483
Douglas Gregord8e8a582010-05-25 21:41:55 +00001484 // switch (condition) { }
1485 Pattern = new CodeCompletionString;
1486 Pattern->AddTypedTextChunk("switch");
1487 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
1488 if (SemaRef.getLangOptions().CPlusPlus)
1489 Pattern->AddPlaceholderChunk("condition");
1490 else
1491 Pattern->AddPlaceholderChunk("expression");
1492 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
1493 Pattern->AddChunk(CodeCompletionString::CK_LeftBrace);
1494 Pattern->AddChunk(CodeCompletionString::CK_VerticalSpace);
1495 Pattern->AddChunk(CodeCompletionString::CK_RightBrace);
1496 Results.AddResult(Result(Pattern));
1497 }
1498
Douglas Gregor01dfea02010-01-10 23:08:15 +00001499 // Switch-specific statements.
John McCall781472f2010-08-25 08:40:02 +00001500 if (!SemaRef.getCurFunction()->SwitchStack.empty()) {
Douglas Gregor01dfea02010-01-10 23:08:15 +00001501 // case expression:
1502 Pattern = new CodeCompletionString;
1503 Pattern->AddTypedTextChunk("case");
Douglas Gregorc8bddde2010-05-28 00:22:41 +00001504 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
Douglas Gregor01dfea02010-01-10 23:08:15 +00001505 Pattern->AddPlaceholderChunk("expression");
1506 Pattern->AddChunk(CodeCompletionString::CK_Colon);
Douglas Gregora4477812010-01-14 16:01:26 +00001507 Results.AddResult(Result(Pattern));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001508
1509 // default:
1510 Pattern = new CodeCompletionString;
1511 Pattern->AddTypedTextChunk("default");
1512 Pattern->AddChunk(CodeCompletionString::CK_Colon);
Douglas Gregora4477812010-01-14 16:01:26 +00001513 Results.AddResult(Result(Pattern));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001514 }
1515
Douglas Gregord8e8a582010-05-25 21:41:55 +00001516 if (Results.includeCodePatterns()) {
1517 /// while (condition) { statements }
1518 Pattern = new CodeCompletionString;
1519 Pattern->AddTypedTextChunk("while");
1520 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
1521 if (SemaRef.getLangOptions().CPlusPlus)
1522 Pattern->AddPlaceholderChunk("condition");
1523 else
1524 Pattern->AddPlaceholderChunk("expression");
1525 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
1526 Pattern->AddChunk(CodeCompletionString::CK_LeftBrace);
1527 Pattern->AddPlaceholderChunk("statements");
1528 Pattern->AddChunk(CodeCompletionString::CK_VerticalSpace);
1529 Pattern->AddChunk(CodeCompletionString::CK_RightBrace);
1530 Results.AddResult(Result(Pattern));
1531
1532 // do { statements } while ( expression );
1533 Pattern = new CodeCompletionString;
1534 Pattern->AddTypedTextChunk("do");
1535 Pattern->AddChunk(CodeCompletionString::CK_LeftBrace);
1536 Pattern->AddPlaceholderChunk("statements");
1537 Pattern->AddChunk(CodeCompletionString::CK_VerticalSpace);
1538 Pattern->AddChunk(CodeCompletionString::CK_RightBrace);
1539 Pattern->AddTextChunk("while");
1540 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
Douglas Gregor01dfea02010-01-10 23:08:15 +00001541 Pattern->AddPlaceholderChunk("expression");
Douglas Gregord8e8a582010-05-25 21:41:55 +00001542 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
1543 Results.AddResult(Result(Pattern));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001544
Douglas Gregord8e8a582010-05-25 21:41:55 +00001545 // for ( for-init-statement ; condition ; expression ) { statements }
1546 Pattern = new CodeCompletionString;
1547 Pattern->AddTypedTextChunk("for");
1548 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
1549 if (SemaRef.getLangOptions().CPlusPlus || SemaRef.getLangOptions().C99)
1550 Pattern->AddPlaceholderChunk("init-statement");
1551 else
1552 Pattern->AddPlaceholderChunk("init-expression");
1553 Pattern->AddChunk(CodeCompletionString::CK_SemiColon);
1554 Pattern->AddPlaceholderChunk("condition");
1555 Pattern->AddChunk(CodeCompletionString::CK_SemiColon);
1556 Pattern->AddPlaceholderChunk("inc-expression");
1557 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
1558 Pattern->AddChunk(CodeCompletionString::CK_LeftBrace);
1559 Pattern->AddPlaceholderChunk("statements");
1560 Pattern->AddChunk(CodeCompletionString::CK_VerticalSpace);
1561 Pattern->AddChunk(CodeCompletionString::CK_RightBrace);
1562 Results.AddResult(Result(Pattern));
1563 }
Douglas Gregor01dfea02010-01-10 23:08:15 +00001564
1565 if (S->getContinueParent()) {
1566 // continue ;
1567 Pattern = new CodeCompletionString;
1568 Pattern->AddTypedTextChunk("continue");
Douglas Gregora4477812010-01-14 16:01:26 +00001569 Results.AddResult(Result(Pattern));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001570 }
1571
1572 if (S->getBreakParent()) {
1573 // break ;
1574 Pattern = new CodeCompletionString;
1575 Pattern->AddTypedTextChunk("break");
Douglas Gregora4477812010-01-14 16:01:26 +00001576 Results.AddResult(Result(Pattern));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001577 }
1578
1579 // "return expression ;" or "return ;", depending on whether we
1580 // know the function is void or not.
1581 bool isVoid = false;
1582 if (FunctionDecl *Function = dyn_cast<FunctionDecl>(SemaRef.CurContext))
1583 isVoid = Function->getResultType()->isVoidType();
1584 else if (ObjCMethodDecl *Method
1585 = dyn_cast<ObjCMethodDecl>(SemaRef.CurContext))
1586 isVoid = Method->getResultType()->isVoidType();
Douglas Gregor9ea9bdb2010-03-01 23:15:13 +00001587 else if (SemaRef.getCurBlock() &&
1588 !SemaRef.getCurBlock()->ReturnType.isNull())
1589 isVoid = SemaRef.getCurBlock()->ReturnType->isVoidType();
Douglas Gregor01dfea02010-01-10 23:08:15 +00001590 Pattern = new CodeCompletionString;
1591 Pattern->AddTypedTextChunk("return");
Douglas Gregor93298002010-02-18 04:06:48 +00001592 if (!isVoid) {
1593 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
Douglas Gregor01dfea02010-01-10 23:08:15 +00001594 Pattern->AddPlaceholderChunk("expression");
Douglas Gregor93298002010-02-18 04:06:48 +00001595 }
Douglas Gregora4477812010-01-14 16:01:26 +00001596 Results.AddResult(Result(Pattern));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001597
Douglas Gregorc8bddde2010-05-28 00:22:41 +00001598 // goto identifier ;
1599 Pattern = new CodeCompletionString;
1600 Pattern->AddTypedTextChunk("goto");
1601 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
1602 Pattern->AddPlaceholderChunk("label");
1603 Results.AddResult(Result(Pattern));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001604
Douglas Gregorc8bddde2010-05-28 00:22:41 +00001605 // Using directives
1606 Pattern = new CodeCompletionString;
1607 Pattern->AddTypedTextChunk("using");
1608 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
1609 Pattern->AddTextChunk("namespace");
1610 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
1611 Pattern->AddPlaceholderChunk("identifier");
1612 Results.AddResult(Result(Pattern));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001613 }
1614
1615 // Fall through (for statement expressions).
John McCallf312b1e2010-08-26 23:41:50 +00001616 case Sema::PCC_ForInit:
1617 case Sema::PCC_Condition:
Douglas Gregorbca403c2010-01-13 23:51:12 +00001618 AddStorageSpecifiers(CCC, SemaRef.getLangOptions(), Results);
Douglas Gregor01dfea02010-01-10 23:08:15 +00001619 // Fall through: conditions and statements can have expressions.
1620
Douglas Gregor02688102010-09-14 23:59:36 +00001621 case Sema::PCC_ParenthesizedExpression:
John McCallf312b1e2010-08-26 23:41:50 +00001622 case Sema::PCC_Expression: {
Douglas Gregor01dfea02010-01-10 23:08:15 +00001623 CodeCompletionString *Pattern = 0;
1624 if (SemaRef.getLangOptions().CPlusPlus) {
1625 // 'this', if we're in a non-static member function.
1626 if (CXXMethodDecl *Method = dyn_cast<CXXMethodDecl>(SemaRef.CurContext))
1627 if (!Method->isStatic())
Douglas Gregora4477812010-01-14 16:01:26 +00001628 Results.AddResult(Result("this"));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001629
1630 // true, false
Douglas Gregora4477812010-01-14 16:01:26 +00001631 Results.AddResult(Result("true"));
1632 Results.AddResult(Result("false"));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001633
Douglas Gregorc8bddde2010-05-28 00:22:41 +00001634 // dynamic_cast < type-id > ( expression )
1635 Pattern = new CodeCompletionString;
1636 Pattern->AddTypedTextChunk("dynamic_cast");
1637 Pattern->AddChunk(CodeCompletionString::CK_LeftAngle);
1638 Pattern->AddPlaceholderChunk("type");
1639 Pattern->AddChunk(CodeCompletionString::CK_RightAngle);
1640 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
1641 Pattern->AddPlaceholderChunk("expression");
1642 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
1643 Results.AddResult(Result(Pattern));
1644
1645 // static_cast < type-id > ( expression )
1646 Pattern = new CodeCompletionString;
1647 Pattern->AddTypedTextChunk("static_cast");
1648 Pattern->AddChunk(CodeCompletionString::CK_LeftAngle);
1649 Pattern->AddPlaceholderChunk("type");
1650 Pattern->AddChunk(CodeCompletionString::CK_RightAngle);
1651 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
1652 Pattern->AddPlaceholderChunk("expression");
1653 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
1654 Results.AddResult(Result(Pattern));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001655
Douglas Gregorc8bddde2010-05-28 00:22:41 +00001656 // reinterpret_cast < type-id > ( expression )
1657 Pattern = new CodeCompletionString;
1658 Pattern->AddTypedTextChunk("reinterpret_cast");
1659 Pattern->AddChunk(CodeCompletionString::CK_LeftAngle);
1660 Pattern->AddPlaceholderChunk("type");
1661 Pattern->AddChunk(CodeCompletionString::CK_RightAngle);
1662 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
1663 Pattern->AddPlaceholderChunk("expression");
1664 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
1665 Results.AddResult(Result(Pattern));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001666
Douglas Gregorc8bddde2010-05-28 00:22:41 +00001667 // const_cast < type-id > ( expression )
1668 Pattern = new CodeCompletionString;
1669 Pattern->AddTypedTextChunk("const_cast");
1670 Pattern->AddChunk(CodeCompletionString::CK_LeftAngle);
1671 Pattern->AddPlaceholderChunk("type");
1672 Pattern->AddChunk(CodeCompletionString::CK_RightAngle);
1673 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
1674 Pattern->AddPlaceholderChunk("expression");
1675 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
1676 Results.AddResult(Result(Pattern));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001677
Douglas Gregorc8bddde2010-05-28 00:22:41 +00001678 // typeid ( expression-or-type )
1679 Pattern = new CodeCompletionString;
1680 Pattern->AddTypedTextChunk("typeid");
1681 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
1682 Pattern->AddPlaceholderChunk("expression-or-type");
1683 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
1684 Results.AddResult(Result(Pattern));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001685
Douglas Gregorc8bddde2010-05-28 00:22:41 +00001686 // new T ( ... )
1687 Pattern = new CodeCompletionString;
1688 Pattern->AddTypedTextChunk("new");
1689 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
1690 Pattern->AddPlaceholderChunk("type");
1691 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
1692 Pattern->AddPlaceholderChunk("expressions");
1693 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
1694 Results.AddResult(Result(Pattern));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001695
Douglas Gregorc8bddde2010-05-28 00:22:41 +00001696 // new T [ ] ( ... )
1697 Pattern = new CodeCompletionString;
1698 Pattern->AddTypedTextChunk("new");
1699 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
1700 Pattern->AddPlaceholderChunk("type");
1701 Pattern->AddChunk(CodeCompletionString::CK_LeftBracket);
1702 Pattern->AddPlaceholderChunk("size");
1703 Pattern->AddChunk(CodeCompletionString::CK_RightBracket);
1704 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
1705 Pattern->AddPlaceholderChunk("expressions");
1706 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
1707 Results.AddResult(Result(Pattern));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001708
Douglas Gregorc8bddde2010-05-28 00:22:41 +00001709 // delete expression
1710 Pattern = new CodeCompletionString;
1711 Pattern->AddTypedTextChunk("delete");
1712 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
1713 Pattern->AddPlaceholderChunk("expression");
1714 Results.AddResult(Result(Pattern));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001715
Douglas Gregorc8bddde2010-05-28 00:22:41 +00001716 // delete [] expression
1717 Pattern = new CodeCompletionString;
1718 Pattern->AddTypedTextChunk("delete");
1719 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
1720 Pattern->AddChunk(CodeCompletionString::CK_LeftBracket);
1721 Pattern->AddChunk(CodeCompletionString::CK_RightBracket);
1722 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
1723 Pattern->AddPlaceholderChunk("expression");
1724 Results.AddResult(Result(Pattern));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001725
Douglas Gregorc8bddde2010-05-28 00:22:41 +00001726 // throw expression
1727 Pattern = new CodeCompletionString;
1728 Pattern->AddTypedTextChunk("throw");
1729 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
1730 Pattern->AddPlaceholderChunk("expression");
1731 Results.AddResult(Result(Pattern));
Douglas Gregor12e13132010-05-26 22:00:08 +00001732
1733 // FIXME: Rethrow?
Douglas Gregor01dfea02010-01-10 23:08:15 +00001734 }
1735
1736 if (SemaRef.getLangOptions().ObjC1) {
1737 // Add "super", if we're in an Objective-C class with a superclass.
Ted Kremenek681e2562010-05-31 21:43:10 +00001738 if (ObjCMethodDecl *Method = SemaRef.getCurMethodDecl()) {
1739 // The interface can be NULL.
1740 if (ObjCInterfaceDecl *ID = Method->getClassInterface())
1741 if (ID->getSuperClass())
1742 Results.AddResult(Result("super"));
1743 }
1744
Douglas Gregorbca403c2010-01-13 23:51:12 +00001745 AddObjCExpressionResults(Results, true);
Douglas Gregor01dfea02010-01-10 23:08:15 +00001746 }
1747
Douglas Gregorc8bddde2010-05-28 00:22:41 +00001748 // sizeof expression
1749 Pattern = new CodeCompletionString;
1750 Pattern->AddTypedTextChunk("sizeof");
1751 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
1752 Pattern->AddPlaceholderChunk("expression-or-type");
1753 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
1754 Results.AddResult(Result(Pattern));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001755 break;
1756 }
Douglas Gregord32b0222010-08-24 01:06:58 +00001757
John McCallf312b1e2010-08-26 23:41:50 +00001758 case Sema::PCC_Type:
Douglas Gregord32b0222010-08-24 01:06:58 +00001759 break;
Douglas Gregor01dfea02010-01-10 23:08:15 +00001760 }
1761
Douglas Gregor4710e5b2010-05-28 00:49:12 +00001762 if (WantTypesInContext(CCC, SemaRef.getLangOptions()))
1763 AddTypeSpecifierResults(SemaRef.getLangOptions(), Results);
Douglas Gregor01dfea02010-01-10 23:08:15 +00001764
John McCallf312b1e2010-08-26 23:41:50 +00001765 if (SemaRef.getLangOptions().CPlusPlus && CCC != Sema::PCC_Type)
Douglas Gregora4477812010-01-14 16:01:26 +00001766 Results.AddResult(Result("operator"));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001767}
1768
Douglas Gregorff5ce6e2009-12-18 18:53:37 +00001769/// \brief If the given declaration has an associated type, add it as a result
1770/// type chunk.
1771static void AddResultTypeChunk(ASTContext &Context,
1772 NamedDecl *ND,
1773 CodeCompletionString *Result) {
1774 if (!ND)
1775 return;
Douglas Gregor6f942b22010-09-21 16:06:22 +00001776
1777 // Skip constructors and conversion functions, which have their return types
1778 // built into their names.
1779 if (isa<CXXConstructorDecl>(ND) || isa<CXXConversionDecl>(ND))
1780 return;
1781
Douglas Gregorff5ce6e2009-12-18 18:53:37 +00001782 // Determine the type of the declaration (if it has a type).
Douglas Gregor6f942b22010-09-21 16:06:22 +00001783 QualType T;
Douglas Gregorff5ce6e2009-12-18 18:53:37 +00001784 if (FunctionDecl *Function = dyn_cast<FunctionDecl>(ND))
1785 T = Function->getResultType();
1786 else if (ObjCMethodDecl *Method = dyn_cast<ObjCMethodDecl>(ND))
1787 T = Method->getResultType();
1788 else if (FunctionTemplateDecl *FunTmpl = dyn_cast<FunctionTemplateDecl>(ND))
1789 T = FunTmpl->getTemplatedDecl()->getResultType();
1790 else if (EnumConstantDecl *Enumerator = dyn_cast<EnumConstantDecl>(ND))
1791 T = Context.getTypeDeclType(cast<TypeDecl>(Enumerator->getDeclContext()));
1792 else if (isa<UnresolvedUsingValueDecl>(ND)) {
1793 /* Do nothing: ignore unresolved using declarations*/
1794 } else if (ValueDecl *Value = dyn_cast<ValueDecl>(ND))
1795 T = Value->getType();
1796 else if (ObjCPropertyDecl *Property = dyn_cast<ObjCPropertyDecl>(ND))
1797 T = Property->getType();
1798
1799 if (T.isNull() || Context.hasSameType(T, Context.DependentTy))
1800 return;
1801
Douglas Gregor84139d62010-04-05 21:25:31 +00001802 PrintingPolicy Policy(Context.PrintingPolicy);
1803 Policy.AnonymousTagLocations = false;
1804
Douglas Gregorff5ce6e2009-12-18 18:53:37 +00001805 std::string TypeStr;
Douglas Gregor84139d62010-04-05 21:25:31 +00001806 T.getAsStringInternal(TypeStr, Policy);
Douglas Gregorff5ce6e2009-12-18 18:53:37 +00001807 Result->AddResultTypeChunk(TypeStr);
1808}
1809
Douglas Gregoraaa107a2010-08-23 23:51:41 +00001810static void MaybeAddSentinel(ASTContext &Context, NamedDecl *FunctionOrMethod,
1811 CodeCompletionString *Result) {
1812 if (SentinelAttr *Sentinel = FunctionOrMethod->getAttr<SentinelAttr>())
1813 if (Sentinel->getSentinel() == 0) {
1814 if (Context.getLangOptions().ObjC1 &&
1815 Context.Idents.get("nil").hasMacroDefinition())
1816 Result->AddTextChunk(", nil");
1817 else if (Context.Idents.get("NULL").hasMacroDefinition())
1818 Result->AddTextChunk(", NULL");
1819 else
1820 Result->AddTextChunk(", (void*)0");
1821 }
1822}
1823
Douglas Gregor83482d12010-08-24 16:15:59 +00001824static std::string FormatFunctionParameter(ASTContext &Context,
Douglas Gregoraba48082010-08-29 19:47:46 +00001825 ParmVarDecl *Param,
1826 bool SuppressName = false) {
Douglas Gregor83482d12010-08-24 16:15:59 +00001827 bool ObjCMethodParam = isa<ObjCMethodDecl>(Param->getDeclContext());
1828 if (Param->getType()->isDependentType() ||
1829 !Param->getType()->isBlockPointerType()) {
1830 // The argument for a dependent or non-block parameter is a placeholder
1831 // containing that parameter's type.
1832 std::string Result;
1833
Douglas Gregoraba48082010-08-29 19:47:46 +00001834 if (Param->getIdentifier() && !ObjCMethodParam && !SuppressName)
Douglas Gregor83482d12010-08-24 16:15:59 +00001835 Result = Param->getIdentifier()->getName();
1836
1837 Param->getType().getAsStringInternal(Result,
1838 Context.PrintingPolicy);
1839
1840 if (ObjCMethodParam) {
1841 Result = "(" + Result;
1842 Result += ")";
Douglas Gregoraba48082010-08-29 19:47:46 +00001843 if (Param->getIdentifier() && !SuppressName)
Douglas Gregor83482d12010-08-24 16:15:59 +00001844 Result += Param->getIdentifier()->getName();
1845 }
1846 return Result;
1847 }
1848
1849 // The argument for a block pointer parameter is a block literal with
1850 // the appropriate type.
1851 FunctionProtoTypeLoc *Block = 0;
1852 TypeLoc TL;
1853 if (TypeSourceInfo *TSInfo = Param->getTypeSourceInfo()) {
1854 TL = TSInfo->getTypeLoc().getUnqualifiedLoc();
1855 while (true) {
1856 // Look through typedefs.
1857 if (TypedefTypeLoc *TypedefTL = dyn_cast<TypedefTypeLoc>(&TL)) {
1858 if (TypeSourceInfo *InnerTSInfo
1859 = TypedefTL->getTypedefDecl()->getTypeSourceInfo()) {
1860 TL = InnerTSInfo->getTypeLoc().getUnqualifiedLoc();
1861 continue;
1862 }
1863 }
1864
1865 // Look through qualified types
1866 if (QualifiedTypeLoc *QualifiedTL = dyn_cast<QualifiedTypeLoc>(&TL)) {
1867 TL = QualifiedTL->getUnqualifiedLoc();
1868 continue;
1869 }
1870
1871 // Try to get the function prototype behind the block pointer type,
1872 // then we're done.
1873 if (BlockPointerTypeLoc *BlockPtr
1874 = dyn_cast<BlockPointerTypeLoc>(&TL)) {
1875 TL = BlockPtr->getPointeeLoc();
1876 Block = dyn_cast<FunctionProtoTypeLoc>(&TL);
1877 }
1878 break;
1879 }
1880 }
1881
1882 if (!Block) {
1883 // We were unable to find a FunctionProtoTypeLoc with parameter names
1884 // for the block; just use the parameter type as a placeholder.
1885 std::string Result;
1886 Param->getType().getUnqualifiedType().
1887 getAsStringInternal(Result, Context.PrintingPolicy);
1888
1889 if (ObjCMethodParam) {
1890 Result = "(" + Result;
1891 Result += ")";
1892 if (Param->getIdentifier())
1893 Result += Param->getIdentifier()->getName();
1894 }
1895
1896 return Result;
1897 }
1898
1899 // We have the function prototype behind the block pointer type, as it was
1900 // written in the source.
Douglas Gregor38276252010-09-08 22:47:51 +00001901 std::string Result;
1902 QualType ResultType = Block->getTypePtr()->getResultType();
1903 if (!ResultType->isVoidType())
1904 ResultType.getAsStringInternal(Result, Context.PrintingPolicy);
1905
1906 Result = '^' + Result;
1907 if (Block->getNumArgs() == 0) {
1908 if (Block->getTypePtr()->isVariadic())
1909 Result += "(...)";
1910 } else {
1911 Result += "(";
1912 for (unsigned I = 0, N = Block->getNumArgs(); I != N; ++I) {
1913 if (I)
1914 Result += ", ";
1915 Result += FormatFunctionParameter(Context, Block->getArg(I));
1916
1917 if (I == N - 1 && Block->getTypePtr()->isVariadic())
1918 Result += ", ...";
1919 }
1920 Result += ")";
Douglas Gregore17794f2010-08-31 05:13:43 +00001921 }
Douglas Gregor38276252010-09-08 22:47:51 +00001922
Douglas Gregor83482d12010-08-24 16:15:59 +00001923 return Result;
1924}
1925
Douglas Gregor86d9a522009-09-21 16:56:56 +00001926/// \brief Add function parameter chunks to the given code completion string.
1927static void AddFunctionParameterChunks(ASTContext &Context,
1928 FunctionDecl *Function,
1929 CodeCompletionString *Result) {
Douglas Gregor0c8296d2009-11-07 00:00:49 +00001930 typedef CodeCompletionString::Chunk Chunk;
1931
Douglas Gregor86d9a522009-09-21 16:56:56 +00001932 CodeCompletionString *CCStr = Result;
1933
1934 for (unsigned P = 0, N = Function->getNumParams(); P != N; ++P) {
1935 ParmVarDecl *Param = Function->getParamDecl(P);
1936
1937 if (Param->hasDefaultArg()) {
1938 // When we see an optional default argument, put that argument and
1939 // the remaining default arguments into a new, optional string.
1940 CodeCompletionString *Opt = new CodeCompletionString;
1941 CCStr->AddOptionalChunk(std::auto_ptr<CodeCompletionString>(Opt));
1942 CCStr = Opt;
1943 }
1944
1945 if (P != 0)
Douglas Gregor0c8296d2009-11-07 00:00:49 +00001946 CCStr->AddChunk(Chunk(CodeCompletionString::CK_Comma));
Douglas Gregor86d9a522009-09-21 16:56:56 +00001947
1948 // Format the placeholder string.
Douglas Gregor83482d12010-08-24 16:15:59 +00001949 std::string PlaceholderStr = FormatFunctionParameter(Context, Param);
1950
Douglas Gregore17794f2010-08-31 05:13:43 +00001951 if (Function->isVariadic() && P == N - 1)
1952 PlaceholderStr += ", ...";
1953
Douglas Gregor86d9a522009-09-21 16:56:56 +00001954 // Add the placeholder string.
Benjamin Kramer660cc182009-11-29 20:18:50 +00001955 CCStr->AddPlaceholderChunk(PlaceholderStr);
Douglas Gregor86d9a522009-09-21 16:56:56 +00001956 }
Douglas Gregorb3d45252009-09-22 21:42:17 +00001957
1958 if (const FunctionProtoType *Proto
1959 = Function->getType()->getAs<FunctionProtoType>())
Douglas Gregoraaa107a2010-08-23 23:51:41 +00001960 if (Proto->isVariadic()) {
Douglas Gregore17794f2010-08-31 05:13:43 +00001961 if (Proto->getNumArgs() == 0)
1962 CCStr->AddPlaceholderChunk("...");
Douglas Gregoraaa107a2010-08-23 23:51:41 +00001963
1964 MaybeAddSentinel(Context, Function, CCStr);
1965 }
Douglas Gregor86d9a522009-09-21 16:56:56 +00001966}
1967
1968/// \brief Add template parameter chunks to the given code completion string.
1969static void AddTemplateParameterChunks(ASTContext &Context,
1970 TemplateDecl *Template,
1971 CodeCompletionString *Result,
1972 unsigned MaxParameters = 0) {
Douglas Gregor0c8296d2009-11-07 00:00:49 +00001973 typedef CodeCompletionString::Chunk Chunk;
1974
Douglas Gregor86d9a522009-09-21 16:56:56 +00001975 CodeCompletionString *CCStr = Result;
1976 bool FirstParameter = true;
1977
1978 TemplateParameterList *Params = Template->getTemplateParameters();
1979 TemplateParameterList::iterator PEnd = Params->end();
1980 if (MaxParameters)
1981 PEnd = Params->begin() + MaxParameters;
1982 for (TemplateParameterList::iterator P = Params->begin(); P != PEnd; ++P) {
1983 bool HasDefaultArg = false;
1984 std::string PlaceholderStr;
1985 if (TemplateTypeParmDecl *TTP = dyn_cast<TemplateTypeParmDecl>(*P)) {
1986 if (TTP->wasDeclaredWithTypename())
1987 PlaceholderStr = "typename";
1988 else
1989 PlaceholderStr = "class";
1990
1991 if (TTP->getIdentifier()) {
1992 PlaceholderStr += ' ';
1993 PlaceholderStr += TTP->getIdentifier()->getName();
1994 }
1995
1996 HasDefaultArg = TTP->hasDefaultArgument();
1997 } else if (NonTypeTemplateParmDecl *NTTP
1998 = dyn_cast<NonTypeTemplateParmDecl>(*P)) {
1999 if (NTTP->getIdentifier())
2000 PlaceholderStr = NTTP->getIdentifier()->getName();
2001 NTTP->getType().getAsStringInternal(PlaceholderStr,
2002 Context.PrintingPolicy);
2003 HasDefaultArg = NTTP->hasDefaultArgument();
2004 } else {
2005 assert(isa<TemplateTemplateParmDecl>(*P));
2006 TemplateTemplateParmDecl *TTP = cast<TemplateTemplateParmDecl>(*P);
2007
2008 // Since putting the template argument list into the placeholder would
2009 // be very, very long, we just use an abbreviation.
2010 PlaceholderStr = "template<...> class";
2011 if (TTP->getIdentifier()) {
2012 PlaceholderStr += ' ';
2013 PlaceholderStr += TTP->getIdentifier()->getName();
2014 }
2015
2016 HasDefaultArg = TTP->hasDefaultArgument();
2017 }
2018
2019 if (HasDefaultArg) {
2020 // When we see an optional default argument, put that argument and
2021 // the remaining default arguments into a new, optional string.
2022 CodeCompletionString *Opt = new CodeCompletionString;
2023 CCStr->AddOptionalChunk(std::auto_ptr<CodeCompletionString>(Opt));
2024 CCStr = Opt;
2025 }
2026
2027 if (FirstParameter)
2028 FirstParameter = false;
2029 else
Douglas Gregor0c8296d2009-11-07 00:00:49 +00002030 CCStr->AddChunk(Chunk(CodeCompletionString::CK_Comma));
Douglas Gregor86d9a522009-09-21 16:56:56 +00002031
2032 // Add the placeholder string.
Benjamin Kramer660cc182009-11-29 20:18:50 +00002033 CCStr->AddPlaceholderChunk(PlaceholderStr);
Douglas Gregor86d9a522009-09-21 16:56:56 +00002034 }
2035}
2036
Douglas Gregorb9d0ef72009-09-21 19:57:38 +00002037/// \brief Add a qualifier to the given code-completion string, if the
2038/// provided nested-name-specifier is non-NULL.
Douglas Gregora61a8792009-12-11 18:44:16 +00002039static void
2040AddQualifierToCompletionString(CodeCompletionString *Result,
2041 NestedNameSpecifier *Qualifier,
2042 bool QualifierIsInformative,
2043 ASTContext &Context) {
Douglas Gregorb9d0ef72009-09-21 19:57:38 +00002044 if (!Qualifier)
2045 return;
2046
2047 std::string PrintedNNS;
2048 {
2049 llvm::raw_string_ostream OS(PrintedNNS);
2050 Qualifier->print(OS, Context.PrintingPolicy);
2051 }
Douglas Gregor0563c262009-09-22 23:15:58 +00002052 if (QualifierIsInformative)
Benjamin Kramer660cc182009-11-29 20:18:50 +00002053 Result->AddInformativeChunk(PrintedNNS);
Douglas Gregor0563c262009-09-22 23:15:58 +00002054 else
Benjamin Kramer660cc182009-11-29 20:18:50 +00002055 Result->AddTextChunk(PrintedNNS);
Douglas Gregorb9d0ef72009-09-21 19:57:38 +00002056}
2057
Douglas Gregora61a8792009-12-11 18:44:16 +00002058static void AddFunctionTypeQualsToCompletionString(CodeCompletionString *Result,
2059 FunctionDecl *Function) {
2060 const FunctionProtoType *Proto
2061 = Function->getType()->getAs<FunctionProtoType>();
2062 if (!Proto || !Proto->getTypeQuals())
2063 return;
2064
2065 std::string QualsStr;
2066 if (Proto->getTypeQuals() & Qualifiers::Const)
2067 QualsStr += " const";
2068 if (Proto->getTypeQuals() & Qualifiers::Volatile)
2069 QualsStr += " volatile";
2070 if (Proto->getTypeQuals() & Qualifiers::Restrict)
2071 QualsStr += " restrict";
2072 Result->AddInformativeChunk(QualsStr);
2073}
2074
Douglas Gregor6f942b22010-09-21 16:06:22 +00002075/// \brief Add the name of the given declaration
2076static void AddTypedNameChunk(ASTContext &Context, NamedDecl *ND,
2077 CodeCompletionString *Result) {
2078 typedef CodeCompletionString::Chunk Chunk;
2079
2080 DeclarationName Name = ND->getDeclName();
2081 if (!Name)
2082 return;
2083
2084 switch (Name.getNameKind()) {
2085 case DeclarationName::Identifier:
2086 case DeclarationName::CXXConversionFunctionName:
2087 case DeclarationName::CXXOperatorName:
2088 case DeclarationName::CXXDestructorName:
2089 case DeclarationName::CXXLiteralOperatorName:
2090 Result->AddTypedTextChunk(ND->getNameAsString());
2091 break;
2092
2093 case DeclarationName::CXXUsingDirective:
2094 case DeclarationName::ObjCZeroArgSelector:
2095 case DeclarationName::ObjCOneArgSelector:
2096 case DeclarationName::ObjCMultiArgSelector:
2097 break;
2098
2099 case DeclarationName::CXXConstructorName: {
2100 CXXRecordDecl *Record = 0;
2101 QualType Ty = Name.getCXXNameType();
2102 if (const RecordType *RecordTy = Ty->getAs<RecordType>())
2103 Record = cast<CXXRecordDecl>(RecordTy->getDecl());
2104 else if (const InjectedClassNameType *InjectedTy
2105 = Ty->getAs<InjectedClassNameType>())
2106 Record = InjectedTy->getDecl();
2107 else {
2108 Result->AddTypedTextChunk(ND->getNameAsString());
2109 break;
2110 }
2111
2112 Result->AddTypedTextChunk(Record->getNameAsString());
2113 if (ClassTemplateDecl *Template = Record->getDescribedClassTemplate()) {
2114 Result->AddChunk(Chunk(CodeCompletionString::CK_LeftAngle));
2115 AddTemplateParameterChunks(Context, Template, Result);
2116 Result->AddChunk(Chunk(CodeCompletionString::CK_RightAngle));
2117 }
2118 break;
2119 }
2120 }
2121}
2122
Douglas Gregor86d9a522009-09-21 16:56:56 +00002123/// \brief If possible, create a new code completion string for the given
2124/// result.
2125///
2126/// \returns Either a new, heap-allocated code completion string describing
2127/// how to use this result, or NULL to indicate that the string or name of the
2128/// result is all that is needed.
2129CodeCompletionString *
John McCall0a2c5e22010-08-25 06:19:51 +00002130CodeCompletionResult::CreateCodeCompletionString(Sema &S,
Douglas Gregor6f942b22010-09-21 16:06:22 +00002131 CodeCompletionString *Result) {
Douglas Gregor0c8296d2009-11-07 00:00:49 +00002132 typedef CodeCompletionString::Chunk Chunk;
2133
Douglas Gregor2b4074f2009-12-01 05:55:20 +00002134 if (Kind == RK_Pattern)
Douglas Gregor1abc6bc2010-08-04 16:47:14 +00002135 return Pattern->Clone(Result);
Douglas Gregor2b4074f2009-12-01 05:55:20 +00002136
Douglas Gregor1abc6bc2010-08-04 16:47:14 +00002137 if (!Result)
2138 Result = new CodeCompletionString;
Douglas Gregor2b4074f2009-12-01 05:55:20 +00002139
2140 if (Kind == RK_Keyword) {
2141 Result->AddTypedTextChunk(Keyword);
2142 return Result;
2143 }
Douglas Gregor86d9a522009-09-21 16:56:56 +00002144
Douglas Gregor3f7c7f42009-10-30 16:50:04 +00002145 if (Kind == RK_Macro) {
2146 MacroInfo *MI = S.PP.getMacroInfo(Macro);
Douglas Gregor2b4074f2009-12-01 05:55:20 +00002147 assert(MI && "Not a macro?");
2148
2149 Result->AddTypedTextChunk(Macro->getName());
2150
2151 if (!MI->isFunctionLike())
2152 return Result;
Douglas Gregor3f7c7f42009-10-30 16:50:04 +00002153
2154 // Format a function-like macro with placeholders for the arguments.
Douglas Gregor0c8296d2009-11-07 00:00:49 +00002155 Result->AddChunk(Chunk(CodeCompletionString::CK_LeftParen));
Douglas Gregor3f7c7f42009-10-30 16:50:04 +00002156 for (MacroInfo::arg_iterator A = MI->arg_begin(), AEnd = MI->arg_end();
2157 A != AEnd; ++A) {
2158 if (A != MI->arg_begin())
Douglas Gregor0c8296d2009-11-07 00:00:49 +00002159 Result->AddChunk(Chunk(CodeCompletionString::CK_Comma));
Douglas Gregor3f7c7f42009-10-30 16:50:04 +00002160
2161 if (!MI->isVariadic() || A != AEnd - 1) {
2162 // Non-variadic argument.
Benjamin Kramer660cc182009-11-29 20:18:50 +00002163 Result->AddPlaceholderChunk((*A)->getName());
Douglas Gregor3f7c7f42009-10-30 16:50:04 +00002164 continue;
2165 }
2166
2167 // Variadic argument; cope with the different between GNU and C99
2168 // variadic macros, providing a single placeholder for the rest of the
2169 // arguments.
2170 if ((*A)->isStr("__VA_ARGS__"))
2171 Result->AddPlaceholderChunk("...");
2172 else {
2173 std::string Arg = (*A)->getName();
2174 Arg += "...";
Benjamin Kramer660cc182009-11-29 20:18:50 +00002175 Result->AddPlaceholderChunk(Arg);
Douglas Gregor3f7c7f42009-10-30 16:50:04 +00002176 }
2177 }
Douglas Gregor0c8296d2009-11-07 00:00:49 +00002178 Result->AddChunk(Chunk(CodeCompletionString::CK_RightParen));
Douglas Gregor3f7c7f42009-10-30 16:50:04 +00002179 return Result;
2180 }
2181
Douglas Gregord8e8a582010-05-25 21:41:55 +00002182 assert(Kind == RK_Declaration && "Missed a result kind?");
Douglas Gregor86d9a522009-09-21 16:56:56 +00002183 NamedDecl *ND = Declaration;
2184
Douglas Gregor0c8296d2009-11-07 00:00:49 +00002185 if (StartsNestedNameSpecifier) {
Benjamin Kramer660cc182009-11-29 20:18:50 +00002186 Result->AddTypedTextChunk(ND->getNameAsString());
Douglas Gregor0c8296d2009-11-07 00:00:49 +00002187 Result->AddTextChunk("::");
2188 return Result;
2189 }
2190
Douglas Gregorff5ce6e2009-12-18 18:53:37 +00002191 AddResultTypeChunk(S.Context, ND, Result);
2192
Douglas Gregor86d9a522009-09-21 16:56:56 +00002193 if (FunctionDecl *Function = dyn_cast<FunctionDecl>(ND)) {
Douglas Gregor0563c262009-09-22 23:15:58 +00002194 AddQualifierToCompletionString(Result, Qualifier, QualifierIsInformative,
2195 S.Context);
Douglas Gregor6f942b22010-09-21 16:06:22 +00002196 AddTypedNameChunk(S.Context, ND, Result);
Douglas Gregor0c8296d2009-11-07 00:00:49 +00002197 Result->AddChunk(Chunk(CodeCompletionString::CK_LeftParen));
Douglas Gregor86d9a522009-09-21 16:56:56 +00002198 AddFunctionParameterChunks(S.Context, Function, Result);
Douglas Gregor0c8296d2009-11-07 00:00:49 +00002199 Result->AddChunk(Chunk(CodeCompletionString::CK_RightParen));
Douglas Gregora61a8792009-12-11 18:44:16 +00002200 AddFunctionTypeQualsToCompletionString(Result, Function);
Douglas Gregor86d9a522009-09-21 16:56:56 +00002201 return Result;
2202 }
2203
2204 if (FunctionTemplateDecl *FunTmpl = dyn_cast<FunctionTemplateDecl>(ND)) {
Douglas Gregor0563c262009-09-22 23:15:58 +00002205 AddQualifierToCompletionString(Result, Qualifier, QualifierIsInformative,
2206 S.Context);
Douglas Gregor86d9a522009-09-21 16:56:56 +00002207 FunctionDecl *Function = FunTmpl->getTemplatedDecl();
Douglas Gregor6f942b22010-09-21 16:06:22 +00002208 AddTypedNameChunk(S.Context, Function, Result);
2209
Douglas Gregor86d9a522009-09-21 16:56:56 +00002210 // Figure out which template parameters are deduced (or have default
2211 // arguments).
2212 llvm::SmallVector<bool, 16> Deduced;
2213 S.MarkDeducedTemplateParameters(FunTmpl, Deduced);
2214 unsigned LastDeducibleArgument;
2215 for (LastDeducibleArgument = Deduced.size(); LastDeducibleArgument > 0;
2216 --LastDeducibleArgument) {
2217 if (!Deduced[LastDeducibleArgument - 1]) {
2218 // C++0x: Figure out if the template argument has a default. If so,
2219 // the user doesn't need to type this argument.
2220 // FIXME: We need to abstract template parameters better!
2221 bool HasDefaultArg = false;
2222 NamedDecl *Param = FunTmpl->getTemplateParameters()->getParam(
2223 LastDeducibleArgument - 1);
2224 if (TemplateTypeParmDecl *TTP = dyn_cast<TemplateTypeParmDecl>(Param))
2225 HasDefaultArg = TTP->hasDefaultArgument();
2226 else if (NonTypeTemplateParmDecl *NTTP
2227 = dyn_cast<NonTypeTemplateParmDecl>(Param))
2228 HasDefaultArg = NTTP->hasDefaultArgument();
2229 else {
2230 assert(isa<TemplateTemplateParmDecl>(Param));
2231 HasDefaultArg
Douglas Gregor0c8296d2009-11-07 00:00:49 +00002232 = cast<TemplateTemplateParmDecl>(Param)->hasDefaultArgument();
Douglas Gregor86d9a522009-09-21 16:56:56 +00002233 }
2234
2235 if (!HasDefaultArg)
2236 break;
2237 }
2238 }
2239
2240 if (LastDeducibleArgument) {
2241 // Some of the function template arguments cannot be deduced from a
2242 // function call, so we introduce an explicit template argument list
2243 // containing all of the arguments up to the first deducible argument.
Douglas Gregor0c8296d2009-11-07 00:00:49 +00002244 Result->AddChunk(Chunk(CodeCompletionString::CK_LeftAngle));
Douglas Gregor86d9a522009-09-21 16:56:56 +00002245 AddTemplateParameterChunks(S.Context, FunTmpl, Result,
2246 LastDeducibleArgument);
Douglas Gregor0c8296d2009-11-07 00:00:49 +00002247 Result->AddChunk(Chunk(CodeCompletionString::CK_RightAngle));
Douglas Gregor86d9a522009-09-21 16:56:56 +00002248 }
2249
2250 // Add the function parameters
Douglas Gregor0c8296d2009-11-07 00:00:49 +00002251 Result->AddChunk(Chunk(CodeCompletionString::CK_LeftParen));
Douglas Gregor86d9a522009-09-21 16:56:56 +00002252 AddFunctionParameterChunks(S.Context, Function, Result);
Douglas Gregor0c8296d2009-11-07 00:00:49 +00002253 Result->AddChunk(Chunk(CodeCompletionString::CK_RightParen));
Douglas Gregora61a8792009-12-11 18:44:16 +00002254 AddFunctionTypeQualsToCompletionString(Result, Function);
Douglas Gregor86d9a522009-09-21 16:56:56 +00002255 return Result;
2256 }
2257
2258 if (TemplateDecl *Template = dyn_cast<TemplateDecl>(ND)) {
Douglas Gregor0563c262009-09-22 23:15:58 +00002259 AddQualifierToCompletionString(Result, Qualifier, QualifierIsInformative,
2260 S.Context);
Benjamin Kramer660cc182009-11-29 20:18:50 +00002261 Result->AddTypedTextChunk(Template->getNameAsString());
Douglas Gregor0c8296d2009-11-07 00:00:49 +00002262 Result->AddChunk(Chunk(CodeCompletionString::CK_LeftAngle));
Douglas Gregor86d9a522009-09-21 16:56:56 +00002263 AddTemplateParameterChunks(S.Context, Template, Result);
Douglas Gregor0c8296d2009-11-07 00:00:49 +00002264 Result->AddChunk(Chunk(CodeCompletionString::CK_RightAngle));
Douglas Gregor86d9a522009-09-21 16:56:56 +00002265 return Result;
2266 }
2267
Douglas Gregor9630eb62009-11-17 16:44:22 +00002268 if (ObjCMethodDecl *Method = dyn_cast<ObjCMethodDecl>(ND)) {
Douglas Gregor9630eb62009-11-17 16:44:22 +00002269 Selector Sel = Method->getSelector();
2270 if (Sel.isUnarySelector()) {
2271 Result->AddTypedTextChunk(Sel.getIdentifierInfoForSlot(0)->getName());
2272 return Result;
2273 }
2274
Douglas Gregord3c68542009-11-19 01:08:35 +00002275 std::string SelName = Sel.getIdentifierInfoForSlot(0)->getName().str();
2276 SelName += ':';
2277 if (StartParameter == 0)
2278 Result->AddTypedTextChunk(SelName);
2279 else {
2280 Result->AddInformativeChunk(SelName);
2281
2282 // If there is only one parameter, and we're past it, add an empty
2283 // typed-text chunk since there is nothing to type.
2284 if (Method->param_size() == 1)
2285 Result->AddTypedTextChunk("");
2286 }
Douglas Gregor9630eb62009-11-17 16:44:22 +00002287 unsigned Idx = 0;
2288 for (ObjCMethodDecl::param_iterator P = Method->param_begin(),
2289 PEnd = Method->param_end();
2290 P != PEnd; (void)++P, ++Idx) {
2291 if (Idx > 0) {
Douglas Gregord3c68542009-11-19 01:08:35 +00002292 std::string Keyword;
2293 if (Idx > StartParameter)
Douglas Gregor834389b2010-01-12 06:38:28 +00002294 Result->AddChunk(CodeCompletionString::CK_HorizontalSpace);
Douglas Gregor9630eb62009-11-17 16:44:22 +00002295 if (IdentifierInfo *II = Sel.getIdentifierInfoForSlot(Idx))
2296 Keyword += II->getName().str();
2297 Keyword += ":";
Douglas Gregor1f5537a2010-07-08 23:20:03 +00002298 if (Idx < StartParameter || AllParametersAreInformative)
Douglas Gregord3c68542009-11-19 01:08:35 +00002299 Result->AddInformativeChunk(Keyword);
Douglas Gregor1f5537a2010-07-08 23:20:03 +00002300 else if (Idx == StartParameter)
Douglas Gregord3c68542009-11-19 01:08:35 +00002301 Result->AddTypedTextChunk(Keyword);
2302 else
2303 Result->AddTextChunk(Keyword);
Douglas Gregor9630eb62009-11-17 16:44:22 +00002304 }
Douglas Gregord3c68542009-11-19 01:08:35 +00002305
2306 // If we're before the starting parameter, skip the placeholder.
2307 if (Idx < StartParameter)
2308 continue;
Douglas Gregor9630eb62009-11-17 16:44:22 +00002309
2310 std::string Arg;
Douglas Gregor83482d12010-08-24 16:15:59 +00002311
2312 if ((*P)->getType()->isBlockPointerType() && !DeclaringEntity)
Douglas Gregoraba48082010-08-29 19:47:46 +00002313 Arg = FormatFunctionParameter(S.Context, *P, true);
Douglas Gregor83482d12010-08-24 16:15:59 +00002314 else {
2315 (*P)->getType().getAsStringInternal(Arg, S.Context.PrintingPolicy);
2316 Arg = "(" + Arg + ")";
2317 if (IdentifierInfo *II = (*P)->getIdentifier())
Douglas Gregoraba48082010-08-29 19:47:46 +00002318 if (DeclaringEntity || AllParametersAreInformative)
2319 Arg += II->getName().str();
Douglas Gregor83482d12010-08-24 16:15:59 +00002320 }
2321
Douglas Gregore17794f2010-08-31 05:13:43 +00002322 if (Method->isVariadic() && (P + 1) == PEnd)
2323 Arg += ", ...";
2324
Douglas Gregor1f5537a2010-07-08 23:20:03 +00002325 if (DeclaringEntity)
2326 Result->AddTextChunk(Arg);
2327 else if (AllParametersAreInformative)
Douglas Gregor4ad96852009-11-19 07:41:15 +00002328 Result->AddInformativeChunk(Arg);
2329 else
2330 Result->AddPlaceholderChunk(Arg);
Douglas Gregor9630eb62009-11-17 16:44:22 +00002331 }
2332
Douglas Gregor2a17af02009-12-23 00:21:46 +00002333 if (Method->isVariadic()) {
Douglas Gregore17794f2010-08-31 05:13:43 +00002334 if (Method->param_size() == 0) {
2335 if (DeclaringEntity)
2336 Result->AddTextChunk(", ...");
2337 else if (AllParametersAreInformative)
2338 Result->AddInformativeChunk(", ...");
2339 else
2340 Result->AddPlaceholderChunk(", ...");
2341 }
Douglas Gregoraaa107a2010-08-23 23:51:41 +00002342
2343 MaybeAddSentinel(S.Context, Method, Result);
Douglas Gregor2a17af02009-12-23 00:21:46 +00002344 }
2345
Douglas Gregor9630eb62009-11-17 16:44:22 +00002346 return Result;
2347 }
2348
Douglas Gregor2b4074f2009-12-01 05:55:20 +00002349 if (Qualifier)
Douglas Gregor0563c262009-09-22 23:15:58 +00002350 AddQualifierToCompletionString(Result, Qualifier, QualifierIsInformative,
2351 S.Context);
Douglas Gregor2b4074f2009-12-01 05:55:20 +00002352
2353 Result->AddTypedTextChunk(ND->getNameAsString());
2354 return Result;
Douglas Gregor86d9a522009-09-21 16:56:56 +00002355}
2356
Douglas Gregor86d802e2009-09-23 00:34:09 +00002357CodeCompletionString *
2358CodeCompleteConsumer::OverloadCandidate::CreateSignatureString(
2359 unsigned CurrentArg,
2360 Sema &S) const {
Douglas Gregor0c8296d2009-11-07 00:00:49 +00002361 typedef CodeCompletionString::Chunk Chunk;
2362
Douglas Gregor86d802e2009-09-23 00:34:09 +00002363 CodeCompletionString *Result = new CodeCompletionString;
2364 FunctionDecl *FDecl = getFunction();
Douglas Gregorff5ce6e2009-12-18 18:53:37 +00002365 AddResultTypeChunk(S.Context, FDecl, Result);
Douglas Gregor86d802e2009-09-23 00:34:09 +00002366 const FunctionProtoType *Proto
2367 = dyn_cast<FunctionProtoType>(getFunctionType());
2368 if (!FDecl && !Proto) {
2369 // Function without a prototype. Just give the return type and a
2370 // highlighted ellipsis.
2371 const FunctionType *FT = getFunctionType();
2372 Result->AddTextChunk(
Benjamin Kramer660cc182009-11-29 20:18:50 +00002373 FT->getResultType().getAsString(S.Context.PrintingPolicy));
Douglas Gregor0c8296d2009-11-07 00:00:49 +00002374 Result->AddChunk(Chunk(CodeCompletionString::CK_LeftParen));
2375 Result->AddChunk(Chunk(CodeCompletionString::CK_CurrentParameter, "..."));
2376 Result->AddChunk(Chunk(CodeCompletionString::CK_RightParen));
Douglas Gregor86d802e2009-09-23 00:34:09 +00002377 return Result;
2378 }
2379
2380 if (FDecl)
Benjamin Kramer660cc182009-11-29 20:18:50 +00002381 Result->AddTextChunk(FDecl->getNameAsString());
Douglas Gregor86d802e2009-09-23 00:34:09 +00002382 else
2383 Result->AddTextChunk(
Benjamin Kramer660cc182009-11-29 20:18:50 +00002384 Proto->getResultType().getAsString(S.Context.PrintingPolicy));
Douglas Gregor86d802e2009-09-23 00:34:09 +00002385
Douglas Gregor0c8296d2009-11-07 00:00:49 +00002386 Result->AddChunk(Chunk(CodeCompletionString::CK_LeftParen));
Douglas Gregor86d802e2009-09-23 00:34:09 +00002387 unsigned NumParams = FDecl? FDecl->getNumParams() : Proto->getNumArgs();
2388 for (unsigned I = 0; I != NumParams; ++I) {
2389 if (I)
Douglas Gregor0c8296d2009-11-07 00:00:49 +00002390 Result->AddChunk(Chunk(CodeCompletionString::CK_Comma));
Douglas Gregor86d802e2009-09-23 00:34:09 +00002391
2392 std::string ArgString;
2393 QualType ArgType;
2394
2395 if (FDecl) {
2396 ArgString = FDecl->getParamDecl(I)->getNameAsString();
2397 ArgType = FDecl->getParamDecl(I)->getOriginalType();
2398 } else {
2399 ArgType = Proto->getArgType(I);
2400 }
2401
2402 ArgType.getAsStringInternal(ArgString, S.Context.PrintingPolicy);
2403
2404 if (I == CurrentArg)
Douglas Gregor0c8296d2009-11-07 00:00:49 +00002405 Result->AddChunk(Chunk(CodeCompletionString::CK_CurrentParameter,
Benjamin Kramer660cc182009-11-29 20:18:50 +00002406 ArgString));
Douglas Gregor86d802e2009-09-23 00:34:09 +00002407 else
Benjamin Kramer660cc182009-11-29 20:18:50 +00002408 Result->AddTextChunk(ArgString);
Douglas Gregor86d802e2009-09-23 00:34:09 +00002409 }
2410
2411 if (Proto && Proto->isVariadic()) {
Douglas Gregor0c8296d2009-11-07 00:00:49 +00002412 Result->AddChunk(Chunk(CodeCompletionString::CK_Comma));
Douglas Gregor86d802e2009-09-23 00:34:09 +00002413 if (CurrentArg < NumParams)
2414 Result->AddTextChunk("...");
2415 else
Douglas Gregor0c8296d2009-11-07 00:00:49 +00002416 Result->AddChunk(Chunk(CodeCompletionString::CK_CurrentParameter, "..."));
Douglas Gregor86d802e2009-09-23 00:34:09 +00002417 }
Douglas Gregor0c8296d2009-11-07 00:00:49 +00002418 Result->AddChunk(Chunk(CodeCompletionString::CK_RightParen));
Douglas Gregor86d802e2009-09-23 00:34:09 +00002419
2420 return Result;
2421}
2422
Douglas Gregor1827e102010-08-16 16:18:59 +00002423unsigned clang::getMacroUsagePriority(llvm::StringRef MacroName,
Douglas Gregorb05496d2010-09-20 21:11:48 +00002424 const LangOptions &LangOpts,
Douglas Gregor1827e102010-08-16 16:18:59 +00002425 bool PreferredTypeIsPointer) {
2426 unsigned Priority = CCP_Macro;
2427
Douglas Gregorb05496d2010-09-20 21:11:48 +00002428 // Treat the "nil", "Nil" and "NULL" macros as null pointer constants.
2429 if (MacroName.equals("nil") || MacroName.equals("NULL") ||
2430 MacroName.equals("Nil")) {
Douglas Gregor1827e102010-08-16 16:18:59 +00002431 Priority = CCP_Constant;
2432 if (PreferredTypeIsPointer)
2433 Priority = Priority / CCF_SimilarTypeMatch;
Douglas Gregorb05496d2010-09-20 21:11:48 +00002434 }
2435 // Treat "YES", "NO", "true", and "false" as constants.
2436 else if (MacroName.equals("YES") || MacroName.equals("NO") ||
2437 MacroName.equals("true") || MacroName.equals("false"))
2438 Priority = CCP_Constant;
2439 // Treat "bool" as a type.
2440 else if (MacroName.equals("bool"))
2441 Priority = CCP_Type + (LangOpts.ObjC1? CCD_bool_in_ObjC : 0);
2442
Douglas Gregor1827e102010-08-16 16:18:59 +00002443
2444 return Priority;
2445}
2446
Douglas Gregore8d7beb2010-09-03 23:30:36 +00002447CXCursorKind clang::getCursorKindForDecl(Decl *D) {
2448 if (!D)
2449 return CXCursor_UnexposedDecl;
2450
2451 switch (D->getKind()) {
2452 case Decl::Enum: return CXCursor_EnumDecl;
2453 case Decl::EnumConstant: return CXCursor_EnumConstantDecl;
2454 case Decl::Field: return CXCursor_FieldDecl;
2455 case Decl::Function:
2456 return CXCursor_FunctionDecl;
2457 case Decl::ObjCCategory: return CXCursor_ObjCCategoryDecl;
2458 case Decl::ObjCCategoryImpl: return CXCursor_ObjCCategoryImplDecl;
2459 case Decl::ObjCClass:
2460 // FIXME
2461 return CXCursor_UnexposedDecl;
2462 case Decl::ObjCForwardProtocol:
2463 // FIXME
2464 return CXCursor_UnexposedDecl;
2465 case Decl::ObjCImplementation: return CXCursor_ObjCImplementationDecl;
2466 case Decl::ObjCInterface: return CXCursor_ObjCInterfaceDecl;
2467 case Decl::ObjCIvar: return CXCursor_ObjCIvarDecl;
2468 case Decl::ObjCMethod:
2469 return cast<ObjCMethodDecl>(D)->isInstanceMethod()
2470 ? CXCursor_ObjCInstanceMethodDecl : CXCursor_ObjCClassMethodDecl;
2471 case Decl::CXXMethod: return CXCursor_CXXMethod;
2472 case Decl::CXXConstructor: return CXCursor_Constructor;
2473 case Decl::CXXDestructor: return CXCursor_Destructor;
2474 case Decl::CXXConversion: return CXCursor_ConversionFunction;
2475 case Decl::ObjCProperty: return CXCursor_ObjCPropertyDecl;
2476 case Decl::ObjCProtocol: return CXCursor_ObjCProtocolDecl;
2477 case Decl::ParmVar: return CXCursor_ParmDecl;
2478 case Decl::Typedef: return CXCursor_TypedefDecl;
2479 case Decl::Var: return CXCursor_VarDecl;
2480 case Decl::Namespace: return CXCursor_Namespace;
2481 case Decl::NamespaceAlias: return CXCursor_NamespaceAlias;
2482 case Decl::TemplateTypeParm: return CXCursor_TemplateTypeParameter;
2483 case Decl::NonTypeTemplateParm:return CXCursor_NonTypeTemplateParameter;
2484 case Decl::TemplateTemplateParm:return CXCursor_TemplateTemplateParameter;
2485 case Decl::FunctionTemplate: return CXCursor_FunctionTemplate;
2486 case Decl::ClassTemplate: return CXCursor_ClassTemplate;
2487 case Decl::ClassTemplatePartialSpecialization:
2488 return CXCursor_ClassTemplatePartialSpecialization;
2489 case Decl::UsingDirective: return CXCursor_UsingDirective;
2490
2491 case Decl::Using:
2492 case Decl::UnresolvedUsingValue:
2493 case Decl::UnresolvedUsingTypename:
2494 return CXCursor_UsingDeclaration;
2495
2496 default:
2497 if (TagDecl *TD = dyn_cast<TagDecl>(D)) {
2498 switch (TD->getTagKind()) {
2499 case TTK_Struct: return CXCursor_StructDecl;
2500 case TTK_Class: return CXCursor_ClassDecl;
2501 case TTK_Union: return CXCursor_UnionDecl;
2502 case TTK_Enum: return CXCursor_EnumDecl;
2503 }
2504 }
2505 }
2506
2507 return CXCursor_UnexposedDecl;
2508}
2509
Douglas Gregor590c7d52010-07-08 20:55:51 +00002510static void AddMacroResults(Preprocessor &PP, ResultBuilder &Results,
2511 bool TargetTypeIsPointer = false) {
John McCall0a2c5e22010-08-25 06:19:51 +00002512 typedef CodeCompletionResult Result;
Douglas Gregor590c7d52010-07-08 20:55:51 +00002513
Douglas Gregor3f7c7f42009-10-30 16:50:04 +00002514 Results.EnterNewScope();
Douglas Gregor0c8296d2009-11-07 00:00:49 +00002515 for (Preprocessor::macro_iterator M = PP.macro_begin(),
2516 MEnd = PP.macro_end();
Douglas Gregor590c7d52010-07-08 20:55:51 +00002517 M != MEnd; ++M) {
Douglas Gregor1827e102010-08-16 16:18:59 +00002518 Results.AddResult(Result(M->first,
2519 getMacroUsagePriority(M->first->getName(),
Douglas Gregorb05496d2010-09-20 21:11:48 +00002520 PP.getLangOptions(),
Douglas Gregor1827e102010-08-16 16:18:59 +00002521 TargetTypeIsPointer)));
Douglas Gregor590c7d52010-07-08 20:55:51 +00002522 }
Douglas Gregor3f7c7f42009-10-30 16:50:04 +00002523 Results.ExitScope();
2524}
2525
Douglas Gregoraa5f77b2010-08-23 21:54:33 +00002526static void AddPrettyFunctionResults(const LangOptions &LangOpts,
2527 ResultBuilder &Results) {
John McCall0a2c5e22010-08-25 06:19:51 +00002528 typedef CodeCompletionResult Result;
Douglas Gregoraa5f77b2010-08-23 21:54:33 +00002529
2530 Results.EnterNewScope();
2531 Results.AddResult(Result("__PRETTY_FUNCTION__", CCP_Constant));
2532 Results.AddResult(Result("__FUNCTION__", CCP_Constant));
2533 if (LangOpts.C99 || LangOpts.CPlusPlus0x)
2534 Results.AddResult(Result("__func__", CCP_Constant));
2535 Results.ExitScope();
2536}
2537
Daniel Dunbar3a2838d2009-11-13 08:58:20 +00002538static void HandleCodeCompleteResults(Sema *S,
2539 CodeCompleteConsumer *CodeCompleter,
Douglas Gregore6b1bb62010-08-11 21:23:17 +00002540 CodeCompletionContext Context,
John McCall0a2c5e22010-08-25 06:19:51 +00002541 CodeCompletionResult *Results,
Douglas Gregore6b1bb62010-08-11 21:23:17 +00002542 unsigned NumResults) {
Douglas Gregor86d9a522009-09-21 16:56:56 +00002543 if (CodeCompleter)
Douglas Gregore6b1bb62010-08-11 21:23:17 +00002544 CodeCompleter->ProcessCodeCompleteResults(*S, Context, Results, NumResults);
Douglas Gregor54f01612009-11-19 00:01:57 +00002545
2546 for (unsigned I = 0; I != NumResults; ++I)
2547 Results[I].Destroy();
Douglas Gregor86d9a522009-09-21 16:56:56 +00002548}
2549
Douglas Gregore6b1bb62010-08-11 21:23:17 +00002550static enum CodeCompletionContext::Kind mapCodeCompletionContext(Sema &S,
2551 Sema::ParserCompletionContext PCC) {
2552 switch (PCC) {
John McCallf312b1e2010-08-26 23:41:50 +00002553 case Sema::PCC_Namespace:
Douglas Gregore6b1bb62010-08-11 21:23:17 +00002554 return CodeCompletionContext::CCC_TopLevel;
2555
John McCallf312b1e2010-08-26 23:41:50 +00002556 case Sema::PCC_Class:
Douglas Gregore6b1bb62010-08-11 21:23:17 +00002557 return CodeCompletionContext::CCC_ClassStructUnion;
2558
John McCallf312b1e2010-08-26 23:41:50 +00002559 case Sema::PCC_ObjCInterface:
Douglas Gregore6b1bb62010-08-11 21:23:17 +00002560 return CodeCompletionContext::CCC_ObjCInterface;
2561
John McCallf312b1e2010-08-26 23:41:50 +00002562 case Sema::PCC_ObjCImplementation:
Douglas Gregore6b1bb62010-08-11 21:23:17 +00002563 return CodeCompletionContext::CCC_ObjCImplementation;
2564
John McCallf312b1e2010-08-26 23:41:50 +00002565 case Sema::PCC_ObjCInstanceVariableList:
Douglas Gregore6b1bb62010-08-11 21:23:17 +00002566 return CodeCompletionContext::CCC_ObjCIvarList;
2567
John McCallf312b1e2010-08-26 23:41:50 +00002568 case Sema::PCC_Template:
2569 case Sema::PCC_MemberTemplate:
2570 case Sema::PCC_RecoveryInFunction:
Douglas Gregore6b1bb62010-08-11 21:23:17 +00002571 return CodeCompletionContext::CCC_Other;
2572
John McCallf312b1e2010-08-26 23:41:50 +00002573 case Sema::PCC_Expression:
2574 case Sema::PCC_ForInit:
2575 case Sema::PCC_Condition:
Douglas Gregore6b1bb62010-08-11 21:23:17 +00002576 return CodeCompletionContext::CCC_Expression;
2577
John McCallf312b1e2010-08-26 23:41:50 +00002578 case Sema::PCC_Statement:
Douglas Gregore6b1bb62010-08-11 21:23:17 +00002579 return CodeCompletionContext::CCC_Statement;
Douglas Gregor72db1082010-08-24 01:11:00 +00002580
John McCallf312b1e2010-08-26 23:41:50 +00002581 case Sema::PCC_Type:
Douglas Gregor72db1082010-08-24 01:11:00 +00002582 return CodeCompletionContext::CCC_Type;
Douglas Gregor02688102010-09-14 23:59:36 +00002583
2584 case Sema::PCC_ParenthesizedExpression:
2585 return CodeCompletionContext::CCC_ParenthesizedExpression;
Douglas Gregore6b1bb62010-08-11 21:23:17 +00002586 }
2587
2588 return CodeCompletionContext::CCC_Other;
2589}
2590
Douglas Gregorf6961522010-08-27 21:18:54 +00002591/// \brief If we're in a C++ virtual member function, add completion results
2592/// that invoke the functions we override, since it's common to invoke the
2593/// overridden function as well as adding new functionality.
2594///
2595/// \param S The semantic analysis object for which we are generating results.
2596///
2597/// \param InContext This context in which the nested-name-specifier preceding
2598/// the code-completion point
2599static void MaybeAddOverrideCalls(Sema &S, DeclContext *InContext,
2600 ResultBuilder &Results) {
2601 // Look through blocks.
2602 DeclContext *CurContext = S.CurContext;
2603 while (isa<BlockDecl>(CurContext))
2604 CurContext = CurContext->getParent();
2605
2606
2607 CXXMethodDecl *Method = dyn_cast<CXXMethodDecl>(CurContext);
2608 if (!Method || !Method->isVirtual())
2609 return;
2610
2611 // We need to have names for all of the parameters, if we're going to
2612 // generate a forwarding call.
2613 for (CXXMethodDecl::param_iterator P = Method->param_begin(),
2614 PEnd = Method->param_end();
2615 P != PEnd;
2616 ++P) {
2617 if (!(*P)->getDeclName())
2618 return;
2619 }
2620
2621 for (CXXMethodDecl::method_iterator M = Method->begin_overridden_methods(),
2622 MEnd = Method->end_overridden_methods();
2623 M != MEnd; ++M) {
2624 CodeCompletionString *Pattern = new CodeCompletionString;
2625 CXXMethodDecl *Overridden = const_cast<CXXMethodDecl *>(*M);
2626 if (Overridden->getCanonicalDecl() == Method->getCanonicalDecl())
2627 continue;
2628
2629 // If we need a nested-name-specifier, add one now.
2630 if (!InContext) {
2631 NestedNameSpecifier *NNS
2632 = getRequiredQualification(S.Context, CurContext,
2633 Overridden->getDeclContext());
2634 if (NNS) {
2635 std::string Str;
2636 llvm::raw_string_ostream OS(Str);
2637 NNS->print(OS, S.Context.PrintingPolicy);
2638 Pattern->AddTextChunk(OS.str());
2639 }
2640 } else if (!InContext->Equals(Overridden->getDeclContext()))
2641 continue;
2642
2643 Pattern->AddTypedTextChunk(Overridden->getNameAsString());
2644 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
2645 bool FirstParam = true;
2646 for (CXXMethodDecl::param_iterator P = Method->param_begin(),
2647 PEnd = Method->param_end();
2648 P != PEnd; ++P) {
2649 if (FirstParam)
2650 FirstParam = false;
2651 else
2652 Pattern->AddChunk(CodeCompletionString::CK_Comma);
2653
2654 Pattern->AddPlaceholderChunk((*P)->getIdentifier()->getName());
2655 }
2656 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
2657 Results.AddResult(CodeCompletionResult(Pattern,
2658 CCP_SuperCompletion,
2659 CXCursor_CXXMethod));
2660 Results.Ignore(Overridden);
2661 }
2662}
2663
Douglas Gregor01dfea02010-01-10 23:08:15 +00002664void Sema::CodeCompleteOrdinaryName(Scope *S,
Douglas Gregore6b1bb62010-08-11 21:23:17 +00002665 ParserCompletionContext CompletionContext) {
John McCall0a2c5e22010-08-25 06:19:51 +00002666 typedef CodeCompletionResult Result;
Douglas Gregor2ccccb32010-08-23 18:23:48 +00002667 ResultBuilder Results(*this);
Douglas Gregorcee9ff12010-09-20 22:39:41 +00002668 Results.setCompletionContext(mapCodeCompletionContext(*this,
2669 CompletionContext));
Douglas Gregorf6961522010-08-27 21:18:54 +00002670 Results.EnterNewScope();
Douglas Gregorcee9ff12010-09-20 22:39:41 +00002671
Douglas Gregor01dfea02010-01-10 23:08:15 +00002672 // Determine how to filter results, e.g., so that the names of
2673 // values (functions, enumerators, function templates, etc.) are
2674 // only allowed where we can have an expression.
2675 switch (CompletionContext) {
Douglas Gregore6b1bb62010-08-11 21:23:17 +00002676 case PCC_Namespace:
2677 case PCC_Class:
2678 case PCC_ObjCInterface:
2679 case PCC_ObjCImplementation:
2680 case PCC_ObjCInstanceVariableList:
2681 case PCC_Template:
2682 case PCC_MemberTemplate:
Douglas Gregor72db1082010-08-24 01:11:00 +00002683 case PCC_Type:
Douglas Gregor01dfea02010-01-10 23:08:15 +00002684 Results.setFilter(&ResultBuilder::IsOrdinaryNonValueName);
2685 break;
2686
Douglas Gregore6b1bb62010-08-11 21:23:17 +00002687 case PCC_Statement:
Douglas Gregor02688102010-09-14 23:59:36 +00002688 case PCC_ParenthesizedExpression:
Douglas Gregoreb0d0142010-08-24 23:58:17 +00002689 case PCC_Expression:
Douglas Gregore6b1bb62010-08-11 21:23:17 +00002690 case PCC_ForInit:
2691 case PCC_Condition:
Douglas Gregor4710e5b2010-05-28 00:49:12 +00002692 if (WantTypesInContext(CompletionContext, getLangOptions()))
2693 Results.setFilter(&ResultBuilder::IsOrdinaryName);
2694 else
2695 Results.setFilter(&ResultBuilder::IsOrdinaryNonTypeName);
Douglas Gregorf6961522010-08-27 21:18:54 +00002696
2697 if (getLangOptions().CPlusPlus)
2698 MaybeAddOverrideCalls(*this, /*InContext=*/0, Results);
Douglas Gregor01dfea02010-01-10 23:08:15 +00002699 break;
Douglas Gregordc845342010-05-25 05:58:43 +00002700
Douglas Gregore6b1bb62010-08-11 21:23:17 +00002701 case PCC_RecoveryInFunction:
Douglas Gregordc845342010-05-25 05:58:43 +00002702 // Unfiltered
2703 break;
Douglas Gregor01dfea02010-01-10 23:08:15 +00002704 }
2705
Douglas Gregor3cdee122010-08-26 16:36:48 +00002706 // If we are in a C++ non-static member function, check the qualifiers on
2707 // the member function to filter/prioritize the results list.
2708 if (CXXMethodDecl *CurMethod = dyn_cast<CXXMethodDecl>(CurContext))
2709 if (CurMethod->isInstance())
2710 Results.setObjectTypeQualifiers(
2711 Qualifiers::fromCVRMask(CurMethod->getTypeQualifiers()));
2712
Douglas Gregor1ca6ae82010-01-14 01:09:38 +00002713 CodeCompletionDeclConsumer Consumer(Results, CurContext);
Douglas Gregor8071e422010-08-15 06:18:01 +00002714 LookupVisibleDecls(S, LookupOrdinaryName, Consumer,
2715 CodeCompleter->includeGlobals());
Douglas Gregor2a7925c2009-12-07 09:54:55 +00002716
Douglas Gregorbca403c2010-01-13 23:51:12 +00002717 AddOrdinaryNameResults(CompletionContext, S, *this, Results);
Douglas Gregor2a7925c2009-12-07 09:54:55 +00002718 Results.ExitScope();
2719
Douglas Gregoraa5f77b2010-08-23 21:54:33 +00002720 switch (CompletionContext) {
Douglas Gregor02688102010-09-14 23:59:36 +00002721 case PCC_ParenthesizedExpression:
Douglas Gregor72db1082010-08-24 01:11:00 +00002722 case PCC_Expression:
2723 case PCC_Statement:
2724 case PCC_RecoveryInFunction:
2725 if (S->getFnParent())
2726 AddPrettyFunctionResults(PP.getLangOptions(), Results);
2727 break;
2728
2729 case PCC_Namespace:
2730 case PCC_Class:
2731 case PCC_ObjCInterface:
2732 case PCC_ObjCImplementation:
2733 case PCC_ObjCInstanceVariableList:
2734 case PCC_Template:
2735 case PCC_MemberTemplate:
2736 case PCC_ForInit:
2737 case PCC_Condition:
2738 case PCC_Type:
2739 break;
Douglas Gregoraa5f77b2010-08-23 21:54:33 +00002740 }
2741
Douglas Gregor0c8296d2009-11-07 00:00:49 +00002742 if (CodeCompleter->includeMacros())
Douglas Gregorbca403c2010-01-13 23:51:12 +00002743 AddMacroResults(PP, Results);
Douglas Gregoraa5f77b2010-08-23 21:54:33 +00002744
Douglas Gregorcee9ff12010-09-20 22:39:41 +00002745 HandleCodeCompleteResults(this, CodeCompleter, Results.getCompletionContext(),
Douglas Gregore6b1bb62010-08-11 21:23:17 +00002746 Results.data(),Results.size());
Douglas Gregor791215b2009-09-21 20:51:25 +00002747}
2748
Douglas Gregorc7b6d882010-09-16 15:14:18 +00002749static void AddClassMessageCompletions(Sema &SemaRef, Scope *S,
2750 ParsedType Receiver,
2751 IdentifierInfo **SelIdents,
2752 unsigned NumSelIdents,
Douglas Gregor70c5ac72010-09-20 23:34:21 +00002753 bool AtArgumentExpression,
Douglas Gregorc7b6d882010-09-16 15:14:18 +00002754 bool IsSuper,
2755 ResultBuilder &Results);
2756
2757void Sema::CodeCompleteDeclSpec(Scope *S, DeclSpec &DS,
2758 bool AllowNonIdentifiers,
2759 bool AllowNestedNameSpecifiers) {
John McCall0a2c5e22010-08-25 06:19:51 +00002760 typedef CodeCompletionResult Result;
Douglas Gregor2ccccb32010-08-23 18:23:48 +00002761 ResultBuilder Results(*this);
2762 Results.EnterNewScope();
2763
2764 // Type qualifiers can come after names.
2765 Results.AddResult(Result("const"));
2766 Results.AddResult(Result("volatile"));
2767 if (getLangOptions().C99)
2768 Results.AddResult(Result("restrict"));
2769
2770 if (getLangOptions().CPlusPlus) {
2771 if (AllowNonIdentifiers) {
2772 Results.AddResult(Result("operator"));
2773 }
2774
2775 // Add nested-name-specifiers.
2776 if (AllowNestedNameSpecifiers) {
2777 Results.allowNestedNameSpecifiers();
2778 CodeCompletionDeclConsumer Consumer(Results, CurContext);
2779 LookupVisibleDecls(S, LookupNestedNameSpecifierName, Consumer,
2780 CodeCompleter->includeGlobals());
2781 }
2782 }
2783 Results.ExitScope();
2784
Douglas Gregorc7b6d882010-09-16 15:14:18 +00002785 // If we're in a context where we might have an expression (rather than a
2786 // declaration), and what we've seen so far is an Objective-C type that could
2787 // be a receiver of a class message, this may be a class message send with
2788 // the initial opening bracket '[' missing. Add appropriate completions.
2789 if (AllowNonIdentifiers && !AllowNestedNameSpecifiers &&
2790 DS.getTypeSpecType() == DeclSpec::TST_typename &&
2791 DS.getStorageClassSpecAsWritten() == DeclSpec::SCS_unspecified &&
2792 !DS.isThreadSpecified() && !DS.isExternInLinkageSpec() &&
2793 DS.getTypeSpecComplex() == DeclSpec::TSC_unspecified &&
2794 DS.getTypeSpecSign() == DeclSpec::TSS_unspecified &&
2795 DS.getTypeQualifiers() == 0 &&
2796 S &&
2797 (S->getFlags() & Scope::DeclScope) != 0 &&
2798 (S->getFlags() & (Scope::ClassScope | Scope::TemplateParamScope |
2799 Scope::FunctionPrototypeScope |
2800 Scope::AtCatchScope)) == 0) {
2801 ParsedType T = DS.getRepAsType();
2802 if (!T.get().isNull() && T.get()->isObjCObjectOrInterfaceType())
Douglas Gregor70c5ac72010-09-20 23:34:21 +00002803 AddClassMessageCompletions(*this, S, T, 0, 0, false, false, Results);
Douglas Gregorc7b6d882010-09-16 15:14:18 +00002804 }
2805
Douglas Gregor4497dd42010-08-24 04:59:56 +00002806 // Note that we intentionally suppress macro results here, since we do not
2807 // encourage using macros to produce the names of entities.
2808
Douglas Gregor2ccccb32010-08-23 18:23:48 +00002809 HandleCodeCompleteResults(this, CodeCompleter,
2810 AllowNestedNameSpecifiers
2811 ? CodeCompletionContext::CCC_PotentiallyQualifiedName
2812 : CodeCompletionContext::CCC_Name,
2813 Results.data(), Results.size());
2814}
2815
Douglas Gregorfb629412010-08-23 21:17:50 +00002816struct Sema::CodeCompleteExpressionData {
2817 CodeCompleteExpressionData(QualType PreferredType = QualType())
2818 : PreferredType(PreferredType), IntegralConstantExpression(false),
2819 ObjCCollection(false) { }
2820
2821 QualType PreferredType;
2822 bool IntegralConstantExpression;
2823 bool ObjCCollection;
2824 llvm::SmallVector<Decl *, 4> IgnoreDecls;
2825};
2826
Douglas Gregor5ac3bdb2010-05-30 01:49:25 +00002827/// \brief Perform code-completion in an expression context when we know what
2828/// type we're looking for.
Douglas Gregorf9578432010-07-28 21:50:18 +00002829///
2830/// \param IntegralConstantExpression Only permit integral constant
2831/// expressions.
Douglas Gregorfb629412010-08-23 21:17:50 +00002832void Sema::CodeCompleteExpression(Scope *S,
2833 const CodeCompleteExpressionData &Data) {
John McCall0a2c5e22010-08-25 06:19:51 +00002834 typedef CodeCompletionResult Result;
Douglas Gregor5ac3bdb2010-05-30 01:49:25 +00002835 ResultBuilder Results(*this);
2836
Douglas Gregorfb629412010-08-23 21:17:50 +00002837 if (Data.ObjCCollection)
2838 Results.setFilter(&ResultBuilder::IsObjCCollection);
2839 else if (Data.IntegralConstantExpression)
Douglas Gregorf9578432010-07-28 21:50:18 +00002840 Results.setFilter(&ResultBuilder::IsIntegralConstantValue);
Douglas Gregore6b1bb62010-08-11 21:23:17 +00002841 else if (WantTypesInContext(PCC_Expression, getLangOptions()))
Douglas Gregor5ac3bdb2010-05-30 01:49:25 +00002842 Results.setFilter(&ResultBuilder::IsOrdinaryName);
2843 else
2844 Results.setFilter(&ResultBuilder::IsOrdinaryNonTypeName);
Douglas Gregorfb629412010-08-23 21:17:50 +00002845
2846 if (!Data.PreferredType.isNull())
2847 Results.setPreferredType(Data.PreferredType.getNonReferenceType());
2848
2849 // Ignore any declarations that we were told that we don't care about.
2850 for (unsigned I = 0, N = Data.IgnoreDecls.size(); I != N; ++I)
2851 Results.Ignore(Data.IgnoreDecls[I]);
Douglas Gregor5ac3bdb2010-05-30 01:49:25 +00002852
2853 CodeCompletionDeclConsumer Consumer(Results, CurContext);
Douglas Gregor8071e422010-08-15 06:18:01 +00002854 LookupVisibleDecls(S, LookupOrdinaryName, Consumer,
2855 CodeCompleter->includeGlobals());
Douglas Gregor5ac3bdb2010-05-30 01:49:25 +00002856
2857 Results.EnterNewScope();
Douglas Gregore6b1bb62010-08-11 21:23:17 +00002858 AddOrdinaryNameResults(PCC_Expression, S, *this, Results);
Douglas Gregor5ac3bdb2010-05-30 01:49:25 +00002859 Results.ExitScope();
2860
Douglas Gregor590c7d52010-07-08 20:55:51 +00002861 bool PreferredTypeIsPointer = false;
Douglas Gregorfb629412010-08-23 21:17:50 +00002862 if (!Data.PreferredType.isNull())
2863 PreferredTypeIsPointer = Data.PreferredType->isAnyPointerType()
2864 || Data.PreferredType->isMemberPointerType()
2865 || Data.PreferredType->isBlockPointerType();
Douglas Gregor590c7d52010-07-08 20:55:51 +00002866
Douglas Gregoraa5f77b2010-08-23 21:54:33 +00002867 if (S->getFnParent() &&
2868 !Data.ObjCCollection &&
2869 !Data.IntegralConstantExpression)
2870 AddPrettyFunctionResults(PP.getLangOptions(), Results);
2871
Douglas Gregor5ac3bdb2010-05-30 01:49:25 +00002872 if (CodeCompleter->includeMacros())
Douglas Gregor590c7d52010-07-08 20:55:51 +00002873 AddMacroResults(PP, Results, PreferredTypeIsPointer);
Douglas Gregore6b1bb62010-08-11 21:23:17 +00002874 HandleCodeCompleteResults(this, CodeCompleter,
Douglas Gregorfb629412010-08-23 21:17:50 +00002875 CodeCompletionContext(CodeCompletionContext::CCC_Expression,
2876 Data.PreferredType),
Douglas Gregore6b1bb62010-08-11 21:23:17 +00002877 Results.data(),Results.size());
Douglas Gregor5ac3bdb2010-05-30 01:49:25 +00002878}
2879
Douglas Gregorac5fd842010-09-18 01:28:11 +00002880void Sema::CodeCompletePostfixExpression(Scope *S, ExprResult E) {
2881 if (E.isInvalid())
2882 CodeCompleteOrdinaryName(S, PCC_RecoveryInFunction);
2883 else if (getLangOptions().ObjC1)
2884 CodeCompleteObjCInstanceMessage(S, E.take(), 0, 0, false);
Douglas Gregor78edf512010-09-15 16:23:04 +00002885}
Douglas Gregor5ac3bdb2010-05-30 01:49:25 +00002886
Douglas Gregor95ac6552009-11-18 01:29:26 +00002887static void AddObjCProperties(ObjCContainerDecl *Container,
Douglas Gregor322328b2009-11-18 22:32:06 +00002888 bool AllowCategories,
Douglas Gregor95ac6552009-11-18 01:29:26 +00002889 DeclContext *CurContext,
2890 ResultBuilder &Results) {
John McCall0a2c5e22010-08-25 06:19:51 +00002891 typedef CodeCompletionResult Result;
Douglas Gregor95ac6552009-11-18 01:29:26 +00002892
2893 // Add properties in this container.
2894 for (ObjCContainerDecl::prop_iterator P = Container->prop_begin(),
2895 PEnd = Container->prop_end();
2896 P != PEnd;
2897 ++P)
2898 Results.MaybeAddResult(Result(*P, 0), CurContext);
2899
2900 // Add properties in referenced protocols.
2901 if (ObjCProtocolDecl *Protocol = dyn_cast<ObjCProtocolDecl>(Container)) {
2902 for (ObjCProtocolDecl::protocol_iterator P = Protocol->protocol_begin(),
2903 PEnd = Protocol->protocol_end();
2904 P != PEnd; ++P)
Douglas Gregor322328b2009-11-18 22:32:06 +00002905 AddObjCProperties(*P, AllowCategories, CurContext, Results);
Douglas Gregor95ac6552009-11-18 01:29:26 +00002906 } else if (ObjCInterfaceDecl *IFace = dyn_cast<ObjCInterfaceDecl>(Container)){
Douglas Gregor322328b2009-11-18 22:32:06 +00002907 if (AllowCategories) {
2908 // Look through categories.
2909 for (ObjCCategoryDecl *Category = IFace->getCategoryList();
2910 Category; Category = Category->getNextClassCategory())
2911 AddObjCProperties(Category, AllowCategories, CurContext, Results);
2912 }
Douglas Gregor95ac6552009-11-18 01:29:26 +00002913
2914 // Look through protocols.
Ted Kremenek53b94412010-09-01 01:21:15 +00002915 for (ObjCInterfaceDecl::all_protocol_iterator
2916 I = IFace->all_referenced_protocol_begin(),
2917 E = IFace->all_referenced_protocol_end(); I != E; ++I)
Douglas Gregor322328b2009-11-18 22:32:06 +00002918 AddObjCProperties(*I, AllowCategories, CurContext, Results);
Douglas Gregor95ac6552009-11-18 01:29:26 +00002919
2920 // Look in the superclass.
2921 if (IFace->getSuperClass())
Douglas Gregor322328b2009-11-18 22:32:06 +00002922 AddObjCProperties(IFace->getSuperClass(), AllowCategories, CurContext,
2923 Results);
Douglas Gregor95ac6552009-11-18 01:29:26 +00002924 } else if (const ObjCCategoryDecl *Category
2925 = dyn_cast<ObjCCategoryDecl>(Container)) {
2926 // Look through protocols.
Ted Kremenek53b94412010-09-01 01:21:15 +00002927 for (ObjCCategoryDecl::protocol_iterator P = Category->protocol_begin(),
2928 PEnd = Category->protocol_end();
Douglas Gregor95ac6552009-11-18 01:29:26 +00002929 P != PEnd; ++P)
Douglas Gregor322328b2009-11-18 22:32:06 +00002930 AddObjCProperties(*P, AllowCategories, CurContext, Results);
Douglas Gregor95ac6552009-11-18 01:29:26 +00002931 }
2932}
2933
Douglas Gregor81b747b2009-09-17 21:32:03 +00002934void Sema::CodeCompleteMemberReferenceExpr(Scope *S, ExprTy *BaseE,
2935 SourceLocation OpLoc,
2936 bool IsArrow) {
2937 if (!BaseE || !CodeCompleter)
2938 return;
2939
John McCall0a2c5e22010-08-25 06:19:51 +00002940 typedef CodeCompletionResult Result;
Douglas Gregor86d9a522009-09-21 16:56:56 +00002941
Douglas Gregor81b747b2009-09-17 21:32:03 +00002942 Expr *Base = static_cast<Expr *>(BaseE);
2943 QualType BaseType = Base->getType();
Douglas Gregor86d9a522009-09-21 16:56:56 +00002944
2945 if (IsArrow) {
2946 if (const PointerType *Ptr = BaseType->getAs<PointerType>())
2947 BaseType = Ptr->getPointeeType();
2948 else if (BaseType->isObjCObjectPointerType())
Douglas Gregor3cdee122010-08-26 16:36:48 +00002949 /*Do nothing*/ ;
Douglas Gregor86d9a522009-09-21 16:56:56 +00002950 else
2951 return;
2952 }
2953
Douglas Gregoreb5758b2009-09-23 22:26:46 +00002954 ResultBuilder Results(*this, &ResultBuilder::IsMember);
Douglas Gregor95ac6552009-11-18 01:29:26 +00002955 Results.EnterNewScope();
2956 if (const RecordType *Record = BaseType->getAs<RecordType>()) {
Douglas Gregor3cdee122010-08-26 16:36:48 +00002957 // Indicate that we are performing a member access, and the cv-qualifiers
2958 // for the base object type.
2959 Results.setObjectTypeQualifiers(BaseType.getQualifiers());
2960
Douglas Gregor95ac6552009-11-18 01:29:26 +00002961 // Access to a C/C++ class, struct, or union.
Douglas Gregor45bcd432010-01-14 03:21:49 +00002962 Results.allowNestedNameSpecifiers();
Douglas Gregor0cc84042010-01-14 15:47:35 +00002963 CodeCompletionDeclConsumer Consumer(Results, CurContext);
Douglas Gregor8071e422010-08-15 06:18:01 +00002964 LookupVisibleDecls(Record->getDecl(), LookupMemberName, Consumer,
2965 CodeCompleter->includeGlobals());
Daniel Dunbar3a2838d2009-11-13 08:58:20 +00002966
Douglas Gregor95ac6552009-11-18 01:29:26 +00002967 if (getLangOptions().CPlusPlus) {
2968 if (!Results.empty()) {
2969 // The "template" keyword can follow "->" or "." in the grammar.
2970 // However, we only want to suggest the template keyword if something
2971 // is dependent.
2972 bool IsDependent = BaseType->isDependentType();
2973 if (!IsDependent) {
2974 for (Scope *DepScope = S; DepScope; DepScope = DepScope->getParent())
2975 if (DeclContext *Ctx = (DeclContext *)DepScope->getEntity()) {
2976 IsDependent = Ctx->isDependentContext();
2977 break;
2978 }
2979 }
Daniel Dunbar3a2838d2009-11-13 08:58:20 +00002980
Douglas Gregor95ac6552009-11-18 01:29:26 +00002981 if (IsDependent)
Douglas Gregora4477812010-01-14 16:01:26 +00002982 Results.AddResult(Result("template"));
Daniel Dunbar3a2838d2009-11-13 08:58:20 +00002983 }
Daniel Dunbar3a2838d2009-11-13 08:58:20 +00002984 }
Douglas Gregor95ac6552009-11-18 01:29:26 +00002985 } else if (!IsArrow && BaseType->getAsObjCInterfacePointerType()) {
2986 // Objective-C property reference.
2987
2988 // Add property results based on our interface.
2989 const ObjCObjectPointerType *ObjCPtr
2990 = BaseType->getAsObjCInterfacePointerType();
2991 assert(ObjCPtr && "Non-NULL pointer guaranteed above!");
Douglas Gregor322328b2009-11-18 22:32:06 +00002992 AddObjCProperties(ObjCPtr->getInterfaceDecl(), true, CurContext, Results);
Douglas Gregor95ac6552009-11-18 01:29:26 +00002993
2994 // Add properties from the protocols in a qualified interface.
2995 for (ObjCObjectPointerType::qual_iterator I = ObjCPtr->qual_begin(),
2996 E = ObjCPtr->qual_end();
2997 I != E; ++I)
Douglas Gregor322328b2009-11-18 22:32:06 +00002998 AddObjCProperties(*I, true, CurContext, Results);
Douglas Gregor95ac6552009-11-18 01:29:26 +00002999 } else if ((IsArrow && BaseType->isObjCObjectPointerType()) ||
John McCallc12c5bb2010-05-15 11:32:37 +00003000 (!IsArrow && BaseType->isObjCObjectType())) {
Douglas Gregor95ac6552009-11-18 01:29:26 +00003001 // Objective-C instance variable access.
3002 ObjCInterfaceDecl *Class = 0;
3003 if (const ObjCObjectPointerType *ObjCPtr
3004 = BaseType->getAs<ObjCObjectPointerType>())
3005 Class = ObjCPtr->getInterfaceDecl();
3006 else
John McCallc12c5bb2010-05-15 11:32:37 +00003007 Class = BaseType->getAs<ObjCObjectType>()->getInterface();
Douglas Gregor95ac6552009-11-18 01:29:26 +00003008
3009 // Add all ivars from this class and its superclasses.
Douglas Gregor80f4f4c2010-01-14 16:08:12 +00003010 if (Class) {
3011 CodeCompletionDeclConsumer Consumer(Results, CurContext);
3012 Results.setFilter(&ResultBuilder::IsObjCIvar);
Douglas Gregor8071e422010-08-15 06:18:01 +00003013 LookupVisibleDecls(Class, LookupMemberName, Consumer,
3014 CodeCompleter->includeGlobals());
Douglas Gregor95ac6552009-11-18 01:29:26 +00003015 }
Douglas Gregor86d9a522009-09-21 16:56:56 +00003016 }
Douglas Gregor95ac6552009-11-18 01:29:26 +00003017
3018 // FIXME: How do we cope with isa?
3019
3020 Results.ExitScope();
Daniel Dunbar3a2838d2009-11-13 08:58:20 +00003021
Daniel Dunbar3a2838d2009-11-13 08:58:20 +00003022 // Hand off the results found for code completion.
Douglas Gregore6b1bb62010-08-11 21:23:17 +00003023 HandleCodeCompleteResults(this, CodeCompleter,
3024 CodeCompletionContext(CodeCompletionContext::CCC_MemberAccess,
3025 BaseType),
3026 Results.data(),Results.size());
Douglas Gregor81b747b2009-09-17 21:32:03 +00003027}
3028
Douglas Gregor374929f2009-09-18 15:37:17 +00003029void Sema::CodeCompleteTag(Scope *S, unsigned TagSpec) {
3030 if (!CodeCompleter)
3031 return;
3032
John McCall0a2c5e22010-08-25 06:19:51 +00003033 typedef CodeCompletionResult Result;
Douglas Gregor86d9a522009-09-21 16:56:56 +00003034 ResultBuilder::LookupFilter Filter = 0;
Douglas Gregore6b1bb62010-08-11 21:23:17 +00003035 enum CodeCompletionContext::Kind ContextKind
3036 = CodeCompletionContext::CCC_Other;
Douglas Gregor374929f2009-09-18 15:37:17 +00003037 switch ((DeclSpec::TST)TagSpec) {
3038 case DeclSpec::TST_enum:
Douglas Gregor86d9a522009-09-21 16:56:56 +00003039 Filter = &ResultBuilder::IsEnum;
Douglas Gregore6b1bb62010-08-11 21:23:17 +00003040 ContextKind = CodeCompletionContext::CCC_EnumTag;
Douglas Gregor374929f2009-09-18 15:37:17 +00003041 break;
3042
3043 case DeclSpec::TST_union:
Douglas Gregor86d9a522009-09-21 16:56:56 +00003044 Filter = &ResultBuilder::IsUnion;
Douglas Gregore6b1bb62010-08-11 21:23:17 +00003045 ContextKind = CodeCompletionContext::CCC_UnionTag;
Douglas Gregor374929f2009-09-18 15:37:17 +00003046 break;
3047
3048 case DeclSpec::TST_struct:
Douglas Gregor374929f2009-09-18 15:37:17 +00003049 case DeclSpec::TST_class:
Douglas Gregor86d9a522009-09-21 16:56:56 +00003050 Filter = &ResultBuilder::IsClassOrStruct;
Douglas Gregore6b1bb62010-08-11 21:23:17 +00003051 ContextKind = CodeCompletionContext::CCC_ClassOrStructTag;
Douglas Gregor374929f2009-09-18 15:37:17 +00003052 break;
3053
3054 default:
3055 assert(false && "Unknown type specifier kind in CodeCompleteTag");
3056 return;
3057 }
Douglas Gregor86d9a522009-09-21 16:56:56 +00003058
John McCall0d6b1642010-04-23 18:46:30 +00003059 ResultBuilder Results(*this);
Douglas Gregor5d2fc402010-01-14 03:27:13 +00003060 CodeCompletionDeclConsumer Consumer(Results, CurContext);
John McCall0d6b1642010-04-23 18:46:30 +00003061
3062 // First pass: look for tags.
3063 Results.setFilter(Filter);
Douglas Gregor8071e422010-08-15 06:18:01 +00003064 LookupVisibleDecls(S, LookupTagName, Consumer,
3065 CodeCompleter->includeGlobals());
John McCall0d6b1642010-04-23 18:46:30 +00003066
Douglas Gregor8071e422010-08-15 06:18:01 +00003067 if (CodeCompleter->includeGlobals()) {
3068 // Second pass: look for nested name specifiers.
3069 Results.setFilter(&ResultBuilder::IsNestedNameSpecifier);
3070 LookupVisibleDecls(S, LookupNestedNameSpecifierName, Consumer);
3071 }
Douglas Gregor86d9a522009-09-21 16:56:56 +00003072
Douglas Gregore6b1bb62010-08-11 21:23:17 +00003073 HandleCodeCompleteResults(this, CodeCompleter, ContextKind,
3074 Results.data(),Results.size());
Douglas Gregor374929f2009-09-18 15:37:17 +00003075}
3076
Douglas Gregor1a480c42010-08-27 17:35:51 +00003077void Sema::CodeCompleteTypeQualifiers(DeclSpec &DS) {
3078 ResultBuilder Results(*this);
3079 Results.EnterNewScope();
3080 if (!(DS.getTypeQualifiers() & DeclSpec::TQ_const))
3081 Results.AddResult("const");
3082 if (!(DS.getTypeQualifiers() & DeclSpec::TQ_volatile))
3083 Results.AddResult("volatile");
3084 if (getLangOptions().C99 &&
3085 !(DS.getTypeQualifiers() & DeclSpec::TQ_restrict))
3086 Results.AddResult("restrict");
3087 Results.ExitScope();
3088 HandleCodeCompleteResults(this, CodeCompleter,
3089 CodeCompletionContext::CCC_TypeQualifiers,
3090 Results.data(), Results.size());
3091}
3092
Douglas Gregor3e1005f2009-09-21 18:10:23 +00003093void Sema::CodeCompleteCase(Scope *S) {
John McCall781472f2010-08-25 08:40:02 +00003094 if (getCurFunction()->SwitchStack.empty() || !CodeCompleter)
Douglas Gregor3e1005f2009-09-21 18:10:23 +00003095 return;
3096
John McCall781472f2010-08-25 08:40:02 +00003097 SwitchStmt *Switch = getCurFunction()->SwitchStack.back();
Douglas Gregorf9578432010-07-28 21:50:18 +00003098 if (!Switch->getCond()->getType()->isEnumeralType()) {
Douglas Gregorfb629412010-08-23 21:17:50 +00003099 CodeCompleteExpressionData Data(Switch->getCond()->getType());
3100 Data.IntegralConstantExpression = true;
3101 CodeCompleteExpression(S, Data);
Douglas Gregor3e1005f2009-09-21 18:10:23 +00003102 return;
Douglas Gregorf9578432010-07-28 21:50:18 +00003103 }
Douglas Gregor3e1005f2009-09-21 18:10:23 +00003104
3105 // Code-complete the cases of a switch statement over an enumeration type
3106 // by providing the list of
3107 EnumDecl *Enum = Switch->getCond()->getType()->getAs<EnumType>()->getDecl();
3108
3109 // Determine which enumerators we have already seen in the switch statement.
3110 // FIXME: Ideally, we would also be able to look *past* the code-completion
3111 // token, in case we are code-completing in the middle of the switch and not
3112 // at the end. However, we aren't able to do so at the moment.
3113 llvm::SmallPtrSet<EnumConstantDecl *, 8> EnumeratorsSeen;
Douglas Gregorb9d0ef72009-09-21 19:57:38 +00003114 NestedNameSpecifier *Qualifier = 0;
Douglas Gregor3e1005f2009-09-21 18:10:23 +00003115 for (SwitchCase *SC = Switch->getSwitchCaseList(); SC;
3116 SC = SC->getNextSwitchCase()) {
3117 CaseStmt *Case = dyn_cast<CaseStmt>(SC);
3118 if (!Case)
3119 continue;
3120
3121 Expr *CaseVal = Case->getLHS()->IgnoreParenCasts();
3122 if (DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(CaseVal))
3123 if (EnumConstantDecl *Enumerator
3124 = dyn_cast<EnumConstantDecl>(DRE->getDecl())) {
3125 // We look into the AST of the case statement to determine which
3126 // enumerator was named. Alternatively, we could compute the value of
3127 // the integral constant expression, then compare it against the
3128 // values of each enumerator. However, value-based approach would not
3129 // work as well with C++ templates where enumerators declared within a
3130 // template are type- and value-dependent.
3131 EnumeratorsSeen.insert(Enumerator);
3132
Douglas Gregorb9d0ef72009-09-21 19:57:38 +00003133 // If this is a qualified-id, keep track of the nested-name-specifier
3134 // so that we can reproduce it as part of code completion, e.g.,
Douglas Gregor3e1005f2009-09-21 18:10:23 +00003135 //
3136 // switch (TagD.getKind()) {
3137 // case TagDecl::TK_enum:
3138 // break;
3139 // case XXX
3140 //
Douglas Gregorb9d0ef72009-09-21 19:57:38 +00003141 // At the XXX, our completions are TagDecl::TK_union,
Douglas Gregor3e1005f2009-09-21 18:10:23 +00003142 // TagDecl::TK_struct, and TagDecl::TK_class, rather than TK_union,
3143 // TK_struct, and TK_class.
Douglas Gregora2813ce2009-10-23 18:54:35 +00003144 Qualifier = DRE->getQualifier();
Douglas Gregor3e1005f2009-09-21 18:10:23 +00003145 }
3146 }
3147
Douglas Gregorb9d0ef72009-09-21 19:57:38 +00003148 if (getLangOptions().CPlusPlus && !Qualifier && EnumeratorsSeen.empty()) {
3149 // If there are no prior enumerators in C++, check whether we have to
3150 // qualify the names of the enumerators that we suggest, because they
3151 // may not be visible in this scope.
3152 Qualifier = getRequiredQualification(Context, CurContext,
3153 Enum->getDeclContext());
3154
3155 // FIXME: Scoped enums need to start with "EnumDecl" as the context!
3156 }
3157
Douglas Gregor3e1005f2009-09-21 18:10:23 +00003158 // Add any enumerators that have not yet been mentioned.
3159 ResultBuilder Results(*this);
3160 Results.EnterNewScope();
3161 for (EnumDecl::enumerator_iterator E = Enum->enumerator_begin(),
3162 EEnd = Enum->enumerator_end();
3163 E != EEnd; ++E) {
3164 if (EnumeratorsSeen.count(*E))
3165 continue;
3166
John McCall0a2c5e22010-08-25 06:19:51 +00003167 Results.AddResult(CodeCompletionResult(*E, Qualifier),
Douglas Gregor608300b2010-01-14 16:14:35 +00003168 CurContext, 0, false);
Douglas Gregor3e1005f2009-09-21 18:10:23 +00003169 }
3170 Results.ExitScope();
Douglas Gregor2f880e42010-04-06 20:02:15 +00003171
Douglas Gregor0c8296d2009-11-07 00:00:49 +00003172 if (CodeCompleter->includeMacros())
Douglas Gregorbca403c2010-01-13 23:51:12 +00003173 AddMacroResults(PP, Results);
Douglas Gregore6b1bb62010-08-11 21:23:17 +00003174 HandleCodeCompleteResults(this, CodeCompleter,
3175 CodeCompletionContext::CCC_Expression,
3176 Results.data(),Results.size());
Douglas Gregor3e1005f2009-09-21 18:10:23 +00003177}
3178
Douglas Gregor9c6a0e92009-09-22 15:41:20 +00003179namespace {
3180 struct IsBetterOverloadCandidate {
3181 Sema &S;
John McCall5769d612010-02-08 23:07:23 +00003182 SourceLocation Loc;
Douglas Gregor9c6a0e92009-09-22 15:41:20 +00003183
3184 public:
John McCall5769d612010-02-08 23:07:23 +00003185 explicit IsBetterOverloadCandidate(Sema &S, SourceLocation Loc)
3186 : S(S), Loc(Loc) { }
Douglas Gregor9c6a0e92009-09-22 15:41:20 +00003187
3188 bool
3189 operator()(const OverloadCandidate &X, const OverloadCandidate &Y) const {
John McCall120d63c2010-08-24 20:38:10 +00003190 return isBetterOverloadCandidate(S, X, Y, Loc);
Douglas Gregor9c6a0e92009-09-22 15:41:20 +00003191 }
3192 };
3193}
3194
Douglas Gregord28dcd72010-05-30 06:10:08 +00003195static bool anyNullArguments(Expr **Args, unsigned NumArgs) {
3196 if (NumArgs && !Args)
3197 return true;
3198
3199 for (unsigned I = 0; I != NumArgs; ++I)
3200 if (!Args[I])
3201 return true;
3202
3203 return false;
3204}
3205
Douglas Gregor9c6a0e92009-09-22 15:41:20 +00003206void Sema::CodeCompleteCall(Scope *S, ExprTy *FnIn,
3207 ExprTy **ArgsIn, unsigned NumArgs) {
3208 if (!CodeCompleter)
3209 return;
Douglas Gregoref96eac2009-12-11 19:06:04 +00003210
3211 // When we're code-completing for a call, we fall back to ordinary
3212 // name code-completion whenever we can't produce specific
3213 // results. We may want to revisit this strategy in the future,
3214 // e.g., by merging the two kinds of results.
3215
Douglas Gregor9c6a0e92009-09-22 15:41:20 +00003216 Expr *Fn = (Expr *)FnIn;
3217 Expr **Args = (Expr **)ArgsIn;
Douglas Gregoref96eac2009-12-11 19:06:04 +00003218
Douglas Gregor9c6a0e92009-09-22 15:41:20 +00003219 // Ignore type-dependent call expressions entirely.
Douglas Gregord28dcd72010-05-30 06:10:08 +00003220 if (!Fn || Fn->isTypeDependent() || anyNullArguments(Args, NumArgs) ||
Douglas Gregoref96eac2009-12-11 19:06:04 +00003221 Expr::hasAnyTypeDependentArguments(Args, NumArgs)) {
Douglas Gregore6b1bb62010-08-11 21:23:17 +00003222 CodeCompleteOrdinaryName(S, PCC_Expression);
Douglas Gregor9c6a0e92009-09-22 15:41:20 +00003223 return;
Douglas Gregoref96eac2009-12-11 19:06:04 +00003224 }
Douglas Gregor9c6a0e92009-09-22 15:41:20 +00003225
John McCall3b4294e2009-12-16 12:17:52 +00003226 // Build an overload candidate set based on the functions we find.
John McCall5769d612010-02-08 23:07:23 +00003227 SourceLocation Loc = Fn->getExprLoc();
3228 OverloadCandidateSet CandidateSet(Loc);
John McCall3b4294e2009-12-16 12:17:52 +00003229
Douglas Gregor9c6a0e92009-09-22 15:41:20 +00003230 // FIXME: What if we're calling something that isn't a function declaration?
3231 // FIXME: What if we're calling a pseudo-destructor?
3232 // FIXME: What if we're calling a member function?
3233
Douglas Gregorc0265402010-01-21 15:46:19 +00003234 typedef CodeCompleteConsumer::OverloadCandidate ResultCandidate;
3235 llvm::SmallVector<ResultCandidate, 8> Results;
3236
John McCall3b4294e2009-12-16 12:17:52 +00003237 Expr *NakedFn = Fn->IgnoreParenCasts();
3238 if (UnresolvedLookupExpr *ULE = dyn_cast<UnresolvedLookupExpr>(NakedFn))
3239 AddOverloadedCallCandidates(ULE, Args, NumArgs, CandidateSet,
3240 /*PartialOverloading=*/ true);
3241 else if (DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(NakedFn)) {
3242 FunctionDecl *FDecl = dyn_cast<FunctionDecl>(DRE->getDecl());
Douglas Gregorc0265402010-01-21 15:46:19 +00003243 if (FDecl) {
Douglas Gregord28dcd72010-05-30 06:10:08 +00003244 if (!getLangOptions().CPlusPlus ||
3245 !FDecl->getType()->getAs<FunctionProtoType>())
Douglas Gregorc0265402010-01-21 15:46:19 +00003246 Results.push_back(ResultCandidate(FDecl));
3247 else
John McCall86820f52010-01-26 01:37:31 +00003248 // FIXME: access?
John McCall9aa472c2010-03-19 07:35:19 +00003249 AddOverloadCandidate(FDecl, DeclAccessPair::make(FDecl, AS_none),
3250 Args, NumArgs, CandidateSet,
Douglas Gregorc27d6c52010-04-16 17:41:49 +00003251 false, /*PartialOverloading*/true);
Douglas Gregorc0265402010-01-21 15:46:19 +00003252 }
John McCall3b4294e2009-12-16 12:17:52 +00003253 }
Douglas Gregor9c6a0e92009-09-22 15:41:20 +00003254
Douglas Gregor5ac3bdb2010-05-30 01:49:25 +00003255 QualType ParamType;
3256
Douglas Gregorc0265402010-01-21 15:46:19 +00003257 if (!CandidateSet.empty()) {
3258 // Sort the overload candidate set by placing the best overloads first.
3259 std::stable_sort(CandidateSet.begin(), CandidateSet.end(),
John McCall5769d612010-02-08 23:07:23 +00003260 IsBetterOverloadCandidate(*this, Loc));
Douglas Gregor9c6a0e92009-09-22 15:41:20 +00003261
Douglas Gregorc0265402010-01-21 15:46:19 +00003262 // Add the remaining viable overload candidates as code-completion reslults.
3263 for (OverloadCandidateSet::iterator Cand = CandidateSet.begin(),
3264 CandEnd = CandidateSet.end();
3265 Cand != CandEnd; ++Cand) {
3266 if (Cand->Viable)
3267 Results.push_back(ResultCandidate(Cand->Function));
3268 }
Douglas Gregor5ac3bdb2010-05-30 01:49:25 +00003269
3270 // From the viable candidates, try to determine the type of this parameter.
3271 for (unsigned I = 0, N = Results.size(); I != N; ++I) {
3272 if (const FunctionType *FType = Results[I].getFunctionType())
3273 if (const FunctionProtoType *Proto = dyn_cast<FunctionProtoType>(FType))
3274 if (NumArgs < Proto->getNumArgs()) {
3275 if (ParamType.isNull())
3276 ParamType = Proto->getArgType(NumArgs);
3277 else if (!Context.hasSameUnqualifiedType(
3278 ParamType.getNonReferenceType(),
3279 Proto->getArgType(NumArgs).getNonReferenceType())) {
3280 ParamType = QualType();
3281 break;
3282 }
3283 }
3284 }
3285 } else {
3286 // Try to determine the parameter type from the type of the expression
3287 // being called.
3288 QualType FunctionType = Fn->getType();
3289 if (const PointerType *Ptr = FunctionType->getAs<PointerType>())
3290 FunctionType = Ptr->getPointeeType();
3291 else if (const BlockPointerType *BlockPtr
3292 = FunctionType->getAs<BlockPointerType>())
3293 FunctionType = BlockPtr->getPointeeType();
3294 else if (const MemberPointerType *MemPtr
3295 = FunctionType->getAs<MemberPointerType>())
3296 FunctionType = MemPtr->getPointeeType();
3297
3298 if (const FunctionProtoType *Proto
3299 = FunctionType->getAs<FunctionProtoType>()) {
3300 if (NumArgs < Proto->getNumArgs())
3301 ParamType = Proto->getArgType(NumArgs);
3302 }
Douglas Gregor9c6a0e92009-09-22 15:41:20 +00003303 }
Douglas Gregoref96eac2009-12-11 19:06:04 +00003304
Douglas Gregor5ac3bdb2010-05-30 01:49:25 +00003305 if (ParamType.isNull())
Douglas Gregore6b1bb62010-08-11 21:23:17 +00003306 CodeCompleteOrdinaryName(S, PCC_Expression);
Douglas Gregor5ac3bdb2010-05-30 01:49:25 +00003307 else
3308 CodeCompleteExpression(S, ParamType);
3309
Douglas Gregor2e4c7a52010-04-06 20:19:47 +00003310 if (!Results.empty())
Douglas Gregoref96eac2009-12-11 19:06:04 +00003311 CodeCompleter->ProcessOverloadCandidates(*this, NumArgs, Results.data(),
3312 Results.size());
Douglas Gregor9c6a0e92009-09-22 15:41:20 +00003313}
3314
John McCalld226f652010-08-21 09:40:31 +00003315void Sema::CodeCompleteInitializer(Scope *S, Decl *D) {
3316 ValueDecl *VD = dyn_cast_or_null<ValueDecl>(D);
Douglas Gregor5ac3bdb2010-05-30 01:49:25 +00003317 if (!VD) {
Douglas Gregore6b1bb62010-08-11 21:23:17 +00003318 CodeCompleteOrdinaryName(S, PCC_Expression);
Douglas Gregor5ac3bdb2010-05-30 01:49:25 +00003319 return;
3320 }
3321
3322 CodeCompleteExpression(S, VD->getType());
3323}
3324
3325void Sema::CodeCompleteReturn(Scope *S) {
3326 QualType ResultType;
3327 if (isa<BlockDecl>(CurContext)) {
3328 if (BlockScopeInfo *BSI = getCurBlock())
3329 ResultType = BSI->ReturnType;
3330 } else if (FunctionDecl *Function = dyn_cast<FunctionDecl>(CurContext))
3331 ResultType = Function->getResultType();
3332 else if (ObjCMethodDecl *Method = dyn_cast<ObjCMethodDecl>(CurContext))
3333 ResultType = Method->getResultType();
3334
3335 if (ResultType.isNull())
Douglas Gregore6b1bb62010-08-11 21:23:17 +00003336 CodeCompleteOrdinaryName(S, PCC_Expression);
Douglas Gregor5ac3bdb2010-05-30 01:49:25 +00003337 else
3338 CodeCompleteExpression(S, ResultType);
3339}
3340
3341void Sema::CodeCompleteAssignmentRHS(Scope *S, ExprTy *LHS) {
3342 if (LHS)
3343 CodeCompleteExpression(S, static_cast<Expr *>(LHS)->getType());
3344 else
Douglas Gregore6b1bb62010-08-11 21:23:17 +00003345 CodeCompleteOrdinaryName(S, PCC_Expression);
Douglas Gregor5ac3bdb2010-05-30 01:49:25 +00003346}
3347
Jeffrey Yasskin9ab14542010-04-08 16:38:48 +00003348void Sema::CodeCompleteQualifiedId(Scope *S, CXXScopeSpec &SS,
Douglas Gregor81b747b2009-09-17 21:32:03 +00003349 bool EnteringContext) {
3350 if (!SS.getScopeRep() || !CodeCompleter)
3351 return;
3352
Douglas Gregor86d9a522009-09-21 16:56:56 +00003353 DeclContext *Ctx = computeDeclContext(SS, EnteringContext);
3354 if (!Ctx)
3355 return;
Douglas Gregord1cd31a2009-12-11 18:28:39 +00003356
3357 // Try to instantiate any non-dependent declaration contexts before
3358 // we look in them.
John McCall77bb1aa2010-05-01 00:40:08 +00003359 if (!isDependentScopeSpecifier(SS) && RequireCompleteDeclContext(SS, Ctx))
Douglas Gregord1cd31a2009-12-11 18:28:39 +00003360 return;
3361
Douglas Gregor86d9a522009-09-21 16:56:56 +00003362 ResultBuilder Results(*this);
Douglas Gregor86d9a522009-09-21 16:56:56 +00003363
Douglas Gregorf6961522010-08-27 21:18:54 +00003364 Results.EnterNewScope();
Douglas Gregor86d9a522009-09-21 16:56:56 +00003365 // The "template" keyword can follow "::" in the grammar, but only
3366 // put it into the grammar if the nested-name-specifier is dependent.
3367 NestedNameSpecifier *NNS = (NestedNameSpecifier *)SS.getScopeRep();
3368 if (!Results.empty() && NNS->isDependent())
Douglas Gregora4477812010-01-14 16:01:26 +00003369 Results.AddResult("template");
Douglas Gregorf6961522010-08-27 21:18:54 +00003370
3371 // Add calls to overridden virtual functions, if there are any.
3372 //
3373 // FIXME: This isn't wonderful, because we don't know whether we're actually
3374 // in a context that permits expressions. This is a general issue with
3375 // qualified-id completions.
3376 if (!EnteringContext)
3377 MaybeAddOverrideCalls(*this, Ctx, Results);
3378 Results.ExitScope();
Douglas Gregor86d9a522009-09-21 16:56:56 +00003379
Douglas Gregorf6961522010-08-27 21:18:54 +00003380 CodeCompletionDeclConsumer Consumer(Results, CurContext);
3381 LookupVisibleDecls(Ctx, LookupOrdinaryName, Consumer);
3382
Douglas Gregore6b1bb62010-08-11 21:23:17 +00003383 HandleCodeCompleteResults(this, CodeCompleter,
Douglas Gregorf6961522010-08-27 21:18:54 +00003384 CodeCompletionContext::CCC_Name,
Douglas Gregore6b1bb62010-08-11 21:23:17 +00003385 Results.data(),Results.size());
Douglas Gregor81b747b2009-09-17 21:32:03 +00003386}
Douglas Gregor49f40bd2009-09-18 19:03:04 +00003387
3388void Sema::CodeCompleteUsing(Scope *S) {
3389 if (!CodeCompleter)
3390 return;
3391
Douglas Gregor86d9a522009-09-21 16:56:56 +00003392 ResultBuilder Results(*this, &ResultBuilder::IsNestedNameSpecifier);
Douglas Gregor8e0a0e42009-09-22 23:31:26 +00003393 Results.EnterNewScope();
Douglas Gregor86d9a522009-09-21 16:56:56 +00003394
3395 // If we aren't in class scope, we could see the "namespace" keyword.
3396 if (!S->isClassScope())
John McCall0a2c5e22010-08-25 06:19:51 +00003397 Results.AddResult(CodeCompletionResult("namespace"));
Douglas Gregor86d9a522009-09-21 16:56:56 +00003398
3399 // After "using", we can see anything that would start a
3400 // nested-name-specifier.
Douglas Gregor5d2fc402010-01-14 03:27:13 +00003401 CodeCompletionDeclConsumer Consumer(Results, CurContext);
Douglas Gregor8071e422010-08-15 06:18:01 +00003402 LookupVisibleDecls(S, LookupOrdinaryName, Consumer,
3403 CodeCompleter->includeGlobals());
Douglas Gregor8e0a0e42009-09-22 23:31:26 +00003404 Results.ExitScope();
Douglas Gregor86d9a522009-09-21 16:56:56 +00003405
Douglas Gregore6b1bb62010-08-11 21:23:17 +00003406 HandleCodeCompleteResults(this, CodeCompleter,
3407 CodeCompletionContext::CCC_Other,
3408 Results.data(),Results.size());
Douglas Gregor49f40bd2009-09-18 19:03:04 +00003409}
3410
3411void Sema::CodeCompleteUsingDirective(Scope *S) {
3412 if (!CodeCompleter)
3413 return;
3414
Douglas Gregor86d9a522009-09-21 16:56:56 +00003415 // After "using namespace", we expect to see a namespace name or namespace
3416 // alias.
3417 ResultBuilder Results(*this, &ResultBuilder::IsNamespaceOrAlias);
Douglas Gregor8e0a0e42009-09-22 23:31:26 +00003418 Results.EnterNewScope();
Douglas Gregor5d2fc402010-01-14 03:27:13 +00003419 CodeCompletionDeclConsumer Consumer(Results, CurContext);
Douglas Gregor8071e422010-08-15 06:18:01 +00003420 LookupVisibleDecls(S, LookupOrdinaryName, Consumer,
3421 CodeCompleter->includeGlobals());
Douglas Gregor8e0a0e42009-09-22 23:31:26 +00003422 Results.ExitScope();
Douglas Gregore6b1bb62010-08-11 21:23:17 +00003423 HandleCodeCompleteResults(this, CodeCompleter,
Douglas Gregor8071e422010-08-15 06:18:01 +00003424 CodeCompletionContext::CCC_Namespace,
Douglas Gregore6b1bb62010-08-11 21:23:17 +00003425 Results.data(),Results.size());
Douglas Gregor49f40bd2009-09-18 19:03:04 +00003426}
3427
3428void Sema::CodeCompleteNamespaceDecl(Scope *S) {
3429 if (!CodeCompleter)
3430 return;
3431
Douglas Gregor86d9a522009-09-21 16:56:56 +00003432 ResultBuilder Results(*this, &ResultBuilder::IsNamespace);
3433 DeclContext *Ctx = (DeclContext *)S->getEntity();
3434 if (!S->getParent())
3435 Ctx = Context.getTranslationUnitDecl();
3436
3437 if (Ctx && Ctx->isFileContext()) {
3438 // We only want to see those namespaces that have already been defined
3439 // within this scope, because its likely that the user is creating an
3440 // extended namespace declaration. Keep track of the most recent
3441 // definition of each namespace.
3442 std::map<NamespaceDecl *, NamespaceDecl *> OrigToLatest;
3443 for (DeclContext::specific_decl_iterator<NamespaceDecl>
3444 NS(Ctx->decls_begin()), NSEnd(Ctx->decls_end());
3445 NS != NSEnd; ++NS)
3446 OrigToLatest[NS->getOriginalNamespace()] = *NS;
3447
3448 // Add the most recent definition (or extended definition) of each
3449 // namespace to the list of results.
Douglas Gregor8e0a0e42009-09-22 23:31:26 +00003450 Results.EnterNewScope();
Douglas Gregor86d9a522009-09-21 16:56:56 +00003451 for (std::map<NamespaceDecl *, NamespaceDecl *>::iterator
3452 NS = OrigToLatest.begin(), NSEnd = OrigToLatest.end();
3453 NS != NSEnd; ++NS)
John McCall0a2c5e22010-08-25 06:19:51 +00003454 Results.AddResult(CodeCompletionResult(NS->second, 0),
Douglas Gregor608300b2010-01-14 16:14:35 +00003455 CurContext, 0, false);
Douglas Gregor8e0a0e42009-09-22 23:31:26 +00003456 Results.ExitScope();
Douglas Gregor86d9a522009-09-21 16:56:56 +00003457 }
3458
Douglas Gregore6b1bb62010-08-11 21:23:17 +00003459 HandleCodeCompleteResults(this, CodeCompleter,
3460 CodeCompletionContext::CCC_Other,
3461 Results.data(),Results.size());
Douglas Gregor49f40bd2009-09-18 19:03:04 +00003462}
3463
3464void Sema::CodeCompleteNamespaceAliasDecl(Scope *S) {
3465 if (!CodeCompleter)
3466 return;
3467
Douglas Gregor86d9a522009-09-21 16:56:56 +00003468 // After "namespace", we expect to see a namespace or alias.
3469 ResultBuilder Results(*this, &ResultBuilder::IsNamespaceOrAlias);
Douglas Gregor5d2fc402010-01-14 03:27:13 +00003470 CodeCompletionDeclConsumer Consumer(Results, CurContext);
Douglas Gregor8071e422010-08-15 06:18:01 +00003471 LookupVisibleDecls(S, LookupOrdinaryName, Consumer,
3472 CodeCompleter->includeGlobals());
Douglas Gregore6b1bb62010-08-11 21:23:17 +00003473 HandleCodeCompleteResults(this, CodeCompleter,
Douglas Gregor8071e422010-08-15 06:18:01 +00003474 CodeCompletionContext::CCC_Namespace,
Douglas Gregore6b1bb62010-08-11 21:23:17 +00003475 Results.data(),Results.size());
Douglas Gregor49f40bd2009-09-18 19:03:04 +00003476}
3477
Douglas Gregored8d3222009-09-18 20:05:18 +00003478void Sema::CodeCompleteOperatorName(Scope *S) {
3479 if (!CodeCompleter)
3480 return;
Douglas Gregor86d9a522009-09-21 16:56:56 +00003481
John McCall0a2c5e22010-08-25 06:19:51 +00003482 typedef CodeCompletionResult Result;
Douglas Gregor86d9a522009-09-21 16:56:56 +00003483 ResultBuilder Results(*this, &ResultBuilder::IsType);
Douglas Gregor8e0a0e42009-09-22 23:31:26 +00003484 Results.EnterNewScope();
Douglas Gregored8d3222009-09-18 20:05:18 +00003485
Douglas Gregor86d9a522009-09-21 16:56:56 +00003486 // Add the names of overloadable operators.
3487#define OVERLOADED_OPERATOR(Name,Spelling,Token,Unary,Binary,MemberOnly) \
3488 if (std::strcmp(Spelling, "?")) \
Douglas Gregora4477812010-01-14 16:01:26 +00003489 Results.AddResult(Result(Spelling));
Douglas Gregor86d9a522009-09-21 16:56:56 +00003490#include "clang/Basic/OperatorKinds.def"
3491
3492 // Add any type names visible from the current scope
Douglas Gregor45bcd432010-01-14 03:21:49 +00003493 Results.allowNestedNameSpecifiers();
Douglas Gregor5d2fc402010-01-14 03:27:13 +00003494 CodeCompletionDeclConsumer Consumer(Results, CurContext);
Douglas Gregor8071e422010-08-15 06:18:01 +00003495 LookupVisibleDecls(S, LookupOrdinaryName, Consumer,
3496 CodeCompleter->includeGlobals());
Douglas Gregor86d9a522009-09-21 16:56:56 +00003497
3498 // Add any type specifiers
Douglas Gregorbca403c2010-01-13 23:51:12 +00003499 AddTypeSpecifierResults(getLangOptions(), Results);
Douglas Gregor8e0a0e42009-09-22 23:31:26 +00003500 Results.ExitScope();
Douglas Gregor86d9a522009-09-21 16:56:56 +00003501
Douglas Gregore6b1bb62010-08-11 21:23:17 +00003502 HandleCodeCompleteResults(this, CodeCompleter,
Douglas Gregor8071e422010-08-15 06:18:01 +00003503 CodeCompletionContext::CCC_Type,
Douglas Gregore6b1bb62010-08-11 21:23:17 +00003504 Results.data(),Results.size());
Douglas Gregored8d3222009-09-18 20:05:18 +00003505}
Douglas Gregor49f40bd2009-09-18 19:03:04 +00003506
Douglas Gregor0133f522010-08-28 00:00:50 +00003507void Sema::CodeCompleteConstructorInitializer(Decl *ConstructorD,
3508 CXXBaseOrMemberInitializer** Initializers,
3509 unsigned NumInitializers) {
3510 CXXConstructorDecl *Constructor
3511 = static_cast<CXXConstructorDecl *>(ConstructorD);
3512 if (!Constructor)
3513 return;
3514
3515 ResultBuilder Results(*this);
3516 Results.EnterNewScope();
3517
3518 // Fill in any already-initialized fields or base classes.
3519 llvm::SmallPtrSet<FieldDecl *, 4> InitializedFields;
3520 llvm::SmallPtrSet<CanQualType, 4> InitializedBases;
3521 for (unsigned I = 0; I != NumInitializers; ++I) {
3522 if (Initializers[I]->isBaseInitializer())
3523 InitializedBases.insert(
3524 Context.getCanonicalType(QualType(Initializers[I]->getBaseClass(), 0)));
3525 else
3526 InitializedFields.insert(cast<FieldDecl>(Initializers[I]->getMember()));
3527 }
3528
3529 // Add completions for base classes.
Douglas Gregor0c431c82010-08-29 19:27:27 +00003530 bool SawLastInitializer = (NumInitializers == 0);
Douglas Gregor0133f522010-08-28 00:00:50 +00003531 CXXRecordDecl *ClassDecl = Constructor->getParent();
3532 for (CXXRecordDecl::base_class_iterator Base = ClassDecl->bases_begin(),
3533 BaseEnd = ClassDecl->bases_end();
3534 Base != BaseEnd; ++Base) {
Douglas Gregor0c431c82010-08-29 19:27:27 +00003535 if (!InitializedBases.insert(Context.getCanonicalType(Base->getType()))) {
3536 SawLastInitializer
3537 = NumInitializers > 0 &&
3538 Initializers[NumInitializers - 1]->isBaseInitializer() &&
3539 Context.hasSameUnqualifiedType(Base->getType(),
3540 QualType(Initializers[NumInitializers - 1]->getBaseClass(), 0));
Douglas Gregor0133f522010-08-28 00:00:50 +00003541 continue;
Douglas Gregor0c431c82010-08-29 19:27:27 +00003542 }
Douglas Gregor0133f522010-08-28 00:00:50 +00003543
3544 CodeCompletionString *Pattern = new CodeCompletionString;
3545 Pattern->AddTypedTextChunk(
3546 Base->getType().getAsString(Context.PrintingPolicy));
3547 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
3548 Pattern->AddPlaceholderChunk("args");
3549 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
Douglas Gregor0c431c82010-08-29 19:27:27 +00003550 Results.AddResult(CodeCompletionResult(Pattern,
3551 SawLastInitializer? CCP_NextInitializer
3552 : CCP_MemberDeclaration));
3553 SawLastInitializer = false;
Douglas Gregor0133f522010-08-28 00:00:50 +00003554 }
3555
3556 // Add completions for virtual base classes.
3557 for (CXXRecordDecl::base_class_iterator Base = ClassDecl->vbases_begin(),
3558 BaseEnd = ClassDecl->vbases_end();
3559 Base != BaseEnd; ++Base) {
Douglas Gregor0c431c82010-08-29 19:27:27 +00003560 if (!InitializedBases.insert(Context.getCanonicalType(Base->getType()))) {
3561 SawLastInitializer
3562 = NumInitializers > 0 &&
3563 Initializers[NumInitializers - 1]->isBaseInitializer() &&
3564 Context.hasSameUnqualifiedType(Base->getType(),
3565 QualType(Initializers[NumInitializers - 1]->getBaseClass(), 0));
Douglas Gregor0133f522010-08-28 00:00:50 +00003566 continue;
Douglas Gregor0c431c82010-08-29 19:27:27 +00003567 }
Douglas Gregor0133f522010-08-28 00:00:50 +00003568
3569 CodeCompletionString *Pattern = new CodeCompletionString;
3570 Pattern->AddTypedTextChunk(
3571 Base->getType().getAsString(Context.PrintingPolicy));
3572 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
3573 Pattern->AddPlaceholderChunk("args");
3574 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
Douglas Gregor0c431c82010-08-29 19:27:27 +00003575 Results.AddResult(CodeCompletionResult(Pattern,
3576 SawLastInitializer? CCP_NextInitializer
3577 : CCP_MemberDeclaration));
3578 SawLastInitializer = false;
Douglas Gregor0133f522010-08-28 00:00:50 +00003579 }
3580
3581 // Add completions for members.
3582 for (CXXRecordDecl::field_iterator Field = ClassDecl->field_begin(),
3583 FieldEnd = ClassDecl->field_end();
3584 Field != FieldEnd; ++Field) {
Douglas Gregor0c431c82010-08-29 19:27:27 +00003585 if (!InitializedFields.insert(cast<FieldDecl>(Field->getCanonicalDecl()))) {
3586 SawLastInitializer
3587 = NumInitializers > 0 &&
3588 Initializers[NumInitializers - 1]->isMemberInitializer() &&
3589 Initializers[NumInitializers - 1]->getMember() == *Field;
Douglas Gregor0133f522010-08-28 00:00:50 +00003590 continue;
Douglas Gregor0c431c82010-08-29 19:27:27 +00003591 }
Douglas Gregor0133f522010-08-28 00:00:50 +00003592
3593 if (!Field->getDeclName())
3594 continue;
3595
3596 CodeCompletionString *Pattern = new CodeCompletionString;
3597 Pattern->AddTypedTextChunk(Field->getIdentifier()->getName());
3598 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
3599 Pattern->AddPlaceholderChunk("args");
3600 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
Douglas Gregor0c431c82010-08-29 19:27:27 +00003601 Results.AddResult(CodeCompletionResult(Pattern,
3602 SawLastInitializer? CCP_NextInitializer
Douglas Gregora67e03f2010-09-09 21:42:20 +00003603 : CCP_MemberDeclaration,
3604 CXCursor_MemberRef));
Douglas Gregor0c431c82010-08-29 19:27:27 +00003605 SawLastInitializer = false;
Douglas Gregor0133f522010-08-28 00:00:50 +00003606 }
3607 Results.ExitScope();
3608
3609 HandleCodeCompleteResults(this, CodeCompleter,
3610 CodeCompletionContext::CCC_Name,
3611 Results.data(), Results.size());
3612}
3613
Douglas Gregorb6ac2452010-01-13 21:24:21 +00003614// Macro that expands to @Keyword or Keyword, depending on whether NeedAt is
3615// true or false.
3616#define OBJC_AT_KEYWORD_NAME(NeedAt,Keyword) NeedAt? "@" #Keyword : #Keyword
Douglas Gregorbca403c2010-01-13 23:51:12 +00003617static void AddObjCImplementationResults(const LangOptions &LangOpts,
Douglas Gregorb6ac2452010-01-13 21:24:21 +00003618 ResultBuilder &Results,
3619 bool NeedAt) {
John McCall0a2c5e22010-08-25 06:19:51 +00003620 typedef CodeCompletionResult Result;
Douglas Gregorb6ac2452010-01-13 21:24:21 +00003621 // Since we have an implementation, we can end it.
Douglas Gregora4477812010-01-14 16:01:26 +00003622 Results.AddResult(Result(OBJC_AT_KEYWORD_NAME(NeedAt,end)));
Douglas Gregorb6ac2452010-01-13 21:24:21 +00003623
3624 CodeCompletionString *Pattern = 0;
3625 if (LangOpts.ObjC2) {
3626 // @dynamic
3627 Pattern = new CodeCompletionString;
3628 Pattern->AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt,dynamic));
3629 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
3630 Pattern->AddPlaceholderChunk("property");
Douglas Gregora4477812010-01-14 16:01:26 +00003631 Results.AddResult(Result(Pattern));
Douglas Gregorb6ac2452010-01-13 21:24:21 +00003632
3633 // @synthesize
3634 Pattern = new CodeCompletionString;
3635 Pattern->AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt,synthesize));
3636 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
3637 Pattern->AddPlaceholderChunk("property");
Douglas Gregora4477812010-01-14 16:01:26 +00003638 Results.AddResult(Result(Pattern));
Douglas Gregorb6ac2452010-01-13 21:24:21 +00003639 }
3640}
3641
Douglas Gregorbca403c2010-01-13 23:51:12 +00003642static void AddObjCInterfaceResults(const LangOptions &LangOpts,
Douglas Gregorb6ac2452010-01-13 21:24:21 +00003643 ResultBuilder &Results,
3644 bool NeedAt) {
John McCall0a2c5e22010-08-25 06:19:51 +00003645 typedef CodeCompletionResult Result;
Douglas Gregorb6ac2452010-01-13 21:24:21 +00003646
3647 // Since we have an interface or protocol, we can end it.
Douglas Gregora4477812010-01-14 16:01:26 +00003648 Results.AddResult(Result(OBJC_AT_KEYWORD_NAME(NeedAt,end)));
Douglas Gregorb6ac2452010-01-13 21:24:21 +00003649
3650 if (LangOpts.ObjC2) {
3651 // @property
Douglas Gregora4477812010-01-14 16:01:26 +00003652 Results.AddResult(Result(OBJC_AT_KEYWORD_NAME(NeedAt,property)));
Douglas Gregorb6ac2452010-01-13 21:24:21 +00003653
3654 // @required
Douglas Gregora4477812010-01-14 16:01:26 +00003655 Results.AddResult(Result(OBJC_AT_KEYWORD_NAME(NeedAt,required)));
Douglas Gregorb6ac2452010-01-13 21:24:21 +00003656
3657 // @optional
Douglas Gregora4477812010-01-14 16:01:26 +00003658 Results.AddResult(Result(OBJC_AT_KEYWORD_NAME(NeedAt,optional)));
Douglas Gregorb6ac2452010-01-13 21:24:21 +00003659 }
3660}
3661
Douglas Gregorbca403c2010-01-13 23:51:12 +00003662static void AddObjCTopLevelResults(ResultBuilder &Results, bool NeedAt) {
John McCall0a2c5e22010-08-25 06:19:51 +00003663 typedef CodeCompletionResult Result;
Douglas Gregorb6ac2452010-01-13 21:24:21 +00003664 CodeCompletionString *Pattern = 0;
3665
3666 // @class name ;
3667 Pattern = new CodeCompletionString;
3668 Pattern->AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt,class));
3669 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
Douglas Gregorc8bddde2010-05-28 00:22:41 +00003670 Pattern->AddPlaceholderChunk("name");
Douglas Gregora4477812010-01-14 16:01:26 +00003671 Results.AddResult(Result(Pattern));
Douglas Gregorb6ac2452010-01-13 21:24:21 +00003672
Douglas Gregorc8bddde2010-05-28 00:22:41 +00003673 if (Results.includeCodePatterns()) {
3674 // @interface name
3675 // FIXME: Could introduce the whole pattern, including superclasses and
3676 // such.
3677 Pattern = new CodeCompletionString;
3678 Pattern->AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt,interface));
3679 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
3680 Pattern->AddPlaceholderChunk("class");
3681 Results.AddResult(Result(Pattern));
Douglas Gregorb6ac2452010-01-13 21:24:21 +00003682
Douglas Gregorc8bddde2010-05-28 00:22:41 +00003683 // @protocol name
3684 Pattern = new CodeCompletionString;
3685 Pattern->AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt,protocol));
3686 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
3687 Pattern->AddPlaceholderChunk("protocol");
3688 Results.AddResult(Result(Pattern));
3689
3690 // @implementation name
3691 Pattern = new CodeCompletionString;
3692 Pattern->AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt,implementation));
3693 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
3694 Pattern->AddPlaceholderChunk("class");
3695 Results.AddResult(Result(Pattern));
3696 }
Douglas Gregorb6ac2452010-01-13 21:24:21 +00003697
3698 // @compatibility_alias name
3699 Pattern = new CodeCompletionString;
3700 Pattern->AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt,compatibility_alias));
3701 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
3702 Pattern->AddPlaceholderChunk("alias");
3703 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
3704 Pattern->AddPlaceholderChunk("class");
Douglas Gregora4477812010-01-14 16:01:26 +00003705 Results.AddResult(Result(Pattern));
Douglas Gregorb6ac2452010-01-13 21:24:21 +00003706}
3707
John McCalld226f652010-08-21 09:40:31 +00003708void Sema::CodeCompleteObjCAtDirective(Scope *S, Decl *ObjCImpDecl,
Douglas Gregorc464ae82009-12-07 09:27:33 +00003709 bool InInterface) {
John McCall0a2c5e22010-08-25 06:19:51 +00003710 typedef CodeCompletionResult Result;
Douglas Gregorc464ae82009-12-07 09:27:33 +00003711 ResultBuilder Results(*this);
3712 Results.EnterNewScope();
Douglas Gregorb6ac2452010-01-13 21:24:21 +00003713 if (ObjCImpDecl)
Douglas Gregorbca403c2010-01-13 23:51:12 +00003714 AddObjCImplementationResults(getLangOptions(), Results, false);
Douglas Gregorb6ac2452010-01-13 21:24:21 +00003715 else if (InInterface)
Douglas Gregorbca403c2010-01-13 23:51:12 +00003716 AddObjCInterfaceResults(getLangOptions(), Results, false);
Douglas Gregorb6ac2452010-01-13 21:24:21 +00003717 else
Douglas Gregorbca403c2010-01-13 23:51:12 +00003718 AddObjCTopLevelResults(Results, false);
Douglas Gregorc464ae82009-12-07 09:27:33 +00003719 Results.ExitScope();
Douglas Gregore6b1bb62010-08-11 21:23:17 +00003720 HandleCodeCompleteResults(this, CodeCompleter,
3721 CodeCompletionContext::CCC_Other,
3722 Results.data(),Results.size());
Douglas Gregorc464ae82009-12-07 09:27:33 +00003723}
3724
Douglas Gregorbca403c2010-01-13 23:51:12 +00003725static void AddObjCExpressionResults(ResultBuilder &Results, bool NeedAt) {
John McCall0a2c5e22010-08-25 06:19:51 +00003726 typedef CodeCompletionResult Result;
Douglas Gregor9a0c85e2009-12-07 09:51:25 +00003727 CodeCompletionString *Pattern = 0;
3728
3729 // @encode ( type-name )
3730 Pattern = new CodeCompletionString;
Douglas Gregorb6ac2452010-01-13 21:24:21 +00003731 Pattern->AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt,encode));
Douglas Gregor9a0c85e2009-12-07 09:51:25 +00003732 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
3733 Pattern->AddPlaceholderChunk("type-name");
3734 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
Douglas Gregora4477812010-01-14 16:01:26 +00003735 Results.AddResult(Result(Pattern));
Douglas Gregor9a0c85e2009-12-07 09:51:25 +00003736
3737 // @protocol ( protocol-name )
3738 Pattern = new CodeCompletionString;
Douglas Gregorb6ac2452010-01-13 21:24:21 +00003739 Pattern->AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt,protocol));
Douglas Gregor9a0c85e2009-12-07 09:51:25 +00003740 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
3741 Pattern->AddPlaceholderChunk("protocol-name");
3742 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
Douglas Gregora4477812010-01-14 16:01:26 +00003743 Results.AddResult(Result(Pattern));
Douglas Gregor9a0c85e2009-12-07 09:51:25 +00003744
3745 // @selector ( selector )
3746 Pattern = new CodeCompletionString;
Douglas Gregorb6ac2452010-01-13 21:24:21 +00003747 Pattern->AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt,selector));
Douglas Gregor9a0c85e2009-12-07 09:51:25 +00003748 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
3749 Pattern->AddPlaceholderChunk("selector");
3750 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
Douglas Gregora4477812010-01-14 16:01:26 +00003751 Results.AddResult(Result(Pattern));
Douglas Gregor9a0c85e2009-12-07 09:51:25 +00003752}
3753
Douglas Gregorbca403c2010-01-13 23:51:12 +00003754static void AddObjCStatementResults(ResultBuilder &Results, bool NeedAt) {
John McCall0a2c5e22010-08-25 06:19:51 +00003755 typedef CodeCompletionResult Result;
Douglas Gregor9a0c85e2009-12-07 09:51:25 +00003756 CodeCompletionString *Pattern = 0;
Douglas Gregorb6ac2452010-01-13 21:24:21 +00003757
Douglas Gregorc8bddde2010-05-28 00:22:41 +00003758 if (Results.includeCodePatterns()) {
3759 // @try { statements } @catch ( declaration ) { statements } @finally
3760 // { statements }
3761 Pattern = new CodeCompletionString;
3762 Pattern->AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt,try));
3763 Pattern->AddChunk(CodeCompletionString::CK_LeftBrace);
3764 Pattern->AddPlaceholderChunk("statements");
3765 Pattern->AddChunk(CodeCompletionString::CK_RightBrace);
3766 Pattern->AddTextChunk("@catch");
3767 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
3768 Pattern->AddPlaceholderChunk("parameter");
3769 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
3770 Pattern->AddChunk(CodeCompletionString::CK_LeftBrace);
3771 Pattern->AddPlaceholderChunk("statements");
3772 Pattern->AddChunk(CodeCompletionString::CK_RightBrace);
3773 Pattern->AddTextChunk("@finally");
3774 Pattern->AddChunk(CodeCompletionString::CK_LeftBrace);
3775 Pattern->AddPlaceholderChunk("statements");
3776 Pattern->AddChunk(CodeCompletionString::CK_RightBrace);
3777 Results.AddResult(Result(Pattern));
3778 }
Douglas Gregorb6ac2452010-01-13 21:24:21 +00003779
Douglas Gregor9a0c85e2009-12-07 09:51:25 +00003780 // @throw
3781 Pattern = new CodeCompletionString;
Douglas Gregorb6ac2452010-01-13 21:24:21 +00003782 Pattern->AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt,throw));
Douglas Gregor834389b2010-01-12 06:38:28 +00003783 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
Douglas Gregor9a0c85e2009-12-07 09:51:25 +00003784 Pattern->AddPlaceholderChunk("expression");
Douglas Gregora4477812010-01-14 16:01:26 +00003785 Results.AddResult(Result(Pattern));
Douglas Gregorb6ac2452010-01-13 21:24:21 +00003786
Douglas Gregorc8bddde2010-05-28 00:22:41 +00003787 if (Results.includeCodePatterns()) {
3788 // @synchronized ( expression ) { statements }
3789 Pattern = new CodeCompletionString;
3790 Pattern->AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt,synchronized));
3791 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
3792 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
3793 Pattern->AddPlaceholderChunk("expression");
3794 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
3795 Pattern->AddChunk(CodeCompletionString::CK_LeftBrace);
3796 Pattern->AddPlaceholderChunk("statements");
3797 Pattern->AddChunk(CodeCompletionString::CK_RightBrace);
3798 Results.AddResult(Result(Pattern));
3799 }
Douglas Gregorb6ac2452010-01-13 21:24:21 +00003800}
Douglas Gregor9a0c85e2009-12-07 09:51:25 +00003801
Douglas Gregorbca403c2010-01-13 23:51:12 +00003802static void AddObjCVisibilityResults(const LangOptions &LangOpts,
Douglas Gregorc38c3e12010-01-13 21:54:15 +00003803 ResultBuilder &Results,
3804 bool NeedAt) {
John McCall0a2c5e22010-08-25 06:19:51 +00003805 typedef CodeCompletionResult Result;
Douglas Gregora4477812010-01-14 16:01:26 +00003806 Results.AddResult(Result(OBJC_AT_KEYWORD_NAME(NeedAt,private)));
3807 Results.AddResult(Result(OBJC_AT_KEYWORD_NAME(NeedAt,protected)));
3808 Results.AddResult(Result(OBJC_AT_KEYWORD_NAME(NeedAt,public)));
Douglas Gregorc38c3e12010-01-13 21:54:15 +00003809 if (LangOpts.ObjC2)
Douglas Gregora4477812010-01-14 16:01:26 +00003810 Results.AddResult(Result(OBJC_AT_KEYWORD_NAME(NeedAt,package)));
Douglas Gregorc38c3e12010-01-13 21:54:15 +00003811}
3812
3813void Sema::CodeCompleteObjCAtVisibility(Scope *S) {
3814 ResultBuilder Results(*this);
3815 Results.EnterNewScope();
Douglas Gregorbca403c2010-01-13 23:51:12 +00003816 AddObjCVisibilityResults(getLangOptions(), Results, false);
Douglas Gregorc38c3e12010-01-13 21:54:15 +00003817 Results.ExitScope();
Douglas Gregore6b1bb62010-08-11 21:23:17 +00003818 HandleCodeCompleteResults(this, CodeCompleter,
3819 CodeCompletionContext::CCC_Other,
3820 Results.data(),Results.size());
Douglas Gregorc38c3e12010-01-13 21:54:15 +00003821}
3822
3823void Sema::CodeCompleteObjCAtStatement(Scope *S) {
Douglas Gregorb6ac2452010-01-13 21:24:21 +00003824 ResultBuilder Results(*this);
3825 Results.EnterNewScope();
Douglas Gregorbca403c2010-01-13 23:51:12 +00003826 AddObjCStatementResults(Results, false);
3827 AddObjCExpressionResults(Results, false);
Douglas Gregor9a0c85e2009-12-07 09:51:25 +00003828 Results.ExitScope();
Douglas Gregore6b1bb62010-08-11 21:23:17 +00003829 HandleCodeCompleteResults(this, CodeCompleter,
3830 CodeCompletionContext::CCC_Other,
3831 Results.data(),Results.size());
Douglas Gregor9a0c85e2009-12-07 09:51:25 +00003832}
3833
3834void Sema::CodeCompleteObjCAtExpression(Scope *S) {
3835 ResultBuilder Results(*this);
3836 Results.EnterNewScope();
Douglas Gregorbca403c2010-01-13 23:51:12 +00003837 AddObjCExpressionResults(Results, false);
Douglas Gregor9a0c85e2009-12-07 09:51:25 +00003838 Results.ExitScope();
Douglas Gregore6b1bb62010-08-11 21:23:17 +00003839 HandleCodeCompleteResults(this, CodeCompleter,
3840 CodeCompletionContext::CCC_Other,
3841 Results.data(),Results.size());
Douglas Gregor9a0c85e2009-12-07 09:51:25 +00003842}
3843
Douglas Gregor988358f2009-11-19 00:14:45 +00003844/// \brief Determine whether the addition of the given flag to an Objective-C
3845/// property's attributes will cause a conflict.
3846static bool ObjCPropertyFlagConflicts(unsigned Attributes, unsigned NewFlag) {
3847 // Check if we've already added this flag.
3848 if (Attributes & NewFlag)
3849 return true;
3850
3851 Attributes |= NewFlag;
3852
3853 // Check for collisions with "readonly".
3854 if ((Attributes & ObjCDeclSpec::DQ_PR_readonly) &&
3855 (Attributes & (ObjCDeclSpec::DQ_PR_readwrite |
3856 ObjCDeclSpec::DQ_PR_assign |
3857 ObjCDeclSpec::DQ_PR_copy |
3858 ObjCDeclSpec::DQ_PR_retain)))
3859 return true;
3860
3861 // Check for more than one of { assign, copy, retain }.
3862 unsigned AssignCopyRetMask = Attributes & (ObjCDeclSpec::DQ_PR_assign |
3863 ObjCDeclSpec::DQ_PR_copy |
3864 ObjCDeclSpec::DQ_PR_retain);
3865 if (AssignCopyRetMask &&
3866 AssignCopyRetMask != ObjCDeclSpec::DQ_PR_assign &&
3867 AssignCopyRetMask != ObjCDeclSpec::DQ_PR_copy &&
3868 AssignCopyRetMask != ObjCDeclSpec::DQ_PR_retain)
3869 return true;
3870
3871 return false;
3872}
3873
Douglas Gregora93b1082009-11-18 23:08:07 +00003874void Sema::CodeCompleteObjCPropertyFlags(Scope *S, ObjCDeclSpec &ODS) {
Steve Naroffece8e712009-10-08 21:55:05 +00003875 if (!CodeCompleter)
3876 return;
Douglas Gregord3c68542009-11-19 01:08:35 +00003877
Steve Naroffece8e712009-10-08 21:55:05 +00003878 unsigned Attributes = ODS.getPropertyAttributes();
3879
John McCall0a2c5e22010-08-25 06:19:51 +00003880 typedef CodeCompletionResult Result;
Steve Naroffece8e712009-10-08 21:55:05 +00003881 ResultBuilder Results(*this);
3882 Results.EnterNewScope();
Douglas Gregor988358f2009-11-19 00:14:45 +00003883 if (!ObjCPropertyFlagConflicts(Attributes, ObjCDeclSpec::DQ_PR_readonly))
John McCall0a2c5e22010-08-25 06:19:51 +00003884 Results.AddResult(CodeCompletionResult("readonly"));
Douglas Gregor988358f2009-11-19 00:14:45 +00003885 if (!ObjCPropertyFlagConflicts(Attributes, ObjCDeclSpec::DQ_PR_assign))
John McCall0a2c5e22010-08-25 06:19:51 +00003886 Results.AddResult(CodeCompletionResult("assign"));
Douglas Gregor988358f2009-11-19 00:14:45 +00003887 if (!ObjCPropertyFlagConflicts(Attributes, ObjCDeclSpec::DQ_PR_readwrite))
John McCall0a2c5e22010-08-25 06:19:51 +00003888 Results.AddResult(CodeCompletionResult("readwrite"));
Douglas Gregor988358f2009-11-19 00:14:45 +00003889 if (!ObjCPropertyFlagConflicts(Attributes, ObjCDeclSpec::DQ_PR_retain))
John McCall0a2c5e22010-08-25 06:19:51 +00003890 Results.AddResult(CodeCompletionResult("retain"));
Douglas Gregor988358f2009-11-19 00:14:45 +00003891 if (!ObjCPropertyFlagConflicts(Attributes, ObjCDeclSpec::DQ_PR_copy))
John McCall0a2c5e22010-08-25 06:19:51 +00003892 Results.AddResult(CodeCompletionResult("copy"));
Douglas Gregor988358f2009-11-19 00:14:45 +00003893 if (!ObjCPropertyFlagConflicts(Attributes, ObjCDeclSpec::DQ_PR_nonatomic))
John McCall0a2c5e22010-08-25 06:19:51 +00003894 Results.AddResult(CodeCompletionResult("nonatomic"));
Douglas Gregor988358f2009-11-19 00:14:45 +00003895 if (!ObjCPropertyFlagConflicts(Attributes, ObjCDeclSpec::DQ_PR_setter)) {
Douglas Gregor54f01612009-11-19 00:01:57 +00003896 CodeCompletionString *Setter = new CodeCompletionString;
3897 Setter->AddTypedTextChunk("setter");
3898 Setter->AddTextChunk(" = ");
3899 Setter->AddPlaceholderChunk("method");
John McCall0a2c5e22010-08-25 06:19:51 +00003900 Results.AddResult(CodeCompletionResult(Setter));
Douglas Gregor54f01612009-11-19 00:01:57 +00003901 }
Douglas Gregor988358f2009-11-19 00:14:45 +00003902 if (!ObjCPropertyFlagConflicts(Attributes, ObjCDeclSpec::DQ_PR_getter)) {
Douglas Gregor54f01612009-11-19 00:01:57 +00003903 CodeCompletionString *Getter = new CodeCompletionString;
3904 Getter->AddTypedTextChunk("getter");
3905 Getter->AddTextChunk(" = ");
3906 Getter->AddPlaceholderChunk("method");
John McCall0a2c5e22010-08-25 06:19:51 +00003907 Results.AddResult(CodeCompletionResult(Getter));
Douglas Gregor54f01612009-11-19 00:01:57 +00003908 }
Steve Naroffece8e712009-10-08 21:55:05 +00003909 Results.ExitScope();
Douglas Gregore6b1bb62010-08-11 21:23:17 +00003910 HandleCodeCompleteResults(this, CodeCompleter,
3911 CodeCompletionContext::CCC_Other,
3912 Results.data(),Results.size());
Steve Naroffece8e712009-10-08 21:55:05 +00003913}
Steve Naroffc4df6d22009-11-07 02:08:14 +00003914
Douglas Gregor4ad96852009-11-19 07:41:15 +00003915/// \brief Descripts the kind of Objective-C method that we want to find
3916/// via code completion.
3917enum ObjCMethodKind {
3918 MK_Any, //< Any kind of method, provided it means other specified criteria.
3919 MK_ZeroArgSelector, //< Zero-argument (unary) selector.
3920 MK_OneArgSelector //< One-argument selector.
3921};
3922
Douglas Gregor458433d2010-08-26 15:07:07 +00003923static bool isAcceptableObjCSelector(Selector Sel,
3924 ObjCMethodKind WantKind,
3925 IdentifierInfo **SelIdents,
3926 unsigned NumSelIdents) {
3927 if (NumSelIdents > Sel.getNumArgs())
3928 return false;
3929
3930 switch (WantKind) {
3931 case MK_Any: break;
3932 case MK_ZeroArgSelector: return Sel.isUnarySelector();
3933 case MK_OneArgSelector: return Sel.getNumArgs() == 1;
3934 }
3935
3936 for (unsigned I = 0; I != NumSelIdents; ++I)
3937 if (SelIdents[I] != Sel.getIdentifierInfoForSlot(I))
3938 return false;
3939
3940 return true;
3941}
3942
Douglas Gregor4ad96852009-11-19 07:41:15 +00003943static bool isAcceptableObjCMethod(ObjCMethodDecl *Method,
3944 ObjCMethodKind WantKind,
3945 IdentifierInfo **SelIdents,
3946 unsigned NumSelIdents) {
Douglas Gregor458433d2010-08-26 15:07:07 +00003947 return isAcceptableObjCSelector(Method->getSelector(), WantKind, SelIdents,
3948 NumSelIdents);
Douglas Gregor4ad96852009-11-19 07:41:15 +00003949}
Douglas Gregord36adf52010-09-16 16:06:31 +00003950
3951namespace {
3952 /// \brief A set of selectors, which is used to avoid introducing multiple
3953 /// completions with the same selector into the result set.
3954 typedef llvm::SmallPtrSet<Selector, 16> VisitedSelectorSet;
3955}
3956
Douglas Gregor36ecb042009-11-17 23:22:23 +00003957/// \brief Add all of the Objective-C methods in the given Objective-C
3958/// container to the set of results.
3959///
3960/// The container will be a class, protocol, category, or implementation of
3961/// any of the above. This mether will recurse to include methods from
3962/// the superclasses of classes along with their categories, protocols, and
3963/// implementations.
3964///
3965/// \param Container the container in which we'll look to find methods.
3966///
3967/// \param WantInstance whether to add instance methods (only); if false, this
3968/// routine will add factory methods (only).
3969///
3970/// \param CurContext the context in which we're performing the lookup that
3971/// finds methods.
3972///
3973/// \param Results the structure into which we'll add results.
3974static void AddObjCMethods(ObjCContainerDecl *Container,
3975 bool WantInstanceMethods,
Douglas Gregor4ad96852009-11-19 07:41:15 +00003976 ObjCMethodKind WantKind,
Douglas Gregord3c68542009-11-19 01:08:35 +00003977 IdentifierInfo **SelIdents,
3978 unsigned NumSelIdents,
Douglas Gregor36ecb042009-11-17 23:22:23 +00003979 DeclContext *CurContext,
Douglas Gregord36adf52010-09-16 16:06:31 +00003980 VisitedSelectorSet &Selectors,
Douglas Gregor408be5a2010-08-25 01:08:01 +00003981 ResultBuilder &Results,
3982 bool InOriginalClass = true) {
John McCall0a2c5e22010-08-25 06:19:51 +00003983 typedef CodeCompletionResult Result;
Douglas Gregor36ecb042009-11-17 23:22:23 +00003984 for (ObjCContainerDecl::method_iterator M = Container->meth_begin(),
3985 MEnd = Container->meth_end();
3986 M != MEnd; ++M) {
Douglas Gregord3c68542009-11-19 01:08:35 +00003987 if ((*M)->isInstanceMethod() == WantInstanceMethods) {
3988 // Check whether the selector identifiers we've been given are a
3989 // subset of the identifiers for this particular method.
Douglas Gregor4ad96852009-11-19 07:41:15 +00003990 if (!isAcceptableObjCMethod(*M, WantKind, SelIdents, NumSelIdents))
Douglas Gregord3c68542009-11-19 01:08:35 +00003991 continue;
Douglas Gregor4ad96852009-11-19 07:41:15 +00003992
Douglas Gregord36adf52010-09-16 16:06:31 +00003993 if (!Selectors.insert((*M)->getSelector()))
3994 continue;
3995
Douglas Gregord3c68542009-11-19 01:08:35 +00003996 Result R = Result(*M, 0);
3997 R.StartParameter = NumSelIdents;
Douglas Gregor4ad96852009-11-19 07:41:15 +00003998 R.AllParametersAreInformative = (WantKind != MK_Any);
Douglas Gregor408be5a2010-08-25 01:08:01 +00003999 if (!InOriginalClass)
4000 R.Priority += CCD_InBaseClass;
Douglas Gregord3c68542009-11-19 01:08:35 +00004001 Results.MaybeAddResult(R, CurContext);
4002 }
Douglas Gregor36ecb042009-11-17 23:22:23 +00004003 }
4004
Douglas Gregore396c7b2010-09-16 15:34:59 +00004005 // Visit the protocols of protocols.
4006 if (ObjCProtocolDecl *Protocol = dyn_cast<ObjCProtocolDecl>(Container)) {
4007 const ObjCList<ObjCProtocolDecl> &Protocols
4008 = Protocol->getReferencedProtocols();
4009 for (ObjCList<ObjCProtocolDecl>::iterator I = Protocols.begin(),
4010 E = Protocols.end();
4011 I != E; ++I)
4012 AddObjCMethods(*I, WantInstanceMethods, WantKind, SelIdents, NumSelIdents,
Douglas Gregord36adf52010-09-16 16:06:31 +00004013 CurContext, Selectors, Results, false);
Douglas Gregore396c7b2010-09-16 15:34:59 +00004014 }
4015
Douglas Gregor36ecb042009-11-17 23:22:23 +00004016 ObjCInterfaceDecl *IFace = dyn_cast<ObjCInterfaceDecl>(Container);
4017 if (!IFace)
4018 return;
4019
4020 // Add methods in protocols.
4021 const ObjCList<ObjCProtocolDecl> &Protocols= IFace->getReferencedProtocols();
4022 for (ObjCList<ObjCProtocolDecl>::iterator I = Protocols.begin(),
4023 E = Protocols.end();
4024 I != E; ++I)
Douglas Gregor4ad96852009-11-19 07:41:15 +00004025 AddObjCMethods(*I, WantInstanceMethods, WantKind, SelIdents, NumSelIdents,
Douglas Gregord36adf52010-09-16 16:06:31 +00004026 CurContext, Selectors, Results, false);
Douglas Gregor36ecb042009-11-17 23:22:23 +00004027
4028 // Add methods in categories.
4029 for (ObjCCategoryDecl *CatDecl = IFace->getCategoryList(); CatDecl;
4030 CatDecl = CatDecl->getNextClassCategory()) {
Douglas Gregor4ad96852009-11-19 07:41:15 +00004031 AddObjCMethods(CatDecl, WantInstanceMethods, WantKind, SelIdents,
Douglas Gregord36adf52010-09-16 16:06:31 +00004032 NumSelIdents, CurContext, Selectors, Results,
4033 InOriginalClass);
Douglas Gregor36ecb042009-11-17 23:22:23 +00004034
4035 // Add a categories protocol methods.
4036 const ObjCList<ObjCProtocolDecl> &Protocols
4037 = CatDecl->getReferencedProtocols();
4038 for (ObjCList<ObjCProtocolDecl>::iterator I = Protocols.begin(),
4039 E = Protocols.end();
4040 I != E; ++I)
Douglas Gregor4ad96852009-11-19 07:41:15 +00004041 AddObjCMethods(*I, WantInstanceMethods, WantKind, SelIdents,
Douglas Gregord36adf52010-09-16 16:06:31 +00004042 NumSelIdents, CurContext, Selectors, Results, false);
Douglas Gregor36ecb042009-11-17 23:22:23 +00004043
4044 // Add methods in category implementations.
4045 if (ObjCCategoryImplDecl *Impl = CatDecl->getImplementation())
Douglas Gregor4ad96852009-11-19 07:41:15 +00004046 AddObjCMethods(Impl, WantInstanceMethods, WantKind, SelIdents,
Douglas Gregord36adf52010-09-16 16:06:31 +00004047 NumSelIdents, CurContext, Selectors, Results,
4048 InOriginalClass);
Douglas Gregor36ecb042009-11-17 23:22:23 +00004049 }
4050
4051 // Add methods in superclass.
4052 if (IFace->getSuperClass())
Douglas Gregor4ad96852009-11-19 07:41:15 +00004053 AddObjCMethods(IFace->getSuperClass(), WantInstanceMethods, WantKind,
Douglas Gregord36adf52010-09-16 16:06:31 +00004054 SelIdents, NumSelIdents, CurContext, Selectors, Results,
4055 false);
Douglas Gregor36ecb042009-11-17 23:22:23 +00004056
4057 // Add methods in our implementation, if any.
4058 if (ObjCImplementationDecl *Impl = IFace->getImplementation())
Douglas Gregor4ad96852009-11-19 07:41:15 +00004059 AddObjCMethods(Impl, WantInstanceMethods, WantKind, SelIdents,
Douglas Gregord36adf52010-09-16 16:06:31 +00004060 NumSelIdents, CurContext, Selectors, Results,
4061 InOriginalClass);
Douglas Gregor4ad96852009-11-19 07:41:15 +00004062}
4063
4064
John McCalld226f652010-08-21 09:40:31 +00004065void Sema::CodeCompleteObjCPropertyGetter(Scope *S, Decl *ClassDecl,
4066 Decl **Methods,
Douglas Gregor4ad96852009-11-19 07:41:15 +00004067 unsigned NumMethods) {
John McCall0a2c5e22010-08-25 06:19:51 +00004068 typedef CodeCompletionResult Result;
Douglas Gregor4ad96852009-11-19 07:41:15 +00004069
4070 // Try to find the interface where getters might live.
John McCalld226f652010-08-21 09:40:31 +00004071 ObjCInterfaceDecl *Class = dyn_cast_or_null<ObjCInterfaceDecl>(ClassDecl);
Douglas Gregor4ad96852009-11-19 07:41:15 +00004072 if (!Class) {
4073 if (ObjCCategoryDecl *Category
John McCalld226f652010-08-21 09:40:31 +00004074 = dyn_cast_or_null<ObjCCategoryDecl>(ClassDecl))
Douglas Gregor4ad96852009-11-19 07:41:15 +00004075 Class = Category->getClassInterface();
4076
4077 if (!Class)
4078 return;
4079 }
4080
4081 // Find all of the potential getters.
4082 ResultBuilder Results(*this);
4083 Results.EnterNewScope();
4084
4085 // FIXME: We need to do this because Objective-C methods don't get
4086 // pushed into DeclContexts early enough. Argh!
4087 for (unsigned I = 0; I != NumMethods; ++I) {
4088 if (ObjCMethodDecl *Method
John McCalld226f652010-08-21 09:40:31 +00004089 = dyn_cast_or_null<ObjCMethodDecl>(Methods[I]))
Douglas Gregor4ad96852009-11-19 07:41:15 +00004090 if (Method->isInstanceMethod() &&
4091 isAcceptableObjCMethod(Method, MK_ZeroArgSelector, 0, 0)) {
4092 Result R = Result(Method, 0);
4093 R.AllParametersAreInformative = true;
4094 Results.MaybeAddResult(R, CurContext);
4095 }
4096 }
4097
Douglas Gregord36adf52010-09-16 16:06:31 +00004098 VisitedSelectorSet Selectors;
4099 AddObjCMethods(Class, true, MK_ZeroArgSelector, 0, 0, CurContext, Selectors,
4100 Results);
Douglas Gregor4ad96852009-11-19 07:41:15 +00004101 Results.ExitScope();
Douglas Gregore6b1bb62010-08-11 21:23:17 +00004102 HandleCodeCompleteResults(this, CodeCompleter,
4103 CodeCompletionContext::CCC_Other,
4104 Results.data(),Results.size());
Douglas Gregor4ad96852009-11-19 07:41:15 +00004105}
4106
John McCalld226f652010-08-21 09:40:31 +00004107void Sema::CodeCompleteObjCPropertySetter(Scope *S, Decl *ObjCImplDecl,
4108 Decl **Methods,
Douglas Gregor4ad96852009-11-19 07:41:15 +00004109 unsigned NumMethods) {
John McCall0a2c5e22010-08-25 06:19:51 +00004110 typedef CodeCompletionResult Result;
Douglas Gregor4ad96852009-11-19 07:41:15 +00004111
4112 // Try to find the interface where setters might live.
4113 ObjCInterfaceDecl *Class
John McCalld226f652010-08-21 09:40:31 +00004114 = dyn_cast_or_null<ObjCInterfaceDecl>(ObjCImplDecl);
Douglas Gregor4ad96852009-11-19 07:41:15 +00004115 if (!Class) {
4116 if (ObjCCategoryDecl *Category
John McCalld226f652010-08-21 09:40:31 +00004117 = dyn_cast_or_null<ObjCCategoryDecl>(ObjCImplDecl))
Douglas Gregor4ad96852009-11-19 07:41:15 +00004118 Class = Category->getClassInterface();
4119
4120 if (!Class)
4121 return;
4122 }
4123
4124 // Find all of the potential getters.
4125 ResultBuilder Results(*this);
4126 Results.EnterNewScope();
4127
4128 // FIXME: We need to do this because Objective-C methods don't get
4129 // pushed into DeclContexts early enough. Argh!
4130 for (unsigned I = 0; I != NumMethods; ++I) {
4131 if (ObjCMethodDecl *Method
John McCalld226f652010-08-21 09:40:31 +00004132 = dyn_cast_or_null<ObjCMethodDecl>(Methods[I]))
Douglas Gregor4ad96852009-11-19 07:41:15 +00004133 if (Method->isInstanceMethod() &&
4134 isAcceptableObjCMethod(Method, MK_OneArgSelector, 0, 0)) {
4135 Result R = Result(Method, 0);
4136 R.AllParametersAreInformative = true;
4137 Results.MaybeAddResult(R, CurContext);
4138 }
4139 }
4140
Douglas Gregord36adf52010-09-16 16:06:31 +00004141 VisitedSelectorSet Selectors;
4142 AddObjCMethods(Class, true, MK_OneArgSelector, 0, 0, CurContext,
4143 Selectors, Results);
Douglas Gregor4ad96852009-11-19 07:41:15 +00004144
4145 Results.ExitScope();
Douglas Gregore6b1bb62010-08-11 21:23:17 +00004146 HandleCodeCompleteResults(this, CodeCompleter,
4147 CodeCompletionContext::CCC_Other,
4148 Results.data(),Results.size());
Douglas Gregor36ecb042009-11-17 23:22:23 +00004149}
4150
Douglas Gregord32b0222010-08-24 01:06:58 +00004151void Sema::CodeCompleteObjCPassingType(Scope *S, ObjCDeclSpec &DS) {
John McCall0a2c5e22010-08-25 06:19:51 +00004152 typedef CodeCompletionResult Result;
Douglas Gregord32b0222010-08-24 01:06:58 +00004153 ResultBuilder Results(*this);
4154 Results.EnterNewScope();
4155
4156 // Add context-sensitive, Objective-C parameter-passing keywords.
4157 bool AddedInOut = false;
4158 if ((DS.getObjCDeclQualifier() &
4159 (ObjCDeclSpec::DQ_In | ObjCDeclSpec::DQ_Inout)) == 0) {
4160 Results.AddResult("in");
4161 Results.AddResult("inout");
4162 AddedInOut = true;
4163 }
4164 if ((DS.getObjCDeclQualifier() &
4165 (ObjCDeclSpec::DQ_Out | ObjCDeclSpec::DQ_Inout)) == 0) {
4166 Results.AddResult("out");
4167 if (!AddedInOut)
4168 Results.AddResult("inout");
4169 }
4170 if ((DS.getObjCDeclQualifier() &
4171 (ObjCDeclSpec::DQ_Bycopy | ObjCDeclSpec::DQ_Byref |
4172 ObjCDeclSpec::DQ_Oneway)) == 0) {
4173 Results.AddResult("bycopy");
4174 Results.AddResult("byref");
4175 Results.AddResult("oneway");
4176 }
4177
4178 // Add various builtin type names and specifiers.
4179 AddOrdinaryNameResults(PCC_Type, S, *this, Results);
4180 Results.ExitScope();
4181
4182 // Add the various type names
4183 Results.setFilter(&ResultBuilder::IsOrdinaryNonValueName);
4184 CodeCompletionDeclConsumer Consumer(Results, CurContext);
4185 LookupVisibleDecls(S, LookupOrdinaryName, Consumer,
4186 CodeCompleter->includeGlobals());
4187
4188 if (CodeCompleter->includeMacros())
4189 AddMacroResults(PP, Results);
4190
4191 HandleCodeCompleteResults(this, CodeCompleter,
4192 CodeCompletionContext::CCC_Type,
4193 Results.data(), Results.size());
4194}
4195
Douglas Gregor22f56992010-04-06 19:22:33 +00004196/// \brief When we have an expression with type "id", we may assume
4197/// that it has some more-specific class type based on knowledge of
4198/// common uses of Objective-C. This routine returns that class type,
4199/// or NULL if no better result could be determined.
4200static ObjCInterfaceDecl *GetAssumedMessageSendExprType(Expr *E) {
Douglas Gregor78edf512010-09-15 16:23:04 +00004201 ObjCMessageExpr *Msg = dyn_cast_or_null<ObjCMessageExpr>(E);
Douglas Gregor22f56992010-04-06 19:22:33 +00004202 if (!Msg)
4203 return 0;
4204
4205 Selector Sel = Msg->getSelector();
4206 if (Sel.isNull())
4207 return 0;
4208
4209 IdentifierInfo *Id = Sel.getIdentifierInfoForSlot(0);
4210 if (!Id)
4211 return 0;
4212
4213 ObjCMethodDecl *Method = Msg->getMethodDecl();
4214 if (!Method)
4215 return 0;
4216
4217 // Determine the class that we're sending the message to.
Douglas Gregor04badcf2010-04-21 00:45:42 +00004218 ObjCInterfaceDecl *IFace = 0;
4219 switch (Msg->getReceiverKind()) {
4220 case ObjCMessageExpr::Class:
John McCallc12c5bb2010-05-15 11:32:37 +00004221 if (const ObjCObjectType *ObjType
4222 = Msg->getClassReceiver()->getAs<ObjCObjectType>())
4223 IFace = ObjType->getInterface();
Douglas Gregor04badcf2010-04-21 00:45:42 +00004224 break;
4225
4226 case ObjCMessageExpr::Instance: {
4227 QualType T = Msg->getInstanceReceiver()->getType();
4228 if (const ObjCObjectPointerType *Ptr = T->getAs<ObjCObjectPointerType>())
4229 IFace = Ptr->getInterfaceDecl();
4230 break;
4231 }
4232
4233 case ObjCMessageExpr::SuperInstance:
4234 case ObjCMessageExpr::SuperClass:
4235 break;
Douglas Gregor22f56992010-04-06 19:22:33 +00004236 }
4237
4238 if (!IFace)
4239 return 0;
4240
4241 ObjCInterfaceDecl *Super = IFace->getSuperClass();
4242 if (Method->isInstanceMethod())
4243 return llvm::StringSwitch<ObjCInterfaceDecl *>(Id->getName())
4244 .Case("retain", IFace)
4245 .Case("autorelease", IFace)
4246 .Case("copy", IFace)
4247 .Case("copyWithZone", IFace)
4248 .Case("mutableCopy", IFace)
4249 .Case("mutableCopyWithZone", IFace)
4250 .Case("awakeFromCoder", IFace)
4251 .Case("replacementObjectFromCoder", IFace)
4252 .Case("class", IFace)
4253 .Case("classForCoder", IFace)
4254 .Case("superclass", Super)
4255 .Default(0);
4256
4257 return llvm::StringSwitch<ObjCInterfaceDecl *>(Id->getName())
4258 .Case("new", IFace)
4259 .Case("alloc", IFace)
4260 .Case("allocWithZone", IFace)
4261 .Case("class", IFace)
4262 .Case("superclass", Super)
4263 .Default(0);
4264}
4265
Douglas Gregor03d8aec2010-08-27 15:10:57 +00004266// Add a special completion for a message send to "super", which fills in the
4267// most likely case of forwarding all of our arguments to the superclass
4268// function.
4269///
4270/// \param S The semantic analysis object.
4271///
4272/// \param S NeedSuperKeyword Whether we need to prefix this completion with
4273/// the "super" keyword. Otherwise, we just need to provide the arguments.
4274///
4275/// \param SelIdents The identifiers in the selector that have already been
4276/// provided as arguments for a send to "super".
4277///
4278/// \param NumSelIdents The number of identifiers in \p SelIdents.
4279///
4280/// \param Results The set of results to augment.
4281///
4282/// \returns the Objective-C method declaration that would be invoked by
4283/// this "super" completion. If NULL, no completion was added.
4284static ObjCMethodDecl *AddSuperSendCompletion(Sema &S, bool NeedSuperKeyword,
4285 IdentifierInfo **SelIdents,
4286 unsigned NumSelIdents,
4287 ResultBuilder &Results) {
4288 ObjCMethodDecl *CurMethod = S.getCurMethodDecl();
4289 if (!CurMethod)
4290 return 0;
4291
4292 ObjCInterfaceDecl *Class = CurMethod->getClassInterface();
4293 if (!Class)
4294 return 0;
4295
4296 // Try to find a superclass method with the same selector.
4297 ObjCMethodDecl *SuperMethod = 0;
4298 while ((Class = Class->getSuperClass()) && !SuperMethod)
4299 SuperMethod = Class->getMethod(CurMethod->getSelector(),
4300 CurMethod->isInstanceMethod());
4301
4302 if (!SuperMethod)
4303 return 0;
4304
4305 // Check whether the superclass method has the same signature.
4306 if (CurMethod->param_size() != SuperMethod->param_size() ||
4307 CurMethod->isVariadic() != SuperMethod->isVariadic())
4308 return 0;
4309
4310 for (ObjCMethodDecl::param_iterator CurP = CurMethod->param_begin(),
4311 CurPEnd = CurMethod->param_end(),
4312 SuperP = SuperMethod->param_begin();
4313 CurP != CurPEnd; ++CurP, ++SuperP) {
4314 // Make sure the parameter types are compatible.
4315 if (!S.Context.hasSameUnqualifiedType((*CurP)->getType(),
4316 (*SuperP)->getType()))
4317 return 0;
4318
4319 // Make sure we have a parameter name to forward!
4320 if (!(*CurP)->getIdentifier())
4321 return 0;
4322 }
4323
4324 // We have a superclass method. Now, form the send-to-super completion.
4325 CodeCompletionString *Pattern = new CodeCompletionString;
4326
4327 // Give this completion a return type.
4328 AddResultTypeChunk(S.Context, SuperMethod, Pattern);
4329
4330 // If we need the "super" keyword, add it (plus some spacing).
4331 if (NeedSuperKeyword) {
4332 Pattern->AddTypedTextChunk("super");
4333 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
4334 }
4335
4336 Selector Sel = CurMethod->getSelector();
4337 if (Sel.isUnarySelector()) {
4338 if (NeedSuperKeyword)
4339 Pattern->AddTextChunk(Sel.getIdentifierInfoForSlot(0)->getName());
4340 else
4341 Pattern->AddTypedTextChunk(Sel.getIdentifierInfoForSlot(0)->getName());
4342 } else {
4343 ObjCMethodDecl::param_iterator CurP = CurMethod->param_begin();
4344 for (unsigned I = 0, N = Sel.getNumArgs(); I != N; ++I, ++CurP) {
4345 if (I > NumSelIdents)
4346 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
4347
4348 if (I < NumSelIdents)
4349 Pattern->AddInformativeChunk(
4350 Sel.getIdentifierInfoForSlot(I)->getName().str() + ":");
4351 else if (NeedSuperKeyword || I > NumSelIdents) {
4352 Pattern->AddTextChunk(
4353 Sel.getIdentifierInfoForSlot(I)->getName().str() + ":");
4354 Pattern->AddPlaceholderChunk((*CurP)->getIdentifier()->getName());
4355 } else {
4356 Pattern->AddTypedTextChunk(
4357 Sel.getIdentifierInfoForSlot(I)->getName().str() + ":");
4358 Pattern->AddPlaceholderChunk((*CurP)->getIdentifier()->getName());
4359 }
4360 }
4361 }
4362
4363 Results.AddResult(CodeCompletionResult(Pattern, CCP_SuperCompletion,
4364 SuperMethod->isInstanceMethod()
4365 ? CXCursor_ObjCInstanceMethodDecl
4366 : CXCursor_ObjCClassMethodDecl));
4367 return SuperMethod;
4368}
4369
Douglas Gregor8e254cf2010-05-27 23:06:34 +00004370void Sema::CodeCompleteObjCMessageReceiver(Scope *S) {
John McCall0a2c5e22010-08-25 06:19:51 +00004371 typedef CodeCompletionResult Result;
Douglas Gregor8e254cf2010-05-27 23:06:34 +00004372 ResultBuilder Results(*this);
4373
4374 // Find anything that looks like it could be a message receiver.
4375 Results.setFilter(&ResultBuilder::IsObjCMessageReceiver);
Douglas Gregorcee9ff12010-09-20 22:39:41 +00004376 Results.setCompletionContext(CodeCompletionContext::CCC_ObjCMessageReceiver);
4377
Douglas Gregor8e254cf2010-05-27 23:06:34 +00004378 CodeCompletionDeclConsumer Consumer(Results, CurContext);
4379 Results.EnterNewScope();
Douglas Gregor8071e422010-08-15 06:18:01 +00004380 LookupVisibleDecls(S, LookupOrdinaryName, Consumer,
4381 CodeCompleter->includeGlobals());
Douglas Gregor8e254cf2010-05-27 23:06:34 +00004382
4383 // If we are in an Objective-C method inside a class that has a superclass,
4384 // add "super" as an option.
4385 if (ObjCMethodDecl *Method = getCurMethodDecl())
4386 if (ObjCInterfaceDecl *Iface = Method->getClassInterface())
Douglas Gregor03d8aec2010-08-27 15:10:57 +00004387 if (Iface->getSuperClass()) {
Douglas Gregor8e254cf2010-05-27 23:06:34 +00004388 Results.AddResult(Result("super"));
Douglas Gregor03d8aec2010-08-27 15:10:57 +00004389
4390 AddSuperSendCompletion(*this, /*NeedSuperKeyword=*/true, 0, 0, Results);
4391 }
Douglas Gregor8e254cf2010-05-27 23:06:34 +00004392
4393 Results.ExitScope();
4394
4395 if (CodeCompleter->includeMacros())
4396 AddMacroResults(PP, Results);
Douglas Gregorcee9ff12010-09-20 22:39:41 +00004397 HandleCodeCompleteResults(this, CodeCompleter, Results.getCompletionContext(),
Douglas Gregore6b1bb62010-08-11 21:23:17 +00004398 Results.data(), Results.size());
Douglas Gregor8e254cf2010-05-27 23:06:34 +00004399
4400}
4401
Douglas Gregor2725ca82010-04-21 19:57:20 +00004402void Sema::CodeCompleteObjCSuperMessage(Scope *S, SourceLocation SuperLoc,
4403 IdentifierInfo **SelIdents,
Douglas Gregor70c5ac72010-09-20 23:34:21 +00004404 unsigned NumSelIdents,
4405 bool AtArgumentExpression) {
Douglas Gregor2725ca82010-04-21 19:57:20 +00004406 ObjCInterfaceDecl *CDecl = 0;
4407 if (ObjCMethodDecl *CurMethod = getCurMethodDecl()) {
4408 // Figure out which interface we're in.
4409 CDecl = CurMethod->getClassInterface();
4410 if (!CDecl)
4411 return;
4412
4413 // Find the superclass of this class.
4414 CDecl = CDecl->getSuperClass();
4415 if (!CDecl)
4416 return;
4417
4418 if (CurMethod->isInstanceMethod()) {
4419 // We are inside an instance method, which means that the message
4420 // send [super ...] is actually calling an instance method on the
4421 // current object. Build the super expression and handle this like
4422 // an instance method.
4423 QualType SuperTy = Context.getObjCInterfaceType(CDecl);
4424 SuperTy = Context.getObjCObjectPointerType(SuperTy);
John McCall60d7b3a2010-08-24 06:29:42 +00004425 ExprResult Super
Douglas Gregor2725ca82010-04-21 19:57:20 +00004426 = Owned(new (Context) ObjCSuperExpr(SuperLoc, SuperTy));
4427 return CodeCompleteObjCInstanceMessage(S, (Expr *)Super.get(),
Douglas Gregor03d8aec2010-08-27 15:10:57 +00004428 SelIdents, NumSelIdents,
Douglas Gregor70c5ac72010-09-20 23:34:21 +00004429 AtArgumentExpression,
Douglas Gregor03d8aec2010-08-27 15:10:57 +00004430 /*IsSuper=*/true);
Douglas Gregor2725ca82010-04-21 19:57:20 +00004431 }
4432
4433 // Fall through to send to the superclass in CDecl.
4434 } else {
4435 // "super" may be the name of a type or variable. Figure out which
4436 // it is.
4437 IdentifierInfo *Super = &Context.Idents.get("super");
4438 NamedDecl *ND = LookupSingleName(S, Super, SuperLoc,
4439 LookupOrdinaryName);
4440 if ((CDecl = dyn_cast_or_null<ObjCInterfaceDecl>(ND))) {
4441 // "super" names an interface. Use it.
4442 } else if (TypeDecl *TD = dyn_cast_or_null<TypeDecl>(ND)) {
John McCallc12c5bb2010-05-15 11:32:37 +00004443 if (const ObjCObjectType *Iface
4444 = Context.getTypeDeclType(TD)->getAs<ObjCObjectType>())
4445 CDecl = Iface->getInterface();
Douglas Gregor2725ca82010-04-21 19:57:20 +00004446 } else if (ND && isa<UnresolvedUsingTypenameDecl>(ND)) {
4447 // "super" names an unresolved type; we can't be more specific.
4448 } else {
4449 // Assume that "super" names some kind of value and parse that way.
4450 CXXScopeSpec SS;
4451 UnqualifiedId id;
4452 id.setIdentifier(Super, SuperLoc);
John McCall60d7b3a2010-08-24 06:29:42 +00004453 ExprResult SuperExpr = ActOnIdExpression(S, SS, id, false, false);
Douglas Gregor2725ca82010-04-21 19:57:20 +00004454 return CodeCompleteObjCInstanceMessage(S, (Expr *)SuperExpr.get(),
Douglas Gregor70c5ac72010-09-20 23:34:21 +00004455 SelIdents, NumSelIdents,
4456 AtArgumentExpression);
Douglas Gregor2725ca82010-04-21 19:57:20 +00004457 }
4458
4459 // Fall through
4460 }
4461
John McCallb3d87482010-08-24 05:47:05 +00004462 ParsedType Receiver;
Douglas Gregor2725ca82010-04-21 19:57:20 +00004463 if (CDecl)
John McCallb3d87482010-08-24 05:47:05 +00004464 Receiver = ParsedType::make(Context.getObjCInterfaceType(CDecl));
Douglas Gregor2725ca82010-04-21 19:57:20 +00004465 return CodeCompleteObjCClassMessage(S, Receiver, SelIdents,
Douglas Gregor70c5ac72010-09-20 23:34:21 +00004466 NumSelIdents, AtArgumentExpression,
4467 /*IsSuper=*/true);
Douglas Gregor2725ca82010-04-21 19:57:20 +00004468}
4469
Douglas Gregorb9d77572010-09-21 00:03:25 +00004470/// \brief Given a set of code-completion results for the argument of a message
4471/// send, determine the preferred type (if any) for that argument expression.
4472static QualType getPreferredArgumentTypeForMessageSend(ResultBuilder &Results,
4473 unsigned NumSelIdents) {
4474 typedef CodeCompletionResult Result;
4475 ASTContext &Context = Results.getSema().Context;
4476
4477 QualType PreferredType;
4478 unsigned BestPriority = CCP_Unlikely * 2;
4479 Result *ResultsData = Results.data();
4480 for (unsigned I = 0, N = Results.size(); I != N; ++I) {
4481 Result &R = ResultsData[I];
4482 if (R.Kind == Result::RK_Declaration &&
4483 isa<ObjCMethodDecl>(R.Declaration)) {
4484 if (R.Priority <= BestPriority) {
4485 ObjCMethodDecl *Method = cast<ObjCMethodDecl>(R.Declaration);
4486 if (NumSelIdents <= Method->param_size()) {
4487 QualType MyPreferredType = Method->param_begin()[NumSelIdents - 1]
4488 ->getType();
4489 if (R.Priority < BestPriority || PreferredType.isNull()) {
4490 BestPriority = R.Priority;
4491 PreferredType = MyPreferredType;
4492 } else if (!Context.hasSameUnqualifiedType(PreferredType,
4493 MyPreferredType)) {
4494 PreferredType = QualType();
4495 }
4496 }
4497 }
4498 }
4499 }
4500
4501 return PreferredType;
4502}
4503
Douglas Gregorc7b6d882010-09-16 15:14:18 +00004504static void AddClassMessageCompletions(Sema &SemaRef, Scope *S,
4505 ParsedType Receiver,
4506 IdentifierInfo **SelIdents,
4507 unsigned NumSelIdents,
Douglas Gregor70c5ac72010-09-20 23:34:21 +00004508 bool AtArgumentExpression,
Douglas Gregorc7b6d882010-09-16 15:14:18 +00004509 bool IsSuper,
4510 ResultBuilder &Results) {
John McCall0a2c5e22010-08-25 06:19:51 +00004511 typedef CodeCompletionResult Result;
Douglas Gregor24a069f2009-11-17 17:59:40 +00004512 ObjCInterfaceDecl *CDecl = 0;
Douglas Gregorc7b6d882010-09-16 15:14:18 +00004513
Douglas Gregor24a069f2009-11-17 17:59:40 +00004514 // If the given name refers to an interface type, retrieve the
4515 // corresponding declaration.
Douglas Gregor2725ca82010-04-21 19:57:20 +00004516 if (Receiver) {
Douglas Gregorc7b6d882010-09-16 15:14:18 +00004517 QualType T = SemaRef.GetTypeFromParser(Receiver, 0);
Douglas Gregor2725ca82010-04-21 19:57:20 +00004518 if (!T.isNull())
John McCallc12c5bb2010-05-15 11:32:37 +00004519 if (const ObjCObjectType *Interface = T->getAs<ObjCObjectType>())
4520 CDecl = Interface->getInterface();
Douglas Gregor24a069f2009-11-17 17:59:40 +00004521 }
Douglas Gregorc7b6d882010-09-16 15:14:18 +00004522
Douglas Gregor36ecb042009-11-17 23:22:23 +00004523 // Add all of the factory methods in this Objective-C class, its protocols,
4524 // superclasses, categories, implementation, etc.
Steve Naroffc4df6d22009-11-07 02:08:14 +00004525 Results.EnterNewScope();
Douglas Gregorc7b6d882010-09-16 15:14:18 +00004526
Douglas Gregor03d8aec2010-08-27 15:10:57 +00004527 // If this is a send-to-super, try to add the special "super" send
4528 // completion.
4529 if (IsSuper) {
4530 if (ObjCMethodDecl *SuperMethod
Douglas Gregorc7b6d882010-09-16 15:14:18 +00004531 = AddSuperSendCompletion(SemaRef, false, SelIdents, NumSelIdents,
4532 Results))
Douglas Gregor03d8aec2010-08-27 15:10:57 +00004533 Results.Ignore(SuperMethod);
4534 }
Douglas Gregorc7b6d882010-09-16 15:14:18 +00004535
Douglas Gregor265f7492010-08-27 15:29:55 +00004536 // If we're inside an Objective-C method definition, prefer its selector to
4537 // others.
Douglas Gregorc7b6d882010-09-16 15:14:18 +00004538 if (ObjCMethodDecl *CurMethod = SemaRef.getCurMethodDecl())
Douglas Gregor265f7492010-08-27 15:29:55 +00004539 Results.setPreferredSelector(CurMethod->getSelector());
Douglas Gregorc7b6d882010-09-16 15:14:18 +00004540
Douglas Gregord36adf52010-09-16 16:06:31 +00004541 VisitedSelectorSet Selectors;
Douglas Gregor13438f92010-04-06 16:40:00 +00004542 if (CDecl)
Douglas Gregorc7b6d882010-09-16 15:14:18 +00004543 AddObjCMethods(CDecl, false, MK_Any, SelIdents, NumSelIdents,
Douglas Gregord36adf52010-09-16 16:06:31 +00004544 SemaRef.CurContext, Selectors, Results);
Douglas Gregor2725ca82010-04-21 19:57:20 +00004545 else {
Douglas Gregor13438f92010-04-06 16:40:00 +00004546 // We're messaging "id" as a type; provide all class/factory methods.
Douglas Gregorc7b6d882010-09-16 15:14:18 +00004547
Douglas Gregor719770d2010-04-06 17:30:22 +00004548 // If we have an external source, load the entire class method
Sebastian Redl3c7f4132010-08-18 23:57:06 +00004549 // pool from the AST file.
Douglas Gregorc7b6d882010-09-16 15:14:18 +00004550 if (SemaRef.ExternalSource) {
4551 for (uint32_t I = 0,
4552 N = SemaRef.ExternalSource->GetNumExternalSelectors();
John McCall76bd1f32010-06-01 09:23:16 +00004553 I != N; ++I) {
Douglas Gregorc7b6d882010-09-16 15:14:18 +00004554 Selector Sel = SemaRef.ExternalSource->GetExternalSelector(I);
4555 if (Sel.isNull() || SemaRef.MethodPool.count(Sel))
Douglas Gregor719770d2010-04-06 17:30:22 +00004556 continue;
Douglas Gregorc7b6d882010-09-16 15:14:18 +00004557
4558 SemaRef.ReadMethodPool(Sel);
Douglas Gregor719770d2010-04-06 17:30:22 +00004559 }
4560 }
Douglas Gregorc7b6d882010-09-16 15:14:18 +00004561
4562 for (Sema::GlobalMethodPool::iterator M = SemaRef.MethodPool.begin(),
4563 MEnd = SemaRef.MethodPool.end();
Sebastian Redldb9d2142010-08-02 23:18:59 +00004564 M != MEnd; ++M) {
4565 for (ObjCMethodList *MethList = &M->second.second;
4566 MethList && MethList->Method;
Douglas Gregor13438f92010-04-06 16:40:00 +00004567 MethList = MethList->Next) {
4568 if (!isAcceptableObjCMethod(MethList->Method, MK_Any, SelIdents,
4569 NumSelIdents))
4570 continue;
Douglas Gregorc7b6d882010-09-16 15:14:18 +00004571
Douglas Gregor13438f92010-04-06 16:40:00 +00004572 Result R(MethList->Method, 0);
4573 R.StartParameter = NumSelIdents;
4574 R.AllParametersAreInformative = false;
Douglas Gregorc7b6d882010-09-16 15:14:18 +00004575 Results.MaybeAddResult(R, SemaRef.CurContext);
Douglas Gregor13438f92010-04-06 16:40:00 +00004576 }
4577 }
4578 }
Douglas Gregorc7b6d882010-09-16 15:14:18 +00004579
4580 Results.ExitScope();
4581}
Douglas Gregor13438f92010-04-06 16:40:00 +00004582
Douglas Gregorc7b6d882010-09-16 15:14:18 +00004583void Sema::CodeCompleteObjCClassMessage(Scope *S, ParsedType Receiver,
4584 IdentifierInfo **SelIdents,
4585 unsigned NumSelIdents,
Douglas Gregor70c5ac72010-09-20 23:34:21 +00004586 bool AtArgumentExpression,
Douglas Gregorc7b6d882010-09-16 15:14:18 +00004587 bool IsSuper) {
4588 ResultBuilder Results(*this);
Douglas Gregor70c5ac72010-09-20 23:34:21 +00004589 AddClassMessageCompletions(*this, S, Receiver, SelIdents, NumSelIdents,
4590 AtArgumentExpression, IsSuper, Results);
Douglas Gregorb9d77572010-09-21 00:03:25 +00004591
4592 // If we're actually at the argument expression (rather than prior to the
4593 // selector), we're actually performing code completion for an expression.
4594 // Determine whether we have a single, best method. If so, we can
4595 // code-complete the expression using the corresponding parameter type as
4596 // our preferred type, improving completion results.
4597 if (AtArgumentExpression) {
4598 QualType PreferredType = getPreferredArgumentTypeForMessageSend(Results,
4599 NumSelIdents);
4600 if (PreferredType.isNull())
4601 CodeCompleteOrdinaryName(S, PCC_Expression);
4602 else
4603 CodeCompleteExpression(S, PreferredType);
4604 return;
4605 }
4606
Douglas Gregore6b1bb62010-08-11 21:23:17 +00004607 HandleCodeCompleteResults(this, CodeCompleter,
4608 CodeCompletionContext::CCC_Other,
Douglas Gregor03d8aec2010-08-27 15:10:57 +00004609 Results.data(), Results.size());
Steve Naroffc4df6d22009-11-07 02:08:14 +00004610}
4611
Douglas Gregord3c68542009-11-19 01:08:35 +00004612void Sema::CodeCompleteObjCInstanceMessage(Scope *S, ExprTy *Receiver,
4613 IdentifierInfo **SelIdents,
Douglas Gregor03d8aec2010-08-27 15:10:57 +00004614 unsigned NumSelIdents,
Douglas Gregor70c5ac72010-09-20 23:34:21 +00004615 bool AtArgumentExpression,
Douglas Gregor03d8aec2010-08-27 15:10:57 +00004616 bool IsSuper) {
John McCall0a2c5e22010-08-25 06:19:51 +00004617 typedef CodeCompletionResult Result;
Steve Naroffc4df6d22009-11-07 02:08:14 +00004618
4619 Expr *RecExpr = static_cast<Expr *>(Receiver);
Steve Naroffc4df6d22009-11-07 02:08:14 +00004620
Douglas Gregor36ecb042009-11-17 23:22:23 +00004621 // If necessary, apply function/array conversion to the receiver.
4622 // C99 6.7.5.3p[7,8].
Douglas Gregor78edf512010-09-15 16:23:04 +00004623 if (RecExpr)
4624 DefaultFunctionArrayLvalueConversion(RecExpr);
4625 QualType ReceiverType = RecExpr? RecExpr->getType() : Context.getObjCIdType();
Steve Naroffc4df6d22009-11-07 02:08:14 +00004626
Douglas Gregor36ecb042009-11-17 23:22:23 +00004627 // Build the set of methods we can see.
4628 ResultBuilder Results(*this);
4629 Results.EnterNewScope();
Douglas Gregor22f56992010-04-06 19:22:33 +00004630
Douglas Gregor03d8aec2010-08-27 15:10:57 +00004631 // If this is a send-to-super, try to add the special "super" send
4632 // completion.
4633 if (IsSuper) {
4634 if (ObjCMethodDecl *SuperMethod
4635 = AddSuperSendCompletion(*this, false, SelIdents, NumSelIdents,
4636 Results))
4637 Results.Ignore(SuperMethod);
4638 }
4639
Douglas Gregor265f7492010-08-27 15:29:55 +00004640 // If we're inside an Objective-C method definition, prefer its selector to
4641 // others.
4642 if (ObjCMethodDecl *CurMethod = getCurMethodDecl())
4643 Results.setPreferredSelector(CurMethod->getSelector());
4644
Douglas Gregor22f56992010-04-06 19:22:33 +00004645 // If we're messaging an expression with type "id" or "Class", check
4646 // whether we know something special about the receiver that allows
4647 // us to assume a more-specific receiver type.
4648 if (ReceiverType->isObjCIdType() || ReceiverType->isObjCClassType())
4649 if (ObjCInterfaceDecl *IFace = GetAssumedMessageSendExprType(RecExpr))
4650 ReceiverType = Context.getObjCObjectPointerType(
4651 Context.getObjCInterfaceType(IFace));
Douglas Gregor36ecb042009-11-17 23:22:23 +00004652
Douglas Gregord36adf52010-09-16 16:06:31 +00004653 // Keep track of the selectors we've already added.
4654 VisitedSelectorSet Selectors;
4655
Douglas Gregorf74a4192009-11-18 00:06:18 +00004656 // Handle messages to Class. This really isn't a message to an instance
4657 // method, so we treat it the same way we would treat a message send to a
4658 // class method.
4659 if (ReceiverType->isObjCClassType() ||
4660 ReceiverType->isObjCQualifiedClassType()) {
4661 if (ObjCMethodDecl *CurMethod = getCurMethodDecl()) {
4662 if (ObjCInterfaceDecl *ClassDecl = CurMethod->getClassInterface())
Douglas Gregor4ad96852009-11-19 07:41:15 +00004663 AddObjCMethods(ClassDecl, false, MK_Any, SelIdents, NumSelIdents,
Douglas Gregord36adf52010-09-16 16:06:31 +00004664 CurContext, Selectors, Results);
Douglas Gregorf74a4192009-11-18 00:06:18 +00004665 }
4666 }
4667 // Handle messages to a qualified ID ("id<foo>").
4668 else if (const ObjCObjectPointerType *QualID
4669 = ReceiverType->getAsObjCQualifiedIdType()) {
4670 // Search protocols for instance methods.
4671 for (ObjCObjectPointerType::qual_iterator I = QualID->qual_begin(),
4672 E = QualID->qual_end();
4673 I != E; ++I)
Douglas Gregor4ad96852009-11-19 07:41:15 +00004674 AddObjCMethods(*I, true, MK_Any, SelIdents, NumSelIdents, CurContext,
Douglas Gregord36adf52010-09-16 16:06:31 +00004675 Selectors, Results);
Douglas Gregorf74a4192009-11-18 00:06:18 +00004676 }
4677 // Handle messages to a pointer to interface type.
4678 else if (const ObjCObjectPointerType *IFacePtr
4679 = ReceiverType->getAsObjCInterfacePointerType()) {
4680 // Search the class, its superclasses, etc., for instance methods.
Douglas Gregor4ad96852009-11-19 07:41:15 +00004681 AddObjCMethods(IFacePtr->getInterfaceDecl(), true, MK_Any, SelIdents,
Douglas Gregord36adf52010-09-16 16:06:31 +00004682 NumSelIdents, CurContext, Selectors, Results);
Douglas Gregorf74a4192009-11-18 00:06:18 +00004683
4684 // Search protocols for instance methods.
4685 for (ObjCObjectPointerType::qual_iterator I = IFacePtr->qual_begin(),
4686 E = IFacePtr->qual_end();
4687 I != E; ++I)
Douglas Gregor4ad96852009-11-19 07:41:15 +00004688 AddObjCMethods(*I, true, MK_Any, SelIdents, NumSelIdents, CurContext,
Douglas Gregord36adf52010-09-16 16:06:31 +00004689 Selectors, Results);
Douglas Gregorf74a4192009-11-18 00:06:18 +00004690 }
Douglas Gregor13438f92010-04-06 16:40:00 +00004691 // Handle messages to "id".
4692 else if (ReceiverType->isObjCIdType()) {
Douglas Gregor719770d2010-04-06 17:30:22 +00004693 // We're messaging "id", so provide all instance methods we know
4694 // about as code-completion results.
4695
4696 // If we have an external source, load the entire class method
Sebastian Redl3c7f4132010-08-18 23:57:06 +00004697 // pool from the AST file.
Douglas Gregor719770d2010-04-06 17:30:22 +00004698 if (ExternalSource) {
John McCall76bd1f32010-06-01 09:23:16 +00004699 for (uint32_t I = 0, N = ExternalSource->GetNumExternalSelectors();
4700 I != N; ++I) {
4701 Selector Sel = ExternalSource->GetExternalSelector(I);
Sebastian Redldb9d2142010-08-02 23:18:59 +00004702 if (Sel.isNull() || MethodPool.count(Sel))
Douglas Gregor719770d2010-04-06 17:30:22 +00004703 continue;
4704
Sebastian Redldb9d2142010-08-02 23:18:59 +00004705 ReadMethodPool(Sel);
Douglas Gregor719770d2010-04-06 17:30:22 +00004706 }
4707 }
4708
Sebastian Redldb9d2142010-08-02 23:18:59 +00004709 for (GlobalMethodPool::iterator M = MethodPool.begin(),
4710 MEnd = MethodPool.end();
4711 M != MEnd; ++M) {
4712 for (ObjCMethodList *MethList = &M->second.first;
4713 MethList && MethList->Method;
Douglas Gregor13438f92010-04-06 16:40:00 +00004714 MethList = MethList->Next) {
4715 if (!isAcceptableObjCMethod(MethList->Method, MK_Any, SelIdents,
4716 NumSelIdents))
4717 continue;
Douglas Gregord36adf52010-09-16 16:06:31 +00004718
4719 if (!Selectors.insert(MethList->Method->getSelector()))
4720 continue;
4721
Douglas Gregor13438f92010-04-06 16:40:00 +00004722 Result R(MethList->Method, 0);
4723 R.StartParameter = NumSelIdents;
4724 R.AllParametersAreInformative = false;
4725 Results.MaybeAddResult(R, CurContext);
4726 }
4727 }
4728 }
Steve Naroffc4df6d22009-11-07 02:08:14 +00004729 Results.ExitScope();
Douglas Gregorb9d77572010-09-21 00:03:25 +00004730
4731
4732 // If we're actually at the argument expression (rather than prior to the
4733 // selector), we're actually performing code completion for an expression.
4734 // Determine whether we have a single, best method. If so, we can
4735 // code-complete the expression using the corresponding parameter type as
4736 // our preferred type, improving completion results.
4737 if (AtArgumentExpression) {
4738 QualType PreferredType = getPreferredArgumentTypeForMessageSend(Results,
4739 NumSelIdents);
4740 if (PreferredType.isNull())
4741 CodeCompleteOrdinaryName(S, PCC_Expression);
4742 else
4743 CodeCompleteExpression(S, PreferredType);
4744 return;
4745 }
4746
Douglas Gregore6b1bb62010-08-11 21:23:17 +00004747 HandleCodeCompleteResults(this, CodeCompleter,
4748 CodeCompletionContext::CCC_Other,
4749 Results.data(),Results.size());
Steve Naroffc4df6d22009-11-07 02:08:14 +00004750}
Douglas Gregor55385fe2009-11-18 04:19:12 +00004751
Douglas Gregorfb629412010-08-23 21:17:50 +00004752void Sema::CodeCompleteObjCForCollection(Scope *S,
4753 DeclGroupPtrTy IterationVar) {
4754 CodeCompleteExpressionData Data;
4755 Data.ObjCCollection = true;
4756
4757 if (IterationVar.getAsOpaquePtr()) {
4758 DeclGroupRef DG = IterationVar.getAsVal<DeclGroupRef>();
4759 for (DeclGroupRef::iterator I = DG.begin(), End = DG.end(); I != End; ++I) {
4760 if (*I)
4761 Data.IgnoreDecls.push_back(*I);
4762 }
4763 }
4764
4765 CodeCompleteExpression(S, Data);
4766}
4767
Douglas Gregor458433d2010-08-26 15:07:07 +00004768void Sema::CodeCompleteObjCSelector(Scope *S, IdentifierInfo **SelIdents,
4769 unsigned NumSelIdents) {
4770 // If we have an external source, load the entire class method
4771 // pool from the AST file.
4772 if (ExternalSource) {
4773 for (uint32_t I = 0, N = ExternalSource->GetNumExternalSelectors();
4774 I != N; ++I) {
4775 Selector Sel = ExternalSource->GetExternalSelector(I);
4776 if (Sel.isNull() || MethodPool.count(Sel))
4777 continue;
4778
4779 ReadMethodPool(Sel);
4780 }
4781 }
4782
4783 ResultBuilder Results(*this);
4784 Results.EnterNewScope();
4785 for (GlobalMethodPool::iterator M = MethodPool.begin(),
4786 MEnd = MethodPool.end();
4787 M != MEnd; ++M) {
4788
4789 Selector Sel = M->first;
4790 if (!isAcceptableObjCSelector(Sel, MK_Any, SelIdents, NumSelIdents))
4791 continue;
4792
4793 CodeCompletionString *Pattern = new CodeCompletionString;
4794 if (Sel.isUnarySelector()) {
4795 Pattern->AddTypedTextChunk(Sel.getIdentifierInfoForSlot(0)->getName());
4796 Results.AddResult(Pattern);
4797 continue;
4798 }
4799
Douglas Gregor2d9e21f2010-08-26 16:46:39 +00004800 std::string Accumulator;
Douglas Gregor458433d2010-08-26 15:07:07 +00004801 for (unsigned I = 0, N = Sel.getNumArgs(); I != N; ++I) {
Douglas Gregor2d9e21f2010-08-26 16:46:39 +00004802 if (I == NumSelIdents) {
4803 if (!Accumulator.empty()) {
4804 Pattern->AddInformativeChunk(Accumulator);
4805 Accumulator.clear();
4806 }
4807 }
4808
4809 Accumulator += Sel.getIdentifierInfoForSlot(I)->getName().str();
4810 Accumulator += ':';
Douglas Gregor458433d2010-08-26 15:07:07 +00004811 }
Douglas Gregor2d9e21f2010-08-26 16:46:39 +00004812 Pattern->AddTypedTextChunk(Accumulator);
Douglas Gregor458433d2010-08-26 15:07:07 +00004813 Results.AddResult(Pattern);
4814 }
4815 Results.ExitScope();
4816
4817 HandleCodeCompleteResults(this, CodeCompleter,
4818 CodeCompletionContext::CCC_SelectorName,
4819 Results.data(), Results.size());
4820}
4821
Douglas Gregor55385fe2009-11-18 04:19:12 +00004822/// \brief Add all of the protocol declarations that we find in the given
4823/// (translation unit) context.
4824static void AddProtocolResults(DeclContext *Ctx, DeclContext *CurContext,
Douglas Gregor083128f2009-11-18 04:49:41 +00004825 bool OnlyForwardDeclarations,
Douglas Gregor55385fe2009-11-18 04:19:12 +00004826 ResultBuilder &Results) {
John McCall0a2c5e22010-08-25 06:19:51 +00004827 typedef CodeCompletionResult Result;
Douglas Gregor55385fe2009-11-18 04:19:12 +00004828
4829 for (DeclContext::decl_iterator D = Ctx->decls_begin(),
4830 DEnd = Ctx->decls_end();
4831 D != DEnd; ++D) {
4832 // Record any protocols we find.
4833 if (ObjCProtocolDecl *Proto = dyn_cast<ObjCProtocolDecl>(*D))
Douglas Gregor083128f2009-11-18 04:49:41 +00004834 if (!OnlyForwardDeclarations || Proto->isForwardDecl())
Douglas Gregor608300b2010-01-14 16:14:35 +00004835 Results.AddResult(Result(Proto, 0), CurContext, 0, false);
Douglas Gregor55385fe2009-11-18 04:19:12 +00004836
4837 // Record any forward-declared protocols we find.
4838 if (ObjCForwardProtocolDecl *Forward
4839 = dyn_cast<ObjCForwardProtocolDecl>(*D)) {
4840 for (ObjCForwardProtocolDecl::protocol_iterator
4841 P = Forward->protocol_begin(),
4842 PEnd = Forward->protocol_end();
4843 P != PEnd; ++P)
Douglas Gregor083128f2009-11-18 04:49:41 +00004844 if (!OnlyForwardDeclarations || (*P)->isForwardDecl())
Douglas Gregor608300b2010-01-14 16:14:35 +00004845 Results.AddResult(Result(*P, 0), CurContext, 0, false);
Douglas Gregor55385fe2009-11-18 04:19:12 +00004846 }
4847 }
4848}
4849
4850void Sema::CodeCompleteObjCProtocolReferences(IdentifierLocPair *Protocols,
4851 unsigned NumProtocols) {
4852 ResultBuilder Results(*this);
4853 Results.EnterNewScope();
4854
4855 // Tell the result set to ignore all of the protocols we have
4856 // already seen.
4857 for (unsigned I = 0; I != NumProtocols; ++I)
Douglas Gregorc83c6872010-04-15 22:33:43 +00004858 if (ObjCProtocolDecl *Protocol = LookupProtocol(Protocols[I].first,
4859 Protocols[I].second))
Douglas Gregor55385fe2009-11-18 04:19:12 +00004860 Results.Ignore(Protocol);
4861
4862 // Add all protocols.
Douglas Gregor083128f2009-11-18 04:49:41 +00004863 AddProtocolResults(Context.getTranslationUnitDecl(), CurContext, false,
4864 Results);
4865
4866 Results.ExitScope();
Douglas Gregore6b1bb62010-08-11 21:23:17 +00004867 HandleCodeCompleteResults(this, CodeCompleter,
4868 CodeCompletionContext::CCC_ObjCProtocolName,
4869 Results.data(),Results.size());
Douglas Gregor083128f2009-11-18 04:49:41 +00004870}
4871
4872void Sema::CodeCompleteObjCProtocolDecl(Scope *) {
4873 ResultBuilder Results(*this);
4874 Results.EnterNewScope();
4875
4876 // Add all protocols.
4877 AddProtocolResults(Context.getTranslationUnitDecl(), CurContext, true,
4878 Results);
Douglas Gregor55385fe2009-11-18 04:19:12 +00004879
4880 Results.ExitScope();
Douglas Gregore6b1bb62010-08-11 21:23:17 +00004881 HandleCodeCompleteResults(this, CodeCompleter,
4882 CodeCompletionContext::CCC_ObjCProtocolName,
4883 Results.data(),Results.size());
Douglas Gregor55385fe2009-11-18 04:19:12 +00004884}
Douglas Gregor3b49aca2009-11-18 16:26:39 +00004885
4886/// \brief Add all of the Objective-C interface declarations that we find in
4887/// the given (translation unit) context.
4888static void AddInterfaceResults(DeclContext *Ctx, DeclContext *CurContext,
4889 bool OnlyForwardDeclarations,
4890 bool OnlyUnimplemented,
4891 ResultBuilder &Results) {
John McCall0a2c5e22010-08-25 06:19:51 +00004892 typedef CodeCompletionResult Result;
Douglas Gregor3b49aca2009-11-18 16:26:39 +00004893
4894 for (DeclContext::decl_iterator D = Ctx->decls_begin(),
4895 DEnd = Ctx->decls_end();
4896 D != DEnd; ++D) {
Douglas Gregordeacbdc2010-08-11 12:19:30 +00004897 // Record any interfaces we find.
4898 if (ObjCInterfaceDecl *Class = dyn_cast<ObjCInterfaceDecl>(*D))
4899 if ((!OnlyForwardDeclarations || Class->isForwardDecl()) &&
4900 (!OnlyUnimplemented || !Class->getImplementation()))
4901 Results.AddResult(Result(Class, 0), CurContext, 0, false);
Douglas Gregor3b49aca2009-11-18 16:26:39 +00004902
4903 // Record any forward-declared interfaces we find.
4904 if (ObjCClassDecl *Forward = dyn_cast<ObjCClassDecl>(*D)) {
4905 for (ObjCClassDecl::iterator C = Forward->begin(), CEnd = Forward->end();
Douglas Gregordeacbdc2010-08-11 12:19:30 +00004906 C != CEnd; ++C)
4907 if ((!OnlyForwardDeclarations || C->getInterface()->isForwardDecl()) &&
4908 (!OnlyUnimplemented || !C->getInterface()->getImplementation()))
4909 Results.AddResult(Result(C->getInterface(), 0), CurContext,
Douglas Gregor608300b2010-01-14 16:14:35 +00004910 0, false);
Douglas Gregor3b49aca2009-11-18 16:26:39 +00004911 }
4912 }
4913}
4914
4915void Sema::CodeCompleteObjCInterfaceDecl(Scope *S) {
4916 ResultBuilder Results(*this);
4917 Results.EnterNewScope();
4918
4919 // Add all classes.
4920 AddInterfaceResults(Context.getTranslationUnitDecl(), CurContext, true,
4921 false, Results);
4922
4923 Results.ExitScope();
Douglas Gregore6b1bb62010-08-11 21:23:17 +00004924 HandleCodeCompleteResults(this, CodeCompleter,
4925 CodeCompletionContext::CCC_Other,
4926 Results.data(),Results.size());
Douglas Gregor3b49aca2009-11-18 16:26:39 +00004927}
4928
Douglas Gregorc83c6872010-04-15 22:33:43 +00004929void Sema::CodeCompleteObjCSuperclass(Scope *S, IdentifierInfo *ClassName,
4930 SourceLocation ClassNameLoc) {
Douglas Gregor3b49aca2009-11-18 16:26:39 +00004931 ResultBuilder Results(*this);
4932 Results.EnterNewScope();
4933
4934 // Make sure that we ignore the class we're currently defining.
4935 NamedDecl *CurClass
Douglas Gregorc83c6872010-04-15 22:33:43 +00004936 = LookupSingleName(TUScope, ClassName, ClassNameLoc, LookupOrdinaryName);
Douglas Gregor33ced0b2009-11-18 19:08:43 +00004937 if (CurClass && isa<ObjCInterfaceDecl>(CurClass))
Douglas Gregor3b49aca2009-11-18 16:26:39 +00004938 Results.Ignore(CurClass);
4939
4940 // Add all classes.
4941 AddInterfaceResults(Context.getTranslationUnitDecl(), CurContext, false,
4942 false, Results);
4943
4944 Results.ExitScope();
Douglas Gregore6b1bb62010-08-11 21:23:17 +00004945 HandleCodeCompleteResults(this, CodeCompleter,
4946 CodeCompletionContext::CCC_Other,
4947 Results.data(),Results.size());
Douglas Gregor3b49aca2009-11-18 16:26:39 +00004948}
4949
4950void Sema::CodeCompleteObjCImplementationDecl(Scope *S) {
4951 ResultBuilder Results(*this);
4952 Results.EnterNewScope();
4953
4954 // Add all unimplemented classes.
4955 AddInterfaceResults(Context.getTranslationUnitDecl(), CurContext, false,
4956 true, Results);
4957
4958 Results.ExitScope();
Douglas Gregore6b1bb62010-08-11 21:23:17 +00004959 HandleCodeCompleteResults(this, CodeCompleter,
4960 CodeCompletionContext::CCC_Other,
4961 Results.data(),Results.size());
Douglas Gregor3b49aca2009-11-18 16:26:39 +00004962}
Douglas Gregor33ced0b2009-11-18 19:08:43 +00004963
4964void Sema::CodeCompleteObjCInterfaceCategory(Scope *S,
Douglas Gregorc83c6872010-04-15 22:33:43 +00004965 IdentifierInfo *ClassName,
4966 SourceLocation ClassNameLoc) {
John McCall0a2c5e22010-08-25 06:19:51 +00004967 typedef CodeCompletionResult Result;
Douglas Gregor33ced0b2009-11-18 19:08:43 +00004968
4969 ResultBuilder Results(*this);
4970
4971 // Ignore any categories we find that have already been implemented by this
4972 // interface.
4973 llvm::SmallPtrSet<IdentifierInfo *, 16> CategoryNames;
4974 NamedDecl *CurClass
Douglas Gregorc83c6872010-04-15 22:33:43 +00004975 = LookupSingleName(TUScope, ClassName, ClassNameLoc, LookupOrdinaryName);
Douglas Gregor33ced0b2009-11-18 19:08:43 +00004976 if (ObjCInterfaceDecl *Class = dyn_cast_or_null<ObjCInterfaceDecl>(CurClass))
4977 for (ObjCCategoryDecl *Category = Class->getCategoryList(); Category;
4978 Category = Category->getNextClassCategory())
4979 CategoryNames.insert(Category->getIdentifier());
4980
4981 // Add all of the categories we know about.
4982 Results.EnterNewScope();
4983 TranslationUnitDecl *TU = Context.getTranslationUnitDecl();
4984 for (DeclContext::decl_iterator D = TU->decls_begin(),
4985 DEnd = TU->decls_end();
4986 D != DEnd; ++D)
4987 if (ObjCCategoryDecl *Category = dyn_cast<ObjCCategoryDecl>(*D))
4988 if (CategoryNames.insert(Category->getIdentifier()))
Douglas Gregor608300b2010-01-14 16:14:35 +00004989 Results.AddResult(Result(Category, 0), CurContext, 0, false);
Douglas Gregor33ced0b2009-11-18 19:08:43 +00004990 Results.ExitScope();
4991
Douglas Gregore6b1bb62010-08-11 21:23:17 +00004992 HandleCodeCompleteResults(this, CodeCompleter,
4993 CodeCompletionContext::CCC_Other,
4994 Results.data(),Results.size());
Douglas Gregor33ced0b2009-11-18 19:08:43 +00004995}
4996
4997void Sema::CodeCompleteObjCImplementationCategory(Scope *S,
Douglas Gregorc83c6872010-04-15 22:33:43 +00004998 IdentifierInfo *ClassName,
4999 SourceLocation ClassNameLoc) {
John McCall0a2c5e22010-08-25 06:19:51 +00005000 typedef CodeCompletionResult Result;
Douglas Gregor33ced0b2009-11-18 19:08:43 +00005001
5002 // Find the corresponding interface. If we couldn't find the interface, the
5003 // program itself is ill-formed. However, we'll try to be helpful still by
5004 // providing the list of all of the categories we know about.
5005 NamedDecl *CurClass
Douglas Gregorc83c6872010-04-15 22:33:43 +00005006 = LookupSingleName(TUScope, ClassName, ClassNameLoc, LookupOrdinaryName);
Douglas Gregor33ced0b2009-11-18 19:08:43 +00005007 ObjCInterfaceDecl *Class = dyn_cast_or_null<ObjCInterfaceDecl>(CurClass);
5008 if (!Class)
Douglas Gregorc83c6872010-04-15 22:33:43 +00005009 return CodeCompleteObjCInterfaceCategory(S, ClassName, ClassNameLoc);
Douglas Gregor33ced0b2009-11-18 19:08:43 +00005010
5011 ResultBuilder Results(*this);
5012
5013 // Add all of the categories that have have corresponding interface
5014 // declarations in this class and any of its superclasses, except for
5015 // already-implemented categories in the class itself.
5016 llvm::SmallPtrSet<IdentifierInfo *, 16> CategoryNames;
5017 Results.EnterNewScope();
5018 bool IgnoreImplemented = true;
5019 while (Class) {
5020 for (ObjCCategoryDecl *Category = Class->getCategoryList(); Category;
5021 Category = Category->getNextClassCategory())
5022 if ((!IgnoreImplemented || !Category->getImplementation()) &&
5023 CategoryNames.insert(Category->getIdentifier()))
Douglas Gregor608300b2010-01-14 16:14:35 +00005024 Results.AddResult(Result(Category, 0), CurContext, 0, false);
Douglas Gregor33ced0b2009-11-18 19:08:43 +00005025
5026 Class = Class->getSuperClass();
5027 IgnoreImplemented = false;
5028 }
5029 Results.ExitScope();
5030
Douglas Gregore6b1bb62010-08-11 21:23:17 +00005031 HandleCodeCompleteResults(this, CodeCompleter,
5032 CodeCompletionContext::CCC_Other,
5033 Results.data(),Results.size());
Douglas Gregor33ced0b2009-11-18 19:08:43 +00005034}
Douglas Gregor322328b2009-11-18 22:32:06 +00005035
John McCalld226f652010-08-21 09:40:31 +00005036void Sema::CodeCompleteObjCPropertyDefinition(Scope *S, Decl *ObjCImpDecl) {
John McCall0a2c5e22010-08-25 06:19:51 +00005037 typedef CodeCompletionResult Result;
Douglas Gregor322328b2009-11-18 22:32:06 +00005038 ResultBuilder Results(*this);
5039
5040 // Figure out where this @synthesize lives.
5041 ObjCContainerDecl *Container
John McCalld226f652010-08-21 09:40:31 +00005042 = dyn_cast_or_null<ObjCContainerDecl>(ObjCImpDecl);
Douglas Gregor322328b2009-11-18 22:32:06 +00005043 if (!Container ||
5044 (!isa<ObjCImplementationDecl>(Container) &&
5045 !isa<ObjCCategoryImplDecl>(Container)))
5046 return;
5047
5048 // Ignore any properties that have already been implemented.
5049 for (DeclContext::decl_iterator D = Container->decls_begin(),
5050 DEnd = Container->decls_end();
5051 D != DEnd; ++D)
5052 if (ObjCPropertyImplDecl *PropertyImpl = dyn_cast<ObjCPropertyImplDecl>(*D))
5053 Results.Ignore(PropertyImpl->getPropertyDecl());
5054
5055 // Add any properties that we find.
5056 Results.EnterNewScope();
5057 if (ObjCImplementationDecl *ClassImpl
5058 = dyn_cast<ObjCImplementationDecl>(Container))
5059 AddObjCProperties(ClassImpl->getClassInterface(), false, CurContext,
5060 Results);
5061 else
5062 AddObjCProperties(cast<ObjCCategoryImplDecl>(Container)->getCategoryDecl(),
5063 false, CurContext, Results);
5064 Results.ExitScope();
5065
Douglas Gregore6b1bb62010-08-11 21:23:17 +00005066 HandleCodeCompleteResults(this, CodeCompleter,
5067 CodeCompletionContext::CCC_Other,
5068 Results.data(),Results.size());
Douglas Gregor322328b2009-11-18 22:32:06 +00005069}
5070
5071void Sema::CodeCompleteObjCPropertySynthesizeIvar(Scope *S,
5072 IdentifierInfo *PropertyName,
John McCalld226f652010-08-21 09:40:31 +00005073 Decl *ObjCImpDecl) {
John McCall0a2c5e22010-08-25 06:19:51 +00005074 typedef CodeCompletionResult Result;
Douglas Gregor322328b2009-11-18 22:32:06 +00005075 ResultBuilder Results(*this);
5076
5077 // Figure out where this @synthesize lives.
5078 ObjCContainerDecl *Container
John McCalld226f652010-08-21 09:40:31 +00005079 = dyn_cast_or_null<ObjCContainerDecl>(ObjCImpDecl);
Douglas Gregor322328b2009-11-18 22:32:06 +00005080 if (!Container ||
5081 (!isa<ObjCImplementationDecl>(Container) &&
5082 !isa<ObjCCategoryImplDecl>(Container)))
5083 return;
5084
5085 // Figure out which interface we're looking into.
5086 ObjCInterfaceDecl *Class = 0;
5087 if (ObjCImplementationDecl *ClassImpl
5088 = dyn_cast<ObjCImplementationDecl>(Container))
5089 Class = ClassImpl->getClassInterface();
5090 else
5091 Class = cast<ObjCCategoryImplDecl>(Container)->getCategoryDecl()
5092 ->getClassInterface();
5093
5094 // Add all of the instance variables in this class and its superclasses.
5095 Results.EnterNewScope();
5096 for(; Class; Class = Class->getSuperClass()) {
5097 // FIXME: We could screen the type of each ivar for compatibility with
5098 // the property, but is that being too paternal?
5099 for (ObjCInterfaceDecl::ivar_iterator IVar = Class->ivar_begin(),
5100 IVarEnd = Class->ivar_end();
5101 IVar != IVarEnd; ++IVar)
Douglas Gregor608300b2010-01-14 16:14:35 +00005102 Results.AddResult(Result(*IVar, 0), CurContext, 0, false);
Douglas Gregor322328b2009-11-18 22:32:06 +00005103 }
5104 Results.ExitScope();
5105
Douglas Gregore6b1bb62010-08-11 21:23:17 +00005106 HandleCodeCompleteResults(this, CodeCompleter,
5107 CodeCompletionContext::CCC_Other,
5108 Results.data(),Results.size());
Douglas Gregor322328b2009-11-18 22:32:06 +00005109}
Douglas Gregore8f5a172010-04-07 00:21:17 +00005110
Douglas Gregor408be5a2010-08-25 01:08:01 +00005111// Mapping from selectors to the methods that implement that selector, along
5112// with the "in original class" flag.
5113typedef llvm::DenseMap<Selector, std::pair<ObjCMethodDecl *, bool> >
5114 KnownMethodsMap;
Douglas Gregore8f5a172010-04-07 00:21:17 +00005115
5116/// \brief Find all of the methods that reside in the given container
5117/// (and its superclasses, protocols, etc.) that meet the given
5118/// criteria. Insert those methods into the map of known methods,
5119/// indexed by selector so they can be easily found.
5120static void FindImplementableMethods(ASTContext &Context,
5121 ObjCContainerDecl *Container,
5122 bool WantInstanceMethods,
5123 QualType ReturnType,
5124 bool IsInImplementation,
Douglas Gregor408be5a2010-08-25 01:08:01 +00005125 KnownMethodsMap &KnownMethods,
5126 bool InOriginalClass = true) {
Douglas Gregore8f5a172010-04-07 00:21:17 +00005127 if (ObjCInterfaceDecl *IFace = dyn_cast<ObjCInterfaceDecl>(Container)) {
5128 // Recurse into protocols.
5129 const ObjCList<ObjCProtocolDecl> &Protocols
5130 = IFace->getReferencedProtocols();
5131 for (ObjCList<ObjCProtocolDecl>::iterator I = Protocols.begin(),
5132 E = Protocols.end();
5133 I != E; ++I)
5134 FindImplementableMethods(Context, *I, WantInstanceMethods, ReturnType,
Douglas Gregor408be5a2010-08-25 01:08:01 +00005135 IsInImplementation, KnownMethods,
5136 InOriginalClass);
Douglas Gregore8f5a172010-04-07 00:21:17 +00005137
5138 // If we're not in the implementation of a class, also visit the
5139 // superclass.
5140 if (!IsInImplementation && IFace->getSuperClass())
5141 FindImplementableMethods(Context, IFace->getSuperClass(),
5142 WantInstanceMethods, ReturnType,
Douglas Gregor408be5a2010-08-25 01:08:01 +00005143 IsInImplementation, KnownMethods,
5144 false);
Douglas Gregore8f5a172010-04-07 00:21:17 +00005145
5146 // Add methods from any class extensions (but not from categories;
5147 // those should go into category implementations).
Fariborz Jahanian80aa1cd2010-06-22 23:20:40 +00005148 for (const ObjCCategoryDecl *Cat = IFace->getFirstClassExtension(); Cat;
5149 Cat = Cat->getNextClassExtension())
5150 FindImplementableMethods(Context, const_cast<ObjCCategoryDecl*>(Cat),
5151 WantInstanceMethods, ReturnType,
Douglas Gregor408be5a2010-08-25 01:08:01 +00005152 IsInImplementation, KnownMethods,
5153 InOriginalClass);
Douglas Gregore8f5a172010-04-07 00:21:17 +00005154 }
5155
5156 if (ObjCCategoryDecl *Category = dyn_cast<ObjCCategoryDecl>(Container)) {
5157 // Recurse into protocols.
5158 const ObjCList<ObjCProtocolDecl> &Protocols
5159 = Category->getReferencedProtocols();
5160 for (ObjCList<ObjCProtocolDecl>::iterator I = Protocols.begin(),
5161 E = Protocols.end();
5162 I != E; ++I)
5163 FindImplementableMethods(Context, *I, WantInstanceMethods, ReturnType,
Douglas Gregor408be5a2010-08-25 01:08:01 +00005164 IsInImplementation, KnownMethods,
5165 InOriginalClass);
Douglas Gregore8f5a172010-04-07 00:21:17 +00005166 }
5167
5168 if (ObjCProtocolDecl *Protocol = dyn_cast<ObjCProtocolDecl>(Container)) {
5169 // Recurse into protocols.
5170 const ObjCList<ObjCProtocolDecl> &Protocols
5171 = Protocol->getReferencedProtocols();
5172 for (ObjCList<ObjCProtocolDecl>::iterator I = Protocols.begin(),
5173 E = Protocols.end();
5174 I != E; ++I)
5175 FindImplementableMethods(Context, *I, WantInstanceMethods, ReturnType,
Douglas Gregor408be5a2010-08-25 01:08:01 +00005176 IsInImplementation, KnownMethods, false);
Douglas Gregore8f5a172010-04-07 00:21:17 +00005177 }
5178
5179 // Add methods in this container. This operation occurs last because
5180 // we want the methods from this container to override any methods
5181 // we've previously seen with the same selector.
5182 for (ObjCContainerDecl::method_iterator M = Container->meth_begin(),
5183 MEnd = Container->meth_end();
5184 M != MEnd; ++M) {
5185 if ((*M)->isInstanceMethod() == WantInstanceMethods) {
5186 if (!ReturnType.isNull() &&
5187 !Context.hasSameUnqualifiedType(ReturnType, (*M)->getResultType()))
5188 continue;
5189
Douglas Gregor408be5a2010-08-25 01:08:01 +00005190 KnownMethods[(*M)->getSelector()] = std::make_pair(*M, InOriginalClass);
Douglas Gregore8f5a172010-04-07 00:21:17 +00005191 }
5192 }
5193}
5194
5195void Sema::CodeCompleteObjCMethodDecl(Scope *S,
5196 bool IsInstanceMethod,
John McCallb3d87482010-08-24 05:47:05 +00005197 ParsedType ReturnTy,
John McCalld226f652010-08-21 09:40:31 +00005198 Decl *IDecl) {
Douglas Gregore8f5a172010-04-07 00:21:17 +00005199 // Determine the return type of the method we're declaring, if
5200 // provided.
5201 QualType ReturnType = GetTypeFromParser(ReturnTy);
5202
5203 // Determine where we should start searching for methods, and where we
5204 ObjCContainerDecl *SearchDecl = 0, *CurrentDecl = 0;
5205 bool IsInImplementation = false;
John McCalld226f652010-08-21 09:40:31 +00005206 if (Decl *D = IDecl) {
Douglas Gregore8f5a172010-04-07 00:21:17 +00005207 if (ObjCImplementationDecl *Impl = dyn_cast<ObjCImplementationDecl>(D)) {
5208 SearchDecl = Impl->getClassInterface();
5209 CurrentDecl = Impl;
5210 IsInImplementation = true;
5211 } else if (ObjCCategoryImplDecl *CatImpl
5212 = dyn_cast<ObjCCategoryImplDecl>(D)) {
5213 SearchDecl = CatImpl->getCategoryDecl();
5214 CurrentDecl = CatImpl;
5215 IsInImplementation = true;
5216 } else {
5217 SearchDecl = dyn_cast<ObjCContainerDecl>(D);
5218 CurrentDecl = SearchDecl;
5219 }
5220 }
5221
5222 if (!SearchDecl && S) {
5223 if (DeclContext *DC = static_cast<DeclContext *>(S->getEntity())) {
5224 SearchDecl = dyn_cast<ObjCContainerDecl>(DC);
5225 CurrentDecl = SearchDecl;
5226 }
5227 }
5228
5229 if (!SearchDecl || !CurrentDecl) {
Douglas Gregore6b1bb62010-08-11 21:23:17 +00005230 HandleCodeCompleteResults(this, CodeCompleter,
5231 CodeCompletionContext::CCC_Other,
5232 0, 0);
Douglas Gregore8f5a172010-04-07 00:21:17 +00005233 return;
5234 }
5235
5236 // Find all of the methods that we could declare/implement here.
5237 KnownMethodsMap KnownMethods;
5238 FindImplementableMethods(Context, SearchDecl, IsInstanceMethod,
5239 ReturnType, IsInImplementation, KnownMethods);
5240
5241 // Erase any methods that have already been declared or
5242 // implemented here.
5243 for (ObjCContainerDecl::method_iterator M = CurrentDecl->meth_begin(),
5244 MEnd = CurrentDecl->meth_end();
5245 M != MEnd; ++M) {
5246 if ((*M)->isInstanceMethod() != IsInstanceMethod)
5247 continue;
5248
5249 KnownMethodsMap::iterator Pos = KnownMethods.find((*M)->getSelector());
5250 if (Pos != KnownMethods.end())
5251 KnownMethods.erase(Pos);
5252 }
5253
5254 // Add declarations or definitions for each of the known methods.
John McCall0a2c5e22010-08-25 06:19:51 +00005255 typedef CodeCompletionResult Result;
Douglas Gregore8f5a172010-04-07 00:21:17 +00005256 ResultBuilder Results(*this);
5257 Results.EnterNewScope();
5258 PrintingPolicy Policy(Context.PrintingPolicy);
5259 Policy.AnonymousTagLocations = false;
5260 for (KnownMethodsMap::iterator M = KnownMethods.begin(),
5261 MEnd = KnownMethods.end();
5262 M != MEnd; ++M) {
Douglas Gregor408be5a2010-08-25 01:08:01 +00005263 ObjCMethodDecl *Method = M->second.first;
Douglas Gregore8f5a172010-04-07 00:21:17 +00005264 CodeCompletionString *Pattern = new CodeCompletionString;
5265
5266 // If the result type was not already provided, add it to the
5267 // pattern as (type).
5268 if (ReturnType.isNull()) {
5269 std::string TypeStr;
5270 Method->getResultType().getAsStringInternal(TypeStr, Policy);
5271 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
5272 Pattern->AddTextChunk(TypeStr);
5273 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
5274 }
5275
5276 Selector Sel = Method->getSelector();
5277
5278 // Add the first part of the selector to the pattern.
5279 Pattern->AddTypedTextChunk(Sel.getIdentifierInfoForSlot(0)->getName());
5280
5281 // Add parameters to the pattern.
5282 unsigned I = 0;
5283 for (ObjCMethodDecl::param_iterator P = Method->param_begin(),
5284 PEnd = Method->param_end();
5285 P != PEnd; (void)++P, ++I) {
5286 // Add the part of the selector name.
5287 if (I == 0)
5288 Pattern->AddChunk(CodeCompletionString::CK_Colon);
5289 else if (I < Sel.getNumArgs()) {
5290 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
Douglas Gregor47c03a72010-08-17 15:53:35 +00005291 Pattern->AddTextChunk(Sel.getIdentifierInfoForSlot(I)->getName());
Douglas Gregore8f5a172010-04-07 00:21:17 +00005292 Pattern->AddChunk(CodeCompletionString::CK_Colon);
5293 } else
5294 break;
5295
5296 // Add the parameter type.
5297 std::string TypeStr;
5298 (*P)->getOriginalType().getAsStringInternal(TypeStr, Policy);
5299 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
5300 Pattern->AddTextChunk(TypeStr);
5301 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
5302
5303 if (IdentifierInfo *Id = (*P)->getIdentifier())
Douglas Gregore17794f2010-08-31 05:13:43 +00005304 Pattern->AddTextChunk(Id->getName());
Douglas Gregore8f5a172010-04-07 00:21:17 +00005305 }
5306
5307 if (Method->isVariadic()) {
5308 if (Method->param_size() > 0)
5309 Pattern->AddChunk(CodeCompletionString::CK_Comma);
5310 Pattern->AddTextChunk("...");
Douglas Gregore17794f2010-08-31 05:13:43 +00005311 }
Douglas Gregore8f5a172010-04-07 00:21:17 +00005312
Douglas Gregor447107d2010-05-28 00:57:46 +00005313 if (IsInImplementation && Results.includeCodePatterns()) {
Douglas Gregore8f5a172010-04-07 00:21:17 +00005314 // We will be defining the method here, so add a compound statement.
5315 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
5316 Pattern->AddChunk(CodeCompletionString::CK_LeftBrace);
5317 Pattern->AddChunk(CodeCompletionString::CK_VerticalSpace);
5318 if (!Method->getResultType()->isVoidType()) {
5319 // If the result type is not void, add a return clause.
5320 Pattern->AddTextChunk("return");
5321 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
5322 Pattern->AddPlaceholderChunk("expression");
5323 Pattern->AddChunk(CodeCompletionString::CK_SemiColon);
5324 } else
5325 Pattern->AddPlaceholderChunk("statements");
5326
5327 Pattern->AddChunk(CodeCompletionString::CK_VerticalSpace);
5328 Pattern->AddChunk(CodeCompletionString::CK_RightBrace);
5329 }
5330
Douglas Gregor408be5a2010-08-25 01:08:01 +00005331 unsigned Priority = CCP_CodePattern;
5332 if (!M->second.second)
5333 Priority += CCD_InBaseClass;
5334
5335 Results.AddResult(Result(Pattern, Priority,
Douglas Gregor16ed9ad2010-08-17 16:06:07 +00005336 Method->isInstanceMethod()
5337 ? CXCursor_ObjCInstanceMethodDecl
5338 : CXCursor_ObjCClassMethodDecl));
Douglas Gregore8f5a172010-04-07 00:21:17 +00005339 }
5340
5341 Results.ExitScope();
5342
Douglas Gregore6b1bb62010-08-11 21:23:17 +00005343 HandleCodeCompleteResults(this, CodeCompleter,
5344 CodeCompletionContext::CCC_Other,
5345 Results.data(),Results.size());
Douglas Gregore8f5a172010-04-07 00:21:17 +00005346}
Douglas Gregor1f5537a2010-07-08 23:20:03 +00005347
5348void Sema::CodeCompleteObjCMethodDeclSelector(Scope *S,
5349 bool IsInstanceMethod,
Douglas Gregor40ed9a12010-07-08 23:37:41 +00005350 bool AtParameterName,
John McCallb3d87482010-08-24 05:47:05 +00005351 ParsedType ReturnTy,
Douglas Gregor1f5537a2010-07-08 23:20:03 +00005352 IdentifierInfo **SelIdents,
5353 unsigned NumSelIdents) {
Douglas Gregor1f5537a2010-07-08 23:20:03 +00005354 // If we have an external source, load the entire class method
Sebastian Redl3c7f4132010-08-18 23:57:06 +00005355 // pool from the AST file.
Douglas Gregor1f5537a2010-07-08 23:20:03 +00005356 if (ExternalSource) {
5357 for (uint32_t I = 0, N = ExternalSource->GetNumExternalSelectors();
5358 I != N; ++I) {
5359 Selector Sel = ExternalSource->GetExternalSelector(I);
Sebastian Redldb9d2142010-08-02 23:18:59 +00005360 if (Sel.isNull() || MethodPool.count(Sel))
Douglas Gregor1f5537a2010-07-08 23:20:03 +00005361 continue;
Sebastian Redldb9d2142010-08-02 23:18:59 +00005362
5363 ReadMethodPool(Sel);
Douglas Gregor1f5537a2010-07-08 23:20:03 +00005364 }
5365 }
5366
5367 // Build the set of methods we can see.
John McCall0a2c5e22010-08-25 06:19:51 +00005368 typedef CodeCompletionResult Result;
Douglas Gregor1f5537a2010-07-08 23:20:03 +00005369 ResultBuilder Results(*this);
5370
5371 if (ReturnTy)
5372 Results.setPreferredType(GetTypeFromParser(ReturnTy).getNonReferenceType());
Sebastian Redldb9d2142010-08-02 23:18:59 +00005373
Douglas Gregor1f5537a2010-07-08 23:20:03 +00005374 Results.EnterNewScope();
Sebastian Redldb9d2142010-08-02 23:18:59 +00005375 for (GlobalMethodPool::iterator M = MethodPool.begin(),
5376 MEnd = MethodPool.end();
5377 M != MEnd; ++M) {
5378 for (ObjCMethodList *MethList = IsInstanceMethod ? &M->second.first :
5379 &M->second.second;
5380 MethList && MethList->Method;
Douglas Gregor1f5537a2010-07-08 23:20:03 +00005381 MethList = MethList->Next) {
5382 if (!isAcceptableObjCMethod(MethList->Method, MK_Any, SelIdents,
5383 NumSelIdents))
5384 continue;
5385
Douglas Gregor40ed9a12010-07-08 23:37:41 +00005386 if (AtParameterName) {
5387 // Suggest parameter names we've seen before.
5388 if (NumSelIdents && NumSelIdents <= MethList->Method->param_size()) {
5389 ParmVarDecl *Param = MethList->Method->param_begin()[NumSelIdents-1];
5390 if (Param->getIdentifier()) {
5391 CodeCompletionString *Pattern = new CodeCompletionString;
5392 Pattern->AddTypedTextChunk(Param->getIdentifier()->getName());
5393 Results.AddResult(Pattern);
5394 }
5395 }
5396
5397 continue;
5398 }
5399
Douglas Gregor1f5537a2010-07-08 23:20:03 +00005400 Result R(MethList->Method, 0);
5401 R.StartParameter = NumSelIdents;
5402 R.AllParametersAreInformative = false;
5403 R.DeclaringEntity = true;
5404 Results.MaybeAddResult(R, CurContext);
5405 }
5406 }
5407
5408 Results.ExitScope();
Douglas Gregore6b1bb62010-08-11 21:23:17 +00005409 HandleCodeCompleteResults(this, CodeCompleter,
5410 CodeCompletionContext::CCC_Other,
5411 Results.data(),Results.size());
Douglas Gregor1f5537a2010-07-08 23:20:03 +00005412}
Douglas Gregor87c08a52010-08-13 22:48:40 +00005413
Douglas Gregorf29c5232010-08-24 22:20:20 +00005414void Sema::CodeCompletePreprocessorDirective(bool InConditional) {
Douglas Gregorf44e8542010-08-24 19:08:16 +00005415 ResultBuilder Results(*this);
5416 Results.EnterNewScope();
5417
5418 // #if <condition>
5419 CodeCompletionString *Pattern = new CodeCompletionString;
5420 Pattern->AddTypedTextChunk("if");
5421 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
5422 Pattern->AddPlaceholderChunk("condition");
5423 Results.AddResult(Pattern);
5424
5425 // #ifdef <macro>
5426 Pattern = new CodeCompletionString;
5427 Pattern->AddTypedTextChunk("ifdef");
5428 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
5429 Pattern->AddPlaceholderChunk("macro");
5430 Results.AddResult(Pattern);
5431
5432 // #ifndef <macro>
5433 Pattern = new CodeCompletionString;
5434 Pattern->AddTypedTextChunk("ifndef");
5435 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
5436 Pattern->AddPlaceholderChunk("macro");
5437 Results.AddResult(Pattern);
5438
5439 if (InConditional) {
5440 // #elif <condition>
5441 Pattern = new CodeCompletionString;
5442 Pattern->AddTypedTextChunk("elif");
5443 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
5444 Pattern->AddPlaceholderChunk("condition");
5445 Results.AddResult(Pattern);
5446
5447 // #else
5448 Pattern = new CodeCompletionString;
5449 Pattern->AddTypedTextChunk("else");
5450 Results.AddResult(Pattern);
5451
5452 // #endif
5453 Pattern = new CodeCompletionString;
5454 Pattern->AddTypedTextChunk("endif");
5455 Results.AddResult(Pattern);
5456 }
5457
5458 // #include "header"
5459 Pattern = new CodeCompletionString;
5460 Pattern->AddTypedTextChunk("include");
5461 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
5462 Pattern->AddTextChunk("\"");
5463 Pattern->AddPlaceholderChunk("header");
5464 Pattern->AddTextChunk("\"");
5465 Results.AddResult(Pattern);
5466
5467 // #include <header>
5468 Pattern = new CodeCompletionString;
5469 Pattern->AddTypedTextChunk("include");
5470 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
5471 Pattern->AddTextChunk("<");
5472 Pattern->AddPlaceholderChunk("header");
5473 Pattern->AddTextChunk(">");
5474 Results.AddResult(Pattern);
5475
5476 // #define <macro>
5477 Pattern = new CodeCompletionString;
5478 Pattern->AddTypedTextChunk("define");
5479 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
5480 Pattern->AddPlaceholderChunk("macro");
5481 Results.AddResult(Pattern);
5482
5483 // #define <macro>(<args>)
5484 Pattern = new CodeCompletionString;
5485 Pattern->AddTypedTextChunk("define");
5486 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
5487 Pattern->AddPlaceholderChunk("macro");
5488 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
5489 Pattern->AddPlaceholderChunk("args");
5490 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
5491 Results.AddResult(Pattern);
5492
5493 // #undef <macro>
5494 Pattern = new CodeCompletionString;
5495 Pattern->AddTypedTextChunk("undef");
5496 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
5497 Pattern->AddPlaceholderChunk("macro");
5498 Results.AddResult(Pattern);
5499
5500 // #line <number>
5501 Pattern = new CodeCompletionString;
5502 Pattern->AddTypedTextChunk("line");
5503 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
5504 Pattern->AddPlaceholderChunk("number");
5505 Results.AddResult(Pattern);
5506
5507 // #line <number> "filename"
5508 Pattern = new CodeCompletionString;
5509 Pattern->AddTypedTextChunk("line");
5510 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
5511 Pattern->AddPlaceholderChunk("number");
5512 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
5513 Pattern->AddTextChunk("\"");
5514 Pattern->AddPlaceholderChunk("filename");
5515 Pattern->AddTextChunk("\"");
5516 Results.AddResult(Pattern);
5517
5518 // #error <message>
5519 Pattern = new CodeCompletionString;
5520 Pattern->AddTypedTextChunk("error");
5521 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
5522 Pattern->AddPlaceholderChunk("message");
5523 Results.AddResult(Pattern);
5524
5525 // #pragma <arguments>
5526 Pattern = new CodeCompletionString;
5527 Pattern->AddTypedTextChunk("pragma");
5528 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
5529 Pattern->AddPlaceholderChunk("arguments");
5530 Results.AddResult(Pattern);
5531
5532 if (getLangOptions().ObjC1) {
5533 // #import "header"
5534 Pattern = new CodeCompletionString;
5535 Pattern->AddTypedTextChunk("import");
5536 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
5537 Pattern->AddTextChunk("\"");
5538 Pattern->AddPlaceholderChunk("header");
5539 Pattern->AddTextChunk("\"");
5540 Results.AddResult(Pattern);
5541
5542 // #import <header>
5543 Pattern = new CodeCompletionString;
5544 Pattern->AddTypedTextChunk("import");
5545 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
5546 Pattern->AddTextChunk("<");
5547 Pattern->AddPlaceholderChunk("header");
5548 Pattern->AddTextChunk(">");
5549 Results.AddResult(Pattern);
5550 }
5551
5552 // #include_next "header"
5553 Pattern = new CodeCompletionString;
5554 Pattern->AddTypedTextChunk("include_next");
5555 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
5556 Pattern->AddTextChunk("\"");
5557 Pattern->AddPlaceholderChunk("header");
5558 Pattern->AddTextChunk("\"");
5559 Results.AddResult(Pattern);
5560
5561 // #include_next <header>
5562 Pattern = new CodeCompletionString;
5563 Pattern->AddTypedTextChunk("include_next");
5564 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
5565 Pattern->AddTextChunk("<");
5566 Pattern->AddPlaceholderChunk("header");
5567 Pattern->AddTextChunk(">");
5568 Results.AddResult(Pattern);
5569
5570 // #warning <message>
5571 Pattern = new CodeCompletionString;
5572 Pattern->AddTypedTextChunk("warning");
5573 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
5574 Pattern->AddPlaceholderChunk("message");
5575 Results.AddResult(Pattern);
5576
5577 // Note: #ident and #sccs are such crazy anachronisms that we don't provide
5578 // completions for them. And __include_macros is a Clang-internal extension
5579 // that we don't want to encourage anyone to use.
5580
5581 // FIXME: we don't support #assert or #unassert, so don't suggest them.
5582 Results.ExitScope();
5583
Douglas Gregorf44e8542010-08-24 19:08:16 +00005584 HandleCodeCompleteResults(this, CodeCompleter,
Douglas Gregor721f3592010-08-25 18:41:16 +00005585 CodeCompletionContext::CCC_PreprocessorDirective,
Douglas Gregorf44e8542010-08-24 19:08:16 +00005586 Results.data(), Results.size());
5587}
5588
5589void Sema::CodeCompleteInPreprocessorConditionalExclusion(Scope *S) {
Douglas Gregorf29c5232010-08-24 22:20:20 +00005590 CodeCompleteOrdinaryName(S,
John McCallf312b1e2010-08-26 23:41:50 +00005591 S->getFnParent()? Sema::PCC_RecoveryInFunction
5592 : Sema::PCC_Namespace);
Douglas Gregorf44e8542010-08-24 19:08:16 +00005593}
5594
Douglas Gregorf29c5232010-08-24 22:20:20 +00005595void Sema::CodeCompletePreprocessorMacroName(bool IsDefinition) {
Douglas Gregor1fbb4472010-08-24 20:21:13 +00005596 ResultBuilder Results(*this);
5597 if (!IsDefinition && (!CodeCompleter || CodeCompleter->includeMacros())) {
5598 // Add just the names of macros, not their arguments.
5599 Results.EnterNewScope();
5600 for (Preprocessor::macro_iterator M = PP.macro_begin(),
5601 MEnd = PP.macro_end();
5602 M != MEnd; ++M) {
5603 CodeCompletionString *Pattern = new CodeCompletionString;
5604 Pattern->AddTypedTextChunk(M->first->getName());
5605 Results.AddResult(Pattern);
5606 }
5607 Results.ExitScope();
5608 } else if (IsDefinition) {
5609 // FIXME: Can we detect when the user just wrote an include guard above?
5610 }
5611
5612 HandleCodeCompleteResults(this, CodeCompleter,
5613 IsDefinition? CodeCompletionContext::CCC_MacroName
5614 : CodeCompletionContext::CCC_MacroNameUse,
5615 Results.data(), Results.size());
5616}
5617
Douglas Gregorf29c5232010-08-24 22:20:20 +00005618void Sema::CodeCompletePreprocessorExpression() {
5619 ResultBuilder Results(*this);
5620
5621 if (!CodeCompleter || CodeCompleter->includeMacros())
5622 AddMacroResults(PP, Results);
5623
5624 // defined (<macro>)
5625 Results.EnterNewScope();
5626 CodeCompletionString *Pattern = new CodeCompletionString;
5627 Pattern->AddTypedTextChunk("defined");
5628 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
5629 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
5630 Pattern->AddPlaceholderChunk("macro");
5631 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
5632 Results.AddResult(Pattern);
5633 Results.ExitScope();
5634
5635 HandleCodeCompleteResults(this, CodeCompleter,
5636 CodeCompletionContext::CCC_PreprocessorExpression,
5637 Results.data(), Results.size());
5638}
5639
5640void Sema::CodeCompletePreprocessorMacroArgument(Scope *S,
5641 IdentifierInfo *Macro,
5642 MacroInfo *MacroInfo,
5643 unsigned Argument) {
5644 // FIXME: In the future, we could provide "overload" results, much like we
5645 // do for function calls.
5646
5647 CodeCompleteOrdinaryName(S,
John McCallf312b1e2010-08-26 23:41:50 +00005648 S->getFnParent()? Sema::PCC_RecoveryInFunction
5649 : Sema::PCC_Namespace);
Douglas Gregorf29c5232010-08-24 22:20:20 +00005650}
5651
Douglas Gregor55817af2010-08-25 17:04:25 +00005652void Sema::CodeCompleteNaturalLanguage() {
Douglas Gregor55817af2010-08-25 17:04:25 +00005653 HandleCodeCompleteResults(this, CodeCompleter,
Douglas Gregoraf1c6b52010-08-25 17:10:00 +00005654 CodeCompletionContext::CCC_NaturalLanguage,
Douglas Gregor55817af2010-08-25 17:04:25 +00005655 0, 0);
5656}
5657
Douglas Gregor87c08a52010-08-13 22:48:40 +00005658void Sema::GatherGlobalCodeCompletions(
John McCall0a2c5e22010-08-25 06:19:51 +00005659 llvm::SmallVectorImpl<CodeCompletionResult> &Results) {
Douglas Gregor87c08a52010-08-13 22:48:40 +00005660 ResultBuilder Builder(*this);
5661
Douglas Gregor8071e422010-08-15 06:18:01 +00005662 if (!CodeCompleter || CodeCompleter->includeGlobals()) {
5663 CodeCompletionDeclConsumer Consumer(Builder,
5664 Context.getTranslationUnitDecl());
5665 LookupVisibleDecls(Context.getTranslationUnitDecl(), LookupAnyName,
5666 Consumer);
5667 }
Douglas Gregor87c08a52010-08-13 22:48:40 +00005668
5669 if (!CodeCompleter || CodeCompleter->includeMacros())
5670 AddMacroResults(PP, Builder);
5671
5672 Results.clear();
5673 Results.insert(Results.end(),
5674 Builder.data(), Builder.data() + Builder.size());
5675}