blob: c3feb3b6a0dacdb21db951c9ffc764bbe928ea71 [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 Gregor86d9a522009-09-21 16:56:56 +0000155 public:
156 explicit ResultBuilder(Sema &SemaRef, LookupFilter Filter = 0)
Douglas Gregor3cdee122010-08-26 16:36:48 +0000157 : SemaRef(SemaRef), Filter(Filter), AllowNestedNameSpecifiers(false),
Douglas Gregorcee9ff12010-09-20 22:39:41 +0000158 HasObjectTypeQualifiers(false),
159 CompletionContext(CodeCompletionContext::CCC_Other) { }
Douglas Gregor86d9a522009-09-21 16:56:56 +0000160
Douglas Gregord8e8a582010-05-25 21:41:55 +0000161 /// \brief Whether we should include code patterns in the completion
162 /// results.
163 bool includeCodePatterns() const {
164 return SemaRef.CodeCompleter &&
Douglas Gregorf6961522010-08-27 21:18:54 +0000165 SemaRef.CodeCompleter->includeCodePatterns();
Douglas Gregord8e8a582010-05-25 21:41:55 +0000166 }
167
Douglas Gregor86d9a522009-09-21 16:56:56 +0000168 /// \brief Set the filter used for code-completion results.
169 void setFilter(LookupFilter Filter) {
170 this->Filter = Filter;
171 }
172
Douglas Gregor86d9a522009-09-21 16:56:56 +0000173 Result *data() { return Results.empty()? 0 : &Results.front(); }
174 unsigned size() const { return Results.size(); }
175 bool empty() const { return Results.empty(); }
176
Douglas Gregor5ac3bdb2010-05-30 01:49:25 +0000177 /// \brief Specify the preferred type.
178 void setPreferredType(QualType T) {
179 PreferredType = SemaRef.Context.getCanonicalType(T);
180 }
181
Douglas Gregor3cdee122010-08-26 16:36:48 +0000182 /// \brief Set the cv-qualifiers on the object type, for us in filtering
183 /// calls to member functions.
184 ///
185 /// When there are qualifiers in this set, they will be used to filter
186 /// out member functions that aren't available (because there will be a
187 /// cv-qualifier mismatch) or prefer functions with an exact qualifier
188 /// match.
189 void setObjectTypeQualifiers(Qualifiers Quals) {
190 ObjectTypeQualifiers = Quals;
191 HasObjectTypeQualifiers = true;
192 }
193
Douglas Gregor265f7492010-08-27 15:29:55 +0000194 /// \brief Set the preferred selector.
195 ///
196 /// When an Objective-C method declaration result is added, and that
197 /// method's selector matches this preferred selector, we give that method
198 /// a slight priority boost.
199 void setPreferredSelector(Selector Sel) {
200 PreferredSelector = Sel;
201 }
202
Douglas Gregorcee9ff12010-09-20 22:39:41 +0000203 /// \brief Retrieve the code-completion context for which results are
204 /// being collected.
205 const CodeCompletionContext &getCompletionContext() const {
206 return CompletionContext;
207 }
208
209 /// \brief Set the code-completion context.
210 void setCompletionContext(const CodeCompletionContext &CompletionContext) {
211 this->CompletionContext = CompletionContext;
212 }
213
Douglas Gregor45bcd432010-01-14 03:21:49 +0000214 /// \brief Specify whether nested-name-specifiers are allowed.
215 void allowNestedNameSpecifiers(bool Allow = true) {
216 AllowNestedNameSpecifiers = Allow;
217 }
218
Douglas Gregore495b7f2010-01-14 00:20:49 +0000219 /// \brief Determine whether the given declaration is at all interesting
220 /// as a code-completion result.
Douglas Gregor45bcd432010-01-14 03:21:49 +0000221 ///
222 /// \param ND the declaration that we are inspecting.
223 ///
224 /// \param AsNestedNameSpecifier will be set true if this declaration is
225 /// only interesting when it is a nested-name-specifier.
226 bool isInterestingDecl(NamedDecl *ND, bool &AsNestedNameSpecifier) const;
Douglas Gregor6660d842010-01-14 00:41:07 +0000227
228 /// \brief Check whether the result is hidden by the Hiding declaration.
229 ///
230 /// \returns true if the result is hidden and cannot be found, false if
231 /// the hidden result could still be found. When false, \p R may be
232 /// modified to describe how the result can be found (e.g., via extra
233 /// qualification).
234 bool CheckHiddenResult(Result &R, DeclContext *CurContext,
235 NamedDecl *Hiding);
236
Douglas Gregor86d9a522009-09-21 16:56:56 +0000237 /// \brief Add a new result to this result set (if it isn't already in one
238 /// of the shadow maps), or replace an existing result (for, e.g., a
239 /// redeclaration).
Douglas Gregor456c4a12009-09-21 20:12:40 +0000240 ///
Douglas Gregor1ca6ae82010-01-14 01:09:38 +0000241 /// \param CurContext the result to add (if it is unique).
Douglas Gregor456c4a12009-09-21 20:12:40 +0000242 ///
243 /// \param R the context in which this result will be named.
244 void MaybeAddResult(Result R, DeclContext *CurContext = 0);
Douglas Gregor86d9a522009-09-21 16:56:56 +0000245
Douglas Gregor1ca6ae82010-01-14 01:09:38 +0000246 /// \brief Add a new result to this result set, where we already know
247 /// the hiding declation (if any).
248 ///
249 /// \param R the result to add (if it is unique).
250 ///
251 /// \param CurContext the context in which this result will be named.
252 ///
253 /// \param Hiding the declaration that hides the result.
Douglas Gregor0cc84042010-01-14 15:47:35 +0000254 ///
255 /// \param InBaseClass whether the result was found in a base
256 /// class of the searched context.
257 void AddResult(Result R, DeclContext *CurContext, NamedDecl *Hiding,
258 bool InBaseClass);
Douglas Gregor1ca6ae82010-01-14 01:09:38 +0000259
Douglas Gregora4477812010-01-14 16:01:26 +0000260 /// \brief Add a new non-declaration result to this result set.
261 void AddResult(Result R);
262
Douglas Gregor86d9a522009-09-21 16:56:56 +0000263 /// \brief Enter into a new scope.
264 void EnterNewScope();
265
266 /// \brief Exit from the current scope.
267 void ExitScope();
268
Douglas Gregor55385fe2009-11-18 04:19:12 +0000269 /// \brief Ignore this declaration, if it is seen again.
270 void Ignore(Decl *D) { AllDeclsFound.insert(D->getCanonicalDecl()); }
271
Douglas Gregor86d9a522009-09-21 16:56:56 +0000272 /// \name Name lookup predicates
273 ///
274 /// These predicates can be passed to the name lookup functions to filter the
275 /// results of name lookup. All of the predicates have the same type, so that
276 ///
277 //@{
Douglas Gregor791215b2009-09-21 20:51:25 +0000278 bool IsOrdinaryName(NamedDecl *ND) const;
Douglas Gregor4710e5b2010-05-28 00:49:12 +0000279 bool IsOrdinaryNonTypeName(NamedDecl *ND) const;
Douglas Gregorf9578432010-07-28 21:50:18 +0000280 bool IsIntegralConstantValue(NamedDecl *ND) const;
Douglas Gregor01dfea02010-01-10 23:08:15 +0000281 bool IsOrdinaryNonValueName(NamedDecl *ND) const;
Douglas Gregor86d9a522009-09-21 16:56:56 +0000282 bool IsNestedNameSpecifier(NamedDecl *ND) const;
283 bool IsEnum(NamedDecl *ND) const;
284 bool IsClassOrStruct(NamedDecl *ND) const;
285 bool IsUnion(NamedDecl *ND) const;
286 bool IsNamespace(NamedDecl *ND) const;
287 bool IsNamespaceOrAlias(NamedDecl *ND) const;
288 bool IsType(NamedDecl *ND) const;
Douglas Gregoreb5758b2009-09-23 22:26:46 +0000289 bool IsMember(NamedDecl *ND) const;
Douglas Gregor80f4f4c2010-01-14 16:08:12 +0000290 bool IsObjCIvar(NamedDecl *ND) const;
Douglas Gregor8e254cf2010-05-27 23:06:34 +0000291 bool IsObjCMessageReceiver(NamedDecl *ND) const;
Douglas Gregorfb629412010-08-23 21:17:50 +0000292 bool IsObjCCollection(NamedDecl *ND) const;
Douglas Gregor86d9a522009-09-21 16:56:56 +0000293 //@}
294 };
295}
296
Douglas Gregorfbcb5d62009-12-06 20:23:50 +0000297class ResultBuilder::ShadowMapEntry::iterator {
298 llvm::PointerUnion<NamedDecl*, const DeclIndexPair*> DeclOrIterator;
299 unsigned SingleDeclIndex;
300
301public:
302 typedef DeclIndexPair value_type;
303 typedef value_type reference;
304 typedef std::ptrdiff_t difference_type;
305 typedef std::input_iterator_tag iterator_category;
306
307 class pointer {
308 DeclIndexPair Value;
309
310 public:
311 pointer(const DeclIndexPair &Value) : Value(Value) { }
312
313 const DeclIndexPair *operator->() const {
314 return &Value;
315 }
316 };
317
318 iterator() : DeclOrIterator((NamedDecl *)0), SingleDeclIndex(0) { }
319
320 iterator(NamedDecl *SingleDecl, unsigned Index)
321 : DeclOrIterator(SingleDecl), SingleDeclIndex(Index) { }
322
323 iterator(const DeclIndexPair *Iterator)
324 : DeclOrIterator(Iterator), SingleDeclIndex(0) { }
325
326 iterator &operator++() {
327 if (DeclOrIterator.is<NamedDecl *>()) {
328 DeclOrIterator = (NamedDecl *)0;
329 SingleDeclIndex = 0;
330 return *this;
331 }
332
333 const DeclIndexPair *I = DeclOrIterator.get<const DeclIndexPair*>();
334 ++I;
335 DeclOrIterator = I;
336 return *this;
337 }
338
Chris Lattner66392d42010-09-04 18:12:20 +0000339 /*iterator operator++(int) {
Douglas Gregorfbcb5d62009-12-06 20:23:50 +0000340 iterator tmp(*this);
341 ++(*this);
342 return tmp;
Chris Lattner66392d42010-09-04 18:12:20 +0000343 }*/
Douglas Gregorfbcb5d62009-12-06 20:23:50 +0000344
345 reference operator*() const {
346 if (NamedDecl *ND = DeclOrIterator.dyn_cast<NamedDecl *>())
347 return reference(ND, SingleDeclIndex);
348
Douglas Gregord490f952009-12-06 21:27:58 +0000349 return *DeclOrIterator.get<const DeclIndexPair*>();
Douglas Gregorfbcb5d62009-12-06 20:23:50 +0000350 }
351
352 pointer operator->() const {
353 return pointer(**this);
354 }
355
356 friend bool operator==(const iterator &X, const iterator &Y) {
Douglas Gregord490f952009-12-06 21:27:58 +0000357 return X.DeclOrIterator.getOpaqueValue()
358 == Y.DeclOrIterator.getOpaqueValue() &&
Douglas Gregorfbcb5d62009-12-06 20:23:50 +0000359 X.SingleDeclIndex == Y.SingleDeclIndex;
360 }
361
362 friend bool operator!=(const iterator &X, const iterator &Y) {
Douglas Gregord490f952009-12-06 21:27:58 +0000363 return !(X == Y);
Douglas Gregorfbcb5d62009-12-06 20:23:50 +0000364 }
365};
366
Douglas Gregorfbcb5d62009-12-06 20:23:50 +0000367ResultBuilder::ShadowMapEntry::iterator
368ResultBuilder::ShadowMapEntry::begin() const {
369 if (DeclOrVector.isNull())
370 return iterator();
371
372 if (NamedDecl *ND = DeclOrVector.dyn_cast<NamedDecl *>())
373 return iterator(ND, SingleDeclIndex);
374
375 return iterator(DeclOrVector.get<DeclIndexPairVector *>()->begin());
376}
377
378ResultBuilder::ShadowMapEntry::iterator
379ResultBuilder::ShadowMapEntry::end() const {
380 if (DeclOrVector.is<NamedDecl *>() || DeclOrVector.isNull())
381 return iterator();
382
383 return iterator(DeclOrVector.get<DeclIndexPairVector *>()->end());
384}
385
Douglas Gregor456c4a12009-09-21 20:12:40 +0000386/// \brief Compute the qualification required to get from the current context
387/// (\p CurContext) to the target context (\p TargetContext).
388///
389/// \param Context the AST context in which the qualification will be used.
390///
391/// \param CurContext the context where an entity is being named, which is
392/// typically based on the current scope.
393///
394/// \param TargetContext the context in which the named entity actually
395/// resides.
396///
397/// \returns a nested name specifier that refers into the target context, or
398/// NULL if no qualification is needed.
399static NestedNameSpecifier *
400getRequiredQualification(ASTContext &Context,
401 DeclContext *CurContext,
402 DeclContext *TargetContext) {
403 llvm::SmallVector<DeclContext *, 4> TargetParents;
404
405 for (DeclContext *CommonAncestor = TargetContext;
406 CommonAncestor && !CommonAncestor->Encloses(CurContext);
407 CommonAncestor = CommonAncestor->getLookupParent()) {
408 if (CommonAncestor->isTransparentContext() ||
409 CommonAncestor->isFunctionOrMethod())
410 continue;
411
412 TargetParents.push_back(CommonAncestor);
413 }
414
415 NestedNameSpecifier *Result = 0;
416 while (!TargetParents.empty()) {
417 DeclContext *Parent = TargetParents.back();
418 TargetParents.pop_back();
419
Douglas Gregorfb629412010-08-23 21:17:50 +0000420 if (NamespaceDecl *Namespace = dyn_cast<NamespaceDecl>(Parent)) {
421 if (!Namespace->getIdentifier())
422 continue;
423
Douglas Gregor456c4a12009-09-21 20:12:40 +0000424 Result = NestedNameSpecifier::Create(Context, Result, Namespace);
Douglas Gregorfb629412010-08-23 21:17:50 +0000425 }
Douglas Gregor456c4a12009-09-21 20:12:40 +0000426 else if (TagDecl *TD = dyn_cast<TagDecl>(Parent))
427 Result = NestedNameSpecifier::Create(Context, Result,
428 false,
429 Context.getTypeDeclType(TD).getTypePtr());
Douglas Gregor0c8296d2009-11-07 00:00:49 +0000430 }
Douglas Gregor456c4a12009-09-21 20:12:40 +0000431 return Result;
432}
433
Douglas Gregor45bcd432010-01-14 03:21:49 +0000434bool ResultBuilder::isInterestingDecl(NamedDecl *ND,
435 bool &AsNestedNameSpecifier) const {
436 AsNestedNameSpecifier = false;
437
Douglas Gregore495b7f2010-01-14 00:20:49 +0000438 ND = ND->getUnderlyingDecl();
439 unsigned IDNS = ND->getIdentifierNamespace();
Douglas Gregorf52cede2009-10-09 22:16:47 +0000440
441 // Skip unnamed entities.
Douglas Gregore495b7f2010-01-14 00:20:49 +0000442 if (!ND->getDeclName())
443 return false;
Douglas Gregor86d9a522009-09-21 16:56:56 +0000444
445 // Friend declarations and declarations introduced due to friends are never
446 // added as results.
John McCall92b7f702010-03-11 07:50:04 +0000447 if (IDNS & (Decl::IDNS_OrdinaryFriend | Decl::IDNS_TagFriend))
Douglas Gregore495b7f2010-01-14 00:20:49 +0000448 return false;
449
Douglas Gregor76282942009-12-11 17:31:05 +0000450 // Class template (partial) specializations are never added as results.
Douglas Gregore495b7f2010-01-14 00:20:49 +0000451 if (isa<ClassTemplateSpecializationDecl>(ND) ||
452 isa<ClassTemplatePartialSpecializationDecl>(ND))
453 return false;
Douglas Gregor86d9a522009-09-21 16:56:56 +0000454
Douglas Gregor76282942009-12-11 17:31:05 +0000455 // Using declarations themselves are never added as results.
Douglas Gregore495b7f2010-01-14 00:20:49 +0000456 if (isa<UsingDecl>(ND))
457 return false;
458
459 // Some declarations have reserved names that we don't want to ever show.
460 if (const IdentifierInfo *Id = ND->getIdentifier()) {
Douglas Gregor86d9a522009-09-21 16:56:56 +0000461 // __va_list_tag is a freak of nature. Find it and skip it.
462 if (Id->isStr("__va_list_tag") || Id->isStr("__builtin_va_list"))
Douglas Gregore495b7f2010-01-14 00:20:49 +0000463 return false;
Douglas Gregor86d9a522009-09-21 16:56:56 +0000464
Douglas Gregorf52cede2009-10-09 22:16:47 +0000465 // Filter out names reserved for the implementation (C99 7.1.3,
Douglas Gregor797efb52010-07-14 17:44:04 +0000466 // C++ [lib.global.names]) if they come from a system header.
Daniel Dunbare013d682009-10-18 20:26:12 +0000467 //
468 // FIXME: Add predicate for this.
Douglas Gregorf52cede2009-10-09 22:16:47 +0000469 if (Id->getLength() >= 2) {
Daniel Dunbare013d682009-10-18 20:26:12 +0000470 const char *Name = Id->getNameStart();
Douglas Gregorf52cede2009-10-09 22:16:47 +0000471 if (Name[0] == '_' &&
Douglas Gregor797efb52010-07-14 17:44:04 +0000472 (Name[1] == '_' || (Name[1] >= 'A' && Name[1] <= 'Z')) &&
473 (ND->getLocation().isInvalid() ||
474 SemaRef.SourceMgr.isInSystemHeader(
475 SemaRef.SourceMgr.getSpellingLoc(ND->getLocation()))))
Douglas Gregore495b7f2010-01-14 00:20:49 +0000476 return false;
Douglas Gregorf52cede2009-10-09 22:16:47 +0000477 }
Douglas Gregor86d9a522009-09-21 16:56:56 +0000478 }
Douglas Gregore495b7f2010-01-14 00:20:49 +0000479
Douglas Gregor86d9a522009-09-21 16:56:56 +0000480 // C++ constructors are never found by name lookup.
Douglas Gregore495b7f2010-01-14 00:20:49 +0000481 if (isa<CXXConstructorDecl>(ND))
482 return false;
Douglas Gregor86d9a522009-09-21 16:56:56 +0000483
Douglas Gregora5fb7c32010-08-16 23:05:20 +0000484 if (Filter == &ResultBuilder::IsNestedNameSpecifier ||
485 ((isa<NamespaceDecl>(ND) || isa<NamespaceAliasDecl>(ND)) &&
486 Filter != &ResultBuilder::IsNamespace &&
487 Filter != &ResultBuilder::IsNamespaceOrAlias))
488 AsNestedNameSpecifier = true;
489
Douglas Gregor86d9a522009-09-21 16:56:56 +0000490 // Filter out any unwanted results.
Douglas Gregor45bcd432010-01-14 03:21:49 +0000491 if (Filter && !(this->*Filter)(ND)) {
492 // Check whether it is interesting as a nested-name-specifier.
493 if (AllowNestedNameSpecifiers && SemaRef.getLangOptions().CPlusPlus &&
494 IsNestedNameSpecifier(ND) &&
495 (Filter != &ResultBuilder::IsMember ||
496 (isa<CXXRecordDecl>(ND) &&
497 cast<CXXRecordDecl>(ND)->isInjectedClassName()))) {
498 AsNestedNameSpecifier = true;
499 return true;
500 }
501
Douglas Gregore495b7f2010-01-14 00:20:49 +0000502 return false;
Douglas Gregora5fb7c32010-08-16 23:05:20 +0000503 }
Douglas Gregore495b7f2010-01-14 00:20:49 +0000504 // ... then it must be interesting!
505 return true;
506}
507
Douglas Gregor6660d842010-01-14 00:41:07 +0000508bool ResultBuilder::CheckHiddenResult(Result &R, DeclContext *CurContext,
509 NamedDecl *Hiding) {
510 // In C, there is no way to refer to a hidden name.
511 // FIXME: This isn't true; we can find a tag name hidden by an ordinary
512 // name if we introduce the tag type.
513 if (!SemaRef.getLangOptions().CPlusPlus)
514 return true;
515
Sebastian Redl7a126a42010-08-31 00:36:30 +0000516 DeclContext *HiddenCtx = R.Declaration->getDeclContext()->getRedeclContext();
Douglas Gregor6660d842010-01-14 00:41:07 +0000517
518 // There is no way to qualify a name declared in a function or method.
519 if (HiddenCtx->isFunctionOrMethod())
520 return true;
521
Sebastian Redl7a126a42010-08-31 00:36:30 +0000522 if (HiddenCtx == Hiding->getDeclContext()->getRedeclContext())
Douglas Gregor6660d842010-01-14 00:41:07 +0000523 return true;
524
525 // We can refer to the result with the appropriate qualification. Do it.
526 R.Hidden = true;
527 R.QualifierIsInformative = false;
528
529 if (!R.Qualifier)
530 R.Qualifier = getRequiredQualification(SemaRef.Context,
531 CurContext,
532 R.Declaration->getDeclContext());
533 return false;
534}
535
Douglas Gregor1f5537a2010-07-08 23:20:03 +0000536/// \brief A simplified classification of types used to determine whether two
537/// types are "similar enough" when adjusting priorities.
Douglas Gregor1827e102010-08-16 16:18:59 +0000538SimplifiedTypeClass clang::getSimplifiedTypeClass(CanQualType T) {
Douglas Gregor1f5537a2010-07-08 23:20:03 +0000539 switch (T->getTypeClass()) {
540 case Type::Builtin:
541 switch (cast<BuiltinType>(T)->getKind()) {
542 case BuiltinType::Void:
543 return STC_Void;
544
545 case BuiltinType::NullPtr:
546 return STC_Pointer;
547
548 case BuiltinType::Overload:
549 case BuiltinType::Dependent:
550 case BuiltinType::UndeducedAuto:
551 return STC_Other;
552
553 case BuiltinType::ObjCId:
554 case BuiltinType::ObjCClass:
555 case BuiltinType::ObjCSel:
556 return STC_ObjectiveC;
557
558 default:
559 return STC_Arithmetic;
560 }
561 return STC_Other;
562
563 case Type::Complex:
564 return STC_Arithmetic;
565
566 case Type::Pointer:
567 return STC_Pointer;
568
569 case Type::BlockPointer:
570 return STC_Block;
571
572 case Type::LValueReference:
573 case Type::RValueReference:
574 return getSimplifiedTypeClass(T->getAs<ReferenceType>()->getPointeeType());
575
576 case Type::ConstantArray:
577 case Type::IncompleteArray:
578 case Type::VariableArray:
579 case Type::DependentSizedArray:
580 return STC_Array;
581
582 case Type::DependentSizedExtVector:
583 case Type::Vector:
584 case Type::ExtVector:
585 return STC_Arithmetic;
586
587 case Type::FunctionProto:
588 case Type::FunctionNoProto:
589 return STC_Function;
590
591 case Type::Record:
592 return STC_Record;
593
594 case Type::Enum:
595 return STC_Arithmetic;
596
597 case Type::ObjCObject:
598 case Type::ObjCInterface:
599 case Type::ObjCObjectPointer:
600 return STC_ObjectiveC;
601
602 default:
603 return STC_Other;
604 }
605}
606
607/// \brief Get the type that a given expression will have if this declaration
608/// is used as an expression in its "typical" code-completion form.
Douglas Gregor1827e102010-08-16 16:18:59 +0000609QualType clang::getDeclUsageType(ASTContext &C, NamedDecl *ND) {
Douglas Gregor1f5537a2010-07-08 23:20:03 +0000610 ND = cast<NamedDecl>(ND->getUnderlyingDecl());
611
612 if (TypeDecl *Type = dyn_cast<TypeDecl>(ND))
613 return C.getTypeDeclType(Type);
614 if (ObjCInterfaceDecl *Iface = dyn_cast<ObjCInterfaceDecl>(ND))
615 return C.getObjCInterfaceType(Iface);
616
617 QualType T;
618 if (FunctionDecl *Function = dyn_cast<FunctionDecl>(ND))
Douglas Gregor5291c3c2010-07-13 08:18:22 +0000619 T = Function->getCallResultType();
Douglas Gregor1f5537a2010-07-08 23:20:03 +0000620 else if (ObjCMethodDecl *Method = dyn_cast<ObjCMethodDecl>(ND))
Douglas Gregor5291c3c2010-07-13 08:18:22 +0000621 T = Method->getSendResultType();
Douglas Gregor1f5537a2010-07-08 23:20:03 +0000622 else if (FunctionTemplateDecl *FunTmpl = dyn_cast<FunctionTemplateDecl>(ND))
Douglas Gregor5291c3c2010-07-13 08:18:22 +0000623 T = FunTmpl->getTemplatedDecl()->getCallResultType();
Douglas Gregor1f5537a2010-07-08 23:20:03 +0000624 else if (EnumConstantDecl *Enumerator = dyn_cast<EnumConstantDecl>(ND))
625 T = C.getTypeDeclType(cast<EnumDecl>(Enumerator->getDeclContext()));
626 else if (ObjCPropertyDecl *Property = dyn_cast<ObjCPropertyDecl>(ND))
627 T = Property->getType();
628 else if (ValueDecl *Value = dyn_cast<ValueDecl>(ND))
629 T = Value->getType();
630 else
631 return QualType();
632
633 return T.getNonReferenceType();
634}
635
Douglas Gregorcee9ff12010-09-20 22:39:41 +0000636void ResultBuilder::AdjustResultPriorityForDecl(Result &R) {
637 // If this is an Objective-C method declaration whose selector matches our
638 // preferred selector, give it a priority boost.
639 if (!PreferredSelector.isNull())
640 if (ObjCMethodDecl *Method = dyn_cast<ObjCMethodDecl>(R.Declaration))
641 if (PreferredSelector == Method->getSelector())
642 R.Priority += CCD_SelectorMatch;
Douglas Gregor08f43cd2010-09-20 23:11:55 +0000643
Douglas Gregorcee9ff12010-09-20 22:39:41 +0000644 // If we have a preferred type, adjust the priority for results with exactly-
645 // matching or nearly-matching types.
646 if (!PreferredType.isNull()) {
647 QualType T = getDeclUsageType(SemaRef.Context, R.Declaration);
648 if (!T.isNull()) {
649 CanQualType TC = SemaRef.Context.getCanonicalType(T);
650 // Check for exactly-matching types (modulo qualifiers).
651 if (SemaRef.Context.hasSameUnqualifiedType(PreferredType, TC))
652 R.Priority /= CCF_ExactTypeMatch;
653 // Check for nearly-matching types, based on classification of each.
654 else if ((getSimplifiedTypeClass(PreferredType)
Douglas Gregor1f5537a2010-07-08 23:20:03 +0000655 == getSimplifiedTypeClass(TC)) &&
Douglas Gregorcee9ff12010-09-20 22:39:41 +0000656 !(PreferredType->isEnumeralType() && TC->isEnumeralType()))
657 R.Priority /= CCF_SimilarTypeMatch;
658 }
659 }
Douglas Gregor1f5537a2010-07-08 23:20:03 +0000660}
661
Douglas Gregore495b7f2010-01-14 00:20:49 +0000662void ResultBuilder::MaybeAddResult(Result R, DeclContext *CurContext) {
663 assert(!ShadowMaps.empty() && "Must enter into a results scope");
664
665 if (R.Kind != Result::RK_Declaration) {
666 // For non-declaration results, just add the result.
667 Results.push_back(R);
668 return;
669 }
670
671 // Look through using declarations.
672 if (UsingShadowDecl *Using = dyn_cast<UsingShadowDecl>(R.Declaration)) {
673 MaybeAddResult(Result(Using->getTargetDecl(), R.Qualifier), CurContext);
674 return;
675 }
676
677 Decl *CanonDecl = R.Declaration->getCanonicalDecl();
678 unsigned IDNS = CanonDecl->getIdentifierNamespace();
679
Douglas Gregor45bcd432010-01-14 03:21:49 +0000680 bool AsNestedNameSpecifier = false;
681 if (!isInterestingDecl(R.Declaration, AsNestedNameSpecifier))
Douglas Gregore495b7f2010-01-14 00:20:49 +0000682 return;
683
Douglas Gregor86d9a522009-09-21 16:56:56 +0000684 ShadowMap &SMap = ShadowMaps.back();
Douglas Gregorfbcb5d62009-12-06 20:23:50 +0000685 ShadowMapEntry::iterator I, IEnd;
686 ShadowMap::iterator NamePos = SMap.find(R.Declaration->getDeclName());
687 if (NamePos != SMap.end()) {
688 I = NamePos->second.begin();
689 IEnd = NamePos->second.end();
690 }
691
692 for (; I != IEnd; ++I) {
693 NamedDecl *ND = I->first;
694 unsigned Index = I->second;
Douglas Gregor86d9a522009-09-21 16:56:56 +0000695 if (ND->getCanonicalDecl() == CanonDecl) {
696 // This is a redeclaration. Always pick the newer declaration.
Douglas Gregor86d9a522009-09-21 16:56:56 +0000697 Results[Index].Declaration = R.Declaration;
698
Douglas Gregor86d9a522009-09-21 16:56:56 +0000699 // We're done.
700 return;
701 }
702 }
703
704 // This is a new declaration in this scope. However, check whether this
705 // declaration name is hidden by a similarly-named declaration in an outer
706 // scope.
707 std::list<ShadowMap>::iterator SM, SMEnd = ShadowMaps.end();
708 --SMEnd;
709 for (SM = ShadowMaps.begin(); SM != SMEnd; ++SM) {
Douglas Gregorfbcb5d62009-12-06 20:23:50 +0000710 ShadowMapEntry::iterator I, IEnd;
711 ShadowMap::iterator NamePos = SM->find(R.Declaration->getDeclName());
712 if (NamePos != SM->end()) {
713 I = NamePos->second.begin();
714 IEnd = NamePos->second.end();
715 }
716 for (; I != IEnd; ++I) {
Douglas Gregor86d9a522009-09-21 16:56:56 +0000717 // A tag declaration does not hide a non-tag declaration.
John McCall0d6b1642010-04-23 18:46:30 +0000718 if (I->first->hasTagIdentifierNamespace() &&
Douglas Gregor86d9a522009-09-21 16:56:56 +0000719 (IDNS & (Decl::IDNS_Member | Decl::IDNS_Ordinary |
720 Decl::IDNS_ObjCProtocol)))
721 continue;
722
723 // Protocols are in distinct namespaces from everything else.
Douglas Gregorfbcb5d62009-12-06 20:23:50 +0000724 if (((I->first->getIdentifierNamespace() & Decl::IDNS_ObjCProtocol)
Douglas Gregor86d9a522009-09-21 16:56:56 +0000725 || (IDNS & Decl::IDNS_ObjCProtocol)) &&
Douglas Gregorfbcb5d62009-12-06 20:23:50 +0000726 I->first->getIdentifierNamespace() != IDNS)
Douglas Gregor86d9a522009-09-21 16:56:56 +0000727 continue;
728
729 // The newly-added result is hidden by an entry in the shadow map.
Douglas Gregor6660d842010-01-14 00:41:07 +0000730 if (CheckHiddenResult(R, CurContext, I->first))
Douglas Gregor86d9a522009-09-21 16:56:56 +0000731 return;
Douglas Gregor86d9a522009-09-21 16:56:56 +0000732
733 break;
734 }
735 }
736
737 // Make sure that any given declaration only shows up in the result set once.
738 if (!AllDeclsFound.insert(CanonDecl))
739 return;
Douglas Gregor265f7492010-08-27 15:29:55 +0000740
Douglas Gregoreb5758b2009-09-23 22:26:46 +0000741 // If the filter is for nested-name-specifiers, then this result starts a
742 // nested-name-specifier.
Douglas Gregor12e13132010-05-26 22:00:08 +0000743 if (AsNestedNameSpecifier) {
Douglas Gregoreb5758b2009-09-23 22:26:46 +0000744 R.StartsNestedNameSpecifier = true;
Douglas Gregor12e13132010-05-26 22:00:08 +0000745 R.Priority = CCP_NestedNameSpecifier;
Douglas Gregorcee9ff12010-09-20 22:39:41 +0000746 } else
747 AdjustResultPriorityForDecl(R);
Douglas Gregor265f7492010-08-27 15:29:55 +0000748
Douglas Gregor0563c262009-09-22 23:15:58 +0000749 // If this result is supposed to have an informative qualifier, add one.
Douglas Gregoreb5758b2009-09-23 22:26:46 +0000750 if (R.QualifierIsInformative && !R.Qualifier &&
751 !R.StartsNestedNameSpecifier) {
Douglas Gregor0563c262009-09-22 23:15:58 +0000752 DeclContext *Ctx = R.Declaration->getDeclContext();
753 if (NamespaceDecl *Namespace = dyn_cast<NamespaceDecl>(Ctx))
754 R.Qualifier = NestedNameSpecifier::Create(SemaRef.Context, 0, Namespace);
755 else if (TagDecl *Tag = dyn_cast<TagDecl>(Ctx))
756 R.Qualifier = NestedNameSpecifier::Create(SemaRef.Context, 0, false,
757 SemaRef.Context.getTypeDeclType(Tag).getTypePtr());
758 else
759 R.QualifierIsInformative = false;
760 }
Douglas Gregoreb5758b2009-09-23 22:26:46 +0000761
Douglas Gregor86d9a522009-09-21 16:56:56 +0000762 // Insert this result into the set of results and into the current shadow
763 // map.
Douglas Gregorfbcb5d62009-12-06 20:23:50 +0000764 SMap[R.Declaration->getDeclName()].Add(R.Declaration, Results.size());
Douglas Gregor86d9a522009-09-21 16:56:56 +0000765 Results.push_back(R);
766}
767
Douglas Gregor1ca6ae82010-01-14 01:09:38 +0000768void ResultBuilder::AddResult(Result R, DeclContext *CurContext,
Douglas Gregor0cc84042010-01-14 15:47:35 +0000769 NamedDecl *Hiding, bool InBaseClass = false) {
Douglas Gregora4477812010-01-14 16:01:26 +0000770 if (R.Kind != Result::RK_Declaration) {
771 // For non-declaration results, just add the result.
772 Results.push_back(R);
773 return;
774 }
775
Douglas Gregor1ca6ae82010-01-14 01:09:38 +0000776 // Look through using declarations.
777 if (UsingShadowDecl *Using = dyn_cast<UsingShadowDecl>(R.Declaration)) {
778 AddResult(Result(Using->getTargetDecl(), R.Qualifier), CurContext, Hiding);
779 return;
780 }
781
Douglas Gregor45bcd432010-01-14 03:21:49 +0000782 bool AsNestedNameSpecifier = false;
783 if (!isInterestingDecl(R.Declaration, AsNestedNameSpecifier))
Douglas Gregor1ca6ae82010-01-14 01:09:38 +0000784 return;
785
786 if (Hiding && CheckHiddenResult(R, CurContext, Hiding))
787 return;
788
789 // Make sure that any given declaration only shows up in the result set once.
790 if (!AllDeclsFound.insert(R.Declaration->getCanonicalDecl()))
791 return;
792
793 // If the filter is for nested-name-specifiers, then this result starts a
794 // nested-name-specifier.
Douglas Gregor12e13132010-05-26 22:00:08 +0000795 if (AsNestedNameSpecifier) {
Douglas Gregor1ca6ae82010-01-14 01:09:38 +0000796 R.StartsNestedNameSpecifier = true;
Douglas Gregor12e13132010-05-26 22:00:08 +0000797 R.Priority = CCP_NestedNameSpecifier;
798 }
Douglas Gregor0cc84042010-01-14 15:47:35 +0000799 else if (Filter == &ResultBuilder::IsMember && !R.Qualifier && InBaseClass &&
800 isa<CXXRecordDecl>(R.Declaration->getDeclContext()
Sebastian Redl7a126a42010-08-31 00:36:30 +0000801 ->getRedeclContext()))
Douglas Gregor0cc84042010-01-14 15:47:35 +0000802 R.QualifierIsInformative = true;
803
Douglas Gregor1ca6ae82010-01-14 01:09:38 +0000804 // If this result is supposed to have an informative qualifier, add one.
805 if (R.QualifierIsInformative && !R.Qualifier &&
806 !R.StartsNestedNameSpecifier) {
807 DeclContext *Ctx = R.Declaration->getDeclContext();
808 if (NamespaceDecl *Namespace = dyn_cast<NamespaceDecl>(Ctx))
809 R.Qualifier = NestedNameSpecifier::Create(SemaRef.Context, 0, Namespace);
810 else if (TagDecl *Tag = dyn_cast<TagDecl>(Ctx))
811 R.Qualifier = NestedNameSpecifier::Create(SemaRef.Context, 0, false,
Douglas Gregor45bcd432010-01-14 03:21:49 +0000812 SemaRef.Context.getTypeDeclType(Tag).getTypePtr());
Douglas Gregor1ca6ae82010-01-14 01:09:38 +0000813 else
814 R.QualifierIsInformative = false;
815 }
816
Douglas Gregor12e13132010-05-26 22:00:08 +0000817 // Adjust the priority if this result comes from a base class.
818 if (InBaseClass)
819 R.Priority += CCD_InBaseClass;
820
Douglas Gregorcee9ff12010-09-20 22:39:41 +0000821 AdjustResultPriorityForDecl(R);
Douglas Gregor5ac3bdb2010-05-30 01:49:25 +0000822
Douglas Gregor3cdee122010-08-26 16:36:48 +0000823 if (HasObjectTypeQualifiers)
824 if (CXXMethodDecl *Method = dyn_cast<CXXMethodDecl>(R.Declaration))
825 if (Method->isInstance()) {
826 Qualifiers MethodQuals
827 = Qualifiers::fromCVRMask(Method->getTypeQualifiers());
828 if (ObjectTypeQualifiers == MethodQuals)
829 R.Priority += CCD_ObjectQualifierMatch;
830 else if (ObjectTypeQualifiers - MethodQuals) {
831 // The method cannot be invoked, because doing so would drop
832 // qualifiers.
833 return;
834 }
835 }
836
Douglas Gregor1ca6ae82010-01-14 01:09:38 +0000837 // Insert this result into the set of results.
838 Results.push_back(R);
839}
840
Douglas Gregora4477812010-01-14 16:01:26 +0000841void ResultBuilder::AddResult(Result R) {
842 assert(R.Kind != Result::RK_Declaration &&
843 "Declaration results need more context");
844 Results.push_back(R);
845}
846
Douglas Gregor86d9a522009-09-21 16:56:56 +0000847/// \brief Enter into a new scope.
848void ResultBuilder::EnterNewScope() {
849 ShadowMaps.push_back(ShadowMap());
850}
851
852/// \brief Exit from the current scope.
853void ResultBuilder::ExitScope() {
Douglas Gregorfbcb5d62009-12-06 20:23:50 +0000854 for (ShadowMap::iterator E = ShadowMaps.back().begin(),
855 EEnd = ShadowMaps.back().end();
856 E != EEnd;
857 ++E)
858 E->second.Destroy();
859
Douglas Gregor86d9a522009-09-21 16:56:56 +0000860 ShadowMaps.pop_back();
861}
862
Douglas Gregor791215b2009-09-21 20:51:25 +0000863/// \brief Determines whether this given declaration will be found by
864/// ordinary name lookup.
865bool ResultBuilder::IsOrdinaryName(NamedDecl *ND) const {
Douglas Gregor4710e5b2010-05-28 00:49:12 +0000866 ND = cast<NamedDecl>(ND->getUnderlyingDecl());
867
Douglas Gregor791215b2009-09-21 20:51:25 +0000868 unsigned IDNS = Decl::IDNS_Ordinary;
869 if (SemaRef.getLangOptions().CPlusPlus)
Douglas Gregor9b30b262010-06-15 20:26:51 +0000870 IDNS |= Decl::IDNS_Tag | Decl::IDNS_Namespace | Decl::IDNS_Member;
Douglas Gregor1ca6ae82010-01-14 01:09:38 +0000871 else if (SemaRef.getLangOptions().ObjC1 && isa<ObjCIvarDecl>(ND))
872 return true;
873
Douglas Gregor791215b2009-09-21 20:51:25 +0000874 return ND->getIdentifierNamespace() & IDNS;
875}
876
Douglas Gregor01dfea02010-01-10 23:08:15 +0000877/// \brief Determines whether this given declaration will be found by
Douglas Gregor4710e5b2010-05-28 00:49:12 +0000878/// ordinary name lookup but is not a type name.
879bool ResultBuilder::IsOrdinaryNonTypeName(NamedDecl *ND) const {
880 ND = cast<NamedDecl>(ND->getUnderlyingDecl());
881 if (isa<TypeDecl>(ND) || isa<ObjCInterfaceDecl>(ND))
882 return false;
883
884 unsigned IDNS = Decl::IDNS_Ordinary;
885 if (SemaRef.getLangOptions().CPlusPlus)
Douglas Gregor9b30b262010-06-15 20:26:51 +0000886 IDNS |= Decl::IDNS_Tag | Decl::IDNS_Namespace | Decl::IDNS_Member;
Douglas Gregor4710e5b2010-05-28 00:49:12 +0000887 else if (SemaRef.getLangOptions().ObjC1 && isa<ObjCIvarDecl>(ND))
888 return true;
889
890 return ND->getIdentifierNamespace() & IDNS;
891}
892
Douglas Gregorf9578432010-07-28 21:50:18 +0000893bool ResultBuilder::IsIntegralConstantValue(NamedDecl *ND) const {
894 if (!IsOrdinaryNonTypeName(ND))
895 return 0;
896
897 if (ValueDecl *VD = dyn_cast<ValueDecl>(ND->getUnderlyingDecl()))
898 if (VD->getType()->isIntegralOrEnumerationType())
899 return true;
900
901 return false;
902}
903
Douglas Gregor4710e5b2010-05-28 00:49:12 +0000904/// \brief Determines whether this given declaration will be found by
Douglas Gregor01dfea02010-01-10 23:08:15 +0000905/// ordinary name lookup.
906bool ResultBuilder::IsOrdinaryNonValueName(NamedDecl *ND) const {
Douglas Gregor4710e5b2010-05-28 00:49:12 +0000907 ND = cast<NamedDecl>(ND->getUnderlyingDecl());
908
Douglas Gregor01dfea02010-01-10 23:08:15 +0000909 unsigned IDNS = Decl::IDNS_Ordinary;
910 if (SemaRef.getLangOptions().CPlusPlus)
John McCall0d6b1642010-04-23 18:46:30 +0000911 IDNS |= Decl::IDNS_Tag | Decl::IDNS_Namespace;
Douglas Gregor01dfea02010-01-10 23:08:15 +0000912
913 return (ND->getIdentifierNamespace() & IDNS) &&
Douglas Gregor4710e5b2010-05-28 00:49:12 +0000914 !isa<ValueDecl>(ND) && !isa<FunctionTemplateDecl>(ND) &&
915 !isa<ObjCPropertyDecl>(ND);
Douglas Gregor01dfea02010-01-10 23:08:15 +0000916}
917
Douglas Gregor86d9a522009-09-21 16:56:56 +0000918/// \brief Determines whether the given declaration is suitable as the
919/// start of a C++ nested-name-specifier, e.g., a class or namespace.
920bool ResultBuilder::IsNestedNameSpecifier(NamedDecl *ND) const {
921 // Allow us to find class templates, too.
922 if (ClassTemplateDecl *ClassTemplate = dyn_cast<ClassTemplateDecl>(ND))
923 ND = ClassTemplate->getTemplatedDecl();
924
925 return SemaRef.isAcceptableNestedNameSpecifier(ND);
926}
927
928/// \brief Determines whether the given declaration is an enumeration.
929bool ResultBuilder::IsEnum(NamedDecl *ND) const {
930 return isa<EnumDecl>(ND);
931}
932
933/// \brief Determines whether the given declaration is a class or struct.
934bool ResultBuilder::IsClassOrStruct(NamedDecl *ND) const {
935 // Allow us to find class templates, too.
936 if (ClassTemplateDecl *ClassTemplate = dyn_cast<ClassTemplateDecl>(ND))
937 ND = ClassTemplate->getTemplatedDecl();
938
939 if (RecordDecl *RD = dyn_cast<RecordDecl>(ND))
Abramo Bagnara465d41b2010-05-11 21:36:43 +0000940 return RD->getTagKind() == TTK_Class ||
941 RD->getTagKind() == TTK_Struct;
Douglas Gregor86d9a522009-09-21 16:56:56 +0000942
943 return false;
944}
945
946/// \brief Determines whether the given declaration is a union.
947bool ResultBuilder::IsUnion(NamedDecl *ND) const {
948 // Allow us to find class templates, too.
949 if (ClassTemplateDecl *ClassTemplate = dyn_cast<ClassTemplateDecl>(ND))
950 ND = ClassTemplate->getTemplatedDecl();
951
952 if (RecordDecl *RD = dyn_cast<RecordDecl>(ND))
Abramo Bagnara465d41b2010-05-11 21:36:43 +0000953 return RD->getTagKind() == TTK_Union;
Douglas Gregor86d9a522009-09-21 16:56:56 +0000954
955 return false;
956}
957
958/// \brief Determines whether the given declaration is a namespace.
959bool ResultBuilder::IsNamespace(NamedDecl *ND) const {
960 return isa<NamespaceDecl>(ND);
961}
962
963/// \brief Determines whether the given declaration is a namespace or
964/// namespace alias.
965bool ResultBuilder::IsNamespaceOrAlias(NamedDecl *ND) const {
966 return isa<NamespaceDecl>(ND) || isa<NamespaceAliasDecl>(ND);
967}
968
Douglas Gregor76282942009-12-11 17:31:05 +0000969/// \brief Determines whether the given declaration is a type.
Douglas Gregor86d9a522009-09-21 16:56:56 +0000970bool ResultBuilder::IsType(NamedDecl *ND) const {
Douglas Gregord32b0222010-08-24 01:06:58 +0000971 if (UsingShadowDecl *Using = dyn_cast<UsingShadowDecl>(ND))
972 ND = Using->getTargetDecl();
973
974 return isa<TypeDecl>(ND) || isa<ObjCInterfaceDecl>(ND);
Douglas Gregor86d9a522009-09-21 16:56:56 +0000975}
976
Douglas Gregor76282942009-12-11 17:31:05 +0000977/// \brief Determines which members of a class should be visible via
978/// "." or "->". Only value declarations, nested name specifiers, and
979/// using declarations thereof should show up.
Douglas Gregoreb5758b2009-09-23 22:26:46 +0000980bool ResultBuilder::IsMember(NamedDecl *ND) const {
Douglas Gregor76282942009-12-11 17:31:05 +0000981 if (UsingShadowDecl *Using = dyn_cast<UsingShadowDecl>(ND))
982 ND = Using->getTargetDecl();
983
Douglas Gregorce821962009-12-11 18:14:22 +0000984 return isa<ValueDecl>(ND) || isa<FunctionTemplateDecl>(ND) ||
985 isa<ObjCPropertyDecl>(ND);
Douglas Gregoreb5758b2009-09-23 22:26:46 +0000986}
987
Douglas Gregor8e254cf2010-05-27 23:06:34 +0000988static bool isObjCReceiverType(ASTContext &C, QualType T) {
989 T = C.getCanonicalType(T);
990 switch (T->getTypeClass()) {
991 case Type::ObjCObject:
992 case Type::ObjCInterface:
993 case Type::ObjCObjectPointer:
994 return true;
995
996 case Type::Builtin:
997 switch (cast<BuiltinType>(T)->getKind()) {
998 case BuiltinType::ObjCId:
999 case BuiltinType::ObjCClass:
1000 case BuiltinType::ObjCSel:
1001 return true;
1002
1003 default:
1004 break;
1005 }
1006 return false;
1007
1008 default:
1009 break;
1010 }
1011
1012 if (!C.getLangOptions().CPlusPlus)
1013 return false;
1014
1015 // FIXME: We could perform more analysis here to determine whether a
1016 // particular class type has any conversions to Objective-C types. For now,
1017 // just accept all class types.
1018 return T->isDependentType() || T->isRecordType();
1019}
1020
1021bool ResultBuilder::IsObjCMessageReceiver(NamedDecl *ND) const {
1022 QualType T = getDeclUsageType(SemaRef.Context, ND);
1023 if (T.isNull())
1024 return false;
1025
1026 T = SemaRef.Context.getBaseElementType(T);
1027 return isObjCReceiverType(SemaRef.Context, T);
1028}
1029
Douglas Gregorfb629412010-08-23 21:17:50 +00001030bool ResultBuilder::IsObjCCollection(NamedDecl *ND) const {
1031 if ((SemaRef.getLangOptions().CPlusPlus && !IsOrdinaryName(ND)) ||
1032 (!SemaRef.getLangOptions().CPlusPlus && !IsOrdinaryNonTypeName(ND)))
1033 return false;
1034
1035 QualType T = getDeclUsageType(SemaRef.Context, ND);
1036 if (T.isNull())
1037 return false;
1038
1039 T = SemaRef.Context.getBaseElementType(T);
1040 return T->isObjCObjectType() || T->isObjCObjectPointerType() ||
1041 T->isObjCIdType() ||
1042 (SemaRef.getLangOptions().CPlusPlus && T->isRecordType());
1043}
Douglas Gregor8e254cf2010-05-27 23:06:34 +00001044
Douglas Gregor80f4f4c2010-01-14 16:08:12 +00001045/// \rief Determines whether the given declaration is an Objective-C
1046/// instance variable.
1047bool ResultBuilder::IsObjCIvar(NamedDecl *ND) const {
1048 return isa<ObjCIvarDecl>(ND);
1049}
1050
Douglas Gregor1ca6ae82010-01-14 01:09:38 +00001051namespace {
1052 /// \brief Visible declaration consumer that adds a code-completion result
1053 /// for each visible declaration.
1054 class CodeCompletionDeclConsumer : public VisibleDeclConsumer {
1055 ResultBuilder &Results;
1056 DeclContext *CurContext;
1057
1058 public:
1059 CodeCompletionDeclConsumer(ResultBuilder &Results, DeclContext *CurContext)
1060 : Results(Results), CurContext(CurContext) { }
1061
Douglas Gregor0cc84042010-01-14 15:47:35 +00001062 virtual void FoundDecl(NamedDecl *ND, NamedDecl *Hiding, bool InBaseClass) {
1063 Results.AddResult(ND, CurContext, Hiding, InBaseClass);
Douglas Gregor1ca6ae82010-01-14 01:09:38 +00001064 }
1065 };
1066}
1067
Douglas Gregor86d9a522009-09-21 16:56:56 +00001068/// \brief Add type specifiers for the current language as keyword results.
Douglas Gregorbca403c2010-01-13 23:51:12 +00001069static void AddTypeSpecifierResults(const LangOptions &LangOpts,
Douglas Gregor86d9a522009-09-21 16:56:56 +00001070 ResultBuilder &Results) {
John McCall0a2c5e22010-08-25 06:19:51 +00001071 typedef CodeCompletionResult Result;
Douglas Gregor12e13132010-05-26 22:00:08 +00001072 Results.AddResult(Result("short", CCP_Type));
1073 Results.AddResult(Result("long", CCP_Type));
1074 Results.AddResult(Result("signed", CCP_Type));
1075 Results.AddResult(Result("unsigned", CCP_Type));
1076 Results.AddResult(Result("void", CCP_Type));
1077 Results.AddResult(Result("char", CCP_Type));
1078 Results.AddResult(Result("int", CCP_Type));
1079 Results.AddResult(Result("float", CCP_Type));
1080 Results.AddResult(Result("double", CCP_Type));
1081 Results.AddResult(Result("enum", CCP_Type));
1082 Results.AddResult(Result("struct", CCP_Type));
1083 Results.AddResult(Result("union", CCP_Type));
1084 Results.AddResult(Result("const", CCP_Type));
1085 Results.AddResult(Result("volatile", CCP_Type));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001086
Douglas Gregor86d9a522009-09-21 16:56:56 +00001087 if (LangOpts.C99) {
1088 // C99-specific
Douglas Gregor12e13132010-05-26 22:00:08 +00001089 Results.AddResult(Result("_Complex", CCP_Type));
1090 Results.AddResult(Result("_Imaginary", CCP_Type));
1091 Results.AddResult(Result("_Bool", CCP_Type));
1092 Results.AddResult(Result("restrict", CCP_Type));
Douglas Gregor86d9a522009-09-21 16:56:56 +00001093 }
1094
1095 if (LangOpts.CPlusPlus) {
1096 // C++-specific
Douglas Gregorb05496d2010-09-20 21:11:48 +00001097 Results.AddResult(Result("bool", CCP_Type +
1098 (LangOpts.ObjC1? CCD_bool_in_ObjC : 0)));
Douglas Gregor12e13132010-05-26 22:00:08 +00001099 Results.AddResult(Result("class", CCP_Type));
1100 Results.AddResult(Result("wchar_t", CCP_Type));
Douglas Gregor86d9a522009-09-21 16:56:56 +00001101
Douglas Gregorc8bddde2010-05-28 00:22:41 +00001102 // typename qualified-id
1103 CodeCompletionString *Pattern = new CodeCompletionString;
1104 Pattern->AddTypedTextChunk("typename");
1105 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
1106 Pattern->AddPlaceholderChunk("qualifier");
1107 Pattern->AddTextChunk("::");
1108 Pattern->AddPlaceholderChunk("name");
1109 Results.AddResult(Result(Pattern));
Douglas Gregord8e8a582010-05-25 21:41:55 +00001110
Douglas Gregor86d9a522009-09-21 16:56:56 +00001111 if (LangOpts.CPlusPlus0x) {
Douglas Gregor12e13132010-05-26 22:00:08 +00001112 Results.AddResult(Result("auto", CCP_Type));
1113 Results.AddResult(Result("char16_t", CCP_Type));
1114 Results.AddResult(Result("char32_t", CCP_Type));
Douglas Gregorc8bddde2010-05-28 00:22:41 +00001115
1116 CodeCompletionString *Pattern = new CodeCompletionString;
1117 Pattern->AddTypedTextChunk("decltype");
1118 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
1119 Pattern->AddPlaceholderChunk("expression");
1120 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
1121 Results.AddResult(Result(Pattern));
Douglas Gregor86d9a522009-09-21 16:56:56 +00001122 }
1123 }
1124
1125 // GNU extensions
1126 if (LangOpts.GNUMode) {
1127 // FIXME: Enable when we actually support decimal floating point.
Douglas Gregora4477812010-01-14 16:01:26 +00001128 // Results.AddResult(Result("_Decimal32"));
1129 // Results.AddResult(Result("_Decimal64"));
1130 // Results.AddResult(Result("_Decimal128"));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001131
Douglas Gregorc8bddde2010-05-28 00:22:41 +00001132 CodeCompletionString *Pattern = new CodeCompletionString;
1133 Pattern->AddTypedTextChunk("typeof");
1134 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
1135 Pattern->AddPlaceholderChunk("expression");
1136 Results.AddResult(Result(Pattern));
1137
1138 Pattern = new CodeCompletionString;
1139 Pattern->AddTypedTextChunk("typeof");
1140 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
1141 Pattern->AddPlaceholderChunk("type");
1142 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
1143 Results.AddResult(Result(Pattern));
Douglas Gregor86d9a522009-09-21 16:56:56 +00001144 }
1145}
1146
John McCallf312b1e2010-08-26 23:41:50 +00001147static void AddStorageSpecifiers(Sema::ParserCompletionContext CCC,
Douglas Gregor01dfea02010-01-10 23:08:15 +00001148 const LangOptions &LangOpts,
Douglas Gregor01dfea02010-01-10 23:08:15 +00001149 ResultBuilder &Results) {
John McCall0a2c5e22010-08-25 06:19:51 +00001150 typedef CodeCompletionResult Result;
Douglas Gregor01dfea02010-01-10 23:08:15 +00001151 // Note: we don't suggest either "auto" or "register", because both
1152 // are pointless as storage specifiers. Elsewhere, we suggest "auto"
1153 // in C++0x as a type specifier.
Douglas Gregora4477812010-01-14 16:01:26 +00001154 Results.AddResult(Result("extern"));
1155 Results.AddResult(Result("static"));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001156}
1157
John McCallf312b1e2010-08-26 23:41:50 +00001158static void AddFunctionSpecifiers(Sema::ParserCompletionContext CCC,
Douglas Gregor01dfea02010-01-10 23:08:15 +00001159 const LangOptions &LangOpts,
Douglas Gregor01dfea02010-01-10 23:08:15 +00001160 ResultBuilder &Results) {
John McCall0a2c5e22010-08-25 06:19:51 +00001161 typedef CodeCompletionResult Result;
Douglas Gregor01dfea02010-01-10 23:08:15 +00001162 switch (CCC) {
John McCallf312b1e2010-08-26 23:41:50 +00001163 case Sema::PCC_Class:
1164 case Sema::PCC_MemberTemplate:
Douglas Gregor01dfea02010-01-10 23:08:15 +00001165 if (LangOpts.CPlusPlus) {
Douglas Gregora4477812010-01-14 16:01:26 +00001166 Results.AddResult(Result("explicit"));
1167 Results.AddResult(Result("friend"));
1168 Results.AddResult(Result("mutable"));
1169 Results.AddResult(Result("virtual"));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001170 }
1171 // Fall through
1172
John McCallf312b1e2010-08-26 23:41:50 +00001173 case Sema::PCC_ObjCInterface:
1174 case Sema::PCC_ObjCImplementation:
1175 case Sema::PCC_Namespace:
1176 case Sema::PCC_Template:
Douglas Gregor01dfea02010-01-10 23:08:15 +00001177 if (LangOpts.CPlusPlus || LangOpts.C99)
Douglas Gregora4477812010-01-14 16:01:26 +00001178 Results.AddResult(Result("inline"));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001179 break;
1180
John McCallf312b1e2010-08-26 23:41:50 +00001181 case Sema::PCC_ObjCInstanceVariableList:
1182 case Sema::PCC_Expression:
1183 case Sema::PCC_Statement:
1184 case Sema::PCC_ForInit:
1185 case Sema::PCC_Condition:
1186 case Sema::PCC_RecoveryInFunction:
1187 case Sema::PCC_Type:
Douglas Gregor02688102010-09-14 23:59:36 +00001188 case Sema::PCC_ParenthesizedExpression:
Douglas Gregor01dfea02010-01-10 23:08:15 +00001189 break;
1190 }
1191}
1192
Douglas Gregorbca403c2010-01-13 23:51:12 +00001193static void AddObjCExpressionResults(ResultBuilder &Results, bool NeedAt);
1194static void AddObjCStatementResults(ResultBuilder &Results, bool NeedAt);
1195static void AddObjCVisibilityResults(const LangOptions &LangOpts,
Douglas Gregorc38c3e12010-01-13 21:54:15 +00001196 ResultBuilder &Results,
1197 bool NeedAt);
Douglas Gregorbca403c2010-01-13 23:51:12 +00001198static void AddObjCImplementationResults(const LangOptions &LangOpts,
Douglas Gregorb6ac2452010-01-13 21:24:21 +00001199 ResultBuilder &Results,
1200 bool NeedAt);
Douglas Gregorbca403c2010-01-13 23:51:12 +00001201static void AddObjCInterfaceResults(const LangOptions &LangOpts,
Douglas Gregorb6ac2452010-01-13 21:24:21 +00001202 ResultBuilder &Results,
1203 bool NeedAt);
Douglas Gregorbca403c2010-01-13 23:51:12 +00001204static void AddObjCTopLevelResults(ResultBuilder &Results, bool NeedAt);
Douglas Gregorb6ac2452010-01-13 21:24:21 +00001205
Douglas Gregorc8bddde2010-05-28 00:22:41 +00001206static void AddTypedefResult(ResultBuilder &Results) {
1207 CodeCompletionString *Pattern = new CodeCompletionString;
1208 Pattern->AddTypedTextChunk("typedef");
1209 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
1210 Pattern->AddPlaceholderChunk("type");
1211 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
1212 Pattern->AddPlaceholderChunk("name");
John McCall0a2c5e22010-08-25 06:19:51 +00001213 Results.AddResult(CodeCompletionResult(Pattern));
Douglas Gregorc8bddde2010-05-28 00:22:41 +00001214}
1215
John McCallf312b1e2010-08-26 23:41:50 +00001216static bool WantTypesInContext(Sema::ParserCompletionContext CCC,
Douglas Gregor4710e5b2010-05-28 00:49:12 +00001217 const LangOptions &LangOpts) {
Douglas Gregor4710e5b2010-05-28 00:49:12 +00001218 switch (CCC) {
John McCallf312b1e2010-08-26 23:41:50 +00001219 case Sema::PCC_Namespace:
1220 case Sema::PCC_Class:
1221 case Sema::PCC_ObjCInstanceVariableList:
1222 case Sema::PCC_Template:
1223 case Sema::PCC_MemberTemplate:
1224 case Sema::PCC_Statement:
1225 case Sema::PCC_RecoveryInFunction:
1226 case Sema::PCC_Type:
Douglas Gregor02688102010-09-14 23:59:36 +00001227 case Sema::PCC_ParenthesizedExpression:
Douglas Gregor4710e5b2010-05-28 00:49:12 +00001228 return true;
1229
John McCallf312b1e2010-08-26 23:41:50 +00001230 case Sema::PCC_Expression:
1231 case Sema::PCC_Condition:
Douglas Gregor02688102010-09-14 23:59:36 +00001232 return LangOpts.CPlusPlus;
1233
1234 case Sema::PCC_ObjCInterface:
1235 case Sema::PCC_ObjCImplementation:
Douglas Gregor4710e5b2010-05-28 00:49:12 +00001236 return false;
1237
John McCallf312b1e2010-08-26 23:41:50 +00001238 case Sema::PCC_ForInit:
Douglas Gregor02688102010-09-14 23:59:36 +00001239 return LangOpts.CPlusPlus || LangOpts.ObjC1 || LangOpts.C99;
Douglas Gregor4710e5b2010-05-28 00:49:12 +00001240 }
1241
1242 return false;
1243}
1244
Douglas Gregor01dfea02010-01-10 23:08:15 +00001245/// \brief Add language constructs that show up for "ordinary" names.
John McCallf312b1e2010-08-26 23:41:50 +00001246static void AddOrdinaryNameResults(Sema::ParserCompletionContext CCC,
Douglas Gregor01dfea02010-01-10 23:08:15 +00001247 Scope *S,
1248 Sema &SemaRef,
Douglas Gregor01dfea02010-01-10 23:08:15 +00001249 ResultBuilder &Results) {
John McCall0a2c5e22010-08-25 06:19:51 +00001250 typedef CodeCompletionResult Result;
Douglas Gregor01dfea02010-01-10 23:08:15 +00001251 switch (CCC) {
John McCallf312b1e2010-08-26 23:41:50 +00001252 case Sema::PCC_Namespace:
Douglas Gregorc8bddde2010-05-28 00:22:41 +00001253 if (SemaRef.getLangOptions().CPlusPlus) {
1254 CodeCompletionString *Pattern = 0;
1255
1256 if (Results.includeCodePatterns()) {
1257 // namespace <identifier> { declarations }
1258 CodeCompletionString *Pattern = new CodeCompletionString;
1259 Pattern->AddTypedTextChunk("namespace");
1260 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
1261 Pattern->AddPlaceholderChunk("identifier");
1262 Pattern->AddChunk(CodeCompletionString::CK_LeftBrace);
1263 Pattern->AddPlaceholderChunk("declarations");
1264 Pattern->AddChunk(CodeCompletionString::CK_VerticalSpace);
1265 Pattern->AddChunk(CodeCompletionString::CK_RightBrace);
1266 Results.AddResult(Result(Pattern));
1267 }
1268
Douglas Gregor01dfea02010-01-10 23:08:15 +00001269 // namespace identifier = identifier ;
1270 Pattern = new CodeCompletionString;
1271 Pattern->AddTypedTextChunk("namespace");
1272 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
Douglas Gregorc8bddde2010-05-28 00:22:41 +00001273 Pattern->AddPlaceholderChunk("name");
Douglas Gregor01dfea02010-01-10 23:08:15 +00001274 Pattern->AddChunk(CodeCompletionString::CK_Equal);
Douglas Gregorc8bddde2010-05-28 00:22:41 +00001275 Pattern->AddPlaceholderChunk("namespace");
Douglas Gregora4477812010-01-14 16:01:26 +00001276 Results.AddResult(Result(Pattern));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001277
1278 // Using directives
1279 Pattern = new CodeCompletionString;
1280 Pattern->AddTypedTextChunk("using");
1281 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
1282 Pattern->AddTextChunk("namespace");
1283 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
1284 Pattern->AddPlaceholderChunk("identifier");
Douglas Gregora4477812010-01-14 16:01:26 +00001285 Results.AddResult(Result(Pattern));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001286
1287 // asm(string-literal)
1288 Pattern = new CodeCompletionString;
1289 Pattern->AddTypedTextChunk("asm");
1290 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
1291 Pattern->AddPlaceholderChunk("string-literal");
1292 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
Douglas Gregora4477812010-01-14 16:01:26 +00001293 Results.AddResult(Result(Pattern));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001294
Douglas Gregorc8bddde2010-05-28 00:22:41 +00001295 if (Results.includeCodePatterns()) {
1296 // Explicit template instantiation
1297 Pattern = new CodeCompletionString;
1298 Pattern->AddTypedTextChunk("template");
1299 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
1300 Pattern->AddPlaceholderChunk("declaration");
1301 Results.AddResult(Result(Pattern));
1302 }
Douglas Gregor01dfea02010-01-10 23:08:15 +00001303 }
Douglas Gregorb6ac2452010-01-13 21:24:21 +00001304
1305 if (SemaRef.getLangOptions().ObjC1)
Douglas Gregorbca403c2010-01-13 23:51:12 +00001306 AddObjCTopLevelResults(Results, true);
Douglas Gregorb6ac2452010-01-13 21:24:21 +00001307
Douglas Gregorc8bddde2010-05-28 00:22:41 +00001308 AddTypedefResult(Results);
Douglas Gregor01dfea02010-01-10 23:08:15 +00001309 // Fall through
1310
John McCallf312b1e2010-08-26 23:41:50 +00001311 case Sema::PCC_Class:
Douglas Gregorc8bddde2010-05-28 00:22:41 +00001312 if (SemaRef.getLangOptions().CPlusPlus) {
Douglas Gregor01dfea02010-01-10 23:08:15 +00001313 // Using declaration
1314 CodeCompletionString *Pattern = new CodeCompletionString;
1315 Pattern->AddTypedTextChunk("using");
1316 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
Douglas Gregorc8bddde2010-05-28 00:22:41 +00001317 Pattern->AddPlaceholderChunk("qualifier");
1318 Pattern->AddTextChunk("::");
1319 Pattern->AddPlaceholderChunk("name");
Douglas Gregora4477812010-01-14 16:01:26 +00001320 Results.AddResult(Result(Pattern));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001321
Douglas Gregorc8bddde2010-05-28 00:22:41 +00001322 // using typename qualifier::name (only in a dependent context)
Douglas Gregor01dfea02010-01-10 23:08:15 +00001323 if (SemaRef.CurContext->isDependentContext()) {
1324 Pattern = new CodeCompletionString;
1325 Pattern->AddTypedTextChunk("using");
1326 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
1327 Pattern->AddTextChunk("typename");
1328 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
Douglas Gregorc8bddde2010-05-28 00:22:41 +00001329 Pattern->AddPlaceholderChunk("qualifier");
1330 Pattern->AddTextChunk("::");
1331 Pattern->AddPlaceholderChunk("name");
Douglas Gregora4477812010-01-14 16:01:26 +00001332 Results.AddResult(Result(Pattern));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001333 }
1334
John McCallf312b1e2010-08-26 23:41:50 +00001335 if (CCC == Sema::PCC_Class) {
Douglas Gregorc8bddde2010-05-28 00:22:41 +00001336 AddTypedefResult(Results);
1337
Douglas Gregor01dfea02010-01-10 23:08:15 +00001338 // public:
1339 Pattern = new CodeCompletionString;
1340 Pattern->AddTypedTextChunk("public");
1341 Pattern->AddChunk(CodeCompletionString::CK_Colon);
Douglas Gregora4477812010-01-14 16:01:26 +00001342 Results.AddResult(Result(Pattern));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001343
1344 // protected:
1345 Pattern = new CodeCompletionString;
1346 Pattern->AddTypedTextChunk("protected");
1347 Pattern->AddChunk(CodeCompletionString::CK_Colon);
Douglas Gregora4477812010-01-14 16:01:26 +00001348 Results.AddResult(Result(Pattern));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001349
1350 // private:
1351 Pattern = new CodeCompletionString;
1352 Pattern->AddTypedTextChunk("private");
1353 Pattern->AddChunk(CodeCompletionString::CK_Colon);
Douglas Gregora4477812010-01-14 16:01:26 +00001354 Results.AddResult(Result(Pattern));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001355 }
1356 }
1357 // Fall through
1358
John McCallf312b1e2010-08-26 23:41:50 +00001359 case Sema::PCC_Template:
1360 case Sema::PCC_MemberTemplate:
Douglas Gregord8e8a582010-05-25 21:41:55 +00001361 if (SemaRef.getLangOptions().CPlusPlus && Results.includeCodePatterns()) {
Douglas Gregor01dfea02010-01-10 23:08:15 +00001362 // template < parameters >
1363 CodeCompletionString *Pattern = new CodeCompletionString;
1364 Pattern->AddTypedTextChunk("template");
1365 Pattern->AddChunk(CodeCompletionString::CK_LeftAngle);
1366 Pattern->AddPlaceholderChunk("parameters");
1367 Pattern->AddChunk(CodeCompletionString::CK_RightAngle);
Douglas Gregora4477812010-01-14 16:01:26 +00001368 Results.AddResult(Result(Pattern));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001369 }
1370
Douglas Gregorbca403c2010-01-13 23:51:12 +00001371 AddStorageSpecifiers(CCC, SemaRef.getLangOptions(), Results);
1372 AddFunctionSpecifiers(CCC, SemaRef.getLangOptions(), Results);
Douglas Gregor01dfea02010-01-10 23:08:15 +00001373 break;
1374
John McCallf312b1e2010-08-26 23:41:50 +00001375 case Sema::PCC_ObjCInterface:
Douglas Gregorbca403c2010-01-13 23:51:12 +00001376 AddObjCInterfaceResults(SemaRef.getLangOptions(), Results, true);
1377 AddStorageSpecifiers(CCC, SemaRef.getLangOptions(), Results);
1378 AddFunctionSpecifiers(CCC, SemaRef.getLangOptions(), Results);
Douglas Gregorb6ac2452010-01-13 21:24:21 +00001379 break;
1380
John McCallf312b1e2010-08-26 23:41:50 +00001381 case Sema::PCC_ObjCImplementation:
Douglas Gregorbca403c2010-01-13 23:51:12 +00001382 AddObjCImplementationResults(SemaRef.getLangOptions(), Results, true);
1383 AddStorageSpecifiers(CCC, SemaRef.getLangOptions(), Results);
1384 AddFunctionSpecifiers(CCC, SemaRef.getLangOptions(), Results);
Douglas Gregorb6ac2452010-01-13 21:24:21 +00001385 break;
1386
John McCallf312b1e2010-08-26 23:41:50 +00001387 case Sema::PCC_ObjCInstanceVariableList:
Douglas Gregorbca403c2010-01-13 23:51:12 +00001388 AddObjCVisibilityResults(SemaRef.getLangOptions(), Results, true);
Douglas Gregorc38c3e12010-01-13 21:54:15 +00001389 break;
1390
John McCallf312b1e2010-08-26 23:41:50 +00001391 case Sema::PCC_RecoveryInFunction:
1392 case Sema::PCC_Statement: {
Douglas Gregorc8bddde2010-05-28 00:22:41 +00001393 AddTypedefResult(Results);
Douglas Gregor01dfea02010-01-10 23:08:15 +00001394
1395 CodeCompletionString *Pattern = 0;
Douglas Gregord8e8a582010-05-25 21:41:55 +00001396 if (SemaRef.getLangOptions().CPlusPlus && Results.includeCodePatterns()) {
Douglas Gregor01dfea02010-01-10 23:08:15 +00001397 Pattern = new CodeCompletionString;
1398 Pattern->AddTypedTextChunk("try");
1399 Pattern->AddChunk(CodeCompletionString::CK_LeftBrace);
1400 Pattern->AddPlaceholderChunk("statements");
1401 Pattern->AddChunk(CodeCompletionString::CK_VerticalSpace);
1402 Pattern->AddChunk(CodeCompletionString::CK_RightBrace);
1403 Pattern->AddTextChunk("catch");
1404 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
1405 Pattern->AddPlaceholderChunk("declaration");
1406 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
1407 Pattern->AddChunk(CodeCompletionString::CK_LeftBrace);
1408 Pattern->AddPlaceholderChunk("statements");
1409 Pattern->AddChunk(CodeCompletionString::CK_VerticalSpace);
1410 Pattern->AddChunk(CodeCompletionString::CK_RightBrace);
Douglas Gregora4477812010-01-14 16:01:26 +00001411 Results.AddResult(Result(Pattern));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001412 }
Douglas Gregorb6ac2452010-01-13 21:24:21 +00001413 if (SemaRef.getLangOptions().ObjC1)
Douglas Gregorbca403c2010-01-13 23:51:12 +00001414 AddObjCStatementResults(Results, true);
Douglas Gregorb6ac2452010-01-13 21:24:21 +00001415
Douglas Gregord8e8a582010-05-25 21:41:55 +00001416 if (Results.includeCodePatterns()) {
1417 // if (condition) { statements }
1418 Pattern = new CodeCompletionString;
1419 Pattern->AddTypedTextChunk("if");
1420 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
1421 if (SemaRef.getLangOptions().CPlusPlus)
1422 Pattern->AddPlaceholderChunk("condition");
1423 else
1424 Pattern->AddPlaceholderChunk("expression");
1425 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
1426 Pattern->AddChunk(CodeCompletionString::CK_LeftBrace);
1427 Pattern->AddPlaceholderChunk("statements");
1428 Pattern->AddChunk(CodeCompletionString::CK_VerticalSpace);
1429 Pattern->AddChunk(CodeCompletionString::CK_RightBrace);
1430 Results.AddResult(Result(Pattern));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001431
Douglas Gregord8e8a582010-05-25 21:41:55 +00001432 // switch (condition) { }
1433 Pattern = new CodeCompletionString;
1434 Pattern->AddTypedTextChunk("switch");
1435 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
1436 if (SemaRef.getLangOptions().CPlusPlus)
1437 Pattern->AddPlaceholderChunk("condition");
1438 else
1439 Pattern->AddPlaceholderChunk("expression");
1440 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
1441 Pattern->AddChunk(CodeCompletionString::CK_LeftBrace);
1442 Pattern->AddChunk(CodeCompletionString::CK_VerticalSpace);
1443 Pattern->AddChunk(CodeCompletionString::CK_RightBrace);
1444 Results.AddResult(Result(Pattern));
1445 }
1446
Douglas Gregor01dfea02010-01-10 23:08:15 +00001447 // Switch-specific statements.
John McCall781472f2010-08-25 08:40:02 +00001448 if (!SemaRef.getCurFunction()->SwitchStack.empty()) {
Douglas Gregor01dfea02010-01-10 23:08:15 +00001449 // case expression:
1450 Pattern = new CodeCompletionString;
1451 Pattern->AddTypedTextChunk("case");
Douglas Gregorc8bddde2010-05-28 00:22:41 +00001452 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
Douglas Gregor01dfea02010-01-10 23:08:15 +00001453 Pattern->AddPlaceholderChunk("expression");
1454 Pattern->AddChunk(CodeCompletionString::CK_Colon);
Douglas Gregora4477812010-01-14 16:01:26 +00001455 Results.AddResult(Result(Pattern));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001456
1457 // default:
1458 Pattern = new CodeCompletionString;
1459 Pattern->AddTypedTextChunk("default");
1460 Pattern->AddChunk(CodeCompletionString::CK_Colon);
Douglas Gregora4477812010-01-14 16:01:26 +00001461 Results.AddResult(Result(Pattern));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001462 }
1463
Douglas Gregord8e8a582010-05-25 21:41:55 +00001464 if (Results.includeCodePatterns()) {
1465 /// while (condition) { statements }
1466 Pattern = new CodeCompletionString;
1467 Pattern->AddTypedTextChunk("while");
1468 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
1469 if (SemaRef.getLangOptions().CPlusPlus)
1470 Pattern->AddPlaceholderChunk("condition");
1471 else
1472 Pattern->AddPlaceholderChunk("expression");
1473 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
1474 Pattern->AddChunk(CodeCompletionString::CK_LeftBrace);
1475 Pattern->AddPlaceholderChunk("statements");
1476 Pattern->AddChunk(CodeCompletionString::CK_VerticalSpace);
1477 Pattern->AddChunk(CodeCompletionString::CK_RightBrace);
1478 Results.AddResult(Result(Pattern));
1479
1480 // do { statements } while ( expression );
1481 Pattern = new CodeCompletionString;
1482 Pattern->AddTypedTextChunk("do");
1483 Pattern->AddChunk(CodeCompletionString::CK_LeftBrace);
1484 Pattern->AddPlaceholderChunk("statements");
1485 Pattern->AddChunk(CodeCompletionString::CK_VerticalSpace);
1486 Pattern->AddChunk(CodeCompletionString::CK_RightBrace);
1487 Pattern->AddTextChunk("while");
1488 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
Douglas Gregor01dfea02010-01-10 23:08:15 +00001489 Pattern->AddPlaceholderChunk("expression");
Douglas Gregord8e8a582010-05-25 21:41:55 +00001490 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
1491 Results.AddResult(Result(Pattern));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001492
Douglas Gregord8e8a582010-05-25 21:41:55 +00001493 // for ( for-init-statement ; condition ; expression ) { statements }
1494 Pattern = new CodeCompletionString;
1495 Pattern->AddTypedTextChunk("for");
1496 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
1497 if (SemaRef.getLangOptions().CPlusPlus || SemaRef.getLangOptions().C99)
1498 Pattern->AddPlaceholderChunk("init-statement");
1499 else
1500 Pattern->AddPlaceholderChunk("init-expression");
1501 Pattern->AddChunk(CodeCompletionString::CK_SemiColon);
1502 Pattern->AddPlaceholderChunk("condition");
1503 Pattern->AddChunk(CodeCompletionString::CK_SemiColon);
1504 Pattern->AddPlaceholderChunk("inc-expression");
1505 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
1506 Pattern->AddChunk(CodeCompletionString::CK_LeftBrace);
1507 Pattern->AddPlaceholderChunk("statements");
1508 Pattern->AddChunk(CodeCompletionString::CK_VerticalSpace);
1509 Pattern->AddChunk(CodeCompletionString::CK_RightBrace);
1510 Results.AddResult(Result(Pattern));
1511 }
Douglas Gregor01dfea02010-01-10 23:08:15 +00001512
1513 if (S->getContinueParent()) {
1514 // continue ;
1515 Pattern = new CodeCompletionString;
1516 Pattern->AddTypedTextChunk("continue");
Douglas Gregora4477812010-01-14 16:01:26 +00001517 Results.AddResult(Result(Pattern));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001518 }
1519
1520 if (S->getBreakParent()) {
1521 // break ;
1522 Pattern = new CodeCompletionString;
1523 Pattern->AddTypedTextChunk("break");
Douglas Gregora4477812010-01-14 16:01:26 +00001524 Results.AddResult(Result(Pattern));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001525 }
1526
1527 // "return expression ;" or "return ;", depending on whether we
1528 // know the function is void or not.
1529 bool isVoid = false;
1530 if (FunctionDecl *Function = dyn_cast<FunctionDecl>(SemaRef.CurContext))
1531 isVoid = Function->getResultType()->isVoidType();
1532 else if (ObjCMethodDecl *Method
1533 = dyn_cast<ObjCMethodDecl>(SemaRef.CurContext))
1534 isVoid = Method->getResultType()->isVoidType();
Douglas Gregor9ea9bdb2010-03-01 23:15:13 +00001535 else if (SemaRef.getCurBlock() &&
1536 !SemaRef.getCurBlock()->ReturnType.isNull())
1537 isVoid = SemaRef.getCurBlock()->ReturnType->isVoidType();
Douglas Gregor01dfea02010-01-10 23:08:15 +00001538 Pattern = new CodeCompletionString;
1539 Pattern->AddTypedTextChunk("return");
Douglas Gregor93298002010-02-18 04:06:48 +00001540 if (!isVoid) {
1541 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
Douglas Gregor01dfea02010-01-10 23:08:15 +00001542 Pattern->AddPlaceholderChunk("expression");
Douglas Gregor93298002010-02-18 04:06:48 +00001543 }
Douglas Gregora4477812010-01-14 16:01:26 +00001544 Results.AddResult(Result(Pattern));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001545
Douglas Gregorc8bddde2010-05-28 00:22:41 +00001546 // goto identifier ;
1547 Pattern = new CodeCompletionString;
1548 Pattern->AddTypedTextChunk("goto");
1549 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
1550 Pattern->AddPlaceholderChunk("label");
1551 Results.AddResult(Result(Pattern));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001552
Douglas Gregorc8bddde2010-05-28 00:22:41 +00001553 // Using directives
1554 Pattern = new CodeCompletionString;
1555 Pattern->AddTypedTextChunk("using");
1556 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
1557 Pattern->AddTextChunk("namespace");
1558 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
1559 Pattern->AddPlaceholderChunk("identifier");
1560 Results.AddResult(Result(Pattern));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001561 }
1562
1563 // Fall through (for statement expressions).
John McCallf312b1e2010-08-26 23:41:50 +00001564 case Sema::PCC_ForInit:
1565 case Sema::PCC_Condition:
Douglas Gregorbca403c2010-01-13 23:51:12 +00001566 AddStorageSpecifiers(CCC, SemaRef.getLangOptions(), Results);
Douglas Gregor01dfea02010-01-10 23:08:15 +00001567 // Fall through: conditions and statements can have expressions.
1568
Douglas Gregor02688102010-09-14 23:59:36 +00001569 case Sema::PCC_ParenthesizedExpression:
John McCallf312b1e2010-08-26 23:41:50 +00001570 case Sema::PCC_Expression: {
Douglas Gregor01dfea02010-01-10 23:08:15 +00001571 CodeCompletionString *Pattern = 0;
1572 if (SemaRef.getLangOptions().CPlusPlus) {
1573 // 'this', if we're in a non-static member function.
1574 if (CXXMethodDecl *Method = dyn_cast<CXXMethodDecl>(SemaRef.CurContext))
1575 if (!Method->isStatic())
Douglas Gregora4477812010-01-14 16:01:26 +00001576 Results.AddResult(Result("this"));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001577
1578 // true, false
Douglas Gregora4477812010-01-14 16:01:26 +00001579 Results.AddResult(Result("true"));
1580 Results.AddResult(Result("false"));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001581
Douglas Gregorc8bddde2010-05-28 00:22:41 +00001582 // dynamic_cast < type-id > ( expression )
1583 Pattern = new CodeCompletionString;
1584 Pattern->AddTypedTextChunk("dynamic_cast");
1585 Pattern->AddChunk(CodeCompletionString::CK_LeftAngle);
1586 Pattern->AddPlaceholderChunk("type");
1587 Pattern->AddChunk(CodeCompletionString::CK_RightAngle);
1588 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
1589 Pattern->AddPlaceholderChunk("expression");
1590 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
1591 Results.AddResult(Result(Pattern));
1592
1593 // static_cast < type-id > ( expression )
1594 Pattern = new CodeCompletionString;
1595 Pattern->AddTypedTextChunk("static_cast");
1596 Pattern->AddChunk(CodeCompletionString::CK_LeftAngle);
1597 Pattern->AddPlaceholderChunk("type");
1598 Pattern->AddChunk(CodeCompletionString::CK_RightAngle);
1599 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
1600 Pattern->AddPlaceholderChunk("expression");
1601 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
1602 Results.AddResult(Result(Pattern));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001603
Douglas Gregorc8bddde2010-05-28 00:22:41 +00001604 // reinterpret_cast < type-id > ( expression )
1605 Pattern = new CodeCompletionString;
1606 Pattern->AddTypedTextChunk("reinterpret_cast");
1607 Pattern->AddChunk(CodeCompletionString::CK_LeftAngle);
1608 Pattern->AddPlaceholderChunk("type");
1609 Pattern->AddChunk(CodeCompletionString::CK_RightAngle);
1610 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
1611 Pattern->AddPlaceholderChunk("expression");
1612 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
1613 Results.AddResult(Result(Pattern));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001614
Douglas Gregorc8bddde2010-05-28 00:22:41 +00001615 // const_cast < type-id > ( expression )
1616 Pattern = new CodeCompletionString;
1617 Pattern->AddTypedTextChunk("const_cast");
1618 Pattern->AddChunk(CodeCompletionString::CK_LeftAngle);
1619 Pattern->AddPlaceholderChunk("type");
1620 Pattern->AddChunk(CodeCompletionString::CK_RightAngle);
1621 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
1622 Pattern->AddPlaceholderChunk("expression");
1623 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
1624 Results.AddResult(Result(Pattern));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001625
Douglas Gregorc8bddde2010-05-28 00:22:41 +00001626 // typeid ( expression-or-type )
1627 Pattern = new CodeCompletionString;
1628 Pattern->AddTypedTextChunk("typeid");
1629 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
1630 Pattern->AddPlaceholderChunk("expression-or-type");
1631 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
1632 Results.AddResult(Result(Pattern));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001633
Douglas Gregorc8bddde2010-05-28 00:22:41 +00001634 // new T ( ... )
1635 Pattern = new CodeCompletionString;
1636 Pattern->AddTypedTextChunk("new");
1637 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
1638 Pattern->AddPlaceholderChunk("type");
1639 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
1640 Pattern->AddPlaceholderChunk("expressions");
1641 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
1642 Results.AddResult(Result(Pattern));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001643
Douglas Gregorc8bddde2010-05-28 00:22:41 +00001644 // new T [ ] ( ... )
1645 Pattern = new CodeCompletionString;
1646 Pattern->AddTypedTextChunk("new");
1647 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
1648 Pattern->AddPlaceholderChunk("type");
1649 Pattern->AddChunk(CodeCompletionString::CK_LeftBracket);
1650 Pattern->AddPlaceholderChunk("size");
1651 Pattern->AddChunk(CodeCompletionString::CK_RightBracket);
1652 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
1653 Pattern->AddPlaceholderChunk("expressions");
1654 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
1655 Results.AddResult(Result(Pattern));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001656
Douglas Gregorc8bddde2010-05-28 00:22:41 +00001657 // delete expression
1658 Pattern = new CodeCompletionString;
1659 Pattern->AddTypedTextChunk("delete");
1660 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
1661 Pattern->AddPlaceholderChunk("expression");
1662 Results.AddResult(Result(Pattern));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001663
Douglas Gregorc8bddde2010-05-28 00:22:41 +00001664 // delete [] expression
1665 Pattern = new CodeCompletionString;
1666 Pattern->AddTypedTextChunk("delete");
1667 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
1668 Pattern->AddChunk(CodeCompletionString::CK_LeftBracket);
1669 Pattern->AddChunk(CodeCompletionString::CK_RightBracket);
1670 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
1671 Pattern->AddPlaceholderChunk("expression");
1672 Results.AddResult(Result(Pattern));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001673
Douglas Gregorc8bddde2010-05-28 00:22:41 +00001674 // throw expression
1675 Pattern = new CodeCompletionString;
1676 Pattern->AddTypedTextChunk("throw");
1677 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
1678 Pattern->AddPlaceholderChunk("expression");
1679 Results.AddResult(Result(Pattern));
Douglas Gregor12e13132010-05-26 22:00:08 +00001680
1681 // FIXME: Rethrow?
Douglas Gregor01dfea02010-01-10 23:08:15 +00001682 }
1683
1684 if (SemaRef.getLangOptions().ObjC1) {
1685 // Add "super", if we're in an Objective-C class with a superclass.
Ted Kremenek681e2562010-05-31 21:43:10 +00001686 if (ObjCMethodDecl *Method = SemaRef.getCurMethodDecl()) {
1687 // The interface can be NULL.
1688 if (ObjCInterfaceDecl *ID = Method->getClassInterface())
1689 if (ID->getSuperClass())
1690 Results.AddResult(Result("super"));
1691 }
1692
Douglas Gregorbca403c2010-01-13 23:51:12 +00001693 AddObjCExpressionResults(Results, true);
Douglas Gregor01dfea02010-01-10 23:08:15 +00001694 }
1695
Douglas Gregorc8bddde2010-05-28 00:22:41 +00001696 // sizeof expression
1697 Pattern = new CodeCompletionString;
1698 Pattern->AddTypedTextChunk("sizeof");
1699 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
1700 Pattern->AddPlaceholderChunk("expression-or-type");
1701 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
1702 Results.AddResult(Result(Pattern));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001703 break;
1704 }
Douglas Gregord32b0222010-08-24 01:06:58 +00001705
John McCallf312b1e2010-08-26 23:41:50 +00001706 case Sema::PCC_Type:
Douglas Gregord32b0222010-08-24 01:06:58 +00001707 break;
Douglas Gregor01dfea02010-01-10 23:08:15 +00001708 }
1709
Douglas Gregor4710e5b2010-05-28 00:49:12 +00001710 if (WantTypesInContext(CCC, SemaRef.getLangOptions()))
1711 AddTypeSpecifierResults(SemaRef.getLangOptions(), Results);
Douglas Gregor01dfea02010-01-10 23:08:15 +00001712
John McCallf312b1e2010-08-26 23:41:50 +00001713 if (SemaRef.getLangOptions().CPlusPlus && CCC != Sema::PCC_Type)
Douglas Gregora4477812010-01-14 16:01:26 +00001714 Results.AddResult(Result("operator"));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001715}
1716
Douglas Gregorff5ce6e2009-12-18 18:53:37 +00001717/// \brief If the given declaration has an associated type, add it as a result
1718/// type chunk.
1719static void AddResultTypeChunk(ASTContext &Context,
1720 NamedDecl *ND,
1721 CodeCompletionString *Result) {
1722 if (!ND)
1723 return;
1724
1725 // Determine the type of the declaration (if it has a type).
1726 QualType T;
1727 if (FunctionDecl *Function = dyn_cast<FunctionDecl>(ND))
1728 T = Function->getResultType();
1729 else if (ObjCMethodDecl *Method = dyn_cast<ObjCMethodDecl>(ND))
1730 T = Method->getResultType();
1731 else if (FunctionTemplateDecl *FunTmpl = dyn_cast<FunctionTemplateDecl>(ND))
1732 T = FunTmpl->getTemplatedDecl()->getResultType();
1733 else if (EnumConstantDecl *Enumerator = dyn_cast<EnumConstantDecl>(ND))
1734 T = Context.getTypeDeclType(cast<TypeDecl>(Enumerator->getDeclContext()));
1735 else if (isa<UnresolvedUsingValueDecl>(ND)) {
1736 /* Do nothing: ignore unresolved using declarations*/
1737 } else if (ValueDecl *Value = dyn_cast<ValueDecl>(ND))
1738 T = Value->getType();
1739 else if (ObjCPropertyDecl *Property = dyn_cast<ObjCPropertyDecl>(ND))
1740 T = Property->getType();
1741
1742 if (T.isNull() || Context.hasSameType(T, Context.DependentTy))
1743 return;
1744
Douglas Gregor84139d62010-04-05 21:25:31 +00001745 PrintingPolicy Policy(Context.PrintingPolicy);
1746 Policy.AnonymousTagLocations = false;
1747
Douglas Gregorff5ce6e2009-12-18 18:53:37 +00001748 std::string TypeStr;
Douglas Gregor84139d62010-04-05 21:25:31 +00001749 T.getAsStringInternal(TypeStr, Policy);
Douglas Gregorff5ce6e2009-12-18 18:53:37 +00001750 Result->AddResultTypeChunk(TypeStr);
1751}
1752
Douglas Gregoraaa107a2010-08-23 23:51:41 +00001753static void MaybeAddSentinel(ASTContext &Context, NamedDecl *FunctionOrMethod,
1754 CodeCompletionString *Result) {
1755 if (SentinelAttr *Sentinel = FunctionOrMethod->getAttr<SentinelAttr>())
1756 if (Sentinel->getSentinel() == 0) {
1757 if (Context.getLangOptions().ObjC1 &&
1758 Context.Idents.get("nil").hasMacroDefinition())
1759 Result->AddTextChunk(", nil");
1760 else if (Context.Idents.get("NULL").hasMacroDefinition())
1761 Result->AddTextChunk(", NULL");
1762 else
1763 Result->AddTextChunk(", (void*)0");
1764 }
1765}
1766
Douglas Gregor83482d12010-08-24 16:15:59 +00001767static std::string FormatFunctionParameter(ASTContext &Context,
Douglas Gregoraba48082010-08-29 19:47:46 +00001768 ParmVarDecl *Param,
1769 bool SuppressName = false) {
Douglas Gregor83482d12010-08-24 16:15:59 +00001770 bool ObjCMethodParam = isa<ObjCMethodDecl>(Param->getDeclContext());
1771 if (Param->getType()->isDependentType() ||
1772 !Param->getType()->isBlockPointerType()) {
1773 // The argument for a dependent or non-block parameter is a placeholder
1774 // containing that parameter's type.
1775 std::string Result;
1776
Douglas Gregoraba48082010-08-29 19:47:46 +00001777 if (Param->getIdentifier() && !ObjCMethodParam && !SuppressName)
Douglas Gregor83482d12010-08-24 16:15:59 +00001778 Result = Param->getIdentifier()->getName();
1779
1780 Param->getType().getAsStringInternal(Result,
1781 Context.PrintingPolicy);
1782
1783 if (ObjCMethodParam) {
1784 Result = "(" + Result;
1785 Result += ")";
Douglas Gregoraba48082010-08-29 19:47:46 +00001786 if (Param->getIdentifier() && !SuppressName)
Douglas Gregor83482d12010-08-24 16:15:59 +00001787 Result += Param->getIdentifier()->getName();
1788 }
1789 return Result;
1790 }
1791
1792 // The argument for a block pointer parameter is a block literal with
1793 // the appropriate type.
1794 FunctionProtoTypeLoc *Block = 0;
1795 TypeLoc TL;
1796 if (TypeSourceInfo *TSInfo = Param->getTypeSourceInfo()) {
1797 TL = TSInfo->getTypeLoc().getUnqualifiedLoc();
1798 while (true) {
1799 // Look through typedefs.
1800 if (TypedefTypeLoc *TypedefTL = dyn_cast<TypedefTypeLoc>(&TL)) {
1801 if (TypeSourceInfo *InnerTSInfo
1802 = TypedefTL->getTypedefDecl()->getTypeSourceInfo()) {
1803 TL = InnerTSInfo->getTypeLoc().getUnqualifiedLoc();
1804 continue;
1805 }
1806 }
1807
1808 // Look through qualified types
1809 if (QualifiedTypeLoc *QualifiedTL = dyn_cast<QualifiedTypeLoc>(&TL)) {
1810 TL = QualifiedTL->getUnqualifiedLoc();
1811 continue;
1812 }
1813
1814 // Try to get the function prototype behind the block pointer type,
1815 // then we're done.
1816 if (BlockPointerTypeLoc *BlockPtr
1817 = dyn_cast<BlockPointerTypeLoc>(&TL)) {
1818 TL = BlockPtr->getPointeeLoc();
1819 Block = dyn_cast<FunctionProtoTypeLoc>(&TL);
1820 }
1821 break;
1822 }
1823 }
1824
1825 if (!Block) {
1826 // We were unable to find a FunctionProtoTypeLoc with parameter names
1827 // for the block; just use the parameter type as a placeholder.
1828 std::string Result;
1829 Param->getType().getUnqualifiedType().
1830 getAsStringInternal(Result, Context.PrintingPolicy);
1831
1832 if (ObjCMethodParam) {
1833 Result = "(" + Result;
1834 Result += ")";
1835 if (Param->getIdentifier())
1836 Result += Param->getIdentifier()->getName();
1837 }
1838
1839 return Result;
1840 }
1841
1842 // We have the function prototype behind the block pointer type, as it was
1843 // written in the source.
Douglas Gregor38276252010-09-08 22:47:51 +00001844 std::string Result;
1845 QualType ResultType = Block->getTypePtr()->getResultType();
1846 if (!ResultType->isVoidType())
1847 ResultType.getAsStringInternal(Result, Context.PrintingPolicy);
1848
1849 Result = '^' + Result;
1850 if (Block->getNumArgs() == 0) {
1851 if (Block->getTypePtr()->isVariadic())
1852 Result += "(...)";
1853 } else {
1854 Result += "(";
1855 for (unsigned I = 0, N = Block->getNumArgs(); I != N; ++I) {
1856 if (I)
1857 Result += ", ";
1858 Result += FormatFunctionParameter(Context, Block->getArg(I));
1859
1860 if (I == N - 1 && Block->getTypePtr()->isVariadic())
1861 Result += ", ...";
1862 }
1863 Result += ")";
Douglas Gregore17794f2010-08-31 05:13:43 +00001864 }
Douglas Gregor38276252010-09-08 22:47:51 +00001865
Douglas Gregor83482d12010-08-24 16:15:59 +00001866 return Result;
1867}
1868
Douglas Gregor86d9a522009-09-21 16:56:56 +00001869/// \brief Add function parameter chunks to the given code completion string.
1870static void AddFunctionParameterChunks(ASTContext &Context,
1871 FunctionDecl *Function,
1872 CodeCompletionString *Result) {
Douglas Gregor0c8296d2009-11-07 00:00:49 +00001873 typedef CodeCompletionString::Chunk Chunk;
1874
Douglas Gregor86d9a522009-09-21 16:56:56 +00001875 CodeCompletionString *CCStr = Result;
1876
1877 for (unsigned P = 0, N = Function->getNumParams(); P != N; ++P) {
1878 ParmVarDecl *Param = Function->getParamDecl(P);
1879
1880 if (Param->hasDefaultArg()) {
1881 // When we see an optional default argument, put that argument and
1882 // the remaining default arguments into a new, optional string.
1883 CodeCompletionString *Opt = new CodeCompletionString;
1884 CCStr->AddOptionalChunk(std::auto_ptr<CodeCompletionString>(Opt));
1885 CCStr = Opt;
1886 }
1887
1888 if (P != 0)
Douglas Gregor0c8296d2009-11-07 00:00:49 +00001889 CCStr->AddChunk(Chunk(CodeCompletionString::CK_Comma));
Douglas Gregor86d9a522009-09-21 16:56:56 +00001890
1891 // Format the placeholder string.
Douglas Gregor83482d12010-08-24 16:15:59 +00001892 std::string PlaceholderStr = FormatFunctionParameter(Context, Param);
1893
Douglas Gregore17794f2010-08-31 05:13:43 +00001894 if (Function->isVariadic() && P == N - 1)
1895 PlaceholderStr += ", ...";
1896
Douglas Gregor86d9a522009-09-21 16:56:56 +00001897 // Add the placeholder string.
Benjamin Kramer660cc182009-11-29 20:18:50 +00001898 CCStr->AddPlaceholderChunk(PlaceholderStr);
Douglas Gregor86d9a522009-09-21 16:56:56 +00001899 }
Douglas Gregorb3d45252009-09-22 21:42:17 +00001900
1901 if (const FunctionProtoType *Proto
1902 = Function->getType()->getAs<FunctionProtoType>())
Douglas Gregoraaa107a2010-08-23 23:51:41 +00001903 if (Proto->isVariadic()) {
Douglas Gregore17794f2010-08-31 05:13:43 +00001904 if (Proto->getNumArgs() == 0)
1905 CCStr->AddPlaceholderChunk("...");
Douglas Gregoraaa107a2010-08-23 23:51:41 +00001906
1907 MaybeAddSentinel(Context, Function, CCStr);
1908 }
Douglas Gregor86d9a522009-09-21 16:56:56 +00001909}
1910
1911/// \brief Add template parameter chunks to the given code completion string.
1912static void AddTemplateParameterChunks(ASTContext &Context,
1913 TemplateDecl *Template,
1914 CodeCompletionString *Result,
1915 unsigned MaxParameters = 0) {
Douglas Gregor0c8296d2009-11-07 00:00:49 +00001916 typedef CodeCompletionString::Chunk Chunk;
1917
Douglas Gregor86d9a522009-09-21 16:56:56 +00001918 CodeCompletionString *CCStr = Result;
1919 bool FirstParameter = true;
1920
1921 TemplateParameterList *Params = Template->getTemplateParameters();
1922 TemplateParameterList::iterator PEnd = Params->end();
1923 if (MaxParameters)
1924 PEnd = Params->begin() + MaxParameters;
1925 for (TemplateParameterList::iterator P = Params->begin(); P != PEnd; ++P) {
1926 bool HasDefaultArg = false;
1927 std::string PlaceholderStr;
1928 if (TemplateTypeParmDecl *TTP = dyn_cast<TemplateTypeParmDecl>(*P)) {
1929 if (TTP->wasDeclaredWithTypename())
1930 PlaceholderStr = "typename";
1931 else
1932 PlaceholderStr = "class";
1933
1934 if (TTP->getIdentifier()) {
1935 PlaceholderStr += ' ';
1936 PlaceholderStr += TTP->getIdentifier()->getName();
1937 }
1938
1939 HasDefaultArg = TTP->hasDefaultArgument();
1940 } else if (NonTypeTemplateParmDecl *NTTP
1941 = dyn_cast<NonTypeTemplateParmDecl>(*P)) {
1942 if (NTTP->getIdentifier())
1943 PlaceholderStr = NTTP->getIdentifier()->getName();
1944 NTTP->getType().getAsStringInternal(PlaceholderStr,
1945 Context.PrintingPolicy);
1946 HasDefaultArg = NTTP->hasDefaultArgument();
1947 } else {
1948 assert(isa<TemplateTemplateParmDecl>(*P));
1949 TemplateTemplateParmDecl *TTP = cast<TemplateTemplateParmDecl>(*P);
1950
1951 // Since putting the template argument list into the placeholder would
1952 // be very, very long, we just use an abbreviation.
1953 PlaceholderStr = "template<...> class";
1954 if (TTP->getIdentifier()) {
1955 PlaceholderStr += ' ';
1956 PlaceholderStr += TTP->getIdentifier()->getName();
1957 }
1958
1959 HasDefaultArg = TTP->hasDefaultArgument();
1960 }
1961
1962 if (HasDefaultArg) {
1963 // When we see an optional default argument, put that argument and
1964 // the remaining default arguments into a new, optional string.
1965 CodeCompletionString *Opt = new CodeCompletionString;
1966 CCStr->AddOptionalChunk(std::auto_ptr<CodeCompletionString>(Opt));
1967 CCStr = Opt;
1968 }
1969
1970 if (FirstParameter)
1971 FirstParameter = false;
1972 else
Douglas Gregor0c8296d2009-11-07 00:00:49 +00001973 CCStr->AddChunk(Chunk(CodeCompletionString::CK_Comma));
Douglas Gregor86d9a522009-09-21 16:56:56 +00001974
1975 // Add the placeholder string.
Benjamin Kramer660cc182009-11-29 20:18:50 +00001976 CCStr->AddPlaceholderChunk(PlaceholderStr);
Douglas Gregor86d9a522009-09-21 16:56:56 +00001977 }
1978}
1979
Douglas Gregorb9d0ef72009-09-21 19:57:38 +00001980/// \brief Add a qualifier to the given code-completion string, if the
1981/// provided nested-name-specifier is non-NULL.
Douglas Gregora61a8792009-12-11 18:44:16 +00001982static void
1983AddQualifierToCompletionString(CodeCompletionString *Result,
1984 NestedNameSpecifier *Qualifier,
1985 bool QualifierIsInformative,
1986 ASTContext &Context) {
Douglas Gregorb9d0ef72009-09-21 19:57:38 +00001987 if (!Qualifier)
1988 return;
1989
1990 std::string PrintedNNS;
1991 {
1992 llvm::raw_string_ostream OS(PrintedNNS);
1993 Qualifier->print(OS, Context.PrintingPolicy);
1994 }
Douglas Gregor0563c262009-09-22 23:15:58 +00001995 if (QualifierIsInformative)
Benjamin Kramer660cc182009-11-29 20:18:50 +00001996 Result->AddInformativeChunk(PrintedNNS);
Douglas Gregor0563c262009-09-22 23:15:58 +00001997 else
Benjamin Kramer660cc182009-11-29 20:18:50 +00001998 Result->AddTextChunk(PrintedNNS);
Douglas Gregorb9d0ef72009-09-21 19:57:38 +00001999}
2000
Douglas Gregora61a8792009-12-11 18:44:16 +00002001static void AddFunctionTypeQualsToCompletionString(CodeCompletionString *Result,
2002 FunctionDecl *Function) {
2003 const FunctionProtoType *Proto
2004 = Function->getType()->getAs<FunctionProtoType>();
2005 if (!Proto || !Proto->getTypeQuals())
2006 return;
2007
2008 std::string QualsStr;
2009 if (Proto->getTypeQuals() & Qualifiers::Const)
2010 QualsStr += " const";
2011 if (Proto->getTypeQuals() & Qualifiers::Volatile)
2012 QualsStr += " volatile";
2013 if (Proto->getTypeQuals() & Qualifiers::Restrict)
2014 QualsStr += " restrict";
2015 Result->AddInformativeChunk(QualsStr);
2016}
2017
Douglas Gregor86d9a522009-09-21 16:56:56 +00002018/// \brief If possible, create a new code completion string for the given
2019/// result.
2020///
2021/// \returns Either a new, heap-allocated code completion string describing
2022/// how to use this result, or NULL to indicate that the string or name of the
2023/// result is all that is needed.
2024CodeCompletionString *
John McCall0a2c5e22010-08-25 06:19:51 +00002025CodeCompletionResult::CreateCodeCompletionString(Sema &S,
Douglas Gregor1abc6bc2010-08-04 16:47:14 +00002026 CodeCompletionString *Result) {
Douglas Gregor0c8296d2009-11-07 00:00:49 +00002027 typedef CodeCompletionString::Chunk Chunk;
2028
Douglas Gregor2b4074f2009-12-01 05:55:20 +00002029 if (Kind == RK_Pattern)
Douglas Gregor1abc6bc2010-08-04 16:47:14 +00002030 return Pattern->Clone(Result);
Douglas Gregor2b4074f2009-12-01 05:55:20 +00002031
Douglas Gregor1abc6bc2010-08-04 16:47:14 +00002032 if (!Result)
2033 Result = new CodeCompletionString;
Douglas Gregor2b4074f2009-12-01 05:55:20 +00002034
2035 if (Kind == RK_Keyword) {
2036 Result->AddTypedTextChunk(Keyword);
2037 return Result;
2038 }
Douglas Gregor86d9a522009-09-21 16:56:56 +00002039
Douglas Gregor3f7c7f42009-10-30 16:50:04 +00002040 if (Kind == RK_Macro) {
2041 MacroInfo *MI = S.PP.getMacroInfo(Macro);
Douglas Gregor2b4074f2009-12-01 05:55:20 +00002042 assert(MI && "Not a macro?");
2043
2044 Result->AddTypedTextChunk(Macro->getName());
2045
2046 if (!MI->isFunctionLike())
2047 return Result;
Douglas Gregor3f7c7f42009-10-30 16:50:04 +00002048
2049 // Format a function-like macro with placeholders for the arguments.
Douglas Gregor0c8296d2009-11-07 00:00:49 +00002050 Result->AddChunk(Chunk(CodeCompletionString::CK_LeftParen));
Douglas Gregor3f7c7f42009-10-30 16:50:04 +00002051 for (MacroInfo::arg_iterator A = MI->arg_begin(), AEnd = MI->arg_end();
2052 A != AEnd; ++A) {
2053 if (A != MI->arg_begin())
Douglas Gregor0c8296d2009-11-07 00:00:49 +00002054 Result->AddChunk(Chunk(CodeCompletionString::CK_Comma));
Douglas Gregor3f7c7f42009-10-30 16:50:04 +00002055
2056 if (!MI->isVariadic() || A != AEnd - 1) {
2057 // Non-variadic argument.
Benjamin Kramer660cc182009-11-29 20:18:50 +00002058 Result->AddPlaceholderChunk((*A)->getName());
Douglas Gregor3f7c7f42009-10-30 16:50:04 +00002059 continue;
2060 }
2061
2062 // Variadic argument; cope with the different between GNU and C99
2063 // variadic macros, providing a single placeholder for the rest of the
2064 // arguments.
2065 if ((*A)->isStr("__VA_ARGS__"))
2066 Result->AddPlaceholderChunk("...");
2067 else {
2068 std::string Arg = (*A)->getName();
2069 Arg += "...";
Benjamin Kramer660cc182009-11-29 20:18:50 +00002070 Result->AddPlaceholderChunk(Arg);
Douglas Gregor3f7c7f42009-10-30 16:50:04 +00002071 }
2072 }
Douglas Gregor0c8296d2009-11-07 00:00:49 +00002073 Result->AddChunk(Chunk(CodeCompletionString::CK_RightParen));
Douglas Gregor3f7c7f42009-10-30 16:50:04 +00002074 return Result;
2075 }
2076
Douglas Gregord8e8a582010-05-25 21:41:55 +00002077 assert(Kind == RK_Declaration && "Missed a result kind?");
Douglas Gregor86d9a522009-09-21 16:56:56 +00002078 NamedDecl *ND = Declaration;
2079
Douglas Gregor0c8296d2009-11-07 00:00:49 +00002080 if (StartsNestedNameSpecifier) {
Benjamin Kramer660cc182009-11-29 20:18:50 +00002081 Result->AddTypedTextChunk(ND->getNameAsString());
Douglas Gregor0c8296d2009-11-07 00:00:49 +00002082 Result->AddTextChunk("::");
2083 return Result;
2084 }
2085
Douglas Gregorff5ce6e2009-12-18 18:53:37 +00002086 AddResultTypeChunk(S.Context, ND, Result);
2087
Douglas Gregor86d9a522009-09-21 16:56:56 +00002088 if (FunctionDecl *Function = dyn_cast<FunctionDecl>(ND)) {
Douglas Gregor0563c262009-09-22 23:15:58 +00002089 AddQualifierToCompletionString(Result, Qualifier, QualifierIsInformative,
2090 S.Context);
Benjamin Kramer660cc182009-11-29 20:18:50 +00002091 Result->AddTypedTextChunk(Function->getNameAsString());
Douglas Gregor0c8296d2009-11-07 00:00:49 +00002092 Result->AddChunk(Chunk(CodeCompletionString::CK_LeftParen));
Douglas Gregor86d9a522009-09-21 16:56:56 +00002093 AddFunctionParameterChunks(S.Context, Function, Result);
Douglas Gregor0c8296d2009-11-07 00:00:49 +00002094 Result->AddChunk(Chunk(CodeCompletionString::CK_RightParen));
Douglas Gregora61a8792009-12-11 18:44:16 +00002095 AddFunctionTypeQualsToCompletionString(Result, Function);
Douglas Gregor86d9a522009-09-21 16:56:56 +00002096 return Result;
2097 }
2098
2099 if (FunctionTemplateDecl *FunTmpl = dyn_cast<FunctionTemplateDecl>(ND)) {
Douglas Gregor0563c262009-09-22 23:15:58 +00002100 AddQualifierToCompletionString(Result, Qualifier, QualifierIsInformative,
2101 S.Context);
Douglas Gregor86d9a522009-09-21 16:56:56 +00002102 FunctionDecl *Function = FunTmpl->getTemplatedDecl();
Benjamin Kramer660cc182009-11-29 20:18:50 +00002103 Result->AddTypedTextChunk(Function->getNameAsString());
Douglas Gregor86d9a522009-09-21 16:56:56 +00002104
2105 // Figure out which template parameters are deduced (or have default
2106 // arguments).
2107 llvm::SmallVector<bool, 16> Deduced;
2108 S.MarkDeducedTemplateParameters(FunTmpl, Deduced);
2109 unsigned LastDeducibleArgument;
2110 for (LastDeducibleArgument = Deduced.size(); LastDeducibleArgument > 0;
2111 --LastDeducibleArgument) {
2112 if (!Deduced[LastDeducibleArgument - 1]) {
2113 // C++0x: Figure out if the template argument has a default. If so,
2114 // the user doesn't need to type this argument.
2115 // FIXME: We need to abstract template parameters better!
2116 bool HasDefaultArg = false;
2117 NamedDecl *Param = FunTmpl->getTemplateParameters()->getParam(
2118 LastDeducibleArgument - 1);
2119 if (TemplateTypeParmDecl *TTP = dyn_cast<TemplateTypeParmDecl>(Param))
2120 HasDefaultArg = TTP->hasDefaultArgument();
2121 else if (NonTypeTemplateParmDecl *NTTP
2122 = dyn_cast<NonTypeTemplateParmDecl>(Param))
2123 HasDefaultArg = NTTP->hasDefaultArgument();
2124 else {
2125 assert(isa<TemplateTemplateParmDecl>(Param));
2126 HasDefaultArg
Douglas Gregor0c8296d2009-11-07 00:00:49 +00002127 = cast<TemplateTemplateParmDecl>(Param)->hasDefaultArgument();
Douglas Gregor86d9a522009-09-21 16:56:56 +00002128 }
2129
2130 if (!HasDefaultArg)
2131 break;
2132 }
2133 }
2134
2135 if (LastDeducibleArgument) {
2136 // Some of the function template arguments cannot be deduced from a
2137 // function call, so we introduce an explicit template argument list
2138 // containing all of the arguments up to the first deducible argument.
Douglas Gregor0c8296d2009-11-07 00:00:49 +00002139 Result->AddChunk(Chunk(CodeCompletionString::CK_LeftAngle));
Douglas Gregor86d9a522009-09-21 16:56:56 +00002140 AddTemplateParameterChunks(S.Context, FunTmpl, Result,
2141 LastDeducibleArgument);
Douglas Gregor0c8296d2009-11-07 00:00:49 +00002142 Result->AddChunk(Chunk(CodeCompletionString::CK_RightAngle));
Douglas Gregor86d9a522009-09-21 16:56:56 +00002143 }
2144
2145 // Add the function parameters
Douglas Gregor0c8296d2009-11-07 00:00:49 +00002146 Result->AddChunk(Chunk(CodeCompletionString::CK_LeftParen));
Douglas Gregor86d9a522009-09-21 16:56:56 +00002147 AddFunctionParameterChunks(S.Context, Function, Result);
Douglas Gregor0c8296d2009-11-07 00:00:49 +00002148 Result->AddChunk(Chunk(CodeCompletionString::CK_RightParen));
Douglas Gregora61a8792009-12-11 18:44:16 +00002149 AddFunctionTypeQualsToCompletionString(Result, Function);
Douglas Gregor86d9a522009-09-21 16:56:56 +00002150 return Result;
2151 }
2152
2153 if (TemplateDecl *Template = dyn_cast<TemplateDecl>(ND)) {
Douglas Gregor0563c262009-09-22 23:15:58 +00002154 AddQualifierToCompletionString(Result, Qualifier, QualifierIsInformative,
2155 S.Context);
Benjamin Kramer660cc182009-11-29 20:18:50 +00002156 Result->AddTypedTextChunk(Template->getNameAsString());
Douglas Gregor0c8296d2009-11-07 00:00:49 +00002157 Result->AddChunk(Chunk(CodeCompletionString::CK_LeftAngle));
Douglas Gregor86d9a522009-09-21 16:56:56 +00002158 AddTemplateParameterChunks(S.Context, Template, Result);
Douglas Gregor0c8296d2009-11-07 00:00:49 +00002159 Result->AddChunk(Chunk(CodeCompletionString::CK_RightAngle));
Douglas Gregor86d9a522009-09-21 16:56:56 +00002160 return Result;
2161 }
2162
Douglas Gregor9630eb62009-11-17 16:44:22 +00002163 if (ObjCMethodDecl *Method = dyn_cast<ObjCMethodDecl>(ND)) {
Douglas Gregor9630eb62009-11-17 16:44:22 +00002164 Selector Sel = Method->getSelector();
2165 if (Sel.isUnarySelector()) {
2166 Result->AddTypedTextChunk(Sel.getIdentifierInfoForSlot(0)->getName());
2167 return Result;
2168 }
2169
Douglas Gregord3c68542009-11-19 01:08:35 +00002170 std::string SelName = Sel.getIdentifierInfoForSlot(0)->getName().str();
2171 SelName += ':';
2172 if (StartParameter == 0)
2173 Result->AddTypedTextChunk(SelName);
2174 else {
2175 Result->AddInformativeChunk(SelName);
2176
2177 // If there is only one parameter, and we're past it, add an empty
2178 // typed-text chunk since there is nothing to type.
2179 if (Method->param_size() == 1)
2180 Result->AddTypedTextChunk("");
2181 }
Douglas Gregor9630eb62009-11-17 16:44:22 +00002182 unsigned Idx = 0;
2183 for (ObjCMethodDecl::param_iterator P = Method->param_begin(),
2184 PEnd = Method->param_end();
2185 P != PEnd; (void)++P, ++Idx) {
2186 if (Idx > 0) {
Douglas Gregord3c68542009-11-19 01:08:35 +00002187 std::string Keyword;
2188 if (Idx > StartParameter)
Douglas Gregor834389b2010-01-12 06:38:28 +00002189 Result->AddChunk(CodeCompletionString::CK_HorizontalSpace);
Douglas Gregor9630eb62009-11-17 16:44:22 +00002190 if (IdentifierInfo *II = Sel.getIdentifierInfoForSlot(Idx))
2191 Keyword += II->getName().str();
2192 Keyword += ":";
Douglas Gregor1f5537a2010-07-08 23:20:03 +00002193 if (Idx < StartParameter || AllParametersAreInformative)
Douglas Gregord3c68542009-11-19 01:08:35 +00002194 Result->AddInformativeChunk(Keyword);
Douglas Gregor1f5537a2010-07-08 23:20:03 +00002195 else if (Idx == StartParameter)
Douglas Gregord3c68542009-11-19 01:08:35 +00002196 Result->AddTypedTextChunk(Keyword);
2197 else
2198 Result->AddTextChunk(Keyword);
Douglas Gregor9630eb62009-11-17 16:44:22 +00002199 }
Douglas Gregord3c68542009-11-19 01:08:35 +00002200
2201 // If we're before the starting parameter, skip the placeholder.
2202 if (Idx < StartParameter)
2203 continue;
Douglas Gregor9630eb62009-11-17 16:44:22 +00002204
2205 std::string Arg;
Douglas Gregor83482d12010-08-24 16:15:59 +00002206
2207 if ((*P)->getType()->isBlockPointerType() && !DeclaringEntity)
Douglas Gregoraba48082010-08-29 19:47:46 +00002208 Arg = FormatFunctionParameter(S.Context, *P, true);
Douglas Gregor83482d12010-08-24 16:15:59 +00002209 else {
2210 (*P)->getType().getAsStringInternal(Arg, S.Context.PrintingPolicy);
2211 Arg = "(" + Arg + ")";
2212 if (IdentifierInfo *II = (*P)->getIdentifier())
Douglas Gregoraba48082010-08-29 19:47:46 +00002213 if (DeclaringEntity || AllParametersAreInformative)
2214 Arg += II->getName().str();
Douglas Gregor83482d12010-08-24 16:15:59 +00002215 }
2216
Douglas Gregore17794f2010-08-31 05:13:43 +00002217 if (Method->isVariadic() && (P + 1) == PEnd)
2218 Arg += ", ...";
2219
Douglas Gregor1f5537a2010-07-08 23:20:03 +00002220 if (DeclaringEntity)
2221 Result->AddTextChunk(Arg);
2222 else if (AllParametersAreInformative)
Douglas Gregor4ad96852009-11-19 07:41:15 +00002223 Result->AddInformativeChunk(Arg);
2224 else
2225 Result->AddPlaceholderChunk(Arg);
Douglas Gregor9630eb62009-11-17 16:44:22 +00002226 }
2227
Douglas Gregor2a17af02009-12-23 00:21:46 +00002228 if (Method->isVariadic()) {
Douglas Gregore17794f2010-08-31 05:13:43 +00002229 if (Method->param_size() == 0) {
2230 if (DeclaringEntity)
2231 Result->AddTextChunk(", ...");
2232 else if (AllParametersAreInformative)
2233 Result->AddInformativeChunk(", ...");
2234 else
2235 Result->AddPlaceholderChunk(", ...");
2236 }
Douglas Gregoraaa107a2010-08-23 23:51:41 +00002237
2238 MaybeAddSentinel(S.Context, Method, Result);
Douglas Gregor2a17af02009-12-23 00:21:46 +00002239 }
2240
Douglas Gregor9630eb62009-11-17 16:44:22 +00002241 return Result;
2242 }
2243
Douglas Gregor2b4074f2009-12-01 05:55:20 +00002244 if (Qualifier)
Douglas Gregor0563c262009-09-22 23:15:58 +00002245 AddQualifierToCompletionString(Result, Qualifier, QualifierIsInformative,
2246 S.Context);
Douglas Gregor2b4074f2009-12-01 05:55:20 +00002247
2248 Result->AddTypedTextChunk(ND->getNameAsString());
2249 return Result;
Douglas Gregor86d9a522009-09-21 16:56:56 +00002250}
2251
Douglas Gregor86d802e2009-09-23 00:34:09 +00002252CodeCompletionString *
2253CodeCompleteConsumer::OverloadCandidate::CreateSignatureString(
2254 unsigned CurrentArg,
2255 Sema &S) const {
Douglas Gregor0c8296d2009-11-07 00:00:49 +00002256 typedef CodeCompletionString::Chunk Chunk;
2257
Douglas Gregor86d802e2009-09-23 00:34:09 +00002258 CodeCompletionString *Result = new CodeCompletionString;
2259 FunctionDecl *FDecl = getFunction();
Douglas Gregorff5ce6e2009-12-18 18:53:37 +00002260 AddResultTypeChunk(S.Context, FDecl, Result);
Douglas Gregor86d802e2009-09-23 00:34:09 +00002261 const FunctionProtoType *Proto
2262 = dyn_cast<FunctionProtoType>(getFunctionType());
2263 if (!FDecl && !Proto) {
2264 // Function without a prototype. Just give the return type and a
2265 // highlighted ellipsis.
2266 const FunctionType *FT = getFunctionType();
2267 Result->AddTextChunk(
Benjamin Kramer660cc182009-11-29 20:18:50 +00002268 FT->getResultType().getAsString(S.Context.PrintingPolicy));
Douglas Gregor0c8296d2009-11-07 00:00:49 +00002269 Result->AddChunk(Chunk(CodeCompletionString::CK_LeftParen));
2270 Result->AddChunk(Chunk(CodeCompletionString::CK_CurrentParameter, "..."));
2271 Result->AddChunk(Chunk(CodeCompletionString::CK_RightParen));
Douglas Gregor86d802e2009-09-23 00:34:09 +00002272 return Result;
2273 }
2274
2275 if (FDecl)
Benjamin Kramer660cc182009-11-29 20:18:50 +00002276 Result->AddTextChunk(FDecl->getNameAsString());
Douglas Gregor86d802e2009-09-23 00:34:09 +00002277 else
2278 Result->AddTextChunk(
Benjamin Kramer660cc182009-11-29 20:18:50 +00002279 Proto->getResultType().getAsString(S.Context.PrintingPolicy));
Douglas Gregor86d802e2009-09-23 00:34:09 +00002280
Douglas Gregor0c8296d2009-11-07 00:00:49 +00002281 Result->AddChunk(Chunk(CodeCompletionString::CK_LeftParen));
Douglas Gregor86d802e2009-09-23 00:34:09 +00002282 unsigned NumParams = FDecl? FDecl->getNumParams() : Proto->getNumArgs();
2283 for (unsigned I = 0; I != NumParams; ++I) {
2284 if (I)
Douglas Gregor0c8296d2009-11-07 00:00:49 +00002285 Result->AddChunk(Chunk(CodeCompletionString::CK_Comma));
Douglas Gregor86d802e2009-09-23 00:34:09 +00002286
2287 std::string ArgString;
2288 QualType ArgType;
2289
2290 if (FDecl) {
2291 ArgString = FDecl->getParamDecl(I)->getNameAsString();
2292 ArgType = FDecl->getParamDecl(I)->getOriginalType();
2293 } else {
2294 ArgType = Proto->getArgType(I);
2295 }
2296
2297 ArgType.getAsStringInternal(ArgString, S.Context.PrintingPolicy);
2298
2299 if (I == CurrentArg)
Douglas Gregor0c8296d2009-11-07 00:00:49 +00002300 Result->AddChunk(Chunk(CodeCompletionString::CK_CurrentParameter,
Benjamin Kramer660cc182009-11-29 20:18:50 +00002301 ArgString));
Douglas Gregor86d802e2009-09-23 00:34:09 +00002302 else
Benjamin Kramer660cc182009-11-29 20:18:50 +00002303 Result->AddTextChunk(ArgString);
Douglas Gregor86d802e2009-09-23 00:34:09 +00002304 }
2305
2306 if (Proto && Proto->isVariadic()) {
Douglas Gregor0c8296d2009-11-07 00:00:49 +00002307 Result->AddChunk(Chunk(CodeCompletionString::CK_Comma));
Douglas Gregor86d802e2009-09-23 00:34:09 +00002308 if (CurrentArg < NumParams)
2309 Result->AddTextChunk("...");
2310 else
Douglas Gregor0c8296d2009-11-07 00:00:49 +00002311 Result->AddChunk(Chunk(CodeCompletionString::CK_CurrentParameter, "..."));
Douglas Gregor86d802e2009-09-23 00:34:09 +00002312 }
Douglas Gregor0c8296d2009-11-07 00:00:49 +00002313 Result->AddChunk(Chunk(CodeCompletionString::CK_RightParen));
Douglas Gregor86d802e2009-09-23 00:34:09 +00002314
2315 return Result;
2316}
2317
Douglas Gregor1827e102010-08-16 16:18:59 +00002318unsigned clang::getMacroUsagePriority(llvm::StringRef MacroName,
Douglas Gregorb05496d2010-09-20 21:11:48 +00002319 const LangOptions &LangOpts,
Douglas Gregor1827e102010-08-16 16:18:59 +00002320 bool PreferredTypeIsPointer) {
2321 unsigned Priority = CCP_Macro;
2322
Douglas Gregorb05496d2010-09-20 21:11:48 +00002323 // Treat the "nil", "Nil" and "NULL" macros as null pointer constants.
2324 if (MacroName.equals("nil") || MacroName.equals("NULL") ||
2325 MacroName.equals("Nil")) {
Douglas Gregor1827e102010-08-16 16:18:59 +00002326 Priority = CCP_Constant;
2327 if (PreferredTypeIsPointer)
2328 Priority = Priority / CCF_SimilarTypeMatch;
Douglas Gregorb05496d2010-09-20 21:11:48 +00002329 }
2330 // Treat "YES", "NO", "true", and "false" as constants.
2331 else if (MacroName.equals("YES") || MacroName.equals("NO") ||
2332 MacroName.equals("true") || MacroName.equals("false"))
2333 Priority = CCP_Constant;
2334 // Treat "bool" as a type.
2335 else if (MacroName.equals("bool"))
2336 Priority = CCP_Type + (LangOpts.ObjC1? CCD_bool_in_ObjC : 0);
2337
Douglas Gregor1827e102010-08-16 16:18:59 +00002338
2339 return Priority;
2340}
2341
Douglas Gregore8d7beb2010-09-03 23:30:36 +00002342CXCursorKind clang::getCursorKindForDecl(Decl *D) {
2343 if (!D)
2344 return CXCursor_UnexposedDecl;
2345
2346 switch (D->getKind()) {
2347 case Decl::Enum: return CXCursor_EnumDecl;
2348 case Decl::EnumConstant: return CXCursor_EnumConstantDecl;
2349 case Decl::Field: return CXCursor_FieldDecl;
2350 case Decl::Function:
2351 return CXCursor_FunctionDecl;
2352 case Decl::ObjCCategory: return CXCursor_ObjCCategoryDecl;
2353 case Decl::ObjCCategoryImpl: return CXCursor_ObjCCategoryImplDecl;
2354 case Decl::ObjCClass:
2355 // FIXME
2356 return CXCursor_UnexposedDecl;
2357 case Decl::ObjCForwardProtocol:
2358 // FIXME
2359 return CXCursor_UnexposedDecl;
2360 case Decl::ObjCImplementation: return CXCursor_ObjCImplementationDecl;
2361 case Decl::ObjCInterface: return CXCursor_ObjCInterfaceDecl;
2362 case Decl::ObjCIvar: return CXCursor_ObjCIvarDecl;
2363 case Decl::ObjCMethod:
2364 return cast<ObjCMethodDecl>(D)->isInstanceMethod()
2365 ? CXCursor_ObjCInstanceMethodDecl : CXCursor_ObjCClassMethodDecl;
2366 case Decl::CXXMethod: return CXCursor_CXXMethod;
2367 case Decl::CXXConstructor: return CXCursor_Constructor;
2368 case Decl::CXXDestructor: return CXCursor_Destructor;
2369 case Decl::CXXConversion: return CXCursor_ConversionFunction;
2370 case Decl::ObjCProperty: return CXCursor_ObjCPropertyDecl;
2371 case Decl::ObjCProtocol: return CXCursor_ObjCProtocolDecl;
2372 case Decl::ParmVar: return CXCursor_ParmDecl;
2373 case Decl::Typedef: return CXCursor_TypedefDecl;
2374 case Decl::Var: return CXCursor_VarDecl;
2375 case Decl::Namespace: return CXCursor_Namespace;
2376 case Decl::NamespaceAlias: return CXCursor_NamespaceAlias;
2377 case Decl::TemplateTypeParm: return CXCursor_TemplateTypeParameter;
2378 case Decl::NonTypeTemplateParm:return CXCursor_NonTypeTemplateParameter;
2379 case Decl::TemplateTemplateParm:return CXCursor_TemplateTemplateParameter;
2380 case Decl::FunctionTemplate: return CXCursor_FunctionTemplate;
2381 case Decl::ClassTemplate: return CXCursor_ClassTemplate;
2382 case Decl::ClassTemplatePartialSpecialization:
2383 return CXCursor_ClassTemplatePartialSpecialization;
2384 case Decl::UsingDirective: return CXCursor_UsingDirective;
2385
2386 case Decl::Using:
2387 case Decl::UnresolvedUsingValue:
2388 case Decl::UnresolvedUsingTypename:
2389 return CXCursor_UsingDeclaration;
2390
2391 default:
2392 if (TagDecl *TD = dyn_cast<TagDecl>(D)) {
2393 switch (TD->getTagKind()) {
2394 case TTK_Struct: return CXCursor_StructDecl;
2395 case TTK_Class: return CXCursor_ClassDecl;
2396 case TTK_Union: return CXCursor_UnionDecl;
2397 case TTK_Enum: return CXCursor_EnumDecl;
2398 }
2399 }
2400 }
2401
2402 return CXCursor_UnexposedDecl;
2403}
2404
Douglas Gregor590c7d52010-07-08 20:55:51 +00002405static void AddMacroResults(Preprocessor &PP, ResultBuilder &Results,
2406 bool TargetTypeIsPointer = false) {
John McCall0a2c5e22010-08-25 06:19:51 +00002407 typedef CodeCompletionResult Result;
Douglas Gregor590c7d52010-07-08 20:55:51 +00002408
Douglas Gregor3f7c7f42009-10-30 16:50:04 +00002409 Results.EnterNewScope();
Douglas Gregor0c8296d2009-11-07 00:00:49 +00002410 for (Preprocessor::macro_iterator M = PP.macro_begin(),
2411 MEnd = PP.macro_end();
Douglas Gregor590c7d52010-07-08 20:55:51 +00002412 M != MEnd; ++M) {
Douglas Gregor1827e102010-08-16 16:18:59 +00002413 Results.AddResult(Result(M->first,
2414 getMacroUsagePriority(M->first->getName(),
Douglas Gregorb05496d2010-09-20 21:11:48 +00002415 PP.getLangOptions(),
Douglas Gregor1827e102010-08-16 16:18:59 +00002416 TargetTypeIsPointer)));
Douglas Gregor590c7d52010-07-08 20:55:51 +00002417 }
Douglas Gregor3f7c7f42009-10-30 16:50:04 +00002418 Results.ExitScope();
2419}
2420
Douglas Gregoraa5f77b2010-08-23 21:54:33 +00002421static void AddPrettyFunctionResults(const LangOptions &LangOpts,
2422 ResultBuilder &Results) {
John McCall0a2c5e22010-08-25 06:19:51 +00002423 typedef CodeCompletionResult Result;
Douglas Gregoraa5f77b2010-08-23 21:54:33 +00002424
2425 Results.EnterNewScope();
2426 Results.AddResult(Result("__PRETTY_FUNCTION__", CCP_Constant));
2427 Results.AddResult(Result("__FUNCTION__", CCP_Constant));
2428 if (LangOpts.C99 || LangOpts.CPlusPlus0x)
2429 Results.AddResult(Result("__func__", CCP_Constant));
2430 Results.ExitScope();
2431}
2432
Daniel Dunbar3a2838d2009-11-13 08:58:20 +00002433static void HandleCodeCompleteResults(Sema *S,
2434 CodeCompleteConsumer *CodeCompleter,
Douglas Gregore6b1bb62010-08-11 21:23:17 +00002435 CodeCompletionContext Context,
John McCall0a2c5e22010-08-25 06:19:51 +00002436 CodeCompletionResult *Results,
Douglas Gregore6b1bb62010-08-11 21:23:17 +00002437 unsigned NumResults) {
Douglas Gregor86d9a522009-09-21 16:56:56 +00002438 if (CodeCompleter)
Douglas Gregore6b1bb62010-08-11 21:23:17 +00002439 CodeCompleter->ProcessCodeCompleteResults(*S, Context, Results, NumResults);
Douglas Gregor54f01612009-11-19 00:01:57 +00002440
2441 for (unsigned I = 0; I != NumResults; ++I)
2442 Results[I].Destroy();
Douglas Gregor86d9a522009-09-21 16:56:56 +00002443}
2444
Douglas Gregore6b1bb62010-08-11 21:23:17 +00002445static enum CodeCompletionContext::Kind mapCodeCompletionContext(Sema &S,
2446 Sema::ParserCompletionContext PCC) {
2447 switch (PCC) {
John McCallf312b1e2010-08-26 23:41:50 +00002448 case Sema::PCC_Namespace:
Douglas Gregore6b1bb62010-08-11 21:23:17 +00002449 return CodeCompletionContext::CCC_TopLevel;
2450
John McCallf312b1e2010-08-26 23:41:50 +00002451 case Sema::PCC_Class:
Douglas Gregore6b1bb62010-08-11 21:23:17 +00002452 return CodeCompletionContext::CCC_ClassStructUnion;
2453
John McCallf312b1e2010-08-26 23:41:50 +00002454 case Sema::PCC_ObjCInterface:
Douglas Gregore6b1bb62010-08-11 21:23:17 +00002455 return CodeCompletionContext::CCC_ObjCInterface;
2456
John McCallf312b1e2010-08-26 23:41:50 +00002457 case Sema::PCC_ObjCImplementation:
Douglas Gregore6b1bb62010-08-11 21:23:17 +00002458 return CodeCompletionContext::CCC_ObjCImplementation;
2459
John McCallf312b1e2010-08-26 23:41:50 +00002460 case Sema::PCC_ObjCInstanceVariableList:
Douglas Gregore6b1bb62010-08-11 21:23:17 +00002461 return CodeCompletionContext::CCC_ObjCIvarList;
2462
John McCallf312b1e2010-08-26 23:41:50 +00002463 case Sema::PCC_Template:
2464 case Sema::PCC_MemberTemplate:
2465 case Sema::PCC_RecoveryInFunction:
Douglas Gregore6b1bb62010-08-11 21:23:17 +00002466 return CodeCompletionContext::CCC_Other;
2467
John McCallf312b1e2010-08-26 23:41:50 +00002468 case Sema::PCC_Expression:
2469 case Sema::PCC_ForInit:
2470 case Sema::PCC_Condition:
Douglas Gregore6b1bb62010-08-11 21:23:17 +00002471 return CodeCompletionContext::CCC_Expression;
2472
John McCallf312b1e2010-08-26 23:41:50 +00002473 case Sema::PCC_Statement:
Douglas Gregore6b1bb62010-08-11 21:23:17 +00002474 return CodeCompletionContext::CCC_Statement;
Douglas Gregor72db1082010-08-24 01:11:00 +00002475
John McCallf312b1e2010-08-26 23:41:50 +00002476 case Sema::PCC_Type:
Douglas Gregor72db1082010-08-24 01:11:00 +00002477 return CodeCompletionContext::CCC_Type;
Douglas Gregor02688102010-09-14 23:59:36 +00002478
2479 case Sema::PCC_ParenthesizedExpression:
2480 return CodeCompletionContext::CCC_ParenthesizedExpression;
Douglas Gregore6b1bb62010-08-11 21:23:17 +00002481 }
2482
2483 return CodeCompletionContext::CCC_Other;
2484}
2485
Douglas Gregorf6961522010-08-27 21:18:54 +00002486/// \brief If we're in a C++ virtual member function, add completion results
2487/// that invoke the functions we override, since it's common to invoke the
2488/// overridden function as well as adding new functionality.
2489///
2490/// \param S The semantic analysis object for which we are generating results.
2491///
2492/// \param InContext This context in which the nested-name-specifier preceding
2493/// the code-completion point
2494static void MaybeAddOverrideCalls(Sema &S, DeclContext *InContext,
2495 ResultBuilder &Results) {
2496 // Look through blocks.
2497 DeclContext *CurContext = S.CurContext;
2498 while (isa<BlockDecl>(CurContext))
2499 CurContext = CurContext->getParent();
2500
2501
2502 CXXMethodDecl *Method = dyn_cast<CXXMethodDecl>(CurContext);
2503 if (!Method || !Method->isVirtual())
2504 return;
2505
2506 // We need to have names for all of the parameters, if we're going to
2507 // generate a forwarding call.
2508 for (CXXMethodDecl::param_iterator P = Method->param_begin(),
2509 PEnd = Method->param_end();
2510 P != PEnd;
2511 ++P) {
2512 if (!(*P)->getDeclName())
2513 return;
2514 }
2515
2516 for (CXXMethodDecl::method_iterator M = Method->begin_overridden_methods(),
2517 MEnd = Method->end_overridden_methods();
2518 M != MEnd; ++M) {
2519 CodeCompletionString *Pattern = new CodeCompletionString;
2520 CXXMethodDecl *Overridden = const_cast<CXXMethodDecl *>(*M);
2521 if (Overridden->getCanonicalDecl() == Method->getCanonicalDecl())
2522 continue;
2523
2524 // If we need a nested-name-specifier, add one now.
2525 if (!InContext) {
2526 NestedNameSpecifier *NNS
2527 = getRequiredQualification(S.Context, CurContext,
2528 Overridden->getDeclContext());
2529 if (NNS) {
2530 std::string Str;
2531 llvm::raw_string_ostream OS(Str);
2532 NNS->print(OS, S.Context.PrintingPolicy);
2533 Pattern->AddTextChunk(OS.str());
2534 }
2535 } else if (!InContext->Equals(Overridden->getDeclContext()))
2536 continue;
2537
2538 Pattern->AddTypedTextChunk(Overridden->getNameAsString());
2539 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
2540 bool FirstParam = true;
2541 for (CXXMethodDecl::param_iterator P = Method->param_begin(),
2542 PEnd = Method->param_end();
2543 P != PEnd; ++P) {
2544 if (FirstParam)
2545 FirstParam = false;
2546 else
2547 Pattern->AddChunk(CodeCompletionString::CK_Comma);
2548
2549 Pattern->AddPlaceholderChunk((*P)->getIdentifier()->getName());
2550 }
2551 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
2552 Results.AddResult(CodeCompletionResult(Pattern,
2553 CCP_SuperCompletion,
2554 CXCursor_CXXMethod));
2555 Results.Ignore(Overridden);
2556 }
2557}
2558
Douglas Gregor01dfea02010-01-10 23:08:15 +00002559void Sema::CodeCompleteOrdinaryName(Scope *S,
Douglas Gregore6b1bb62010-08-11 21:23:17 +00002560 ParserCompletionContext CompletionContext) {
John McCall0a2c5e22010-08-25 06:19:51 +00002561 typedef CodeCompletionResult Result;
Douglas Gregor2ccccb32010-08-23 18:23:48 +00002562 ResultBuilder Results(*this);
Douglas Gregorcee9ff12010-09-20 22:39:41 +00002563 Results.setCompletionContext(mapCodeCompletionContext(*this,
2564 CompletionContext));
Douglas Gregorf6961522010-08-27 21:18:54 +00002565 Results.EnterNewScope();
Douglas Gregorcee9ff12010-09-20 22:39:41 +00002566
Douglas Gregor01dfea02010-01-10 23:08:15 +00002567 // Determine how to filter results, e.g., so that the names of
2568 // values (functions, enumerators, function templates, etc.) are
2569 // only allowed where we can have an expression.
2570 switch (CompletionContext) {
Douglas Gregore6b1bb62010-08-11 21:23:17 +00002571 case PCC_Namespace:
2572 case PCC_Class:
2573 case PCC_ObjCInterface:
2574 case PCC_ObjCImplementation:
2575 case PCC_ObjCInstanceVariableList:
2576 case PCC_Template:
2577 case PCC_MemberTemplate:
Douglas Gregor72db1082010-08-24 01:11:00 +00002578 case PCC_Type:
Douglas Gregor01dfea02010-01-10 23:08:15 +00002579 Results.setFilter(&ResultBuilder::IsOrdinaryNonValueName);
2580 break;
2581
Douglas Gregore6b1bb62010-08-11 21:23:17 +00002582 case PCC_Statement:
Douglas Gregor02688102010-09-14 23:59:36 +00002583 case PCC_ParenthesizedExpression:
Douglas Gregoreb0d0142010-08-24 23:58:17 +00002584 case PCC_Expression:
Douglas Gregore6b1bb62010-08-11 21:23:17 +00002585 case PCC_ForInit:
2586 case PCC_Condition:
Douglas Gregor4710e5b2010-05-28 00:49:12 +00002587 if (WantTypesInContext(CompletionContext, getLangOptions()))
2588 Results.setFilter(&ResultBuilder::IsOrdinaryName);
2589 else
2590 Results.setFilter(&ResultBuilder::IsOrdinaryNonTypeName);
Douglas Gregorf6961522010-08-27 21:18:54 +00002591
2592 if (getLangOptions().CPlusPlus)
2593 MaybeAddOverrideCalls(*this, /*InContext=*/0, Results);
Douglas Gregor01dfea02010-01-10 23:08:15 +00002594 break;
Douglas Gregordc845342010-05-25 05:58:43 +00002595
Douglas Gregore6b1bb62010-08-11 21:23:17 +00002596 case PCC_RecoveryInFunction:
Douglas Gregordc845342010-05-25 05:58:43 +00002597 // Unfiltered
2598 break;
Douglas Gregor01dfea02010-01-10 23:08:15 +00002599 }
2600
Douglas Gregor3cdee122010-08-26 16:36:48 +00002601 // If we are in a C++ non-static member function, check the qualifiers on
2602 // the member function to filter/prioritize the results list.
2603 if (CXXMethodDecl *CurMethod = dyn_cast<CXXMethodDecl>(CurContext))
2604 if (CurMethod->isInstance())
2605 Results.setObjectTypeQualifiers(
2606 Qualifiers::fromCVRMask(CurMethod->getTypeQualifiers()));
2607
Douglas Gregor1ca6ae82010-01-14 01:09:38 +00002608 CodeCompletionDeclConsumer Consumer(Results, CurContext);
Douglas Gregor8071e422010-08-15 06:18:01 +00002609 LookupVisibleDecls(S, LookupOrdinaryName, Consumer,
2610 CodeCompleter->includeGlobals());
Douglas Gregor2a7925c2009-12-07 09:54:55 +00002611
Douglas Gregorbca403c2010-01-13 23:51:12 +00002612 AddOrdinaryNameResults(CompletionContext, S, *this, Results);
Douglas Gregor2a7925c2009-12-07 09:54:55 +00002613 Results.ExitScope();
2614
Douglas Gregoraa5f77b2010-08-23 21:54:33 +00002615 switch (CompletionContext) {
Douglas Gregor02688102010-09-14 23:59:36 +00002616 case PCC_ParenthesizedExpression:
Douglas Gregor72db1082010-08-24 01:11:00 +00002617 case PCC_Expression:
2618 case PCC_Statement:
2619 case PCC_RecoveryInFunction:
2620 if (S->getFnParent())
2621 AddPrettyFunctionResults(PP.getLangOptions(), Results);
2622 break;
2623
2624 case PCC_Namespace:
2625 case PCC_Class:
2626 case PCC_ObjCInterface:
2627 case PCC_ObjCImplementation:
2628 case PCC_ObjCInstanceVariableList:
2629 case PCC_Template:
2630 case PCC_MemberTemplate:
2631 case PCC_ForInit:
2632 case PCC_Condition:
2633 case PCC_Type:
2634 break;
Douglas Gregoraa5f77b2010-08-23 21:54:33 +00002635 }
2636
Douglas Gregor0c8296d2009-11-07 00:00:49 +00002637 if (CodeCompleter->includeMacros())
Douglas Gregorbca403c2010-01-13 23:51:12 +00002638 AddMacroResults(PP, Results);
Douglas Gregoraa5f77b2010-08-23 21:54:33 +00002639
Douglas Gregorcee9ff12010-09-20 22:39:41 +00002640 HandleCodeCompleteResults(this, CodeCompleter, Results.getCompletionContext(),
Douglas Gregore6b1bb62010-08-11 21:23:17 +00002641 Results.data(),Results.size());
Douglas Gregor791215b2009-09-21 20:51:25 +00002642}
2643
Douglas Gregorc7b6d882010-09-16 15:14:18 +00002644static void AddClassMessageCompletions(Sema &SemaRef, Scope *S,
2645 ParsedType Receiver,
2646 IdentifierInfo **SelIdents,
2647 unsigned NumSelIdents,
Douglas Gregor70c5ac72010-09-20 23:34:21 +00002648 bool AtArgumentExpression,
Douglas Gregorc7b6d882010-09-16 15:14:18 +00002649 bool IsSuper,
2650 ResultBuilder &Results);
2651
2652void Sema::CodeCompleteDeclSpec(Scope *S, DeclSpec &DS,
2653 bool AllowNonIdentifiers,
2654 bool AllowNestedNameSpecifiers) {
John McCall0a2c5e22010-08-25 06:19:51 +00002655 typedef CodeCompletionResult Result;
Douglas Gregor2ccccb32010-08-23 18:23:48 +00002656 ResultBuilder Results(*this);
2657 Results.EnterNewScope();
2658
2659 // Type qualifiers can come after names.
2660 Results.AddResult(Result("const"));
2661 Results.AddResult(Result("volatile"));
2662 if (getLangOptions().C99)
2663 Results.AddResult(Result("restrict"));
2664
2665 if (getLangOptions().CPlusPlus) {
2666 if (AllowNonIdentifiers) {
2667 Results.AddResult(Result("operator"));
2668 }
2669
2670 // Add nested-name-specifiers.
2671 if (AllowNestedNameSpecifiers) {
2672 Results.allowNestedNameSpecifiers();
2673 CodeCompletionDeclConsumer Consumer(Results, CurContext);
2674 LookupVisibleDecls(S, LookupNestedNameSpecifierName, Consumer,
2675 CodeCompleter->includeGlobals());
2676 }
2677 }
2678 Results.ExitScope();
2679
Douglas Gregorc7b6d882010-09-16 15:14:18 +00002680 // If we're in a context where we might have an expression (rather than a
2681 // declaration), and what we've seen so far is an Objective-C type that could
2682 // be a receiver of a class message, this may be a class message send with
2683 // the initial opening bracket '[' missing. Add appropriate completions.
2684 if (AllowNonIdentifiers && !AllowNestedNameSpecifiers &&
2685 DS.getTypeSpecType() == DeclSpec::TST_typename &&
2686 DS.getStorageClassSpecAsWritten() == DeclSpec::SCS_unspecified &&
2687 !DS.isThreadSpecified() && !DS.isExternInLinkageSpec() &&
2688 DS.getTypeSpecComplex() == DeclSpec::TSC_unspecified &&
2689 DS.getTypeSpecSign() == DeclSpec::TSS_unspecified &&
2690 DS.getTypeQualifiers() == 0 &&
2691 S &&
2692 (S->getFlags() & Scope::DeclScope) != 0 &&
2693 (S->getFlags() & (Scope::ClassScope | Scope::TemplateParamScope |
2694 Scope::FunctionPrototypeScope |
2695 Scope::AtCatchScope)) == 0) {
2696 ParsedType T = DS.getRepAsType();
2697 if (!T.get().isNull() && T.get()->isObjCObjectOrInterfaceType())
Douglas Gregor70c5ac72010-09-20 23:34:21 +00002698 AddClassMessageCompletions(*this, S, T, 0, 0, false, false, Results);
Douglas Gregorc7b6d882010-09-16 15:14:18 +00002699 }
2700
Douglas Gregor4497dd42010-08-24 04:59:56 +00002701 // Note that we intentionally suppress macro results here, since we do not
2702 // encourage using macros to produce the names of entities.
2703
Douglas Gregor2ccccb32010-08-23 18:23:48 +00002704 HandleCodeCompleteResults(this, CodeCompleter,
2705 AllowNestedNameSpecifiers
2706 ? CodeCompletionContext::CCC_PotentiallyQualifiedName
2707 : CodeCompletionContext::CCC_Name,
2708 Results.data(), Results.size());
2709}
2710
Douglas Gregorfb629412010-08-23 21:17:50 +00002711struct Sema::CodeCompleteExpressionData {
2712 CodeCompleteExpressionData(QualType PreferredType = QualType())
2713 : PreferredType(PreferredType), IntegralConstantExpression(false),
2714 ObjCCollection(false) { }
2715
2716 QualType PreferredType;
2717 bool IntegralConstantExpression;
2718 bool ObjCCollection;
2719 llvm::SmallVector<Decl *, 4> IgnoreDecls;
2720};
2721
Douglas Gregor5ac3bdb2010-05-30 01:49:25 +00002722/// \brief Perform code-completion in an expression context when we know what
2723/// type we're looking for.
Douglas Gregorf9578432010-07-28 21:50:18 +00002724///
2725/// \param IntegralConstantExpression Only permit integral constant
2726/// expressions.
Douglas Gregorfb629412010-08-23 21:17:50 +00002727void Sema::CodeCompleteExpression(Scope *S,
2728 const CodeCompleteExpressionData &Data) {
John McCall0a2c5e22010-08-25 06:19:51 +00002729 typedef CodeCompletionResult Result;
Douglas Gregor5ac3bdb2010-05-30 01:49:25 +00002730 ResultBuilder Results(*this);
2731
Douglas Gregorfb629412010-08-23 21:17:50 +00002732 if (Data.ObjCCollection)
2733 Results.setFilter(&ResultBuilder::IsObjCCollection);
2734 else if (Data.IntegralConstantExpression)
Douglas Gregorf9578432010-07-28 21:50:18 +00002735 Results.setFilter(&ResultBuilder::IsIntegralConstantValue);
Douglas Gregore6b1bb62010-08-11 21:23:17 +00002736 else if (WantTypesInContext(PCC_Expression, getLangOptions()))
Douglas Gregor5ac3bdb2010-05-30 01:49:25 +00002737 Results.setFilter(&ResultBuilder::IsOrdinaryName);
2738 else
2739 Results.setFilter(&ResultBuilder::IsOrdinaryNonTypeName);
Douglas Gregorfb629412010-08-23 21:17:50 +00002740
2741 if (!Data.PreferredType.isNull())
2742 Results.setPreferredType(Data.PreferredType.getNonReferenceType());
2743
2744 // Ignore any declarations that we were told that we don't care about.
2745 for (unsigned I = 0, N = Data.IgnoreDecls.size(); I != N; ++I)
2746 Results.Ignore(Data.IgnoreDecls[I]);
Douglas Gregor5ac3bdb2010-05-30 01:49:25 +00002747
2748 CodeCompletionDeclConsumer Consumer(Results, CurContext);
Douglas Gregor8071e422010-08-15 06:18:01 +00002749 LookupVisibleDecls(S, LookupOrdinaryName, Consumer,
2750 CodeCompleter->includeGlobals());
Douglas Gregor5ac3bdb2010-05-30 01:49:25 +00002751
2752 Results.EnterNewScope();
Douglas Gregore6b1bb62010-08-11 21:23:17 +00002753 AddOrdinaryNameResults(PCC_Expression, S, *this, Results);
Douglas Gregor5ac3bdb2010-05-30 01:49:25 +00002754 Results.ExitScope();
2755
Douglas Gregor590c7d52010-07-08 20:55:51 +00002756 bool PreferredTypeIsPointer = false;
Douglas Gregorfb629412010-08-23 21:17:50 +00002757 if (!Data.PreferredType.isNull())
2758 PreferredTypeIsPointer = Data.PreferredType->isAnyPointerType()
2759 || Data.PreferredType->isMemberPointerType()
2760 || Data.PreferredType->isBlockPointerType();
Douglas Gregor590c7d52010-07-08 20:55:51 +00002761
Douglas Gregoraa5f77b2010-08-23 21:54:33 +00002762 if (S->getFnParent() &&
2763 !Data.ObjCCollection &&
2764 !Data.IntegralConstantExpression)
2765 AddPrettyFunctionResults(PP.getLangOptions(), Results);
2766
Douglas Gregor5ac3bdb2010-05-30 01:49:25 +00002767 if (CodeCompleter->includeMacros())
Douglas Gregor590c7d52010-07-08 20:55:51 +00002768 AddMacroResults(PP, Results, PreferredTypeIsPointer);
Douglas Gregore6b1bb62010-08-11 21:23:17 +00002769 HandleCodeCompleteResults(this, CodeCompleter,
Douglas Gregorfb629412010-08-23 21:17:50 +00002770 CodeCompletionContext(CodeCompletionContext::CCC_Expression,
2771 Data.PreferredType),
Douglas Gregore6b1bb62010-08-11 21:23:17 +00002772 Results.data(),Results.size());
Douglas Gregor5ac3bdb2010-05-30 01:49:25 +00002773}
2774
Douglas Gregorac5fd842010-09-18 01:28:11 +00002775void Sema::CodeCompletePostfixExpression(Scope *S, ExprResult E) {
2776 if (E.isInvalid())
2777 CodeCompleteOrdinaryName(S, PCC_RecoveryInFunction);
2778 else if (getLangOptions().ObjC1)
2779 CodeCompleteObjCInstanceMessage(S, E.take(), 0, 0, false);
Douglas Gregor78edf512010-09-15 16:23:04 +00002780}
Douglas Gregor5ac3bdb2010-05-30 01:49:25 +00002781
Douglas Gregor95ac6552009-11-18 01:29:26 +00002782static void AddObjCProperties(ObjCContainerDecl *Container,
Douglas Gregor322328b2009-11-18 22:32:06 +00002783 bool AllowCategories,
Douglas Gregor95ac6552009-11-18 01:29:26 +00002784 DeclContext *CurContext,
2785 ResultBuilder &Results) {
John McCall0a2c5e22010-08-25 06:19:51 +00002786 typedef CodeCompletionResult Result;
Douglas Gregor95ac6552009-11-18 01:29:26 +00002787
2788 // Add properties in this container.
2789 for (ObjCContainerDecl::prop_iterator P = Container->prop_begin(),
2790 PEnd = Container->prop_end();
2791 P != PEnd;
2792 ++P)
2793 Results.MaybeAddResult(Result(*P, 0), CurContext);
2794
2795 // Add properties in referenced protocols.
2796 if (ObjCProtocolDecl *Protocol = dyn_cast<ObjCProtocolDecl>(Container)) {
2797 for (ObjCProtocolDecl::protocol_iterator P = Protocol->protocol_begin(),
2798 PEnd = Protocol->protocol_end();
2799 P != PEnd; ++P)
Douglas Gregor322328b2009-11-18 22:32:06 +00002800 AddObjCProperties(*P, AllowCategories, CurContext, Results);
Douglas Gregor95ac6552009-11-18 01:29:26 +00002801 } else if (ObjCInterfaceDecl *IFace = dyn_cast<ObjCInterfaceDecl>(Container)){
Douglas Gregor322328b2009-11-18 22:32:06 +00002802 if (AllowCategories) {
2803 // Look through categories.
2804 for (ObjCCategoryDecl *Category = IFace->getCategoryList();
2805 Category; Category = Category->getNextClassCategory())
2806 AddObjCProperties(Category, AllowCategories, CurContext, Results);
2807 }
Douglas Gregor95ac6552009-11-18 01:29:26 +00002808
2809 // Look through protocols.
Ted Kremenek53b94412010-09-01 01:21:15 +00002810 for (ObjCInterfaceDecl::all_protocol_iterator
2811 I = IFace->all_referenced_protocol_begin(),
2812 E = IFace->all_referenced_protocol_end(); I != E; ++I)
Douglas Gregor322328b2009-11-18 22:32:06 +00002813 AddObjCProperties(*I, AllowCategories, CurContext, Results);
Douglas Gregor95ac6552009-11-18 01:29:26 +00002814
2815 // Look in the superclass.
2816 if (IFace->getSuperClass())
Douglas Gregor322328b2009-11-18 22:32:06 +00002817 AddObjCProperties(IFace->getSuperClass(), AllowCategories, CurContext,
2818 Results);
Douglas Gregor95ac6552009-11-18 01:29:26 +00002819 } else if (const ObjCCategoryDecl *Category
2820 = dyn_cast<ObjCCategoryDecl>(Container)) {
2821 // Look through protocols.
Ted Kremenek53b94412010-09-01 01:21:15 +00002822 for (ObjCCategoryDecl::protocol_iterator P = Category->protocol_begin(),
2823 PEnd = Category->protocol_end();
Douglas Gregor95ac6552009-11-18 01:29:26 +00002824 P != PEnd; ++P)
Douglas Gregor322328b2009-11-18 22:32:06 +00002825 AddObjCProperties(*P, AllowCategories, CurContext, Results);
Douglas Gregor95ac6552009-11-18 01:29:26 +00002826 }
2827}
2828
Douglas Gregor81b747b2009-09-17 21:32:03 +00002829void Sema::CodeCompleteMemberReferenceExpr(Scope *S, ExprTy *BaseE,
2830 SourceLocation OpLoc,
2831 bool IsArrow) {
2832 if (!BaseE || !CodeCompleter)
2833 return;
2834
John McCall0a2c5e22010-08-25 06:19:51 +00002835 typedef CodeCompletionResult Result;
Douglas Gregor86d9a522009-09-21 16:56:56 +00002836
Douglas Gregor81b747b2009-09-17 21:32:03 +00002837 Expr *Base = static_cast<Expr *>(BaseE);
2838 QualType BaseType = Base->getType();
Douglas Gregor86d9a522009-09-21 16:56:56 +00002839
2840 if (IsArrow) {
2841 if (const PointerType *Ptr = BaseType->getAs<PointerType>())
2842 BaseType = Ptr->getPointeeType();
2843 else if (BaseType->isObjCObjectPointerType())
Douglas Gregor3cdee122010-08-26 16:36:48 +00002844 /*Do nothing*/ ;
Douglas Gregor86d9a522009-09-21 16:56:56 +00002845 else
2846 return;
2847 }
2848
Douglas Gregoreb5758b2009-09-23 22:26:46 +00002849 ResultBuilder Results(*this, &ResultBuilder::IsMember);
Douglas Gregor95ac6552009-11-18 01:29:26 +00002850 Results.EnterNewScope();
2851 if (const RecordType *Record = BaseType->getAs<RecordType>()) {
Douglas Gregor3cdee122010-08-26 16:36:48 +00002852 // Indicate that we are performing a member access, and the cv-qualifiers
2853 // for the base object type.
2854 Results.setObjectTypeQualifiers(BaseType.getQualifiers());
2855
Douglas Gregor95ac6552009-11-18 01:29:26 +00002856 // Access to a C/C++ class, struct, or union.
Douglas Gregor45bcd432010-01-14 03:21:49 +00002857 Results.allowNestedNameSpecifiers();
Douglas Gregor0cc84042010-01-14 15:47:35 +00002858 CodeCompletionDeclConsumer Consumer(Results, CurContext);
Douglas Gregor8071e422010-08-15 06:18:01 +00002859 LookupVisibleDecls(Record->getDecl(), LookupMemberName, Consumer,
2860 CodeCompleter->includeGlobals());
Daniel Dunbar3a2838d2009-11-13 08:58:20 +00002861
Douglas Gregor95ac6552009-11-18 01:29:26 +00002862 if (getLangOptions().CPlusPlus) {
2863 if (!Results.empty()) {
2864 // The "template" keyword can follow "->" or "." in the grammar.
2865 // However, we only want to suggest the template keyword if something
2866 // is dependent.
2867 bool IsDependent = BaseType->isDependentType();
2868 if (!IsDependent) {
2869 for (Scope *DepScope = S; DepScope; DepScope = DepScope->getParent())
2870 if (DeclContext *Ctx = (DeclContext *)DepScope->getEntity()) {
2871 IsDependent = Ctx->isDependentContext();
2872 break;
2873 }
2874 }
Daniel Dunbar3a2838d2009-11-13 08:58:20 +00002875
Douglas Gregor95ac6552009-11-18 01:29:26 +00002876 if (IsDependent)
Douglas Gregora4477812010-01-14 16:01:26 +00002877 Results.AddResult(Result("template"));
Daniel Dunbar3a2838d2009-11-13 08:58:20 +00002878 }
Daniel Dunbar3a2838d2009-11-13 08:58:20 +00002879 }
Douglas Gregor95ac6552009-11-18 01:29:26 +00002880 } else if (!IsArrow && BaseType->getAsObjCInterfacePointerType()) {
2881 // Objective-C property reference.
2882
2883 // Add property results based on our interface.
2884 const ObjCObjectPointerType *ObjCPtr
2885 = BaseType->getAsObjCInterfacePointerType();
2886 assert(ObjCPtr && "Non-NULL pointer guaranteed above!");
Douglas Gregor322328b2009-11-18 22:32:06 +00002887 AddObjCProperties(ObjCPtr->getInterfaceDecl(), true, CurContext, Results);
Douglas Gregor95ac6552009-11-18 01:29:26 +00002888
2889 // Add properties from the protocols in a qualified interface.
2890 for (ObjCObjectPointerType::qual_iterator I = ObjCPtr->qual_begin(),
2891 E = ObjCPtr->qual_end();
2892 I != E; ++I)
Douglas Gregor322328b2009-11-18 22:32:06 +00002893 AddObjCProperties(*I, true, CurContext, Results);
Douglas Gregor95ac6552009-11-18 01:29:26 +00002894 } else if ((IsArrow && BaseType->isObjCObjectPointerType()) ||
John McCallc12c5bb2010-05-15 11:32:37 +00002895 (!IsArrow && BaseType->isObjCObjectType())) {
Douglas Gregor95ac6552009-11-18 01:29:26 +00002896 // Objective-C instance variable access.
2897 ObjCInterfaceDecl *Class = 0;
2898 if (const ObjCObjectPointerType *ObjCPtr
2899 = BaseType->getAs<ObjCObjectPointerType>())
2900 Class = ObjCPtr->getInterfaceDecl();
2901 else
John McCallc12c5bb2010-05-15 11:32:37 +00002902 Class = BaseType->getAs<ObjCObjectType>()->getInterface();
Douglas Gregor95ac6552009-11-18 01:29:26 +00002903
2904 // Add all ivars from this class and its superclasses.
Douglas Gregor80f4f4c2010-01-14 16:08:12 +00002905 if (Class) {
2906 CodeCompletionDeclConsumer Consumer(Results, CurContext);
2907 Results.setFilter(&ResultBuilder::IsObjCIvar);
Douglas Gregor8071e422010-08-15 06:18:01 +00002908 LookupVisibleDecls(Class, LookupMemberName, Consumer,
2909 CodeCompleter->includeGlobals());
Douglas Gregor95ac6552009-11-18 01:29:26 +00002910 }
Douglas Gregor86d9a522009-09-21 16:56:56 +00002911 }
Douglas Gregor95ac6552009-11-18 01:29:26 +00002912
2913 // FIXME: How do we cope with isa?
2914
2915 Results.ExitScope();
Daniel Dunbar3a2838d2009-11-13 08:58:20 +00002916
Daniel Dunbar3a2838d2009-11-13 08:58:20 +00002917 // Hand off the results found for code completion.
Douglas Gregore6b1bb62010-08-11 21:23:17 +00002918 HandleCodeCompleteResults(this, CodeCompleter,
2919 CodeCompletionContext(CodeCompletionContext::CCC_MemberAccess,
2920 BaseType),
2921 Results.data(),Results.size());
Douglas Gregor81b747b2009-09-17 21:32:03 +00002922}
2923
Douglas Gregor374929f2009-09-18 15:37:17 +00002924void Sema::CodeCompleteTag(Scope *S, unsigned TagSpec) {
2925 if (!CodeCompleter)
2926 return;
2927
John McCall0a2c5e22010-08-25 06:19:51 +00002928 typedef CodeCompletionResult Result;
Douglas Gregor86d9a522009-09-21 16:56:56 +00002929 ResultBuilder::LookupFilter Filter = 0;
Douglas Gregore6b1bb62010-08-11 21:23:17 +00002930 enum CodeCompletionContext::Kind ContextKind
2931 = CodeCompletionContext::CCC_Other;
Douglas Gregor374929f2009-09-18 15:37:17 +00002932 switch ((DeclSpec::TST)TagSpec) {
2933 case DeclSpec::TST_enum:
Douglas Gregor86d9a522009-09-21 16:56:56 +00002934 Filter = &ResultBuilder::IsEnum;
Douglas Gregore6b1bb62010-08-11 21:23:17 +00002935 ContextKind = CodeCompletionContext::CCC_EnumTag;
Douglas Gregor374929f2009-09-18 15:37:17 +00002936 break;
2937
2938 case DeclSpec::TST_union:
Douglas Gregor86d9a522009-09-21 16:56:56 +00002939 Filter = &ResultBuilder::IsUnion;
Douglas Gregore6b1bb62010-08-11 21:23:17 +00002940 ContextKind = CodeCompletionContext::CCC_UnionTag;
Douglas Gregor374929f2009-09-18 15:37:17 +00002941 break;
2942
2943 case DeclSpec::TST_struct:
Douglas Gregor374929f2009-09-18 15:37:17 +00002944 case DeclSpec::TST_class:
Douglas Gregor86d9a522009-09-21 16:56:56 +00002945 Filter = &ResultBuilder::IsClassOrStruct;
Douglas Gregore6b1bb62010-08-11 21:23:17 +00002946 ContextKind = CodeCompletionContext::CCC_ClassOrStructTag;
Douglas Gregor374929f2009-09-18 15:37:17 +00002947 break;
2948
2949 default:
2950 assert(false && "Unknown type specifier kind in CodeCompleteTag");
2951 return;
2952 }
Douglas Gregor86d9a522009-09-21 16:56:56 +00002953
John McCall0d6b1642010-04-23 18:46:30 +00002954 ResultBuilder Results(*this);
Douglas Gregor5d2fc402010-01-14 03:27:13 +00002955 CodeCompletionDeclConsumer Consumer(Results, CurContext);
John McCall0d6b1642010-04-23 18:46:30 +00002956
2957 // First pass: look for tags.
2958 Results.setFilter(Filter);
Douglas Gregor8071e422010-08-15 06:18:01 +00002959 LookupVisibleDecls(S, LookupTagName, Consumer,
2960 CodeCompleter->includeGlobals());
John McCall0d6b1642010-04-23 18:46:30 +00002961
Douglas Gregor8071e422010-08-15 06:18:01 +00002962 if (CodeCompleter->includeGlobals()) {
2963 // Second pass: look for nested name specifiers.
2964 Results.setFilter(&ResultBuilder::IsNestedNameSpecifier);
2965 LookupVisibleDecls(S, LookupNestedNameSpecifierName, Consumer);
2966 }
Douglas Gregor86d9a522009-09-21 16:56:56 +00002967
Douglas Gregore6b1bb62010-08-11 21:23:17 +00002968 HandleCodeCompleteResults(this, CodeCompleter, ContextKind,
2969 Results.data(),Results.size());
Douglas Gregor374929f2009-09-18 15:37:17 +00002970}
2971
Douglas Gregor1a480c42010-08-27 17:35:51 +00002972void Sema::CodeCompleteTypeQualifiers(DeclSpec &DS) {
2973 ResultBuilder Results(*this);
2974 Results.EnterNewScope();
2975 if (!(DS.getTypeQualifiers() & DeclSpec::TQ_const))
2976 Results.AddResult("const");
2977 if (!(DS.getTypeQualifiers() & DeclSpec::TQ_volatile))
2978 Results.AddResult("volatile");
2979 if (getLangOptions().C99 &&
2980 !(DS.getTypeQualifiers() & DeclSpec::TQ_restrict))
2981 Results.AddResult("restrict");
2982 Results.ExitScope();
2983 HandleCodeCompleteResults(this, CodeCompleter,
2984 CodeCompletionContext::CCC_TypeQualifiers,
2985 Results.data(), Results.size());
2986}
2987
Douglas Gregor3e1005f2009-09-21 18:10:23 +00002988void Sema::CodeCompleteCase(Scope *S) {
John McCall781472f2010-08-25 08:40:02 +00002989 if (getCurFunction()->SwitchStack.empty() || !CodeCompleter)
Douglas Gregor3e1005f2009-09-21 18:10:23 +00002990 return;
2991
John McCall781472f2010-08-25 08:40:02 +00002992 SwitchStmt *Switch = getCurFunction()->SwitchStack.back();
Douglas Gregorf9578432010-07-28 21:50:18 +00002993 if (!Switch->getCond()->getType()->isEnumeralType()) {
Douglas Gregorfb629412010-08-23 21:17:50 +00002994 CodeCompleteExpressionData Data(Switch->getCond()->getType());
2995 Data.IntegralConstantExpression = true;
2996 CodeCompleteExpression(S, Data);
Douglas Gregor3e1005f2009-09-21 18:10:23 +00002997 return;
Douglas Gregorf9578432010-07-28 21:50:18 +00002998 }
Douglas Gregor3e1005f2009-09-21 18:10:23 +00002999
3000 // Code-complete the cases of a switch statement over an enumeration type
3001 // by providing the list of
3002 EnumDecl *Enum = Switch->getCond()->getType()->getAs<EnumType>()->getDecl();
3003
3004 // Determine which enumerators we have already seen in the switch statement.
3005 // FIXME: Ideally, we would also be able to look *past* the code-completion
3006 // token, in case we are code-completing in the middle of the switch and not
3007 // at the end. However, we aren't able to do so at the moment.
3008 llvm::SmallPtrSet<EnumConstantDecl *, 8> EnumeratorsSeen;
Douglas Gregorb9d0ef72009-09-21 19:57:38 +00003009 NestedNameSpecifier *Qualifier = 0;
Douglas Gregor3e1005f2009-09-21 18:10:23 +00003010 for (SwitchCase *SC = Switch->getSwitchCaseList(); SC;
3011 SC = SC->getNextSwitchCase()) {
3012 CaseStmt *Case = dyn_cast<CaseStmt>(SC);
3013 if (!Case)
3014 continue;
3015
3016 Expr *CaseVal = Case->getLHS()->IgnoreParenCasts();
3017 if (DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(CaseVal))
3018 if (EnumConstantDecl *Enumerator
3019 = dyn_cast<EnumConstantDecl>(DRE->getDecl())) {
3020 // We look into the AST of the case statement to determine which
3021 // enumerator was named. Alternatively, we could compute the value of
3022 // the integral constant expression, then compare it against the
3023 // values of each enumerator. However, value-based approach would not
3024 // work as well with C++ templates where enumerators declared within a
3025 // template are type- and value-dependent.
3026 EnumeratorsSeen.insert(Enumerator);
3027
Douglas Gregorb9d0ef72009-09-21 19:57:38 +00003028 // If this is a qualified-id, keep track of the nested-name-specifier
3029 // so that we can reproduce it as part of code completion, e.g.,
Douglas Gregor3e1005f2009-09-21 18:10:23 +00003030 //
3031 // switch (TagD.getKind()) {
3032 // case TagDecl::TK_enum:
3033 // break;
3034 // case XXX
3035 //
Douglas Gregorb9d0ef72009-09-21 19:57:38 +00003036 // At the XXX, our completions are TagDecl::TK_union,
Douglas Gregor3e1005f2009-09-21 18:10:23 +00003037 // TagDecl::TK_struct, and TagDecl::TK_class, rather than TK_union,
3038 // TK_struct, and TK_class.
Douglas Gregora2813ce2009-10-23 18:54:35 +00003039 Qualifier = DRE->getQualifier();
Douglas Gregor3e1005f2009-09-21 18:10:23 +00003040 }
3041 }
3042
Douglas Gregorb9d0ef72009-09-21 19:57:38 +00003043 if (getLangOptions().CPlusPlus && !Qualifier && EnumeratorsSeen.empty()) {
3044 // If there are no prior enumerators in C++, check whether we have to
3045 // qualify the names of the enumerators that we suggest, because they
3046 // may not be visible in this scope.
3047 Qualifier = getRequiredQualification(Context, CurContext,
3048 Enum->getDeclContext());
3049
3050 // FIXME: Scoped enums need to start with "EnumDecl" as the context!
3051 }
3052
Douglas Gregor3e1005f2009-09-21 18:10:23 +00003053 // Add any enumerators that have not yet been mentioned.
3054 ResultBuilder Results(*this);
3055 Results.EnterNewScope();
3056 for (EnumDecl::enumerator_iterator E = Enum->enumerator_begin(),
3057 EEnd = Enum->enumerator_end();
3058 E != EEnd; ++E) {
3059 if (EnumeratorsSeen.count(*E))
3060 continue;
3061
John McCall0a2c5e22010-08-25 06:19:51 +00003062 Results.AddResult(CodeCompletionResult(*E, Qualifier),
Douglas Gregor608300b2010-01-14 16:14:35 +00003063 CurContext, 0, false);
Douglas Gregor3e1005f2009-09-21 18:10:23 +00003064 }
3065 Results.ExitScope();
Douglas Gregor2f880e42010-04-06 20:02:15 +00003066
Douglas Gregor0c8296d2009-11-07 00:00:49 +00003067 if (CodeCompleter->includeMacros())
Douglas Gregorbca403c2010-01-13 23:51:12 +00003068 AddMacroResults(PP, Results);
Douglas Gregore6b1bb62010-08-11 21:23:17 +00003069 HandleCodeCompleteResults(this, CodeCompleter,
3070 CodeCompletionContext::CCC_Expression,
3071 Results.data(),Results.size());
Douglas Gregor3e1005f2009-09-21 18:10:23 +00003072}
3073
Douglas Gregor9c6a0e92009-09-22 15:41:20 +00003074namespace {
3075 struct IsBetterOverloadCandidate {
3076 Sema &S;
John McCall5769d612010-02-08 23:07:23 +00003077 SourceLocation Loc;
Douglas Gregor9c6a0e92009-09-22 15:41:20 +00003078
3079 public:
John McCall5769d612010-02-08 23:07:23 +00003080 explicit IsBetterOverloadCandidate(Sema &S, SourceLocation Loc)
3081 : S(S), Loc(Loc) { }
Douglas Gregor9c6a0e92009-09-22 15:41:20 +00003082
3083 bool
3084 operator()(const OverloadCandidate &X, const OverloadCandidate &Y) const {
John McCall120d63c2010-08-24 20:38:10 +00003085 return isBetterOverloadCandidate(S, X, Y, Loc);
Douglas Gregor9c6a0e92009-09-22 15:41:20 +00003086 }
3087 };
3088}
3089
Douglas Gregord28dcd72010-05-30 06:10:08 +00003090static bool anyNullArguments(Expr **Args, unsigned NumArgs) {
3091 if (NumArgs && !Args)
3092 return true;
3093
3094 for (unsigned I = 0; I != NumArgs; ++I)
3095 if (!Args[I])
3096 return true;
3097
3098 return false;
3099}
3100
Douglas Gregor9c6a0e92009-09-22 15:41:20 +00003101void Sema::CodeCompleteCall(Scope *S, ExprTy *FnIn,
3102 ExprTy **ArgsIn, unsigned NumArgs) {
3103 if (!CodeCompleter)
3104 return;
Douglas Gregoref96eac2009-12-11 19:06:04 +00003105
3106 // When we're code-completing for a call, we fall back to ordinary
3107 // name code-completion whenever we can't produce specific
3108 // results. We may want to revisit this strategy in the future,
3109 // e.g., by merging the two kinds of results.
3110
Douglas Gregor9c6a0e92009-09-22 15:41:20 +00003111 Expr *Fn = (Expr *)FnIn;
3112 Expr **Args = (Expr **)ArgsIn;
Douglas Gregoref96eac2009-12-11 19:06:04 +00003113
Douglas Gregor9c6a0e92009-09-22 15:41:20 +00003114 // Ignore type-dependent call expressions entirely.
Douglas Gregord28dcd72010-05-30 06:10:08 +00003115 if (!Fn || Fn->isTypeDependent() || anyNullArguments(Args, NumArgs) ||
Douglas Gregoref96eac2009-12-11 19:06:04 +00003116 Expr::hasAnyTypeDependentArguments(Args, NumArgs)) {
Douglas Gregore6b1bb62010-08-11 21:23:17 +00003117 CodeCompleteOrdinaryName(S, PCC_Expression);
Douglas Gregor9c6a0e92009-09-22 15:41:20 +00003118 return;
Douglas Gregoref96eac2009-12-11 19:06:04 +00003119 }
Douglas Gregor9c6a0e92009-09-22 15:41:20 +00003120
John McCall3b4294e2009-12-16 12:17:52 +00003121 // Build an overload candidate set based on the functions we find.
John McCall5769d612010-02-08 23:07:23 +00003122 SourceLocation Loc = Fn->getExprLoc();
3123 OverloadCandidateSet CandidateSet(Loc);
John McCall3b4294e2009-12-16 12:17:52 +00003124
Douglas Gregor9c6a0e92009-09-22 15:41:20 +00003125 // FIXME: What if we're calling something that isn't a function declaration?
3126 // FIXME: What if we're calling a pseudo-destructor?
3127 // FIXME: What if we're calling a member function?
3128
Douglas Gregorc0265402010-01-21 15:46:19 +00003129 typedef CodeCompleteConsumer::OverloadCandidate ResultCandidate;
3130 llvm::SmallVector<ResultCandidate, 8> Results;
3131
John McCall3b4294e2009-12-16 12:17:52 +00003132 Expr *NakedFn = Fn->IgnoreParenCasts();
3133 if (UnresolvedLookupExpr *ULE = dyn_cast<UnresolvedLookupExpr>(NakedFn))
3134 AddOverloadedCallCandidates(ULE, Args, NumArgs, CandidateSet,
3135 /*PartialOverloading=*/ true);
3136 else if (DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(NakedFn)) {
3137 FunctionDecl *FDecl = dyn_cast<FunctionDecl>(DRE->getDecl());
Douglas Gregorc0265402010-01-21 15:46:19 +00003138 if (FDecl) {
Douglas Gregord28dcd72010-05-30 06:10:08 +00003139 if (!getLangOptions().CPlusPlus ||
3140 !FDecl->getType()->getAs<FunctionProtoType>())
Douglas Gregorc0265402010-01-21 15:46:19 +00003141 Results.push_back(ResultCandidate(FDecl));
3142 else
John McCall86820f52010-01-26 01:37:31 +00003143 // FIXME: access?
John McCall9aa472c2010-03-19 07:35:19 +00003144 AddOverloadCandidate(FDecl, DeclAccessPair::make(FDecl, AS_none),
3145 Args, NumArgs, CandidateSet,
Douglas Gregorc27d6c52010-04-16 17:41:49 +00003146 false, /*PartialOverloading*/true);
Douglas Gregorc0265402010-01-21 15:46:19 +00003147 }
John McCall3b4294e2009-12-16 12:17:52 +00003148 }
Douglas Gregor9c6a0e92009-09-22 15:41:20 +00003149
Douglas Gregor5ac3bdb2010-05-30 01:49:25 +00003150 QualType ParamType;
3151
Douglas Gregorc0265402010-01-21 15:46:19 +00003152 if (!CandidateSet.empty()) {
3153 // Sort the overload candidate set by placing the best overloads first.
3154 std::stable_sort(CandidateSet.begin(), CandidateSet.end(),
John McCall5769d612010-02-08 23:07:23 +00003155 IsBetterOverloadCandidate(*this, Loc));
Douglas Gregor9c6a0e92009-09-22 15:41:20 +00003156
Douglas Gregorc0265402010-01-21 15:46:19 +00003157 // Add the remaining viable overload candidates as code-completion reslults.
3158 for (OverloadCandidateSet::iterator Cand = CandidateSet.begin(),
3159 CandEnd = CandidateSet.end();
3160 Cand != CandEnd; ++Cand) {
3161 if (Cand->Viable)
3162 Results.push_back(ResultCandidate(Cand->Function));
3163 }
Douglas Gregor5ac3bdb2010-05-30 01:49:25 +00003164
3165 // From the viable candidates, try to determine the type of this parameter.
3166 for (unsigned I = 0, N = Results.size(); I != N; ++I) {
3167 if (const FunctionType *FType = Results[I].getFunctionType())
3168 if (const FunctionProtoType *Proto = dyn_cast<FunctionProtoType>(FType))
3169 if (NumArgs < Proto->getNumArgs()) {
3170 if (ParamType.isNull())
3171 ParamType = Proto->getArgType(NumArgs);
3172 else if (!Context.hasSameUnqualifiedType(
3173 ParamType.getNonReferenceType(),
3174 Proto->getArgType(NumArgs).getNonReferenceType())) {
3175 ParamType = QualType();
3176 break;
3177 }
3178 }
3179 }
3180 } else {
3181 // Try to determine the parameter type from the type of the expression
3182 // being called.
3183 QualType FunctionType = Fn->getType();
3184 if (const PointerType *Ptr = FunctionType->getAs<PointerType>())
3185 FunctionType = Ptr->getPointeeType();
3186 else if (const BlockPointerType *BlockPtr
3187 = FunctionType->getAs<BlockPointerType>())
3188 FunctionType = BlockPtr->getPointeeType();
3189 else if (const MemberPointerType *MemPtr
3190 = FunctionType->getAs<MemberPointerType>())
3191 FunctionType = MemPtr->getPointeeType();
3192
3193 if (const FunctionProtoType *Proto
3194 = FunctionType->getAs<FunctionProtoType>()) {
3195 if (NumArgs < Proto->getNumArgs())
3196 ParamType = Proto->getArgType(NumArgs);
3197 }
Douglas Gregor9c6a0e92009-09-22 15:41:20 +00003198 }
Douglas Gregoref96eac2009-12-11 19:06:04 +00003199
Douglas Gregor5ac3bdb2010-05-30 01:49:25 +00003200 if (ParamType.isNull())
Douglas Gregore6b1bb62010-08-11 21:23:17 +00003201 CodeCompleteOrdinaryName(S, PCC_Expression);
Douglas Gregor5ac3bdb2010-05-30 01:49:25 +00003202 else
3203 CodeCompleteExpression(S, ParamType);
3204
Douglas Gregor2e4c7a52010-04-06 20:19:47 +00003205 if (!Results.empty())
Douglas Gregoref96eac2009-12-11 19:06:04 +00003206 CodeCompleter->ProcessOverloadCandidates(*this, NumArgs, Results.data(),
3207 Results.size());
Douglas Gregor9c6a0e92009-09-22 15:41:20 +00003208}
3209
John McCalld226f652010-08-21 09:40:31 +00003210void Sema::CodeCompleteInitializer(Scope *S, Decl *D) {
3211 ValueDecl *VD = dyn_cast_or_null<ValueDecl>(D);
Douglas Gregor5ac3bdb2010-05-30 01:49:25 +00003212 if (!VD) {
Douglas Gregore6b1bb62010-08-11 21:23:17 +00003213 CodeCompleteOrdinaryName(S, PCC_Expression);
Douglas Gregor5ac3bdb2010-05-30 01:49:25 +00003214 return;
3215 }
3216
3217 CodeCompleteExpression(S, VD->getType());
3218}
3219
3220void Sema::CodeCompleteReturn(Scope *S) {
3221 QualType ResultType;
3222 if (isa<BlockDecl>(CurContext)) {
3223 if (BlockScopeInfo *BSI = getCurBlock())
3224 ResultType = BSI->ReturnType;
3225 } else if (FunctionDecl *Function = dyn_cast<FunctionDecl>(CurContext))
3226 ResultType = Function->getResultType();
3227 else if (ObjCMethodDecl *Method = dyn_cast<ObjCMethodDecl>(CurContext))
3228 ResultType = Method->getResultType();
3229
3230 if (ResultType.isNull())
Douglas Gregore6b1bb62010-08-11 21:23:17 +00003231 CodeCompleteOrdinaryName(S, PCC_Expression);
Douglas Gregor5ac3bdb2010-05-30 01:49:25 +00003232 else
3233 CodeCompleteExpression(S, ResultType);
3234}
3235
3236void Sema::CodeCompleteAssignmentRHS(Scope *S, ExprTy *LHS) {
3237 if (LHS)
3238 CodeCompleteExpression(S, static_cast<Expr *>(LHS)->getType());
3239 else
Douglas Gregore6b1bb62010-08-11 21:23:17 +00003240 CodeCompleteOrdinaryName(S, PCC_Expression);
Douglas Gregor5ac3bdb2010-05-30 01:49:25 +00003241}
3242
Jeffrey Yasskin9ab14542010-04-08 16:38:48 +00003243void Sema::CodeCompleteQualifiedId(Scope *S, CXXScopeSpec &SS,
Douglas Gregor81b747b2009-09-17 21:32:03 +00003244 bool EnteringContext) {
3245 if (!SS.getScopeRep() || !CodeCompleter)
3246 return;
3247
Douglas Gregor86d9a522009-09-21 16:56:56 +00003248 DeclContext *Ctx = computeDeclContext(SS, EnteringContext);
3249 if (!Ctx)
3250 return;
Douglas Gregord1cd31a2009-12-11 18:28:39 +00003251
3252 // Try to instantiate any non-dependent declaration contexts before
3253 // we look in them.
John McCall77bb1aa2010-05-01 00:40:08 +00003254 if (!isDependentScopeSpecifier(SS) && RequireCompleteDeclContext(SS, Ctx))
Douglas Gregord1cd31a2009-12-11 18:28:39 +00003255 return;
3256
Douglas Gregor86d9a522009-09-21 16:56:56 +00003257 ResultBuilder Results(*this);
Douglas Gregor86d9a522009-09-21 16:56:56 +00003258
Douglas Gregorf6961522010-08-27 21:18:54 +00003259 Results.EnterNewScope();
Douglas Gregor86d9a522009-09-21 16:56:56 +00003260 // The "template" keyword can follow "::" in the grammar, but only
3261 // put it into the grammar if the nested-name-specifier is dependent.
3262 NestedNameSpecifier *NNS = (NestedNameSpecifier *)SS.getScopeRep();
3263 if (!Results.empty() && NNS->isDependent())
Douglas Gregora4477812010-01-14 16:01:26 +00003264 Results.AddResult("template");
Douglas Gregorf6961522010-08-27 21:18:54 +00003265
3266 // Add calls to overridden virtual functions, if there are any.
3267 //
3268 // FIXME: This isn't wonderful, because we don't know whether we're actually
3269 // in a context that permits expressions. This is a general issue with
3270 // qualified-id completions.
3271 if (!EnteringContext)
3272 MaybeAddOverrideCalls(*this, Ctx, Results);
3273 Results.ExitScope();
Douglas Gregor86d9a522009-09-21 16:56:56 +00003274
Douglas Gregorf6961522010-08-27 21:18:54 +00003275 CodeCompletionDeclConsumer Consumer(Results, CurContext);
3276 LookupVisibleDecls(Ctx, LookupOrdinaryName, Consumer);
3277
Douglas Gregore6b1bb62010-08-11 21:23:17 +00003278 HandleCodeCompleteResults(this, CodeCompleter,
Douglas Gregorf6961522010-08-27 21:18:54 +00003279 CodeCompletionContext::CCC_Name,
Douglas Gregore6b1bb62010-08-11 21:23:17 +00003280 Results.data(),Results.size());
Douglas Gregor81b747b2009-09-17 21:32:03 +00003281}
Douglas Gregor49f40bd2009-09-18 19:03:04 +00003282
3283void Sema::CodeCompleteUsing(Scope *S) {
3284 if (!CodeCompleter)
3285 return;
3286
Douglas Gregor86d9a522009-09-21 16:56:56 +00003287 ResultBuilder Results(*this, &ResultBuilder::IsNestedNameSpecifier);
Douglas Gregor8e0a0e42009-09-22 23:31:26 +00003288 Results.EnterNewScope();
Douglas Gregor86d9a522009-09-21 16:56:56 +00003289
3290 // If we aren't in class scope, we could see the "namespace" keyword.
3291 if (!S->isClassScope())
John McCall0a2c5e22010-08-25 06:19:51 +00003292 Results.AddResult(CodeCompletionResult("namespace"));
Douglas Gregor86d9a522009-09-21 16:56:56 +00003293
3294 // After "using", we can see anything that would start a
3295 // nested-name-specifier.
Douglas Gregor5d2fc402010-01-14 03:27:13 +00003296 CodeCompletionDeclConsumer Consumer(Results, CurContext);
Douglas Gregor8071e422010-08-15 06:18:01 +00003297 LookupVisibleDecls(S, LookupOrdinaryName, Consumer,
3298 CodeCompleter->includeGlobals());
Douglas Gregor8e0a0e42009-09-22 23:31:26 +00003299 Results.ExitScope();
Douglas Gregor86d9a522009-09-21 16:56:56 +00003300
Douglas Gregore6b1bb62010-08-11 21:23:17 +00003301 HandleCodeCompleteResults(this, CodeCompleter,
3302 CodeCompletionContext::CCC_Other,
3303 Results.data(),Results.size());
Douglas Gregor49f40bd2009-09-18 19:03:04 +00003304}
3305
3306void Sema::CodeCompleteUsingDirective(Scope *S) {
3307 if (!CodeCompleter)
3308 return;
3309
Douglas Gregor86d9a522009-09-21 16:56:56 +00003310 // After "using namespace", we expect to see a namespace name or namespace
3311 // alias.
3312 ResultBuilder Results(*this, &ResultBuilder::IsNamespaceOrAlias);
Douglas Gregor8e0a0e42009-09-22 23:31:26 +00003313 Results.EnterNewScope();
Douglas Gregor5d2fc402010-01-14 03:27:13 +00003314 CodeCompletionDeclConsumer Consumer(Results, CurContext);
Douglas Gregor8071e422010-08-15 06:18:01 +00003315 LookupVisibleDecls(S, LookupOrdinaryName, Consumer,
3316 CodeCompleter->includeGlobals());
Douglas Gregor8e0a0e42009-09-22 23:31:26 +00003317 Results.ExitScope();
Douglas Gregore6b1bb62010-08-11 21:23:17 +00003318 HandleCodeCompleteResults(this, CodeCompleter,
Douglas Gregor8071e422010-08-15 06:18:01 +00003319 CodeCompletionContext::CCC_Namespace,
Douglas Gregore6b1bb62010-08-11 21:23:17 +00003320 Results.data(),Results.size());
Douglas Gregor49f40bd2009-09-18 19:03:04 +00003321}
3322
3323void Sema::CodeCompleteNamespaceDecl(Scope *S) {
3324 if (!CodeCompleter)
3325 return;
3326
Douglas Gregor86d9a522009-09-21 16:56:56 +00003327 ResultBuilder Results(*this, &ResultBuilder::IsNamespace);
3328 DeclContext *Ctx = (DeclContext *)S->getEntity();
3329 if (!S->getParent())
3330 Ctx = Context.getTranslationUnitDecl();
3331
3332 if (Ctx && Ctx->isFileContext()) {
3333 // We only want to see those namespaces that have already been defined
3334 // within this scope, because its likely that the user is creating an
3335 // extended namespace declaration. Keep track of the most recent
3336 // definition of each namespace.
3337 std::map<NamespaceDecl *, NamespaceDecl *> OrigToLatest;
3338 for (DeclContext::specific_decl_iterator<NamespaceDecl>
3339 NS(Ctx->decls_begin()), NSEnd(Ctx->decls_end());
3340 NS != NSEnd; ++NS)
3341 OrigToLatest[NS->getOriginalNamespace()] = *NS;
3342
3343 // Add the most recent definition (or extended definition) of each
3344 // namespace to the list of results.
Douglas Gregor8e0a0e42009-09-22 23:31:26 +00003345 Results.EnterNewScope();
Douglas Gregor86d9a522009-09-21 16:56:56 +00003346 for (std::map<NamespaceDecl *, NamespaceDecl *>::iterator
3347 NS = OrigToLatest.begin(), NSEnd = OrigToLatest.end();
3348 NS != NSEnd; ++NS)
John McCall0a2c5e22010-08-25 06:19:51 +00003349 Results.AddResult(CodeCompletionResult(NS->second, 0),
Douglas Gregor608300b2010-01-14 16:14:35 +00003350 CurContext, 0, false);
Douglas Gregor8e0a0e42009-09-22 23:31:26 +00003351 Results.ExitScope();
Douglas Gregor86d9a522009-09-21 16:56:56 +00003352 }
3353
Douglas Gregore6b1bb62010-08-11 21:23:17 +00003354 HandleCodeCompleteResults(this, CodeCompleter,
3355 CodeCompletionContext::CCC_Other,
3356 Results.data(),Results.size());
Douglas Gregor49f40bd2009-09-18 19:03:04 +00003357}
3358
3359void Sema::CodeCompleteNamespaceAliasDecl(Scope *S) {
3360 if (!CodeCompleter)
3361 return;
3362
Douglas Gregor86d9a522009-09-21 16:56:56 +00003363 // After "namespace", we expect to see a namespace or alias.
3364 ResultBuilder Results(*this, &ResultBuilder::IsNamespaceOrAlias);
Douglas Gregor5d2fc402010-01-14 03:27:13 +00003365 CodeCompletionDeclConsumer Consumer(Results, CurContext);
Douglas Gregor8071e422010-08-15 06:18:01 +00003366 LookupVisibleDecls(S, LookupOrdinaryName, Consumer,
3367 CodeCompleter->includeGlobals());
Douglas Gregore6b1bb62010-08-11 21:23:17 +00003368 HandleCodeCompleteResults(this, CodeCompleter,
Douglas Gregor8071e422010-08-15 06:18:01 +00003369 CodeCompletionContext::CCC_Namespace,
Douglas Gregore6b1bb62010-08-11 21:23:17 +00003370 Results.data(),Results.size());
Douglas Gregor49f40bd2009-09-18 19:03:04 +00003371}
3372
Douglas Gregored8d3222009-09-18 20:05:18 +00003373void Sema::CodeCompleteOperatorName(Scope *S) {
3374 if (!CodeCompleter)
3375 return;
Douglas Gregor86d9a522009-09-21 16:56:56 +00003376
John McCall0a2c5e22010-08-25 06:19:51 +00003377 typedef CodeCompletionResult Result;
Douglas Gregor86d9a522009-09-21 16:56:56 +00003378 ResultBuilder Results(*this, &ResultBuilder::IsType);
Douglas Gregor8e0a0e42009-09-22 23:31:26 +00003379 Results.EnterNewScope();
Douglas Gregored8d3222009-09-18 20:05:18 +00003380
Douglas Gregor86d9a522009-09-21 16:56:56 +00003381 // Add the names of overloadable operators.
3382#define OVERLOADED_OPERATOR(Name,Spelling,Token,Unary,Binary,MemberOnly) \
3383 if (std::strcmp(Spelling, "?")) \
Douglas Gregora4477812010-01-14 16:01:26 +00003384 Results.AddResult(Result(Spelling));
Douglas Gregor86d9a522009-09-21 16:56:56 +00003385#include "clang/Basic/OperatorKinds.def"
3386
3387 // Add any type names visible from the current scope
Douglas Gregor45bcd432010-01-14 03:21:49 +00003388 Results.allowNestedNameSpecifiers();
Douglas Gregor5d2fc402010-01-14 03:27:13 +00003389 CodeCompletionDeclConsumer Consumer(Results, CurContext);
Douglas Gregor8071e422010-08-15 06:18:01 +00003390 LookupVisibleDecls(S, LookupOrdinaryName, Consumer,
3391 CodeCompleter->includeGlobals());
Douglas Gregor86d9a522009-09-21 16:56:56 +00003392
3393 // Add any type specifiers
Douglas Gregorbca403c2010-01-13 23:51:12 +00003394 AddTypeSpecifierResults(getLangOptions(), Results);
Douglas Gregor8e0a0e42009-09-22 23:31:26 +00003395 Results.ExitScope();
Douglas Gregor86d9a522009-09-21 16:56:56 +00003396
Douglas Gregore6b1bb62010-08-11 21:23:17 +00003397 HandleCodeCompleteResults(this, CodeCompleter,
Douglas Gregor8071e422010-08-15 06:18:01 +00003398 CodeCompletionContext::CCC_Type,
Douglas Gregore6b1bb62010-08-11 21:23:17 +00003399 Results.data(),Results.size());
Douglas Gregored8d3222009-09-18 20:05:18 +00003400}
Douglas Gregor49f40bd2009-09-18 19:03:04 +00003401
Douglas Gregor0133f522010-08-28 00:00:50 +00003402void Sema::CodeCompleteConstructorInitializer(Decl *ConstructorD,
3403 CXXBaseOrMemberInitializer** Initializers,
3404 unsigned NumInitializers) {
3405 CXXConstructorDecl *Constructor
3406 = static_cast<CXXConstructorDecl *>(ConstructorD);
3407 if (!Constructor)
3408 return;
3409
3410 ResultBuilder Results(*this);
3411 Results.EnterNewScope();
3412
3413 // Fill in any already-initialized fields or base classes.
3414 llvm::SmallPtrSet<FieldDecl *, 4> InitializedFields;
3415 llvm::SmallPtrSet<CanQualType, 4> InitializedBases;
3416 for (unsigned I = 0; I != NumInitializers; ++I) {
3417 if (Initializers[I]->isBaseInitializer())
3418 InitializedBases.insert(
3419 Context.getCanonicalType(QualType(Initializers[I]->getBaseClass(), 0)));
3420 else
3421 InitializedFields.insert(cast<FieldDecl>(Initializers[I]->getMember()));
3422 }
3423
3424 // Add completions for base classes.
Douglas Gregor0c431c82010-08-29 19:27:27 +00003425 bool SawLastInitializer = (NumInitializers == 0);
Douglas Gregor0133f522010-08-28 00:00:50 +00003426 CXXRecordDecl *ClassDecl = Constructor->getParent();
3427 for (CXXRecordDecl::base_class_iterator Base = ClassDecl->bases_begin(),
3428 BaseEnd = ClassDecl->bases_end();
3429 Base != BaseEnd; ++Base) {
Douglas Gregor0c431c82010-08-29 19:27:27 +00003430 if (!InitializedBases.insert(Context.getCanonicalType(Base->getType()))) {
3431 SawLastInitializer
3432 = NumInitializers > 0 &&
3433 Initializers[NumInitializers - 1]->isBaseInitializer() &&
3434 Context.hasSameUnqualifiedType(Base->getType(),
3435 QualType(Initializers[NumInitializers - 1]->getBaseClass(), 0));
Douglas Gregor0133f522010-08-28 00:00:50 +00003436 continue;
Douglas Gregor0c431c82010-08-29 19:27:27 +00003437 }
Douglas Gregor0133f522010-08-28 00:00:50 +00003438
3439 CodeCompletionString *Pattern = new CodeCompletionString;
3440 Pattern->AddTypedTextChunk(
3441 Base->getType().getAsString(Context.PrintingPolicy));
3442 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
3443 Pattern->AddPlaceholderChunk("args");
3444 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
Douglas Gregor0c431c82010-08-29 19:27:27 +00003445 Results.AddResult(CodeCompletionResult(Pattern,
3446 SawLastInitializer? CCP_NextInitializer
3447 : CCP_MemberDeclaration));
3448 SawLastInitializer = false;
Douglas Gregor0133f522010-08-28 00:00:50 +00003449 }
3450
3451 // Add completions for virtual base classes.
3452 for (CXXRecordDecl::base_class_iterator Base = ClassDecl->vbases_begin(),
3453 BaseEnd = ClassDecl->vbases_end();
3454 Base != BaseEnd; ++Base) {
Douglas Gregor0c431c82010-08-29 19:27:27 +00003455 if (!InitializedBases.insert(Context.getCanonicalType(Base->getType()))) {
3456 SawLastInitializer
3457 = NumInitializers > 0 &&
3458 Initializers[NumInitializers - 1]->isBaseInitializer() &&
3459 Context.hasSameUnqualifiedType(Base->getType(),
3460 QualType(Initializers[NumInitializers - 1]->getBaseClass(), 0));
Douglas Gregor0133f522010-08-28 00:00:50 +00003461 continue;
Douglas Gregor0c431c82010-08-29 19:27:27 +00003462 }
Douglas Gregor0133f522010-08-28 00:00:50 +00003463
3464 CodeCompletionString *Pattern = new CodeCompletionString;
3465 Pattern->AddTypedTextChunk(
3466 Base->getType().getAsString(Context.PrintingPolicy));
3467 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
3468 Pattern->AddPlaceholderChunk("args");
3469 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
Douglas Gregor0c431c82010-08-29 19:27:27 +00003470 Results.AddResult(CodeCompletionResult(Pattern,
3471 SawLastInitializer? CCP_NextInitializer
3472 : CCP_MemberDeclaration));
3473 SawLastInitializer = false;
Douglas Gregor0133f522010-08-28 00:00:50 +00003474 }
3475
3476 // Add completions for members.
3477 for (CXXRecordDecl::field_iterator Field = ClassDecl->field_begin(),
3478 FieldEnd = ClassDecl->field_end();
3479 Field != FieldEnd; ++Field) {
Douglas Gregor0c431c82010-08-29 19:27:27 +00003480 if (!InitializedFields.insert(cast<FieldDecl>(Field->getCanonicalDecl()))) {
3481 SawLastInitializer
3482 = NumInitializers > 0 &&
3483 Initializers[NumInitializers - 1]->isMemberInitializer() &&
3484 Initializers[NumInitializers - 1]->getMember() == *Field;
Douglas Gregor0133f522010-08-28 00:00:50 +00003485 continue;
Douglas Gregor0c431c82010-08-29 19:27:27 +00003486 }
Douglas Gregor0133f522010-08-28 00:00:50 +00003487
3488 if (!Field->getDeclName())
3489 continue;
3490
3491 CodeCompletionString *Pattern = new CodeCompletionString;
3492 Pattern->AddTypedTextChunk(Field->getIdentifier()->getName());
3493 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
3494 Pattern->AddPlaceholderChunk("args");
3495 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
Douglas Gregor0c431c82010-08-29 19:27:27 +00003496 Results.AddResult(CodeCompletionResult(Pattern,
3497 SawLastInitializer? CCP_NextInitializer
Douglas Gregora67e03f2010-09-09 21:42:20 +00003498 : CCP_MemberDeclaration,
3499 CXCursor_MemberRef));
Douglas Gregor0c431c82010-08-29 19:27:27 +00003500 SawLastInitializer = false;
Douglas Gregor0133f522010-08-28 00:00:50 +00003501 }
3502 Results.ExitScope();
3503
3504 HandleCodeCompleteResults(this, CodeCompleter,
3505 CodeCompletionContext::CCC_Name,
3506 Results.data(), Results.size());
3507}
3508
Douglas Gregorb6ac2452010-01-13 21:24:21 +00003509// Macro that expands to @Keyword or Keyword, depending on whether NeedAt is
3510// true or false.
3511#define OBJC_AT_KEYWORD_NAME(NeedAt,Keyword) NeedAt? "@" #Keyword : #Keyword
Douglas Gregorbca403c2010-01-13 23:51:12 +00003512static void AddObjCImplementationResults(const LangOptions &LangOpts,
Douglas Gregorb6ac2452010-01-13 21:24:21 +00003513 ResultBuilder &Results,
3514 bool NeedAt) {
John McCall0a2c5e22010-08-25 06:19:51 +00003515 typedef CodeCompletionResult Result;
Douglas Gregorb6ac2452010-01-13 21:24:21 +00003516 // Since we have an implementation, we can end it.
Douglas Gregora4477812010-01-14 16:01:26 +00003517 Results.AddResult(Result(OBJC_AT_KEYWORD_NAME(NeedAt,end)));
Douglas Gregorb6ac2452010-01-13 21:24:21 +00003518
3519 CodeCompletionString *Pattern = 0;
3520 if (LangOpts.ObjC2) {
3521 // @dynamic
3522 Pattern = new CodeCompletionString;
3523 Pattern->AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt,dynamic));
3524 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
3525 Pattern->AddPlaceholderChunk("property");
Douglas Gregora4477812010-01-14 16:01:26 +00003526 Results.AddResult(Result(Pattern));
Douglas Gregorb6ac2452010-01-13 21:24:21 +00003527
3528 // @synthesize
3529 Pattern = new CodeCompletionString;
3530 Pattern->AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt,synthesize));
3531 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
3532 Pattern->AddPlaceholderChunk("property");
Douglas Gregora4477812010-01-14 16:01:26 +00003533 Results.AddResult(Result(Pattern));
Douglas Gregorb6ac2452010-01-13 21:24:21 +00003534 }
3535}
3536
Douglas Gregorbca403c2010-01-13 23:51:12 +00003537static void AddObjCInterfaceResults(const LangOptions &LangOpts,
Douglas Gregorb6ac2452010-01-13 21:24:21 +00003538 ResultBuilder &Results,
3539 bool NeedAt) {
John McCall0a2c5e22010-08-25 06:19:51 +00003540 typedef CodeCompletionResult Result;
Douglas Gregorb6ac2452010-01-13 21:24:21 +00003541
3542 // Since we have an interface or protocol, we can end it.
Douglas Gregora4477812010-01-14 16:01:26 +00003543 Results.AddResult(Result(OBJC_AT_KEYWORD_NAME(NeedAt,end)));
Douglas Gregorb6ac2452010-01-13 21:24:21 +00003544
3545 if (LangOpts.ObjC2) {
3546 // @property
Douglas Gregora4477812010-01-14 16:01:26 +00003547 Results.AddResult(Result(OBJC_AT_KEYWORD_NAME(NeedAt,property)));
Douglas Gregorb6ac2452010-01-13 21:24:21 +00003548
3549 // @required
Douglas Gregora4477812010-01-14 16:01:26 +00003550 Results.AddResult(Result(OBJC_AT_KEYWORD_NAME(NeedAt,required)));
Douglas Gregorb6ac2452010-01-13 21:24:21 +00003551
3552 // @optional
Douglas Gregora4477812010-01-14 16:01:26 +00003553 Results.AddResult(Result(OBJC_AT_KEYWORD_NAME(NeedAt,optional)));
Douglas Gregorb6ac2452010-01-13 21:24:21 +00003554 }
3555}
3556
Douglas Gregorbca403c2010-01-13 23:51:12 +00003557static void AddObjCTopLevelResults(ResultBuilder &Results, bool NeedAt) {
John McCall0a2c5e22010-08-25 06:19:51 +00003558 typedef CodeCompletionResult Result;
Douglas Gregorb6ac2452010-01-13 21:24:21 +00003559 CodeCompletionString *Pattern = 0;
3560
3561 // @class name ;
3562 Pattern = new CodeCompletionString;
3563 Pattern->AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt,class));
3564 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
Douglas Gregorc8bddde2010-05-28 00:22:41 +00003565 Pattern->AddPlaceholderChunk("name");
Douglas Gregora4477812010-01-14 16:01:26 +00003566 Results.AddResult(Result(Pattern));
Douglas Gregorb6ac2452010-01-13 21:24:21 +00003567
Douglas Gregorc8bddde2010-05-28 00:22:41 +00003568 if (Results.includeCodePatterns()) {
3569 // @interface name
3570 // FIXME: Could introduce the whole pattern, including superclasses and
3571 // such.
3572 Pattern = new CodeCompletionString;
3573 Pattern->AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt,interface));
3574 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
3575 Pattern->AddPlaceholderChunk("class");
3576 Results.AddResult(Result(Pattern));
Douglas Gregorb6ac2452010-01-13 21:24:21 +00003577
Douglas Gregorc8bddde2010-05-28 00:22:41 +00003578 // @protocol name
3579 Pattern = new CodeCompletionString;
3580 Pattern->AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt,protocol));
3581 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
3582 Pattern->AddPlaceholderChunk("protocol");
3583 Results.AddResult(Result(Pattern));
3584
3585 // @implementation name
3586 Pattern = new CodeCompletionString;
3587 Pattern->AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt,implementation));
3588 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
3589 Pattern->AddPlaceholderChunk("class");
3590 Results.AddResult(Result(Pattern));
3591 }
Douglas Gregorb6ac2452010-01-13 21:24:21 +00003592
3593 // @compatibility_alias name
3594 Pattern = new CodeCompletionString;
3595 Pattern->AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt,compatibility_alias));
3596 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
3597 Pattern->AddPlaceholderChunk("alias");
3598 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
3599 Pattern->AddPlaceholderChunk("class");
Douglas Gregora4477812010-01-14 16:01:26 +00003600 Results.AddResult(Result(Pattern));
Douglas Gregorb6ac2452010-01-13 21:24:21 +00003601}
3602
John McCalld226f652010-08-21 09:40:31 +00003603void Sema::CodeCompleteObjCAtDirective(Scope *S, Decl *ObjCImpDecl,
Douglas Gregorc464ae82009-12-07 09:27:33 +00003604 bool InInterface) {
John McCall0a2c5e22010-08-25 06:19:51 +00003605 typedef CodeCompletionResult Result;
Douglas Gregorc464ae82009-12-07 09:27:33 +00003606 ResultBuilder Results(*this);
3607 Results.EnterNewScope();
Douglas Gregorb6ac2452010-01-13 21:24:21 +00003608 if (ObjCImpDecl)
Douglas Gregorbca403c2010-01-13 23:51:12 +00003609 AddObjCImplementationResults(getLangOptions(), Results, false);
Douglas Gregorb6ac2452010-01-13 21:24:21 +00003610 else if (InInterface)
Douglas Gregorbca403c2010-01-13 23:51:12 +00003611 AddObjCInterfaceResults(getLangOptions(), Results, false);
Douglas Gregorb6ac2452010-01-13 21:24:21 +00003612 else
Douglas Gregorbca403c2010-01-13 23:51:12 +00003613 AddObjCTopLevelResults(Results, false);
Douglas Gregorc464ae82009-12-07 09:27:33 +00003614 Results.ExitScope();
Douglas Gregore6b1bb62010-08-11 21:23:17 +00003615 HandleCodeCompleteResults(this, CodeCompleter,
3616 CodeCompletionContext::CCC_Other,
3617 Results.data(),Results.size());
Douglas Gregorc464ae82009-12-07 09:27:33 +00003618}
3619
Douglas Gregorbca403c2010-01-13 23:51:12 +00003620static void AddObjCExpressionResults(ResultBuilder &Results, bool NeedAt) {
John McCall0a2c5e22010-08-25 06:19:51 +00003621 typedef CodeCompletionResult Result;
Douglas Gregor9a0c85e2009-12-07 09:51:25 +00003622 CodeCompletionString *Pattern = 0;
3623
3624 // @encode ( type-name )
3625 Pattern = new CodeCompletionString;
Douglas Gregorb6ac2452010-01-13 21:24:21 +00003626 Pattern->AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt,encode));
Douglas Gregor9a0c85e2009-12-07 09:51:25 +00003627 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
3628 Pattern->AddPlaceholderChunk("type-name");
3629 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
Douglas Gregora4477812010-01-14 16:01:26 +00003630 Results.AddResult(Result(Pattern));
Douglas Gregor9a0c85e2009-12-07 09:51:25 +00003631
3632 // @protocol ( protocol-name )
3633 Pattern = new CodeCompletionString;
Douglas Gregorb6ac2452010-01-13 21:24:21 +00003634 Pattern->AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt,protocol));
Douglas Gregor9a0c85e2009-12-07 09:51:25 +00003635 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
3636 Pattern->AddPlaceholderChunk("protocol-name");
3637 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
Douglas Gregora4477812010-01-14 16:01:26 +00003638 Results.AddResult(Result(Pattern));
Douglas Gregor9a0c85e2009-12-07 09:51:25 +00003639
3640 // @selector ( selector )
3641 Pattern = new CodeCompletionString;
Douglas Gregorb6ac2452010-01-13 21:24:21 +00003642 Pattern->AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt,selector));
Douglas Gregor9a0c85e2009-12-07 09:51:25 +00003643 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
3644 Pattern->AddPlaceholderChunk("selector");
3645 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
Douglas Gregora4477812010-01-14 16:01:26 +00003646 Results.AddResult(Result(Pattern));
Douglas Gregor9a0c85e2009-12-07 09:51:25 +00003647}
3648
Douglas Gregorbca403c2010-01-13 23:51:12 +00003649static void AddObjCStatementResults(ResultBuilder &Results, bool NeedAt) {
John McCall0a2c5e22010-08-25 06:19:51 +00003650 typedef CodeCompletionResult Result;
Douglas Gregor9a0c85e2009-12-07 09:51:25 +00003651 CodeCompletionString *Pattern = 0;
Douglas Gregorb6ac2452010-01-13 21:24:21 +00003652
Douglas Gregorc8bddde2010-05-28 00:22:41 +00003653 if (Results.includeCodePatterns()) {
3654 // @try { statements } @catch ( declaration ) { statements } @finally
3655 // { statements }
3656 Pattern = new CodeCompletionString;
3657 Pattern->AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt,try));
3658 Pattern->AddChunk(CodeCompletionString::CK_LeftBrace);
3659 Pattern->AddPlaceholderChunk("statements");
3660 Pattern->AddChunk(CodeCompletionString::CK_RightBrace);
3661 Pattern->AddTextChunk("@catch");
3662 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
3663 Pattern->AddPlaceholderChunk("parameter");
3664 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
3665 Pattern->AddChunk(CodeCompletionString::CK_LeftBrace);
3666 Pattern->AddPlaceholderChunk("statements");
3667 Pattern->AddChunk(CodeCompletionString::CK_RightBrace);
3668 Pattern->AddTextChunk("@finally");
3669 Pattern->AddChunk(CodeCompletionString::CK_LeftBrace);
3670 Pattern->AddPlaceholderChunk("statements");
3671 Pattern->AddChunk(CodeCompletionString::CK_RightBrace);
3672 Results.AddResult(Result(Pattern));
3673 }
Douglas Gregorb6ac2452010-01-13 21:24:21 +00003674
Douglas Gregor9a0c85e2009-12-07 09:51:25 +00003675 // @throw
3676 Pattern = new CodeCompletionString;
Douglas Gregorb6ac2452010-01-13 21:24:21 +00003677 Pattern->AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt,throw));
Douglas Gregor834389b2010-01-12 06:38:28 +00003678 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
Douglas Gregor9a0c85e2009-12-07 09:51:25 +00003679 Pattern->AddPlaceholderChunk("expression");
Douglas Gregora4477812010-01-14 16:01:26 +00003680 Results.AddResult(Result(Pattern));
Douglas Gregorb6ac2452010-01-13 21:24:21 +00003681
Douglas Gregorc8bddde2010-05-28 00:22:41 +00003682 if (Results.includeCodePatterns()) {
3683 // @synchronized ( expression ) { statements }
3684 Pattern = new CodeCompletionString;
3685 Pattern->AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt,synchronized));
3686 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
3687 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
3688 Pattern->AddPlaceholderChunk("expression");
3689 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
3690 Pattern->AddChunk(CodeCompletionString::CK_LeftBrace);
3691 Pattern->AddPlaceholderChunk("statements");
3692 Pattern->AddChunk(CodeCompletionString::CK_RightBrace);
3693 Results.AddResult(Result(Pattern));
3694 }
Douglas Gregorb6ac2452010-01-13 21:24:21 +00003695}
Douglas Gregor9a0c85e2009-12-07 09:51:25 +00003696
Douglas Gregorbca403c2010-01-13 23:51:12 +00003697static void AddObjCVisibilityResults(const LangOptions &LangOpts,
Douglas Gregorc38c3e12010-01-13 21:54:15 +00003698 ResultBuilder &Results,
3699 bool NeedAt) {
John McCall0a2c5e22010-08-25 06:19:51 +00003700 typedef CodeCompletionResult Result;
Douglas Gregora4477812010-01-14 16:01:26 +00003701 Results.AddResult(Result(OBJC_AT_KEYWORD_NAME(NeedAt,private)));
3702 Results.AddResult(Result(OBJC_AT_KEYWORD_NAME(NeedAt,protected)));
3703 Results.AddResult(Result(OBJC_AT_KEYWORD_NAME(NeedAt,public)));
Douglas Gregorc38c3e12010-01-13 21:54:15 +00003704 if (LangOpts.ObjC2)
Douglas Gregora4477812010-01-14 16:01:26 +00003705 Results.AddResult(Result(OBJC_AT_KEYWORD_NAME(NeedAt,package)));
Douglas Gregorc38c3e12010-01-13 21:54:15 +00003706}
3707
3708void Sema::CodeCompleteObjCAtVisibility(Scope *S) {
3709 ResultBuilder Results(*this);
3710 Results.EnterNewScope();
Douglas Gregorbca403c2010-01-13 23:51:12 +00003711 AddObjCVisibilityResults(getLangOptions(), Results, false);
Douglas Gregorc38c3e12010-01-13 21:54:15 +00003712 Results.ExitScope();
Douglas Gregore6b1bb62010-08-11 21:23:17 +00003713 HandleCodeCompleteResults(this, CodeCompleter,
3714 CodeCompletionContext::CCC_Other,
3715 Results.data(),Results.size());
Douglas Gregorc38c3e12010-01-13 21:54:15 +00003716}
3717
3718void Sema::CodeCompleteObjCAtStatement(Scope *S) {
Douglas Gregorb6ac2452010-01-13 21:24:21 +00003719 ResultBuilder Results(*this);
3720 Results.EnterNewScope();
Douglas Gregorbca403c2010-01-13 23:51:12 +00003721 AddObjCStatementResults(Results, false);
3722 AddObjCExpressionResults(Results, false);
Douglas Gregor9a0c85e2009-12-07 09:51:25 +00003723 Results.ExitScope();
Douglas Gregore6b1bb62010-08-11 21:23:17 +00003724 HandleCodeCompleteResults(this, CodeCompleter,
3725 CodeCompletionContext::CCC_Other,
3726 Results.data(),Results.size());
Douglas Gregor9a0c85e2009-12-07 09:51:25 +00003727}
3728
3729void Sema::CodeCompleteObjCAtExpression(Scope *S) {
3730 ResultBuilder Results(*this);
3731 Results.EnterNewScope();
Douglas Gregorbca403c2010-01-13 23:51:12 +00003732 AddObjCExpressionResults(Results, false);
Douglas Gregor9a0c85e2009-12-07 09:51:25 +00003733 Results.ExitScope();
Douglas Gregore6b1bb62010-08-11 21:23:17 +00003734 HandleCodeCompleteResults(this, CodeCompleter,
3735 CodeCompletionContext::CCC_Other,
3736 Results.data(),Results.size());
Douglas Gregor9a0c85e2009-12-07 09:51:25 +00003737}
3738
Douglas Gregor988358f2009-11-19 00:14:45 +00003739/// \brief Determine whether the addition of the given flag to an Objective-C
3740/// property's attributes will cause a conflict.
3741static bool ObjCPropertyFlagConflicts(unsigned Attributes, unsigned NewFlag) {
3742 // Check if we've already added this flag.
3743 if (Attributes & NewFlag)
3744 return true;
3745
3746 Attributes |= NewFlag;
3747
3748 // Check for collisions with "readonly".
3749 if ((Attributes & ObjCDeclSpec::DQ_PR_readonly) &&
3750 (Attributes & (ObjCDeclSpec::DQ_PR_readwrite |
3751 ObjCDeclSpec::DQ_PR_assign |
3752 ObjCDeclSpec::DQ_PR_copy |
3753 ObjCDeclSpec::DQ_PR_retain)))
3754 return true;
3755
3756 // Check for more than one of { assign, copy, retain }.
3757 unsigned AssignCopyRetMask = Attributes & (ObjCDeclSpec::DQ_PR_assign |
3758 ObjCDeclSpec::DQ_PR_copy |
3759 ObjCDeclSpec::DQ_PR_retain);
3760 if (AssignCopyRetMask &&
3761 AssignCopyRetMask != ObjCDeclSpec::DQ_PR_assign &&
3762 AssignCopyRetMask != ObjCDeclSpec::DQ_PR_copy &&
3763 AssignCopyRetMask != ObjCDeclSpec::DQ_PR_retain)
3764 return true;
3765
3766 return false;
3767}
3768
Douglas Gregora93b1082009-11-18 23:08:07 +00003769void Sema::CodeCompleteObjCPropertyFlags(Scope *S, ObjCDeclSpec &ODS) {
Steve Naroffece8e712009-10-08 21:55:05 +00003770 if (!CodeCompleter)
3771 return;
Douglas Gregord3c68542009-11-19 01:08:35 +00003772
Steve Naroffece8e712009-10-08 21:55:05 +00003773 unsigned Attributes = ODS.getPropertyAttributes();
3774
John McCall0a2c5e22010-08-25 06:19:51 +00003775 typedef CodeCompletionResult Result;
Steve Naroffece8e712009-10-08 21:55:05 +00003776 ResultBuilder Results(*this);
3777 Results.EnterNewScope();
Douglas Gregor988358f2009-11-19 00:14:45 +00003778 if (!ObjCPropertyFlagConflicts(Attributes, ObjCDeclSpec::DQ_PR_readonly))
John McCall0a2c5e22010-08-25 06:19:51 +00003779 Results.AddResult(CodeCompletionResult("readonly"));
Douglas Gregor988358f2009-11-19 00:14:45 +00003780 if (!ObjCPropertyFlagConflicts(Attributes, ObjCDeclSpec::DQ_PR_assign))
John McCall0a2c5e22010-08-25 06:19:51 +00003781 Results.AddResult(CodeCompletionResult("assign"));
Douglas Gregor988358f2009-11-19 00:14:45 +00003782 if (!ObjCPropertyFlagConflicts(Attributes, ObjCDeclSpec::DQ_PR_readwrite))
John McCall0a2c5e22010-08-25 06:19:51 +00003783 Results.AddResult(CodeCompletionResult("readwrite"));
Douglas Gregor988358f2009-11-19 00:14:45 +00003784 if (!ObjCPropertyFlagConflicts(Attributes, ObjCDeclSpec::DQ_PR_retain))
John McCall0a2c5e22010-08-25 06:19:51 +00003785 Results.AddResult(CodeCompletionResult("retain"));
Douglas Gregor988358f2009-11-19 00:14:45 +00003786 if (!ObjCPropertyFlagConflicts(Attributes, ObjCDeclSpec::DQ_PR_copy))
John McCall0a2c5e22010-08-25 06:19:51 +00003787 Results.AddResult(CodeCompletionResult("copy"));
Douglas Gregor988358f2009-11-19 00:14:45 +00003788 if (!ObjCPropertyFlagConflicts(Attributes, ObjCDeclSpec::DQ_PR_nonatomic))
John McCall0a2c5e22010-08-25 06:19:51 +00003789 Results.AddResult(CodeCompletionResult("nonatomic"));
Douglas Gregor988358f2009-11-19 00:14:45 +00003790 if (!ObjCPropertyFlagConflicts(Attributes, ObjCDeclSpec::DQ_PR_setter)) {
Douglas Gregor54f01612009-11-19 00:01:57 +00003791 CodeCompletionString *Setter = new CodeCompletionString;
3792 Setter->AddTypedTextChunk("setter");
3793 Setter->AddTextChunk(" = ");
3794 Setter->AddPlaceholderChunk("method");
John McCall0a2c5e22010-08-25 06:19:51 +00003795 Results.AddResult(CodeCompletionResult(Setter));
Douglas Gregor54f01612009-11-19 00:01:57 +00003796 }
Douglas Gregor988358f2009-11-19 00:14:45 +00003797 if (!ObjCPropertyFlagConflicts(Attributes, ObjCDeclSpec::DQ_PR_getter)) {
Douglas Gregor54f01612009-11-19 00:01:57 +00003798 CodeCompletionString *Getter = new CodeCompletionString;
3799 Getter->AddTypedTextChunk("getter");
3800 Getter->AddTextChunk(" = ");
3801 Getter->AddPlaceholderChunk("method");
John McCall0a2c5e22010-08-25 06:19:51 +00003802 Results.AddResult(CodeCompletionResult(Getter));
Douglas Gregor54f01612009-11-19 00:01:57 +00003803 }
Steve Naroffece8e712009-10-08 21:55:05 +00003804 Results.ExitScope();
Douglas Gregore6b1bb62010-08-11 21:23:17 +00003805 HandleCodeCompleteResults(this, CodeCompleter,
3806 CodeCompletionContext::CCC_Other,
3807 Results.data(),Results.size());
Steve Naroffece8e712009-10-08 21:55:05 +00003808}
Steve Naroffc4df6d22009-11-07 02:08:14 +00003809
Douglas Gregor4ad96852009-11-19 07:41:15 +00003810/// \brief Descripts the kind of Objective-C method that we want to find
3811/// via code completion.
3812enum ObjCMethodKind {
3813 MK_Any, //< Any kind of method, provided it means other specified criteria.
3814 MK_ZeroArgSelector, //< Zero-argument (unary) selector.
3815 MK_OneArgSelector //< One-argument selector.
3816};
3817
Douglas Gregor458433d2010-08-26 15:07:07 +00003818static bool isAcceptableObjCSelector(Selector Sel,
3819 ObjCMethodKind WantKind,
3820 IdentifierInfo **SelIdents,
3821 unsigned NumSelIdents) {
3822 if (NumSelIdents > Sel.getNumArgs())
3823 return false;
3824
3825 switch (WantKind) {
3826 case MK_Any: break;
3827 case MK_ZeroArgSelector: return Sel.isUnarySelector();
3828 case MK_OneArgSelector: return Sel.getNumArgs() == 1;
3829 }
3830
3831 for (unsigned I = 0; I != NumSelIdents; ++I)
3832 if (SelIdents[I] != Sel.getIdentifierInfoForSlot(I))
3833 return false;
3834
3835 return true;
3836}
3837
Douglas Gregor4ad96852009-11-19 07:41:15 +00003838static bool isAcceptableObjCMethod(ObjCMethodDecl *Method,
3839 ObjCMethodKind WantKind,
3840 IdentifierInfo **SelIdents,
3841 unsigned NumSelIdents) {
Douglas Gregor458433d2010-08-26 15:07:07 +00003842 return isAcceptableObjCSelector(Method->getSelector(), WantKind, SelIdents,
3843 NumSelIdents);
Douglas Gregor4ad96852009-11-19 07:41:15 +00003844}
Douglas Gregord36adf52010-09-16 16:06:31 +00003845
3846namespace {
3847 /// \brief A set of selectors, which is used to avoid introducing multiple
3848 /// completions with the same selector into the result set.
3849 typedef llvm::SmallPtrSet<Selector, 16> VisitedSelectorSet;
3850}
3851
Douglas Gregor36ecb042009-11-17 23:22:23 +00003852/// \brief Add all of the Objective-C methods in the given Objective-C
3853/// container to the set of results.
3854///
3855/// The container will be a class, protocol, category, or implementation of
3856/// any of the above. This mether will recurse to include methods from
3857/// the superclasses of classes along with their categories, protocols, and
3858/// implementations.
3859///
3860/// \param Container the container in which we'll look to find methods.
3861///
3862/// \param WantInstance whether to add instance methods (only); if false, this
3863/// routine will add factory methods (only).
3864///
3865/// \param CurContext the context in which we're performing the lookup that
3866/// finds methods.
3867///
3868/// \param Results the structure into which we'll add results.
3869static void AddObjCMethods(ObjCContainerDecl *Container,
3870 bool WantInstanceMethods,
Douglas Gregor4ad96852009-11-19 07:41:15 +00003871 ObjCMethodKind WantKind,
Douglas Gregord3c68542009-11-19 01:08:35 +00003872 IdentifierInfo **SelIdents,
3873 unsigned NumSelIdents,
Douglas Gregor36ecb042009-11-17 23:22:23 +00003874 DeclContext *CurContext,
Douglas Gregord36adf52010-09-16 16:06:31 +00003875 VisitedSelectorSet &Selectors,
Douglas Gregor408be5a2010-08-25 01:08:01 +00003876 ResultBuilder &Results,
3877 bool InOriginalClass = true) {
John McCall0a2c5e22010-08-25 06:19:51 +00003878 typedef CodeCompletionResult Result;
Douglas Gregor36ecb042009-11-17 23:22:23 +00003879 for (ObjCContainerDecl::method_iterator M = Container->meth_begin(),
3880 MEnd = Container->meth_end();
3881 M != MEnd; ++M) {
Douglas Gregord3c68542009-11-19 01:08:35 +00003882 if ((*M)->isInstanceMethod() == WantInstanceMethods) {
3883 // Check whether the selector identifiers we've been given are a
3884 // subset of the identifiers for this particular method.
Douglas Gregor4ad96852009-11-19 07:41:15 +00003885 if (!isAcceptableObjCMethod(*M, WantKind, SelIdents, NumSelIdents))
Douglas Gregord3c68542009-11-19 01:08:35 +00003886 continue;
Douglas Gregor4ad96852009-11-19 07:41:15 +00003887
Douglas Gregord36adf52010-09-16 16:06:31 +00003888 if (!Selectors.insert((*M)->getSelector()))
3889 continue;
3890
Douglas Gregord3c68542009-11-19 01:08:35 +00003891 Result R = Result(*M, 0);
3892 R.StartParameter = NumSelIdents;
Douglas Gregor4ad96852009-11-19 07:41:15 +00003893 R.AllParametersAreInformative = (WantKind != MK_Any);
Douglas Gregor408be5a2010-08-25 01:08:01 +00003894 if (!InOriginalClass)
3895 R.Priority += CCD_InBaseClass;
Douglas Gregord3c68542009-11-19 01:08:35 +00003896 Results.MaybeAddResult(R, CurContext);
3897 }
Douglas Gregor36ecb042009-11-17 23:22:23 +00003898 }
3899
Douglas Gregore396c7b2010-09-16 15:34:59 +00003900 // Visit the protocols of protocols.
3901 if (ObjCProtocolDecl *Protocol = dyn_cast<ObjCProtocolDecl>(Container)) {
3902 const ObjCList<ObjCProtocolDecl> &Protocols
3903 = Protocol->getReferencedProtocols();
3904 for (ObjCList<ObjCProtocolDecl>::iterator I = Protocols.begin(),
3905 E = Protocols.end();
3906 I != E; ++I)
3907 AddObjCMethods(*I, WantInstanceMethods, WantKind, SelIdents, NumSelIdents,
Douglas Gregord36adf52010-09-16 16:06:31 +00003908 CurContext, Selectors, Results, false);
Douglas Gregore396c7b2010-09-16 15:34:59 +00003909 }
3910
Douglas Gregor36ecb042009-11-17 23:22:23 +00003911 ObjCInterfaceDecl *IFace = dyn_cast<ObjCInterfaceDecl>(Container);
3912 if (!IFace)
3913 return;
3914
3915 // Add methods in protocols.
3916 const ObjCList<ObjCProtocolDecl> &Protocols= IFace->getReferencedProtocols();
3917 for (ObjCList<ObjCProtocolDecl>::iterator I = Protocols.begin(),
3918 E = Protocols.end();
3919 I != E; ++I)
Douglas Gregor4ad96852009-11-19 07:41:15 +00003920 AddObjCMethods(*I, WantInstanceMethods, WantKind, SelIdents, NumSelIdents,
Douglas Gregord36adf52010-09-16 16:06:31 +00003921 CurContext, Selectors, Results, false);
Douglas Gregor36ecb042009-11-17 23:22:23 +00003922
3923 // Add methods in categories.
3924 for (ObjCCategoryDecl *CatDecl = IFace->getCategoryList(); CatDecl;
3925 CatDecl = CatDecl->getNextClassCategory()) {
Douglas Gregor4ad96852009-11-19 07:41:15 +00003926 AddObjCMethods(CatDecl, WantInstanceMethods, WantKind, SelIdents,
Douglas Gregord36adf52010-09-16 16:06:31 +00003927 NumSelIdents, CurContext, Selectors, Results,
3928 InOriginalClass);
Douglas Gregor36ecb042009-11-17 23:22:23 +00003929
3930 // Add a categories protocol methods.
3931 const ObjCList<ObjCProtocolDecl> &Protocols
3932 = CatDecl->getReferencedProtocols();
3933 for (ObjCList<ObjCProtocolDecl>::iterator I = Protocols.begin(),
3934 E = Protocols.end();
3935 I != E; ++I)
Douglas Gregor4ad96852009-11-19 07:41:15 +00003936 AddObjCMethods(*I, WantInstanceMethods, WantKind, SelIdents,
Douglas Gregord36adf52010-09-16 16:06:31 +00003937 NumSelIdents, CurContext, Selectors, Results, false);
Douglas Gregor36ecb042009-11-17 23:22:23 +00003938
3939 // Add methods in category implementations.
3940 if (ObjCCategoryImplDecl *Impl = CatDecl->getImplementation())
Douglas Gregor4ad96852009-11-19 07:41:15 +00003941 AddObjCMethods(Impl, WantInstanceMethods, WantKind, SelIdents,
Douglas Gregord36adf52010-09-16 16:06:31 +00003942 NumSelIdents, CurContext, Selectors, Results,
3943 InOriginalClass);
Douglas Gregor36ecb042009-11-17 23:22:23 +00003944 }
3945
3946 // Add methods in superclass.
3947 if (IFace->getSuperClass())
Douglas Gregor4ad96852009-11-19 07:41:15 +00003948 AddObjCMethods(IFace->getSuperClass(), WantInstanceMethods, WantKind,
Douglas Gregord36adf52010-09-16 16:06:31 +00003949 SelIdents, NumSelIdents, CurContext, Selectors, Results,
3950 false);
Douglas Gregor36ecb042009-11-17 23:22:23 +00003951
3952 // Add methods in our implementation, if any.
3953 if (ObjCImplementationDecl *Impl = IFace->getImplementation())
Douglas Gregor4ad96852009-11-19 07:41:15 +00003954 AddObjCMethods(Impl, WantInstanceMethods, WantKind, SelIdents,
Douglas Gregord36adf52010-09-16 16:06:31 +00003955 NumSelIdents, CurContext, Selectors, Results,
3956 InOriginalClass);
Douglas Gregor4ad96852009-11-19 07:41:15 +00003957}
3958
3959
John McCalld226f652010-08-21 09:40:31 +00003960void Sema::CodeCompleteObjCPropertyGetter(Scope *S, Decl *ClassDecl,
3961 Decl **Methods,
Douglas Gregor4ad96852009-11-19 07:41:15 +00003962 unsigned NumMethods) {
John McCall0a2c5e22010-08-25 06:19:51 +00003963 typedef CodeCompletionResult Result;
Douglas Gregor4ad96852009-11-19 07:41:15 +00003964
3965 // Try to find the interface where getters might live.
John McCalld226f652010-08-21 09:40:31 +00003966 ObjCInterfaceDecl *Class = dyn_cast_or_null<ObjCInterfaceDecl>(ClassDecl);
Douglas Gregor4ad96852009-11-19 07:41:15 +00003967 if (!Class) {
3968 if (ObjCCategoryDecl *Category
John McCalld226f652010-08-21 09:40:31 +00003969 = dyn_cast_or_null<ObjCCategoryDecl>(ClassDecl))
Douglas Gregor4ad96852009-11-19 07:41:15 +00003970 Class = Category->getClassInterface();
3971
3972 if (!Class)
3973 return;
3974 }
3975
3976 // Find all of the potential getters.
3977 ResultBuilder Results(*this);
3978 Results.EnterNewScope();
3979
3980 // FIXME: We need to do this because Objective-C methods don't get
3981 // pushed into DeclContexts early enough. Argh!
3982 for (unsigned I = 0; I != NumMethods; ++I) {
3983 if (ObjCMethodDecl *Method
John McCalld226f652010-08-21 09:40:31 +00003984 = dyn_cast_or_null<ObjCMethodDecl>(Methods[I]))
Douglas Gregor4ad96852009-11-19 07:41:15 +00003985 if (Method->isInstanceMethod() &&
3986 isAcceptableObjCMethod(Method, MK_ZeroArgSelector, 0, 0)) {
3987 Result R = Result(Method, 0);
3988 R.AllParametersAreInformative = true;
3989 Results.MaybeAddResult(R, CurContext);
3990 }
3991 }
3992
Douglas Gregord36adf52010-09-16 16:06:31 +00003993 VisitedSelectorSet Selectors;
3994 AddObjCMethods(Class, true, MK_ZeroArgSelector, 0, 0, CurContext, Selectors,
3995 Results);
Douglas Gregor4ad96852009-11-19 07:41:15 +00003996 Results.ExitScope();
Douglas Gregore6b1bb62010-08-11 21:23:17 +00003997 HandleCodeCompleteResults(this, CodeCompleter,
3998 CodeCompletionContext::CCC_Other,
3999 Results.data(),Results.size());
Douglas Gregor4ad96852009-11-19 07:41:15 +00004000}
4001
John McCalld226f652010-08-21 09:40:31 +00004002void Sema::CodeCompleteObjCPropertySetter(Scope *S, Decl *ObjCImplDecl,
4003 Decl **Methods,
Douglas Gregor4ad96852009-11-19 07:41:15 +00004004 unsigned NumMethods) {
John McCall0a2c5e22010-08-25 06:19:51 +00004005 typedef CodeCompletionResult Result;
Douglas Gregor4ad96852009-11-19 07:41:15 +00004006
4007 // Try to find the interface where setters might live.
4008 ObjCInterfaceDecl *Class
John McCalld226f652010-08-21 09:40:31 +00004009 = dyn_cast_or_null<ObjCInterfaceDecl>(ObjCImplDecl);
Douglas Gregor4ad96852009-11-19 07:41:15 +00004010 if (!Class) {
4011 if (ObjCCategoryDecl *Category
John McCalld226f652010-08-21 09:40:31 +00004012 = dyn_cast_or_null<ObjCCategoryDecl>(ObjCImplDecl))
Douglas Gregor4ad96852009-11-19 07:41:15 +00004013 Class = Category->getClassInterface();
4014
4015 if (!Class)
4016 return;
4017 }
4018
4019 // Find all of the potential getters.
4020 ResultBuilder Results(*this);
4021 Results.EnterNewScope();
4022
4023 // FIXME: We need to do this because Objective-C methods don't get
4024 // pushed into DeclContexts early enough. Argh!
4025 for (unsigned I = 0; I != NumMethods; ++I) {
4026 if (ObjCMethodDecl *Method
John McCalld226f652010-08-21 09:40:31 +00004027 = dyn_cast_or_null<ObjCMethodDecl>(Methods[I]))
Douglas Gregor4ad96852009-11-19 07:41:15 +00004028 if (Method->isInstanceMethod() &&
4029 isAcceptableObjCMethod(Method, MK_OneArgSelector, 0, 0)) {
4030 Result R = Result(Method, 0);
4031 R.AllParametersAreInformative = true;
4032 Results.MaybeAddResult(R, CurContext);
4033 }
4034 }
4035
Douglas Gregord36adf52010-09-16 16:06:31 +00004036 VisitedSelectorSet Selectors;
4037 AddObjCMethods(Class, true, MK_OneArgSelector, 0, 0, CurContext,
4038 Selectors, Results);
Douglas Gregor4ad96852009-11-19 07:41:15 +00004039
4040 Results.ExitScope();
Douglas Gregore6b1bb62010-08-11 21:23:17 +00004041 HandleCodeCompleteResults(this, CodeCompleter,
4042 CodeCompletionContext::CCC_Other,
4043 Results.data(),Results.size());
Douglas Gregor36ecb042009-11-17 23:22:23 +00004044}
4045
Douglas Gregord32b0222010-08-24 01:06:58 +00004046void Sema::CodeCompleteObjCPassingType(Scope *S, ObjCDeclSpec &DS) {
John McCall0a2c5e22010-08-25 06:19:51 +00004047 typedef CodeCompletionResult Result;
Douglas Gregord32b0222010-08-24 01:06:58 +00004048 ResultBuilder Results(*this);
4049 Results.EnterNewScope();
4050
4051 // Add context-sensitive, Objective-C parameter-passing keywords.
4052 bool AddedInOut = false;
4053 if ((DS.getObjCDeclQualifier() &
4054 (ObjCDeclSpec::DQ_In | ObjCDeclSpec::DQ_Inout)) == 0) {
4055 Results.AddResult("in");
4056 Results.AddResult("inout");
4057 AddedInOut = true;
4058 }
4059 if ((DS.getObjCDeclQualifier() &
4060 (ObjCDeclSpec::DQ_Out | ObjCDeclSpec::DQ_Inout)) == 0) {
4061 Results.AddResult("out");
4062 if (!AddedInOut)
4063 Results.AddResult("inout");
4064 }
4065 if ((DS.getObjCDeclQualifier() &
4066 (ObjCDeclSpec::DQ_Bycopy | ObjCDeclSpec::DQ_Byref |
4067 ObjCDeclSpec::DQ_Oneway)) == 0) {
4068 Results.AddResult("bycopy");
4069 Results.AddResult("byref");
4070 Results.AddResult("oneway");
4071 }
4072
4073 // Add various builtin type names and specifiers.
4074 AddOrdinaryNameResults(PCC_Type, S, *this, Results);
4075 Results.ExitScope();
4076
4077 // Add the various type names
4078 Results.setFilter(&ResultBuilder::IsOrdinaryNonValueName);
4079 CodeCompletionDeclConsumer Consumer(Results, CurContext);
4080 LookupVisibleDecls(S, LookupOrdinaryName, Consumer,
4081 CodeCompleter->includeGlobals());
4082
4083 if (CodeCompleter->includeMacros())
4084 AddMacroResults(PP, Results);
4085
4086 HandleCodeCompleteResults(this, CodeCompleter,
4087 CodeCompletionContext::CCC_Type,
4088 Results.data(), Results.size());
4089}
4090
Douglas Gregor22f56992010-04-06 19:22:33 +00004091/// \brief When we have an expression with type "id", we may assume
4092/// that it has some more-specific class type based on knowledge of
4093/// common uses of Objective-C. This routine returns that class type,
4094/// or NULL if no better result could be determined.
4095static ObjCInterfaceDecl *GetAssumedMessageSendExprType(Expr *E) {
Douglas Gregor78edf512010-09-15 16:23:04 +00004096 ObjCMessageExpr *Msg = dyn_cast_or_null<ObjCMessageExpr>(E);
Douglas Gregor22f56992010-04-06 19:22:33 +00004097 if (!Msg)
4098 return 0;
4099
4100 Selector Sel = Msg->getSelector();
4101 if (Sel.isNull())
4102 return 0;
4103
4104 IdentifierInfo *Id = Sel.getIdentifierInfoForSlot(0);
4105 if (!Id)
4106 return 0;
4107
4108 ObjCMethodDecl *Method = Msg->getMethodDecl();
4109 if (!Method)
4110 return 0;
4111
4112 // Determine the class that we're sending the message to.
Douglas Gregor04badcf2010-04-21 00:45:42 +00004113 ObjCInterfaceDecl *IFace = 0;
4114 switch (Msg->getReceiverKind()) {
4115 case ObjCMessageExpr::Class:
John McCallc12c5bb2010-05-15 11:32:37 +00004116 if (const ObjCObjectType *ObjType
4117 = Msg->getClassReceiver()->getAs<ObjCObjectType>())
4118 IFace = ObjType->getInterface();
Douglas Gregor04badcf2010-04-21 00:45:42 +00004119 break;
4120
4121 case ObjCMessageExpr::Instance: {
4122 QualType T = Msg->getInstanceReceiver()->getType();
4123 if (const ObjCObjectPointerType *Ptr = T->getAs<ObjCObjectPointerType>())
4124 IFace = Ptr->getInterfaceDecl();
4125 break;
4126 }
4127
4128 case ObjCMessageExpr::SuperInstance:
4129 case ObjCMessageExpr::SuperClass:
4130 break;
Douglas Gregor22f56992010-04-06 19:22:33 +00004131 }
4132
4133 if (!IFace)
4134 return 0;
4135
4136 ObjCInterfaceDecl *Super = IFace->getSuperClass();
4137 if (Method->isInstanceMethod())
4138 return llvm::StringSwitch<ObjCInterfaceDecl *>(Id->getName())
4139 .Case("retain", IFace)
4140 .Case("autorelease", IFace)
4141 .Case("copy", IFace)
4142 .Case("copyWithZone", IFace)
4143 .Case("mutableCopy", IFace)
4144 .Case("mutableCopyWithZone", IFace)
4145 .Case("awakeFromCoder", IFace)
4146 .Case("replacementObjectFromCoder", IFace)
4147 .Case("class", IFace)
4148 .Case("classForCoder", IFace)
4149 .Case("superclass", Super)
4150 .Default(0);
4151
4152 return llvm::StringSwitch<ObjCInterfaceDecl *>(Id->getName())
4153 .Case("new", IFace)
4154 .Case("alloc", IFace)
4155 .Case("allocWithZone", IFace)
4156 .Case("class", IFace)
4157 .Case("superclass", Super)
4158 .Default(0);
4159}
4160
Douglas Gregor03d8aec2010-08-27 15:10:57 +00004161// Add a special completion for a message send to "super", which fills in the
4162// most likely case of forwarding all of our arguments to the superclass
4163// function.
4164///
4165/// \param S The semantic analysis object.
4166///
4167/// \param S NeedSuperKeyword Whether we need to prefix this completion with
4168/// the "super" keyword. Otherwise, we just need to provide the arguments.
4169///
4170/// \param SelIdents The identifiers in the selector that have already been
4171/// provided as arguments for a send to "super".
4172///
4173/// \param NumSelIdents The number of identifiers in \p SelIdents.
4174///
4175/// \param Results The set of results to augment.
4176///
4177/// \returns the Objective-C method declaration that would be invoked by
4178/// this "super" completion. If NULL, no completion was added.
4179static ObjCMethodDecl *AddSuperSendCompletion(Sema &S, bool NeedSuperKeyword,
4180 IdentifierInfo **SelIdents,
4181 unsigned NumSelIdents,
4182 ResultBuilder &Results) {
4183 ObjCMethodDecl *CurMethod = S.getCurMethodDecl();
4184 if (!CurMethod)
4185 return 0;
4186
4187 ObjCInterfaceDecl *Class = CurMethod->getClassInterface();
4188 if (!Class)
4189 return 0;
4190
4191 // Try to find a superclass method with the same selector.
4192 ObjCMethodDecl *SuperMethod = 0;
4193 while ((Class = Class->getSuperClass()) && !SuperMethod)
4194 SuperMethod = Class->getMethod(CurMethod->getSelector(),
4195 CurMethod->isInstanceMethod());
4196
4197 if (!SuperMethod)
4198 return 0;
4199
4200 // Check whether the superclass method has the same signature.
4201 if (CurMethod->param_size() != SuperMethod->param_size() ||
4202 CurMethod->isVariadic() != SuperMethod->isVariadic())
4203 return 0;
4204
4205 for (ObjCMethodDecl::param_iterator CurP = CurMethod->param_begin(),
4206 CurPEnd = CurMethod->param_end(),
4207 SuperP = SuperMethod->param_begin();
4208 CurP != CurPEnd; ++CurP, ++SuperP) {
4209 // Make sure the parameter types are compatible.
4210 if (!S.Context.hasSameUnqualifiedType((*CurP)->getType(),
4211 (*SuperP)->getType()))
4212 return 0;
4213
4214 // Make sure we have a parameter name to forward!
4215 if (!(*CurP)->getIdentifier())
4216 return 0;
4217 }
4218
4219 // We have a superclass method. Now, form the send-to-super completion.
4220 CodeCompletionString *Pattern = new CodeCompletionString;
4221
4222 // Give this completion a return type.
4223 AddResultTypeChunk(S.Context, SuperMethod, Pattern);
4224
4225 // If we need the "super" keyword, add it (plus some spacing).
4226 if (NeedSuperKeyword) {
4227 Pattern->AddTypedTextChunk("super");
4228 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
4229 }
4230
4231 Selector Sel = CurMethod->getSelector();
4232 if (Sel.isUnarySelector()) {
4233 if (NeedSuperKeyword)
4234 Pattern->AddTextChunk(Sel.getIdentifierInfoForSlot(0)->getName());
4235 else
4236 Pattern->AddTypedTextChunk(Sel.getIdentifierInfoForSlot(0)->getName());
4237 } else {
4238 ObjCMethodDecl::param_iterator CurP = CurMethod->param_begin();
4239 for (unsigned I = 0, N = Sel.getNumArgs(); I != N; ++I, ++CurP) {
4240 if (I > NumSelIdents)
4241 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
4242
4243 if (I < NumSelIdents)
4244 Pattern->AddInformativeChunk(
4245 Sel.getIdentifierInfoForSlot(I)->getName().str() + ":");
4246 else if (NeedSuperKeyword || I > NumSelIdents) {
4247 Pattern->AddTextChunk(
4248 Sel.getIdentifierInfoForSlot(I)->getName().str() + ":");
4249 Pattern->AddPlaceholderChunk((*CurP)->getIdentifier()->getName());
4250 } else {
4251 Pattern->AddTypedTextChunk(
4252 Sel.getIdentifierInfoForSlot(I)->getName().str() + ":");
4253 Pattern->AddPlaceholderChunk((*CurP)->getIdentifier()->getName());
4254 }
4255 }
4256 }
4257
4258 Results.AddResult(CodeCompletionResult(Pattern, CCP_SuperCompletion,
4259 SuperMethod->isInstanceMethod()
4260 ? CXCursor_ObjCInstanceMethodDecl
4261 : CXCursor_ObjCClassMethodDecl));
4262 return SuperMethod;
4263}
4264
Douglas Gregor8e254cf2010-05-27 23:06:34 +00004265void Sema::CodeCompleteObjCMessageReceiver(Scope *S) {
John McCall0a2c5e22010-08-25 06:19:51 +00004266 typedef CodeCompletionResult Result;
Douglas Gregor8e254cf2010-05-27 23:06:34 +00004267 ResultBuilder Results(*this);
4268
4269 // Find anything that looks like it could be a message receiver.
4270 Results.setFilter(&ResultBuilder::IsObjCMessageReceiver);
Douglas Gregorcee9ff12010-09-20 22:39:41 +00004271 Results.setCompletionContext(CodeCompletionContext::CCC_ObjCMessageReceiver);
4272
Douglas Gregor8e254cf2010-05-27 23:06:34 +00004273 CodeCompletionDeclConsumer Consumer(Results, CurContext);
4274 Results.EnterNewScope();
Douglas Gregor8071e422010-08-15 06:18:01 +00004275 LookupVisibleDecls(S, LookupOrdinaryName, Consumer,
4276 CodeCompleter->includeGlobals());
Douglas Gregor8e254cf2010-05-27 23:06:34 +00004277
4278 // If we are in an Objective-C method inside a class that has a superclass,
4279 // add "super" as an option.
4280 if (ObjCMethodDecl *Method = getCurMethodDecl())
4281 if (ObjCInterfaceDecl *Iface = Method->getClassInterface())
Douglas Gregor03d8aec2010-08-27 15:10:57 +00004282 if (Iface->getSuperClass()) {
Douglas Gregor8e254cf2010-05-27 23:06:34 +00004283 Results.AddResult(Result("super"));
Douglas Gregor03d8aec2010-08-27 15:10:57 +00004284
4285 AddSuperSendCompletion(*this, /*NeedSuperKeyword=*/true, 0, 0, Results);
4286 }
Douglas Gregor8e254cf2010-05-27 23:06:34 +00004287
4288 Results.ExitScope();
4289
4290 if (CodeCompleter->includeMacros())
4291 AddMacroResults(PP, Results);
Douglas Gregorcee9ff12010-09-20 22:39:41 +00004292 HandleCodeCompleteResults(this, CodeCompleter, Results.getCompletionContext(),
Douglas Gregore6b1bb62010-08-11 21:23:17 +00004293 Results.data(), Results.size());
Douglas Gregor8e254cf2010-05-27 23:06:34 +00004294
4295}
4296
Douglas Gregor2725ca82010-04-21 19:57:20 +00004297void Sema::CodeCompleteObjCSuperMessage(Scope *S, SourceLocation SuperLoc,
4298 IdentifierInfo **SelIdents,
Douglas Gregor70c5ac72010-09-20 23:34:21 +00004299 unsigned NumSelIdents,
4300 bool AtArgumentExpression) {
Douglas Gregor2725ca82010-04-21 19:57:20 +00004301 ObjCInterfaceDecl *CDecl = 0;
4302 if (ObjCMethodDecl *CurMethod = getCurMethodDecl()) {
4303 // Figure out which interface we're in.
4304 CDecl = CurMethod->getClassInterface();
4305 if (!CDecl)
4306 return;
4307
4308 // Find the superclass of this class.
4309 CDecl = CDecl->getSuperClass();
4310 if (!CDecl)
4311 return;
4312
4313 if (CurMethod->isInstanceMethod()) {
4314 // We are inside an instance method, which means that the message
4315 // send [super ...] is actually calling an instance method on the
4316 // current object. Build the super expression and handle this like
4317 // an instance method.
4318 QualType SuperTy = Context.getObjCInterfaceType(CDecl);
4319 SuperTy = Context.getObjCObjectPointerType(SuperTy);
John McCall60d7b3a2010-08-24 06:29:42 +00004320 ExprResult Super
Douglas Gregor2725ca82010-04-21 19:57:20 +00004321 = Owned(new (Context) ObjCSuperExpr(SuperLoc, SuperTy));
4322 return CodeCompleteObjCInstanceMessage(S, (Expr *)Super.get(),
Douglas Gregor03d8aec2010-08-27 15:10:57 +00004323 SelIdents, NumSelIdents,
Douglas Gregor70c5ac72010-09-20 23:34:21 +00004324 AtArgumentExpression,
Douglas Gregor03d8aec2010-08-27 15:10:57 +00004325 /*IsSuper=*/true);
Douglas Gregor2725ca82010-04-21 19:57:20 +00004326 }
4327
4328 // Fall through to send to the superclass in CDecl.
4329 } else {
4330 // "super" may be the name of a type or variable. Figure out which
4331 // it is.
4332 IdentifierInfo *Super = &Context.Idents.get("super");
4333 NamedDecl *ND = LookupSingleName(S, Super, SuperLoc,
4334 LookupOrdinaryName);
4335 if ((CDecl = dyn_cast_or_null<ObjCInterfaceDecl>(ND))) {
4336 // "super" names an interface. Use it.
4337 } else if (TypeDecl *TD = dyn_cast_or_null<TypeDecl>(ND)) {
John McCallc12c5bb2010-05-15 11:32:37 +00004338 if (const ObjCObjectType *Iface
4339 = Context.getTypeDeclType(TD)->getAs<ObjCObjectType>())
4340 CDecl = Iface->getInterface();
Douglas Gregor2725ca82010-04-21 19:57:20 +00004341 } else if (ND && isa<UnresolvedUsingTypenameDecl>(ND)) {
4342 // "super" names an unresolved type; we can't be more specific.
4343 } else {
4344 // Assume that "super" names some kind of value and parse that way.
4345 CXXScopeSpec SS;
4346 UnqualifiedId id;
4347 id.setIdentifier(Super, SuperLoc);
John McCall60d7b3a2010-08-24 06:29:42 +00004348 ExprResult SuperExpr = ActOnIdExpression(S, SS, id, false, false);
Douglas Gregor2725ca82010-04-21 19:57:20 +00004349 return CodeCompleteObjCInstanceMessage(S, (Expr *)SuperExpr.get(),
Douglas Gregor70c5ac72010-09-20 23:34:21 +00004350 SelIdents, NumSelIdents,
4351 AtArgumentExpression);
Douglas Gregor2725ca82010-04-21 19:57:20 +00004352 }
4353
4354 // Fall through
4355 }
4356
John McCallb3d87482010-08-24 05:47:05 +00004357 ParsedType Receiver;
Douglas Gregor2725ca82010-04-21 19:57:20 +00004358 if (CDecl)
John McCallb3d87482010-08-24 05:47:05 +00004359 Receiver = ParsedType::make(Context.getObjCInterfaceType(CDecl));
Douglas Gregor2725ca82010-04-21 19:57:20 +00004360 return CodeCompleteObjCClassMessage(S, Receiver, SelIdents,
Douglas Gregor70c5ac72010-09-20 23:34:21 +00004361 NumSelIdents, AtArgumentExpression,
4362 /*IsSuper=*/true);
Douglas Gregor2725ca82010-04-21 19:57:20 +00004363}
4364
Douglas Gregorc7b6d882010-09-16 15:14:18 +00004365static void AddClassMessageCompletions(Sema &SemaRef, Scope *S,
4366 ParsedType Receiver,
4367 IdentifierInfo **SelIdents,
4368 unsigned NumSelIdents,
Douglas Gregor70c5ac72010-09-20 23:34:21 +00004369 bool AtArgumentExpression,
Douglas Gregorc7b6d882010-09-16 15:14:18 +00004370 bool IsSuper,
4371 ResultBuilder &Results) {
John McCall0a2c5e22010-08-25 06:19:51 +00004372 typedef CodeCompletionResult Result;
Douglas Gregor24a069f2009-11-17 17:59:40 +00004373 ObjCInterfaceDecl *CDecl = 0;
Douglas Gregorc7b6d882010-09-16 15:14:18 +00004374
Douglas Gregor24a069f2009-11-17 17:59:40 +00004375 // If the given name refers to an interface type, retrieve the
4376 // corresponding declaration.
Douglas Gregor2725ca82010-04-21 19:57:20 +00004377 if (Receiver) {
Douglas Gregorc7b6d882010-09-16 15:14:18 +00004378 QualType T = SemaRef.GetTypeFromParser(Receiver, 0);
Douglas Gregor2725ca82010-04-21 19:57:20 +00004379 if (!T.isNull())
John McCallc12c5bb2010-05-15 11:32:37 +00004380 if (const ObjCObjectType *Interface = T->getAs<ObjCObjectType>())
4381 CDecl = Interface->getInterface();
Douglas Gregor24a069f2009-11-17 17:59:40 +00004382 }
Douglas Gregorc7b6d882010-09-16 15:14:18 +00004383
Douglas Gregor36ecb042009-11-17 23:22:23 +00004384 // Add all of the factory methods in this Objective-C class, its protocols,
4385 // superclasses, categories, implementation, etc.
Steve Naroffc4df6d22009-11-07 02:08:14 +00004386 Results.EnterNewScope();
Douglas Gregorc7b6d882010-09-16 15:14:18 +00004387
Douglas Gregor03d8aec2010-08-27 15:10:57 +00004388 // If this is a send-to-super, try to add the special "super" send
4389 // completion.
4390 if (IsSuper) {
4391 if (ObjCMethodDecl *SuperMethod
Douglas Gregorc7b6d882010-09-16 15:14:18 +00004392 = AddSuperSendCompletion(SemaRef, false, SelIdents, NumSelIdents,
4393 Results))
Douglas Gregor03d8aec2010-08-27 15:10:57 +00004394 Results.Ignore(SuperMethod);
4395 }
Douglas Gregorc7b6d882010-09-16 15:14:18 +00004396
Douglas Gregor265f7492010-08-27 15:29:55 +00004397 // If we're inside an Objective-C method definition, prefer its selector to
4398 // others.
Douglas Gregorc7b6d882010-09-16 15:14:18 +00004399 if (ObjCMethodDecl *CurMethod = SemaRef.getCurMethodDecl())
Douglas Gregor265f7492010-08-27 15:29:55 +00004400 Results.setPreferredSelector(CurMethod->getSelector());
Douglas Gregorc7b6d882010-09-16 15:14:18 +00004401
Douglas Gregord36adf52010-09-16 16:06:31 +00004402 VisitedSelectorSet Selectors;
Douglas Gregor13438f92010-04-06 16:40:00 +00004403 if (CDecl)
Douglas Gregorc7b6d882010-09-16 15:14:18 +00004404 AddObjCMethods(CDecl, false, MK_Any, SelIdents, NumSelIdents,
Douglas Gregord36adf52010-09-16 16:06:31 +00004405 SemaRef.CurContext, Selectors, Results);
Douglas Gregor2725ca82010-04-21 19:57:20 +00004406 else {
Douglas Gregor13438f92010-04-06 16:40:00 +00004407 // We're messaging "id" as a type; provide all class/factory methods.
Douglas Gregorc7b6d882010-09-16 15:14:18 +00004408
Douglas Gregor719770d2010-04-06 17:30:22 +00004409 // If we have an external source, load the entire class method
Sebastian Redl3c7f4132010-08-18 23:57:06 +00004410 // pool from the AST file.
Douglas Gregorc7b6d882010-09-16 15:14:18 +00004411 if (SemaRef.ExternalSource) {
4412 for (uint32_t I = 0,
4413 N = SemaRef.ExternalSource->GetNumExternalSelectors();
John McCall76bd1f32010-06-01 09:23:16 +00004414 I != N; ++I) {
Douglas Gregorc7b6d882010-09-16 15:14:18 +00004415 Selector Sel = SemaRef.ExternalSource->GetExternalSelector(I);
4416 if (Sel.isNull() || SemaRef.MethodPool.count(Sel))
Douglas Gregor719770d2010-04-06 17:30:22 +00004417 continue;
Douglas Gregorc7b6d882010-09-16 15:14:18 +00004418
4419 SemaRef.ReadMethodPool(Sel);
Douglas Gregor719770d2010-04-06 17:30:22 +00004420 }
4421 }
Douglas Gregorc7b6d882010-09-16 15:14:18 +00004422
4423 for (Sema::GlobalMethodPool::iterator M = SemaRef.MethodPool.begin(),
4424 MEnd = SemaRef.MethodPool.end();
Sebastian Redldb9d2142010-08-02 23:18:59 +00004425 M != MEnd; ++M) {
4426 for (ObjCMethodList *MethList = &M->second.second;
4427 MethList && MethList->Method;
Douglas Gregor13438f92010-04-06 16:40:00 +00004428 MethList = MethList->Next) {
4429 if (!isAcceptableObjCMethod(MethList->Method, MK_Any, SelIdents,
4430 NumSelIdents))
4431 continue;
Douglas Gregorc7b6d882010-09-16 15:14:18 +00004432
Douglas Gregor13438f92010-04-06 16:40:00 +00004433 Result R(MethList->Method, 0);
4434 R.StartParameter = NumSelIdents;
4435 R.AllParametersAreInformative = false;
Douglas Gregorc7b6d882010-09-16 15:14:18 +00004436 Results.MaybeAddResult(R, SemaRef.CurContext);
Douglas Gregor13438f92010-04-06 16:40:00 +00004437 }
4438 }
4439 }
Douglas Gregorc7b6d882010-09-16 15:14:18 +00004440
4441 Results.ExitScope();
4442}
Douglas Gregor13438f92010-04-06 16:40:00 +00004443
Douglas Gregorc7b6d882010-09-16 15:14:18 +00004444void Sema::CodeCompleteObjCClassMessage(Scope *S, ParsedType Receiver,
4445 IdentifierInfo **SelIdents,
4446 unsigned NumSelIdents,
Douglas Gregor70c5ac72010-09-20 23:34:21 +00004447 bool AtArgumentExpression,
Douglas Gregorc7b6d882010-09-16 15:14:18 +00004448 bool IsSuper) {
Douglas Gregor70c5ac72010-09-20 23:34:21 +00004449 if (AtArgumentExpression)
4450 return CodeCompleteOrdinaryName(S, PCC_Expression);
4451
Douglas Gregorc7b6d882010-09-16 15:14:18 +00004452 ResultBuilder Results(*this);
Douglas Gregor70c5ac72010-09-20 23:34:21 +00004453 AddClassMessageCompletions(*this, S, Receiver, SelIdents, NumSelIdents,
4454 AtArgumentExpression, IsSuper, Results);
Douglas Gregore6b1bb62010-08-11 21:23:17 +00004455 HandleCodeCompleteResults(this, CodeCompleter,
4456 CodeCompletionContext::CCC_Other,
Douglas Gregor03d8aec2010-08-27 15:10:57 +00004457 Results.data(), Results.size());
Steve Naroffc4df6d22009-11-07 02:08:14 +00004458}
4459
Douglas Gregord3c68542009-11-19 01:08:35 +00004460void Sema::CodeCompleteObjCInstanceMessage(Scope *S, ExprTy *Receiver,
4461 IdentifierInfo **SelIdents,
Douglas Gregor03d8aec2010-08-27 15:10:57 +00004462 unsigned NumSelIdents,
Douglas Gregor70c5ac72010-09-20 23:34:21 +00004463 bool AtArgumentExpression,
Douglas Gregor03d8aec2010-08-27 15:10:57 +00004464 bool IsSuper) {
Douglas Gregor70c5ac72010-09-20 23:34:21 +00004465 if (AtArgumentExpression)
4466 return CodeCompleteOrdinaryName(S, PCC_Expression);
4467
John McCall0a2c5e22010-08-25 06:19:51 +00004468 typedef CodeCompletionResult Result;
Steve Naroffc4df6d22009-11-07 02:08:14 +00004469
4470 Expr *RecExpr = static_cast<Expr *>(Receiver);
Steve Naroffc4df6d22009-11-07 02:08:14 +00004471
Douglas Gregor36ecb042009-11-17 23:22:23 +00004472 // If necessary, apply function/array conversion to the receiver.
4473 // C99 6.7.5.3p[7,8].
Douglas Gregor78edf512010-09-15 16:23:04 +00004474 if (RecExpr)
4475 DefaultFunctionArrayLvalueConversion(RecExpr);
4476 QualType ReceiverType = RecExpr? RecExpr->getType() : Context.getObjCIdType();
Steve Naroffc4df6d22009-11-07 02:08:14 +00004477
Douglas Gregor36ecb042009-11-17 23:22:23 +00004478 // Build the set of methods we can see.
4479 ResultBuilder Results(*this);
4480 Results.EnterNewScope();
Douglas Gregor22f56992010-04-06 19:22:33 +00004481
Douglas Gregor03d8aec2010-08-27 15:10:57 +00004482 // If this is a send-to-super, try to add the special "super" send
4483 // completion.
4484 if (IsSuper) {
4485 if (ObjCMethodDecl *SuperMethod
4486 = AddSuperSendCompletion(*this, false, SelIdents, NumSelIdents,
4487 Results))
4488 Results.Ignore(SuperMethod);
4489 }
4490
Douglas Gregor265f7492010-08-27 15:29:55 +00004491 // If we're inside an Objective-C method definition, prefer its selector to
4492 // others.
4493 if (ObjCMethodDecl *CurMethod = getCurMethodDecl())
4494 Results.setPreferredSelector(CurMethod->getSelector());
4495
Douglas Gregor22f56992010-04-06 19:22:33 +00004496 // If we're messaging an expression with type "id" or "Class", check
4497 // whether we know something special about the receiver that allows
4498 // us to assume a more-specific receiver type.
4499 if (ReceiverType->isObjCIdType() || ReceiverType->isObjCClassType())
4500 if (ObjCInterfaceDecl *IFace = GetAssumedMessageSendExprType(RecExpr))
4501 ReceiverType = Context.getObjCObjectPointerType(
4502 Context.getObjCInterfaceType(IFace));
Douglas Gregor36ecb042009-11-17 23:22:23 +00004503
Douglas Gregord36adf52010-09-16 16:06:31 +00004504 // Keep track of the selectors we've already added.
4505 VisitedSelectorSet Selectors;
4506
Douglas Gregorf74a4192009-11-18 00:06:18 +00004507 // Handle messages to Class. This really isn't a message to an instance
4508 // method, so we treat it the same way we would treat a message send to a
4509 // class method.
4510 if (ReceiverType->isObjCClassType() ||
4511 ReceiverType->isObjCQualifiedClassType()) {
4512 if (ObjCMethodDecl *CurMethod = getCurMethodDecl()) {
4513 if (ObjCInterfaceDecl *ClassDecl = CurMethod->getClassInterface())
Douglas Gregor4ad96852009-11-19 07:41:15 +00004514 AddObjCMethods(ClassDecl, false, MK_Any, SelIdents, NumSelIdents,
Douglas Gregord36adf52010-09-16 16:06:31 +00004515 CurContext, Selectors, Results);
Douglas Gregorf74a4192009-11-18 00:06:18 +00004516 }
4517 }
4518 // Handle messages to a qualified ID ("id<foo>").
4519 else if (const ObjCObjectPointerType *QualID
4520 = ReceiverType->getAsObjCQualifiedIdType()) {
4521 // Search protocols for instance methods.
4522 for (ObjCObjectPointerType::qual_iterator I = QualID->qual_begin(),
4523 E = QualID->qual_end();
4524 I != E; ++I)
Douglas Gregor4ad96852009-11-19 07:41:15 +00004525 AddObjCMethods(*I, true, MK_Any, SelIdents, NumSelIdents, CurContext,
Douglas Gregord36adf52010-09-16 16:06:31 +00004526 Selectors, Results);
Douglas Gregorf74a4192009-11-18 00:06:18 +00004527 }
4528 // Handle messages to a pointer to interface type.
4529 else if (const ObjCObjectPointerType *IFacePtr
4530 = ReceiverType->getAsObjCInterfacePointerType()) {
4531 // Search the class, its superclasses, etc., for instance methods.
Douglas Gregor4ad96852009-11-19 07:41:15 +00004532 AddObjCMethods(IFacePtr->getInterfaceDecl(), true, MK_Any, SelIdents,
Douglas Gregord36adf52010-09-16 16:06:31 +00004533 NumSelIdents, CurContext, Selectors, Results);
Douglas Gregorf74a4192009-11-18 00:06:18 +00004534
4535 // Search protocols for instance methods.
4536 for (ObjCObjectPointerType::qual_iterator I = IFacePtr->qual_begin(),
4537 E = IFacePtr->qual_end();
4538 I != E; ++I)
Douglas Gregor4ad96852009-11-19 07:41:15 +00004539 AddObjCMethods(*I, true, MK_Any, SelIdents, NumSelIdents, CurContext,
Douglas Gregord36adf52010-09-16 16:06:31 +00004540 Selectors, Results);
Douglas Gregorf74a4192009-11-18 00:06:18 +00004541 }
Douglas Gregor13438f92010-04-06 16:40:00 +00004542 // Handle messages to "id".
4543 else if (ReceiverType->isObjCIdType()) {
Douglas Gregor719770d2010-04-06 17:30:22 +00004544 // We're messaging "id", so provide all instance methods we know
4545 // about as code-completion results.
4546
4547 // If we have an external source, load the entire class method
Sebastian Redl3c7f4132010-08-18 23:57:06 +00004548 // pool from the AST file.
Douglas Gregor719770d2010-04-06 17:30:22 +00004549 if (ExternalSource) {
John McCall76bd1f32010-06-01 09:23:16 +00004550 for (uint32_t I = 0, N = ExternalSource->GetNumExternalSelectors();
4551 I != N; ++I) {
4552 Selector Sel = ExternalSource->GetExternalSelector(I);
Sebastian Redldb9d2142010-08-02 23:18:59 +00004553 if (Sel.isNull() || MethodPool.count(Sel))
Douglas Gregor719770d2010-04-06 17:30:22 +00004554 continue;
4555
Sebastian Redldb9d2142010-08-02 23:18:59 +00004556 ReadMethodPool(Sel);
Douglas Gregor719770d2010-04-06 17:30:22 +00004557 }
4558 }
4559
Sebastian Redldb9d2142010-08-02 23:18:59 +00004560 for (GlobalMethodPool::iterator M = MethodPool.begin(),
4561 MEnd = MethodPool.end();
4562 M != MEnd; ++M) {
4563 for (ObjCMethodList *MethList = &M->second.first;
4564 MethList && MethList->Method;
Douglas Gregor13438f92010-04-06 16:40:00 +00004565 MethList = MethList->Next) {
4566 if (!isAcceptableObjCMethod(MethList->Method, MK_Any, SelIdents,
4567 NumSelIdents))
4568 continue;
Douglas Gregord36adf52010-09-16 16:06:31 +00004569
4570 if (!Selectors.insert(MethList->Method->getSelector()))
4571 continue;
4572
Douglas Gregor13438f92010-04-06 16:40:00 +00004573 Result R(MethList->Method, 0);
4574 R.StartParameter = NumSelIdents;
4575 R.AllParametersAreInformative = false;
4576 Results.MaybeAddResult(R, CurContext);
4577 }
4578 }
4579 }
4580
Steve Naroffc4df6d22009-11-07 02:08:14 +00004581 Results.ExitScope();
Douglas Gregore6b1bb62010-08-11 21:23:17 +00004582 HandleCodeCompleteResults(this, CodeCompleter,
4583 CodeCompletionContext::CCC_Other,
4584 Results.data(),Results.size());
Steve Naroffc4df6d22009-11-07 02:08:14 +00004585}
Douglas Gregor55385fe2009-11-18 04:19:12 +00004586
Douglas Gregorfb629412010-08-23 21:17:50 +00004587void Sema::CodeCompleteObjCForCollection(Scope *S,
4588 DeclGroupPtrTy IterationVar) {
4589 CodeCompleteExpressionData Data;
4590 Data.ObjCCollection = true;
4591
4592 if (IterationVar.getAsOpaquePtr()) {
4593 DeclGroupRef DG = IterationVar.getAsVal<DeclGroupRef>();
4594 for (DeclGroupRef::iterator I = DG.begin(), End = DG.end(); I != End; ++I) {
4595 if (*I)
4596 Data.IgnoreDecls.push_back(*I);
4597 }
4598 }
4599
4600 CodeCompleteExpression(S, Data);
4601}
4602
Douglas Gregor458433d2010-08-26 15:07:07 +00004603void Sema::CodeCompleteObjCSelector(Scope *S, IdentifierInfo **SelIdents,
4604 unsigned NumSelIdents) {
4605 // If we have an external source, load the entire class method
4606 // pool from the AST file.
4607 if (ExternalSource) {
4608 for (uint32_t I = 0, N = ExternalSource->GetNumExternalSelectors();
4609 I != N; ++I) {
4610 Selector Sel = ExternalSource->GetExternalSelector(I);
4611 if (Sel.isNull() || MethodPool.count(Sel))
4612 continue;
4613
4614 ReadMethodPool(Sel);
4615 }
4616 }
4617
4618 ResultBuilder Results(*this);
4619 Results.EnterNewScope();
4620 for (GlobalMethodPool::iterator M = MethodPool.begin(),
4621 MEnd = MethodPool.end();
4622 M != MEnd; ++M) {
4623
4624 Selector Sel = M->first;
4625 if (!isAcceptableObjCSelector(Sel, MK_Any, SelIdents, NumSelIdents))
4626 continue;
4627
4628 CodeCompletionString *Pattern = new CodeCompletionString;
4629 if (Sel.isUnarySelector()) {
4630 Pattern->AddTypedTextChunk(Sel.getIdentifierInfoForSlot(0)->getName());
4631 Results.AddResult(Pattern);
4632 continue;
4633 }
4634
Douglas Gregor2d9e21f2010-08-26 16:46:39 +00004635 std::string Accumulator;
Douglas Gregor458433d2010-08-26 15:07:07 +00004636 for (unsigned I = 0, N = Sel.getNumArgs(); I != N; ++I) {
Douglas Gregor2d9e21f2010-08-26 16:46:39 +00004637 if (I == NumSelIdents) {
4638 if (!Accumulator.empty()) {
4639 Pattern->AddInformativeChunk(Accumulator);
4640 Accumulator.clear();
4641 }
4642 }
4643
4644 Accumulator += Sel.getIdentifierInfoForSlot(I)->getName().str();
4645 Accumulator += ':';
Douglas Gregor458433d2010-08-26 15:07:07 +00004646 }
Douglas Gregor2d9e21f2010-08-26 16:46:39 +00004647 Pattern->AddTypedTextChunk(Accumulator);
Douglas Gregor458433d2010-08-26 15:07:07 +00004648 Results.AddResult(Pattern);
4649 }
4650 Results.ExitScope();
4651
4652 HandleCodeCompleteResults(this, CodeCompleter,
4653 CodeCompletionContext::CCC_SelectorName,
4654 Results.data(), Results.size());
4655}
4656
Douglas Gregor55385fe2009-11-18 04:19:12 +00004657/// \brief Add all of the protocol declarations that we find in the given
4658/// (translation unit) context.
4659static void AddProtocolResults(DeclContext *Ctx, DeclContext *CurContext,
Douglas Gregor083128f2009-11-18 04:49:41 +00004660 bool OnlyForwardDeclarations,
Douglas Gregor55385fe2009-11-18 04:19:12 +00004661 ResultBuilder &Results) {
John McCall0a2c5e22010-08-25 06:19:51 +00004662 typedef CodeCompletionResult Result;
Douglas Gregor55385fe2009-11-18 04:19:12 +00004663
4664 for (DeclContext::decl_iterator D = Ctx->decls_begin(),
4665 DEnd = Ctx->decls_end();
4666 D != DEnd; ++D) {
4667 // Record any protocols we find.
4668 if (ObjCProtocolDecl *Proto = dyn_cast<ObjCProtocolDecl>(*D))
Douglas Gregor083128f2009-11-18 04:49:41 +00004669 if (!OnlyForwardDeclarations || Proto->isForwardDecl())
Douglas Gregor608300b2010-01-14 16:14:35 +00004670 Results.AddResult(Result(Proto, 0), CurContext, 0, false);
Douglas Gregor55385fe2009-11-18 04:19:12 +00004671
4672 // Record any forward-declared protocols we find.
4673 if (ObjCForwardProtocolDecl *Forward
4674 = dyn_cast<ObjCForwardProtocolDecl>(*D)) {
4675 for (ObjCForwardProtocolDecl::protocol_iterator
4676 P = Forward->protocol_begin(),
4677 PEnd = Forward->protocol_end();
4678 P != PEnd; ++P)
Douglas Gregor083128f2009-11-18 04:49:41 +00004679 if (!OnlyForwardDeclarations || (*P)->isForwardDecl())
Douglas Gregor608300b2010-01-14 16:14:35 +00004680 Results.AddResult(Result(*P, 0), CurContext, 0, false);
Douglas Gregor55385fe2009-11-18 04:19:12 +00004681 }
4682 }
4683}
4684
4685void Sema::CodeCompleteObjCProtocolReferences(IdentifierLocPair *Protocols,
4686 unsigned NumProtocols) {
4687 ResultBuilder Results(*this);
4688 Results.EnterNewScope();
4689
4690 // Tell the result set to ignore all of the protocols we have
4691 // already seen.
4692 for (unsigned I = 0; I != NumProtocols; ++I)
Douglas Gregorc83c6872010-04-15 22:33:43 +00004693 if (ObjCProtocolDecl *Protocol = LookupProtocol(Protocols[I].first,
4694 Protocols[I].second))
Douglas Gregor55385fe2009-11-18 04:19:12 +00004695 Results.Ignore(Protocol);
4696
4697 // Add all protocols.
Douglas Gregor083128f2009-11-18 04:49:41 +00004698 AddProtocolResults(Context.getTranslationUnitDecl(), CurContext, false,
4699 Results);
4700
4701 Results.ExitScope();
Douglas Gregore6b1bb62010-08-11 21:23:17 +00004702 HandleCodeCompleteResults(this, CodeCompleter,
4703 CodeCompletionContext::CCC_ObjCProtocolName,
4704 Results.data(),Results.size());
Douglas Gregor083128f2009-11-18 04:49:41 +00004705}
4706
4707void Sema::CodeCompleteObjCProtocolDecl(Scope *) {
4708 ResultBuilder Results(*this);
4709 Results.EnterNewScope();
4710
4711 // Add all protocols.
4712 AddProtocolResults(Context.getTranslationUnitDecl(), CurContext, true,
4713 Results);
Douglas Gregor55385fe2009-11-18 04:19:12 +00004714
4715 Results.ExitScope();
Douglas Gregore6b1bb62010-08-11 21:23:17 +00004716 HandleCodeCompleteResults(this, CodeCompleter,
4717 CodeCompletionContext::CCC_ObjCProtocolName,
4718 Results.data(),Results.size());
Douglas Gregor55385fe2009-11-18 04:19:12 +00004719}
Douglas Gregor3b49aca2009-11-18 16:26:39 +00004720
4721/// \brief Add all of the Objective-C interface declarations that we find in
4722/// the given (translation unit) context.
4723static void AddInterfaceResults(DeclContext *Ctx, DeclContext *CurContext,
4724 bool OnlyForwardDeclarations,
4725 bool OnlyUnimplemented,
4726 ResultBuilder &Results) {
John McCall0a2c5e22010-08-25 06:19:51 +00004727 typedef CodeCompletionResult Result;
Douglas Gregor3b49aca2009-11-18 16:26:39 +00004728
4729 for (DeclContext::decl_iterator D = Ctx->decls_begin(),
4730 DEnd = Ctx->decls_end();
4731 D != DEnd; ++D) {
Douglas Gregordeacbdc2010-08-11 12:19:30 +00004732 // Record any interfaces we find.
4733 if (ObjCInterfaceDecl *Class = dyn_cast<ObjCInterfaceDecl>(*D))
4734 if ((!OnlyForwardDeclarations || Class->isForwardDecl()) &&
4735 (!OnlyUnimplemented || !Class->getImplementation()))
4736 Results.AddResult(Result(Class, 0), CurContext, 0, false);
Douglas Gregor3b49aca2009-11-18 16:26:39 +00004737
4738 // Record any forward-declared interfaces we find.
4739 if (ObjCClassDecl *Forward = dyn_cast<ObjCClassDecl>(*D)) {
4740 for (ObjCClassDecl::iterator C = Forward->begin(), CEnd = Forward->end();
Douglas Gregordeacbdc2010-08-11 12:19:30 +00004741 C != CEnd; ++C)
4742 if ((!OnlyForwardDeclarations || C->getInterface()->isForwardDecl()) &&
4743 (!OnlyUnimplemented || !C->getInterface()->getImplementation()))
4744 Results.AddResult(Result(C->getInterface(), 0), CurContext,
Douglas Gregor608300b2010-01-14 16:14:35 +00004745 0, false);
Douglas Gregor3b49aca2009-11-18 16:26:39 +00004746 }
4747 }
4748}
4749
4750void Sema::CodeCompleteObjCInterfaceDecl(Scope *S) {
4751 ResultBuilder Results(*this);
4752 Results.EnterNewScope();
4753
4754 // Add all classes.
4755 AddInterfaceResults(Context.getTranslationUnitDecl(), CurContext, true,
4756 false, Results);
4757
4758 Results.ExitScope();
Douglas Gregore6b1bb62010-08-11 21:23:17 +00004759 HandleCodeCompleteResults(this, CodeCompleter,
4760 CodeCompletionContext::CCC_Other,
4761 Results.data(),Results.size());
Douglas Gregor3b49aca2009-11-18 16:26:39 +00004762}
4763
Douglas Gregorc83c6872010-04-15 22:33:43 +00004764void Sema::CodeCompleteObjCSuperclass(Scope *S, IdentifierInfo *ClassName,
4765 SourceLocation ClassNameLoc) {
Douglas Gregor3b49aca2009-11-18 16:26:39 +00004766 ResultBuilder Results(*this);
4767 Results.EnterNewScope();
4768
4769 // Make sure that we ignore the class we're currently defining.
4770 NamedDecl *CurClass
Douglas Gregorc83c6872010-04-15 22:33:43 +00004771 = LookupSingleName(TUScope, ClassName, ClassNameLoc, LookupOrdinaryName);
Douglas Gregor33ced0b2009-11-18 19:08:43 +00004772 if (CurClass && isa<ObjCInterfaceDecl>(CurClass))
Douglas Gregor3b49aca2009-11-18 16:26:39 +00004773 Results.Ignore(CurClass);
4774
4775 // Add all classes.
4776 AddInterfaceResults(Context.getTranslationUnitDecl(), CurContext, false,
4777 false, Results);
4778
4779 Results.ExitScope();
Douglas Gregore6b1bb62010-08-11 21:23:17 +00004780 HandleCodeCompleteResults(this, CodeCompleter,
4781 CodeCompletionContext::CCC_Other,
4782 Results.data(),Results.size());
Douglas Gregor3b49aca2009-11-18 16:26:39 +00004783}
4784
4785void Sema::CodeCompleteObjCImplementationDecl(Scope *S) {
4786 ResultBuilder Results(*this);
4787 Results.EnterNewScope();
4788
4789 // Add all unimplemented classes.
4790 AddInterfaceResults(Context.getTranslationUnitDecl(), CurContext, false,
4791 true, Results);
4792
4793 Results.ExitScope();
Douglas Gregore6b1bb62010-08-11 21:23:17 +00004794 HandleCodeCompleteResults(this, CodeCompleter,
4795 CodeCompletionContext::CCC_Other,
4796 Results.data(),Results.size());
Douglas Gregor3b49aca2009-11-18 16:26:39 +00004797}
Douglas Gregor33ced0b2009-11-18 19:08:43 +00004798
4799void Sema::CodeCompleteObjCInterfaceCategory(Scope *S,
Douglas Gregorc83c6872010-04-15 22:33:43 +00004800 IdentifierInfo *ClassName,
4801 SourceLocation ClassNameLoc) {
John McCall0a2c5e22010-08-25 06:19:51 +00004802 typedef CodeCompletionResult Result;
Douglas Gregor33ced0b2009-11-18 19:08:43 +00004803
4804 ResultBuilder Results(*this);
4805
4806 // Ignore any categories we find that have already been implemented by this
4807 // interface.
4808 llvm::SmallPtrSet<IdentifierInfo *, 16> CategoryNames;
4809 NamedDecl *CurClass
Douglas Gregorc83c6872010-04-15 22:33:43 +00004810 = LookupSingleName(TUScope, ClassName, ClassNameLoc, LookupOrdinaryName);
Douglas Gregor33ced0b2009-11-18 19:08:43 +00004811 if (ObjCInterfaceDecl *Class = dyn_cast_or_null<ObjCInterfaceDecl>(CurClass))
4812 for (ObjCCategoryDecl *Category = Class->getCategoryList(); Category;
4813 Category = Category->getNextClassCategory())
4814 CategoryNames.insert(Category->getIdentifier());
4815
4816 // Add all of the categories we know about.
4817 Results.EnterNewScope();
4818 TranslationUnitDecl *TU = Context.getTranslationUnitDecl();
4819 for (DeclContext::decl_iterator D = TU->decls_begin(),
4820 DEnd = TU->decls_end();
4821 D != DEnd; ++D)
4822 if (ObjCCategoryDecl *Category = dyn_cast<ObjCCategoryDecl>(*D))
4823 if (CategoryNames.insert(Category->getIdentifier()))
Douglas Gregor608300b2010-01-14 16:14:35 +00004824 Results.AddResult(Result(Category, 0), CurContext, 0, false);
Douglas Gregor33ced0b2009-11-18 19:08:43 +00004825 Results.ExitScope();
4826
Douglas Gregore6b1bb62010-08-11 21:23:17 +00004827 HandleCodeCompleteResults(this, CodeCompleter,
4828 CodeCompletionContext::CCC_Other,
4829 Results.data(),Results.size());
Douglas Gregor33ced0b2009-11-18 19:08:43 +00004830}
4831
4832void Sema::CodeCompleteObjCImplementationCategory(Scope *S,
Douglas Gregorc83c6872010-04-15 22:33:43 +00004833 IdentifierInfo *ClassName,
4834 SourceLocation ClassNameLoc) {
John McCall0a2c5e22010-08-25 06:19:51 +00004835 typedef CodeCompletionResult Result;
Douglas Gregor33ced0b2009-11-18 19:08:43 +00004836
4837 // Find the corresponding interface. If we couldn't find the interface, the
4838 // program itself is ill-formed. However, we'll try to be helpful still by
4839 // providing the list of all of the categories we know about.
4840 NamedDecl *CurClass
Douglas Gregorc83c6872010-04-15 22:33:43 +00004841 = LookupSingleName(TUScope, ClassName, ClassNameLoc, LookupOrdinaryName);
Douglas Gregor33ced0b2009-11-18 19:08:43 +00004842 ObjCInterfaceDecl *Class = dyn_cast_or_null<ObjCInterfaceDecl>(CurClass);
4843 if (!Class)
Douglas Gregorc83c6872010-04-15 22:33:43 +00004844 return CodeCompleteObjCInterfaceCategory(S, ClassName, ClassNameLoc);
Douglas Gregor33ced0b2009-11-18 19:08:43 +00004845
4846 ResultBuilder Results(*this);
4847
4848 // Add all of the categories that have have corresponding interface
4849 // declarations in this class and any of its superclasses, except for
4850 // already-implemented categories in the class itself.
4851 llvm::SmallPtrSet<IdentifierInfo *, 16> CategoryNames;
4852 Results.EnterNewScope();
4853 bool IgnoreImplemented = true;
4854 while (Class) {
4855 for (ObjCCategoryDecl *Category = Class->getCategoryList(); Category;
4856 Category = Category->getNextClassCategory())
4857 if ((!IgnoreImplemented || !Category->getImplementation()) &&
4858 CategoryNames.insert(Category->getIdentifier()))
Douglas Gregor608300b2010-01-14 16:14:35 +00004859 Results.AddResult(Result(Category, 0), CurContext, 0, false);
Douglas Gregor33ced0b2009-11-18 19:08:43 +00004860
4861 Class = Class->getSuperClass();
4862 IgnoreImplemented = false;
4863 }
4864 Results.ExitScope();
4865
Douglas Gregore6b1bb62010-08-11 21:23:17 +00004866 HandleCodeCompleteResults(this, CodeCompleter,
4867 CodeCompletionContext::CCC_Other,
4868 Results.data(),Results.size());
Douglas Gregor33ced0b2009-11-18 19:08:43 +00004869}
Douglas Gregor322328b2009-11-18 22:32:06 +00004870
John McCalld226f652010-08-21 09:40:31 +00004871void Sema::CodeCompleteObjCPropertyDefinition(Scope *S, Decl *ObjCImpDecl) {
John McCall0a2c5e22010-08-25 06:19:51 +00004872 typedef CodeCompletionResult Result;
Douglas Gregor322328b2009-11-18 22:32:06 +00004873 ResultBuilder Results(*this);
4874
4875 // Figure out where this @synthesize lives.
4876 ObjCContainerDecl *Container
John McCalld226f652010-08-21 09:40:31 +00004877 = dyn_cast_or_null<ObjCContainerDecl>(ObjCImpDecl);
Douglas Gregor322328b2009-11-18 22:32:06 +00004878 if (!Container ||
4879 (!isa<ObjCImplementationDecl>(Container) &&
4880 !isa<ObjCCategoryImplDecl>(Container)))
4881 return;
4882
4883 // Ignore any properties that have already been implemented.
4884 for (DeclContext::decl_iterator D = Container->decls_begin(),
4885 DEnd = Container->decls_end();
4886 D != DEnd; ++D)
4887 if (ObjCPropertyImplDecl *PropertyImpl = dyn_cast<ObjCPropertyImplDecl>(*D))
4888 Results.Ignore(PropertyImpl->getPropertyDecl());
4889
4890 // Add any properties that we find.
4891 Results.EnterNewScope();
4892 if (ObjCImplementationDecl *ClassImpl
4893 = dyn_cast<ObjCImplementationDecl>(Container))
4894 AddObjCProperties(ClassImpl->getClassInterface(), false, CurContext,
4895 Results);
4896 else
4897 AddObjCProperties(cast<ObjCCategoryImplDecl>(Container)->getCategoryDecl(),
4898 false, CurContext, Results);
4899 Results.ExitScope();
4900
Douglas Gregore6b1bb62010-08-11 21:23:17 +00004901 HandleCodeCompleteResults(this, CodeCompleter,
4902 CodeCompletionContext::CCC_Other,
4903 Results.data(),Results.size());
Douglas Gregor322328b2009-11-18 22:32:06 +00004904}
4905
4906void Sema::CodeCompleteObjCPropertySynthesizeIvar(Scope *S,
4907 IdentifierInfo *PropertyName,
John McCalld226f652010-08-21 09:40:31 +00004908 Decl *ObjCImpDecl) {
John McCall0a2c5e22010-08-25 06:19:51 +00004909 typedef CodeCompletionResult Result;
Douglas Gregor322328b2009-11-18 22:32:06 +00004910 ResultBuilder Results(*this);
4911
4912 // Figure out where this @synthesize lives.
4913 ObjCContainerDecl *Container
John McCalld226f652010-08-21 09:40:31 +00004914 = dyn_cast_or_null<ObjCContainerDecl>(ObjCImpDecl);
Douglas Gregor322328b2009-11-18 22:32:06 +00004915 if (!Container ||
4916 (!isa<ObjCImplementationDecl>(Container) &&
4917 !isa<ObjCCategoryImplDecl>(Container)))
4918 return;
4919
4920 // Figure out which interface we're looking into.
4921 ObjCInterfaceDecl *Class = 0;
4922 if (ObjCImplementationDecl *ClassImpl
4923 = dyn_cast<ObjCImplementationDecl>(Container))
4924 Class = ClassImpl->getClassInterface();
4925 else
4926 Class = cast<ObjCCategoryImplDecl>(Container)->getCategoryDecl()
4927 ->getClassInterface();
4928
4929 // Add all of the instance variables in this class and its superclasses.
4930 Results.EnterNewScope();
4931 for(; Class; Class = Class->getSuperClass()) {
4932 // FIXME: We could screen the type of each ivar for compatibility with
4933 // the property, but is that being too paternal?
4934 for (ObjCInterfaceDecl::ivar_iterator IVar = Class->ivar_begin(),
4935 IVarEnd = Class->ivar_end();
4936 IVar != IVarEnd; ++IVar)
Douglas Gregor608300b2010-01-14 16:14:35 +00004937 Results.AddResult(Result(*IVar, 0), CurContext, 0, false);
Douglas Gregor322328b2009-11-18 22:32:06 +00004938 }
4939 Results.ExitScope();
4940
Douglas Gregore6b1bb62010-08-11 21:23:17 +00004941 HandleCodeCompleteResults(this, CodeCompleter,
4942 CodeCompletionContext::CCC_Other,
4943 Results.data(),Results.size());
Douglas Gregor322328b2009-11-18 22:32:06 +00004944}
Douglas Gregore8f5a172010-04-07 00:21:17 +00004945
Douglas Gregor408be5a2010-08-25 01:08:01 +00004946// Mapping from selectors to the methods that implement that selector, along
4947// with the "in original class" flag.
4948typedef llvm::DenseMap<Selector, std::pair<ObjCMethodDecl *, bool> >
4949 KnownMethodsMap;
Douglas Gregore8f5a172010-04-07 00:21:17 +00004950
4951/// \brief Find all of the methods that reside in the given container
4952/// (and its superclasses, protocols, etc.) that meet the given
4953/// criteria. Insert those methods into the map of known methods,
4954/// indexed by selector so they can be easily found.
4955static void FindImplementableMethods(ASTContext &Context,
4956 ObjCContainerDecl *Container,
4957 bool WantInstanceMethods,
4958 QualType ReturnType,
4959 bool IsInImplementation,
Douglas Gregor408be5a2010-08-25 01:08:01 +00004960 KnownMethodsMap &KnownMethods,
4961 bool InOriginalClass = true) {
Douglas Gregore8f5a172010-04-07 00:21:17 +00004962 if (ObjCInterfaceDecl *IFace = dyn_cast<ObjCInterfaceDecl>(Container)) {
4963 // Recurse into protocols.
4964 const ObjCList<ObjCProtocolDecl> &Protocols
4965 = IFace->getReferencedProtocols();
4966 for (ObjCList<ObjCProtocolDecl>::iterator I = Protocols.begin(),
4967 E = Protocols.end();
4968 I != E; ++I)
4969 FindImplementableMethods(Context, *I, WantInstanceMethods, ReturnType,
Douglas Gregor408be5a2010-08-25 01:08:01 +00004970 IsInImplementation, KnownMethods,
4971 InOriginalClass);
Douglas Gregore8f5a172010-04-07 00:21:17 +00004972
4973 // If we're not in the implementation of a class, also visit the
4974 // superclass.
4975 if (!IsInImplementation && IFace->getSuperClass())
4976 FindImplementableMethods(Context, IFace->getSuperClass(),
4977 WantInstanceMethods, ReturnType,
Douglas Gregor408be5a2010-08-25 01:08:01 +00004978 IsInImplementation, KnownMethods,
4979 false);
Douglas Gregore8f5a172010-04-07 00:21:17 +00004980
4981 // Add methods from any class extensions (but not from categories;
4982 // those should go into category implementations).
Fariborz Jahanian80aa1cd2010-06-22 23:20:40 +00004983 for (const ObjCCategoryDecl *Cat = IFace->getFirstClassExtension(); Cat;
4984 Cat = Cat->getNextClassExtension())
4985 FindImplementableMethods(Context, const_cast<ObjCCategoryDecl*>(Cat),
4986 WantInstanceMethods, ReturnType,
Douglas Gregor408be5a2010-08-25 01:08:01 +00004987 IsInImplementation, KnownMethods,
4988 InOriginalClass);
Douglas Gregore8f5a172010-04-07 00:21:17 +00004989 }
4990
4991 if (ObjCCategoryDecl *Category = dyn_cast<ObjCCategoryDecl>(Container)) {
4992 // Recurse into protocols.
4993 const ObjCList<ObjCProtocolDecl> &Protocols
4994 = Category->getReferencedProtocols();
4995 for (ObjCList<ObjCProtocolDecl>::iterator I = Protocols.begin(),
4996 E = Protocols.end();
4997 I != E; ++I)
4998 FindImplementableMethods(Context, *I, WantInstanceMethods, ReturnType,
Douglas Gregor408be5a2010-08-25 01:08:01 +00004999 IsInImplementation, KnownMethods,
5000 InOriginalClass);
Douglas Gregore8f5a172010-04-07 00:21:17 +00005001 }
5002
5003 if (ObjCProtocolDecl *Protocol = dyn_cast<ObjCProtocolDecl>(Container)) {
5004 // Recurse into protocols.
5005 const ObjCList<ObjCProtocolDecl> &Protocols
5006 = Protocol->getReferencedProtocols();
5007 for (ObjCList<ObjCProtocolDecl>::iterator I = Protocols.begin(),
5008 E = Protocols.end();
5009 I != E; ++I)
5010 FindImplementableMethods(Context, *I, WantInstanceMethods, ReturnType,
Douglas Gregor408be5a2010-08-25 01:08:01 +00005011 IsInImplementation, KnownMethods, false);
Douglas Gregore8f5a172010-04-07 00:21:17 +00005012 }
5013
5014 // Add methods in this container. This operation occurs last because
5015 // we want the methods from this container to override any methods
5016 // we've previously seen with the same selector.
5017 for (ObjCContainerDecl::method_iterator M = Container->meth_begin(),
5018 MEnd = Container->meth_end();
5019 M != MEnd; ++M) {
5020 if ((*M)->isInstanceMethod() == WantInstanceMethods) {
5021 if (!ReturnType.isNull() &&
5022 !Context.hasSameUnqualifiedType(ReturnType, (*M)->getResultType()))
5023 continue;
5024
Douglas Gregor408be5a2010-08-25 01:08:01 +00005025 KnownMethods[(*M)->getSelector()] = std::make_pair(*M, InOriginalClass);
Douglas Gregore8f5a172010-04-07 00:21:17 +00005026 }
5027 }
5028}
5029
5030void Sema::CodeCompleteObjCMethodDecl(Scope *S,
5031 bool IsInstanceMethod,
John McCallb3d87482010-08-24 05:47:05 +00005032 ParsedType ReturnTy,
John McCalld226f652010-08-21 09:40:31 +00005033 Decl *IDecl) {
Douglas Gregore8f5a172010-04-07 00:21:17 +00005034 // Determine the return type of the method we're declaring, if
5035 // provided.
5036 QualType ReturnType = GetTypeFromParser(ReturnTy);
5037
5038 // Determine where we should start searching for methods, and where we
5039 ObjCContainerDecl *SearchDecl = 0, *CurrentDecl = 0;
5040 bool IsInImplementation = false;
John McCalld226f652010-08-21 09:40:31 +00005041 if (Decl *D = IDecl) {
Douglas Gregore8f5a172010-04-07 00:21:17 +00005042 if (ObjCImplementationDecl *Impl = dyn_cast<ObjCImplementationDecl>(D)) {
5043 SearchDecl = Impl->getClassInterface();
5044 CurrentDecl = Impl;
5045 IsInImplementation = true;
5046 } else if (ObjCCategoryImplDecl *CatImpl
5047 = dyn_cast<ObjCCategoryImplDecl>(D)) {
5048 SearchDecl = CatImpl->getCategoryDecl();
5049 CurrentDecl = CatImpl;
5050 IsInImplementation = true;
5051 } else {
5052 SearchDecl = dyn_cast<ObjCContainerDecl>(D);
5053 CurrentDecl = SearchDecl;
5054 }
5055 }
5056
5057 if (!SearchDecl && S) {
5058 if (DeclContext *DC = static_cast<DeclContext *>(S->getEntity())) {
5059 SearchDecl = dyn_cast<ObjCContainerDecl>(DC);
5060 CurrentDecl = SearchDecl;
5061 }
5062 }
5063
5064 if (!SearchDecl || !CurrentDecl) {
Douglas Gregore6b1bb62010-08-11 21:23:17 +00005065 HandleCodeCompleteResults(this, CodeCompleter,
5066 CodeCompletionContext::CCC_Other,
5067 0, 0);
Douglas Gregore8f5a172010-04-07 00:21:17 +00005068 return;
5069 }
5070
5071 // Find all of the methods that we could declare/implement here.
5072 KnownMethodsMap KnownMethods;
5073 FindImplementableMethods(Context, SearchDecl, IsInstanceMethod,
5074 ReturnType, IsInImplementation, KnownMethods);
5075
5076 // Erase any methods that have already been declared or
5077 // implemented here.
5078 for (ObjCContainerDecl::method_iterator M = CurrentDecl->meth_begin(),
5079 MEnd = CurrentDecl->meth_end();
5080 M != MEnd; ++M) {
5081 if ((*M)->isInstanceMethod() != IsInstanceMethod)
5082 continue;
5083
5084 KnownMethodsMap::iterator Pos = KnownMethods.find((*M)->getSelector());
5085 if (Pos != KnownMethods.end())
5086 KnownMethods.erase(Pos);
5087 }
5088
5089 // Add declarations or definitions for each of the known methods.
John McCall0a2c5e22010-08-25 06:19:51 +00005090 typedef CodeCompletionResult Result;
Douglas Gregore8f5a172010-04-07 00:21:17 +00005091 ResultBuilder Results(*this);
5092 Results.EnterNewScope();
5093 PrintingPolicy Policy(Context.PrintingPolicy);
5094 Policy.AnonymousTagLocations = false;
5095 for (KnownMethodsMap::iterator M = KnownMethods.begin(),
5096 MEnd = KnownMethods.end();
5097 M != MEnd; ++M) {
Douglas Gregor408be5a2010-08-25 01:08:01 +00005098 ObjCMethodDecl *Method = M->second.first;
Douglas Gregore8f5a172010-04-07 00:21:17 +00005099 CodeCompletionString *Pattern = new CodeCompletionString;
5100
5101 // If the result type was not already provided, add it to the
5102 // pattern as (type).
5103 if (ReturnType.isNull()) {
5104 std::string TypeStr;
5105 Method->getResultType().getAsStringInternal(TypeStr, Policy);
5106 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
5107 Pattern->AddTextChunk(TypeStr);
5108 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
5109 }
5110
5111 Selector Sel = Method->getSelector();
5112
5113 // Add the first part of the selector to the pattern.
5114 Pattern->AddTypedTextChunk(Sel.getIdentifierInfoForSlot(0)->getName());
5115
5116 // Add parameters to the pattern.
5117 unsigned I = 0;
5118 for (ObjCMethodDecl::param_iterator P = Method->param_begin(),
5119 PEnd = Method->param_end();
5120 P != PEnd; (void)++P, ++I) {
5121 // Add the part of the selector name.
5122 if (I == 0)
5123 Pattern->AddChunk(CodeCompletionString::CK_Colon);
5124 else if (I < Sel.getNumArgs()) {
5125 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
Douglas Gregor47c03a72010-08-17 15:53:35 +00005126 Pattern->AddTextChunk(Sel.getIdentifierInfoForSlot(I)->getName());
Douglas Gregore8f5a172010-04-07 00:21:17 +00005127 Pattern->AddChunk(CodeCompletionString::CK_Colon);
5128 } else
5129 break;
5130
5131 // Add the parameter type.
5132 std::string TypeStr;
5133 (*P)->getOriginalType().getAsStringInternal(TypeStr, Policy);
5134 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
5135 Pattern->AddTextChunk(TypeStr);
5136 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
5137
5138 if (IdentifierInfo *Id = (*P)->getIdentifier())
Douglas Gregore17794f2010-08-31 05:13:43 +00005139 Pattern->AddTextChunk(Id->getName());
Douglas Gregore8f5a172010-04-07 00:21:17 +00005140 }
5141
5142 if (Method->isVariadic()) {
5143 if (Method->param_size() > 0)
5144 Pattern->AddChunk(CodeCompletionString::CK_Comma);
5145 Pattern->AddTextChunk("...");
Douglas Gregore17794f2010-08-31 05:13:43 +00005146 }
Douglas Gregore8f5a172010-04-07 00:21:17 +00005147
Douglas Gregor447107d2010-05-28 00:57:46 +00005148 if (IsInImplementation && Results.includeCodePatterns()) {
Douglas Gregore8f5a172010-04-07 00:21:17 +00005149 // We will be defining the method here, so add a compound statement.
5150 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
5151 Pattern->AddChunk(CodeCompletionString::CK_LeftBrace);
5152 Pattern->AddChunk(CodeCompletionString::CK_VerticalSpace);
5153 if (!Method->getResultType()->isVoidType()) {
5154 // If the result type is not void, add a return clause.
5155 Pattern->AddTextChunk("return");
5156 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
5157 Pattern->AddPlaceholderChunk("expression");
5158 Pattern->AddChunk(CodeCompletionString::CK_SemiColon);
5159 } else
5160 Pattern->AddPlaceholderChunk("statements");
5161
5162 Pattern->AddChunk(CodeCompletionString::CK_VerticalSpace);
5163 Pattern->AddChunk(CodeCompletionString::CK_RightBrace);
5164 }
5165
Douglas Gregor408be5a2010-08-25 01:08:01 +00005166 unsigned Priority = CCP_CodePattern;
5167 if (!M->second.second)
5168 Priority += CCD_InBaseClass;
5169
5170 Results.AddResult(Result(Pattern, Priority,
Douglas Gregor16ed9ad2010-08-17 16:06:07 +00005171 Method->isInstanceMethod()
5172 ? CXCursor_ObjCInstanceMethodDecl
5173 : CXCursor_ObjCClassMethodDecl));
Douglas Gregore8f5a172010-04-07 00:21:17 +00005174 }
5175
5176 Results.ExitScope();
5177
Douglas Gregore6b1bb62010-08-11 21:23:17 +00005178 HandleCodeCompleteResults(this, CodeCompleter,
5179 CodeCompletionContext::CCC_Other,
5180 Results.data(),Results.size());
Douglas Gregore8f5a172010-04-07 00:21:17 +00005181}
Douglas Gregor1f5537a2010-07-08 23:20:03 +00005182
5183void Sema::CodeCompleteObjCMethodDeclSelector(Scope *S,
5184 bool IsInstanceMethod,
Douglas Gregor40ed9a12010-07-08 23:37:41 +00005185 bool AtParameterName,
John McCallb3d87482010-08-24 05:47:05 +00005186 ParsedType ReturnTy,
Douglas Gregor1f5537a2010-07-08 23:20:03 +00005187 IdentifierInfo **SelIdents,
5188 unsigned NumSelIdents) {
Douglas Gregor1f5537a2010-07-08 23:20:03 +00005189 // If we have an external source, load the entire class method
Sebastian Redl3c7f4132010-08-18 23:57:06 +00005190 // pool from the AST file.
Douglas Gregor1f5537a2010-07-08 23:20:03 +00005191 if (ExternalSource) {
5192 for (uint32_t I = 0, N = ExternalSource->GetNumExternalSelectors();
5193 I != N; ++I) {
5194 Selector Sel = ExternalSource->GetExternalSelector(I);
Sebastian Redldb9d2142010-08-02 23:18:59 +00005195 if (Sel.isNull() || MethodPool.count(Sel))
Douglas Gregor1f5537a2010-07-08 23:20:03 +00005196 continue;
Sebastian Redldb9d2142010-08-02 23:18:59 +00005197
5198 ReadMethodPool(Sel);
Douglas Gregor1f5537a2010-07-08 23:20:03 +00005199 }
5200 }
5201
5202 // Build the set of methods we can see.
John McCall0a2c5e22010-08-25 06:19:51 +00005203 typedef CodeCompletionResult Result;
Douglas Gregor1f5537a2010-07-08 23:20:03 +00005204 ResultBuilder Results(*this);
5205
5206 if (ReturnTy)
5207 Results.setPreferredType(GetTypeFromParser(ReturnTy).getNonReferenceType());
Sebastian Redldb9d2142010-08-02 23:18:59 +00005208
Douglas Gregor1f5537a2010-07-08 23:20:03 +00005209 Results.EnterNewScope();
Sebastian Redldb9d2142010-08-02 23:18:59 +00005210 for (GlobalMethodPool::iterator M = MethodPool.begin(),
5211 MEnd = MethodPool.end();
5212 M != MEnd; ++M) {
5213 for (ObjCMethodList *MethList = IsInstanceMethod ? &M->second.first :
5214 &M->second.second;
5215 MethList && MethList->Method;
Douglas Gregor1f5537a2010-07-08 23:20:03 +00005216 MethList = MethList->Next) {
5217 if (!isAcceptableObjCMethod(MethList->Method, MK_Any, SelIdents,
5218 NumSelIdents))
5219 continue;
5220
Douglas Gregor40ed9a12010-07-08 23:37:41 +00005221 if (AtParameterName) {
5222 // Suggest parameter names we've seen before.
5223 if (NumSelIdents && NumSelIdents <= MethList->Method->param_size()) {
5224 ParmVarDecl *Param = MethList->Method->param_begin()[NumSelIdents-1];
5225 if (Param->getIdentifier()) {
5226 CodeCompletionString *Pattern = new CodeCompletionString;
5227 Pattern->AddTypedTextChunk(Param->getIdentifier()->getName());
5228 Results.AddResult(Pattern);
5229 }
5230 }
5231
5232 continue;
5233 }
5234
Douglas Gregor1f5537a2010-07-08 23:20:03 +00005235 Result R(MethList->Method, 0);
5236 R.StartParameter = NumSelIdents;
5237 R.AllParametersAreInformative = false;
5238 R.DeclaringEntity = true;
5239 Results.MaybeAddResult(R, CurContext);
5240 }
5241 }
5242
5243 Results.ExitScope();
Douglas Gregore6b1bb62010-08-11 21:23:17 +00005244 HandleCodeCompleteResults(this, CodeCompleter,
5245 CodeCompletionContext::CCC_Other,
5246 Results.data(),Results.size());
Douglas Gregor1f5537a2010-07-08 23:20:03 +00005247}
Douglas Gregor87c08a52010-08-13 22:48:40 +00005248
Douglas Gregorf29c5232010-08-24 22:20:20 +00005249void Sema::CodeCompletePreprocessorDirective(bool InConditional) {
Douglas Gregorf44e8542010-08-24 19:08:16 +00005250 ResultBuilder Results(*this);
5251 Results.EnterNewScope();
5252
5253 // #if <condition>
5254 CodeCompletionString *Pattern = new CodeCompletionString;
5255 Pattern->AddTypedTextChunk("if");
5256 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
5257 Pattern->AddPlaceholderChunk("condition");
5258 Results.AddResult(Pattern);
5259
5260 // #ifdef <macro>
5261 Pattern = new CodeCompletionString;
5262 Pattern->AddTypedTextChunk("ifdef");
5263 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
5264 Pattern->AddPlaceholderChunk("macro");
5265 Results.AddResult(Pattern);
5266
5267 // #ifndef <macro>
5268 Pattern = new CodeCompletionString;
5269 Pattern->AddTypedTextChunk("ifndef");
5270 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
5271 Pattern->AddPlaceholderChunk("macro");
5272 Results.AddResult(Pattern);
5273
5274 if (InConditional) {
5275 // #elif <condition>
5276 Pattern = new CodeCompletionString;
5277 Pattern->AddTypedTextChunk("elif");
5278 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
5279 Pattern->AddPlaceholderChunk("condition");
5280 Results.AddResult(Pattern);
5281
5282 // #else
5283 Pattern = new CodeCompletionString;
5284 Pattern->AddTypedTextChunk("else");
5285 Results.AddResult(Pattern);
5286
5287 // #endif
5288 Pattern = new CodeCompletionString;
5289 Pattern->AddTypedTextChunk("endif");
5290 Results.AddResult(Pattern);
5291 }
5292
5293 // #include "header"
5294 Pattern = new CodeCompletionString;
5295 Pattern->AddTypedTextChunk("include");
5296 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
5297 Pattern->AddTextChunk("\"");
5298 Pattern->AddPlaceholderChunk("header");
5299 Pattern->AddTextChunk("\"");
5300 Results.AddResult(Pattern);
5301
5302 // #include <header>
5303 Pattern = new CodeCompletionString;
5304 Pattern->AddTypedTextChunk("include");
5305 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
5306 Pattern->AddTextChunk("<");
5307 Pattern->AddPlaceholderChunk("header");
5308 Pattern->AddTextChunk(">");
5309 Results.AddResult(Pattern);
5310
5311 // #define <macro>
5312 Pattern = new CodeCompletionString;
5313 Pattern->AddTypedTextChunk("define");
5314 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
5315 Pattern->AddPlaceholderChunk("macro");
5316 Results.AddResult(Pattern);
5317
5318 // #define <macro>(<args>)
5319 Pattern = new CodeCompletionString;
5320 Pattern->AddTypedTextChunk("define");
5321 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
5322 Pattern->AddPlaceholderChunk("macro");
5323 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
5324 Pattern->AddPlaceholderChunk("args");
5325 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
5326 Results.AddResult(Pattern);
5327
5328 // #undef <macro>
5329 Pattern = new CodeCompletionString;
5330 Pattern->AddTypedTextChunk("undef");
5331 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
5332 Pattern->AddPlaceholderChunk("macro");
5333 Results.AddResult(Pattern);
5334
5335 // #line <number>
5336 Pattern = new CodeCompletionString;
5337 Pattern->AddTypedTextChunk("line");
5338 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
5339 Pattern->AddPlaceholderChunk("number");
5340 Results.AddResult(Pattern);
5341
5342 // #line <number> "filename"
5343 Pattern = new CodeCompletionString;
5344 Pattern->AddTypedTextChunk("line");
5345 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
5346 Pattern->AddPlaceholderChunk("number");
5347 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
5348 Pattern->AddTextChunk("\"");
5349 Pattern->AddPlaceholderChunk("filename");
5350 Pattern->AddTextChunk("\"");
5351 Results.AddResult(Pattern);
5352
5353 // #error <message>
5354 Pattern = new CodeCompletionString;
5355 Pattern->AddTypedTextChunk("error");
5356 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
5357 Pattern->AddPlaceholderChunk("message");
5358 Results.AddResult(Pattern);
5359
5360 // #pragma <arguments>
5361 Pattern = new CodeCompletionString;
5362 Pattern->AddTypedTextChunk("pragma");
5363 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
5364 Pattern->AddPlaceholderChunk("arguments");
5365 Results.AddResult(Pattern);
5366
5367 if (getLangOptions().ObjC1) {
5368 // #import "header"
5369 Pattern = new CodeCompletionString;
5370 Pattern->AddTypedTextChunk("import");
5371 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
5372 Pattern->AddTextChunk("\"");
5373 Pattern->AddPlaceholderChunk("header");
5374 Pattern->AddTextChunk("\"");
5375 Results.AddResult(Pattern);
5376
5377 // #import <header>
5378 Pattern = new CodeCompletionString;
5379 Pattern->AddTypedTextChunk("import");
5380 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
5381 Pattern->AddTextChunk("<");
5382 Pattern->AddPlaceholderChunk("header");
5383 Pattern->AddTextChunk(">");
5384 Results.AddResult(Pattern);
5385 }
5386
5387 // #include_next "header"
5388 Pattern = new CodeCompletionString;
5389 Pattern->AddTypedTextChunk("include_next");
5390 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
5391 Pattern->AddTextChunk("\"");
5392 Pattern->AddPlaceholderChunk("header");
5393 Pattern->AddTextChunk("\"");
5394 Results.AddResult(Pattern);
5395
5396 // #include_next <header>
5397 Pattern = new CodeCompletionString;
5398 Pattern->AddTypedTextChunk("include_next");
5399 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
5400 Pattern->AddTextChunk("<");
5401 Pattern->AddPlaceholderChunk("header");
5402 Pattern->AddTextChunk(">");
5403 Results.AddResult(Pattern);
5404
5405 // #warning <message>
5406 Pattern = new CodeCompletionString;
5407 Pattern->AddTypedTextChunk("warning");
5408 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
5409 Pattern->AddPlaceholderChunk("message");
5410 Results.AddResult(Pattern);
5411
5412 // Note: #ident and #sccs are such crazy anachronisms that we don't provide
5413 // completions for them. And __include_macros is a Clang-internal extension
5414 // that we don't want to encourage anyone to use.
5415
5416 // FIXME: we don't support #assert or #unassert, so don't suggest them.
5417 Results.ExitScope();
5418
Douglas Gregorf44e8542010-08-24 19:08:16 +00005419 HandleCodeCompleteResults(this, CodeCompleter,
Douglas Gregor721f3592010-08-25 18:41:16 +00005420 CodeCompletionContext::CCC_PreprocessorDirective,
Douglas Gregorf44e8542010-08-24 19:08:16 +00005421 Results.data(), Results.size());
5422}
5423
5424void Sema::CodeCompleteInPreprocessorConditionalExclusion(Scope *S) {
Douglas Gregorf29c5232010-08-24 22:20:20 +00005425 CodeCompleteOrdinaryName(S,
John McCallf312b1e2010-08-26 23:41:50 +00005426 S->getFnParent()? Sema::PCC_RecoveryInFunction
5427 : Sema::PCC_Namespace);
Douglas Gregorf44e8542010-08-24 19:08:16 +00005428}
5429
Douglas Gregorf29c5232010-08-24 22:20:20 +00005430void Sema::CodeCompletePreprocessorMacroName(bool IsDefinition) {
Douglas Gregor1fbb4472010-08-24 20:21:13 +00005431 ResultBuilder Results(*this);
5432 if (!IsDefinition && (!CodeCompleter || CodeCompleter->includeMacros())) {
5433 // Add just the names of macros, not their arguments.
5434 Results.EnterNewScope();
5435 for (Preprocessor::macro_iterator M = PP.macro_begin(),
5436 MEnd = PP.macro_end();
5437 M != MEnd; ++M) {
5438 CodeCompletionString *Pattern = new CodeCompletionString;
5439 Pattern->AddTypedTextChunk(M->first->getName());
5440 Results.AddResult(Pattern);
5441 }
5442 Results.ExitScope();
5443 } else if (IsDefinition) {
5444 // FIXME: Can we detect when the user just wrote an include guard above?
5445 }
5446
5447 HandleCodeCompleteResults(this, CodeCompleter,
5448 IsDefinition? CodeCompletionContext::CCC_MacroName
5449 : CodeCompletionContext::CCC_MacroNameUse,
5450 Results.data(), Results.size());
5451}
5452
Douglas Gregorf29c5232010-08-24 22:20:20 +00005453void Sema::CodeCompletePreprocessorExpression() {
5454 ResultBuilder Results(*this);
5455
5456 if (!CodeCompleter || CodeCompleter->includeMacros())
5457 AddMacroResults(PP, Results);
5458
5459 // defined (<macro>)
5460 Results.EnterNewScope();
5461 CodeCompletionString *Pattern = new CodeCompletionString;
5462 Pattern->AddTypedTextChunk("defined");
5463 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
5464 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
5465 Pattern->AddPlaceholderChunk("macro");
5466 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
5467 Results.AddResult(Pattern);
5468 Results.ExitScope();
5469
5470 HandleCodeCompleteResults(this, CodeCompleter,
5471 CodeCompletionContext::CCC_PreprocessorExpression,
5472 Results.data(), Results.size());
5473}
5474
5475void Sema::CodeCompletePreprocessorMacroArgument(Scope *S,
5476 IdentifierInfo *Macro,
5477 MacroInfo *MacroInfo,
5478 unsigned Argument) {
5479 // FIXME: In the future, we could provide "overload" results, much like we
5480 // do for function calls.
5481
5482 CodeCompleteOrdinaryName(S,
John McCallf312b1e2010-08-26 23:41:50 +00005483 S->getFnParent()? Sema::PCC_RecoveryInFunction
5484 : Sema::PCC_Namespace);
Douglas Gregorf29c5232010-08-24 22:20:20 +00005485}
5486
Douglas Gregor55817af2010-08-25 17:04:25 +00005487void Sema::CodeCompleteNaturalLanguage() {
Douglas Gregor55817af2010-08-25 17:04:25 +00005488 HandleCodeCompleteResults(this, CodeCompleter,
Douglas Gregoraf1c6b52010-08-25 17:10:00 +00005489 CodeCompletionContext::CCC_NaturalLanguage,
Douglas Gregor55817af2010-08-25 17:04:25 +00005490 0, 0);
5491}
5492
Douglas Gregor87c08a52010-08-13 22:48:40 +00005493void Sema::GatherGlobalCodeCompletions(
John McCall0a2c5e22010-08-25 06:19:51 +00005494 llvm::SmallVectorImpl<CodeCompletionResult> &Results) {
Douglas Gregor87c08a52010-08-13 22:48:40 +00005495 ResultBuilder Builder(*this);
5496
Douglas Gregor8071e422010-08-15 06:18:01 +00005497 if (!CodeCompleter || CodeCompleter->includeGlobals()) {
5498 CodeCompletionDeclConsumer Consumer(Builder,
5499 Context.getTranslationUnitDecl());
5500 LookupVisibleDecls(Context.getTranslationUnitDecl(), LookupAnyName,
5501 Consumer);
5502 }
Douglas Gregor87c08a52010-08-13 22:48:40 +00005503
5504 if (!CodeCompleter || CodeCompleter->includeMacros())
5505 AddMacroResults(PP, Builder);
5506
5507 Results.clear();
5508 Results.insert(Results.end(),
5509 Builder.data(), Builder.data() + Builder.size());
5510}