blob: 615d126fb37c6f36618c92ec8337c795041c19c6 [file] [log] [blame]
Douglas Gregor81b747b2009-09-17 21:32:03 +00001//===---------------- SemaCodeComplete.cpp - Code Completion ----*- C++ -*-===//
2//
3// The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9//
10// This file defines the code-completion semantic actions.
11//
12//===----------------------------------------------------------------------===//
John McCall2d887082010-08-25 22:03:47 +000013#include "clang/Sema/SemaInternal.h"
Douglas Gregore737f502010-08-12 20:07:10 +000014#include "clang/Sema/Lookup.h"
John McCall120d63c2010-08-24 20:38:10 +000015#include "clang/Sema/Overload.h"
Douglas Gregor81b747b2009-09-17 21:32:03 +000016#include "clang/Sema/CodeCompleteConsumer.h"
Douglas Gregor719770d2010-04-06 17:30:22 +000017#include "clang/Sema/ExternalSemaSource.h"
John McCall5f1e0942010-08-24 08:50:51 +000018#include "clang/Sema/Scope.h"
John McCall781472f2010-08-25 08:40:02 +000019#include "clang/Sema/ScopeInfo.h"
John McCall7cd088e2010-08-24 07:21:54 +000020#include "clang/AST/DeclObjC.h"
Douglas Gregorb9d0ef72009-09-21 19:57:38 +000021#include "clang/AST/ExprCXX.h"
Douglas Gregor24a069f2009-11-17 17:59:40 +000022#include "clang/AST/ExprObjC.h"
Douglas Gregor3f7c7f42009-10-30 16:50:04 +000023#include "clang/Lex/MacroInfo.h"
24#include "clang/Lex/Preprocessor.h"
Douglas Gregor86d9a522009-09-21 16:56:56 +000025#include "llvm/ADT/SmallPtrSet.h"
Douglas Gregor6a684032009-09-28 03:51:44 +000026#include "llvm/ADT/StringExtras.h"
Douglas Gregor22f56992010-04-06 19:22:33 +000027#include "llvm/ADT/StringSwitch.h"
Douglas Gregor458433d2010-08-26 15:07:07 +000028#include "llvm/ADT/Twine.h"
Douglas Gregor86d9a522009-09-21 16:56:56 +000029#include <list>
30#include <map>
31#include <vector>
Douglas Gregor81b747b2009-09-17 21:32:03 +000032
33using namespace clang;
John McCall781472f2010-08-25 08:40:02 +000034using namespace sema;
Douglas Gregor81b747b2009-09-17 21:32:03 +000035
Douglas Gregor86d9a522009-09-21 16:56:56 +000036namespace {
37 /// \brief A container of code-completion results.
38 class ResultBuilder {
39 public:
40 /// \brief The type of a name-lookup filter, which can be provided to the
41 /// name-lookup routines to specify which declarations should be included in
42 /// the result set (when it returns true) and which declarations should be
43 /// filtered out (returns false).
44 typedef bool (ResultBuilder::*LookupFilter)(NamedDecl *) const;
45
John McCall0a2c5e22010-08-25 06:19:51 +000046 typedef CodeCompletionResult Result;
Douglas Gregor86d9a522009-09-21 16:56:56 +000047
48 private:
49 /// \brief The actual results we have found.
50 std::vector<Result> Results;
51
52 /// \brief A record of all of the declarations we have found and placed
53 /// into the result set, used to ensure that no declaration ever gets into
54 /// the result set twice.
55 llvm::SmallPtrSet<Decl*, 16> AllDeclsFound;
56
Douglas Gregorfbcb5d62009-12-06 20:23:50 +000057 typedef std::pair<NamedDecl *, unsigned> DeclIndexPair;
58
59 /// \brief An entry in the shadow map, which is optimized to store
60 /// a single (declaration, index) mapping (the common case) but
61 /// can also store a list of (declaration, index) mappings.
62 class ShadowMapEntry {
63 typedef llvm::SmallVector<DeclIndexPair, 4> DeclIndexPairVector;
64
65 /// \brief Contains either the solitary NamedDecl * or a vector
66 /// of (declaration, index) pairs.
67 llvm::PointerUnion<NamedDecl *, DeclIndexPairVector*> DeclOrVector;
68
69 /// \brief When the entry contains a single declaration, this is
70 /// the index associated with that entry.
71 unsigned SingleDeclIndex;
72
73 public:
74 ShadowMapEntry() : DeclOrVector(), SingleDeclIndex(0) { }
75
76 void Add(NamedDecl *ND, unsigned Index) {
77 if (DeclOrVector.isNull()) {
78 // 0 - > 1 elements: just set the single element information.
79 DeclOrVector = ND;
80 SingleDeclIndex = Index;
81 return;
82 }
83
84 if (NamedDecl *PrevND = DeclOrVector.dyn_cast<NamedDecl *>()) {
85 // 1 -> 2 elements: create the vector of results and push in the
86 // existing declaration.
87 DeclIndexPairVector *Vec = new DeclIndexPairVector;
88 Vec->push_back(DeclIndexPair(PrevND, SingleDeclIndex));
89 DeclOrVector = Vec;
90 }
91
92 // Add the new element to the end of the vector.
93 DeclOrVector.get<DeclIndexPairVector*>()->push_back(
94 DeclIndexPair(ND, Index));
95 }
96
97 void Destroy() {
98 if (DeclIndexPairVector *Vec
99 = DeclOrVector.dyn_cast<DeclIndexPairVector *>()) {
100 delete Vec;
101 DeclOrVector = ((NamedDecl *)0);
102 }
103 }
104
105 // Iteration.
106 class iterator;
107 iterator begin() const;
108 iterator end() const;
109 };
110
Douglas Gregor86d9a522009-09-21 16:56:56 +0000111 /// \brief A mapping from declaration names to the declarations that have
112 /// this name within a particular scope and their index within the list of
113 /// results.
Douglas Gregorfbcb5d62009-12-06 20:23:50 +0000114 typedef llvm::DenseMap<DeclarationName, ShadowMapEntry> ShadowMap;
Douglas Gregor86d9a522009-09-21 16:56:56 +0000115
116 /// \brief The semantic analysis object for which results are being
117 /// produced.
118 Sema &SemaRef;
119
120 /// \brief If non-NULL, a filter function used to remove any code-completion
121 /// results that are not desirable.
122 LookupFilter Filter;
Douglas Gregor45bcd432010-01-14 03:21:49 +0000123
124 /// \brief Whether we should allow declarations as
125 /// nested-name-specifiers that would otherwise be filtered out.
126 bool AllowNestedNameSpecifiers;
127
Douglas Gregor5ac3bdb2010-05-30 01:49:25 +0000128 /// \brief If set, the type that we would prefer our resulting value
129 /// declarations to have.
130 ///
131 /// Closely matching the preferred type gives a boost to a result's
132 /// priority.
133 CanQualType PreferredType;
134
Douglas Gregor86d9a522009-09-21 16:56:56 +0000135 /// \brief A list of shadow maps, which is used to model name hiding at
136 /// different levels of, e.g., the inheritance hierarchy.
137 std::list<ShadowMap> ShadowMaps;
138
Douglas Gregor3cdee122010-08-26 16:36:48 +0000139 /// \brief If we're potentially referring to a C++ member function, the set
140 /// of qualifiers applied to the object type.
141 Qualifiers ObjectTypeQualifiers;
142
143 /// \brief Whether the \p ObjectTypeQualifiers field is active.
144 bool HasObjectTypeQualifiers;
145
Douglas Gregor265f7492010-08-27 15:29:55 +0000146 /// \brief The selector that we prefer.
147 Selector PreferredSelector;
148
Douglas Gregor1f5537a2010-07-08 23:20:03 +0000149 void AdjustResultPriorityForPreferredType(Result &R);
150
Douglas Gregor86d9a522009-09-21 16:56:56 +0000151 public:
152 explicit ResultBuilder(Sema &SemaRef, LookupFilter Filter = 0)
Douglas Gregor3cdee122010-08-26 16:36:48 +0000153 : SemaRef(SemaRef), Filter(Filter), AllowNestedNameSpecifiers(false),
154 HasObjectTypeQualifiers(false) { }
Douglas Gregor86d9a522009-09-21 16:56:56 +0000155
Douglas Gregord8e8a582010-05-25 21:41:55 +0000156 /// \brief Whether we should include code patterns in the completion
157 /// results.
158 bool includeCodePatterns() const {
159 return SemaRef.CodeCompleter &&
Douglas Gregorf6961522010-08-27 21:18:54 +0000160 SemaRef.CodeCompleter->includeCodePatterns();
Douglas Gregord8e8a582010-05-25 21:41:55 +0000161 }
162
Douglas Gregor86d9a522009-09-21 16:56:56 +0000163 /// \brief Set the filter used for code-completion results.
164 void setFilter(LookupFilter Filter) {
165 this->Filter = Filter;
166 }
167
Douglas Gregor86d9a522009-09-21 16:56:56 +0000168 Result *data() { return Results.empty()? 0 : &Results.front(); }
169 unsigned size() const { return Results.size(); }
170 bool empty() const { return Results.empty(); }
171
Douglas Gregor5ac3bdb2010-05-30 01:49:25 +0000172 /// \brief Specify the preferred type.
173 void setPreferredType(QualType T) {
174 PreferredType = SemaRef.Context.getCanonicalType(T);
175 }
176
Douglas Gregor3cdee122010-08-26 16:36:48 +0000177 /// \brief Set the cv-qualifiers on the object type, for us in filtering
178 /// calls to member functions.
179 ///
180 /// When there are qualifiers in this set, they will be used to filter
181 /// out member functions that aren't available (because there will be a
182 /// cv-qualifier mismatch) or prefer functions with an exact qualifier
183 /// match.
184 void setObjectTypeQualifiers(Qualifiers Quals) {
185 ObjectTypeQualifiers = Quals;
186 HasObjectTypeQualifiers = true;
187 }
188
Douglas Gregor265f7492010-08-27 15:29:55 +0000189 /// \brief Set the preferred selector.
190 ///
191 /// When an Objective-C method declaration result is added, and that
192 /// method's selector matches this preferred selector, we give that method
193 /// a slight priority boost.
194 void setPreferredSelector(Selector Sel) {
195 PreferredSelector = Sel;
196 }
197
Douglas Gregor45bcd432010-01-14 03:21:49 +0000198 /// \brief Specify whether nested-name-specifiers are allowed.
199 void allowNestedNameSpecifiers(bool Allow = true) {
200 AllowNestedNameSpecifiers = Allow;
201 }
202
Douglas Gregore495b7f2010-01-14 00:20:49 +0000203 /// \brief Determine whether the given declaration is at all interesting
204 /// as a code-completion result.
Douglas Gregor45bcd432010-01-14 03:21:49 +0000205 ///
206 /// \param ND the declaration that we are inspecting.
207 ///
208 /// \param AsNestedNameSpecifier will be set true if this declaration is
209 /// only interesting when it is a nested-name-specifier.
210 bool isInterestingDecl(NamedDecl *ND, bool &AsNestedNameSpecifier) const;
Douglas Gregor6660d842010-01-14 00:41:07 +0000211
212 /// \brief Check whether the result is hidden by the Hiding declaration.
213 ///
214 /// \returns true if the result is hidden and cannot be found, false if
215 /// the hidden result could still be found. When false, \p R may be
216 /// modified to describe how the result can be found (e.g., via extra
217 /// qualification).
218 bool CheckHiddenResult(Result &R, DeclContext *CurContext,
219 NamedDecl *Hiding);
220
Douglas Gregor86d9a522009-09-21 16:56:56 +0000221 /// \brief Add a new result to this result set (if it isn't already in one
222 /// of the shadow maps), or replace an existing result (for, e.g., a
223 /// redeclaration).
Douglas Gregor456c4a12009-09-21 20:12:40 +0000224 ///
Douglas Gregor1ca6ae82010-01-14 01:09:38 +0000225 /// \param CurContext the result to add (if it is unique).
Douglas Gregor456c4a12009-09-21 20:12:40 +0000226 ///
227 /// \param R the context in which this result will be named.
228 void MaybeAddResult(Result R, DeclContext *CurContext = 0);
Douglas Gregor86d9a522009-09-21 16:56:56 +0000229
Douglas Gregor1ca6ae82010-01-14 01:09:38 +0000230 /// \brief Add a new result to this result set, where we already know
231 /// the hiding declation (if any).
232 ///
233 /// \param R the result to add (if it is unique).
234 ///
235 /// \param CurContext the context in which this result will be named.
236 ///
237 /// \param Hiding the declaration that hides the result.
Douglas Gregor0cc84042010-01-14 15:47:35 +0000238 ///
239 /// \param InBaseClass whether the result was found in a base
240 /// class of the searched context.
241 void AddResult(Result R, DeclContext *CurContext, NamedDecl *Hiding,
242 bool InBaseClass);
Douglas Gregor1ca6ae82010-01-14 01:09:38 +0000243
Douglas Gregora4477812010-01-14 16:01:26 +0000244 /// \brief Add a new non-declaration result to this result set.
245 void AddResult(Result R);
246
Douglas Gregor86d9a522009-09-21 16:56:56 +0000247 /// \brief Enter into a new scope.
248 void EnterNewScope();
249
250 /// \brief Exit from the current scope.
251 void ExitScope();
252
Douglas Gregor55385fe2009-11-18 04:19:12 +0000253 /// \brief Ignore this declaration, if it is seen again.
254 void Ignore(Decl *D) { AllDeclsFound.insert(D->getCanonicalDecl()); }
255
Douglas Gregor86d9a522009-09-21 16:56:56 +0000256 /// \name Name lookup predicates
257 ///
258 /// These predicates can be passed to the name lookup functions to filter the
259 /// results of name lookup. All of the predicates have the same type, so that
260 ///
261 //@{
Douglas Gregor791215b2009-09-21 20:51:25 +0000262 bool IsOrdinaryName(NamedDecl *ND) const;
Douglas Gregor4710e5b2010-05-28 00:49:12 +0000263 bool IsOrdinaryNonTypeName(NamedDecl *ND) const;
Douglas Gregorf9578432010-07-28 21:50:18 +0000264 bool IsIntegralConstantValue(NamedDecl *ND) const;
Douglas Gregor01dfea02010-01-10 23:08:15 +0000265 bool IsOrdinaryNonValueName(NamedDecl *ND) const;
Douglas Gregor86d9a522009-09-21 16:56:56 +0000266 bool IsNestedNameSpecifier(NamedDecl *ND) const;
267 bool IsEnum(NamedDecl *ND) const;
268 bool IsClassOrStruct(NamedDecl *ND) const;
269 bool IsUnion(NamedDecl *ND) const;
270 bool IsNamespace(NamedDecl *ND) const;
271 bool IsNamespaceOrAlias(NamedDecl *ND) const;
272 bool IsType(NamedDecl *ND) const;
Douglas Gregoreb5758b2009-09-23 22:26:46 +0000273 bool IsMember(NamedDecl *ND) const;
Douglas Gregor80f4f4c2010-01-14 16:08:12 +0000274 bool IsObjCIvar(NamedDecl *ND) const;
Douglas Gregor8e254cf2010-05-27 23:06:34 +0000275 bool IsObjCMessageReceiver(NamedDecl *ND) const;
Douglas Gregorfb629412010-08-23 21:17:50 +0000276 bool IsObjCCollection(NamedDecl *ND) const;
Douglas Gregor86d9a522009-09-21 16:56:56 +0000277 //@}
278 };
279}
280
Douglas Gregorfbcb5d62009-12-06 20:23:50 +0000281class ResultBuilder::ShadowMapEntry::iterator {
282 llvm::PointerUnion<NamedDecl*, const DeclIndexPair*> DeclOrIterator;
283 unsigned SingleDeclIndex;
284
285public:
286 typedef DeclIndexPair value_type;
287 typedef value_type reference;
288 typedef std::ptrdiff_t difference_type;
289 typedef std::input_iterator_tag iterator_category;
290
291 class pointer {
292 DeclIndexPair Value;
293
294 public:
295 pointer(const DeclIndexPair &Value) : Value(Value) { }
296
297 const DeclIndexPair *operator->() const {
298 return &Value;
299 }
300 };
301
302 iterator() : DeclOrIterator((NamedDecl *)0), SingleDeclIndex(0) { }
303
304 iterator(NamedDecl *SingleDecl, unsigned Index)
305 : DeclOrIterator(SingleDecl), SingleDeclIndex(Index) { }
306
307 iterator(const DeclIndexPair *Iterator)
308 : DeclOrIterator(Iterator), SingleDeclIndex(0) { }
309
310 iterator &operator++() {
311 if (DeclOrIterator.is<NamedDecl *>()) {
312 DeclOrIterator = (NamedDecl *)0;
313 SingleDeclIndex = 0;
314 return *this;
315 }
316
317 const DeclIndexPair *I = DeclOrIterator.get<const DeclIndexPair*>();
318 ++I;
319 DeclOrIterator = I;
320 return *this;
321 }
322
Chris Lattner66392d42010-09-04 18:12:20 +0000323 /*iterator operator++(int) {
Douglas Gregorfbcb5d62009-12-06 20:23:50 +0000324 iterator tmp(*this);
325 ++(*this);
326 return tmp;
Chris Lattner66392d42010-09-04 18:12:20 +0000327 }*/
Douglas Gregorfbcb5d62009-12-06 20:23:50 +0000328
329 reference operator*() const {
330 if (NamedDecl *ND = DeclOrIterator.dyn_cast<NamedDecl *>())
331 return reference(ND, SingleDeclIndex);
332
Douglas Gregord490f952009-12-06 21:27:58 +0000333 return *DeclOrIterator.get<const DeclIndexPair*>();
Douglas Gregorfbcb5d62009-12-06 20:23:50 +0000334 }
335
336 pointer operator->() const {
337 return pointer(**this);
338 }
339
340 friend bool operator==(const iterator &X, const iterator &Y) {
Douglas Gregord490f952009-12-06 21:27:58 +0000341 return X.DeclOrIterator.getOpaqueValue()
342 == Y.DeclOrIterator.getOpaqueValue() &&
Douglas Gregorfbcb5d62009-12-06 20:23:50 +0000343 X.SingleDeclIndex == Y.SingleDeclIndex;
344 }
345
346 friend bool operator!=(const iterator &X, const iterator &Y) {
Douglas Gregord490f952009-12-06 21:27:58 +0000347 return !(X == Y);
Douglas Gregorfbcb5d62009-12-06 20:23:50 +0000348 }
349};
350
Douglas Gregorfbcb5d62009-12-06 20:23:50 +0000351ResultBuilder::ShadowMapEntry::iterator
352ResultBuilder::ShadowMapEntry::begin() const {
353 if (DeclOrVector.isNull())
354 return iterator();
355
356 if (NamedDecl *ND = DeclOrVector.dyn_cast<NamedDecl *>())
357 return iterator(ND, SingleDeclIndex);
358
359 return iterator(DeclOrVector.get<DeclIndexPairVector *>()->begin());
360}
361
362ResultBuilder::ShadowMapEntry::iterator
363ResultBuilder::ShadowMapEntry::end() const {
364 if (DeclOrVector.is<NamedDecl *>() || DeclOrVector.isNull())
365 return iterator();
366
367 return iterator(DeclOrVector.get<DeclIndexPairVector *>()->end());
368}
369
Douglas Gregor456c4a12009-09-21 20:12:40 +0000370/// \brief Compute the qualification required to get from the current context
371/// (\p CurContext) to the target context (\p TargetContext).
372///
373/// \param Context the AST context in which the qualification will be used.
374///
375/// \param CurContext the context where an entity is being named, which is
376/// typically based on the current scope.
377///
378/// \param TargetContext the context in which the named entity actually
379/// resides.
380///
381/// \returns a nested name specifier that refers into the target context, or
382/// NULL if no qualification is needed.
383static NestedNameSpecifier *
384getRequiredQualification(ASTContext &Context,
385 DeclContext *CurContext,
386 DeclContext *TargetContext) {
387 llvm::SmallVector<DeclContext *, 4> TargetParents;
388
389 for (DeclContext *CommonAncestor = TargetContext;
390 CommonAncestor && !CommonAncestor->Encloses(CurContext);
391 CommonAncestor = CommonAncestor->getLookupParent()) {
392 if (CommonAncestor->isTransparentContext() ||
393 CommonAncestor->isFunctionOrMethod())
394 continue;
395
396 TargetParents.push_back(CommonAncestor);
397 }
398
399 NestedNameSpecifier *Result = 0;
400 while (!TargetParents.empty()) {
401 DeclContext *Parent = TargetParents.back();
402 TargetParents.pop_back();
403
Douglas Gregorfb629412010-08-23 21:17:50 +0000404 if (NamespaceDecl *Namespace = dyn_cast<NamespaceDecl>(Parent)) {
405 if (!Namespace->getIdentifier())
406 continue;
407
Douglas Gregor456c4a12009-09-21 20:12:40 +0000408 Result = NestedNameSpecifier::Create(Context, Result, Namespace);
Douglas Gregorfb629412010-08-23 21:17:50 +0000409 }
Douglas Gregor456c4a12009-09-21 20:12:40 +0000410 else if (TagDecl *TD = dyn_cast<TagDecl>(Parent))
411 Result = NestedNameSpecifier::Create(Context, Result,
412 false,
413 Context.getTypeDeclType(TD).getTypePtr());
Douglas Gregor0c8296d2009-11-07 00:00:49 +0000414 }
Douglas Gregor456c4a12009-09-21 20:12:40 +0000415 return Result;
416}
417
Douglas Gregor45bcd432010-01-14 03:21:49 +0000418bool ResultBuilder::isInterestingDecl(NamedDecl *ND,
419 bool &AsNestedNameSpecifier) const {
420 AsNestedNameSpecifier = false;
421
Douglas Gregore495b7f2010-01-14 00:20:49 +0000422 ND = ND->getUnderlyingDecl();
423 unsigned IDNS = ND->getIdentifierNamespace();
Douglas Gregorf52cede2009-10-09 22:16:47 +0000424
425 // Skip unnamed entities.
Douglas Gregore495b7f2010-01-14 00:20:49 +0000426 if (!ND->getDeclName())
427 return false;
Douglas Gregor86d9a522009-09-21 16:56:56 +0000428
429 // Friend declarations and declarations introduced due to friends are never
430 // added as results.
John McCall92b7f702010-03-11 07:50:04 +0000431 if (IDNS & (Decl::IDNS_OrdinaryFriend | Decl::IDNS_TagFriend))
Douglas Gregore495b7f2010-01-14 00:20:49 +0000432 return false;
433
Douglas Gregor76282942009-12-11 17:31:05 +0000434 // Class template (partial) specializations are never added as results.
Douglas Gregore495b7f2010-01-14 00:20:49 +0000435 if (isa<ClassTemplateSpecializationDecl>(ND) ||
436 isa<ClassTemplatePartialSpecializationDecl>(ND))
437 return false;
Douglas Gregor86d9a522009-09-21 16:56:56 +0000438
Douglas Gregor76282942009-12-11 17:31:05 +0000439 // Using declarations themselves are never added as results.
Douglas Gregore495b7f2010-01-14 00:20:49 +0000440 if (isa<UsingDecl>(ND))
441 return false;
442
443 // Some declarations have reserved names that we don't want to ever show.
444 if (const IdentifierInfo *Id = ND->getIdentifier()) {
Douglas Gregor86d9a522009-09-21 16:56:56 +0000445 // __va_list_tag is a freak of nature. Find it and skip it.
446 if (Id->isStr("__va_list_tag") || Id->isStr("__builtin_va_list"))
Douglas Gregore495b7f2010-01-14 00:20:49 +0000447 return false;
Douglas Gregor86d9a522009-09-21 16:56:56 +0000448
Douglas Gregorf52cede2009-10-09 22:16:47 +0000449 // Filter out names reserved for the implementation (C99 7.1.3,
Douglas Gregor797efb52010-07-14 17:44:04 +0000450 // C++ [lib.global.names]) if they come from a system header.
Daniel Dunbare013d682009-10-18 20:26:12 +0000451 //
452 // FIXME: Add predicate for this.
Douglas Gregorf52cede2009-10-09 22:16:47 +0000453 if (Id->getLength() >= 2) {
Daniel Dunbare013d682009-10-18 20:26:12 +0000454 const char *Name = Id->getNameStart();
Douglas Gregorf52cede2009-10-09 22:16:47 +0000455 if (Name[0] == '_' &&
Douglas Gregor797efb52010-07-14 17:44:04 +0000456 (Name[1] == '_' || (Name[1] >= 'A' && Name[1] <= 'Z')) &&
457 (ND->getLocation().isInvalid() ||
458 SemaRef.SourceMgr.isInSystemHeader(
459 SemaRef.SourceMgr.getSpellingLoc(ND->getLocation()))))
Douglas Gregore495b7f2010-01-14 00:20:49 +0000460 return false;
Douglas Gregorf52cede2009-10-09 22:16:47 +0000461 }
Douglas Gregor86d9a522009-09-21 16:56:56 +0000462 }
Douglas Gregore495b7f2010-01-14 00:20:49 +0000463
Douglas Gregor86d9a522009-09-21 16:56:56 +0000464 // C++ constructors are never found by name lookup.
Douglas Gregore495b7f2010-01-14 00:20:49 +0000465 if (isa<CXXConstructorDecl>(ND))
466 return false;
Douglas Gregor86d9a522009-09-21 16:56:56 +0000467
Douglas Gregora5fb7c32010-08-16 23:05:20 +0000468 if (Filter == &ResultBuilder::IsNestedNameSpecifier ||
469 ((isa<NamespaceDecl>(ND) || isa<NamespaceAliasDecl>(ND)) &&
470 Filter != &ResultBuilder::IsNamespace &&
471 Filter != &ResultBuilder::IsNamespaceOrAlias))
472 AsNestedNameSpecifier = true;
473
Douglas Gregor86d9a522009-09-21 16:56:56 +0000474 // Filter out any unwanted results.
Douglas Gregor45bcd432010-01-14 03:21:49 +0000475 if (Filter && !(this->*Filter)(ND)) {
476 // Check whether it is interesting as a nested-name-specifier.
477 if (AllowNestedNameSpecifiers && SemaRef.getLangOptions().CPlusPlus &&
478 IsNestedNameSpecifier(ND) &&
479 (Filter != &ResultBuilder::IsMember ||
480 (isa<CXXRecordDecl>(ND) &&
481 cast<CXXRecordDecl>(ND)->isInjectedClassName()))) {
482 AsNestedNameSpecifier = true;
483 return true;
484 }
485
Douglas Gregore495b7f2010-01-14 00:20:49 +0000486 return false;
Douglas Gregora5fb7c32010-08-16 23:05:20 +0000487 }
Douglas Gregore495b7f2010-01-14 00:20:49 +0000488 // ... then it must be interesting!
489 return true;
490}
491
Douglas Gregor6660d842010-01-14 00:41:07 +0000492bool ResultBuilder::CheckHiddenResult(Result &R, DeclContext *CurContext,
493 NamedDecl *Hiding) {
494 // In C, there is no way to refer to a hidden name.
495 // FIXME: This isn't true; we can find a tag name hidden by an ordinary
496 // name if we introduce the tag type.
497 if (!SemaRef.getLangOptions().CPlusPlus)
498 return true;
499
Sebastian Redl7a126a42010-08-31 00:36:30 +0000500 DeclContext *HiddenCtx = R.Declaration->getDeclContext()->getRedeclContext();
Douglas Gregor6660d842010-01-14 00:41:07 +0000501
502 // There is no way to qualify a name declared in a function or method.
503 if (HiddenCtx->isFunctionOrMethod())
504 return true;
505
Sebastian Redl7a126a42010-08-31 00:36:30 +0000506 if (HiddenCtx == Hiding->getDeclContext()->getRedeclContext())
Douglas Gregor6660d842010-01-14 00:41:07 +0000507 return true;
508
509 // We can refer to the result with the appropriate qualification. Do it.
510 R.Hidden = true;
511 R.QualifierIsInformative = false;
512
513 if (!R.Qualifier)
514 R.Qualifier = getRequiredQualification(SemaRef.Context,
515 CurContext,
516 R.Declaration->getDeclContext());
517 return false;
518}
519
Douglas Gregor1f5537a2010-07-08 23:20:03 +0000520/// \brief A simplified classification of types used to determine whether two
521/// types are "similar enough" when adjusting priorities.
Douglas Gregor1827e102010-08-16 16:18:59 +0000522SimplifiedTypeClass clang::getSimplifiedTypeClass(CanQualType T) {
Douglas Gregor1f5537a2010-07-08 23:20:03 +0000523 switch (T->getTypeClass()) {
524 case Type::Builtin:
525 switch (cast<BuiltinType>(T)->getKind()) {
526 case BuiltinType::Void:
527 return STC_Void;
528
529 case BuiltinType::NullPtr:
530 return STC_Pointer;
531
532 case BuiltinType::Overload:
533 case BuiltinType::Dependent:
534 case BuiltinType::UndeducedAuto:
535 return STC_Other;
536
537 case BuiltinType::ObjCId:
538 case BuiltinType::ObjCClass:
539 case BuiltinType::ObjCSel:
540 return STC_ObjectiveC;
541
542 default:
543 return STC_Arithmetic;
544 }
545 return STC_Other;
546
547 case Type::Complex:
548 return STC_Arithmetic;
549
550 case Type::Pointer:
551 return STC_Pointer;
552
553 case Type::BlockPointer:
554 return STC_Block;
555
556 case Type::LValueReference:
557 case Type::RValueReference:
558 return getSimplifiedTypeClass(T->getAs<ReferenceType>()->getPointeeType());
559
560 case Type::ConstantArray:
561 case Type::IncompleteArray:
562 case Type::VariableArray:
563 case Type::DependentSizedArray:
564 return STC_Array;
565
566 case Type::DependentSizedExtVector:
567 case Type::Vector:
568 case Type::ExtVector:
569 return STC_Arithmetic;
570
571 case Type::FunctionProto:
572 case Type::FunctionNoProto:
573 return STC_Function;
574
575 case Type::Record:
576 return STC_Record;
577
578 case Type::Enum:
579 return STC_Arithmetic;
580
581 case Type::ObjCObject:
582 case Type::ObjCInterface:
583 case Type::ObjCObjectPointer:
584 return STC_ObjectiveC;
585
586 default:
587 return STC_Other;
588 }
589}
590
591/// \brief Get the type that a given expression will have if this declaration
592/// is used as an expression in its "typical" code-completion form.
Douglas Gregor1827e102010-08-16 16:18:59 +0000593QualType clang::getDeclUsageType(ASTContext &C, NamedDecl *ND) {
Douglas Gregor1f5537a2010-07-08 23:20:03 +0000594 ND = cast<NamedDecl>(ND->getUnderlyingDecl());
595
596 if (TypeDecl *Type = dyn_cast<TypeDecl>(ND))
597 return C.getTypeDeclType(Type);
598 if (ObjCInterfaceDecl *Iface = dyn_cast<ObjCInterfaceDecl>(ND))
599 return C.getObjCInterfaceType(Iface);
600
601 QualType T;
602 if (FunctionDecl *Function = dyn_cast<FunctionDecl>(ND))
Douglas Gregor5291c3c2010-07-13 08:18:22 +0000603 T = Function->getCallResultType();
Douglas Gregor1f5537a2010-07-08 23:20:03 +0000604 else if (ObjCMethodDecl *Method = dyn_cast<ObjCMethodDecl>(ND))
Douglas Gregor5291c3c2010-07-13 08:18:22 +0000605 T = Method->getSendResultType();
Douglas Gregor1f5537a2010-07-08 23:20:03 +0000606 else if (FunctionTemplateDecl *FunTmpl = dyn_cast<FunctionTemplateDecl>(ND))
Douglas Gregor5291c3c2010-07-13 08:18:22 +0000607 T = FunTmpl->getTemplatedDecl()->getCallResultType();
Douglas Gregor1f5537a2010-07-08 23:20:03 +0000608 else if (EnumConstantDecl *Enumerator = dyn_cast<EnumConstantDecl>(ND))
609 T = C.getTypeDeclType(cast<EnumDecl>(Enumerator->getDeclContext()));
610 else if (ObjCPropertyDecl *Property = dyn_cast<ObjCPropertyDecl>(ND))
611 T = Property->getType();
612 else if (ValueDecl *Value = dyn_cast<ValueDecl>(ND))
613 T = Value->getType();
614 else
615 return QualType();
616
617 return T.getNonReferenceType();
618}
619
620void ResultBuilder::AdjustResultPriorityForPreferredType(Result &R) {
621 QualType T = getDeclUsageType(SemaRef.Context, R.Declaration);
622 if (T.isNull())
623 return;
624
625 CanQualType TC = SemaRef.Context.getCanonicalType(T);
626 // Check for exactly-matching types (modulo qualifiers).
Douglas Gregoreb0d0142010-08-24 23:58:17 +0000627 if (SemaRef.Context.hasSameUnqualifiedType(PreferredType, TC)) {
628 if (PreferredType->isVoidType())
629 R.Priority += CCD_VoidMatch;
630 else
631 R.Priority /= CCF_ExactTypeMatch;
632 } // Check for nearly-matching types, based on classification of each.
Douglas Gregor1f5537a2010-07-08 23:20:03 +0000633 else if ((getSimplifiedTypeClass(PreferredType)
634 == getSimplifiedTypeClass(TC)) &&
635 !(PreferredType->isEnumeralType() && TC->isEnumeralType()))
636 R.Priority /= CCF_SimilarTypeMatch;
637}
638
Douglas Gregore495b7f2010-01-14 00:20:49 +0000639void ResultBuilder::MaybeAddResult(Result R, DeclContext *CurContext) {
640 assert(!ShadowMaps.empty() && "Must enter into a results scope");
641
642 if (R.Kind != Result::RK_Declaration) {
643 // For non-declaration results, just add the result.
644 Results.push_back(R);
645 return;
646 }
647
648 // Look through using declarations.
649 if (UsingShadowDecl *Using = dyn_cast<UsingShadowDecl>(R.Declaration)) {
650 MaybeAddResult(Result(Using->getTargetDecl(), R.Qualifier), CurContext);
651 return;
652 }
653
654 Decl *CanonDecl = R.Declaration->getCanonicalDecl();
655 unsigned IDNS = CanonDecl->getIdentifierNamespace();
656
Douglas Gregor45bcd432010-01-14 03:21:49 +0000657 bool AsNestedNameSpecifier = false;
658 if (!isInterestingDecl(R.Declaration, AsNestedNameSpecifier))
Douglas Gregore495b7f2010-01-14 00:20:49 +0000659 return;
660
Douglas Gregor86d9a522009-09-21 16:56:56 +0000661 ShadowMap &SMap = ShadowMaps.back();
Douglas Gregorfbcb5d62009-12-06 20:23:50 +0000662 ShadowMapEntry::iterator I, IEnd;
663 ShadowMap::iterator NamePos = SMap.find(R.Declaration->getDeclName());
664 if (NamePos != SMap.end()) {
665 I = NamePos->second.begin();
666 IEnd = NamePos->second.end();
667 }
668
669 for (; I != IEnd; ++I) {
670 NamedDecl *ND = I->first;
671 unsigned Index = I->second;
Douglas Gregor86d9a522009-09-21 16:56:56 +0000672 if (ND->getCanonicalDecl() == CanonDecl) {
673 // This is a redeclaration. Always pick the newer declaration.
Douglas Gregor86d9a522009-09-21 16:56:56 +0000674 Results[Index].Declaration = R.Declaration;
675
Douglas Gregor86d9a522009-09-21 16:56:56 +0000676 // We're done.
677 return;
678 }
679 }
680
681 // This is a new declaration in this scope. However, check whether this
682 // declaration name is hidden by a similarly-named declaration in an outer
683 // scope.
684 std::list<ShadowMap>::iterator SM, SMEnd = ShadowMaps.end();
685 --SMEnd;
686 for (SM = ShadowMaps.begin(); SM != SMEnd; ++SM) {
Douglas Gregorfbcb5d62009-12-06 20:23:50 +0000687 ShadowMapEntry::iterator I, IEnd;
688 ShadowMap::iterator NamePos = SM->find(R.Declaration->getDeclName());
689 if (NamePos != SM->end()) {
690 I = NamePos->second.begin();
691 IEnd = NamePos->second.end();
692 }
693 for (; I != IEnd; ++I) {
Douglas Gregor86d9a522009-09-21 16:56:56 +0000694 // A tag declaration does not hide a non-tag declaration.
John McCall0d6b1642010-04-23 18:46:30 +0000695 if (I->first->hasTagIdentifierNamespace() &&
Douglas Gregor86d9a522009-09-21 16:56:56 +0000696 (IDNS & (Decl::IDNS_Member | Decl::IDNS_Ordinary |
697 Decl::IDNS_ObjCProtocol)))
698 continue;
699
700 // Protocols are in distinct namespaces from everything else.
Douglas Gregorfbcb5d62009-12-06 20:23:50 +0000701 if (((I->first->getIdentifierNamespace() & Decl::IDNS_ObjCProtocol)
Douglas Gregor86d9a522009-09-21 16:56:56 +0000702 || (IDNS & Decl::IDNS_ObjCProtocol)) &&
Douglas Gregorfbcb5d62009-12-06 20:23:50 +0000703 I->first->getIdentifierNamespace() != IDNS)
Douglas Gregor86d9a522009-09-21 16:56:56 +0000704 continue;
705
706 // The newly-added result is hidden by an entry in the shadow map.
Douglas Gregor6660d842010-01-14 00:41:07 +0000707 if (CheckHiddenResult(R, CurContext, I->first))
Douglas Gregor86d9a522009-09-21 16:56:56 +0000708 return;
Douglas Gregor86d9a522009-09-21 16:56:56 +0000709
710 break;
711 }
712 }
713
714 // Make sure that any given declaration only shows up in the result set once.
715 if (!AllDeclsFound.insert(CanonDecl))
716 return;
Douglas Gregor265f7492010-08-27 15:29:55 +0000717
718 // If this is an Objective-C method declaration whose selector matches our
719 // preferred selector, give it a priority boost.
720 if (!PreferredSelector.isNull())
721 if (ObjCMethodDecl *Method = dyn_cast<ObjCMethodDecl>(R.Declaration))
722 if (PreferredSelector == Method->getSelector())
723 R.Priority += CCD_SelectorMatch;
724
Douglas Gregoreb5758b2009-09-23 22:26:46 +0000725 // If the filter is for nested-name-specifiers, then this result starts a
726 // nested-name-specifier.
Douglas Gregor12e13132010-05-26 22:00:08 +0000727 if (AsNestedNameSpecifier) {
Douglas Gregoreb5758b2009-09-23 22:26:46 +0000728 R.StartsNestedNameSpecifier = true;
Douglas Gregor12e13132010-05-26 22:00:08 +0000729 R.Priority = CCP_NestedNameSpecifier;
Douglas Gregor1f5537a2010-07-08 23:20:03 +0000730 } else if (!PreferredType.isNull())
731 AdjustResultPriorityForPreferredType(R);
Douglas Gregor265f7492010-08-27 15:29:55 +0000732
Douglas Gregor0563c262009-09-22 23:15:58 +0000733 // If this result is supposed to have an informative qualifier, add one.
Douglas Gregoreb5758b2009-09-23 22:26:46 +0000734 if (R.QualifierIsInformative && !R.Qualifier &&
735 !R.StartsNestedNameSpecifier) {
Douglas Gregor0563c262009-09-22 23:15:58 +0000736 DeclContext *Ctx = R.Declaration->getDeclContext();
737 if (NamespaceDecl *Namespace = dyn_cast<NamespaceDecl>(Ctx))
738 R.Qualifier = NestedNameSpecifier::Create(SemaRef.Context, 0, Namespace);
739 else if (TagDecl *Tag = dyn_cast<TagDecl>(Ctx))
740 R.Qualifier = NestedNameSpecifier::Create(SemaRef.Context, 0, false,
741 SemaRef.Context.getTypeDeclType(Tag).getTypePtr());
742 else
743 R.QualifierIsInformative = false;
744 }
Douglas Gregoreb5758b2009-09-23 22:26:46 +0000745
Douglas Gregor86d9a522009-09-21 16:56:56 +0000746 // Insert this result into the set of results and into the current shadow
747 // map.
Douglas Gregorfbcb5d62009-12-06 20:23:50 +0000748 SMap[R.Declaration->getDeclName()].Add(R.Declaration, Results.size());
Douglas Gregor86d9a522009-09-21 16:56:56 +0000749 Results.push_back(R);
750}
751
Douglas Gregor1ca6ae82010-01-14 01:09:38 +0000752void ResultBuilder::AddResult(Result R, DeclContext *CurContext,
Douglas Gregor0cc84042010-01-14 15:47:35 +0000753 NamedDecl *Hiding, bool InBaseClass = false) {
Douglas Gregora4477812010-01-14 16:01:26 +0000754 if (R.Kind != Result::RK_Declaration) {
755 // For non-declaration results, just add the result.
756 Results.push_back(R);
757 return;
758 }
759
Douglas Gregor1ca6ae82010-01-14 01:09:38 +0000760 // Look through using declarations.
761 if (UsingShadowDecl *Using = dyn_cast<UsingShadowDecl>(R.Declaration)) {
762 AddResult(Result(Using->getTargetDecl(), R.Qualifier), CurContext, Hiding);
763 return;
764 }
765
Douglas Gregor45bcd432010-01-14 03:21:49 +0000766 bool AsNestedNameSpecifier = false;
767 if (!isInterestingDecl(R.Declaration, AsNestedNameSpecifier))
Douglas Gregor1ca6ae82010-01-14 01:09:38 +0000768 return;
769
770 if (Hiding && CheckHiddenResult(R, CurContext, Hiding))
771 return;
772
773 // Make sure that any given declaration only shows up in the result set once.
774 if (!AllDeclsFound.insert(R.Declaration->getCanonicalDecl()))
775 return;
776
777 // If the filter is for nested-name-specifiers, then this result starts a
778 // nested-name-specifier.
Douglas Gregor12e13132010-05-26 22:00:08 +0000779 if (AsNestedNameSpecifier) {
Douglas Gregor1ca6ae82010-01-14 01:09:38 +0000780 R.StartsNestedNameSpecifier = true;
Douglas Gregor12e13132010-05-26 22:00:08 +0000781 R.Priority = CCP_NestedNameSpecifier;
782 }
Douglas Gregor0cc84042010-01-14 15:47:35 +0000783 else if (Filter == &ResultBuilder::IsMember && !R.Qualifier && InBaseClass &&
784 isa<CXXRecordDecl>(R.Declaration->getDeclContext()
Sebastian Redl7a126a42010-08-31 00:36:30 +0000785 ->getRedeclContext()))
Douglas Gregor0cc84042010-01-14 15:47:35 +0000786 R.QualifierIsInformative = true;
787
Douglas Gregor1ca6ae82010-01-14 01:09:38 +0000788 // If this result is supposed to have an informative qualifier, add one.
789 if (R.QualifierIsInformative && !R.Qualifier &&
790 !R.StartsNestedNameSpecifier) {
791 DeclContext *Ctx = R.Declaration->getDeclContext();
792 if (NamespaceDecl *Namespace = dyn_cast<NamespaceDecl>(Ctx))
793 R.Qualifier = NestedNameSpecifier::Create(SemaRef.Context, 0, Namespace);
794 else if (TagDecl *Tag = dyn_cast<TagDecl>(Ctx))
795 R.Qualifier = NestedNameSpecifier::Create(SemaRef.Context, 0, false,
Douglas Gregor45bcd432010-01-14 03:21:49 +0000796 SemaRef.Context.getTypeDeclType(Tag).getTypePtr());
Douglas Gregor1ca6ae82010-01-14 01:09:38 +0000797 else
798 R.QualifierIsInformative = false;
799 }
800
Douglas Gregor12e13132010-05-26 22:00:08 +0000801 // Adjust the priority if this result comes from a base class.
802 if (InBaseClass)
803 R.Priority += CCD_InBaseClass;
804
Douglas Gregor265f7492010-08-27 15:29:55 +0000805 // If this is an Objective-C method declaration whose selector matches our
806 // preferred selector, give it a priority boost.
807 if (!PreferredSelector.isNull())
808 if (ObjCMethodDecl *Method = dyn_cast<ObjCMethodDecl>(R.Declaration))
809 if (PreferredSelector == Method->getSelector())
810 R.Priority += CCD_SelectorMatch;
811
Douglas Gregor1f5537a2010-07-08 23:20:03 +0000812 if (!PreferredType.isNull())
813 AdjustResultPriorityForPreferredType(R);
Douglas Gregor5ac3bdb2010-05-30 01:49:25 +0000814
Douglas Gregor3cdee122010-08-26 16:36:48 +0000815 if (HasObjectTypeQualifiers)
816 if (CXXMethodDecl *Method = dyn_cast<CXXMethodDecl>(R.Declaration))
817 if (Method->isInstance()) {
818 Qualifiers MethodQuals
819 = Qualifiers::fromCVRMask(Method->getTypeQualifiers());
820 if (ObjectTypeQualifiers == MethodQuals)
821 R.Priority += CCD_ObjectQualifierMatch;
822 else if (ObjectTypeQualifiers - MethodQuals) {
823 // The method cannot be invoked, because doing so would drop
824 // qualifiers.
825 return;
826 }
827 }
828
Douglas Gregor1ca6ae82010-01-14 01:09:38 +0000829 // Insert this result into the set of results.
830 Results.push_back(R);
831}
832
Douglas Gregora4477812010-01-14 16:01:26 +0000833void ResultBuilder::AddResult(Result R) {
834 assert(R.Kind != Result::RK_Declaration &&
835 "Declaration results need more context");
836 Results.push_back(R);
837}
838
Douglas Gregor86d9a522009-09-21 16:56:56 +0000839/// \brief Enter into a new scope.
840void ResultBuilder::EnterNewScope() {
841 ShadowMaps.push_back(ShadowMap());
842}
843
844/// \brief Exit from the current scope.
845void ResultBuilder::ExitScope() {
Douglas Gregorfbcb5d62009-12-06 20:23:50 +0000846 for (ShadowMap::iterator E = ShadowMaps.back().begin(),
847 EEnd = ShadowMaps.back().end();
848 E != EEnd;
849 ++E)
850 E->second.Destroy();
851
Douglas Gregor86d9a522009-09-21 16:56:56 +0000852 ShadowMaps.pop_back();
853}
854
Douglas Gregor791215b2009-09-21 20:51:25 +0000855/// \brief Determines whether this given declaration will be found by
856/// ordinary name lookup.
857bool ResultBuilder::IsOrdinaryName(NamedDecl *ND) const {
Douglas Gregor4710e5b2010-05-28 00:49:12 +0000858 ND = cast<NamedDecl>(ND->getUnderlyingDecl());
859
Douglas Gregor791215b2009-09-21 20:51:25 +0000860 unsigned IDNS = Decl::IDNS_Ordinary;
861 if (SemaRef.getLangOptions().CPlusPlus)
Douglas Gregor9b30b262010-06-15 20:26:51 +0000862 IDNS |= Decl::IDNS_Tag | Decl::IDNS_Namespace | Decl::IDNS_Member;
Douglas Gregor1ca6ae82010-01-14 01:09:38 +0000863 else if (SemaRef.getLangOptions().ObjC1 && isa<ObjCIvarDecl>(ND))
864 return true;
865
Douglas Gregor791215b2009-09-21 20:51:25 +0000866 return ND->getIdentifierNamespace() & IDNS;
867}
868
Douglas Gregor01dfea02010-01-10 23:08:15 +0000869/// \brief Determines whether this given declaration will be found by
Douglas Gregor4710e5b2010-05-28 00:49:12 +0000870/// ordinary name lookup but is not a type name.
871bool ResultBuilder::IsOrdinaryNonTypeName(NamedDecl *ND) const {
872 ND = cast<NamedDecl>(ND->getUnderlyingDecl());
873 if (isa<TypeDecl>(ND) || isa<ObjCInterfaceDecl>(ND))
874 return false;
875
876 unsigned IDNS = Decl::IDNS_Ordinary;
877 if (SemaRef.getLangOptions().CPlusPlus)
Douglas Gregor9b30b262010-06-15 20:26:51 +0000878 IDNS |= Decl::IDNS_Tag | Decl::IDNS_Namespace | Decl::IDNS_Member;
Douglas Gregor4710e5b2010-05-28 00:49:12 +0000879 else if (SemaRef.getLangOptions().ObjC1 && isa<ObjCIvarDecl>(ND))
880 return true;
881
882 return ND->getIdentifierNamespace() & IDNS;
883}
884
Douglas Gregorf9578432010-07-28 21:50:18 +0000885bool ResultBuilder::IsIntegralConstantValue(NamedDecl *ND) const {
886 if (!IsOrdinaryNonTypeName(ND))
887 return 0;
888
889 if (ValueDecl *VD = dyn_cast<ValueDecl>(ND->getUnderlyingDecl()))
890 if (VD->getType()->isIntegralOrEnumerationType())
891 return true;
892
893 return false;
894}
895
Douglas Gregor4710e5b2010-05-28 00:49:12 +0000896/// \brief Determines whether this given declaration will be found by
Douglas Gregor01dfea02010-01-10 23:08:15 +0000897/// ordinary name lookup.
898bool ResultBuilder::IsOrdinaryNonValueName(NamedDecl *ND) const {
Douglas Gregor4710e5b2010-05-28 00:49:12 +0000899 ND = cast<NamedDecl>(ND->getUnderlyingDecl());
900
Douglas Gregor01dfea02010-01-10 23:08:15 +0000901 unsigned IDNS = Decl::IDNS_Ordinary;
902 if (SemaRef.getLangOptions().CPlusPlus)
John McCall0d6b1642010-04-23 18:46:30 +0000903 IDNS |= Decl::IDNS_Tag | Decl::IDNS_Namespace;
Douglas Gregor01dfea02010-01-10 23:08:15 +0000904
905 return (ND->getIdentifierNamespace() & IDNS) &&
Douglas Gregor4710e5b2010-05-28 00:49:12 +0000906 !isa<ValueDecl>(ND) && !isa<FunctionTemplateDecl>(ND) &&
907 !isa<ObjCPropertyDecl>(ND);
Douglas Gregor01dfea02010-01-10 23:08:15 +0000908}
909
Douglas Gregor86d9a522009-09-21 16:56:56 +0000910/// \brief Determines whether the given declaration is suitable as the
911/// start of a C++ nested-name-specifier, e.g., a class or namespace.
912bool ResultBuilder::IsNestedNameSpecifier(NamedDecl *ND) const {
913 // Allow us to find class templates, too.
914 if (ClassTemplateDecl *ClassTemplate = dyn_cast<ClassTemplateDecl>(ND))
915 ND = ClassTemplate->getTemplatedDecl();
916
917 return SemaRef.isAcceptableNestedNameSpecifier(ND);
918}
919
920/// \brief Determines whether the given declaration is an enumeration.
921bool ResultBuilder::IsEnum(NamedDecl *ND) const {
922 return isa<EnumDecl>(ND);
923}
924
925/// \brief Determines whether the given declaration is a class or struct.
926bool ResultBuilder::IsClassOrStruct(NamedDecl *ND) const {
927 // Allow us to find class templates, too.
928 if (ClassTemplateDecl *ClassTemplate = dyn_cast<ClassTemplateDecl>(ND))
929 ND = ClassTemplate->getTemplatedDecl();
930
931 if (RecordDecl *RD = dyn_cast<RecordDecl>(ND))
Abramo Bagnara465d41b2010-05-11 21:36:43 +0000932 return RD->getTagKind() == TTK_Class ||
933 RD->getTagKind() == TTK_Struct;
Douglas Gregor86d9a522009-09-21 16:56:56 +0000934
935 return false;
936}
937
938/// \brief Determines whether the given declaration is a union.
939bool ResultBuilder::IsUnion(NamedDecl *ND) const {
940 // Allow us to find class templates, too.
941 if (ClassTemplateDecl *ClassTemplate = dyn_cast<ClassTemplateDecl>(ND))
942 ND = ClassTemplate->getTemplatedDecl();
943
944 if (RecordDecl *RD = dyn_cast<RecordDecl>(ND))
Abramo Bagnara465d41b2010-05-11 21:36:43 +0000945 return RD->getTagKind() == TTK_Union;
Douglas Gregor86d9a522009-09-21 16:56:56 +0000946
947 return false;
948}
949
950/// \brief Determines whether the given declaration is a namespace.
951bool ResultBuilder::IsNamespace(NamedDecl *ND) const {
952 return isa<NamespaceDecl>(ND);
953}
954
955/// \brief Determines whether the given declaration is a namespace or
956/// namespace alias.
957bool ResultBuilder::IsNamespaceOrAlias(NamedDecl *ND) const {
958 return isa<NamespaceDecl>(ND) || isa<NamespaceAliasDecl>(ND);
959}
960
Douglas Gregor76282942009-12-11 17:31:05 +0000961/// \brief Determines whether the given declaration is a type.
Douglas Gregor86d9a522009-09-21 16:56:56 +0000962bool ResultBuilder::IsType(NamedDecl *ND) const {
Douglas Gregord32b0222010-08-24 01:06:58 +0000963 if (UsingShadowDecl *Using = dyn_cast<UsingShadowDecl>(ND))
964 ND = Using->getTargetDecl();
965
966 return isa<TypeDecl>(ND) || isa<ObjCInterfaceDecl>(ND);
Douglas Gregor86d9a522009-09-21 16:56:56 +0000967}
968
Douglas Gregor76282942009-12-11 17:31:05 +0000969/// \brief Determines which members of a class should be visible via
970/// "." or "->". Only value declarations, nested name specifiers, and
971/// using declarations thereof should show up.
Douglas Gregoreb5758b2009-09-23 22:26:46 +0000972bool ResultBuilder::IsMember(NamedDecl *ND) const {
Douglas Gregor76282942009-12-11 17:31:05 +0000973 if (UsingShadowDecl *Using = dyn_cast<UsingShadowDecl>(ND))
974 ND = Using->getTargetDecl();
975
Douglas Gregorce821962009-12-11 18:14:22 +0000976 return isa<ValueDecl>(ND) || isa<FunctionTemplateDecl>(ND) ||
977 isa<ObjCPropertyDecl>(ND);
Douglas Gregoreb5758b2009-09-23 22:26:46 +0000978}
979
Douglas Gregor8e254cf2010-05-27 23:06:34 +0000980static bool isObjCReceiverType(ASTContext &C, QualType T) {
981 T = C.getCanonicalType(T);
982 switch (T->getTypeClass()) {
983 case Type::ObjCObject:
984 case Type::ObjCInterface:
985 case Type::ObjCObjectPointer:
986 return true;
987
988 case Type::Builtin:
989 switch (cast<BuiltinType>(T)->getKind()) {
990 case BuiltinType::ObjCId:
991 case BuiltinType::ObjCClass:
992 case BuiltinType::ObjCSel:
993 return true;
994
995 default:
996 break;
997 }
998 return false;
999
1000 default:
1001 break;
1002 }
1003
1004 if (!C.getLangOptions().CPlusPlus)
1005 return false;
1006
1007 // FIXME: We could perform more analysis here to determine whether a
1008 // particular class type has any conversions to Objective-C types. For now,
1009 // just accept all class types.
1010 return T->isDependentType() || T->isRecordType();
1011}
1012
1013bool ResultBuilder::IsObjCMessageReceiver(NamedDecl *ND) const {
1014 QualType T = getDeclUsageType(SemaRef.Context, ND);
1015 if (T.isNull())
1016 return false;
1017
1018 T = SemaRef.Context.getBaseElementType(T);
1019 return isObjCReceiverType(SemaRef.Context, T);
1020}
1021
Douglas Gregorfb629412010-08-23 21:17:50 +00001022bool ResultBuilder::IsObjCCollection(NamedDecl *ND) const {
1023 if ((SemaRef.getLangOptions().CPlusPlus && !IsOrdinaryName(ND)) ||
1024 (!SemaRef.getLangOptions().CPlusPlus && !IsOrdinaryNonTypeName(ND)))
1025 return false;
1026
1027 QualType T = getDeclUsageType(SemaRef.Context, ND);
1028 if (T.isNull())
1029 return false;
1030
1031 T = SemaRef.Context.getBaseElementType(T);
1032 return T->isObjCObjectType() || T->isObjCObjectPointerType() ||
1033 T->isObjCIdType() ||
1034 (SemaRef.getLangOptions().CPlusPlus && T->isRecordType());
1035}
Douglas Gregor8e254cf2010-05-27 23:06:34 +00001036
Douglas Gregor80f4f4c2010-01-14 16:08:12 +00001037/// \rief Determines whether the given declaration is an Objective-C
1038/// instance variable.
1039bool ResultBuilder::IsObjCIvar(NamedDecl *ND) const {
1040 return isa<ObjCIvarDecl>(ND);
1041}
1042
Douglas Gregor1ca6ae82010-01-14 01:09:38 +00001043namespace {
1044 /// \brief Visible declaration consumer that adds a code-completion result
1045 /// for each visible declaration.
1046 class CodeCompletionDeclConsumer : public VisibleDeclConsumer {
1047 ResultBuilder &Results;
1048 DeclContext *CurContext;
1049
1050 public:
1051 CodeCompletionDeclConsumer(ResultBuilder &Results, DeclContext *CurContext)
1052 : Results(Results), CurContext(CurContext) { }
1053
Douglas Gregor0cc84042010-01-14 15:47:35 +00001054 virtual void FoundDecl(NamedDecl *ND, NamedDecl *Hiding, bool InBaseClass) {
1055 Results.AddResult(ND, CurContext, Hiding, InBaseClass);
Douglas Gregor1ca6ae82010-01-14 01:09:38 +00001056 }
1057 };
1058}
1059
Douglas Gregor86d9a522009-09-21 16:56:56 +00001060/// \brief Add type specifiers for the current language as keyword results.
Douglas Gregorbca403c2010-01-13 23:51:12 +00001061static void AddTypeSpecifierResults(const LangOptions &LangOpts,
Douglas Gregor86d9a522009-09-21 16:56:56 +00001062 ResultBuilder &Results) {
John McCall0a2c5e22010-08-25 06:19:51 +00001063 typedef CodeCompletionResult Result;
Douglas Gregor12e13132010-05-26 22:00:08 +00001064 Results.AddResult(Result("short", CCP_Type));
1065 Results.AddResult(Result("long", CCP_Type));
1066 Results.AddResult(Result("signed", CCP_Type));
1067 Results.AddResult(Result("unsigned", CCP_Type));
1068 Results.AddResult(Result("void", CCP_Type));
1069 Results.AddResult(Result("char", CCP_Type));
1070 Results.AddResult(Result("int", CCP_Type));
1071 Results.AddResult(Result("float", CCP_Type));
1072 Results.AddResult(Result("double", CCP_Type));
1073 Results.AddResult(Result("enum", CCP_Type));
1074 Results.AddResult(Result("struct", CCP_Type));
1075 Results.AddResult(Result("union", CCP_Type));
1076 Results.AddResult(Result("const", CCP_Type));
1077 Results.AddResult(Result("volatile", CCP_Type));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001078
Douglas Gregor86d9a522009-09-21 16:56:56 +00001079 if (LangOpts.C99) {
1080 // C99-specific
Douglas Gregor12e13132010-05-26 22:00:08 +00001081 Results.AddResult(Result("_Complex", CCP_Type));
1082 Results.AddResult(Result("_Imaginary", CCP_Type));
1083 Results.AddResult(Result("_Bool", CCP_Type));
1084 Results.AddResult(Result("restrict", CCP_Type));
Douglas Gregor86d9a522009-09-21 16:56:56 +00001085 }
1086
1087 if (LangOpts.CPlusPlus) {
1088 // C++-specific
Douglas Gregor12e13132010-05-26 22:00:08 +00001089 Results.AddResult(Result("bool", CCP_Type));
1090 Results.AddResult(Result("class", CCP_Type));
1091 Results.AddResult(Result("wchar_t", CCP_Type));
Douglas Gregor86d9a522009-09-21 16:56:56 +00001092
Douglas Gregorc8bddde2010-05-28 00:22:41 +00001093 // typename qualified-id
1094 CodeCompletionString *Pattern = new CodeCompletionString;
1095 Pattern->AddTypedTextChunk("typename");
1096 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
1097 Pattern->AddPlaceholderChunk("qualifier");
1098 Pattern->AddTextChunk("::");
1099 Pattern->AddPlaceholderChunk("name");
1100 Results.AddResult(Result(Pattern));
Douglas Gregord8e8a582010-05-25 21:41:55 +00001101
Douglas Gregor86d9a522009-09-21 16:56:56 +00001102 if (LangOpts.CPlusPlus0x) {
Douglas Gregor12e13132010-05-26 22:00:08 +00001103 Results.AddResult(Result("auto", CCP_Type));
1104 Results.AddResult(Result("char16_t", CCP_Type));
1105 Results.AddResult(Result("char32_t", CCP_Type));
Douglas Gregorc8bddde2010-05-28 00:22:41 +00001106
1107 CodeCompletionString *Pattern = new CodeCompletionString;
1108 Pattern->AddTypedTextChunk("decltype");
1109 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
1110 Pattern->AddPlaceholderChunk("expression");
1111 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
1112 Results.AddResult(Result(Pattern));
Douglas Gregor86d9a522009-09-21 16:56:56 +00001113 }
1114 }
1115
1116 // GNU extensions
1117 if (LangOpts.GNUMode) {
1118 // FIXME: Enable when we actually support decimal floating point.
Douglas Gregora4477812010-01-14 16:01:26 +00001119 // Results.AddResult(Result("_Decimal32"));
1120 // Results.AddResult(Result("_Decimal64"));
1121 // Results.AddResult(Result("_Decimal128"));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001122
Douglas Gregorc8bddde2010-05-28 00:22:41 +00001123 CodeCompletionString *Pattern = new CodeCompletionString;
1124 Pattern->AddTypedTextChunk("typeof");
1125 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
1126 Pattern->AddPlaceholderChunk("expression");
1127 Results.AddResult(Result(Pattern));
1128
1129 Pattern = new CodeCompletionString;
1130 Pattern->AddTypedTextChunk("typeof");
1131 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
1132 Pattern->AddPlaceholderChunk("type");
1133 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
1134 Results.AddResult(Result(Pattern));
Douglas Gregor86d9a522009-09-21 16:56:56 +00001135 }
1136}
1137
John McCallf312b1e2010-08-26 23:41:50 +00001138static void AddStorageSpecifiers(Sema::ParserCompletionContext CCC,
Douglas Gregor01dfea02010-01-10 23:08:15 +00001139 const LangOptions &LangOpts,
Douglas Gregor01dfea02010-01-10 23:08:15 +00001140 ResultBuilder &Results) {
John McCall0a2c5e22010-08-25 06:19:51 +00001141 typedef CodeCompletionResult Result;
Douglas Gregor01dfea02010-01-10 23:08:15 +00001142 // Note: we don't suggest either "auto" or "register", because both
1143 // are pointless as storage specifiers. Elsewhere, we suggest "auto"
1144 // in C++0x as a type specifier.
Douglas Gregora4477812010-01-14 16:01:26 +00001145 Results.AddResult(Result("extern"));
1146 Results.AddResult(Result("static"));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001147}
1148
John McCallf312b1e2010-08-26 23:41:50 +00001149static void AddFunctionSpecifiers(Sema::ParserCompletionContext CCC,
Douglas Gregor01dfea02010-01-10 23:08:15 +00001150 const LangOptions &LangOpts,
Douglas Gregor01dfea02010-01-10 23:08:15 +00001151 ResultBuilder &Results) {
John McCall0a2c5e22010-08-25 06:19:51 +00001152 typedef CodeCompletionResult Result;
Douglas Gregor01dfea02010-01-10 23:08:15 +00001153 switch (CCC) {
John McCallf312b1e2010-08-26 23:41:50 +00001154 case Sema::PCC_Class:
1155 case Sema::PCC_MemberTemplate:
Douglas Gregor01dfea02010-01-10 23:08:15 +00001156 if (LangOpts.CPlusPlus) {
Douglas Gregora4477812010-01-14 16:01:26 +00001157 Results.AddResult(Result("explicit"));
1158 Results.AddResult(Result("friend"));
1159 Results.AddResult(Result("mutable"));
1160 Results.AddResult(Result("virtual"));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001161 }
1162 // Fall through
1163
John McCallf312b1e2010-08-26 23:41:50 +00001164 case Sema::PCC_ObjCInterface:
1165 case Sema::PCC_ObjCImplementation:
1166 case Sema::PCC_Namespace:
1167 case Sema::PCC_Template:
Douglas Gregor01dfea02010-01-10 23:08:15 +00001168 if (LangOpts.CPlusPlus || LangOpts.C99)
Douglas Gregora4477812010-01-14 16:01:26 +00001169 Results.AddResult(Result("inline"));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001170 break;
1171
John McCallf312b1e2010-08-26 23:41:50 +00001172 case Sema::PCC_ObjCInstanceVariableList:
1173 case Sema::PCC_Expression:
1174 case Sema::PCC_Statement:
1175 case Sema::PCC_ForInit:
1176 case Sema::PCC_Condition:
1177 case Sema::PCC_RecoveryInFunction:
1178 case Sema::PCC_Type:
Douglas Gregor02688102010-09-14 23:59:36 +00001179 case Sema::PCC_ParenthesizedExpression:
Douglas Gregor01dfea02010-01-10 23:08:15 +00001180 break;
1181 }
1182}
1183
Douglas Gregorbca403c2010-01-13 23:51:12 +00001184static void AddObjCExpressionResults(ResultBuilder &Results, bool NeedAt);
1185static void AddObjCStatementResults(ResultBuilder &Results, bool NeedAt);
1186static void AddObjCVisibilityResults(const LangOptions &LangOpts,
Douglas Gregorc38c3e12010-01-13 21:54:15 +00001187 ResultBuilder &Results,
1188 bool NeedAt);
Douglas Gregorbca403c2010-01-13 23:51:12 +00001189static void AddObjCImplementationResults(const LangOptions &LangOpts,
Douglas Gregorb6ac2452010-01-13 21:24:21 +00001190 ResultBuilder &Results,
1191 bool NeedAt);
Douglas Gregorbca403c2010-01-13 23:51:12 +00001192static void AddObjCInterfaceResults(const LangOptions &LangOpts,
Douglas Gregorb6ac2452010-01-13 21:24:21 +00001193 ResultBuilder &Results,
1194 bool NeedAt);
Douglas Gregorbca403c2010-01-13 23:51:12 +00001195static void AddObjCTopLevelResults(ResultBuilder &Results, bool NeedAt);
Douglas Gregorb6ac2452010-01-13 21:24:21 +00001196
Douglas Gregorc8bddde2010-05-28 00:22:41 +00001197static void AddTypedefResult(ResultBuilder &Results) {
1198 CodeCompletionString *Pattern = new CodeCompletionString;
1199 Pattern->AddTypedTextChunk("typedef");
1200 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
1201 Pattern->AddPlaceholderChunk("type");
1202 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
1203 Pattern->AddPlaceholderChunk("name");
John McCall0a2c5e22010-08-25 06:19:51 +00001204 Results.AddResult(CodeCompletionResult(Pattern));
Douglas Gregorc8bddde2010-05-28 00:22:41 +00001205}
1206
John McCallf312b1e2010-08-26 23:41:50 +00001207static bool WantTypesInContext(Sema::ParserCompletionContext CCC,
Douglas Gregor4710e5b2010-05-28 00:49:12 +00001208 const LangOptions &LangOpts) {
Douglas Gregor4710e5b2010-05-28 00:49:12 +00001209 switch (CCC) {
John McCallf312b1e2010-08-26 23:41:50 +00001210 case Sema::PCC_Namespace:
1211 case Sema::PCC_Class:
1212 case Sema::PCC_ObjCInstanceVariableList:
1213 case Sema::PCC_Template:
1214 case Sema::PCC_MemberTemplate:
1215 case Sema::PCC_Statement:
1216 case Sema::PCC_RecoveryInFunction:
1217 case Sema::PCC_Type:
Douglas Gregor02688102010-09-14 23:59:36 +00001218 case Sema::PCC_ParenthesizedExpression:
Douglas Gregor4710e5b2010-05-28 00:49:12 +00001219 return true;
1220
John McCallf312b1e2010-08-26 23:41:50 +00001221 case Sema::PCC_Expression:
1222 case Sema::PCC_Condition:
Douglas Gregor02688102010-09-14 23:59:36 +00001223 return LangOpts.CPlusPlus;
1224
1225 case Sema::PCC_ObjCInterface:
1226 case Sema::PCC_ObjCImplementation:
Douglas Gregor4710e5b2010-05-28 00:49:12 +00001227 return false;
1228
John McCallf312b1e2010-08-26 23:41:50 +00001229 case Sema::PCC_ForInit:
Douglas Gregor02688102010-09-14 23:59:36 +00001230 return LangOpts.CPlusPlus || LangOpts.ObjC1 || LangOpts.C99;
Douglas Gregor4710e5b2010-05-28 00:49:12 +00001231 }
1232
1233 return false;
1234}
1235
Douglas Gregor01dfea02010-01-10 23:08:15 +00001236/// \brief Add language constructs that show up for "ordinary" names.
John McCallf312b1e2010-08-26 23:41:50 +00001237static void AddOrdinaryNameResults(Sema::ParserCompletionContext CCC,
Douglas Gregor01dfea02010-01-10 23:08:15 +00001238 Scope *S,
1239 Sema &SemaRef,
Douglas Gregor01dfea02010-01-10 23:08:15 +00001240 ResultBuilder &Results) {
John McCall0a2c5e22010-08-25 06:19:51 +00001241 typedef CodeCompletionResult Result;
Douglas Gregor01dfea02010-01-10 23:08:15 +00001242 switch (CCC) {
John McCallf312b1e2010-08-26 23:41:50 +00001243 case Sema::PCC_Namespace:
Douglas Gregorc8bddde2010-05-28 00:22:41 +00001244 if (SemaRef.getLangOptions().CPlusPlus) {
1245 CodeCompletionString *Pattern = 0;
1246
1247 if (Results.includeCodePatterns()) {
1248 // namespace <identifier> { declarations }
1249 CodeCompletionString *Pattern = new CodeCompletionString;
1250 Pattern->AddTypedTextChunk("namespace");
1251 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
1252 Pattern->AddPlaceholderChunk("identifier");
1253 Pattern->AddChunk(CodeCompletionString::CK_LeftBrace);
1254 Pattern->AddPlaceholderChunk("declarations");
1255 Pattern->AddChunk(CodeCompletionString::CK_VerticalSpace);
1256 Pattern->AddChunk(CodeCompletionString::CK_RightBrace);
1257 Results.AddResult(Result(Pattern));
1258 }
1259
Douglas Gregor01dfea02010-01-10 23:08:15 +00001260 // namespace identifier = identifier ;
1261 Pattern = new CodeCompletionString;
1262 Pattern->AddTypedTextChunk("namespace");
1263 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
Douglas Gregorc8bddde2010-05-28 00:22:41 +00001264 Pattern->AddPlaceholderChunk("name");
Douglas Gregor01dfea02010-01-10 23:08:15 +00001265 Pattern->AddChunk(CodeCompletionString::CK_Equal);
Douglas Gregorc8bddde2010-05-28 00:22:41 +00001266 Pattern->AddPlaceholderChunk("namespace");
Douglas Gregora4477812010-01-14 16:01:26 +00001267 Results.AddResult(Result(Pattern));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001268
1269 // Using directives
1270 Pattern = new CodeCompletionString;
1271 Pattern->AddTypedTextChunk("using");
1272 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
1273 Pattern->AddTextChunk("namespace");
1274 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
1275 Pattern->AddPlaceholderChunk("identifier");
Douglas Gregora4477812010-01-14 16:01:26 +00001276 Results.AddResult(Result(Pattern));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001277
1278 // asm(string-literal)
1279 Pattern = new CodeCompletionString;
1280 Pattern->AddTypedTextChunk("asm");
1281 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
1282 Pattern->AddPlaceholderChunk("string-literal");
1283 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
Douglas Gregora4477812010-01-14 16:01:26 +00001284 Results.AddResult(Result(Pattern));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001285
Douglas Gregorc8bddde2010-05-28 00:22:41 +00001286 if (Results.includeCodePatterns()) {
1287 // Explicit template instantiation
1288 Pattern = new CodeCompletionString;
1289 Pattern->AddTypedTextChunk("template");
1290 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
1291 Pattern->AddPlaceholderChunk("declaration");
1292 Results.AddResult(Result(Pattern));
1293 }
Douglas Gregor01dfea02010-01-10 23:08:15 +00001294 }
Douglas Gregorb6ac2452010-01-13 21:24:21 +00001295
1296 if (SemaRef.getLangOptions().ObjC1)
Douglas Gregorbca403c2010-01-13 23:51:12 +00001297 AddObjCTopLevelResults(Results, true);
Douglas Gregorb6ac2452010-01-13 21:24:21 +00001298
Douglas Gregorc8bddde2010-05-28 00:22:41 +00001299 AddTypedefResult(Results);
Douglas Gregor01dfea02010-01-10 23:08:15 +00001300 // Fall through
1301
John McCallf312b1e2010-08-26 23:41:50 +00001302 case Sema::PCC_Class:
Douglas Gregorc8bddde2010-05-28 00:22:41 +00001303 if (SemaRef.getLangOptions().CPlusPlus) {
Douglas Gregor01dfea02010-01-10 23:08:15 +00001304 // Using declaration
1305 CodeCompletionString *Pattern = new CodeCompletionString;
1306 Pattern->AddTypedTextChunk("using");
1307 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
Douglas Gregorc8bddde2010-05-28 00:22:41 +00001308 Pattern->AddPlaceholderChunk("qualifier");
1309 Pattern->AddTextChunk("::");
1310 Pattern->AddPlaceholderChunk("name");
Douglas Gregora4477812010-01-14 16:01:26 +00001311 Results.AddResult(Result(Pattern));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001312
Douglas Gregorc8bddde2010-05-28 00:22:41 +00001313 // using typename qualifier::name (only in a dependent context)
Douglas Gregor01dfea02010-01-10 23:08:15 +00001314 if (SemaRef.CurContext->isDependentContext()) {
1315 Pattern = new CodeCompletionString;
1316 Pattern->AddTypedTextChunk("using");
1317 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
1318 Pattern->AddTextChunk("typename");
1319 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
Douglas Gregorc8bddde2010-05-28 00:22:41 +00001320 Pattern->AddPlaceholderChunk("qualifier");
1321 Pattern->AddTextChunk("::");
1322 Pattern->AddPlaceholderChunk("name");
Douglas Gregora4477812010-01-14 16:01:26 +00001323 Results.AddResult(Result(Pattern));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001324 }
1325
John McCallf312b1e2010-08-26 23:41:50 +00001326 if (CCC == Sema::PCC_Class) {
Douglas Gregorc8bddde2010-05-28 00:22:41 +00001327 AddTypedefResult(Results);
1328
Douglas Gregor01dfea02010-01-10 23:08:15 +00001329 // public:
1330 Pattern = new CodeCompletionString;
1331 Pattern->AddTypedTextChunk("public");
1332 Pattern->AddChunk(CodeCompletionString::CK_Colon);
Douglas Gregora4477812010-01-14 16:01:26 +00001333 Results.AddResult(Result(Pattern));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001334
1335 // protected:
1336 Pattern = new CodeCompletionString;
1337 Pattern->AddTypedTextChunk("protected");
1338 Pattern->AddChunk(CodeCompletionString::CK_Colon);
Douglas Gregora4477812010-01-14 16:01:26 +00001339 Results.AddResult(Result(Pattern));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001340
1341 // private:
1342 Pattern = new CodeCompletionString;
1343 Pattern->AddTypedTextChunk("private");
1344 Pattern->AddChunk(CodeCompletionString::CK_Colon);
Douglas Gregora4477812010-01-14 16:01:26 +00001345 Results.AddResult(Result(Pattern));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001346 }
1347 }
1348 // Fall through
1349
John McCallf312b1e2010-08-26 23:41:50 +00001350 case Sema::PCC_Template:
1351 case Sema::PCC_MemberTemplate:
Douglas Gregord8e8a582010-05-25 21:41:55 +00001352 if (SemaRef.getLangOptions().CPlusPlus && Results.includeCodePatterns()) {
Douglas Gregor01dfea02010-01-10 23:08:15 +00001353 // template < parameters >
1354 CodeCompletionString *Pattern = new CodeCompletionString;
1355 Pattern->AddTypedTextChunk("template");
1356 Pattern->AddChunk(CodeCompletionString::CK_LeftAngle);
1357 Pattern->AddPlaceholderChunk("parameters");
1358 Pattern->AddChunk(CodeCompletionString::CK_RightAngle);
Douglas Gregora4477812010-01-14 16:01:26 +00001359 Results.AddResult(Result(Pattern));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001360 }
1361
Douglas Gregorbca403c2010-01-13 23:51:12 +00001362 AddStorageSpecifiers(CCC, SemaRef.getLangOptions(), Results);
1363 AddFunctionSpecifiers(CCC, SemaRef.getLangOptions(), Results);
Douglas Gregor01dfea02010-01-10 23:08:15 +00001364 break;
1365
John McCallf312b1e2010-08-26 23:41:50 +00001366 case Sema::PCC_ObjCInterface:
Douglas Gregorbca403c2010-01-13 23:51:12 +00001367 AddObjCInterfaceResults(SemaRef.getLangOptions(), Results, true);
1368 AddStorageSpecifiers(CCC, SemaRef.getLangOptions(), Results);
1369 AddFunctionSpecifiers(CCC, SemaRef.getLangOptions(), Results);
Douglas Gregorb6ac2452010-01-13 21:24:21 +00001370 break;
1371
John McCallf312b1e2010-08-26 23:41:50 +00001372 case Sema::PCC_ObjCImplementation:
Douglas Gregorbca403c2010-01-13 23:51:12 +00001373 AddObjCImplementationResults(SemaRef.getLangOptions(), Results, true);
1374 AddStorageSpecifiers(CCC, SemaRef.getLangOptions(), Results);
1375 AddFunctionSpecifiers(CCC, SemaRef.getLangOptions(), Results);
Douglas Gregorb6ac2452010-01-13 21:24:21 +00001376 break;
1377
John McCallf312b1e2010-08-26 23:41:50 +00001378 case Sema::PCC_ObjCInstanceVariableList:
Douglas Gregorbca403c2010-01-13 23:51:12 +00001379 AddObjCVisibilityResults(SemaRef.getLangOptions(), Results, true);
Douglas Gregorc38c3e12010-01-13 21:54:15 +00001380 break;
1381
John McCallf312b1e2010-08-26 23:41:50 +00001382 case Sema::PCC_RecoveryInFunction:
1383 case Sema::PCC_Statement: {
Douglas Gregorc8bddde2010-05-28 00:22:41 +00001384 AddTypedefResult(Results);
Douglas Gregor01dfea02010-01-10 23:08:15 +00001385
1386 CodeCompletionString *Pattern = 0;
Douglas Gregord8e8a582010-05-25 21:41:55 +00001387 if (SemaRef.getLangOptions().CPlusPlus && Results.includeCodePatterns()) {
Douglas Gregor01dfea02010-01-10 23:08:15 +00001388 Pattern = new CodeCompletionString;
1389 Pattern->AddTypedTextChunk("try");
1390 Pattern->AddChunk(CodeCompletionString::CK_LeftBrace);
1391 Pattern->AddPlaceholderChunk("statements");
1392 Pattern->AddChunk(CodeCompletionString::CK_VerticalSpace);
1393 Pattern->AddChunk(CodeCompletionString::CK_RightBrace);
1394 Pattern->AddTextChunk("catch");
1395 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
1396 Pattern->AddPlaceholderChunk("declaration");
1397 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
1398 Pattern->AddChunk(CodeCompletionString::CK_LeftBrace);
1399 Pattern->AddPlaceholderChunk("statements");
1400 Pattern->AddChunk(CodeCompletionString::CK_VerticalSpace);
1401 Pattern->AddChunk(CodeCompletionString::CK_RightBrace);
Douglas Gregora4477812010-01-14 16:01:26 +00001402 Results.AddResult(Result(Pattern));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001403 }
Douglas Gregorb6ac2452010-01-13 21:24:21 +00001404 if (SemaRef.getLangOptions().ObjC1)
Douglas Gregorbca403c2010-01-13 23:51:12 +00001405 AddObjCStatementResults(Results, true);
Douglas Gregorb6ac2452010-01-13 21:24:21 +00001406
Douglas Gregord8e8a582010-05-25 21:41:55 +00001407 if (Results.includeCodePatterns()) {
1408 // if (condition) { statements }
1409 Pattern = new CodeCompletionString;
1410 Pattern->AddTypedTextChunk("if");
1411 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
1412 if (SemaRef.getLangOptions().CPlusPlus)
1413 Pattern->AddPlaceholderChunk("condition");
1414 else
1415 Pattern->AddPlaceholderChunk("expression");
1416 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
1417 Pattern->AddChunk(CodeCompletionString::CK_LeftBrace);
1418 Pattern->AddPlaceholderChunk("statements");
1419 Pattern->AddChunk(CodeCompletionString::CK_VerticalSpace);
1420 Pattern->AddChunk(CodeCompletionString::CK_RightBrace);
1421 Results.AddResult(Result(Pattern));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001422
Douglas Gregord8e8a582010-05-25 21:41:55 +00001423 // switch (condition) { }
1424 Pattern = new CodeCompletionString;
1425 Pattern->AddTypedTextChunk("switch");
1426 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
1427 if (SemaRef.getLangOptions().CPlusPlus)
1428 Pattern->AddPlaceholderChunk("condition");
1429 else
1430 Pattern->AddPlaceholderChunk("expression");
1431 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
1432 Pattern->AddChunk(CodeCompletionString::CK_LeftBrace);
1433 Pattern->AddChunk(CodeCompletionString::CK_VerticalSpace);
1434 Pattern->AddChunk(CodeCompletionString::CK_RightBrace);
1435 Results.AddResult(Result(Pattern));
1436 }
1437
Douglas Gregor01dfea02010-01-10 23:08:15 +00001438 // Switch-specific statements.
John McCall781472f2010-08-25 08:40:02 +00001439 if (!SemaRef.getCurFunction()->SwitchStack.empty()) {
Douglas Gregor01dfea02010-01-10 23:08:15 +00001440 // case expression:
1441 Pattern = new CodeCompletionString;
1442 Pattern->AddTypedTextChunk("case");
Douglas Gregorc8bddde2010-05-28 00:22:41 +00001443 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
Douglas Gregor01dfea02010-01-10 23:08:15 +00001444 Pattern->AddPlaceholderChunk("expression");
1445 Pattern->AddChunk(CodeCompletionString::CK_Colon);
Douglas Gregora4477812010-01-14 16:01:26 +00001446 Results.AddResult(Result(Pattern));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001447
1448 // default:
1449 Pattern = new CodeCompletionString;
1450 Pattern->AddTypedTextChunk("default");
1451 Pattern->AddChunk(CodeCompletionString::CK_Colon);
Douglas Gregora4477812010-01-14 16:01:26 +00001452 Results.AddResult(Result(Pattern));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001453 }
1454
Douglas Gregord8e8a582010-05-25 21:41:55 +00001455 if (Results.includeCodePatterns()) {
1456 /// while (condition) { statements }
1457 Pattern = new CodeCompletionString;
1458 Pattern->AddTypedTextChunk("while");
1459 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
1460 if (SemaRef.getLangOptions().CPlusPlus)
1461 Pattern->AddPlaceholderChunk("condition");
1462 else
1463 Pattern->AddPlaceholderChunk("expression");
1464 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
1465 Pattern->AddChunk(CodeCompletionString::CK_LeftBrace);
1466 Pattern->AddPlaceholderChunk("statements");
1467 Pattern->AddChunk(CodeCompletionString::CK_VerticalSpace);
1468 Pattern->AddChunk(CodeCompletionString::CK_RightBrace);
1469 Results.AddResult(Result(Pattern));
1470
1471 // do { statements } while ( expression );
1472 Pattern = new CodeCompletionString;
1473 Pattern->AddTypedTextChunk("do");
1474 Pattern->AddChunk(CodeCompletionString::CK_LeftBrace);
1475 Pattern->AddPlaceholderChunk("statements");
1476 Pattern->AddChunk(CodeCompletionString::CK_VerticalSpace);
1477 Pattern->AddChunk(CodeCompletionString::CK_RightBrace);
1478 Pattern->AddTextChunk("while");
1479 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
Douglas Gregor01dfea02010-01-10 23:08:15 +00001480 Pattern->AddPlaceholderChunk("expression");
Douglas Gregord8e8a582010-05-25 21:41:55 +00001481 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
1482 Results.AddResult(Result(Pattern));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001483
Douglas Gregord8e8a582010-05-25 21:41:55 +00001484 // for ( for-init-statement ; condition ; expression ) { statements }
1485 Pattern = new CodeCompletionString;
1486 Pattern->AddTypedTextChunk("for");
1487 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
1488 if (SemaRef.getLangOptions().CPlusPlus || SemaRef.getLangOptions().C99)
1489 Pattern->AddPlaceholderChunk("init-statement");
1490 else
1491 Pattern->AddPlaceholderChunk("init-expression");
1492 Pattern->AddChunk(CodeCompletionString::CK_SemiColon);
1493 Pattern->AddPlaceholderChunk("condition");
1494 Pattern->AddChunk(CodeCompletionString::CK_SemiColon);
1495 Pattern->AddPlaceholderChunk("inc-expression");
1496 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
1497 Pattern->AddChunk(CodeCompletionString::CK_LeftBrace);
1498 Pattern->AddPlaceholderChunk("statements");
1499 Pattern->AddChunk(CodeCompletionString::CK_VerticalSpace);
1500 Pattern->AddChunk(CodeCompletionString::CK_RightBrace);
1501 Results.AddResult(Result(Pattern));
1502 }
Douglas Gregor01dfea02010-01-10 23:08:15 +00001503
1504 if (S->getContinueParent()) {
1505 // continue ;
1506 Pattern = new CodeCompletionString;
1507 Pattern->AddTypedTextChunk("continue");
Douglas Gregora4477812010-01-14 16:01:26 +00001508 Results.AddResult(Result(Pattern));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001509 }
1510
1511 if (S->getBreakParent()) {
1512 // break ;
1513 Pattern = new CodeCompletionString;
1514 Pattern->AddTypedTextChunk("break");
Douglas Gregora4477812010-01-14 16:01:26 +00001515 Results.AddResult(Result(Pattern));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001516 }
1517
1518 // "return expression ;" or "return ;", depending on whether we
1519 // know the function is void or not.
1520 bool isVoid = false;
1521 if (FunctionDecl *Function = dyn_cast<FunctionDecl>(SemaRef.CurContext))
1522 isVoid = Function->getResultType()->isVoidType();
1523 else if (ObjCMethodDecl *Method
1524 = dyn_cast<ObjCMethodDecl>(SemaRef.CurContext))
1525 isVoid = Method->getResultType()->isVoidType();
Douglas Gregor9ea9bdb2010-03-01 23:15:13 +00001526 else if (SemaRef.getCurBlock() &&
1527 !SemaRef.getCurBlock()->ReturnType.isNull())
1528 isVoid = SemaRef.getCurBlock()->ReturnType->isVoidType();
Douglas Gregor01dfea02010-01-10 23:08:15 +00001529 Pattern = new CodeCompletionString;
1530 Pattern->AddTypedTextChunk("return");
Douglas Gregor93298002010-02-18 04:06:48 +00001531 if (!isVoid) {
1532 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
Douglas Gregor01dfea02010-01-10 23:08:15 +00001533 Pattern->AddPlaceholderChunk("expression");
Douglas Gregor93298002010-02-18 04:06:48 +00001534 }
Douglas Gregora4477812010-01-14 16:01:26 +00001535 Results.AddResult(Result(Pattern));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001536
Douglas Gregorc8bddde2010-05-28 00:22:41 +00001537 // goto identifier ;
1538 Pattern = new CodeCompletionString;
1539 Pattern->AddTypedTextChunk("goto");
1540 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
1541 Pattern->AddPlaceholderChunk("label");
1542 Results.AddResult(Result(Pattern));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001543
Douglas Gregorc8bddde2010-05-28 00:22:41 +00001544 // Using directives
1545 Pattern = new CodeCompletionString;
1546 Pattern->AddTypedTextChunk("using");
1547 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
1548 Pattern->AddTextChunk("namespace");
1549 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
1550 Pattern->AddPlaceholderChunk("identifier");
1551 Results.AddResult(Result(Pattern));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001552 }
1553
1554 // Fall through (for statement expressions).
John McCallf312b1e2010-08-26 23:41:50 +00001555 case Sema::PCC_ForInit:
1556 case Sema::PCC_Condition:
Douglas Gregorbca403c2010-01-13 23:51:12 +00001557 AddStorageSpecifiers(CCC, SemaRef.getLangOptions(), Results);
Douglas Gregor01dfea02010-01-10 23:08:15 +00001558 // Fall through: conditions and statements can have expressions.
1559
Douglas Gregor02688102010-09-14 23:59:36 +00001560 case Sema::PCC_ParenthesizedExpression:
John McCallf312b1e2010-08-26 23:41:50 +00001561 case Sema::PCC_Expression: {
Douglas Gregor01dfea02010-01-10 23:08:15 +00001562 CodeCompletionString *Pattern = 0;
1563 if (SemaRef.getLangOptions().CPlusPlus) {
1564 // 'this', if we're in a non-static member function.
1565 if (CXXMethodDecl *Method = dyn_cast<CXXMethodDecl>(SemaRef.CurContext))
1566 if (!Method->isStatic())
Douglas Gregora4477812010-01-14 16:01:26 +00001567 Results.AddResult(Result("this"));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001568
1569 // true, false
Douglas Gregora4477812010-01-14 16:01:26 +00001570 Results.AddResult(Result("true"));
1571 Results.AddResult(Result("false"));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001572
Douglas Gregorc8bddde2010-05-28 00:22:41 +00001573 // dynamic_cast < type-id > ( expression )
1574 Pattern = new CodeCompletionString;
1575 Pattern->AddTypedTextChunk("dynamic_cast");
1576 Pattern->AddChunk(CodeCompletionString::CK_LeftAngle);
1577 Pattern->AddPlaceholderChunk("type");
1578 Pattern->AddChunk(CodeCompletionString::CK_RightAngle);
1579 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
1580 Pattern->AddPlaceholderChunk("expression");
1581 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
1582 Results.AddResult(Result(Pattern));
1583
1584 // static_cast < type-id > ( expression )
1585 Pattern = new CodeCompletionString;
1586 Pattern->AddTypedTextChunk("static_cast");
1587 Pattern->AddChunk(CodeCompletionString::CK_LeftAngle);
1588 Pattern->AddPlaceholderChunk("type");
1589 Pattern->AddChunk(CodeCompletionString::CK_RightAngle);
1590 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
1591 Pattern->AddPlaceholderChunk("expression");
1592 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
1593 Results.AddResult(Result(Pattern));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001594
Douglas Gregorc8bddde2010-05-28 00:22:41 +00001595 // reinterpret_cast < type-id > ( expression )
1596 Pattern = new CodeCompletionString;
1597 Pattern->AddTypedTextChunk("reinterpret_cast");
1598 Pattern->AddChunk(CodeCompletionString::CK_LeftAngle);
1599 Pattern->AddPlaceholderChunk("type");
1600 Pattern->AddChunk(CodeCompletionString::CK_RightAngle);
1601 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
1602 Pattern->AddPlaceholderChunk("expression");
1603 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
1604 Results.AddResult(Result(Pattern));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001605
Douglas Gregorc8bddde2010-05-28 00:22:41 +00001606 // const_cast < type-id > ( expression )
1607 Pattern = new CodeCompletionString;
1608 Pattern->AddTypedTextChunk("const_cast");
1609 Pattern->AddChunk(CodeCompletionString::CK_LeftAngle);
1610 Pattern->AddPlaceholderChunk("type");
1611 Pattern->AddChunk(CodeCompletionString::CK_RightAngle);
1612 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
1613 Pattern->AddPlaceholderChunk("expression");
1614 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
1615 Results.AddResult(Result(Pattern));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001616
Douglas Gregorc8bddde2010-05-28 00:22:41 +00001617 // typeid ( expression-or-type )
1618 Pattern = new CodeCompletionString;
1619 Pattern->AddTypedTextChunk("typeid");
1620 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
1621 Pattern->AddPlaceholderChunk("expression-or-type");
1622 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
1623 Results.AddResult(Result(Pattern));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001624
Douglas Gregorc8bddde2010-05-28 00:22:41 +00001625 // new T ( ... )
1626 Pattern = new CodeCompletionString;
1627 Pattern->AddTypedTextChunk("new");
1628 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
1629 Pattern->AddPlaceholderChunk("type");
1630 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
1631 Pattern->AddPlaceholderChunk("expressions");
1632 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
1633 Results.AddResult(Result(Pattern));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001634
Douglas Gregorc8bddde2010-05-28 00:22:41 +00001635 // new T [ ] ( ... )
1636 Pattern = new CodeCompletionString;
1637 Pattern->AddTypedTextChunk("new");
1638 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
1639 Pattern->AddPlaceholderChunk("type");
1640 Pattern->AddChunk(CodeCompletionString::CK_LeftBracket);
1641 Pattern->AddPlaceholderChunk("size");
1642 Pattern->AddChunk(CodeCompletionString::CK_RightBracket);
1643 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
1644 Pattern->AddPlaceholderChunk("expressions");
1645 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
1646 Results.AddResult(Result(Pattern));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001647
Douglas Gregorc8bddde2010-05-28 00:22:41 +00001648 // delete expression
1649 Pattern = new CodeCompletionString;
1650 Pattern->AddTypedTextChunk("delete");
1651 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
1652 Pattern->AddPlaceholderChunk("expression");
1653 Results.AddResult(Result(Pattern));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001654
Douglas Gregorc8bddde2010-05-28 00:22:41 +00001655 // delete [] expression
1656 Pattern = new CodeCompletionString;
1657 Pattern->AddTypedTextChunk("delete");
1658 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
1659 Pattern->AddChunk(CodeCompletionString::CK_LeftBracket);
1660 Pattern->AddChunk(CodeCompletionString::CK_RightBracket);
1661 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
1662 Pattern->AddPlaceholderChunk("expression");
1663 Results.AddResult(Result(Pattern));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001664
Douglas Gregorc8bddde2010-05-28 00:22:41 +00001665 // throw expression
1666 Pattern = new CodeCompletionString;
1667 Pattern->AddTypedTextChunk("throw");
1668 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
1669 Pattern->AddPlaceholderChunk("expression");
1670 Results.AddResult(Result(Pattern));
Douglas Gregor12e13132010-05-26 22:00:08 +00001671
1672 // FIXME: Rethrow?
Douglas Gregor01dfea02010-01-10 23:08:15 +00001673 }
1674
1675 if (SemaRef.getLangOptions().ObjC1) {
1676 // Add "super", if we're in an Objective-C class with a superclass.
Ted Kremenek681e2562010-05-31 21:43:10 +00001677 if (ObjCMethodDecl *Method = SemaRef.getCurMethodDecl()) {
1678 // The interface can be NULL.
1679 if (ObjCInterfaceDecl *ID = Method->getClassInterface())
1680 if (ID->getSuperClass())
1681 Results.AddResult(Result("super"));
1682 }
1683
Douglas Gregorbca403c2010-01-13 23:51:12 +00001684 AddObjCExpressionResults(Results, true);
Douglas Gregor01dfea02010-01-10 23:08:15 +00001685 }
1686
Douglas Gregorc8bddde2010-05-28 00:22:41 +00001687 // sizeof expression
1688 Pattern = new CodeCompletionString;
1689 Pattern->AddTypedTextChunk("sizeof");
1690 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
1691 Pattern->AddPlaceholderChunk("expression-or-type");
1692 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
1693 Results.AddResult(Result(Pattern));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001694 break;
1695 }
Douglas Gregord32b0222010-08-24 01:06:58 +00001696
John McCallf312b1e2010-08-26 23:41:50 +00001697 case Sema::PCC_Type:
Douglas Gregord32b0222010-08-24 01:06:58 +00001698 break;
Douglas Gregor01dfea02010-01-10 23:08:15 +00001699 }
1700
Douglas Gregor4710e5b2010-05-28 00:49:12 +00001701 if (WantTypesInContext(CCC, SemaRef.getLangOptions()))
1702 AddTypeSpecifierResults(SemaRef.getLangOptions(), Results);
Douglas Gregor01dfea02010-01-10 23:08:15 +00001703
John McCallf312b1e2010-08-26 23:41:50 +00001704 if (SemaRef.getLangOptions().CPlusPlus && CCC != Sema::PCC_Type)
Douglas Gregora4477812010-01-14 16:01:26 +00001705 Results.AddResult(Result("operator"));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001706}
1707
Douglas Gregorff5ce6e2009-12-18 18:53:37 +00001708/// \brief If the given declaration has an associated type, add it as a result
1709/// type chunk.
1710static void AddResultTypeChunk(ASTContext &Context,
1711 NamedDecl *ND,
1712 CodeCompletionString *Result) {
1713 if (!ND)
1714 return;
1715
1716 // Determine the type of the declaration (if it has a type).
1717 QualType T;
1718 if (FunctionDecl *Function = dyn_cast<FunctionDecl>(ND))
1719 T = Function->getResultType();
1720 else if (ObjCMethodDecl *Method = dyn_cast<ObjCMethodDecl>(ND))
1721 T = Method->getResultType();
1722 else if (FunctionTemplateDecl *FunTmpl = dyn_cast<FunctionTemplateDecl>(ND))
1723 T = FunTmpl->getTemplatedDecl()->getResultType();
1724 else if (EnumConstantDecl *Enumerator = dyn_cast<EnumConstantDecl>(ND))
1725 T = Context.getTypeDeclType(cast<TypeDecl>(Enumerator->getDeclContext()));
1726 else if (isa<UnresolvedUsingValueDecl>(ND)) {
1727 /* Do nothing: ignore unresolved using declarations*/
1728 } else if (ValueDecl *Value = dyn_cast<ValueDecl>(ND))
1729 T = Value->getType();
1730 else if (ObjCPropertyDecl *Property = dyn_cast<ObjCPropertyDecl>(ND))
1731 T = Property->getType();
1732
1733 if (T.isNull() || Context.hasSameType(T, Context.DependentTy))
1734 return;
1735
Douglas Gregor84139d62010-04-05 21:25:31 +00001736 PrintingPolicy Policy(Context.PrintingPolicy);
1737 Policy.AnonymousTagLocations = false;
1738
Douglas Gregorff5ce6e2009-12-18 18:53:37 +00001739 std::string TypeStr;
Douglas Gregor84139d62010-04-05 21:25:31 +00001740 T.getAsStringInternal(TypeStr, Policy);
Douglas Gregorff5ce6e2009-12-18 18:53:37 +00001741 Result->AddResultTypeChunk(TypeStr);
1742}
1743
Douglas Gregoraaa107a2010-08-23 23:51:41 +00001744static void MaybeAddSentinel(ASTContext &Context, NamedDecl *FunctionOrMethod,
1745 CodeCompletionString *Result) {
1746 if (SentinelAttr *Sentinel = FunctionOrMethod->getAttr<SentinelAttr>())
1747 if (Sentinel->getSentinel() == 0) {
1748 if (Context.getLangOptions().ObjC1 &&
1749 Context.Idents.get("nil").hasMacroDefinition())
1750 Result->AddTextChunk(", nil");
1751 else if (Context.Idents.get("NULL").hasMacroDefinition())
1752 Result->AddTextChunk(", NULL");
1753 else
1754 Result->AddTextChunk(", (void*)0");
1755 }
1756}
1757
Douglas Gregor83482d12010-08-24 16:15:59 +00001758static std::string FormatFunctionParameter(ASTContext &Context,
Douglas Gregoraba48082010-08-29 19:47:46 +00001759 ParmVarDecl *Param,
1760 bool SuppressName = false) {
Douglas Gregor83482d12010-08-24 16:15:59 +00001761 bool ObjCMethodParam = isa<ObjCMethodDecl>(Param->getDeclContext());
1762 if (Param->getType()->isDependentType() ||
1763 !Param->getType()->isBlockPointerType()) {
1764 // The argument for a dependent or non-block parameter is a placeholder
1765 // containing that parameter's type.
1766 std::string Result;
1767
Douglas Gregoraba48082010-08-29 19:47:46 +00001768 if (Param->getIdentifier() && !ObjCMethodParam && !SuppressName)
Douglas Gregor83482d12010-08-24 16:15:59 +00001769 Result = Param->getIdentifier()->getName();
1770
1771 Param->getType().getAsStringInternal(Result,
1772 Context.PrintingPolicy);
1773
1774 if (ObjCMethodParam) {
1775 Result = "(" + Result;
1776 Result += ")";
Douglas Gregoraba48082010-08-29 19:47:46 +00001777 if (Param->getIdentifier() && !SuppressName)
Douglas Gregor83482d12010-08-24 16:15:59 +00001778 Result += Param->getIdentifier()->getName();
1779 }
1780 return Result;
1781 }
1782
1783 // The argument for a block pointer parameter is a block literal with
1784 // the appropriate type.
1785 FunctionProtoTypeLoc *Block = 0;
1786 TypeLoc TL;
1787 if (TypeSourceInfo *TSInfo = Param->getTypeSourceInfo()) {
1788 TL = TSInfo->getTypeLoc().getUnqualifiedLoc();
1789 while (true) {
1790 // Look through typedefs.
1791 if (TypedefTypeLoc *TypedefTL = dyn_cast<TypedefTypeLoc>(&TL)) {
1792 if (TypeSourceInfo *InnerTSInfo
1793 = TypedefTL->getTypedefDecl()->getTypeSourceInfo()) {
1794 TL = InnerTSInfo->getTypeLoc().getUnqualifiedLoc();
1795 continue;
1796 }
1797 }
1798
1799 // Look through qualified types
1800 if (QualifiedTypeLoc *QualifiedTL = dyn_cast<QualifiedTypeLoc>(&TL)) {
1801 TL = QualifiedTL->getUnqualifiedLoc();
1802 continue;
1803 }
1804
1805 // Try to get the function prototype behind the block pointer type,
1806 // then we're done.
1807 if (BlockPointerTypeLoc *BlockPtr
1808 = dyn_cast<BlockPointerTypeLoc>(&TL)) {
1809 TL = BlockPtr->getPointeeLoc();
1810 Block = dyn_cast<FunctionProtoTypeLoc>(&TL);
1811 }
1812 break;
1813 }
1814 }
1815
1816 if (!Block) {
1817 // We were unable to find a FunctionProtoTypeLoc with parameter names
1818 // for the block; just use the parameter type as a placeholder.
1819 std::string Result;
1820 Param->getType().getUnqualifiedType().
1821 getAsStringInternal(Result, Context.PrintingPolicy);
1822
1823 if (ObjCMethodParam) {
1824 Result = "(" + Result;
1825 Result += ")";
1826 if (Param->getIdentifier())
1827 Result += Param->getIdentifier()->getName();
1828 }
1829
1830 return Result;
1831 }
1832
1833 // We have the function prototype behind the block pointer type, as it was
1834 // written in the source.
Douglas Gregor38276252010-09-08 22:47:51 +00001835 std::string Result;
1836 QualType ResultType = Block->getTypePtr()->getResultType();
1837 if (!ResultType->isVoidType())
1838 ResultType.getAsStringInternal(Result, Context.PrintingPolicy);
1839
1840 Result = '^' + Result;
1841 if (Block->getNumArgs() == 0) {
1842 if (Block->getTypePtr()->isVariadic())
1843 Result += "(...)";
1844 } else {
1845 Result += "(";
1846 for (unsigned I = 0, N = Block->getNumArgs(); I != N; ++I) {
1847 if (I)
1848 Result += ", ";
1849 Result += FormatFunctionParameter(Context, Block->getArg(I));
1850
1851 if (I == N - 1 && Block->getTypePtr()->isVariadic())
1852 Result += ", ...";
1853 }
1854 Result += ")";
Douglas Gregore17794f2010-08-31 05:13:43 +00001855 }
Douglas Gregor38276252010-09-08 22:47:51 +00001856
Douglas Gregor83482d12010-08-24 16:15:59 +00001857 return Result;
1858}
1859
Douglas Gregor86d9a522009-09-21 16:56:56 +00001860/// \brief Add function parameter chunks to the given code completion string.
1861static void AddFunctionParameterChunks(ASTContext &Context,
1862 FunctionDecl *Function,
1863 CodeCompletionString *Result) {
Douglas Gregor0c8296d2009-11-07 00:00:49 +00001864 typedef CodeCompletionString::Chunk Chunk;
1865
Douglas Gregor86d9a522009-09-21 16:56:56 +00001866 CodeCompletionString *CCStr = Result;
1867
1868 for (unsigned P = 0, N = Function->getNumParams(); P != N; ++P) {
1869 ParmVarDecl *Param = Function->getParamDecl(P);
1870
1871 if (Param->hasDefaultArg()) {
1872 // When we see an optional default argument, put that argument and
1873 // the remaining default arguments into a new, optional string.
1874 CodeCompletionString *Opt = new CodeCompletionString;
1875 CCStr->AddOptionalChunk(std::auto_ptr<CodeCompletionString>(Opt));
1876 CCStr = Opt;
1877 }
1878
1879 if (P != 0)
Douglas Gregor0c8296d2009-11-07 00:00:49 +00001880 CCStr->AddChunk(Chunk(CodeCompletionString::CK_Comma));
Douglas Gregor86d9a522009-09-21 16:56:56 +00001881
1882 // Format the placeholder string.
Douglas Gregor83482d12010-08-24 16:15:59 +00001883 std::string PlaceholderStr = FormatFunctionParameter(Context, Param);
1884
Douglas Gregore17794f2010-08-31 05:13:43 +00001885 if (Function->isVariadic() && P == N - 1)
1886 PlaceholderStr += ", ...";
1887
Douglas Gregor86d9a522009-09-21 16:56:56 +00001888 // Add the placeholder string.
Benjamin Kramer660cc182009-11-29 20:18:50 +00001889 CCStr->AddPlaceholderChunk(PlaceholderStr);
Douglas Gregor86d9a522009-09-21 16:56:56 +00001890 }
Douglas Gregorb3d45252009-09-22 21:42:17 +00001891
1892 if (const FunctionProtoType *Proto
1893 = Function->getType()->getAs<FunctionProtoType>())
Douglas Gregoraaa107a2010-08-23 23:51:41 +00001894 if (Proto->isVariadic()) {
Douglas Gregore17794f2010-08-31 05:13:43 +00001895 if (Proto->getNumArgs() == 0)
1896 CCStr->AddPlaceholderChunk("...");
Douglas Gregoraaa107a2010-08-23 23:51:41 +00001897
1898 MaybeAddSentinel(Context, Function, CCStr);
1899 }
Douglas Gregor86d9a522009-09-21 16:56:56 +00001900}
1901
1902/// \brief Add template parameter chunks to the given code completion string.
1903static void AddTemplateParameterChunks(ASTContext &Context,
1904 TemplateDecl *Template,
1905 CodeCompletionString *Result,
1906 unsigned MaxParameters = 0) {
Douglas Gregor0c8296d2009-11-07 00:00:49 +00001907 typedef CodeCompletionString::Chunk Chunk;
1908
Douglas Gregor86d9a522009-09-21 16:56:56 +00001909 CodeCompletionString *CCStr = Result;
1910 bool FirstParameter = true;
1911
1912 TemplateParameterList *Params = Template->getTemplateParameters();
1913 TemplateParameterList::iterator PEnd = Params->end();
1914 if (MaxParameters)
1915 PEnd = Params->begin() + MaxParameters;
1916 for (TemplateParameterList::iterator P = Params->begin(); P != PEnd; ++P) {
1917 bool HasDefaultArg = false;
1918 std::string PlaceholderStr;
1919 if (TemplateTypeParmDecl *TTP = dyn_cast<TemplateTypeParmDecl>(*P)) {
1920 if (TTP->wasDeclaredWithTypename())
1921 PlaceholderStr = "typename";
1922 else
1923 PlaceholderStr = "class";
1924
1925 if (TTP->getIdentifier()) {
1926 PlaceholderStr += ' ';
1927 PlaceholderStr += TTP->getIdentifier()->getName();
1928 }
1929
1930 HasDefaultArg = TTP->hasDefaultArgument();
1931 } else if (NonTypeTemplateParmDecl *NTTP
1932 = dyn_cast<NonTypeTemplateParmDecl>(*P)) {
1933 if (NTTP->getIdentifier())
1934 PlaceholderStr = NTTP->getIdentifier()->getName();
1935 NTTP->getType().getAsStringInternal(PlaceholderStr,
1936 Context.PrintingPolicy);
1937 HasDefaultArg = NTTP->hasDefaultArgument();
1938 } else {
1939 assert(isa<TemplateTemplateParmDecl>(*P));
1940 TemplateTemplateParmDecl *TTP = cast<TemplateTemplateParmDecl>(*P);
1941
1942 // Since putting the template argument list into the placeholder would
1943 // be very, very long, we just use an abbreviation.
1944 PlaceholderStr = "template<...> class";
1945 if (TTP->getIdentifier()) {
1946 PlaceholderStr += ' ';
1947 PlaceholderStr += TTP->getIdentifier()->getName();
1948 }
1949
1950 HasDefaultArg = TTP->hasDefaultArgument();
1951 }
1952
1953 if (HasDefaultArg) {
1954 // When we see an optional default argument, put that argument and
1955 // the remaining default arguments into a new, optional string.
1956 CodeCompletionString *Opt = new CodeCompletionString;
1957 CCStr->AddOptionalChunk(std::auto_ptr<CodeCompletionString>(Opt));
1958 CCStr = Opt;
1959 }
1960
1961 if (FirstParameter)
1962 FirstParameter = false;
1963 else
Douglas Gregor0c8296d2009-11-07 00:00:49 +00001964 CCStr->AddChunk(Chunk(CodeCompletionString::CK_Comma));
Douglas Gregor86d9a522009-09-21 16:56:56 +00001965
1966 // Add the placeholder string.
Benjamin Kramer660cc182009-11-29 20:18:50 +00001967 CCStr->AddPlaceholderChunk(PlaceholderStr);
Douglas Gregor86d9a522009-09-21 16:56:56 +00001968 }
1969}
1970
Douglas Gregorb9d0ef72009-09-21 19:57:38 +00001971/// \brief Add a qualifier to the given code-completion string, if the
1972/// provided nested-name-specifier is non-NULL.
Douglas Gregora61a8792009-12-11 18:44:16 +00001973static void
1974AddQualifierToCompletionString(CodeCompletionString *Result,
1975 NestedNameSpecifier *Qualifier,
1976 bool QualifierIsInformative,
1977 ASTContext &Context) {
Douglas Gregorb9d0ef72009-09-21 19:57:38 +00001978 if (!Qualifier)
1979 return;
1980
1981 std::string PrintedNNS;
1982 {
1983 llvm::raw_string_ostream OS(PrintedNNS);
1984 Qualifier->print(OS, Context.PrintingPolicy);
1985 }
Douglas Gregor0563c262009-09-22 23:15:58 +00001986 if (QualifierIsInformative)
Benjamin Kramer660cc182009-11-29 20:18:50 +00001987 Result->AddInformativeChunk(PrintedNNS);
Douglas Gregor0563c262009-09-22 23:15:58 +00001988 else
Benjamin Kramer660cc182009-11-29 20:18:50 +00001989 Result->AddTextChunk(PrintedNNS);
Douglas Gregorb9d0ef72009-09-21 19:57:38 +00001990}
1991
Douglas Gregora61a8792009-12-11 18:44:16 +00001992static void AddFunctionTypeQualsToCompletionString(CodeCompletionString *Result,
1993 FunctionDecl *Function) {
1994 const FunctionProtoType *Proto
1995 = Function->getType()->getAs<FunctionProtoType>();
1996 if (!Proto || !Proto->getTypeQuals())
1997 return;
1998
1999 std::string QualsStr;
2000 if (Proto->getTypeQuals() & Qualifiers::Const)
2001 QualsStr += " const";
2002 if (Proto->getTypeQuals() & Qualifiers::Volatile)
2003 QualsStr += " volatile";
2004 if (Proto->getTypeQuals() & Qualifiers::Restrict)
2005 QualsStr += " restrict";
2006 Result->AddInformativeChunk(QualsStr);
2007}
2008
Douglas Gregor86d9a522009-09-21 16:56:56 +00002009/// \brief If possible, create a new code completion string for the given
2010/// result.
2011///
2012/// \returns Either a new, heap-allocated code completion string describing
2013/// how to use this result, or NULL to indicate that the string or name of the
2014/// result is all that is needed.
2015CodeCompletionString *
John McCall0a2c5e22010-08-25 06:19:51 +00002016CodeCompletionResult::CreateCodeCompletionString(Sema &S,
Douglas Gregor1abc6bc2010-08-04 16:47:14 +00002017 CodeCompletionString *Result) {
Douglas Gregor0c8296d2009-11-07 00:00:49 +00002018 typedef CodeCompletionString::Chunk Chunk;
2019
Douglas Gregor2b4074f2009-12-01 05:55:20 +00002020 if (Kind == RK_Pattern)
Douglas Gregor1abc6bc2010-08-04 16:47:14 +00002021 return Pattern->Clone(Result);
Douglas Gregor2b4074f2009-12-01 05:55:20 +00002022
Douglas Gregor1abc6bc2010-08-04 16:47:14 +00002023 if (!Result)
2024 Result = new CodeCompletionString;
Douglas Gregor2b4074f2009-12-01 05:55:20 +00002025
2026 if (Kind == RK_Keyword) {
2027 Result->AddTypedTextChunk(Keyword);
2028 return Result;
2029 }
Douglas Gregor86d9a522009-09-21 16:56:56 +00002030
Douglas Gregor3f7c7f42009-10-30 16:50:04 +00002031 if (Kind == RK_Macro) {
2032 MacroInfo *MI = S.PP.getMacroInfo(Macro);
Douglas Gregor2b4074f2009-12-01 05:55:20 +00002033 assert(MI && "Not a macro?");
2034
2035 Result->AddTypedTextChunk(Macro->getName());
2036
2037 if (!MI->isFunctionLike())
2038 return Result;
Douglas Gregor3f7c7f42009-10-30 16:50:04 +00002039
2040 // Format a function-like macro with placeholders for the arguments.
Douglas Gregor0c8296d2009-11-07 00:00:49 +00002041 Result->AddChunk(Chunk(CodeCompletionString::CK_LeftParen));
Douglas Gregor3f7c7f42009-10-30 16:50:04 +00002042 for (MacroInfo::arg_iterator A = MI->arg_begin(), AEnd = MI->arg_end();
2043 A != AEnd; ++A) {
2044 if (A != MI->arg_begin())
Douglas Gregor0c8296d2009-11-07 00:00:49 +00002045 Result->AddChunk(Chunk(CodeCompletionString::CK_Comma));
Douglas Gregor3f7c7f42009-10-30 16:50:04 +00002046
2047 if (!MI->isVariadic() || A != AEnd - 1) {
2048 // Non-variadic argument.
Benjamin Kramer660cc182009-11-29 20:18:50 +00002049 Result->AddPlaceholderChunk((*A)->getName());
Douglas Gregor3f7c7f42009-10-30 16:50:04 +00002050 continue;
2051 }
2052
2053 // Variadic argument; cope with the different between GNU and C99
2054 // variadic macros, providing a single placeholder for the rest of the
2055 // arguments.
2056 if ((*A)->isStr("__VA_ARGS__"))
2057 Result->AddPlaceholderChunk("...");
2058 else {
2059 std::string Arg = (*A)->getName();
2060 Arg += "...";
Benjamin Kramer660cc182009-11-29 20:18:50 +00002061 Result->AddPlaceholderChunk(Arg);
Douglas Gregor3f7c7f42009-10-30 16:50:04 +00002062 }
2063 }
Douglas Gregor0c8296d2009-11-07 00:00:49 +00002064 Result->AddChunk(Chunk(CodeCompletionString::CK_RightParen));
Douglas Gregor3f7c7f42009-10-30 16:50:04 +00002065 return Result;
2066 }
2067
Douglas Gregord8e8a582010-05-25 21:41:55 +00002068 assert(Kind == RK_Declaration && "Missed a result kind?");
Douglas Gregor86d9a522009-09-21 16:56:56 +00002069 NamedDecl *ND = Declaration;
2070
Douglas Gregor0c8296d2009-11-07 00:00:49 +00002071 if (StartsNestedNameSpecifier) {
Benjamin Kramer660cc182009-11-29 20:18:50 +00002072 Result->AddTypedTextChunk(ND->getNameAsString());
Douglas Gregor0c8296d2009-11-07 00:00:49 +00002073 Result->AddTextChunk("::");
2074 return Result;
2075 }
2076
Douglas Gregorff5ce6e2009-12-18 18:53:37 +00002077 AddResultTypeChunk(S.Context, ND, Result);
2078
Douglas Gregor86d9a522009-09-21 16:56:56 +00002079 if (FunctionDecl *Function = dyn_cast<FunctionDecl>(ND)) {
Douglas Gregor0563c262009-09-22 23:15:58 +00002080 AddQualifierToCompletionString(Result, Qualifier, QualifierIsInformative,
2081 S.Context);
Benjamin Kramer660cc182009-11-29 20:18:50 +00002082 Result->AddTypedTextChunk(Function->getNameAsString());
Douglas Gregor0c8296d2009-11-07 00:00:49 +00002083 Result->AddChunk(Chunk(CodeCompletionString::CK_LeftParen));
Douglas Gregor86d9a522009-09-21 16:56:56 +00002084 AddFunctionParameterChunks(S.Context, Function, Result);
Douglas Gregor0c8296d2009-11-07 00:00:49 +00002085 Result->AddChunk(Chunk(CodeCompletionString::CK_RightParen));
Douglas Gregora61a8792009-12-11 18:44:16 +00002086 AddFunctionTypeQualsToCompletionString(Result, Function);
Douglas Gregor86d9a522009-09-21 16:56:56 +00002087 return Result;
2088 }
2089
2090 if (FunctionTemplateDecl *FunTmpl = dyn_cast<FunctionTemplateDecl>(ND)) {
Douglas Gregor0563c262009-09-22 23:15:58 +00002091 AddQualifierToCompletionString(Result, Qualifier, QualifierIsInformative,
2092 S.Context);
Douglas Gregor86d9a522009-09-21 16:56:56 +00002093 FunctionDecl *Function = FunTmpl->getTemplatedDecl();
Benjamin Kramer660cc182009-11-29 20:18:50 +00002094 Result->AddTypedTextChunk(Function->getNameAsString());
Douglas Gregor86d9a522009-09-21 16:56:56 +00002095
2096 // Figure out which template parameters are deduced (or have default
2097 // arguments).
2098 llvm::SmallVector<bool, 16> Deduced;
2099 S.MarkDeducedTemplateParameters(FunTmpl, Deduced);
2100 unsigned LastDeducibleArgument;
2101 for (LastDeducibleArgument = Deduced.size(); LastDeducibleArgument > 0;
2102 --LastDeducibleArgument) {
2103 if (!Deduced[LastDeducibleArgument - 1]) {
2104 // C++0x: Figure out if the template argument has a default. If so,
2105 // the user doesn't need to type this argument.
2106 // FIXME: We need to abstract template parameters better!
2107 bool HasDefaultArg = false;
2108 NamedDecl *Param = FunTmpl->getTemplateParameters()->getParam(
2109 LastDeducibleArgument - 1);
2110 if (TemplateTypeParmDecl *TTP = dyn_cast<TemplateTypeParmDecl>(Param))
2111 HasDefaultArg = TTP->hasDefaultArgument();
2112 else if (NonTypeTemplateParmDecl *NTTP
2113 = dyn_cast<NonTypeTemplateParmDecl>(Param))
2114 HasDefaultArg = NTTP->hasDefaultArgument();
2115 else {
2116 assert(isa<TemplateTemplateParmDecl>(Param));
2117 HasDefaultArg
Douglas Gregor0c8296d2009-11-07 00:00:49 +00002118 = cast<TemplateTemplateParmDecl>(Param)->hasDefaultArgument();
Douglas Gregor86d9a522009-09-21 16:56:56 +00002119 }
2120
2121 if (!HasDefaultArg)
2122 break;
2123 }
2124 }
2125
2126 if (LastDeducibleArgument) {
2127 // Some of the function template arguments cannot be deduced from a
2128 // function call, so we introduce an explicit template argument list
2129 // containing all of the arguments up to the first deducible argument.
Douglas Gregor0c8296d2009-11-07 00:00:49 +00002130 Result->AddChunk(Chunk(CodeCompletionString::CK_LeftAngle));
Douglas Gregor86d9a522009-09-21 16:56:56 +00002131 AddTemplateParameterChunks(S.Context, FunTmpl, Result,
2132 LastDeducibleArgument);
Douglas Gregor0c8296d2009-11-07 00:00:49 +00002133 Result->AddChunk(Chunk(CodeCompletionString::CK_RightAngle));
Douglas Gregor86d9a522009-09-21 16:56:56 +00002134 }
2135
2136 // Add the function parameters
Douglas Gregor0c8296d2009-11-07 00:00:49 +00002137 Result->AddChunk(Chunk(CodeCompletionString::CK_LeftParen));
Douglas Gregor86d9a522009-09-21 16:56:56 +00002138 AddFunctionParameterChunks(S.Context, Function, Result);
Douglas Gregor0c8296d2009-11-07 00:00:49 +00002139 Result->AddChunk(Chunk(CodeCompletionString::CK_RightParen));
Douglas Gregora61a8792009-12-11 18:44:16 +00002140 AddFunctionTypeQualsToCompletionString(Result, Function);
Douglas Gregor86d9a522009-09-21 16:56:56 +00002141 return Result;
2142 }
2143
2144 if (TemplateDecl *Template = dyn_cast<TemplateDecl>(ND)) {
Douglas Gregor0563c262009-09-22 23:15:58 +00002145 AddQualifierToCompletionString(Result, Qualifier, QualifierIsInformative,
2146 S.Context);
Benjamin Kramer660cc182009-11-29 20:18:50 +00002147 Result->AddTypedTextChunk(Template->getNameAsString());
Douglas Gregor0c8296d2009-11-07 00:00:49 +00002148 Result->AddChunk(Chunk(CodeCompletionString::CK_LeftAngle));
Douglas Gregor86d9a522009-09-21 16:56:56 +00002149 AddTemplateParameterChunks(S.Context, Template, Result);
Douglas Gregor0c8296d2009-11-07 00:00:49 +00002150 Result->AddChunk(Chunk(CodeCompletionString::CK_RightAngle));
Douglas Gregor86d9a522009-09-21 16:56:56 +00002151 return Result;
2152 }
2153
Douglas Gregor9630eb62009-11-17 16:44:22 +00002154 if (ObjCMethodDecl *Method = dyn_cast<ObjCMethodDecl>(ND)) {
Douglas Gregor9630eb62009-11-17 16:44:22 +00002155 Selector Sel = Method->getSelector();
2156 if (Sel.isUnarySelector()) {
2157 Result->AddTypedTextChunk(Sel.getIdentifierInfoForSlot(0)->getName());
2158 return Result;
2159 }
2160
Douglas Gregord3c68542009-11-19 01:08:35 +00002161 std::string SelName = Sel.getIdentifierInfoForSlot(0)->getName().str();
2162 SelName += ':';
2163 if (StartParameter == 0)
2164 Result->AddTypedTextChunk(SelName);
2165 else {
2166 Result->AddInformativeChunk(SelName);
2167
2168 // If there is only one parameter, and we're past it, add an empty
2169 // typed-text chunk since there is nothing to type.
2170 if (Method->param_size() == 1)
2171 Result->AddTypedTextChunk("");
2172 }
Douglas Gregor9630eb62009-11-17 16:44:22 +00002173 unsigned Idx = 0;
2174 for (ObjCMethodDecl::param_iterator P = Method->param_begin(),
2175 PEnd = Method->param_end();
2176 P != PEnd; (void)++P, ++Idx) {
2177 if (Idx > 0) {
Douglas Gregord3c68542009-11-19 01:08:35 +00002178 std::string Keyword;
2179 if (Idx > StartParameter)
Douglas Gregor834389b2010-01-12 06:38:28 +00002180 Result->AddChunk(CodeCompletionString::CK_HorizontalSpace);
Douglas Gregor9630eb62009-11-17 16:44:22 +00002181 if (IdentifierInfo *II = Sel.getIdentifierInfoForSlot(Idx))
2182 Keyword += II->getName().str();
2183 Keyword += ":";
Douglas Gregor1f5537a2010-07-08 23:20:03 +00002184 if (Idx < StartParameter || AllParametersAreInformative)
Douglas Gregord3c68542009-11-19 01:08:35 +00002185 Result->AddInformativeChunk(Keyword);
Douglas Gregor1f5537a2010-07-08 23:20:03 +00002186 else if (Idx == StartParameter)
Douglas Gregord3c68542009-11-19 01:08:35 +00002187 Result->AddTypedTextChunk(Keyword);
2188 else
2189 Result->AddTextChunk(Keyword);
Douglas Gregor9630eb62009-11-17 16:44:22 +00002190 }
Douglas Gregord3c68542009-11-19 01:08:35 +00002191
2192 // If we're before the starting parameter, skip the placeholder.
2193 if (Idx < StartParameter)
2194 continue;
Douglas Gregor9630eb62009-11-17 16:44:22 +00002195
2196 std::string Arg;
Douglas Gregor83482d12010-08-24 16:15:59 +00002197
2198 if ((*P)->getType()->isBlockPointerType() && !DeclaringEntity)
Douglas Gregoraba48082010-08-29 19:47:46 +00002199 Arg = FormatFunctionParameter(S.Context, *P, true);
Douglas Gregor83482d12010-08-24 16:15:59 +00002200 else {
2201 (*P)->getType().getAsStringInternal(Arg, S.Context.PrintingPolicy);
2202 Arg = "(" + Arg + ")";
2203 if (IdentifierInfo *II = (*P)->getIdentifier())
Douglas Gregoraba48082010-08-29 19:47:46 +00002204 if (DeclaringEntity || AllParametersAreInformative)
2205 Arg += II->getName().str();
Douglas Gregor83482d12010-08-24 16:15:59 +00002206 }
2207
Douglas Gregore17794f2010-08-31 05:13:43 +00002208 if (Method->isVariadic() && (P + 1) == PEnd)
2209 Arg += ", ...";
2210
Douglas Gregor1f5537a2010-07-08 23:20:03 +00002211 if (DeclaringEntity)
2212 Result->AddTextChunk(Arg);
2213 else if (AllParametersAreInformative)
Douglas Gregor4ad96852009-11-19 07:41:15 +00002214 Result->AddInformativeChunk(Arg);
2215 else
2216 Result->AddPlaceholderChunk(Arg);
Douglas Gregor9630eb62009-11-17 16:44:22 +00002217 }
2218
Douglas Gregor2a17af02009-12-23 00:21:46 +00002219 if (Method->isVariadic()) {
Douglas Gregore17794f2010-08-31 05:13:43 +00002220 if (Method->param_size() == 0) {
2221 if (DeclaringEntity)
2222 Result->AddTextChunk(", ...");
2223 else if (AllParametersAreInformative)
2224 Result->AddInformativeChunk(", ...");
2225 else
2226 Result->AddPlaceholderChunk(", ...");
2227 }
Douglas Gregoraaa107a2010-08-23 23:51:41 +00002228
2229 MaybeAddSentinel(S.Context, Method, Result);
Douglas Gregor2a17af02009-12-23 00:21:46 +00002230 }
2231
Douglas Gregor9630eb62009-11-17 16:44:22 +00002232 return Result;
2233 }
2234
Douglas Gregor2b4074f2009-12-01 05:55:20 +00002235 if (Qualifier)
Douglas Gregor0563c262009-09-22 23:15:58 +00002236 AddQualifierToCompletionString(Result, Qualifier, QualifierIsInformative,
2237 S.Context);
Douglas Gregor2b4074f2009-12-01 05:55:20 +00002238
2239 Result->AddTypedTextChunk(ND->getNameAsString());
2240 return Result;
Douglas Gregor86d9a522009-09-21 16:56:56 +00002241}
2242
Douglas Gregor86d802e2009-09-23 00:34:09 +00002243CodeCompletionString *
2244CodeCompleteConsumer::OverloadCandidate::CreateSignatureString(
2245 unsigned CurrentArg,
2246 Sema &S) const {
Douglas Gregor0c8296d2009-11-07 00:00:49 +00002247 typedef CodeCompletionString::Chunk Chunk;
2248
Douglas Gregor86d802e2009-09-23 00:34:09 +00002249 CodeCompletionString *Result = new CodeCompletionString;
2250 FunctionDecl *FDecl = getFunction();
Douglas Gregorff5ce6e2009-12-18 18:53:37 +00002251 AddResultTypeChunk(S.Context, FDecl, Result);
Douglas Gregor86d802e2009-09-23 00:34:09 +00002252 const FunctionProtoType *Proto
2253 = dyn_cast<FunctionProtoType>(getFunctionType());
2254 if (!FDecl && !Proto) {
2255 // Function without a prototype. Just give the return type and a
2256 // highlighted ellipsis.
2257 const FunctionType *FT = getFunctionType();
2258 Result->AddTextChunk(
Benjamin Kramer660cc182009-11-29 20:18:50 +00002259 FT->getResultType().getAsString(S.Context.PrintingPolicy));
Douglas Gregor0c8296d2009-11-07 00:00:49 +00002260 Result->AddChunk(Chunk(CodeCompletionString::CK_LeftParen));
2261 Result->AddChunk(Chunk(CodeCompletionString::CK_CurrentParameter, "..."));
2262 Result->AddChunk(Chunk(CodeCompletionString::CK_RightParen));
Douglas Gregor86d802e2009-09-23 00:34:09 +00002263 return Result;
2264 }
2265
2266 if (FDecl)
Benjamin Kramer660cc182009-11-29 20:18:50 +00002267 Result->AddTextChunk(FDecl->getNameAsString());
Douglas Gregor86d802e2009-09-23 00:34:09 +00002268 else
2269 Result->AddTextChunk(
Benjamin Kramer660cc182009-11-29 20:18:50 +00002270 Proto->getResultType().getAsString(S.Context.PrintingPolicy));
Douglas Gregor86d802e2009-09-23 00:34:09 +00002271
Douglas Gregor0c8296d2009-11-07 00:00:49 +00002272 Result->AddChunk(Chunk(CodeCompletionString::CK_LeftParen));
Douglas Gregor86d802e2009-09-23 00:34:09 +00002273 unsigned NumParams = FDecl? FDecl->getNumParams() : Proto->getNumArgs();
2274 for (unsigned I = 0; I != NumParams; ++I) {
2275 if (I)
Douglas Gregor0c8296d2009-11-07 00:00:49 +00002276 Result->AddChunk(Chunk(CodeCompletionString::CK_Comma));
Douglas Gregor86d802e2009-09-23 00:34:09 +00002277
2278 std::string ArgString;
2279 QualType ArgType;
2280
2281 if (FDecl) {
2282 ArgString = FDecl->getParamDecl(I)->getNameAsString();
2283 ArgType = FDecl->getParamDecl(I)->getOriginalType();
2284 } else {
2285 ArgType = Proto->getArgType(I);
2286 }
2287
2288 ArgType.getAsStringInternal(ArgString, S.Context.PrintingPolicy);
2289
2290 if (I == CurrentArg)
Douglas Gregor0c8296d2009-11-07 00:00:49 +00002291 Result->AddChunk(Chunk(CodeCompletionString::CK_CurrentParameter,
Benjamin Kramer660cc182009-11-29 20:18:50 +00002292 ArgString));
Douglas Gregor86d802e2009-09-23 00:34:09 +00002293 else
Benjamin Kramer660cc182009-11-29 20:18:50 +00002294 Result->AddTextChunk(ArgString);
Douglas Gregor86d802e2009-09-23 00:34:09 +00002295 }
2296
2297 if (Proto && Proto->isVariadic()) {
Douglas Gregor0c8296d2009-11-07 00:00:49 +00002298 Result->AddChunk(Chunk(CodeCompletionString::CK_Comma));
Douglas Gregor86d802e2009-09-23 00:34:09 +00002299 if (CurrentArg < NumParams)
2300 Result->AddTextChunk("...");
2301 else
Douglas Gregor0c8296d2009-11-07 00:00:49 +00002302 Result->AddChunk(Chunk(CodeCompletionString::CK_CurrentParameter, "..."));
Douglas Gregor86d802e2009-09-23 00:34:09 +00002303 }
Douglas Gregor0c8296d2009-11-07 00:00:49 +00002304 Result->AddChunk(Chunk(CodeCompletionString::CK_RightParen));
Douglas Gregor86d802e2009-09-23 00:34:09 +00002305
2306 return Result;
2307}
2308
Douglas Gregor1827e102010-08-16 16:18:59 +00002309unsigned clang::getMacroUsagePriority(llvm::StringRef MacroName,
2310 bool PreferredTypeIsPointer) {
2311 unsigned Priority = CCP_Macro;
2312
2313 // Treat the "nil" and "NULL" macros as null pointer constants.
2314 if (MacroName.equals("nil") || MacroName.equals("NULL")) {
2315 Priority = CCP_Constant;
2316 if (PreferredTypeIsPointer)
2317 Priority = Priority / CCF_SimilarTypeMatch;
2318 }
2319
2320 return Priority;
2321}
2322
Douglas Gregore8d7beb2010-09-03 23:30:36 +00002323CXCursorKind clang::getCursorKindForDecl(Decl *D) {
2324 if (!D)
2325 return CXCursor_UnexposedDecl;
2326
2327 switch (D->getKind()) {
2328 case Decl::Enum: return CXCursor_EnumDecl;
2329 case Decl::EnumConstant: return CXCursor_EnumConstantDecl;
2330 case Decl::Field: return CXCursor_FieldDecl;
2331 case Decl::Function:
2332 return CXCursor_FunctionDecl;
2333 case Decl::ObjCCategory: return CXCursor_ObjCCategoryDecl;
2334 case Decl::ObjCCategoryImpl: return CXCursor_ObjCCategoryImplDecl;
2335 case Decl::ObjCClass:
2336 // FIXME
2337 return CXCursor_UnexposedDecl;
2338 case Decl::ObjCForwardProtocol:
2339 // FIXME
2340 return CXCursor_UnexposedDecl;
2341 case Decl::ObjCImplementation: return CXCursor_ObjCImplementationDecl;
2342 case Decl::ObjCInterface: return CXCursor_ObjCInterfaceDecl;
2343 case Decl::ObjCIvar: return CXCursor_ObjCIvarDecl;
2344 case Decl::ObjCMethod:
2345 return cast<ObjCMethodDecl>(D)->isInstanceMethod()
2346 ? CXCursor_ObjCInstanceMethodDecl : CXCursor_ObjCClassMethodDecl;
2347 case Decl::CXXMethod: return CXCursor_CXXMethod;
2348 case Decl::CXXConstructor: return CXCursor_Constructor;
2349 case Decl::CXXDestructor: return CXCursor_Destructor;
2350 case Decl::CXXConversion: return CXCursor_ConversionFunction;
2351 case Decl::ObjCProperty: return CXCursor_ObjCPropertyDecl;
2352 case Decl::ObjCProtocol: return CXCursor_ObjCProtocolDecl;
2353 case Decl::ParmVar: return CXCursor_ParmDecl;
2354 case Decl::Typedef: return CXCursor_TypedefDecl;
2355 case Decl::Var: return CXCursor_VarDecl;
2356 case Decl::Namespace: return CXCursor_Namespace;
2357 case Decl::NamespaceAlias: return CXCursor_NamespaceAlias;
2358 case Decl::TemplateTypeParm: return CXCursor_TemplateTypeParameter;
2359 case Decl::NonTypeTemplateParm:return CXCursor_NonTypeTemplateParameter;
2360 case Decl::TemplateTemplateParm:return CXCursor_TemplateTemplateParameter;
2361 case Decl::FunctionTemplate: return CXCursor_FunctionTemplate;
2362 case Decl::ClassTemplate: return CXCursor_ClassTemplate;
2363 case Decl::ClassTemplatePartialSpecialization:
2364 return CXCursor_ClassTemplatePartialSpecialization;
2365 case Decl::UsingDirective: return CXCursor_UsingDirective;
2366
2367 case Decl::Using:
2368 case Decl::UnresolvedUsingValue:
2369 case Decl::UnresolvedUsingTypename:
2370 return CXCursor_UsingDeclaration;
2371
2372 default:
2373 if (TagDecl *TD = dyn_cast<TagDecl>(D)) {
2374 switch (TD->getTagKind()) {
2375 case TTK_Struct: return CXCursor_StructDecl;
2376 case TTK_Class: return CXCursor_ClassDecl;
2377 case TTK_Union: return CXCursor_UnionDecl;
2378 case TTK_Enum: return CXCursor_EnumDecl;
2379 }
2380 }
2381 }
2382
2383 return CXCursor_UnexposedDecl;
2384}
2385
Douglas Gregor590c7d52010-07-08 20:55:51 +00002386static void AddMacroResults(Preprocessor &PP, ResultBuilder &Results,
2387 bool TargetTypeIsPointer = false) {
John McCall0a2c5e22010-08-25 06:19:51 +00002388 typedef CodeCompletionResult Result;
Douglas Gregor590c7d52010-07-08 20:55:51 +00002389
Douglas Gregor3f7c7f42009-10-30 16:50:04 +00002390 Results.EnterNewScope();
Douglas Gregor0c8296d2009-11-07 00:00:49 +00002391 for (Preprocessor::macro_iterator M = PP.macro_begin(),
2392 MEnd = PP.macro_end();
Douglas Gregor590c7d52010-07-08 20:55:51 +00002393 M != MEnd; ++M) {
Douglas Gregor1827e102010-08-16 16:18:59 +00002394 Results.AddResult(Result(M->first,
2395 getMacroUsagePriority(M->first->getName(),
2396 TargetTypeIsPointer)));
Douglas Gregor590c7d52010-07-08 20:55:51 +00002397 }
Douglas Gregor3f7c7f42009-10-30 16:50:04 +00002398 Results.ExitScope();
2399}
2400
Douglas Gregoraa5f77b2010-08-23 21:54:33 +00002401static void AddPrettyFunctionResults(const LangOptions &LangOpts,
2402 ResultBuilder &Results) {
John McCall0a2c5e22010-08-25 06:19:51 +00002403 typedef CodeCompletionResult Result;
Douglas Gregoraa5f77b2010-08-23 21:54:33 +00002404
2405 Results.EnterNewScope();
2406 Results.AddResult(Result("__PRETTY_FUNCTION__", CCP_Constant));
2407 Results.AddResult(Result("__FUNCTION__", CCP_Constant));
2408 if (LangOpts.C99 || LangOpts.CPlusPlus0x)
2409 Results.AddResult(Result("__func__", CCP_Constant));
2410 Results.ExitScope();
2411}
2412
Daniel Dunbar3a2838d2009-11-13 08:58:20 +00002413static void HandleCodeCompleteResults(Sema *S,
2414 CodeCompleteConsumer *CodeCompleter,
Douglas Gregore6b1bb62010-08-11 21:23:17 +00002415 CodeCompletionContext Context,
John McCall0a2c5e22010-08-25 06:19:51 +00002416 CodeCompletionResult *Results,
Douglas Gregore6b1bb62010-08-11 21:23:17 +00002417 unsigned NumResults) {
Douglas Gregor86d9a522009-09-21 16:56:56 +00002418 if (CodeCompleter)
Douglas Gregore6b1bb62010-08-11 21:23:17 +00002419 CodeCompleter->ProcessCodeCompleteResults(*S, Context, Results, NumResults);
Douglas Gregor54f01612009-11-19 00:01:57 +00002420
2421 for (unsigned I = 0; I != NumResults; ++I)
2422 Results[I].Destroy();
Douglas Gregor86d9a522009-09-21 16:56:56 +00002423}
2424
Douglas Gregore6b1bb62010-08-11 21:23:17 +00002425static enum CodeCompletionContext::Kind mapCodeCompletionContext(Sema &S,
2426 Sema::ParserCompletionContext PCC) {
2427 switch (PCC) {
John McCallf312b1e2010-08-26 23:41:50 +00002428 case Sema::PCC_Namespace:
Douglas Gregore6b1bb62010-08-11 21:23:17 +00002429 return CodeCompletionContext::CCC_TopLevel;
2430
John McCallf312b1e2010-08-26 23:41:50 +00002431 case Sema::PCC_Class:
Douglas Gregore6b1bb62010-08-11 21:23:17 +00002432 return CodeCompletionContext::CCC_ClassStructUnion;
2433
John McCallf312b1e2010-08-26 23:41:50 +00002434 case Sema::PCC_ObjCInterface:
Douglas Gregore6b1bb62010-08-11 21:23:17 +00002435 return CodeCompletionContext::CCC_ObjCInterface;
2436
John McCallf312b1e2010-08-26 23:41:50 +00002437 case Sema::PCC_ObjCImplementation:
Douglas Gregore6b1bb62010-08-11 21:23:17 +00002438 return CodeCompletionContext::CCC_ObjCImplementation;
2439
John McCallf312b1e2010-08-26 23:41:50 +00002440 case Sema::PCC_ObjCInstanceVariableList:
Douglas Gregore6b1bb62010-08-11 21:23:17 +00002441 return CodeCompletionContext::CCC_ObjCIvarList;
2442
John McCallf312b1e2010-08-26 23:41:50 +00002443 case Sema::PCC_Template:
2444 case Sema::PCC_MemberTemplate:
2445 case Sema::PCC_RecoveryInFunction:
Douglas Gregore6b1bb62010-08-11 21:23:17 +00002446 return CodeCompletionContext::CCC_Other;
2447
John McCallf312b1e2010-08-26 23:41:50 +00002448 case Sema::PCC_Expression:
2449 case Sema::PCC_ForInit:
2450 case Sema::PCC_Condition:
Douglas Gregore6b1bb62010-08-11 21:23:17 +00002451 return CodeCompletionContext::CCC_Expression;
2452
John McCallf312b1e2010-08-26 23:41:50 +00002453 case Sema::PCC_Statement:
Douglas Gregore6b1bb62010-08-11 21:23:17 +00002454 return CodeCompletionContext::CCC_Statement;
Douglas Gregor72db1082010-08-24 01:11:00 +00002455
John McCallf312b1e2010-08-26 23:41:50 +00002456 case Sema::PCC_Type:
Douglas Gregor72db1082010-08-24 01:11:00 +00002457 return CodeCompletionContext::CCC_Type;
Douglas Gregor02688102010-09-14 23:59:36 +00002458
2459 case Sema::PCC_ParenthesizedExpression:
2460 return CodeCompletionContext::CCC_ParenthesizedExpression;
Douglas Gregore6b1bb62010-08-11 21:23:17 +00002461 }
2462
2463 return CodeCompletionContext::CCC_Other;
2464}
2465
Douglas Gregorf6961522010-08-27 21:18:54 +00002466/// \brief If we're in a C++ virtual member function, add completion results
2467/// that invoke the functions we override, since it's common to invoke the
2468/// overridden function as well as adding new functionality.
2469///
2470/// \param S The semantic analysis object for which we are generating results.
2471///
2472/// \param InContext This context in which the nested-name-specifier preceding
2473/// the code-completion point
2474static void MaybeAddOverrideCalls(Sema &S, DeclContext *InContext,
2475 ResultBuilder &Results) {
2476 // Look through blocks.
2477 DeclContext *CurContext = S.CurContext;
2478 while (isa<BlockDecl>(CurContext))
2479 CurContext = CurContext->getParent();
2480
2481
2482 CXXMethodDecl *Method = dyn_cast<CXXMethodDecl>(CurContext);
2483 if (!Method || !Method->isVirtual())
2484 return;
2485
2486 // We need to have names for all of the parameters, if we're going to
2487 // generate a forwarding call.
2488 for (CXXMethodDecl::param_iterator P = Method->param_begin(),
2489 PEnd = Method->param_end();
2490 P != PEnd;
2491 ++P) {
2492 if (!(*P)->getDeclName())
2493 return;
2494 }
2495
2496 for (CXXMethodDecl::method_iterator M = Method->begin_overridden_methods(),
2497 MEnd = Method->end_overridden_methods();
2498 M != MEnd; ++M) {
2499 CodeCompletionString *Pattern = new CodeCompletionString;
2500 CXXMethodDecl *Overridden = const_cast<CXXMethodDecl *>(*M);
2501 if (Overridden->getCanonicalDecl() == Method->getCanonicalDecl())
2502 continue;
2503
2504 // If we need a nested-name-specifier, add one now.
2505 if (!InContext) {
2506 NestedNameSpecifier *NNS
2507 = getRequiredQualification(S.Context, CurContext,
2508 Overridden->getDeclContext());
2509 if (NNS) {
2510 std::string Str;
2511 llvm::raw_string_ostream OS(Str);
2512 NNS->print(OS, S.Context.PrintingPolicy);
2513 Pattern->AddTextChunk(OS.str());
2514 }
2515 } else if (!InContext->Equals(Overridden->getDeclContext()))
2516 continue;
2517
2518 Pattern->AddTypedTextChunk(Overridden->getNameAsString());
2519 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
2520 bool FirstParam = true;
2521 for (CXXMethodDecl::param_iterator P = Method->param_begin(),
2522 PEnd = Method->param_end();
2523 P != PEnd; ++P) {
2524 if (FirstParam)
2525 FirstParam = false;
2526 else
2527 Pattern->AddChunk(CodeCompletionString::CK_Comma);
2528
2529 Pattern->AddPlaceholderChunk((*P)->getIdentifier()->getName());
2530 }
2531 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
2532 Results.AddResult(CodeCompletionResult(Pattern,
2533 CCP_SuperCompletion,
2534 CXCursor_CXXMethod));
2535 Results.Ignore(Overridden);
2536 }
2537}
2538
Douglas Gregor01dfea02010-01-10 23:08:15 +00002539void Sema::CodeCompleteOrdinaryName(Scope *S,
Douglas Gregore6b1bb62010-08-11 21:23:17 +00002540 ParserCompletionContext CompletionContext) {
John McCall0a2c5e22010-08-25 06:19:51 +00002541 typedef CodeCompletionResult Result;
Douglas Gregor2ccccb32010-08-23 18:23:48 +00002542 ResultBuilder Results(*this);
Douglas Gregorf6961522010-08-27 21:18:54 +00002543 Results.EnterNewScope();
Douglas Gregor01dfea02010-01-10 23:08:15 +00002544
2545 // Determine how to filter results, e.g., so that the names of
2546 // values (functions, enumerators, function templates, etc.) are
2547 // only allowed where we can have an expression.
2548 switch (CompletionContext) {
Douglas Gregore6b1bb62010-08-11 21:23:17 +00002549 case PCC_Namespace:
2550 case PCC_Class:
2551 case PCC_ObjCInterface:
2552 case PCC_ObjCImplementation:
2553 case PCC_ObjCInstanceVariableList:
2554 case PCC_Template:
2555 case PCC_MemberTemplate:
Douglas Gregor72db1082010-08-24 01:11:00 +00002556 case PCC_Type:
Douglas Gregor01dfea02010-01-10 23:08:15 +00002557 Results.setFilter(&ResultBuilder::IsOrdinaryNonValueName);
2558 break;
2559
Douglas Gregore6b1bb62010-08-11 21:23:17 +00002560 case PCC_Statement:
Douglas Gregoreb0d0142010-08-24 23:58:17 +00002561 // For statements that are expressions, we prefer to call 'void' functions
2562 // rather than functions that return a result, since then the result would
2563 // be ignored.
2564 Results.setPreferredType(Context.VoidTy);
2565 // Fall through
2566
Douglas Gregor02688102010-09-14 23:59:36 +00002567 case PCC_ParenthesizedExpression:
Douglas Gregoreb0d0142010-08-24 23:58:17 +00002568 case PCC_Expression:
Douglas Gregore6b1bb62010-08-11 21:23:17 +00002569 case PCC_ForInit:
2570 case PCC_Condition:
Douglas Gregor4710e5b2010-05-28 00:49:12 +00002571 if (WantTypesInContext(CompletionContext, getLangOptions()))
2572 Results.setFilter(&ResultBuilder::IsOrdinaryName);
2573 else
2574 Results.setFilter(&ResultBuilder::IsOrdinaryNonTypeName);
Douglas Gregorf6961522010-08-27 21:18:54 +00002575
2576 if (getLangOptions().CPlusPlus)
2577 MaybeAddOverrideCalls(*this, /*InContext=*/0, Results);
Douglas Gregor01dfea02010-01-10 23:08:15 +00002578 break;
Douglas Gregordc845342010-05-25 05:58:43 +00002579
Douglas Gregore6b1bb62010-08-11 21:23:17 +00002580 case PCC_RecoveryInFunction:
Douglas Gregordc845342010-05-25 05:58:43 +00002581 // Unfiltered
2582 break;
Douglas Gregor01dfea02010-01-10 23:08:15 +00002583 }
2584
Douglas Gregor3cdee122010-08-26 16:36:48 +00002585 // If we are in a C++ non-static member function, check the qualifiers on
2586 // the member function to filter/prioritize the results list.
2587 if (CXXMethodDecl *CurMethod = dyn_cast<CXXMethodDecl>(CurContext))
2588 if (CurMethod->isInstance())
2589 Results.setObjectTypeQualifiers(
2590 Qualifiers::fromCVRMask(CurMethod->getTypeQualifiers()));
2591
Douglas Gregor1ca6ae82010-01-14 01:09:38 +00002592 CodeCompletionDeclConsumer Consumer(Results, CurContext);
Douglas Gregor8071e422010-08-15 06:18:01 +00002593 LookupVisibleDecls(S, LookupOrdinaryName, Consumer,
2594 CodeCompleter->includeGlobals());
Douglas Gregor2a7925c2009-12-07 09:54:55 +00002595
Douglas Gregorbca403c2010-01-13 23:51:12 +00002596 AddOrdinaryNameResults(CompletionContext, S, *this, Results);
Douglas Gregor2a7925c2009-12-07 09:54:55 +00002597 Results.ExitScope();
2598
Douglas Gregoraa5f77b2010-08-23 21:54:33 +00002599 switch (CompletionContext) {
Douglas Gregor02688102010-09-14 23:59:36 +00002600 case PCC_ParenthesizedExpression:
Douglas Gregor72db1082010-08-24 01:11:00 +00002601 case PCC_Expression:
2602 case PCC_Statement:
2603 case PCC_RecoveryInFunction:
2604 if (S->getFnParent())
2605 AddPrettyFunctionResults(PP.getLangOptions(), Results);
2606 break;
2607
2608 case PCC_Namespace:
2609 case PCC_Class:
2610 case PCC_ObjCInterface:
2611 case PCC_ObjCImplementation:
2612 case PCC_ObjCInstanceVariableList:
2613 case PCC_Template:
2614 case PCC_MemberTemplate:
2615 case PCC_ForInit:
2616 case PCC_Condition:
2617 case PCC_Type:
2618 break;
Douglas Gregoraa5f77b2010-08-23 21:54:33 +00002619 }
2620
Douglas Gregor0c8296d2009-11-07 00:00:49 +00002621 if (CodeCompleter->includeMacros())
Douglas Gregorbca403c2010-01-13 23:51:12 +00002622 AddMacroResults(PP, Results);
Douglas Gregoraa5f77b2010-08-23 21:54:33 +00002623
Douglas Gregore6b1bb62010-08-11 21:23:17 +00002624 HandleCodeCompleteResults(this, CodeCompleter,
2625 mapCodeCompletionContext(*this, CompletionContext),
2626 Results.data(),Results.size());
Douglas Gregor791215b2009-09-21 20:51:25 +00002627}
2628
Douglas Gregorc7b6d882010-09-16 15:14:18 +00002629static void AddClassMessageCompletions(Sema &SemaRef, Scope *S,
2630 ParsedType Receiver,
2631 IdentifierInfo **SelIdents,
2632 unsigned NumSelIdents,
2633 bool IsSuper,
2634 ResultBuilder &Results);
2635
2636void Sema::CodeCompleteDeclSpec(Scope *S, DeclSpec &DS,
2637 bool AllowNonIdentifiers,
2638 bool AllowNestedNameSpecifiers) {
John McCall0a2c5e22010-08-25 06:19:51 +00002639 typedef CodeCompletionResult Result;
Douglas Gregor2ccccb32010-08-23 18:23:48 +00002640 ResultBuilder Results(*this);
2641 Results.EnterNewScope();
2642
2643 // Type qualifiers can come after names.
2644 Results.AddResult(Result("const"));
2645 Results.AddResult(Result("volatile"));
2646 if (getLangOptions().C99)
2647 Results.AddResult(Result("restrict"));
2648
2649 if (getLangOptions().CPlusPlus) {
2650 if (AllowNonIdentifiers) {
2651 Results.AddResult(Result("operator"));
2652 }
2653
2654 // Add nested-name-specifiers.
2655 if (AllowNestedNameSpecifiers) {
2656 Results.allowNestedNameSpecifiers();
2657 CodeCompletionDeclConsumer Consumer(Results, CurContext);
2658 LookupVisibleDecls(S, LookupNestedNameSpecifierName, Consumer,
2659 CodeCompleter->includeGlobals());
2660 }
2661 }
2662 Results.ExitScope();
2663
Douglas Gregorc7b6d882010-09-16 15:14:18 +00002664 // If we're in a context where we might have an expression (rather than a
2665 // declaration), and what we've seen so far is an Objective-C type that could
2666 // be a receiver of a class message, this may be a class message send with
2667 // the initial opening bracket '[' missing. Add appropriate completions.
2668 if (AllowNonIdentifiers && !AllowNestedNameSpecifiers &&
2669 DS.getTypeSpecType() == DeclSpec::TST_typename &&
2670 DS.getStorageClassSpecAsWritten() == DeclSpec::SCS_unspecified &&
2671 !DS.isThreadSpecified() && !DS.isExternInLinkageSpec() &&
2672 DS.getTypeSpecComplex() == DeclSpec::TSC_unspecified &&
2673 DS.getTypeSpecSign() == DeclSpec::TSS_unspecified &&
2674 DS.getTypeQualifiers() == 0 &&
2675 S &&
2676 (S->getFlags() & Scope::DeclScope) != 0 &&
2677 (S->getFlags() & (Scope::ClassScope | Scope::TemplateParamScope |
2678 Scope::FunctionPrototypeScope |
2679 Scope::AtCatchScope)) == 0) {
2680 ParsedType T = DS.getRepAsType();
2681 if (!T.get().isNull() && T.get()->isObjCObjectOrInterfaceType())
2682 AddClassMessageCompletions(*this, S, T, 0, 0, false, Results);
2683 }
2684
Douglas Gregor4497dd42010-08-24 04:59:56 +00002685 // Note that we intentionally suppress macro results here, since we do not
2686 // encourage using macros to produce the names of entities.
2687
Douglas Gregor2ccccb32010-08-23 18:23:48 +00002688 HandleCodeCompleteResults(this, CodeCompleter,
2689 AllowNestedNameSpecifiers
2690 ? CodeCompletionContext::CCC_PotentiallyQualifiedName
2691 : CodeCompletionContext::CCC_Name,
2692 Results.data(), Results.size());
2693}
2694
Douglas Gregorfb629412010-08-23 21:17:50 +00002695struct Sema::CodeCompleteExpressionData {
2696 CodeCompleteExpressionData(QualType PreferredType = QualType())
2697 : PreferredType(PreferredType), IntegralConstantExpression(false),
2698 ObjCCollection(false) { }
2699
2700 QualType PreferredType;
2701 bool IntegralConstantExpression;
2702 bool ObjCCollection;
2703 llvm::SmallVector<Decl *, 4> IgnoreDecls;
2704};
2705
Douglas Gregor5ac3bdb2010-05-30 01:49:25 +00002706/// \brief Perform code-completion in an expression context when we know what
2707/// type we're looking for.
Douglas Gregorf9578432010-07-28 21:50:18 +00002708///
2709/// \param IntegralConstantExpression Only permit integral constant
2710/// expressions.
Douglas Gregorfb629412010-08-23 21:17:50 +00002711void Sema::CodeCompleteExpression(Scope *S,
2712 const CodeCompleteExpressionData &Data) {
John McCall0a2c5e22010-08-25 06:19:51 +00002713 typedef CodeCompletionResult Result;
Douglas Gregor5ac3bdb2010-05-30 01:49:25 +00002714 ResultBuilder Results(*this);
2715
Douglas Gregorfb629412010-08-23 21:17:50 +00002716 if (Data.ObjCCollection)
2717 Results.setFilter(&ResultBuilder::IsObjCCollection);
2718 else if (Data.IntegralConstantExpression)
Douglas Gregorf9578432010-07-28 21:50:18 +00002719 Results.setFilter(&ResultBuilder::IsIntegralConstantValue);
Douglas Gregore6b1bb62010-08-11 21:23:17 +00002720 else if (WantTypesInContext(PCC_Expression, getLangOptions()))
Douglas Gregor5ac3bdb2010-05-30 01:49:25 +00002721 Results.setFilter(&ResultBuilder::IsOrdinaryName);
2722 else
2723 Results.setFilter(&ResultBuilder::IsOrdinaryNonTypeName);
Douglas Gregorfb629412010-08-23 21:17:50 +00002724
2725 if (!Data.PreferredType.isNull())
2726 Results.setPreferredType(Data.PreferredType.getNonReferenceType());
2727
2728 // Ignore any declarations that we were told that we don't care about.
2729 for (unsigned I = 0, N = Data.IgnoreDecls.size(); I != N; ++I)
2730 Results.Ignore(Data.IgnoreDecls[I]);
Douglas Gregor5ac3bdb2010-05-30 01:49:25 +00002731
2732 CodeCompletionDeclConsumer Consumer(Results, CurContext);
Douglas Gregor8071e422010-08-15 06:18:01 +00002733 LookupVisibleDecls(S, LookupOrdinaryName, Consumer,
2734 CodeCompleter->includeGlobals());
Douglas Gregor5ac3bdb2010-05-30 01:49:25 +00002735
2736 Results.EnterNewScope();
Douglas Gregore6b1bb62010-08-11 21:23:17 +00002737 AddOrdinaryNameResults(PCC_Expression, S, *this, Results);
Douglas Gregor5ac3bdb2010-05-30 01:49:25 +00002738 Results.ExitScope();
2739
Douglas Gregor590c7d52010-07-08 20:55:51 +00002740 bool PreferredTypeIsPointer = false;
Douglas Gregorfb629412010-08-23 21:17:50 +00002741 if (!Data.PreferredType.isNull())
2742 PreferredTypeIsPointer = Data.PreferredType->isAnyPointerType()
2743 || Data.PreferredType->isMemberPointerType()
2744 || Data.PreferredType->isBlockPointerType();
Douglas Gregor590c7d52010-07-08 20:55:51 +00002745
Douglas Gregoraa5f77b2010-08-23 21:54:33 +00002746 if (S->getFnParent() &&
2747 !Data.ObjCCollection &&
2748 !Data.IntegralConstantExpression)
2749 AddPrettyFunctionResults(PP.getLangOptions(), Results);
2750
Douglas Gregor5ac3bdb2010-05-30 01:49:25 +00002751 if (CodeCompleter->includeMacros())
Douglas Gregor590c7d52010-07-08 20:55:51 +00002752 AddMacroResults(PP, Results, PreferredTypeIsPointer);
Douglas Gregore6b1bb62010-08-11 21:23:17 +00002753 HandleCodeCompleteResults(this, CodeCompleter,
Douglas Gregorfb629412010-08-23 21:17:50 +00002754 CodeCompletionContext(CodeCompletionContext::CCC_Expression,
2755 Data.PreferredType),
Douglas Gregore6b1bb62010-08-11 21:23:17 +00002756 Results.data(),Results.size());
Douglas Gregor5ac3bdb2010-05-30 01:49:25 +00002757}
2758
Douglas Gregor78edf512010-09-15 16:23:04 +00002759void Sema::CodeCompletePostfixExpression(Scope *S, Expr *E) {
2760 if (getLangOptions().ObjC1)
2761 CodeCompleteObjCInstanceMessage(S, E, 0, 0, false);
2762}
Douglas Gregor5ac3bdb2010-05-30 01:49:25 +00002763
Douglas Gregor95ac6552009-11-18 01:29:26 +00002764static void AddObjCProperties(ObjCContainerDecl *Container,
Douglas Gregor322328b2009-11-18 22:32:06 +00002765 bool AllowCategories,
Douglas Gregor95ac6552009-11-18 01:29:26 +00002766 DeclContext *CurContext,
2767 ResultBuilder &Results) {
John McCall0a2c5e22010-08-25 06:19:51 +00002768 typedef CodeCompletionResult Result;
Douglas Gregor95ac6552009-11-18 01:29:26 +00002769
2770 // Add properties in this container.
2771 for (ObjCContainerDecl::prop_iterator P = Container->prop_begin(),
2772 PEnd = Container->prop_end();
2773 P != PEnd;
2774 ++P)
2775 Results.MaybeAddResult(Result(*P, 0), CurContext);
2776
2777 // Add properties in referenced protocols.
2778 if (ObjCProtocolDecl *Protocol = dyn_cast<ObjCProtocolDecl>(Container)) {
2779 for (ObjCProtocolDecl::protocol_iterator P = Protocol->protocol_begin(),
2780 PEnd = Protocol->protocol_end();
2781 P != PEnd; ++P)
Douglas Gregor322328b2009-11-18 22:32:06 +00002782 AddObjCProperties(*P, AllowCategories, CurContext, Results);
Douglas Gregor95ac6552009-11-18 01:29:26 +00002783 } else if (ObjCInterfaceDecl *IFace = dyn_cast<ObjCInterfaceDecl>(Container)){
Douglas Gregor322328b2009-11-18 22:32:06 +00002784 if (AllowCategories) {
2785 // Look through categories.
2786 for (ObjCCategoryDecl *Category = IFace->getCategoryList();
2787 Category; Category = Category->getNextClassCategory())
2788 AddObjCProperties(Category, AllowCategories, CurContext, Results);
2789 }
Douglas Gregor95ac6552009-11-18 01:29:26 +00002790
2791 // Look through protocols.
Ted Kremenek53b94412010-09-01 01:21:15 +00002792 for (ObjCInterfaceDecl::all_protocol_iterator
2793 I = IFace->all_referenced_protocol_begin(),
2794 E = IFace->all_referenced_protocol_end(); I != E; ++I)
Douglas Gregor322328b2009-11-18 22:32:06 +00002795 AddObjCProperties(*I, AllowCategories, CurContext, Results);
Douglas Gregor95ac6552009-11-18 01:29:26 +00002796
2797 // Look in the superclass.
2798 if (IFace->getSuperClass())
Douglas Gregor322328b2009-11-18 22:32:06 +00002799 AddObjCProperties(IFace->getSuperClass(), AllowCategories, CurContext,
2800 Results);
Douglas Gregor95ac6552009-11-18 01:29:26 +00002801 } else if (const ObjCCategoryDecl *Category
2802 = dyn_cast<ObjCCategoryDecl>(Container)) {
2803 // Look through protocols.
Ted Kremenek53b94412010-09-01 01:21:15 +00002804 for (ObjCCategoryDecl::protocol_iterator P = Category->protocol_begin(),
2805 PEnd = Category->protocol_end();
Douglas Gregor95ac6552009-11-18 01:29:26 +00002806 P != PEnd; ++P)
Douglas Gregor322328b2009-11-18 22:32:06 +00002807 AddObjCProperties(*P, AllowCategories, CurContext, Results);
Douglas Gregor95ac6552009-11-18 01:29:26 +00002808 }
2809}
2810
Douglas Gregor81b747b2009-09-17 21:32:03 +00002811void Sema::CodeCompleteMemberReferenceExpr(Scope *S, ExprTy *BaseE,
2812 SourceLocation OpLoc,
2813 bool IsArrow) {
2814 if (!BaseE || !CodeCompleter)
2815 return;
2816
John McCall0a2c5e22010-08-25 06:19:51 +00002817 typedef CodeCompletionResult Result;
Douglas Gregor86d9a522009-09-21 16:56:56 +00002818
Douglas Gregor81b747b2009-09-17 21:32:03 +00002819 Expr *Base = static_cast<Expr *>(BaseE);
2820 QualType BaseType = Base->getType();
Douglas Gregor86d9a522009-09-21 16:56:56 +00002821
2822 if (IsArrow) {
2823 if (const PointerType *Ptr = BaseType->getAs<PointerType>())
2824 BaseType = Ptr->getPointeeType();
2825 else if (BaseType->isObjCObjectPointerType())
Douglas Gregor3cdee122010-08-26 16:36:48 +00002826 /*Do nothing*/ ;
Douglas Gregor86d9a522009-09-21 16:56:56 +00002827 else
2828 return;
2829 }
2830
Douglas Gregoreb5758b2009-09-23 22:26:46 +00002831 ResultBuilder Results(*this, &ResultBuilder::IsMember);
Douglas Gregor95ac6552009-11-18 01:29:26 +00002832 Results.EnterNewScope();
2833 if (const RecordType *Record = BaseType->getAs<RecordType>()) {
Douglas Gregor3cdee122010-08-26 16:36:48 +00002834 // Indicate that we are performing a member access, and the cv-qualifiers
2835 // for the base object type.
2836 Results.setObjectTypeQualifiers(BaseType.getQualifiers());
2837
Douglas Gregor95ac6552009-11-18 01:29:26 +00002838 // Access to a C/C++ class, struct, or union.
Douglas Gregor45bcd432010-01-14 03:21:49 +00002839 Results.allowNestedNameSpecifiers();
Douglas Gregor0cc84042010-01-14 15:47:35 +00002840 CodeCompletionDeclConsumer Consumer(Results, CurContext);
Douglas Gregor8071e422010-08-15 06:18:01 +00002841 LookupVisibleDecls(Record->getDecl(), LookupMemberName, Consumer,
2842 CodeCompleter->includeGlobals());
Daniel Dunbar3a2838d2009-11-13 08:58:20 +00002843
Douglas Gregor95ac6552009-11-18 01:29:26 +00002844 if (getLangOptions().CPlusPlus) {
2845 if (!Results.empty()) {
2846 // The "template" keyword can follow "->" or "." in the grammar.
2847 // However, we only want to suggest the template keyword if something
2848 // is dependent.
2849 bool IsDependent = BaseType->isDependentType();
2850 if (!IsDependent) {
2851 for (Scope *DepScope = S; DepScope; DepScope = DepScope->getParent())
2852 if (DeclContext *Ctx = (DeclContext *)DepScope->getEntity()) {
2853 IsDependent = Ctx->isDependentContext();
2854 break;
2855 }
2856 }
Daniel Dunbar3a2838d2009-11-13 08:58:20 +00002857
Douglas Gregor95ac6552009-11-18 01:29:26 +00002858 if (IsDependent)
Douglas Gregora4477812010-01-14 16:01:26 +00002859 Results.AddResult(Result("template"));
Daniel Dunbar3a2838d2009-11-13 08:58:20 +00002860 }
Daniel Dunbar3a2838d2009-11-13 08:58:20 +00002861 }
Douglas Gregor95ac6552009-11-18 01:29:26 +00002862 } else if (!IsArrow && BaseType->getAsObjCInterfacePointerType()) {
2863 // Objective-C property reference.
2864
2865 // Add property results based on our interface.
2866 const ObjCObjectPointerType *ObjCPtr
2867 = BaseType->getAsObjCInterfacePointerType();
2868 assert(ObjCPtr && "Non-NULL pointer guaranteed above!");
Douglas Gregor322328b2009-11-18 22:32:06 +00002869 AddObjCProperties(ObjCPtr->getInterfaceDecl(), true, CurContext, Results);
Douglas Gregor95ac6552009-11-18 01:29:26 +00002870
2871 // Add properties from the protocols in a qualified interface.
2872 for (ObjCObjectPointerType::qual_iterator I = ObjCPtr->qual_begin(),
2873 E = ObjCPtr->qual_end();
2874 I != E; ++I)
Douglas Gregor322328b2009-11-18 22:32:06 +00002875 AddObjCProperties(*I, true, CurContext, Results);
Douglas Gregor95ac6552009-11-18 01:29:26 +00002876 } else if ((IsArrow && BaseType->isObjCObjectPointerType()) ||
John McCallc12c5bb2010-05-15 11:32:37 +00002877 (!IsArrow && BaseType->isObjCObjectType())) {
Douglas Gregor95ac6552009-11-18 01:29:26 +00002878 // Objective-C instance variable access.
2879 ObjCInterfaceDecl *Class = 0;
2880 if (const ObjCObjectPointerType *ObjCPtr
2881 = BaseType->getAs<ObjCObjectPointerType>())
2882 Class = ObjCPtr->getInterfaceDecl();
2883 else
John McCallc12c5bb2010-05-15 11:32:37 +00002884 Class = BaseType->getAs<ObjCObjectType>()->getInterface();
Douglas Gregor95ac6552009-11-18 01:29:26 +00002885
2886 // Add all ivars from this class and its superclasses.
Douglas Gregor80f4f4c2010-01-14 16:08:12 +00002887 if (Class) {
2888 CodeCompletionDeclConsumer Consumer(Results, CurContext);
2889 Results.setFilter(&ResultBuilder::IsObjCIvar);
Douglas Gregor8071e422010-08-15 06:18:01 +00002890 LookupVisibleDecls(Class, LookupMemberName, Consumer,
2891 CodeCompleter->includeGlobals());
Douglas Gregor95ac6552009-11-18 01:29:26 +00002892 }
Douglas Gregor86d9a522009-09-21 16:56:56 +00002893 }
Douglas Gregor95ac6552009-11-18 01:29:26 +00002894
2895 // FIXME: How do we cope with isa?
2896
2897 Results.ExitScope();
Daniel Dunbar3a2838d2009-11-13 08:58:20 +00002898
Daniel Dunbar3a2838d2009-11-13 08:58:20 +00002899 // Hand off the results found for code completion.
Douglas Gregore6b1bb62010-08-11 21:23:17 +00002900 HandleCodeCompleteResults(this, CodeCompleter,
2901 CodeCompletionContext(CodeCompletionContext::CCC_MemberAccess,
2902 BaseType),
2903 Results.data(),Results.size());
Douglas Gregor81b747b2009-09-17 21:32:03 +00002904}
2905
Douglas Gregor374929f2009-09-18 15:37:17 +00002906void Sema::CodeCompleteTag(Scope *S, unsigned TagSpec) {
2907 if (!CodeCompleter)
2908 return;
2909
John McCall0a2c5e22010-08-25 06:19:51 +00002910 typedef CodeCompletionResult Result;
Douglas Gregor86d9a522009-09-21 16:56:56 +00002911 ResultBuilder::LookupFilter Filter = 0;
Douglas Gregore6b1bb62010-08-11 21:23:17 +00002912 enum CodeCompletionContext::Kind ContextKind
2913 = CodeCompletionContext::CCC_Other;
Douglas Gregor374929f2009-09-18 15:37:17 +00002914 switch ((DeclSpec::TST)TagSpec) {
2915 case DeclSpec::TST_enum:
Douglas Gregor86d9a522009-09-21 16:56:56 +00002916 Filter = &ResultBuilder::IsEnum;
Douglas Gregore6b1bb62010-08-11 21:23:17 +00002917 ContextKind = CodeCompletionContext::CCC_EnumTag;
Douglas Gregor374929f2009-09-18 15:37:17 +00002918 break;
2919
2920 case DeclSpec::TST_union:
Douglas Gregor86d9a522009-09-21 16:56:56 +00002921 Filter = &ResultBuilder::IsUnion;
Douglas Gregore6b1bb62010-08-11 21:23:17 +00002922 ContextKind = CodeCompletionContext::CCC_UnionTag;
Douglas Gregor374929f2009-09-18 15:37:17 +00002923 break;
2924
2925 case DeclSpec::TST_struct:
Douglas Gregor374929f2009-09-18 15:37:17 +00002926 case DeclSpec::TST_class:
Douglas Gregor86d9a522009-09-21 16:56:56 +00002927 Filter = &ResultBuilder::IsClassOrStruct;
Douglas Gregore6b1bb62010-08-11 21:23:17 +00002928 ContextKind = CodeCompletionContext::CCC_ClassOrStructTag;
Douglas Gregor374929f2009-09-18 15:37:17 +00002929 break;
2930
2931 default:
2932 assert(false && "Unknown type specifier kind in CodeCompleteTag");
2933 return;
2934 }
Douglas Gregor86d9a522009-09-21 16:56:56 +00002935
John McCall0d6b1642010-04-23 18:46:30 +00002936 ResultBuilder Results(*this);
Douglas Gregor5d2fc402010-01-14 03:27:13 +00002937 CodeCompletionDeclConsumer Consumer(Results, CurContext);
John McCall0d6b1642010-04-23 18:46:30 +00002938
2939 // First pass: look for tags.
2940 Results.setFilter(Filter);
Douglas Gregor8071e422010-08-15 06:18:01 +00002941 LookupVisibleDecls(S, LookupTagName, Consumer,
2942 CodeCompleter->includeGlobals());
John McCall0d6b1642010-04-23 18:46:30 +00002943
Douglas Gregor8071e422010-08-15 06:18:01 +00002944 if (CodeCompleter->includeGlobals()) {
2945 // Second pass: look for nested name specifiers.
2946 Results.setFilter(&ResultBuilder::IsNestedNameSpecifier);
2947 LookupVisibleDecls(S, LookupNestedNameSpecifierName, Consumer);
2948 }
Douglas Gregor86d9a522009-09-21 16:56:56 +00002949
Douglas Gregore6b1bb62010-08-11 21:23:17 +00002950 HandleCodeCompleteResults(this, CodeCompleter, ContextKind,
2951 Results.data(),Results.size());
Douglas Gregor374929f2009-09-18 15:37:17 +00002952}
2953
Douglas Gregor1a480c42010-08-27 17:35:51 +00002954void Sema::CodeCompleteTypeQualifiers(DeclSpec &DS) {
2955 ResultBuilder Results(*this);
2956 Results.EnterNewScope();
2957 if (!(DS.getTypeQualifiers() & DeclSpec::TQ_const))
2958 Results.AddResult("const");
2959 if (!(DS.getTypeQualifiers() & DeclSpec::TQ_volatile))
2960 Results.AddResult("volatile");
2961 if (getLangOptions().C99 &&
2962 !(DS.getTypeQualifiers() & DeclSpec::TQ_restrict))
2963 Results.AddResult("restrict");
2964 Results.ExitScope();
2965 HandleCodeCompleteResults(this, CodeCompleter,
2966 CodeCompletionContext::CCC_TypeQualifiers,
2967 Results.data(), Results.size());
2968}
2969
Douglas Gregor3e1005f2009-09-21 18:10:23 +00002970void Sema::CodeCompleteCase(Scope *S) {
John McCall781472f2010-08-25 08:40:02 +00002971 if (getCurFunction()->SwitchStack.empty() || !CodeCompleter)
Douglas Gregor3e1005f2009-09-21 18:10:23 +00002972 return;
2973
John McCall781472f2010-08-25 08:40:02 +00002974 SwitchStmt *Switch = getCurFunction()->SwitchStack.back();
Douglas Gregorf9578432010-07-28 21:50:18 +00002975 if (!Switch->getCond()->getType()->isEnumeralType()) {
Douglas Gregorfb629412010-08-23 21:17:50 +00002976 CodeCompleteExpressionData Data(Switch->getCond()->getType());
2977 Data.IntegralConstantExpression = true;
2978 CodeCompleteExpression(S, Data);
Douglas Gregor3e1005f2009-09-21 18:10:23 +00002979 return;
Douglas Gregorf9578432010-07-28 21:50:18 +00002980 }
Douglas Gregor3e1005f2009-09-21 18:10:23 +00002981
2982 // Code-complete the cases of a switch statement over an enumeration type
2983 // by providing the list of
2984 EnumDecl *Enum = Switch->getCond()->getType()->getAs<EnumType>()->getDecl();
2985
2986 // Determine which enumerators we have already seen in the switch statement.
2987 // FIXME: Ideally, we would also be able to look *past* the code-completion
2988 // token, in case we are code-completing in the middle of the switch and not
2989 // at the end. However, we aren't able to do so at the moment.
2990 llvm::SmallPtrSet<EnumConstantDecl *, 8> EnumeratorsSeen;
Douglas Gregorb9d0ef72009-09-21 19:57:38 +00002991 NestedNameSpecifier *Qualifier = 0;
Douglas Gregor3e1005f2009-09-21 18:10:23 +00002992 for (SwitchCase *SC = Switch->getSwitchCaseList(); SC;
2993 SC = SC->getNextSwitchCase()) {
2994 CaseStmt *Case = dyn_cast<CaseStmt>(SC);
2995 if (!Case)
2996 continue;
2997
2998 Expr *CaseVal = Case->getLHS()->IgnoreParenCasts();
2999 if (DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(CaseVal))
3000 if (EnumConstantDecl *Enumerator
3001 = dyn_cast<EnumConstantDecl>(DRE->getDecl())) {
3002 // We look into the AST of the case statement to determine which
3003 // enumerator was named. Alternatively, we could compute the value of
3004 // the integral constant expression, then compare it against the
3005 // values of each enumerator. However, value-based approach would not
3006 // work as well with C++ templates where enumerators declared within a
3007 // template are type- and value-dependent.
3008 EnumeratorsSeen.insert(Enumerator);
3009
Douglas Gregorb9d0ef72009-09-21 19:57:38 +00003010 // If this is a qualified-id, keep track of the nested-name-specifier
3011 // so that we can reproduce it as part of code completion, e.g.,
Douglas Gregor3e1005f2009-09-21 18:10:23 +00003012 //
3013 // switch (TagD.getKind()) {
3014 // case TagDecl::TK_enum:
3015 // break;
3016 // case XXX
3017 //
Douglas Gregorb9d0ef72009-09-21 19:57:38 +00003018 // At the XXX, our completions are TagDecl::TK_union,
Douglas Gregor3e1005f2009-09-21 18:10:23 +00003019 // TagDecl::TK_struct, and TagDecl::TK_class, rather than TK_union,
3020 // TK_struct, and TK_class.
Douglas Gregora2813ce2009-10-23 18:54:35 +00003021 Qualifier = DRE->getQualifier();
Douglas Gregor3e1005f2009-09-21 18:10:23 +00003022 }
3023 }
3024
Douglas Gregorb9d0ef72009-09-21 19:57:38 +00003025 if (getLangOptions().CPlusPlus && !Qualifier && EnumeratorsSeen.empty()) {
3026 // If there are no prior enumerators in C++, check whether we have to
3027 // qualify the names of the enumerators that we suggest, because they
3028 // may not be visible in this scope.
3029 Qualifier = getRequiredQualification(Context, CurContext,
3030 Enum->getDeclContext());
3031
3032 // FIXME: Scoped enums need to start with "EnumDecl" as the context!
3033 }
3034
Douglas Gregor3e1005f2009-09-21 18:10:23 +00003035 // Add any enumerators that have not yet been mentioned.
3036 ResultBuilder Results(*this);
3037 Results.EnterNewScope();
3038 for (EnumDecl::enumerator_iterator E = Enum->enumerator_begin(),
3039 EEnd = Enum->enumerator_end();
3040 E != EEnd; ++E) {
3041 if (EnumeratorsSeen.count(*E))
3042 continue;
3043
John McCall0a2c5e22010-08-25 06:19:51 +00003044 Results.AddResult(CodeCompletionResult(*E, Qualifier),
Douglas Gregor608300b2010-01-14 16:14:35 +00003045 CurContext, 0, false);
Douglas Gregor3e1005f2009-09-21 18:10:23 +00003046 }
3047 Results.ExitScope();
Douglas Gregor2f880e42010-04-06 20:02:15 +00003048
Douglas Gregor0c8296d2009-11-07 00:00:49 +00003049 if (CodeCompleter->includeMacros())
Douglas Gregorbca403c2010-01-13 23:51:12 +00003050 AddMacroResults(PP, Results);
Douglas Gregore6b1bb62010-08-11 21:23:17 +00003051 HandleCodeCompleteResults(this, CodeCompleter,
3052 CodeCompletionContext::CCC_Expression,
3053 Results.data(),Results.size());
Douglas Gregor3e1005f2009-09-21 18:10:23 +00003054}
3055
Douglas Gregor9c6a0e92009-09-22 15:41:20 +00003056namespace {
3057 struct IsBetterOverloadCandidate {
3058 Sema &S;
John McCall5769d612010-02-08 23:07:23 +00003059 SourceLocation Loc;
Douglas Gregor9c6a0e92009-09-22 15:41:20 +00003060
3061 public:
John McCall5769d612010-02-08 23:07:23 +00003062 explicit IsBetterOverloadCandidate(Sema &S, SourceLocation Loc)
3063 : S(S), Loc(Loc) { }
Douglas Gregor9c6a0e92009-09-22 15:41:20 +00003064
3065 bool
3066 operator()(const OverloadCandidate &X, const OverloadCandidate &Y) const {
John McCall120d63c2010-08-24 20:38:10 +00003067 return isBetterOverloadCandidate(S, X, Y, Loc);
Douglas Gregor9c6a0e92009-09-22 15:41:20 +00003068 }
3069 };
3070}
3071
Douglas Gregord28dcd72010-05-30 06:10:08 +00003072static bool anyNullArguments(Expr **Args, unsigned NumArgs) {
3073 if (NumArgs && !Args)
3074 return true;
3075
3076 for (unsigned I = 0; I != NumArgs; ++I)
3077 if (!Args[I])
3078 return true;
3079
3080 return false;
3081}
3082
Douglas Gregor9c6a0e92009-09-22 15:41:20 +00003083void Sema::CodeCompleteCall(Scope *S, ExprTy *FnIn,
3084 ExprTy **ArgsIn, unsigned NumArgs) {
3085 if (!CodeCompleter)
3086 return;
Douglas Gregoref96eac2009-12-11 19:06:04 +00003087
3088 // When we're code-completing for a call, we fall back to ordinary
3089 // name code-completion whenever we can't produce specific
3090 // results. We may want to revisit this strategy in the future,
3091 // e.g., by merging the two kinds of results.
3092
Douglas Gregor9c6a0e92009-09-22 15:41:20 +00003093 Expr *Fn = (Expr *)FnIn;
3094 Expr **Args = (Expr **)ArgsIn;
Douglas Gregoref96eac2009-12-11 19:06:04 +00003095
Douglas Gregor9c6a0e92009-09-22 15:41:20 +00003096 // Ignore type-dependent call expressions entirely.
Douglas Gregord28dcd72010-05-30 06:10:08 +00003097 if (!Fn || Fn->isTypeDependent() || anyNullArguments(Args, NumArgs) ||
Douglas Gregoref96eac2009-12-11 19:06:04 +00003098 Expr::hasAnyTypeDependentArguments(Args, NumArgs)) {
Douglas Gregore6b1bb62010-08-11 21:23:17 +00003099 CodeCompleteOrdinaryName(S, PCC_Expression);
Douglas Gregor9c6a0e92009-09-22 15:41:20 +00003100 return;
Douglas Gregoref96eac2009-12-11 19:06:04 +00003101 }
Douglas Gregor9c6a0e92009-09-22 15:41:20 +00003102
John McCall3b4294e2009-12-16 12:17:52 +00003103 // Build an overload candidate set based on the functions we find.
John McCall5769d612010-02-08 23:07:23 +00003104 SourceLocation Loc = Fn->getExprLoc();
3105 OverloadCandidateSet CandidateSet(Loc);
John McCall3b4294e2009-12-16 12:17:52 +00003106
Douglas Gregor9c6a0e92009-09-22 15:41:20 +00003107 // FIXME: What if we're calling something that isn't a function declaration?
3108 // FIXME: What if we're calling a pseudo-destructor?
3109 // FIXME: What if we're calling a member function?
3110
Douglas Gregorc0265402010-01-21 15:46:19 +00003111 typedef CodeCompleteConsumer::OverloadCandidate ResultCandidate;
3112 llvm::SmallVector<ResultCandidate, 8> Results;
3113
John McCall3b4294e2009-12-16 12:17:52 +00003114 Expr *NakedFn = Fn->IgnoreParenCasts();
3115 if (UnresolvedLookupExpr *ULE = dyn_cast<UnresolvedLookupExpr>(NakedFn))
3116 AddOverloadedCallCandidates(ULE, Args, NumArgs, CandidateSet,
3117 /*PartialOverloading=*/ true);
3118 else if (DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(NakedFn)) {
3119 FunctionDecl *FDecl = dyn_cast<FunctionDecl>(DRE->getDecl());
Douglas Gregorc0265402010-01-21 15:46:19 +00003120 if (FDecl) {
Douglas Gregord28dcd72010-05-30 06:10:08 +00003121 if (!getLangOptions().CPlusPlus ||
3122 !FDecl->getType()->getAs<FunctionProtoType>())
Douglas Gregorc0265402010-01-21 15:46:19 +00003123 Results.push_back(ResultCandidate(FDecl));
3124 else
John McCall86820f52010-01-26 01:37:31 +00003125 // FIXME: access?
John McCall9aa472c2010-03-19 07:35:19 +00003126 AddOverloadCandidate(FDecl, DeclAccessPair::make(FDecl, AS_none),
3127 Args, NumArgs, CandidateSet,
Douglas Gregorc27d6c52010-04-16 17:41:49 +00003128 false, /*PartialOverloading*/true);
Douglas Gregorc0265402010-01-21 15:46:19 +00003129 }
John McCall3b4294e2009-12-16 12:17:52 +00003130 }
Douglas Gregor9c6a0e92009-09-22 15:41:20 +00003131
Douglas Gregor5ac3bdb2010-05-30 01:49:25 +00003132 QualType ParamType;
3133
Douglas Gregorc0265402010-01-21 15:46:19 +00003134 if (!CandidateSet.empty()) {
3135 // Sort the overload candidate set by placing the best overloads first.
3136 std::stable_sort(CandidateSet.begin(), CandidateSet.end(),
John McCall5769d612010-02-08 23:07:23 +00003137 IsBetterOverloadCandidate(*this, Loc));
Douglas Gregor9c6a0e92009-09-22 15:41:20 +00003138
Douglas Gregorc0265402010-01-21 15:46:19 +00003139 // Add the remaining viable overload candidates as code-completion reslults.
3140 for (OverloadCandidateSet::iterator Cand = CandidateSet.begin(),
3141 CandEnd = CandidateSet.end();
3142 Cand != CandEnd; ++Cand) {
3143 if (Cand->Viable)
3144 Results.push_back(ResultCandidate(Cand->Function));
3145 }
Douglas Gregor5ac3bdb2010-05-30 01:49:25 +00003146
3147 // From the viable candidates, try to determine the type of this parameter.
3148 for (unsigned I = 0, N = Results.size(); I != N; ++I) {
3149 if (const FunctionType *FType = Results[I].getFunctionType())
3150 if (const FunctionProtoType *Proto = dyn_cast<FunctionProtoType>(FType))
3151 if (NumArgs < Proto->getNumArgs()) {
3152 if (ParamType.isNull())
3153 ParamType = Proto->getArgType(NumArgs);
3154 else if (!Context.hasSameUnqualifiedType(
3155 ParamType.getNonReferenceType(),
3156 Proto->getArgType(NumArgs).getNonReferenceType())) {
3157 ParamType = QualType();
3158 break;
3159 }
3160 }
3161 }
3162 } else {
3163 // Try to determine the parameter type from the type of the expression
3164 // being called.
3165 QualType FunctionType = Fn->getType();
3166 if (const PointerType *Ptr = FunctionType->getAs<PointerType>())
3167 FunctionType = Ptr->getPointeeType();
3168 else if (const BlockPointerType *BlockPtr
3169 = FunctionType->getAs<BlockPointerType>())
3170 FunctionType = BlockPtr->getPointeeType();
3171 else if (const MemberPointerType *MemPtr
3172 = FunctionType->getAs<MemberPointerType>())
3173 FunctionType = MemPtr->getPointeeType();
3174
3175 if (const FunctionProtoType *Proto
3176 = FunctionType->getAs<FunctionProtoType>()) {
3177 if (NumArgs < Proto->getNumArgs())
3178 ParamType = Proto->getArgType(NumArgs);
3179 }
Douglas Gregor9c6a0e92009-09-22 15:41:20 +00003180 }
Douglas Gregoref96eac2009-12-11 19:06:04 +00003181
Douglas Gregor5ac3bdb2010-05-30 01:49:25 +00003182 if (ParamType.isNull())
Douglas Gregore6b1bb62010-08-11 21:23:17 +00003183 CodeCompleteOrdinaryName(S, PCC_Expression);
Douglas Gregor5ac3bdb2010-05-30 01:49:25 +00003184 else
3185 CodeCompleteExpression(S, ParamType);
3186
Douglas Gregor2e4c7a52010-04-06 20:19:47 +00003187 if (!Results.empty())
Douglas Gregoref96eac2009-12-11 19:06:04 +00003188 CodeCompleter->ProcessOverloadCandidates(*this, NumArgs, Results.data(),
3189 Results.size());
Douglas Gregor9c6a0e92009-09-22 15:41:20 +00003190}
3191
John McCalld226f652010-08-21 09:40:31 +00003192void Sema::CodeCompleteInitializer(Scope *S, Decl *D) {
3193 ValueDecl *VD = dyn_cast_or_null<ValueDecl>(D);
Douglas Gregor5ac3bdb2010-05-30 01:49:25 +00003194 if (!VD) {
Douglas Gregore6b1bb62010-08-11 21:23:17 +00003195 CodeCompleteOrdinaryName(S, PCC_Expression);
Douglas Gregor5ac3bdb2010-05-30 01:49:25 +00003196 return;
3197 }
3198
3199 CodeCompleteExpression(S, VD->getType());
3200}
3201
3202void Sema::CodeCompleteReturn(Scope *S) {
3203 QualType ResultType;
3204 if (isa<BlockDecl>(CurContext)) {
3205 if (BlockScopeInfo *BSI = getCurBlock())
3206 ResultType = BSI->ReturnType;
3207 } else if (FunctionDecl *Function = dyn_cast<FunctionDecl>(CurContext))
3208 ResultType = Function->getResultType();
3209 else if (ObjCMethodDecl *Method = dyn_cast<ObjCMethodDecl>(CurContext))
3210 ResultType = Method->getResultType();
3211
3212 if (ResultType.isNull())
Douglas Gregore6b1bb62010-08-11 21:23:17 +00003213 CodeCompleteOrdinaryName(S, PCC_Expression);
Douglas Gregor5ac3bdb2010-05-30 01:49:25 +00003214 else
3215 CodeCompleteExpression(S, ResultType);
3216}
3217
3218void Sema::CodeCompleteAssignmentRHS(Scope *S, ExprTy *LHS) {
3219 if (LHS)
3220 CodeCompleteExpression(S, static_cast<Expr *>(LHS)->getType());
3221 else
Douglas Gregore6b1bb62010-08-11 21:23:17 +00003222 CodeCompleteOrdinaryName(S, PCC_Expression);
Douglas Gregor5ac3bdb2010-05-30 01:49:25 +00003223}
3224
Jeffrey Yasskin9ab14542010-04-08 16:38:48 +00003225void Sema::CodeCompleteQualifiedId(Scope *S, CXXScopeSpec &SS,
Douglas Gregor81b747b2009-09-17 21:32:03 +00003226 bool EnteringContext) {
3227 if (!SS.getScopeRep() || !CodeCompleter)
3228 return;
3229
Douglas Gregor86d9a522009-09-21 16:56:56 +00003230 DeclContext *Ctx = computeDeclContext(SS, EnteringContext);
3231 if (!Ctx)
3232 return;
Douglas Gregord1cd31a2009-12-11 18:28:39 +00003233
3234 // Try to instantiate any non-dependent declaration contexts before
3235 // we look in them.
John McCall77bb1aa2010-05-01 00:40:08 +00003236 if (!isDependentScopeSpecifier(SS) && RequireCompleteDeclContext(SS, Ctx))
Douglas Gregord1cd31a2009-12-11 18:28:39 +00003237 return;
3238
Douglas Gregor86d9a522009-09-21 16:56:56 +00003239 ResultBuilder Results(*this);
Douglas Gregor86d9a522009-09-21 16:56:56 +00003240
Douglas Gregorf6961522010-08-27 21:18:54 +00003241 Results.EnterNewScope();
Douglas Gregor86d9a522009-09-21 16:56:56 +00003242 // The "template" keyword can follow "::" in the grammar, but only
3243 // put it into the grammar if the nested-name-specifier is dependent.
3244 NestedNameSpecifier *NNS = (NestedNameSpecifier *)SS.getScopeRep();
3245 if (!Results.empty() && NNS->isDependent())
Douglas Gregora4477812010-01-14 16:01:26 +00003246 Results.AddResult("template");
Douglas Gregorf6961522010-08-27 21:18:54 +00003247
3248 // Add calls to overridden virtual functions, if there are any.
3249 //
3250 // FIXME: This isn't wonderful, because we don't know whether we're actually
3251 // in a context that permits expressions. This is a general issue with
3252 // qualified-id completions.
3253 if (!EnteringContext)
3254 MaybeAddOverrideCalls(*this, Ctx, Results);
3255 Results.ExitScope();
Douglas Gregor86d9a522009-09-21 16:56:56 +00003256
Douglas Gregorf6961522010-08-27 21:18:54 +00003257 CodeCompletionDeclConsumer Consumer(Results, CurContext);
3258 LookupVisibleDecls(Ctx, LookupOrdinaryName, Consumer);
3259
Douglas Gregore6b1bb62010-08-11 21:23:17 +00003260 HandleCodeCompleteResults(this, CodeCompleter,
Douglas Gregorf6961522010-08-27 21:18:54 +00003261 CodeCompletionContext::CCC_Name,
Douglas Gregore6b1bb62010-08-11 21:23:17 +00003262 Results.data(),Results.size());
Douglas Gregor81b747b2009-09-17 21:32:03 +00003263}
Douglas Gregor49f40bd2009-09-18 19:03:04 +00003264
3265void Sema::CodeCompleteUsing(Scope *S) {
3266 if (!CodeCompleter)
3267 return;
3268
Douglas Gregor86d9a522009-09-21 16:56:56 +00003269 ResultBuilder Results(*this, &ResultBuilder::IsNestedNameSpecifier);
Douglas Gregor8e0a0e42009-09-22 23:31:26 +00003270 Results.EnterNewScope();
Douglas Gregor86d9a522009-09-21 16:56:56 +00003271
3272 // If we aren't in class scope, we could see the "namespace" keyword.
3273 if (!S->isClassScope())
John McCall0a2c5e22010-08-25 06:19:51 +00003274 Results.AddResult(CodeCompletionResult("namespace"));
Douglas Gregor86d9a522009-09-21 16:56:56 +00003275
3276 // After "using", we can see anything that would start a
3277 // nested-name-specifier.
Douglas Gregor5d2fc402010-01-14 03:27:13 +00003278 CodeCompletionDeclConsumer Consumer(Results, CurContext);
Douglas Gregor8071e422010-08-15 06:18:01 +00003279 LookupVisibleDecls(S, LookupOrdinaryName, Consumer,
3280 CodeCompleter->includeGlobals());
Douglas Gregor8e0a0e42009-09-22 23:31:26 +00003281 Results.ExitScope();
Douglas Gregor86d9a522009-09-21 16:56:56 +00003282
Douglas Gregore6b1bb62010-08-11 21:23:17 +00003283 HandleCodeCompleteResults(this, CodeCompleter,
3284 CodeCompletionContext::CCC_Other,
3285 Results.data(),Results.size());
Douglas Gregor49f40bd2009-09-18 19:03:04 +00003286}
3287
3288void Sema::CodeCompleteUsingDirective(Scope *S) {
3289 if (!CodeCompleter)
3290 return;
3291
Douglas Gregor86d9a522009-09-21 16:56:56 +00003292 // After "using namespace", we expect to see a namespace name or namespace
3293 // alias.
3294 ResultBuilder Results(*this, &ResultBuilder::IsNamespaceOrAlias);
Douglas Gregor8e0a0e42009-09-22 23:31:26 +00003295 Results.EnterNewScope();
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 Gregore6b1bb62010-08-11 21:23:17 +00003300 HandleCodeCompleteResults(this, CodeCompleter,
Douglas Gregor8071e422010-08-15 06:18:01 +00003301 CodeCompletionContext::CCC_Namespace,
Douglas Gregore6b1bb62010-08-11 21:23:17 +00003302 Results.data(),Results.size());
Douglas Gregor49f40bd2009-09-18 19:03:04 +00003303}
3304
3305void Sema::CodeCompleteNamespaceDecl(Scope *S) {
3306 if (!CodeCompleter)
3307 return;
3308
Douglas Gregor86d9a522009-09-21 16:56:56 +00003309 ResultBuilder Results(*this, &ResultBuilder::IsNamespace);
3310 DeclContext *Ctx = (DeclContext *)S->getEntity();
3311 if (!S->getParent())
3312 Ctx = Context.getTranslationUnitDecl();
3313
3314 if (Ctx && Ctx->isFileContext()) {
3315 // We only want to see those namespaces that have already been defined
3316 // within this scope, because its likely that the user is creating an
3317 // extended namespace declaration. Keep track of the most recent
3318 // definition of each namespace.
3319 std::map<NamespaceDecl *, NamespaceDecl *> OrigToLatest;
3320 for (DeclContext::specific_decl_iterator<NamespaceDecl>
3321 NS(Ctx->decls_begin()), NSEnd(Ctx->decls_end());
3322 NS != NSEnd; ++NS)
3323 OrigToLatest[NS->getOriginalNamespace()] = *NS;
3324
3325 // Add the most recent definition (or extended definition) of each
3326 // namespace to the list of results.
Douglas Gregor8e0a0e42009-09-22 23:31:26 +00003327 Results.EnterNewScope();
Douglas Gregor86d9a522009-09-21 16:56:56 +00003328 for (std::map<NamespaceDecl *, NamespaceDecl *>::iterator
3329 NS = OrigToLatest.begin(), NSEnd = OrigToLatest.end();
3330 NS != NSEnd; ++NS)
John McCall0a2c5e22010-08-25 06:19:51 +00003331 Results.AddResult(CodeCompletionResult(NS->second, 0),
Douglas Gregor608300b2010-01-14 16:14:35 +00003332 CurContext, 0, false);
Douglas Gregor8e0a0e42009-09-22 23:31:26 +00003333 Results.ExitScope();
Douglas Gregor86d9a522009-09-21 16:56:56 +00003334 }
3335
Douglas Gregore6b1bb62010-08-11 21:23:17 +00003336 HandleCodeCompleteResults(this, CodeCompleter,
3337 CodeCompletionContext::CCC_Other,
3338 Results.data(),Results.size());
Douglas Gregor49f40bd2009-09-18 19:03:04 +00003339}
3340
3341void Sema::CodeCompleteNamespaceAliasDecl(Scope *S) {
3342 if (!CodeCompleter)
3343 return;
3344
Douglas Gregor86d9a522009-09-21 16:56:56 +00003345 // After "namespace", we expect to see a namespace or alias.
3346 ResultBuilder Results(*this, &ResultBuilder::IsNamespaceOrAlias);
Douglas Gregor5d2fc402010-01-14 03:27:13 +00003347 CodeCompletionDeclConsumer Consumer(Results, CurContext);
Douglas Gregor8071e422010-08-15 06:18:01 +00003348 LookupVisibleDecls(S, LookupOrdinaryName, Consumer,
3349 CodeCompleter->includeGlobals());
Douglas Gregore6b1bb62010-08-11 21:23:17 +00003350 HandleCodeCompleteResults(this, CodeCompleter,
Douglas Gregor8071e422010-08-15 06:18:01 +00003351 CodeCompletionContext::CCC_Namespace,
Douglas Gregore6b1bb62010-08-11 21:23:17 +00003352 Results.data(),Results.size());
Douglas Gregor49f40bd2009-09-18 19:03:04 +00003353}
3354
Douglas Gregored8d3222009-09-18 20:05:18 +00003355void Sema::CodeCompleteOperatorName(Scope *S) {
3356 if (!CodeCompleter)
3357 return;
Douglas Gregor86d9a522009-09-21 16:56:56 +00003358
John McCall0a2c5e22010-08-25 06:19:51 +00003359 typedef CodeCompletionResult Result;
Douglas Gregor86d9a522009-09-21 16:56:56 +00003360 ResultBuilder Results(*this, &ResultBuilder::IsType);
Douglas Gregor8e0a0e42009-09-22 23:31:26 +00003361 Results.EnterNewScope();
Douglas Gregored8d3222009-09-18 20:05:18 +00003362
Douglas Gregor86d9a522009-09-21 16:56:56 +00003363 // Add the names of overloadable operators.
3364#define OVERLOADED_OPERATOR(Name,Spelling,Token,Unary,Binary,MemberOnly) \
3365 if (std::strcmp(Spelling, "?")) \
Douglas Gregora4477812010-01-14 16:01:26 +00003366 Results.AddResult(Result(Spelling));
Douglas Gregor86d9a522009-09-21 16:56:56 +00003367#include "clang/Basic/OperatorKinds.def"
3368
3369 // Add any type names visible from the current scope
Douglas Gregor45bcd432010-01-14 03:21:49 +00003370 Results.allowNestedNameSpecifiers();
Douglas Gregor5d2fc402010-01-14 03:27:13 +00003371 CodeCompletionDeclConsumer Consumer(Results, CurContext);
Douglas Gregor8071e422010-08-15 06:18:01 +00003372 LookupVisibleDecls(S, LookupOrdinaryName, Consumer,
3373 CodeCompleter->includeGlobals());
Douglas Gregor86d9a522009-09-21 16:56:56 +00003374
3375 // Add any type specifiers
Douglas Gregorbca403c2010-01-13 23:51:12 +00003376 AddTypeSpecifierResults(getLangOptions(), Results);
Douglas Gregor8e0a0e42009-09-22 23:31:26 +00003377 Results.ExitScope();
Douglas Gregor86d9a522009-09-21 16:56:56 +00003378
Douglas Gregore6b1bb62010-08-11 21:23:17 +00003379 HandleCodeCompleteResults(this, CodeCompleter,
Douglas Gregor8071e422010-08-15 06:18:01 +00003380 CodeCompletionContext::CCC_Type,
Douglas Gregore6b1bb62010-08-11 21:23:17 +00003381 Results.data(),Results.size());
Douglas Gregored8d3222009-09-18 20:05:18 +00003382}
Douglas Gregor49f40bd2009-09-18 19:03:04 +00003383
Douglas Gregor0133f522010-08-28 00:00:50 +00003384void Sema::CodeCompleteConstructorInitializer(Decl *ConstructorD,
3385 CXXBaseOrMemberInitializer** Initializers,
3386 unsigned NumInitializers) {
3387 CXXConstructorDecl *Constructor
3388 = static_cast<CXXConstructorDecl *>(ConstructorD);
3389 if (!Constructor)
3390 return;
3391
3392 ResultBuilder Results(*this);
3393 Results.EnterNewScope();
3394
3395 // Fill in any already-initialized fields or base classes.
3396 llvm::SmallPtrSet<FieldDecl *, 4> InitializedFields;
3397 llvm::SmallPtrSet<CanQualType, 4> InitializedBases;
3398 for (unsigned I = 0; I != NumInitializers; ++I) {
3399 if (Initializers[I]->isBaseInitializer())
3400 InitializedBases.insert(
3401 Context.getCanonicalType(QualType(Initializers[I]->getBaseClass(), 0)));
3402 else
3403 InitializedFields.insert(cast<FieldDecl>(Initializers[I]->getMember()));
3404 }
3405
3406 // Add completions for base classes.
Douglas Gregor0c431c82010-08-29 19:27:27 +00003407 bool SawLastInitializer = (NumInitializers == 0);
Douglas Gregor0133f522010-08-28 00:00:50 +00003408 CXXRecordDecl *ClassDecl = Constructor->getParent();
3409 for (CXXRecordDecl::base_class_iterator Base = ClassDecl->bases_begin(),
3410 BaseEnd = ClassDecl->bases_end();
3411 Base != BaseEnd; ++Base) {
Douglas Gregor0c431c82010-08-29 19:27:27 +00003412 if (!InitializedBases.insert(Context.getCanonicalType(Base->getType()))) {
3413 SawLastInitializer
3414 = NumInitializers > 0 &&
3415 Initializers[NumInitializers - 1]->isBaseInitializer() &&
3416 Context.hasSameUnqualifiedType(Base->getType(),
3417 QualType(Initializers[NumInitializers - 1]->getBaseClass(), 0));
Douglas Gregor0133f522010-08-28 00:00:50 +00003418 continue;
Douglas Gregor0c431c82010-08-29 19:27:27 +00003419 }
Douglas Gregor0133f522010-08-28 00:00:50 +00003420
3421 CodeCompletionString *Pattern = new CodeCompletionString;
3422 Pattern->AddTypedTextChunk(
3423 Base->getType().getAsString(Context.PrintingPolicy));
3424 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
3425 Pattern->AddPlaceholderChunk("args");
3426 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
Douglas Gregor0c431c82010-08-29 19:27:27 +00003427 Results.AddResult(CodeCompletionResult(Pattern,
3428 SawLastInitializer? CCP_NextInitializer
3429 : CCP_MemberDeclaration));
3430 SawLastInitializer = false;
Douglas Gregor0133f522010-08-28 00:00:50 +00003431 }
3432
3433 // Add completions for virtual base classes.
3434 for (CXXRecordDecl::base_class_iterator Base = ClassDecl->vbases_begin(),
3435 BaseEnd = ClassDecl->vbases_end();
3436 Base != BaseEnd; ++Base) {
Douglas Gregor0c431c82010-08-29 19:27:27 +00003437 if (!InitializedBases.insert(Context.getCanonicalType(Base->getType()))) {
3438 SawLastInitializer
3439 = NumInitializers > 0 &&
3440 Initializers[NumInitializers - 1]->isBaseInitializer() &&
3441 Context.hasSameUnqualifiedType(Base->getType(),
3442 QualType(Initializers[NumInitializers - 1]->getBaseClass(), 0));
Douglas Gregor0133f522010-08-28 00:00:50 +00003443 continue;
Douglas Gregor0c431c82010-08-29 19:27:27 +00003444 }
Douglas Gregor0133f522010-08-28 00:00:50 +00003445
3446 CodeCompletionString *Pattern = new CodeCompletionString;
3447 Pattern->AddTypedTextChunk(
3448 Base->getType().getAsString(Context.PrintingPolicy));
3449 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
3450 Pattern->AddPlaceholderChunk("args");
3451 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
Douglas Gregor0c431c82010-08-29 19:27:27 +00003452 Results.AddResult(CodeCompletionResult(Pattern,
3453 SawLastInitializer? CCP_NextInitializer
3454 : CCP_MemberDeclaration));
3455 SawLastInitializer = false;
Douglas Gregor0133f522010-08-28 00:00:50 +00003456 }
3457
3458 // Add completions for members.
3459 for (CXXRecordDecl::field_iterator Field = ClassDecl->field_begin(),
3460 FieldEnd = ClassDecl->field_end();
3461 Field != FieldEnd; ++Field) {
Douglas Gregor0c431c82010-08-29 19:27:27 +00003462 if (!InitializedFields.insert(cast<FieldDecl>(Field->getCanonicalDecl()))) {
3463 SawLastInitializer
3464 = NumInitializers > 0 &&
3465 Initializers[NumInitializers - 1]->isMemberInitializer() &&
3466 Initializers[NumInitializers - 1]->getMember() == *Field;
Douglas Gregor0133f522010-08-28 00:00:50 +00003467 continue;
Douglas Gregor0c431c82010-08-29 19:27:27 +00003468 }
Douglas Gregor0133f522010-08-28 00:00:50 +00003469
3470 if (!Field->getDeclName())
3471 continue;
3472
3473 CodeCompletionString *Pattern = new CodeCompletionString;
3474 Pattern->AddTypedTextChunk(Field->getIdentifier()->getName());
3475 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
3476 Pattern->AddPlaceholderChunk("args");
3477 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
Douglas Gregor0c431c82010-08-29 19:27:27 +00003478 Results.AddResult(CodeCompletionResult(Pattern,
3479 SawLastInitializer? CCP_NextInitializer
Douglas Gregora67e03f2010-09-09 21:42:20 +00003480 : CCP_MemberDeclaration,
3481 CXCursor_MemberRef));
Douglas Gregor0c431c82010-08-29 19:27:27 +00003482 SawLastInitializer = false;
Douglas Gregor0133f522010-08-28 00:00:50 +00003483 }
3484 Results.ExitScope();
3485
3486 HandleCodeCompleteResults(this, CodeCompleter,
3487 CodeCompletionContext::CCC_Name,
3488 Results.data(), Results.size());
3489}
3490
Douglas Gregorb6ac2452010-01-13 21:24:21 +00003491// Macro that expands to @Keyword or Keyword, depending on whether NeedAt is
3492// true or false.
3493#define OBJC_AT_KEYWORD_NAME(NeedAt,Keyword) NeedAt? "@" #Keyword : #Keyword
Douglas Gregorbca403c2010-01-13 23:51:12 +00003494static void AddObjCImplementationResults(const LangOptions &LangOpts,
Douglas Gregorb6ac2452010-01-13 21:24:21 +00003495 ResultBuilder &Results,
3496 bool NeedAt) {
John McCall0a2c5e22010-08-25 06:19:51 +00003497 typedef CodeCompletionResult Result;
Douglas Gregorb6ac2452010-01-13 21:24:21 +00003498 // Since we have an implementation, we can end it.
Douglas Gregora4477812010-01-14 16:01:26 +00003499 Results.AddResult(Result(OBJC_AT_KEYWORD_NAME(NeedAt,end)));
Douglas Gregorb6ac2452010-01-13 21:24:21 +00003500
3501 CodeCompletionString *Pattern = 0;
3502 if (LangOpts.ObjC2) {
3503 // @dynamic
3504 Pattern = new CodeCompletionString;
3505 Pattern->AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt,dynamic));
3506 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
3507 Pattern->AddPlaceholderChunk("property");
Douglas Gregora4477812010-01-14 16:01:26 +00003508 Results.AddResult(Result(Pattern));
Douglas Gregorb6ac2452010-01-13 21:24:21 +00003509
3510 // @synthesize
3511 Pattern = new CodeCompletionString;
3512 Pattern->AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt,synthesize));
3513 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
3514 Pattern->AddPlaceholderChunk("property");
Douglas Gregora4477812010-01-14 16:01:26 +00003515 Results.AddResult(Result(Pattern));
Douglas Gregorb6ac2452010-01-13 21:24:21 +00003516 }
3517}
3518
Douglas Gregorbca403c2010-01-13 23:51:12 +00003519static void AddObjCInterfaceResults(const LangOptions &LangOpts,
Douglas Gregorb6ac2452010-01-13 21:24:21 +00003520 ResultBuilder &Results,
3521 bool NeedAt) {
John McCall0a2c5e22010-08-25 06:19:51 +00003522 typedef CodeCompletionResult Result;
Douglas Gregorb6ac2452010-01-13 21:24:21 +00003523
3524 // Since we have an interface or protocol, we can end it.
Douglas Gregora4477812010-01-14 16:01:26 +00003525 Results.AddResult(Result(OBJC_AT_KEYWORD_NAME(NeedAt,end)));
Douglas Gregorb6ac2452010-01-13 21:24:21 +00003526
3527 if (LangOpts.ObjC2) {
3528 // @property
Douglas Gregora4477812010-01-14 16:01:26 +00003529 Results.AddResult(Result(OBJC_AT_KEYWORD_NAME(NeedAt,property)));
Douglas Gregorb6ac2452010-01-13 21:24:21 +00003530
3531 // @required
Douglas Gregora4477812010-01-14 16:01:26 +00003532 Results.AddResult(Result(OBJC_AT_KEYWORD_NAME(NeedAt,required)));
Douglas Gregorb6ac2452010-01-13 21:24:21 +00003533
3534 // @optional
Douglas Gregora4477812010-01-14 16:01:26 +00003535 Results.AddResult(Result(OBJC_AT_KEYWORD_NAME(NeedAt,optional)));
Douglas Gregorb6ac2452010-01-13 21:24:21 +00003536 }
3537}
3538
Douglas Gregorbca403c2010-01-13 23:51:12 +00003539static void AddObjCTopLevelResults(ResultBuilder &Results, bool NeedAt) {
John McCall0a2c5e22010-08-25 06:19:51 +00003540 typedef CodeCompletionResult Result;
Douglas Gregorb6ac2452010-01-13 21:24:21 +00003541 CodeCompletionString *Pattern = 0;
3542
3543 // @class name ;
3544 Pattern = new CodeCompletionString;
3545 Pattern->AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt,class));
3546 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
Douglas Gregorc8bddde2010-05-28 00:22:41 +00003547 Pattern->AddPlaceholderChunk("name");
Douglas Gregora4477812010-01-14 16:01:26 +00003548 Results.AddResult(Result(Pattern));
Douglas Gregorb6ac2452010-01-13 21:24:21 +00003549
Douglas Gregorc8bddde2010-05-28 00:22:41 +00003550 if (Results.includeCodePatterns()) {
3551 // @interface name
3552 // FIXME: Could introduce the whole pattern, including superclasses and
3553 // such.
3554 Pattern = new CodeCompletionString;
3555 Pattern->AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt,interface));
3556 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
3557 Pattern->AddPlaceholderChunk("class");
3558 Results.AddResult(Result(Pattern));
Douglas Gregorb6ac2452010-01-13 21:24:21 +00003559
Douglas Gregorc8bddde2010-05-28 00:22:41 +00003560 // @protocol name
3561 Pattern = new CodeCompletionString;
3562 Pattern->AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt,protocol));
3563 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
3564 Pattern->AddPlaceholderChunk("protocol");
3565 Results.AddResult(Result(Pattern));
3566
3567 // @implementation name
3568 Pattern = new CodeCompletionString;
3569 Pattern->AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt,implementation));
3570 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
3571 Pattern->AddPlaceholderChunk("class");
3572 Results.AddResult(Result(Pattern));
3573 }
Douglas Gregorb6ac2452010-01-13 21:24:21 +00003574
3575 // @compatibility_alias name
3576 Pattern = new CodeCompletionString;
3577 Pattern->AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt,compatibility_alias));
3578 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
3579 Pattern->AddPlaceholderChunk("alias");
3580 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
3581 Pattern->AddPlaceholderChunk("class");
Douglas Gregora4477812010-01-14 16:01:26 +00003582 Results.AddResult(Result(Pattern));
Douglas Gregorb6ac2452010-01-13 21:24:21 +00003583}
3584
John McCalld226f652010-08-21 09:40:31 +00003585void Sema::CodeCompleteObjCAtDirective(Scope *S, Decl *ObjCImpDecl,
Douglas Gregorc464ae82009-12-07 09:27:33 +00003586 bool InInterface) {
John McCall0a2c5e22010-08-25 06:19:51 +00003587 typedef CodeCompletionResult Result;
Douglas Gregorc464ae82009-12-07 09:27:33 +00003588 ResultBuilder Results(*this);
3589 Results.EnterNewScope();
Douglas Gregorb6ac2452010-01-13 21:24:21 +00003590 if (ObjCImpDecl)
Douglas Gregorbca403c2010-01-13 23:51:12 +00003591 AddObjCImplementationResults(getLangOptions(), Results, false);
Douglas Gregorb6ac2452010-01-13 21:24:21 +00003592 else if (InInterface)
Douglas Gregorbca403c2010-01-13 23:51:12 +00003593 AddObjCInterfaceResults(getLangOptions(), Results, false);
Douglas Gregorb6ac2452010-01-13 21:24:21 +00003594 else
Douglas Gregorbca403c2010-01-13 23:51:12 +00003595 AddObjCTopLevelResults(Results, false);
Douglas Gregorc464ae82009-12-07 09:27:33 +00003596 Results.ExitScope();
Douglas Gregore6b1bb62010-08-11 21:23:17 +00003597 HandleCodeCompleteResults(this, CodeCompleter,
3598 CodeCompletionContext::CCC_Other,
3599 Results.data(),Results.size());
Douglas Gregorc464ae82009-12-07 09:27:33 +00003600}
3601
Douglas Gregorbca403c2010-01-13 23:51:12 +00003602static void AddObjCExpressionResults(ResultBuilder &Results, bool NeedAt) {
John McCall0a2c5e22010-08-25 06:19:51 +00003603 typedef CodeCompletionResult Result;
Douglas Gregor9a0c85e2009-12-07 09:51:25 +00003604 CodeCompletionString *Pattern = 0;
3605
3606 // @encode ( type-name )
3607 Pattern = new CodeCompletionString;
Douglas Gregorb6ac2452010-01-13 21:24:21 +00003608 Pattern->AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt,encode));
Douglas Gregor9a0c85e2009-12-07 09:51:25 +00003609 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
3610 Pattern->AddPlaceholderChunk("type-name");
3611 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
Douglas Gregora4477812010-01-14 16:01:26 +00003612 Results.AddResult(Result(Pattern));
Douglas Gregor9a0c85e2009-12-07 09:51:25 +00003613
3614 // @protocol ( protocol-name )
3615 Pattern = new CodeCompletionString;
Douglas Gregorb6ac2452010-01-13 21:24:21 +00003616 Pattern->AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt,protocol));
Douglas Gregor9a0c85e2009-12-07 09:51:25 +00003617 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
3618 Pattern->AddPlaceholderChunk("protocol-name");
3619 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
Douglas Gregora4477812010-01-14 16:01:26 +00003620 Results.AddResult(Result(Pattern));
Douglas Gregor9a0c85e2009-12-07 09:51:25 +00003621
3622 // @selector ( selector )
3623 Pattern = new CodeCompletionString;
Douglas Gregorb6ac2452010-01-13 21:24:21 +00003624 Pattern->AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt,selector));
Douglas Gregor9a0c85e2009-12-07 09:51:25 +00003625 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
3626 Pattern->AddPlaceholderChunk("selector");
3627 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
Douglas Gregora4477812010-01-14 16:01:26 +00003628 Results.AddResult(Result(Pattern));
Douglas Gregor9a0c85e2009-12-07 09:51:25 +00003629}
3630
Douglas Gregorbca403c2010-01-13 23:51:12 +00003631static void AddObjCStatementResults(ResultBuilder &Results, bool NeedAt) {
John McCall0a2c5e22010-08-25 06:19:51 +00003632 typedef CodeCompletionResult Result;
Douglas Gregor9a0c85e2009-12-07 09:51:25 +00003633 CodeCompletionString *Pattern = 0;
Douglas Gregorb6ac2452010-01-13 21:24:21 +00003634
Douglas Gregorc8bddde2010-05-28 00:22:41 +00003635 if (Results.includeCodePatterns()) {
3636 // @try { statements } @catch ( declaration ) { statements } @finally
3637 // { statements }
3638 Pattern = new CodeCompletionString;
3639 Pattern->AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt,try));
3640 Pattern->AddChunk(CodeCompletionString::CK_LeftBrace);
3641 Pattern->AddPlaceholderChunk("statements");
3642 Pattern->AddChunk(CodeCompletionString::CK_RightBrace);
3643 Pattern->AddTextChunk("@catch");
3644 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
3645 Pattern->AddPlaceholderChunk("parameter");
3646 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
3647 Pattern->AddChunk(CodeCompletionString::CK_LeftBrace);
3648 Pattern->AddPlaceholderChunk("statements");
3649 Pattern->AddChunk(CodeCompletionString::CK_RightBrace);
3650 Pattern->AddTextChunk("@finally");
3651 Pattern->AddChunk(CodeCompletionString::CK_LeftBrace);
3652 Pattern->AddPlaceholderChunk("statements");
3653 Pattern->AddChunk(CodeCompletionString::CK_RightBrace);
3654 Results.AddResult(Result(Pattern));
3655 }
Douglas Gregorb6ac2452010-01-13 21:24:21 +00003656
Douglas Gregor9a0c85e2009-12-07 09:51:25 +00003657 // @throw
3658 Pattern = new CodeCompletionString;
Douglas Gregorb6ac2452010-01-13 21:24:21 +00003659 Pattern->AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt,throw));
Douglas Gregor834389b2010-01-12 06:38:28 +00003660 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
Douglas Gregor9a0c85e2009-12-07 09:51:25 +00003661 Pattern->AddPlaceholderChunk("expression");
Douglas Gregora4477812010-01-14 16:01:26 +00003662 Results.AddResult(Result(Pattern));
Douglas Gregorb6ac2452010-01-13 21:24:21 +00003663
Douglas Gregorc8bddde2010-05-28 00:22:41 +00003664 if (Results.includeCodePatterns()) {
3665 // @synchronized ( expression ) { statements }
3666 Pattern = new CodeCompletionString;
3667 Pattern->AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt,synchronized));
3668 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
3669 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
3670 Pattern->AddPlaceholderChunk("expression");
3671 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
3672 Pattern->AddChunk(CodeCompletionString::CK_LeftBrace);
3673 Pattern->AddPlaceholderChunk("statements");
3674 Pattern->AddChunk(CodeCompletionString::CK_RightBrace);
3675 Results.AddResult(Result(Pattern));
3676 }
Douglas Gregorb6ac2452010-01-13 21:24:21 +00003677}
Douglas Gregor9a0c85e2009-12-07 09:51:25 +00003678
Douglas Gregorbca403c2010-01-13 23:51:12 +00003679static void AddObjCVisibilityResults(const LangOptions &LangOpts,
Douglas Gregorc38c3e12010-01-13 21:54:15 +00003680 ResultBuilder &Results,
3681 bool NeedAt) {
John McCall0a2c5e22010-08-25 06:19:51 +00003682 typedef CodeCompletionResult Result;
Douglas Gregora4477812010-01-14 16:01:26 +00003683 Results.AddResult(Result(OBJC_AT_KEYWORD_NAME(NeedAt,private)));
3684 Results.AddResult(Result(OBJC_AT_KEYWORD_NAME(NeedAt,protected)));
3685 Results.AddResult(Result(OBJC_AT_KEYWORD_NAME(NeedAt,public)));
Douglas Gregorc38c3e12010-01-13 21:54:15 +00003686 if (LangOpts.ObjC2)
Douglas Gregora4477812010-01-14 16:01:26 +00003687 Results.AddResult(Result(OBJC_AT_KEYWORD_NAME(NeedAt,package)));
Douglas Gregorc38c3e12010-01-13 21:54:15 +00003688}
3689
3690void Sema::CodeCompleteObjCAtVisibility(Scope *S) {
3691 ResultBuilder Results(*this);
3692 Results.EnterNewScope();
Douglas Gregorbca403c2010-01-13 23:51:12 +00003693 AddObjCVisibilityResults(getLangOptions(), Results, false);
Douglas Gregorc38c3e12010-01-13 21:54:15 +00003694 Results.ExitScope();
Douglas Gregore6b1bb62010-08-11 21:23:17 +00003695 HandleCodeCompleteResults(this, CodeCompleter,
3696 CodeCompletionContext::CCC_Other,
3697 Results.data(),Results.size());
Douglas Gregorc38c3e12010-01-13 21:54:15 +00003698}
3699
3700void Sema::CodeCompleteObjCAtStatement(Scope *S) {
Douglas Gregorb6ac2452010-01-13 21:24:21 +00003701 ResultBuilder Results(*this);
3702 Results.EnterNewScope();
Douglas Gregorbca403c2010-01-13 23:51:12 +00003703 AddObjCStatementResults(Results, false);
3704 AddObjCExpressionResults(Results, false);
Douglas Gregor9a0c85e2009-12-07 09:51:25 +00003705 Results.ExitScope();
Douglas Gregore6b1bb62010-08-11 21:23:17 +00003706 HandleCodeCompleteResults(this, CodeCompleter,
3707 CodeCompletionContext::CCC_Other,
3708 Results.data(),Results.size());
Douglas Gregor9a0c85e2009-12-07 09:51:25 +00003709}
3710
3711void Sema::CodeCompleteObjCAtExpression(Scope *S) {
3712 ResultBuilder Results(*this);
3713 Results.EnterNewScope();
Douglas Gregorbca403c2010-01-13 23:51:12 +00003714 AddObjCExpressionResults(Results, false);
Douglas Gregor9a0c85e2009-12-07 09:51:25 +00003715 Results.ExitScope();
Douglas Gregore6b1bb62010-08-11 21:23:17 +00003716 HandleCodeCompleteResults(this, CodeCompleter,
3717 CodeCompletionContext::CCC_Other,
3718 Results.data(),Results.size());
Douglas Gregor9a0c85e2009-12-07 09:51:25 +00003719}
3720
Douglas Gregor988358f2009-11-19 00:14:45 +00003721/// \brief Determine whether the addition of the given flag to an Objective-C
3722/// property's attributes will cause a conflict.
3723static bool ObjCPropertyFlagConflicts(unsigned Attributes, unsigned NewFlag) {
3724 // Check if we've already added this flag.
3725 if (Attributes & NewFlag)
3726 return true;
3727
3728 Attributes |= NewFlag;
3729
3730 // Check for collisions with "readonly".
3731 if ((Attributes & ObjCDeclSpec::DQ_PR_readonly) &&
3732 (Attributes & (ObjCDeclSpec::DQ_PR_readwrite |
3733 ObjCDeclSpec::DQ_PR_assign |
3734 ObjCDeclSpec::DQ_PR_copy |
3735 ObjCDeclSpec::DQ_PR_retain)))
3736 return true;
3737
3738 // Check for more than one of { assign, copy, retain }.
3739 unsigned AssignCopyRetMask = Attributes & (ObjCDeclSpec::DQ_PR_assign |
3740 ObjCDeclSpec::DQ_PR_copy |
3741 ObjCDeclSpec::DQ_PR_retain);
3742 if (AssignCopyRetMask &&
3743 AssignCopyRetMask != ObjCDeclSpec::DQ_PR_assign &&
3744 AssignCopyRetMask != ObjCDeclSpec::DQ_PR_copy &&
3745 AssignCopyRetMask != ObjCDeclSpec::DQ_PR_retain)
3746 return true;
3747
3748 return false;
3749}
3750
Douglas Gregora93b1082009-11-18 23:08:07 +00003751void Sema::CodeCompleteObjCPropertyFlags(Scope *S, ObjCDeclSpec &ODS) {
Steve Naroffece8e712009-10-08 21:55:05 +00003752 if (!CodeCompleter)
3753 return;
Douglas Gregord3c68542009-11-19 01:08:35 +00003754
Steve Naroffece8e712009-10-08 21:55:05 +00003755 unsigned Attributes = ODS.getPropertyAttributes();
3756
John McCall0a2c5e22010-08-25 06:19:51 +00003757 typedef CodeCompletionResult Result;
Steve Naroffece8e712009-10-08 21:55:05 +00003758 ResultBuilder Results(*this);
3759 Results.EnterNewScope();
Douglas Gregor988358f2009-11-19 00:14:45 +00003760 if (!ObjCPropertyFlagConflicts(Attributes, ObjCDeclSpec::DQ_PR_readonly))
John McCall0a2c5e22010-08-25 06:19:51 +00003761 Results.AddResult(CodeCompletionResult("readonly"));
Douglas Gregor988358f2009-11-19 00:14:45 +00003762 if (!ObjCPropertyFlagConflicts(Attributes, ObjCDeclSpec::DQ_PR_assign))
John McCall0a2c5e22010-08-25 06:19:51 +00003763 Results.AddResult(CodeCompletionResult("assign"));
Douglas Gregor988358f2009-11-19 00:14:45 +00003764 if (!ObjCPropertyFlagConflicts(Attributes, ObjCDeclSpec::DQ_PR_readwrite))
John McCall0a2c5e22010-08-25 06:19:51 +00003765 Results.AddResult(CodeCompletionResult("readwrite"));
Douglas Gregor988358f2009-11-19 00:14:45 +00003766 if (!ObjCPropertyFlagConflicts(Attributes, ObjCDeclSpec::DQ_PR_retain))
John McCall0a2c5e22010-08-25 06:19:51 +00003767 Results.AddResult(CodeCompletionResult("retain"));
Douglas Gregor988358f2009-11-19 00:14:45 +00003768 if (!ObjCPropertyFlagConflicts(Attributes, ObjCDeclSpec::DQ_PR_copy))
John McCall0a2c5e22010-08-25 06:19:51 +00003769 Results.AddResult(CodeCompletionResult("copy"));
Douglas Gregor988358f2009-11-19 00:14:45 +00003770 if (!ObjCPropertyFlagConflicts(Attributes, ObjCDeclSpec::DQ_PR_nonatomic))
John McCall0a2c5e22010-08-25 06:19:51 +00003771 Results.AddResult(CodeCompletionResult("nonatomic"));
Douglas Gregor988358f2009-11-19 00:14:45 +00003772 if (!ObjCPropertyFlagConflicts(Attributes, ObjCDeclSpec::DQ_PR_setter)) {
Douglas Gregor54f01612009-11-19 00:01:57 +00003773 CodeCompletionString *Setter = new CodeCompletionString;
3774 Setter->AddTypedTextChunk("setter");
3775 Setter->AddTextChunk(" = ");
3776 Setter->AddPlaceholderChunk("method");
John McCall0a2c5e22010-08-25 06:19:51 +00003777 Results.AddResult(CodeCompletionResult(Setter));
Douglas Gregor54f01612009-11-19 00:01:57 +00003778 }
Douglas Gregor988358f2009-11-19 00:14:45 +00003779 if (!ObjCPropertyFlagConflicts(Attributes, ObjCDeclSpec::DQ_PR_getter)) {
Douglas Gregor54f01612009-11-19 00:01:57 +00003780 CodeCompletionString *Getter = new CodeCompletionString;
3781 Getter->AddTypedTextChunk("getter");
3782 Getter->AddTextChunk(" = ");
3783 Getter->AddPlaceholderChunk("method");
John McCall0a2c5e22010-08-25 06:19:51 +00003784 Results.AddResult(CodeCompletionResult(Getter));
Douglas Gregor54f01612009-11-19 00:01:57 +00003785 }
Steve Naroffece8e712009-10-08 21:55:05 +00003786 Results.ExitScope();
Douglas Gregore6b1bb62010-08-11 21:23:17 +00003787 HandleCodeCompleteResults(this, CodeCompleter,
3788 CodeCompletionContext::CCC_Other,
3789 Results.data(),Results.size());
Steve Naroffece8e712009-10-08 21:55:05 +00003790}
Steve Naroffc4df6d22009-11-07 02:08:14 +00003791
Douglas Gregor4ad96852009-11-19 07:41:15 +00003792/// \brief Descripts the kind of Objective-C method that we want to find
3793/// via code completion.
3794enum ObjCMethodKind {
3795 MK_Any, //< Any kind of method, provided it means other specified criteria.
3796 MK_ZeroArgSelector, //< Zero-argument (unary) selector.
3797 MK_OneArgSelector //< One-argument selector.
3798};
3799
Douglas Gregor458433d2010-08-26 15:07:07 +00003800static bool isAcceptableObjCSelector(Selector Sel,
3801 ObjCMethodKind WantKind,
3802 IdentifierInfo **SelIdents,
3803 unsigned NumSelIdents) {
3804 if (NumSelIdents > Sel.getNumArgs())
3805 return false;
3806
3807 switch (WantKind) {
3808 case MK_Any: break;
3809 case MK_ZeroArgSelector: return Sel.isUnarySelector();
3810 case MK_OneArgSelector: return Sel.getNumArgs() == 1;
3811 }
3812
3813 for (unsigned I = 0; I != NumSelIdents; ++I)
3814 if (SelIdents[I] != Sel.getIdentifierInfoForSlot(I))
3815 return false;
3816
3817 return true;
3818}
3819
Douglas Gregor4ad96852009-11-19 07:41:15 +00003820static bool isAcceptableObjCMethod(ObjCMethodDecl *Method,
3821 ObjCMethodKind WantKind,
3822 IdentifierInfo **SelIdents,
3823 unsigned NumSelIdents) {
Douglas Gregor458433d2010-08-26 15:07:07 +00003824 return isAcceptableObjCSelector(Method->getSelector(), WantKind, SelIdents,
3825 NumSelIdents);
Douglas Gregor4ad96852009-11-19 07:41:15 +00003826}
3827
Douglas Gregor36ecb042009-11-17 23:22:23 +00003828/// \brief Add all of the Objective-C methods in the given Objective-C
3829/// container to the set of results.
3830///
3831/// The container will be a class, protocol, category, or implementation of
3832/// any of the above. This mether will recurse to include methods from
3833/// the superclasses of classes along with their categories, protocols, and
3834/// implementations.
3835///
3836/// \param Container the container in which we'll look to find methods.
3837///
3838/// \param WantInstance whether to add instance methods (only); if false, this
3839/// routine will add factory methods (only).
3840///
3841/// \param CurContext the context in which we're performing the lookup that
3842/// finds methods.
3843///
3844/// \param Results the structure into which we'll add results.
3845static void AddObjCMethods(ObjCContainerDecl *Container,
3846 bool WantInstanceMethods,
Douglas Gregor4ad96852009-11-19 07:41:15 +00003847 ObjCMethodKind WantKind,
Douglas Gregord3c68542009-11-19 01:08:35 +00003848 IdentifierInfo **SelIdents,
3849 unsigned NumSelIdents,
Douglas Gregor36ecb042009-11-17 23:22:23 +00003850 DeclContext *CurContext,
Douglas Gregor408be5a2010-08-25 01:08:01 +00003851 ResultBuilder &Results,
3852 bool InOriginalClass = true) {
John McCall0a2c5e22010-08-25 06:19:51 +00003853 typedef CodeCompletionResult Result;
Douglas Gregor36ecb042009-11-17 23:22:23 +00003854 for (ObjCContainerDecl::method_iterator M = Container->meth_begin(),
3855 MEnd = Container->meth_end();
3856 M != MEnd; ++M) {
Douglas Gregord3c68542009-11-19 01:08:35 +00003857 if ((*M)->isInstanceMethod() == WantInstanceMethods) {
3858 // Check whether the selector identifiers we've been given are a
3859 // subset of the identifiers for this particular method.
Douglas Gregor4ad96852009-11-19 07:41:15 +00003860 if (!isAcceptableObjCMethod(*M, WantKind, SelIdents, NumSelIdents))
Douglas Gregord3c68542009-11-19 01:08:35 +00003861 continue;
Douglas Gregor4ad96852009-11-19 07:41:15 +00003862
Douglas Gregord3c68542009-11-19 01:08:35 +00003863 Result R = Result(*M, 0);
3864 R.StartParameter = NumSelIdents;
Douglas Gregor4ad96852009-11-19 07:41:15 +00003865 R.AllParametersAreInformative = (WantKind != MK_Any);
Douglas Gregor408be5a2010-08-25 01:08:01 +00003866 if (!InOriginalClass)
3867 R.Priority += CCD_InBaseClass;
Douglas Gregord3c68542009-11-19 01:08:35 +00003868 Results.MaybeAddResult(R, CurContext);
3869 }
Douglas Gregor36ecb042009-11-17 23:22:23 +00003870 }
3871
Douglas Gregore396c7b2010-09-16 15:34:59 +00003872 // Visit the protocols of protocols.
3873 if (ObjCProtocolDecl *Protocol = dyn_cast<ObjCProtocolDecl>(Container)) {
3874 const ObjCList<ObjCProtocolDecl> &Protocols
3875 = Protocol->getReferencedProtocols();
3876 for (ObjCList<ObjCProtocolDecl>::iterator I = Protocols.begin(),
3877 E = Protocols.end();
3878 I != E; ++I)
3879 AddObjCMethods(*I, WantInstanceMethods, WantKind, SelIdents, NumSelIdents,
3880 CurContext, Results, false);
3881 }
3882
Douglas Gregor36ecb042009-11-17 23:22:23 +00003883 ObjCInterfaceDecl *IFace = dyn_cast<ObjCInterfaceDecl>(Container);
3884 if (!IFace)
3885 return;
3886
3887 // Add methods in protocols.
3888 const ObjCList<ObjCProtocolDecl> &Protocols= IFace->getReferencedProtocols();
3889 for (ObjCList<ObjCProtocolDecl>::iterator I = Protocols.begin(),
3890 E = Protocols.end();
3891 I != E; ++I)
Douglas Gregor4ad96852009-11-19 07:41:15 +00003892 AddObjCMethods(*I, WantInstanceMethods, WantKind, SelIdents, NumSelIdents,
Douglas Gregor408be5a2010-08-25 01:08:01 +00003893 CurContext, Results, false);
Douglas Gregor36ecb042009-11-17 23:22:23 +00003894
3895 // Add methods in categories.
3896 for (ObjCCategoryDecl *CatDecl = IFace->getCategoryList(); CatDecl;
3897 CatDecl = CatDecl->getNextClassCategory()) {
Douglas Gregor4ad96852009-11-19 07:41:15 +00003898 AddObjCMethods(CatDecl, WantInstanceMethods, WantKind, SelIdents,
Douglas Gregor408be5a2010-08-25 01:08:01 +00003899 NumSelIdents, CurContext, Results, InOriginalClass);
Douglas Gregor36ecb042009-11-17 23:22:23 +00003900
3901 // Add a categories protocol methods.
3902 const ObjCList<ObjCProtocolDecl> &Protocols
3903 = CatDecl->getReferencedProtocols();
3904 for (ObjCList<ObjCProtocolDecl>::iterator I = Protocols.begin(),
3905 E = Protocols.end();
3906 I != E; ++I)
Douglas Gregor4ad96852009-11-19 07:41:15 +00003907 AddObjCMethods(*I, WantInstanceMethods, WantKind, SelIdents,
Douglas Gregor408be5a2010-08-25 01:08:01 +00003908 NumSelIdents, CurContext, Results, false);
Douglas Gregor36ecb042009-11-17 23:22:23 +00003909
3910 // Add methods in category implementations.
3911 if (ObjCCategoryImplDecl *Impl = CatDecl->getImplementation())
Douglas Gregor4ad96852009-11-19 07:41:15 +00003912 AddObjCMethods(Impl, WantInstanceMethods, WantKind, SelIdents,
Douglas Gregor408be5a2010-08-25 01:08:01 +00003913 NumSelIdents, CurContext, Results, InOriginalClass);
Douglas Gregor36ecb042009-11-17 23:22:23 +00003914 }
3915
3916 // Add methods in superclass.
3917 if (IFace->getSuperClass())
Douglas Gregor4ad96852009-11-19 07:41:15 +00003918 AddObjCMethods(IFace->getSuperClass(), WantInstanceMethods, WantKind,
Douglas Gregor408be5a2010-08-25 01:08:01 +00003919 SelIdents, NumSelIdents, CurContext, Results, false);
Douglas Gregor36ecb042009-11-17 23:22:23 +00003920
3921 // Add methods in our implementation, if any.
3922 if (ObjCImplementationDecl *Impl = IFace->getImplementation())
Douglas Gregor4ad96852009-11-19 07:41:15 +00003923 AddObjCMethods(Impl, WantInstanceMethods, WantKind, SelIdents,
Douglas Gregor408be5a2010-08-25 01:08:01 +00003924 NumSelIdents, CurContext, Results, InOriginalClass);
Douglas Gregor4ad96852009-11-19 07:41:15 +00003925}
3926
3927
John McCalld226f652010-08-21 09:40:31 +00003928void Sema::CodeCompleteObjCPropertyGetter(Scope *S, Decl *ClassDecl,
3929 Decl **Methods,
Douglas Gregor4ad96852009-11-19 07:41:15 +00003930 unsigned NumMethods) {
John McCall0a2c5e22010-08-25 06:19:51 +00003931 typedef CodeCompletionResult Result;
Douglas Gregor4ad96852009-11-19 07:41:15 +00003932
3933 // Try to find the interface where getters might live.
John McCalld226f652010-08-21 09:40:31 +00003934 ObjCInterfaceDecl *Class = dyn_cast_or_null<ObjCInterfaceDecl>(ClassDecl);
Douglas Gregor4ad96852009-11-19 07:41:15 +00003935 if (!Class) {
3936 if (ObjCCategoryDecl *Category
John McCalld226f652010-08-21 09:40:31 +00003937 = dyn_cast_or_null<ObjCCategoryDecl>(ClassDecl))
Douglas Gregor4ad96852009-11-19 07:41:15 +00003938 Class = Category->getClassInterface();
3939
3940 if (!Class)
3941 return;
3942 }
3943
3944 // Find all of the potential getters.
3945 ResultBuilder Results(*this);
3946 Results.EnterNewScope();
3947
3948 // FIXME: We need to do this because Objective-C methods don't get
3949 // pushed into DeclContexts early enough. Argh!
3950 for (unsigned I = 0; I != NumMethods; ++I) {
3951 if (ObjCMethodDecl *Method
John McCalld226f652010-08-21 09:40:31 +00003952 = dyn_cast_or_null<ObjCMethodDecl>(Methods[I]))
Douglas Gregor4ad96852009-11-19 07:41:15 +00003953 if (Method->isInstanceMethod() &&
3954 isAcceptableObjCMethod(Method, MK_ZeroArgSelector, 0, 0)) {
3955 Result R = Result(Method, 0);
3956 R.AllParametersAreInformative = true;
3957 Results.MaybeAddResult(R, CurContext);
3958 }
3959 }
3960
3961 AddObjCMethods(Class, true, MK_ZeroArgSelector, 0, 0, CurContext, Results);
3962 Results.ExitScope();
Douglas Gregore6b1bb62010-08-11 21:23:17 +00003963 HandleCodeCompleteResults(this, CodeCompleter,
3964 CodeCompletionContext::CCC_Other,
3965 Results.data(),Results.size());
Douglas Gregor4ad96852009-11-19 07:41:15 +00003966}
3967
John McCalld226f652010-08-21 09:40:31 +00003968void Sema::CodeCompleteObjCPropertySetter(Scope *S, Decl *ObjCImplDecl,
3969 Decl **Methods,
Douglas Gregor4ad96852009-11-19 07:41:15 +00003970 unsigned NumMethods) {
John McCall0a2c5e22010-08-25 06:19:51 +00003971 typedef CodeCompletionResult Result;
Douglas Gregor4ad96852009-11-19 07:41:15 +00003972
3973 // Try to find the interface where setters might live.
3974 ObjCInterfaceDecl *Class
John McCalld226f652010-08-21 09:40:31 +00003975 = dyn_cast_or_null<ObjCInterfaceDecl>(ObjCImplDecl);
Douglas Gregor4ad96852009-11-19 07:41:15 +00003976 if (!Class) {
3977 if (ObjCCategoryDecl *Category
John McCalld226f652010-08-21 09:40:31 +00003978 = dyn_cast_or_null<ObjCCategoryDecl>(ObjCImplDecl))
Douglas Gregor4ad96852009-11-19 07:41:15 +00003979 Class = Category->getClassInterface();
3980
3981 if (!Class)
3982 return;
3983 }
3984
3985 // Find all of the potential getters.
3986 ResultBuilder Results(*this);
3987 Results.EnterNewScope();
3988
3989 // FIXME: We need to do this because Objective-C methods don't get
3990 // pushed into DeclContexts early enough. Argh!
3991 for (unsigned I = 0; I != NumMethods; ++I) {
3992 if (ObjCMethodDecl *Method
John McCalld226f652010-08-21 09:40:31 +00003993 = dyn_cast_or_null<ObjCMethodDecl>(Methods[I]))
Douglas Gregor4ad96852009-11-19 07:41:15 +00003994 if (Method->isInstanceMethod() &&
3995 isAcceptableObjCMethod(Method, MK_OneArgSelector, 0, 0)) {
3996 Result R = Result(Method, 0);
3997 R.AllParametersAreInformative = true;
3998 Results.MaybeAddResult(R, CurContext);
3999 }
4000 }
4001
4002 AddObjCMethods(Class, true, MK_OneArgSelector, 0, 0, CurContext, Results);
4003
4004 Results.ExitScope();
Douglas Gregore6b1bb62010-08-11 21:23:17 +00004005 HandleCodeCompleteResults(this, CodeCompleter,
4006 CodeCompletionContext::CCC_Other,
4007 Results.data(),Results.size());
Douglas Gregor36ecb042009-11-17 23:22:23 +00004008}
4009
Douglas Gregord32b0222010-08-24 01:06:58 +00004010void Sema::CodeCompleteObjCPassingType(Scope *S, ObjCDeclSpec &DS) {
John McCall0a2c5e22010-08-25 06:19:51 +00004011 typedef CodeCompletionResult Result;
Douglas Gregord32b0222010-08-24 01:06:58 +00004012 ResultBuilder Results(*this);
4013 Results.EnterNewScope();
4014
4015 // Add context-sensitive, Objective-C parameter-passing keywords.
4016 bool AddedInOut = false;
4017 if ((DS.getObjCDeclQualifier() &
4018 (ObjCDeclSpec::DQ_In | ObjCDeclSpec::DQ_Inout)) == 0) {
4019 Results.AddResult("in");
4020 Results.AddResult("inout");
4021 AddedInOut = true;
4022 }
4023 if ((DS.getObjCDeclQualifier() &
4024 (ObjCDeclSpec::DQ_Out | ObjCDeclSpec::DQ_Inout)) == 0) {
4025 Results.AddResult("out");
4026 if (!AddedInOut)
4027 Results.AddResult("inout");
4028 }
4029 if ((DS.getObjCDeclQualifier() &
4030 (ObjCDeclSpec::DQ_Bycopy | ObjCDeclSpec::DQ_Byref |
4031 ObjCDeclSpec::DQ_Oneway)) == 0) {
4032 Results.AddResult("bycopy");
4033 Results.AddResult("byref");
4034 Results.AddResult("oneway");
4035 }
4036
4037 // Add various builtin type names and specifiers.
4038 AddOrdinaryNameResults(PCC_Type, S, *this, Results);
4039 Results.ExitScope();
4040
4041 // Add the various type names
4042 Results.setFilter(&ResultBuilder::IsOrdinaryNonValueName);
4043 CodeCompletionDeclConsumer Consumer(Results, CurContext);
4044 LookupVisibleDecls(S, LookupOrdinaryName, Consumer,
4045 CodeCompleter->includeGlobals());
4046
4047 if (CodeCompleter->includeMacros())
4048 AddMacroResults(PP, Results);
4049
4050 HandleCodeCompleteResults(this, CodeCompleter,
4051 CodeCompletionContext::CCC_Type,
4052 Results.data(), Results.size());
4053}
4054
Douglas Gregor22f56992010-04-06 19:22:33 +00004055/// \brief When we have an expression with type "id", we may assume
4056/// that it has some more-specific class type based on knowledge of
4057/// common uses of Objective-C. This routine returns that class type,
4058/// or NULL if no better result could be determined.
4059static ObjCInterfaceDecl *GetAssumedMessageSendExprType(Expr *E) {
Douglas Gregor78edf512010-09-15 16:23:04 +00004060 ObjCMessageExpr *Msg = dyn_cast_or_null<ObjCMessageExpr>(E);
Douglas Gregor22f56992010-04-06 19:22:33 +00004061 if (!Msg)
4062 return 0;
4063
4064 Selector Sel = Msg->getSelector();
4065 if (Sel.isNull())
4066 return 0;
4067
4068 IdentifierInfo *Id = Sel.getIdentifierInfoForSlot(0);
4069 if (!Id)
4070 return 0;
4071
4072 ObjCMethodDecl *Method = Msg->getMethodDecl();
4073 if (!Method)
4074 return 0;
4075
4076 // Determine the class that we're sending the message to.
Douglas Gregor04badcf2010-04-21 00:45:42 +00004077 ObjCInterfaceDecl *IFace = 0;
4078 switch (Msg->getReceiverKind()) {
4079 case ObjCMessageExpr::Class:
John McCallc12c5bb2010-05-15 11:32:37 +00004080 if (const ObjCObjectType *ObjType
4081 = Msg->getClassReceiver()->getAs<ObjCObjectType>())
4082 IFace = ObjType->getInterface();
Douglas Gregor04badcf2010-04-21 00:45:42 +00004083 break;
4084
4085 case ObjCMessageExpr::Instance: {
4086 QualType T = Msg->getInstanceReceiver()->getType();
4087 if (const ObjCObjectPointerType *Ptr = T->getAs<ObjCObjectPointerType>())
4088 IFace = Ptr->getInterfaceDecl();
4089 break;
4090 }
4091
4092 case ObjCMessageExpr::SuperInstance:
4093 case ObjCMessageExpr::SuperClass:
4094 break;
Douglas Gregor22f56992010-04-06 19:22:33 +00004095 }
4096
4097 if (!IFace)
4098 return 0;
4099
4100 ObjCInterfaceDecl *Super = IFace->getSuperClass();
4101 if (Method->isInstanceMethod())
4102 return llvm::StringSwitch<ObjCInterfaceDecl *>(Id->getName())
4103 .Case("retain", IFace)
4104 .Case("autorelease", IFace)
4105 .Case("copy", IFace)
4106 .Case("copyWithZone", IFace)
4107 .Case("mutableCopy", IFace)
4108 .Case("mutableCopyWithZone", IFace)
4109 .Case("awakeFromCoder", IFace)
4110 .Case("replacementObjectFromCoder", IFace)
4111 .Case("class", IFace)
4112 .Case("classForCoder", IFace)
4113 .Case("superclass", Super)
4114 .Default(0);
4115
4116 return llvm::StringSwitch<ObjCInterfaceDecl *>(Id->getName())
4117 .Case("new", IFace)
4118 .Case("alloc", IFace)
4119 .Case("allocWithZone", IFace)
4120 .Case("class", IFace)
4121 .Case("superclass", Super)
4122 .Default(0);
4123}
4124
Douglas Gregor03d8aec2010-08-27 15:10:57 +00004125// Add a special completion for a message send to "super", which fills in the
4126// most likely case of forwarding all of our arguments to the superclass
4127// function.
4128///
4129/// \param S The semantic analysis object.
4130///
4131/// \param S NeedSuperKeyword Whether we need to prefix this completion with
4132/// the "super" keyword. Otherwise, we just need to provide the arguments.
4133///
4134/// \param SelIdents The identifiers in the selector that have already been
4135/// provided as arguments for a send to "super".
4136///
4137/// \param NumSelIdents The number of identifiers in \p SelIdents.
4138///
4139/// \param Results The set of results to augment.
4140///
4141/// \returns the Objective-C method declaration that would be invoked by
4142/// this "super" completion. If NULL, no completion was added.
4143static ObjCMethodDecl *AddSuperSendCompletion(Sema &S, bool NeedSuperKeyword,
4144 IdentifierInfo **SelIdents,
4145 unsigned NumSelIdents,
4146 ResultBuilder &Results) {
4147 ObjCMethodDecl *CurMethod = S.getCurMethodDecl();
4148 if (!CurMethod)
4149 return 0;
4150
4151 ObjCInterfaceDecl *Class = CurMethod->getClassInterface();
4152 if (!Class)
4153 return 0;
4154
4155 // Try to find a superclass method with the same selector.
4156 ObjCMethodDecl *SuperMethod = 0;
4157 while ((Class = Class->getSuperClass()) && !SuperMethod)
4158 SuperMethod = Class->getMethod(CurMethod->getSelector(),
4159 CurMethod->isInstanceMethod());
4160
4161 if (!SuperMethod)
4162 return 0;
4163
4164 // Check whether the superclass method has the same signature.
4165 if (CurMethod->param_size() != SuperMethod->param_size() ||
4166 CurMethod->isVariadic() != SuperMethod->isVariadic())
4167 return 0;
4168
4169 for (ObjCMethodDecl::param_iterator CurP = CurMethod->param_begin(),
4170 CurPEnd = CurMethod->param_end(),
4171 SuperP = SuperMethod->param_begin();
4172 CurP != CurPEnd; ++CurP, ++SuperP) {
4173 // Make sure the parameter types are compatible.
4174 if (!S.Context.hasSameUnqualifiedType((*CurP)->getType(),
4175 (*SuperP)->getType()))
4176 return 0;
4177
4178 // Make sure we have a parameter name to forward!
4179 if (!(*CurP)->getIdentifier())
4180 return 0;
4181 }
4182
4183 // We have a superclass method. Now, form the send-to-super completion.
4184 CodeCompletionString *Pattern = new CodeCompletionString;
4185
4186 // Give this completion a return type.
4187 AddResultTypeChunk(S.Context, SuperMethod, Pattern);
4188
4189 // If we need the "super" keyword, add it (plus some spacing).
4190 if (NeedSuperKeyword) {
4191 Pattern->AddTypedTextChunk("super");
4192 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
4193 }
4194
4195 Selector Sel = CurMethod->getSelector();
4196 if (Sel.isUnarySelector()) {
4197 if (NeedSuperKeyword)
4198 Pattern->AddTextChunk(Sel.getIdentifierInfoForSlot(0)->getName());
4199 else
4200 Pattern->AddTypedTextChunk(Sel.getIdentifierInfoForSlot(0)->getName());
4201 } else {
4202 ObjCMethodDecl::param_iterator CurP = CurMethod->param_begin();
4203 for (unsigned I = 0, N = Sel.getNumArgs(); I != N; ++I, ++CurP) {
4204 if (I > NumSelIdents)
4205 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
4206
4207 if (I < NumSelIdents)
4208 Pattern->AddInformativeChunk(
4209 Sel.getIdentifierInfoForSlot(I)->getName().str() + ":");
4210 else if (NeedSuperKeyword || I > NumSelIdents) {
4211 Pattern->AddTextChunk(
4212 Sel.getIdentifierInfoForSlot(I)->getName().str() + ":");
4213 Pattern->AddPlaceholderChunk((*CurP)->getIdentifier()->getName());
4214 } else {
4215 Pattern->AddTypedTextChunk(
4216 Sel.getIdentifierInfoForSlot(I)->getName().str() + ":");
4217 Pattern->AddPlaceholderChunk((*CurP)->getIdentifier()->getName());
4218 }
4219 }
4220 }
4221
4222 Results.AddResult(CodeCompletionResult(Pattern, CCP_SuperCompletion,
4223 SuperMethod->isInstanceMethod()
4224 ? CXCursor_ObjCInstanceMethodDecl
4225 : CXCursor_ObjCClassMethodDecl));
4226 return SuperMethod;
4227}
4228
Douglas Gregor8e254cf2010-05-27 23:06:34 +00004229void Sema::CodeCompleteObjCMessageReceiver(Scope *S) {
John McCall0a2c5e22010-08-25 06:19:51 +00004230 typedef CodeCompletionResult Result;
Douglas Gregor8e254cf2010-05-27 23:06:34 +00004231 ResultBuilder Results(*this);
4232
4233 // Find anything that looks like it could be a message receiver.
4234 Results.setFilter(&ResultBuilder::IsObjCMessageReceiver);
4235 CodeCompletionDeclConsumer Consumer(Results, CurContext);
4236 Results.EnterNewScope();
Douglas Gregor8071e422010-08-15 06:18:01 +00004237 LookupVisibleDecls(S, LookupOrdinaryName, Consumer,
4238 CodeCompleter->includeGlobals());
Douglas Gregor8e254cf2010-05-27 23:06:34 +00004239
4240 // If we are in an Objective-C method inside a class that has a superclass,
4241 // add "super" as an option.
4242 if (ObjCMethodDecl *Method = getCurMethodDecl())
4243 if (ObjCInterfaceDecl *Iface = Method->getClassInterface())
Douglas Gregor03d8aec2010-08-27 15:10:57 +00004244 if (Iface->getSuperClass()) {
Douglas Gregor8e254cf2010-05-27 23:06:34 +00004245 Results.AddResult(Result("super"));
Douglas Gregor03d8aec2010-08-27 15:10:57 +00004246
4247 AddSuperSendCompletion(*this, /*NeedSuperKeyword=*/true, 0, 0, Results);
4248 }
Douglas Gregor8e254cf2010-05-27 23:06:34 +00004249
4250 Results.ExitScope();
4251
4252 if (CodeCompleter->includeMacros())
4253 AddMacroResults(PP, Results);
Douglas Gregore6b1bb62010-08-11 21:23:17 +00004254 HandleCodeCompleteResults(this, CodeCompleter,
4255 CodeCompletionContext::CCC_ObjCMessageReceiver,
4256 Results.data(), Results.size());
Douglas Gregor8e254cf2010-05-27 23:06:34 +00004257
4258}
4259
Douglas Gregor2725ca82010-04-21 19:57:20 +00004260void Sema::CodeCompleteObjCSuperMessage(Scope *S, SourceLocation SuperLoc,
4261 IdentifierInfo **SelIdents,
4262 unsigned NumSelIdents) {
4263 ObjCInterfaceDecl *CDecl = 0;
4264 if (ObjCMethodDecl *CurMethod = getCurMethodDecl()) {
4265 // Figure out which interface we're in.
4266 CDecl = CurMethod->getClassInterface();
4267 if (!CDecl)
4268 return;
4269
4270 // Find the superclass of this class.
4271 CDecl = CDecl->getSuperClass();
4272 if (!CDecl)
4273 return;
4274
4275 if (CurMethod->isInstanceMethod()) {
4276 // We are inside an instance method, which means that the message
4277 // send [super ...] is actually calling an instance method on the
4278 // current object. Build the super expression and handle this like
4279 // an instance method.
4280 QualType SuperTy = Context.getObjCInterfaceType(CDecl);
4281 SuperTy = Context.getObjCObjectPointerType(SuperTy);
John McCall60d7b3a2010-08-24 06:29:42 +00004282 ExprResult Super
Douglas Gregor2725ca82010-04-21 19:57:20 +00004283 = Owned(new (Context) ObjCSuperExpr(SuperLoc, SuperTy));
4284 return CodeCompleteObjCInstanceMessage(S, (Expr *)Super.get(),
Douglas Gregor03d8aec2010-08-27 15:10:57 +00004285 SelIdents, NumSelIdents,
4286 /*IsSuper=*/true);
Douglas Gregor2725ca82010-04-21 19:57:20 +00004287 }
4288
4289 // Fall through to send to the superclass in CDecl.
4290 } else {
4291 // "super" may be the name of a type or variable. Figure out which
4292 // it is.
4293 IdentifierInfo *Super = &Context.Idents.get("super");
4294 NamedDecl *ND = LookupSingleName(S, Super, SuperLoc,
4295 LookupOrdinaryName);
4296 if ((CDecl = dyn_cast_or_null<ObjCInterfaceDecl>(ND))) {
4297 // "super" names an interface. Use it.
4298 } else if (TypeDecl *TD = dyn_cast_or_null<TypeDecl>(ND)) {
John McCallc12c5bb2010-05-15 11:32:37 +00004299 if (const ObjCObjectType *Iface
4300 = Context.getTypeDeclType(TD)->getAs<ObjCObjectType>())
4301 CDecl = Iface->getInterface();
Douglas Gregor2725ca82010-04-21 19:57:20 +00004302 } else if (ND && isa<UnresolvedUsingTypenameDecl>(ND)) {
4303 // "super" names an unresolved type; we can't be more specific.
4304 } else {
4305 // Assume that "super" names some kind of value and parse that way.
4306 CXXScopeSpec SS;
4307 UnqualifiedId id;
4308 id.setIdentifier(Super, SuperLoc);
John McCall60d7b3a2010-08-24 06:29:42 +00004309 ExprResult SuperExpr = ActOnIdExpression(S, SS, id, false, false);
Douglas Gregor2725ca82010-04-21 19:57:20 +00004310 return CodeCompleteObjCInstanceMessage(S, (Expr *)SuperExpr.get(),
4311 SelIdents, NumSelIdents);
4312 }
4313
4314 // Fall through
4315 }
4316
John McCallb3d87482010-08-24 05:47:05 +00004317 ParsedType Receiver;
Douglas Gregor2725ca82010-04-21 19:57:20 +00004318 if (CDecl)
John McCallb3d87482010-08-24 05:47:05 +00004319 Receiver = ParsedType::make(Context.getObjCInterfaceType(CDecl));
Douglas Gregor2725ca82010-04-21 19:57:20 +00004320 return CodeCompleteObjCClassMessage(S, Receiver, SelIdents,
Douglas Gregor03d8aec2010-08-27 15:10:57 +00004321 NumSelIdents, /*IsSuper=*/true);
Douglas Gregor2725ca82010-04-21 19:57:20 +00004322}
4323
Douglas Gregorc7b6d882010-09-16 15:14:18 +00004324static void AddClassMessageCompletions(Sema &SemaRef, Scope *S,
4325 ParsedType Receiver,
4326 IdentifierInfo **SelIdents,
4327 unsigned NumSelIdents,
4328 bool IsSuper,
4329 ResultBuilder &Results) {
John McCall0a2c5e22010-08-25 06:19:51 +00004330 typedef CodeCompletionResult Result;
Douglas Gregor24a069f2009-11-17 17:59:40 +00004331 ObjCInterfaceDecl *CDecl = 0;
Douglas Gregorc7b6d882010-09-16 15:14:18 +00004332
Douglas Gregor24a069f2009-11-17 17:59:40 +00004333 // If the given name refers to an interface type, retrieve the
4334 // corresponding declaration.
Douglas Gregor2725ca82010-04-21 19:57:20 +00004335 if (Receiver) {
Douglas Gregorc7b6d882010-09-16 15:14:18 +00004336 QualType T = SemaRef.GetTypeFromParser(Receiver, 0);
Douglas Gregor2725ca82010-04-21 19:57:20 +00004337 if (!T.isNull())
John McCallc12c5bb2010-05-15 11:32:37 +00004338 if (const ObjCObjectType *Interface = T->getAs<ObjCObjectType>())
4339 CDecl = Interface->getInterface();
Douglas Gregor24a069f2009-11-17 17:59:40 +00004340 }
Douglas Gregorc7b6d882010-09-16 15:14:18 +00004341
Douglas Gregor36ecb042009-11-17 23:22:23 +00004342 // Add all of the factory methods in this Objective-C class, its protocols,
4343 // superclasses, categories, implementation, etc.
Steve Naroffc4df6d22009-11-07 02:08:14 +00004344 Results.EnterNewScope();
Douglas Gregorc7b6d882010-09-16 15:14:18 +00004345
Douglas Gregor03d8aec2010-08-27 15:10:57 +00004346 // If this is a send-to-super, try to add the special "super" send
4347 // completion.
4348 if (IsSuper) {
4349 if (ObjCMethodDecl *SuperMethod
Douglas Gregorc7b6d882010-09-16 15:14:18 +00004350 = AddSuperSendCompletion(SemaRef, false, SelIdents, NumSelIdents,
4351 Results))
Douglas Gregor03d8aec2010-08-27 15:10:57 +00004352 Results.Ignore(SuperMethod);
4353 }
Douglas Gregorc7b6d882010-09-16 15:14:18 +00004354
Douglas Gregor265f7492010-08-27 15:29:55 +00004355 // If we're inside an Objective-C method definition, prefer its selector to
4356 // others.
Douglas Gregorc7b6d882010-09-16 15:14:18 +00004357 if (ObjCMethodDecl *CurMethod = SemaRef.getCurMethodDecl())
Douglas Gregor265f7492010-08-27 15:29:55 +00004358 Results.setPreferredSelector(CurMethod->getSelector());
Douglas Gregorc7b6d882010-09-16 15:14:18 +00004359
Douglas Gregor13438f92010-04-06 16:40:00 +00004360 if (CDecl)
Douglas Gregorc7b6d882010-09-16 15:14:18 +00004361 AddObjCMethods(CDecl, false, MK_Any, SelIdents, NumSelIdents,
4362 SemaRef.CurContext, Results);
Douglas Gregor2725ca82010-04-21 19:57:20 +00004363 else {
Douglas Gregor13438f92010-04-06 16:40:00 +00004364 // We're messaging "id" as a type; provide all class/factory methods.
Douglas Gregorc7b6d882010-09-16 15:14:18 +00004365
Douglas Gregor719770d2010-04-06 17:30:22 +00004366 // If we have an external source, load the entire class method
Sebastian Redl3c7f4132010-08-18 23:57:06 +00004367 // pool from the AST file.
Douglas Gregorc7b6d882010-09-16 15:14:18 +00004368 if (SemaRef.ExternalSource) {
4369 for (uint32_t I = 0,
4370 N = SemaRef.ExternalSource->GetNumExternalSelectors();
John McCall76bd1f32010-06-01 09:23:16 +00004371 I != N; ++I) {
Douglas Gregorc7b6d882010-09-16 15:14:18 +00004372 Selector Sel = SemaRef.ExternalSource->GetExternalSelector(I);
4373 if (Sel.isNull() || SemaRef.MethodPool.count(Sel))
Douglas Gregor719770d2010-04-06 17:30:22 +00004374 continue;
Douglas Gregorc7b6d882010-09-16 15:14:18 +00004375
4376 SemaRef.ReadMethodPool(Sel);
Douglas Gregor719770d2010-04-06 17:30:22 +00004377 }
4378 }
Douglas Gregorc7b6d882010-09-16 15:14:18 +00004379
4380 for (Sema::GlobalMethodPool::iterator M = SemaRef.MethodPool.begin(),
4381 MEnd = SemaRef.MethodPool.end();
Sebastian Redldb9d2142010-08-02 23:18:59 +00004382 M != MEnd; ++M) {
4383 for (ObjCMethodList *MethList = &M->second.second;
4384 MethList && MethList->Method;
Douglas Gregor13438f92010-04-06 16:40:00 +00004385 MethList = MethList->Next) {
4386 if (!isAcceptableObjCMethod(MethList->Method, MK_Any, SelIdents,
4387 NumSelIdents))
4388 continue;
Douglas Gregorc7b6d882010-09-16 15:14:18 +00004389
Douglas Gregor13438f92010-04-06 16:40:00 +00004390 Result R(MethList->Method, 0);
4391 R.StartParameter = NumSelIdents;
4392 R.AllParametersAreInformative = false;
Douglas Gregorc7b6d882010-09-16 15:14:18 +00004393 Results.MaybeAddResult(R, SemaRef.CurContext);
Douglas Gregor13438f92010-04-06 16:40:00 +00004394 }
4395 }
4396 }
Douglas Gregorc7b6d882010-09-16 15:14:18 +00004397
4398 Results.ExitScope();
4399}
Douglas Gregor13438f92010-04-06 16:40:00 +00004400
Douglas Gregorc7b6d882010-09-16 15:14:18 +00004401void Sema::CodeCompleteObjCClassMessage(Scope *S, ParsedType Receiver,
4402 IdentifierInfo **SelIdents,
4403 unsigned NumSelIdents,
4404 bool IsSuper) {
4405 ResultBuilder Results(*this);
4406 AddClassMessageCompletions(*this, S, Receiver, SelIdents, NumSelIdents, IsSuper,
4407 Results);
Douglas Gregore6b1bb62010-08-11 21:23:17 +00004408 HandleCodeCompleteResults(this, CodeCompleter,
4409 CodeCompletionContext::CCC_Other,
Douglas Gregor03d8aec2010-08-27 15:10:57 +00004410 Results.data(), Results.size());
Steve Naroffc4df6d22009-11-07 02:08:14 +00004411}
4412
Douglas Gregord3c68542009-11-19 01:08:35 +00004413void Sema::CodeCompleteObjCInstanceMessage(Scope *S, ExprTy *Receiver,
4414 IdentifierInfo **SelIdents,
Douglas Gregor03d8aec2010-08-27 15:10:57 +00004415 unsigned NumSelIdents,
4416 bool IsSuper) {
John McCall0a2c5e22010-08-25 06:19:51 +00004417 typedef CodeCompletionResult Result;
Steve Naroffc4df6d22009-11-07 02:08:14 +00004418
4419 Expr *RecExpr = static_cast<Expr *>(Receiver);
Steve Naroffc4df6d22009-11-07 02:08:14 +00004420
Douglas Gregor36ecb042009-11-17 23:22:23 +00004421 // If necessary, apply function/array conversion to the receiver.
4422 // C99 6.7.5.3p[7,8].
Douglas Gregor78edf512010-09-15 16:23:04 +00004423 if (RecExpr)
4424 DefaultFunctionArrayLvalueConversion(RecExpr);
4425 QualType ReceiverType = RecExpr? RecExpr->getType() : Context.getObjCIdType();
Steve Naroffc4df6d22009-11-07 02:08:14 +00004426
Douglas Gregor36ecb042009-11-17 23:22:23 +00004427 // Build the set of methods we can see.
4428 ResultBuilder Results(*this);
4429 Results.EnterNewScope();
Douglas Gregor22f56992010-04-06 19:22:33 +00004430
Douglas Gregor03d8aec2010-08-27 15:10:57 +00004431 // If this is a send-to-super, try to add the special "super" send
4432 // completion.
4433 if (IsSuper) {
4434 if (ObjCMethodDecl *SuperMethod
4435 = AddSuperSendCompletion(*this, false, SelIdents, NumSelIdents,
4436 Results))
4437 Results.Ignore(SuperMethod);
4438 }
4439
Douglas Gregor265f7492010-08-27 15:29:55 +00004440 // If we're inside an Objective-C method definition, prefer its selector to
4441 // others.
4442 if (ObjCMethodDecl *CurMethod = getCurMethodDecl())
4443 Results.setPreferredSelector(CurMethod->getSelector());
4444
Douglas Gregor22f56992010-04-06 19:22:33 +00004445 // If we're messaging an expression with type "id" or "Class", check
4446 // whether we know something special about the receiver that allows
4447 // us to assume a more-specific receiver type.
4448 if (ReceiverType->isObjCIdType() || ReceiverType->isObjCClassType())
4449 if (ObjCInterfaceDecl *IFace = GetAssumedMessageSendExprType(RecExpr))
4450 ReceiverType = Context.getObjCObjectPointerType(
4451 Context.getObjCInterfaceType(IFace));
Douglas Gregor36ecb042009-11-17 23:22:23 +00004452
Douglas Gregorf74a4192009-11-18 00:06:18 +00004453 // Handle messages to Class. This really isn't a message to an instance
4454 // method, so we treat it the same way we would treat a message send to a
4455 // class method.
4456 if (ReceiverType->isObjCClassType() ||
4457 ReceiverType->isObjCQualifiedClassType()) {
4458 if (ObjCMethodDecl *CurMethod = getCurMethodDecl()) {
4459 if (ObjCInterfaceDecl *ClassDecl = CurMethod->getClassInterface())
Douglas Gregor4ad96852009-11-19 07:41:15 +00004460 AddObjCMethods(ClassDecl, false, MK_Any, SelIdents, NumSelIdents,
4461 CurContext, Results);
Douglas Gregorf74a4192009-11-18 00:06:18 +00004462 }
4463 }
4464 // Handle messages to a qualified ID ("id<foo>").
4465 else if (const ObjCObjectPointerType *QualID
4466 = ReceiverType->getAsObjCQualifiedIdType()) {
4467 // Search protocols for instance methods.
4468 for (ObjCObjectPointerType::qual_iterator I = QualID->qual_begin(),
4469 E = QualID->qual_end();
4470 I != E; ++I)
Douglas Gregor4ad96852009-11-19 07:41:15 +00004471 AddObjCMethods(*I, true, MK_Any, SelIdents, NumSelIdents, CurContext,
4472 Results);
Douglas Gregorf74a4192009-11-18 00:06:18 +00004473 }
4474 // Handle messages to a pointer to interface type.
4475 else if (const ObjCObjectPointerType *IFacePtr
4476 = ReceiverType->getAsObjCInterfacePointerType()) {
4477 // Search the class, its superclasses, etc., for instance methods.
Douglas Gregor4ad96852009-11-19 07:41:15 +00004478 AddObjCMethods(IFacePtr->getInterfaceDecl(), true, MK_Any, SelIdents,
4479 NumSelIdents, CurContext, Results);
Douglas Gregorf74a4192009-11-18 00:06:18 +00004480
4481 // Search protocols for instance methods.
4482 for (ObjCObjectPointerType::qual_iterator I = IFacePtr->qual_begin(),
4483 E = IFacePtr->qual_end();
4484 I != E; ++I)
Douglas Gregor4ad96852009-11-19 07:41:15 +00004485 AddObjCMethods(*I, true, MK_Any, SelIdents, NumSelIdents, CurContext,
4486 Results);
Douglas Gregorf74a4192009-11-18 00:06:18 +00004487 }
Douglas Gregor13438f92010-04-06 16:40:00 +00004488 // Handle messages to "id".
4489 else if (ReceiverType->isObjCIdType()) {
Douglas Gregor719770d2010-04-06 17:30:22 +00004490 // We're messaging "id", so provide all instance methods we know
4491 // about as code-completion results.
4492
4493 // If we have an external source, load the entire class method
Sebastian Redl3c7f4132010-08-18 23:57:06 +00004494 // pool from the AST file.
Douglas Gregor719770d2010-04-06 17:30:22 +00004495 if (ExternalSource) {
John McCall76bd1f32010-06-01 09:23:16 +00004496 for (uint32_t I = 0, N = ExternalSource->GetNumExternalSelectors();
4497 I != N; ++I) {
4498 Selector Sel = ExternalSource->GetExternalSelector(I);
Sebastian Redldb9d2142010-08-02 23:18:59 +00004499 if (Sel.isNull() || MethodPool.count(Sel))
Douglas Gregor719770d2010-04-06 17:30:22 +00004500 continue;
4501
Sebastian Redldb9d2142010-08-02 23:18:59 +00004502 ReadMethodPool(Sel);
Douglas Gregor719770d2010-04-06 17:30:22 +00004503 }
4504 }
4505
Sebastian Redldb9d2142010-08-02 23:18:59 +00004506 for (GlobalMethodPool::iterator M = MethodPool.begin(),
4507 MEnd = MethodPool.end();
4508 M != MEnd; ++M) {
4509 for (ObjCMethodList *MethList = &M->second.first;
4510 MethList && MethList->Method;
Douglas Gregor13438f92010-04-06 16:40:00 +00004511 MethList = MethList->Next) {
4512 if (!isAcceptableObjCMethod(MethList->Method, MK_Any, SelIdents,
4513 NumSelIdents))
4514 continue;
4515
4516 Result R(MethList->Method, 0);
4517 R.StartParameter = NumSelIdents;
4518 R.AllParametersAreInformative = false;
4519 Results.MaybeAddResult(R, CurContext);
4520 }
4521 }
4522 }
4523
Steve Naroffc4df6d22009-11-07 02:08:14 +00004524 Results.ExitScope();
Douglas Gregore6b1bb62010-08-11 21:23:17 +00004525 HandleCodeCompleteResults(this, CodeCompleter,
4526 CodeCompletionContext::CCC_Other,
4527 Results.data(),Results.size());
Steve Naroffc4df6d22009-11-07 02:08:14 +00004528}
Douglas Gregor55385fe2009-11-18 04:19:12 +00004529
Douglas Gregorfb629412010-08-23 21:17:50 +00004530void Sema::CodeCompleteObjCForCollection(Scope *S,
4531 DeclGroupPtrTy IterationVar) {
4532 CodeCompleteExpressionData Data;
4533 Data.ObjCCollection = true;
4534
4535 if (IterationVar.getAsOpaquePtr()) {
4536 DeclGroupRef DG = IterationVar.getAsVal<DeclGroupRef>();
4537 for (DeclGroupRef::iterator I = DG.begin(), End = DG.end(); I != End; ++I) {
4538 if (*I)
4539 Data.IgnoreDecls.push_back(*I);
4540 }
4541 }
4542
4543 CodeCompleteExpression(S, Data);
4544}
4545
Douglas Gregor458433d2010-08-26 15:07:07 +00004546void Sema::CodeCompleteObjCSelector(Scope *S, IdentifierInfo **SelIdents,
4547 unsigned NumSelIdents) {
4548 // If we have an external source, load the entire class method
4549 // pool from the AST file.
4550 if (ExternalSource) {
4551 for (uint32_t I = 0, N = ExternalSource->GetNumExternalSelectors();
4552 I != N; ++I) {
4553 Selector Sel = ExternalSource->GetExternalSelector(I);
4554 if (Sel.isNull() || MethodPool.count(Sel))
4555 continue;
4556
4557 ReadMethodPool(Sel);
4558 }
4559 }
4560
4561 ResultBuilder Results(*this);
4562 Results.EnterNewScope();
4563 for (GlobalMethodPool::iterator M = MethodPool.begin(),
4564 MEnd = MethodPool.end();
4565 M != MEnd; ++M) {
4566
4567 Selector Sel = M->first;
4568 if (!isAcceptableObjCSelector(Sel, MK_Any, SelIdents, NumSelIdents))
4569 continue;
4570
4571 CodeCompletionString *Pattern = new CodeCompletionString;
4572 if (Sel.isUnarySelector()) {
4573 Pattern->AddTypedTextChunk(Sel.getIdentifierInfoForSlot(0)->getName());
4574 Results.AddResult(Pattern);
4575 continue;
4576 }
4577
Douglas Gregor2d9e21f2010-08-26 16:46:39 +00004578 std::string Accumulator;
Douglas Gregor458433d2010-08-26 15:07:07 +00004579 for (unsigned I = 0, N = Sel.getNumArgs(); I != N; ++I) {
Douglas Gregor2d9e21f2010-08-26 16:46:39 +00004580 if (I == NumSelIdents) {
4581 if (!Accumulator.empty()) {
4582 Pattern->AddInformativeChunk(Accumulator);
4583 Accumulator.clear();
4584 }
4585 }
4586
4587 Accumulator += Sel.getIdentifierInfoForSlot(I)->getName().str();
4588 Accumulator += ':';
Douglas Gregor458433d2010-08-26 15:07:07 +00004589 }
Douglas Gregor2d9e21f2010-08-26 16:46:39 +00004590 Pattern->AddTypedTextChunk(Accumulator);
Douglas Gregor458433d2010-08-26 15:07:07 +00004591 Results.AddResult(Pattern);
4592 }
4593 Results.ExitScope();
4594
4595 HandleCodeCompleteResults(this, CodeCompleter,
4596 CodeCompletionContext::CCC_SelectorName,
4597 Results.data(), Results.size());
4598}
4599
Douglas Gregor55385fe2009-11-18 04:19:12 +00004600/// \brief Add all of the protocol declarations that we find in the given
4601/// (translation unit) context.
4602static void AddProtocolResults(DeclContext *Ctx, DeclContext *CurContext,
Douglas Gregor083128f2009-11-18 04:49:41 +00004603 bool OnlyForwardDeclarations,
Douglas Gregor55385fe2009-11-18 04:19:12 +00004604 ResultBuilder &Results) {
John McCall0a2c5e22010-08-25 06:19:51 +00004605 typedef CodeCompletionResult Result;
Douglas Gregor55385fe2009-11-18 04:19:12 +00004606
4607 for (DeclContext::decl_iterator D = Ctx->decls_begin(),
4608 DEnd = Ctx->decls_end();
4609 D != DEnd; ++D) {
4610 // Record any protocols we find.
4611 if (ObjCProtocolDecl *Proto = dyn_cast<ObjCProtocolDecl>(*D))
Douglas Gregor083128f2009-11-18 04:49:41 +00004612 if (!OnlyForwardDeclarations || Proto->isForwardDecl())
Douglas Gregor608300b2010-01-14 16:14:35 +00004613 Results.AddResult(Result(Proto, 0), CurContext, 0, false);
Douglas Gregor55385fe2009-11-18 04:19:12 +00004614
4615 // Record any forward-declared protocols we find.
4616 if (ObjCForwardProtocolDecl *Forward
4617 = dyn_cast<ObjCForwardProtocolDecl>(*D)) {
4618 for (ObjCForwardProtocolDecl::protocol_iterator
4619 P = Forward->protocol_begin(),
4620 PEnd = Forward->protocol_end();
4621 P != PEnd; ++P)
Douglas Gregor083128f2009-11-18 04:49:41 +00004622 if (!OnlyForwardDeclarations || (*P)->isForwardDecl())
Douglas Gregor608300b2010-01-14 16:14:35 +00004623 Results.AddResult(Result(*P, 0), CurContext, 0, false);
Douglas Gregor55385fe2009-11-18 04:19:12 +00004624 }
4625 }
4626}
4627
4628void Sema::CodeCompleteObjCProtocolReferences(IdentifierLocPair *Protocols,
4629 unsigned NumProtocols) {
4630 ResultBuilder Results(*this);
4631 Results.EnterNewScope();
4632
4633 // Tell the result set to ignore all of the protocols we have
4634 // already seen.
4635 for (unsigned I = 0; I != NumProtocols; ++I)
Douglas Gregorc83c6872010-04-15 22:33:43 +00004636 if (ObjCProtocolDecl *Protocol = LookupProtocol(Protocols[I].first,
4637 Protocols[I].second))
Douglas Gregor55385fe2009-11-18 04:19:12 +00004638 Results.Ignore(Protocol);
4639
4640 // Add all protocols.
Douglas Gregor083128f2009-11-18 04:49:41 +00004641 AddProtocolResults(Context.getTranslationUnitDecl(), CurContext, false,
4642 Results);
4643
4644 Results.ExitScope();
Douglas Gregore6b1bb62010-08-11 21:23:17 +00004645 HandleCodeCompleteResults(this, CodeCompleter,
4646 CodeCompletionContext::CCC_ObjCProtocolName,
4647 Results.data(),Results.size());
Douglas Gregor083128f2009-11-18 04:49:41 +00004648}
4649
4650void Sema::CodeCompleteObjCProtocolDecl(Scope *) {
4651 ResultBuilder Results(*this);
4652 Results.EnterNewScope();
4653
4654 // Add all protocols.
4655 AddProtocolResults(Context.getTranslationUnitDecl(), CurContext, true,
4656 Results);
Douglas Gregor55385fe2009-11-18 04:19:12 +00004657
4658 Results.ExitScope();
Douglas Gregore6b1bb62010-08-11 21:23:17 +00004659 HandleCodeCompleteResults(this, CodeCompleter,
4660 CodeCompletionContext::CCC_ObjCProtocolName,
4661 Results.data(),Results.size());
Douglas Gregor55385fe2009-11-18 04:19:12 +00004662}
Douglas Gregor3b49aca2009-11-18 16:26:39 +00004663
4664/// \brief Add all of the Objective-C interface declarations that we find in
4665/// the given (translation unit) context.
4666static void AddInterfaceResults(DeclContext *Ctx, DeclContext *CurContext,
4667 bool OnlyForwardDeclarations,
4668 bool OnlyUnimplemented,
4669 ResultBuilder &Results) {
John McCall0a2c5e22010-08-25 06:19:51 +00004670 typedef CodeCompletionResult Result;
Douglas Gregor3b49aca2009-11-18 16:26:39 +00004671
4672 for (DeclContext::decl_iterator D = Ctx->decls_begin(),
4673 DEnd = Ctx->decls_end();
4674 D != DEnd; ++D) {
Douglas Gregordeacbdc2010-08-11 12:19:30 +00004675 // Record any interfaces we find.
4676 if (ObjCInterfaceDecl *Class = dyn_cast<ObjCInterfaceDecl>(*D))
4677 if ((!OnlyForwardDeclarations || Class->isForwardDecl()) &&
4678 (!OnlyUnimplemented || !Class->getImplementation()))
4679 Results.AddResult(Result(Class, 0), CurContext, 0, false);
Douglas Gregor3b49aca2009-11-18 16:26:39 +00004680
4681 // Record any forward-declared interfaces we find.
4682 if (ObjCClassDecl *Forward = dyn_cast<ObjCClassDecl>(*D)) {
4683 for (ObjCClassDecl::iterator C = Forward->begin(), CEnd = Forward->end();
Douglas Gregordeacbdc2010-08-11 12:19:30 +00004684 C != CEnd; ++C)
4685 if ((!OnlyForwardDeclarations || C->getInterface()->isForwardDecl()) &&
4686 (!OnlyUnimplemented || !C->getInterface()->getImplementation()))
4687 Results.AddResult(Result(C->getInterface(), 0), CurContext,
Douglas Gregor608300b2010-01-14 16:14:35 +00004688 0, false);
Douglas Gregor3b49aca2009-11-18 16:26:39 +00004689 }
4690 }
4691}
4692
4693void Sema::CodeCompleteObjCInterfaceDecl(Scope *S) {
4694 ResultBuilder Results(*this);
4695 Results.EnterNewScope();
4696
4697 // Add all classes.
4698 AddInterfaceResults(Context.getTranslationUnitDecl(), CurContext, true,
4699 false, Results);
4700
4701 Results.ExitScope();
Douglas Gregore6b1bb62010-08-11 21:23:17 +00004702 HandleCodeCompleteResults(this, CodeCompleter,
4703 CodeCompletionContext::CCC_Other,
4704 Results.data(),Results.size());
Douglas Gregor3b49aca2009-11-18 16:26:39 +00004705}
4706
Douglas Gregorc83c6872010-04-15 22:33:43 +00004707void Sema::CodeCompleteObjCSuperclass(Scope *S, IdentifierInfo *ClassName,
4708 SourceLocation ClassNameLoc) {
Douglas Gregor3b49aca2009-11-18 16:26:39 +00004709 ResultBuilder Results(*this);
4710 Results.EnterNewScope();
4711
4712 // Make sure that we ignore the class we're currently defining.
4713 NamedDecl *CurClass
Douglas Gregorc83c6872010-04-15 22:33:43 +00004714 = LookupSingleName(TUScope, ClassName, ClassNameLoc, LookupOrdinaryName);
Douglas Gregor33ced0b2009-11-18 19:08:43 +00004715 if (CurClass && isa<ObjCInterfaceDecl>(CurClass))
Douglas Gregor3b49aca2009-11-18 16:26:39 +00004716 Results.Ignore(CurClass);
4717
4718 // Add all classes.
4719 AddInterfaceResults(Context.getTranslationUnitDecl(), CurContext, false,
4720 false, Results);
4721
4722 Results.ExitScope();
Douglas Gregore6b1bb62010-08-11 21:23:17 +00004723 HandleCodeCompleteResults(this, CodeCompleter,
4724 CodeCompletionContext::CCC_Other,
4725 Results.data(),Results.size());
Douglas Gregor3b49aca2009-11-18 16:26:39 +00004726}
4727
4728void Sema::CodeCompleteObjCImplementationDecl(Scope *S) {
4729 ResultBuilder Results(*this);
4730 Results.EnterNewScope();
4731
4732 // Add all unimplemented classes.
4733 AddInterfaceResults(Context.getTranslationUnitDecl(), CurContext, false,
4734 true, Results);
4735
4736 Results.ExitScope();
Douglas Gregore6b1bb62010-08-11 21:23:17 +00004737 HandleCodeCompleteResults(this, CodeCompleter,
4738 CodeCompletionContext::CCC_Other,
4739 Results.data(),Results.size());
Douglas Gregor3b49aca2009-11-18 16:26:39 +00004740}
Douglas Gregor33ced0b2009-11-18 19:08:43 +00004741
4742void Sema::CodeCompleteObjCInterfaceCategory(Scope *S,
Douglas Gregorc83c6872010-04-15 22:33:43 +00004743 IdentifierInfo *ClassName,
4744 SourceLocation ClassNameLoc) {
John McCall0a2c5e22010-08-25 06:19:51 +00004745 typedef CodeCompletionResult Result;
Douglas Gregor33ced0b2009-11-18 19:08:43 +00004746
4747 ResultBuilder Results(*this);
4748
4749 // Ignore any categories we find that have already been implemented by this
4750 // interface.
4751 llvm::SmallPtrSet<IdentifierInfo *, 16> CategoryNames;
4752 NamedDecl *CurClass
Douglas Gregorc83c6872010-04-15 22:33:43 +00004753 = LookupSingleName(TUScope, ClassName, ClassNameLoc, LookupOrdinaryName);
Douglas Gregor33ced0b2009-11-18 19:08:43 +00004754 if (ObjCInterfaceDecl *Class = dyn_cast_or_null<ObjCInterfaceDecl>(CurClass))
4755 for (ObjCCategoryDecl *Category = Class->getCategoryList(); Category;
4756 Category = Category->getNextClassCategory())
4757 CategoryNames.insert(Category->getIdentifier());
4758
4759 // Add all of the categories we know about.
4760 Results.EnterNewScope();
4761 TranslationUnitDecl *TU = Context.getTranslationUnitDecl();
4762 for (DeclContext::decl_iterator D = TU->decls_begin(),
4763 DEnd = TU->decls_end();
4764 D != DEnd; ++D)
4765 if (ObjCCategoryDecl *Category = dyn_cast<ObjCCategoryDecl>(*D))
4766 if (CategoryNames.insert(Category->getIdentifier()))
Douglas Gregor608300b2010-01-14 16:14:35 +00004767 Results.AddResult(Result(Category, 0), CurContext, 0, false);
Douglas Gregor33ced0b2009-11-18 19:08:43 +00004768 Results.ExitScope();
4769
Douglas Gregore6b1bb62010-08-11 21:23:17 +00004770 HandleCodeCompleteResults(this, CodeCompleter,
4771 CodeCompletionContext::CCC_Other,
4772 Results.data(),Results.size());
Douglas Gregor33ced0b2009-11-18 19:08:43 +00004773}
4774
4775void Sema::CodeCompleteObjCImplementationCategory(Scope *S,
Douglas Gregorc83c6872010-04-15 22:33:43 +00004776 IdentifierInfo *ClassName,
4777 SourceLocation ClassNameLoc) {
John McCall0a2c5e22010-08-25 06:19:51 +00004778 typedef CodeCompletionResult Result;
Douglas Gregor33ced0b2009-11-18 19:08:43 +00004779
4780 // Find the corresponding interface. If we couldn't find the interface, the
4781 // program itself is ill-formed. However, we'll try to be helpful still by
4782 // providing the list of all of the categories we know about.
4783 NamedDecl *CurClass
Douglas Gregorc83c6872010-04-15 22:33:43 +00004784 = LookupSingleName(TUScope, ClassName, ClassNameLoc, LookupOrdinaryName);
Douglas Gregor33ced0b2009-11-18 19:08:43 +00004785 ObjCInterfaceDecl *Class = dyn_cast_or_null<ObjCInterfaceDecl>(CurClass);
4786 if (!Class)
Douglas Gregorc83c6872010-04-15 22:33:43 +00004787 return CodeCompleteObjCInterfaceCategory(S, ClassName, ClassNameLoc);
Douglas Gregor33ced0b2009-11-18 19:08:43 +00004788
4789 ResultBuilder Results(*this);
4790
4791 // Add all of the categories that have have corresponding interface
4792 // declarations in this class and any of its superclasses, except for
4793 // already-implemented categories in the class itself.
4794 llvm::SmallPtrSet<IdentifierInfo *, 16> CategoryNames;
4795 Results.EnterNewScope();
4796 bool IgnoreImplemented = true;
4797 while (Class) {
4798 for (ObjCCategoryDecl *Category = Class->getCategoryList(); Category;
4799 Category = Category->getNextClassCategory())
4800 if ((!IgnoreImplemented || !Category->getImplementation()) &&
4801 CategoryNames.insert(Category->getIdentifier()))
Douglas Gregor608300b2010-01-14 16:14:35 +00004802 Results.AddResult(Result(Category, 0), CurContext, 0, false);
Douglas Gregor33ced0b2009-11-18 19:08:43 +00004803
4804 Class = Class->getSuperClass();
4805 IgnoreImplemented = false;
4806 }
4807 Results.ExitScope();
4808
Douglas Gregore6b1bb62010-08-11 21:23:17 +00004809 HandleCodeCompleteResults(this, CodeCompleter,
4810 CodeCompletionContext::CCC_Other,
4811 Results.data(),Results.size());
Douglas Gregor33ced0b2009-11-18 19:08:43 +00004812}
Douglas Gregor322328b2009-11-18 22:32:06 +00004813
John McCalld226f652010-08-21 09:40:31 +00004814void Sema::CodeCompleteObjCPropertyDefinition(Scope *S, Decl *ObjCImpDecl) {
John McCall0a2c5e22010-08-25 06:19:51 +00004815 typedef CodeCompletionResult Result;
Douglas Gregor322328b2009-11-18 22:32:06 +00004816 ResultBuilder Results(*this);
4817
4818 // Figure out where this @synthesize lives.
4819 ObjCContainerDecl *Container
John McCalld226f652010-08-21 09:40:31 +00004820 = dyn_cast_or_null<ObjCContainerDecl>(ObjCImpDecl);
Douglas Gregor322328b2009-11-18 22:32:06 +00004821 if (!Container ||
4822 (!isa<ObjCImplementationDecl>(Container) &&
4823 !isa<ObjCCategoryImplDecl>(Container)))
4824 return;
4825
4826 // Ignore any properties that have already been implemented.
4827 for (DeclContext::decl_iterator D = Container->decls_begin(),
4828 DEnd = Container->decls_end();
4829 D != DEnd; ++D)
4830 if (ObjCPropertyImplDecl *PropertyImpl = dyn_cast<ObjCPropertyImplDecl>(*D))
4831 Results.Ignore(PropertyImpl->getPropertyDecl());
4832
4833 // Add any properties that we find.
4834 Results.EnterNewScope();
4835 if (ObjCImplementationDecl *ClassImpl
4836 = dyn_cast<ObjCImplementationDecl>(Container))
4837 AddObjCProperties(ClassImpl->getClassInterface(), false, CurContext,
4838 Results);
4839 else
4840 AddObjCProperties(cast<ObjCCategoryImplDecl>(Container)->getCategoryDecl(),
4841 false, CurContext, Results);
4842 Results.ExitScope();
4843
Douglas Gregore6b1bb62010-08-11 21:23:17 +00004844 HandleCodeCompleteResults(this, CodeCompleter,
4845 CodeCompletionContext::CCC_Other,
4846 Results.data(),Results.size());
Douglas Gregor322328b2009-11-18 22:32:06 +00004847}
4848
4849void Sema::CodeCompleteObjCPropertySynthesizeIvar(Scope *S,
4850 IdentifierInfo *PropertyName,
John McCalld226f652010-08-21 09:40:31 +00004851 Decl *ObjCImpDecl) {
John McCall0a2c5e22010-08-25 06:19:51 +00004852 typedef CodeCompletionResult Result;
Douglas Gregor322328b2009-11-18 22:32:06 +00004853 ResultBuilder Results(*this);
4854
4855 // Figure out where this @synthesize lives.
4856 ObjCContainerDecl *Container
John McCalld226f652010-08-21 09:40:31 +00004857 = dyn_cast_or_null<ObjCContainerDecl>(ObjCImpDecl);
Douglas Gregor322328b2009-11-18 22:32:06 +00004858 if (!Container ||
4859 (!isa<ObjCImplementationDecl>(Container) &&
4860 !isa<ObjCCategoryImplDecl>(Container)))
4861 return;
4862
4863 // Figure out which interface we're looking into.
4864 ObjCInterfaceDecl *Class = 0;
4865 if (ObjCImplementationDecl *ClassImpl
4866 = dyn_cast<ObjCImplementationDecl>(Container))
4867 Class = ClassImpl->getClassInterface();
4868 else
4869 Class = cast<ObjCCategoryImplDecl>(Container)->getCategoryDecl()
4870 ->getClassInterface();
4871
4872 // Add all of the instance variables in this class and its superclasses.
4873 Results.EnterNewScope();
4874 for(; Class; Class = Class->getSuperClass()) {
4875 // FIXME: We could screen the type of each ivar for compatibility with
4876 // the property, but is that being too paternal?
4877 for (ObjCInterfaceDecl::ivar_iterator IVar = Class->ivar_begin(),
4878 IVarEnd = Class->ivar_end();
4879 IVar != IVarEnd; ++IVar)
Douglas Gregor608300b2010-01-14 16:14:35 +00004880 Results.AddResult(Result(*IVar, 0), CurContext, 0, false);
Douglas Gregor322328b2009-11-18 22:32:06 +00004881 }
4882 Results.ExitScope();
4883
Douglas Gregore6b1bb62010-08-11 21:23:17 +00004884 HandleCodeCompleteResults(this, CodeCompleter,
4885 CodeCompletionContext::CCC_Other,
4886 Results.data(),Results.size());
Douglas Gregor322328b2009-11-18 22:32:06 +00004887}
Douglas Gregore8f5a172010-04-07 00:21:17 +00004888
Douglas Gregor408be5a2010-08-25 01:08:01 +00004889// Mapping from selectors to the methods that implement that selector, along
4890// with the "in original class" flag.
4891typedef llvm::DenseMap<Selector, std::pair<ObjCMethodDecl *, bool> >
4892 KnownMethodsMap;
Douglas Gregore8f5a172010-04-07 00:21:17 +00004893
4894/// \brief Find all of the methods that reside in the given container
4895/// (and its superclasses, protocols, etc.) that meet the given
4896/// criteria. Insert those methods into the map of known methods,
4897/// indexed by selector so they can be easily found.
4898static void FindImplementableMethods(ASTContext &Context,
4899 ObjCContainerDecl *Container,
4900 bool WantInstanceMethods,
4901 QualType ReturnType,
4902 bool IsInImplementation,
Douglas Gregor408be5a2010-08-25 01:08:01 +00004903 KnownMethodsMap &KnownMethods,
4904 bool InOriginalClass = true) {
Douglas Gregore8f5a172010-04-07 00:21:17 +00004905 if (ObjCInterfaceDecl *IFace = dyn_cast<ObjCInterfaceDecl>(Container)) {
4906 // Recurse into protocols.
4907 const ObjCList<ObjCProtocolDecl> &Protocols
4908 = IFace->getReferencedProtocols();
4909 for (ObjCList<ObjCProtocolDecl>::iterator I = Protocols.begin(),
4910 E = Protocols.end();
4911 I != E; ++I)
4912 FindImplementableMethods(Context, *I, WantInstanceMethods, ReturnType,
Douglas Gregor408be5a2010-08-25 01:08:01 +00004913 IsInImplementation, KnownMethods,
4914 InOriginalClass);
Douglas Gregore8f5a172010-04-07 00:21:17 +00004915
4916 // If we're not in the implementation of a class, also visit the
4917 // superclass.
4918 if (!IsInImplementation && IFace->getSuperClass())
4919 FindImplementableMethods(Context, IFace->getSuperClass(),
4920 WantInstanceMethods, ReturnType,
Douglas Gregor408be5a2010-08-25 01:08:01 +00004921 IsInImplementation, KnownMethods,
4922 false);
Douglas Gregore8f5a172010-04-07 00:21:17 +00004923
4924 // Add methods from any class extensions (but not from categories;
4925 // those should go into category implementations).
Fariborz Jahanian80aa1cd2010-06-22 23:20:40 +00004926 for (const ObjCCategoryDecl *Cat = IFace->getFirstClassExtension(); Cat;
4927 Cat = Cat->getNextClassExtension())
4928 FindImplementableMethods(Context, const_cast<ObjCCategoryDecl*>(Cat),
4929 WantInstanceMethods, ReturnType,
Douglas Gregor408be5a2010-08-25 01:08:01 +00004930 IsInImplementation, KnownMethods,
4931 InOriginalClass);
Douglas Gregore8f5a172010-04-07 00:21:17 +00004932 }
4933
4934 if (ObjCCategoryDecl *Category = dyn_cast<ObjCCategoryDecl>(Container)) {
4935 // Recurse into protocols.
4936 const ObjCList<ObjCProtocolDecl> &Protocols
4937 = Category->getReferencedProtocols();
4938 for (ObjCList<ObjCProtocolDecl>::iterator I = Protocols.begin(),
4939 E = Protocols.end();
4940 I != E; ++I)
4941 FindImplementableMethods(Context, *I, WantInstanceMethods, ReturnType,
Douglas Gregor408be5a2010-08-25 01:08:01 +00004942 IsInImplementation, KnownMethods,
4943 InOriginalClass);
Douglas Gregore8f5a172010-04-07 00:21:17 +00004944 }
4945
4946 if (ObjCProtocolDecl *Protocol = dyn_cast<ObjCProtocolDecl>(Container)) {
4947 // Recurse into protocols.
4948 const ObjCList<ObjCProtocolDecl> &Protocols
4949 = Protocol->getReferencedProtocols();
4950 for (ObjCList<ObjCProtocolDecl>::iterator I = Protocols.begin(),
4951 E = Protocols.end();
4952 I != E; ++I)
4953 FindImplementableMethods(Context, *I, WantInstanceMethods, ReturnType,
Douglas Gregor408be5a2010-08-25 01:08:01 +00004954 IsInImplementation, KnownMethods, false);
Douglas Gregore8f5a172010-04-07 00:21:17 +00004955 }
4956
4957 // Add methods in this container. This operation occurs last because
4958 // we want the methods from this container to override any methods
4959 // we've previously seen with the same selector.
4960 for (ObjCContainerDecl::method_iterator M = Container->meth_begin(),
4961 MEnd = Container->meth_end();
4962 M != MEnd; ++M) {
4963 if ((*M)->isInstanceMethod() == WantInstanceMethods) {
4964 if (!ReturnType.isNull() &&
4965 !Context.hasSameUnqualifiedType(ReturnType, (*M)->getResultType()))
4966 continue;
4967
Douglas Gregor408be5a2010-08-25 01:08:01 +00004968 KnownMethods[(*M)->getSelector()] = std::make_pair(*M, InOriginalClass);
Douglas Gregore8f5a172010-04-07 00:21:17 +00004969 }
4970 }
4971}
4972
4973void Sema::CodeCompleteObjCMethodDecl(Scope *S,
4974 bool IsInstanceMethod,
John McCallb3d87482010-08-24 05:47:05 +00004975 ParsedType ReturnTy,
John McCalld226f652010-08-21 09:40:31 +00004976 Decl *IDecl) {
Douglas Gregore8f5a172010-04-07 00:21:17 +00004977 // Determine the return type of the method we're declaring, if
4978 // provided.
4979 QualType ReturnType = GetTypeFromParser(ReturnTy);
4980
4981 // Determine where we should start searching for methods, and where we
4982 ObjCContainerDecl *SearchDecl = 0, *CurrentDecl = 0;
4983 bool IsInImplementation = false;
John McCalld226f652010-08-21 09:40:31 +00004984 if (Decl *D = IDecl) {
Douglas Gregore8f5a172010-04-07 00:21:17 +00004985 if (ObjCImplementationDecl *Impl = dyn_cast<ObjCImplementationDecl>(D)) {
4986 SearchDecl = Impl->getClassInterface();
4987 CurrentDecl = Impl;
4988 IsInImplementation = true;
4989 } else if (ObjCCategoryImplDecl *CatImpl
4990 = dyn_cast<ObjCCategoryImplDecl>(D)) {
4991 SearchDecl = CatImpl->getCategoryDecl();
4992 CurrentDecl = CatImpl;
4993 IsInImplementation = true;
4994 } else {
4995 SearchDecl = dyn_cast<ObjCContainerDecl>(D);
4996 CurrentDecl = SearchDecl;
4997 }
4998 }
4999
5000 if (!SearchDecl && S) {
5001 if (DeclContext *DC = static_cast<DeclContext *>(S->getEntity())) {
5002 SearchDecl = dyn_cast<ObjCContainerDecl>(DC);
5003 CurrentDecl = SearchDecl;
5004 }
5005 }
5006
5007 if (!SearchDecl || !CurrentDecl) {
Douglas Gregore6b1bb62010-08-11 21:23:17 +00005008 HandleCodeCompleteResults(this, CodeCompleter,
5009 CodeCompletionContext::CCC_Other,
5010 0, 0);
Douglas Gregore8f5a172010-04-07 00:21:17 +00005011 return;
5012 }
5013
5014 // Find all of the methods that we could declare/implement here.
5015 KnownMethodsMap KnownMethods;
5016 FindImplementableMethods(Context, SearchDecl, IsInstanceMethod,
5017 ReturnType, IsInImplementation, KnownMethods);
5018
5019 // Erase any methods that have already been declared or
5020 // implemented here.
5021 for (ObjCContainerDecl::method_iterator M = CurrentDecl->meth_begin(),
5022 MEnd = CurrentDecl->meth_end();
5023 M != MEnd; ++M) {
5024 if ((*M)->isInstanceMethod() != IsInstanceMethod)
5025 continue;
5026
5027 KnownMethodsMap::iterator Pos = KnownMethods.find((*M)->getSelector());
5028 if (Pos != KnownMethods.end())
5029 KnownMethods.erase(Pos);
5030 }
5031
5032 // Add declarations or definitions for each of the known methods.
John McCall0a2c5e22010-08-25 06:19:51 +00005033 typedef CodeCompletionResult Result;
Douglas Gregore8f5a172010-04-07 00:21:17 +00005034 ResultBuilder Results(*this);
5035 Results.EnterNewScope();
5036 PrintingPolicy Policy(Context.PrintingPolicy);
5037 Policy.AnonymousTagLocations = false;
5038 for (KnownMethodsMap::iterator M = KnownMethods.begin(),
5039 MEnd = KnownMethods.end();
5040 M != MEnd; ++M) {
Douglas Gregor408be5a2010-08-25 01:08:01 +00005041 ObjCMethodDecl *Method = M->second.first;
Douglas Gregore8f5a172010-04-07 00:21:17 +00005042 CodeCompletionString *Pattern = new CodeCompletionString;
5043
5044 // If the result type was not already provided, add it to the
5045 // pattern as (type).
5046 if (ReturnType.isNull()) {
5047 std::string TypeStr;
5048 Method->getResultType().getAsStringInternal(TypeStr, Policy);
5049 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
5050 Pattern->AddTextChunk(TypeStr);
5051 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
5052 }
5053
5054 Selector Sel = Method->getSelector();
5055
5056 // Add the first part of the selector to the pattern.
5057 Pattern->AddTypedTextChunk(Sel.getIdentifierInfoForSlot(0)->getName());
5058
5059 // Add parameters to the pattern.
5060 unsigned I = 0;
5061 for (ObjCMethodDecl::param_iterator P = Method->param_begin(),
5062 PEnd = Method->param_end();
5063 P != PEnd; (void)++P, ++I) {
5064 // Add the part of the selector name.
5065 if (I == 0)
5066 Pattern->AddChunk(CodeCompletionString::CK_Colon);
5067 else if (I < Sel.getNumArgs()) {
5068 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
Douglas Gregor47c03a72010-08-17 15:53:35 +00005069 Pattern->AddTextChunk(Sel.getIdentifierInfoForSlot(I)->getName());
Douglas Gregore8f5a172010-04-07 00:21:17 +00005070 Pattern->AddChunk(CodeCompletionString::CK_Colon);
5071 } else
5072 break;
5073
5074 // Add the parameter type.
5075 std::string TypeStr;
5076 (*P)->getOriginalType().getAsStringInternal(TypeStr, Policy);
5077 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
5078 Pattern->AddTextChunk(TypeStr);
5079 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
5080
5081 if (IdentifierInfo *Id = (*P)->getIdentifier())
Douglas Gregore17794f2010-08-31 05:13:43 +00005082 Pattern->AddTextChunk(Id->getName());
Douglas Gregore8f5a172010-04-07 00:21:17 +00005083 }
5084
5085 if (Method->isVariadic()) {
5086 if (Method->param_size() > 0)
5087 Pattern->AddChunk(CodeCompletionString::CK_Comma);
5088 Pattern->AddTextChunk("...");
Douglas Gregore17794f2010-08-31 05:13:43 +00005089 }
Douglas Gregore8f5a172010-04-07 00:21:17 +00005090
Douglas Gregor447107d2010-05-28 00:57:46 +00005091 if (IsInImplementation && Results.includeCodePatterns()) {
Douglas Gregore8f5a172010-04-07 00:21:17 +00005092 // We will be defining the method here, so add a compound statement.
5093 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
5094 Pattern->AddChunk(CodeCompletionString::CK_LeftBrace);
5095 Pattern->AddChunk(CodeCompletionString::CK_VerticalSpace);
5096 if (!Method->getResultType()->isVoidType()) {
5097 // If the result type is not void, add a return clause.
5098 Pattern->AddTextChunk("return");
5099 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
5100 Pattern->AddPlaceholderChunk("expression");
5101 Pattern->AddChunk(CodeCompletionString::CK_SemiColon);
5102 } else
5103 Pattern->AddPlaceholderChunk("statements");
5104
5105 Pattern->AddChunk(CodeCompletionString::CK_VerticalSpace);
5106 Pattern->AddChunk(CodeCompletionString::CK_RightBrace);
5107 }
5108
Douglas Gregor408be5a2010-08-25 01:08:01 +00005109 unsigned Priority = CCP_CodePattern;
5110 if (!M->second.second)
5111 Priority += CCD_InBaseClass;
5112
5113 Results.AddResult(Result(Pattern, Priority,
Douglas Gregor16ed9ad2010-08-17 16:06:07 +00005114 Method->isInstanceMethod()
5115 ? CXCursor_ObjCInstanceMethodDecl
5116 : CXCursor_ObjCClassMethodDecl));
Douglas Gregore8f5a172010-04-07 00:21:17 +00005117 }
5118
5119 Results.ExitScope();
5120
Douglas Gregore6b1bb62010-08-11 21:23:17 +00005121 HandleCodeCompleteResults(this, CodeCompleter,
5122 CodeCompletionContext::CCC_Other,
5123 Results.data(),Results.size());
Douglas Gregore8f5a172010-04-07 00:21:17 +00005124}
Douglas Gregor1f5537a2010-07-08 23:20:03 +00005125
5126void Sema::CodeCompleteObjCMethodDeclSelector(Scope *S,
5127 bool IsInstanceMethod,
Douglas Gregor40ed9a12010-07-08 23:37:41 +00005128 bool AtParameterName,
John McCallb3d87482010-08-24 05:47:05 +00005129 ParsedType ReturnTy,
Douglas Gregor1f5537a2010-07-08 23:20:03 +00005130 IdentifierInfo **SelIdents,
5131 unsigned NumSelIdents) {
Douglas Gregor1f5537a2010-07-08 23:20:03 +00005132 // If we have an external source, load the entire class method
Sebastian Redl3c7f4132010-08-18 23:57:06 +00005133 // pool from the AST file.
Douglas Gregor1f5537a2010-07-08 23:20:03 +00005134 if (ExternalSource) {
5135 for (uint32_t I = 0, N = ExternalSource->GetNumExternalSelectors();
5136 I != N; ++I) {
5137 Selector Sel = ExternalSource->GetExternalSelector(I);
Sebastian Redldb9d2142010-08-02 23:18:59 +00005138 if (Sel.isNull() || MethodPool.count(Sel))
Douglas Gregor1f5537a2010-07-08 23:20:03 +00005139 continue;
Sebastian Redldb9d2142010-08-02 23:18:59 +00005140
5141 ReadMethodPool(Sel);
Douglas Gregor1f5537a2010-07-08 23:20:03 +00005142 }
5143 }
5144
5145 // Build the set of methods we can see.
John McCall0a2c5e22010-08-25 06:19:51 +00005146 typedef CodeCompletionResult Result;
Douglas Gregor1f5537a2010-07-08 23:20:03 +00005147 ResultBuilder Results(*this);
5148
5149 if (ReturnTy)
5150 Results.setPreferredType(GetTypeFromParser(ReturnTy).getNonReferenceType());
Sebastian Redldb9d2142010-08-02 23:18:59 +00005151
Douglas Gregor1f5537a2010-07-08 23:20:03 +00005152 Results.EnterNewScope();
Sebastian Redldb9d2142010-08-02 23:18:59 +00005153 for (GlobalMethodPool::iterator M = MethodPool.begin(),
5154 MEnd = MethodPool.end();
5155 M != MEnd; ++M) {
5156 for (ObjCMethodList *MethList = IsInstanceMethod ? &M->second.first :
5157 &M->second.second;
5158 MethList && MethList->Method;
Douglas Gregor1f5537a2010-07-08 23:20:03 +00005159 MethList = MethList->Next) {
5160 if (!isAcceptableObjCMethod(MethList->Method, MK_Any, SelIdents,
5161 NumSelIdents))
5162 continue;
5163
Douglas Gregor40ed9a12010-07-08 23:37:41 +00005164 if (AtParameterName) {
5165 // Suggest parameter names we've seen before.
5166 if (NumSelIdents && NumSelIdents <= MethList->Method->param_size()) {
5167 ParmVarDecl *Param = MethList->Method->param_begin()[NumSelIdents-1];
5168 if (Param->getIdentifier()) {
5169 CodeCompletionString *Pattern = new CodeCompletionString;
5170 Pattern->AddTypedTextChunk(Param->getIdentifier()->getName());
5171 Results.AddResult(Pattern);
5172 }
5173 }
5174
5175 continue;
5176 }
5177
Douglas Gregor1f5537a2010-07-08 23:20:03 +00005178 Result R(MethList->Method, 0);
5179 R.StartParameter = NumSelIdents;
5180 R.AllParametersAreInformative = false;
5181 R.DeclaringEntity = true;
5182 Results.MaybeAddResult(R, CurContext);
5183 }
5184 }
5185
5186 Results.ExitScope();
Douglas Gregore6b1bb62010-08-11 21:23:17 +00005187 HandleCodeCompleteResults(this, CodeCompleter,
5188 CodeCompletionContext::CCC_Other,
5189 Results.data(),Results.size());
Douglas Gregor1f5537a2010-07-08 23:20:03 +00005190}
Douglas Gregor87c08a52010-08-13 22:48:40 +00005191
Douglas Gregorf29c5232010-08-24 22:20:20 +00005192void Sema::CodeCompletePreprocessorDirective(bool InConditional) {
Douglas Gregorf44e8542010-08-24 19:08:16 +00005193 ResultBuilder Results(*this);
5194 Results.EnterNewScope();
5195
5196 // #if <condition>
5197 CodeCompletionString *Pattern = new CodeCompletionString;
5198 Pattern->AddTypedTextChunk("if");
5199 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
5200 Pattern->AddPlaceholderChunk("condition");
5201 Results.AddResult(Pattern);
5202
5203 // #ifdef <macro>
5204 Pattern = new CodeCompletionString;
5205 Pattern->AddTypedTextChunk("ifdef");
5206 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
5207 Pattern->AddPlaceholderChunk("macro");
5208 Results.AddResult(Pattern);
5209
5210 // #ifndef <macro>
5211 Pattern = new CodeCompletionString;
5212 Pattern->AddTypedTextChunk("ifndef");
5213 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
5214 Pattern->AddPlaceholderChunk("macro");
5215 Results.AddResult(Pattern);
5216
5217 if (InConditional) {
5218 // #elif <condition>
5219 Pattern = new CodeCompletionString;
5220 Pattern->AddTypedTextChunk("elif");
5221 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
5222 Pattern->AddPlaceholderChunk("condition");
5223 Results.AddResult(Pattern);
5224
5225 // #else
5226 Pattern = new CodeCompletionString;
5227 Pattern->AddTypedTextChunk("else");
5228 Results.AddResult(Pattern);
5229
5230 // #endif
5231 Pattern = new CodeCompletionString;
5232 Pattern->AddTypedTextChunk("endif");
5233 Results.AddResult(Pattern);
5234 }
5235
5236 // #include "header"
5237 Pattern = new CodeCompletionString;
5238 Pattern->AddTypedTextChunk("include");
5239 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
5240 Pattern->AddTextChunk("\"");
5241 Pattern->AddPlaceholderChunk("header");
5242 Pattern->AddTextChunk("\"");
5243 Results.AddResult(Pattern);
5244
5245 // #include <header>
5246 Pattern = new CodeCompletionString;
5247 Pattern->AddTypedTextChunk("include");
5248 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
5249 Pattern->AddTextChunk("<");
5250 Pattern->AddPlaceholderChunk("header");
5251 Pattern->AddTextChunk(">");
5252 Results.AddResult(Pattern);
5253
5254 // #define <macro>
5255 Pattern = new CodeCompletionString;
5256 Pattern->AddTypedTextChunk("define");
5257 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
5258 Pattern->AddPlaceholderChunk("macro");
5259 Results.AddResult(Pattern);
5260
5261 // #define <macro>(<args>)
5262 Pattern = new CodeCompletionString;
5263 Pattern->AddTypedTextChunk("define");
5264 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
5265 Pattern->AddPlaceholderChunk("macro");
5266 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
5267 Pattern->AddPlaceholderChunk("args");
5268 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
5269 Results.AddResult(Pattern);
5270
5271 // #undef <macro>
5272 Pattern = new CodeCompletionString;
5273 Pattern->AddTypedTextChunk("undef");
5274 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
5275 Pattern->AddPlaceholderChunk("macro");
5276 Results.AddResult(Pattern);
5277
5278 // #line <number>
5279 Pattern = new CodeCompletionString;
5280 Pattern->AddTypedTextChunk("line");
5281 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
5282 Pattern->AddPlaceholderChunk("number");
5283 Results.AddResult(Pattern);
5284
5285 // #line <number> "filename"
5286 Pattern = new CodeCompletionString;
5287 Pattern->AddTypedTextChunk("line");
5288 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
5289 Pattern->AddPlaceholderChunk("number");
5290 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
5291 Pattern->AddTextChunk("\"");
5292 Pattern->AddPlaceholderChunk("filename");
5293 Pattern->AddTextChunk("\"");
5294 Results.AddResult(Pattern);
5295
5296 // #error <message>
5297 Pattern = new CodeCompletionString;
5298 Pattern->AddTypedTextChunk("error");
5299 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
5300 Pattern->AddPlaceholderChunk("message");
5301 Results.AddResult(Pattern);
5302
5303 // #pragma <arguments>
5304 Pattern = new CodeCompletionString;
5305 Pattern->AddTypedTextChunk("pragma");
5306 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
5307 Pattern->AddPlaceholderChunk("arguments");
5308 Results.AddResult(Pattern);
5309
5310 if (getLangOptions().ObjC1) {
5311 // #import "header"
5312 Pattern = new CodeCompletionString;
5313 Pattern->AddTypedTextChunk("import");
5314 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
5315 Pattern->AddTextChunk("\"");
5316 Pattern->AddPlaceholderChunk("header");
5317 Pattern->AddTextChunk("\"");
5318 Results.AddResult(Pattern);
5319
5320 // #import <header>
5321 Pattern = new CodeCompletionString;
5322 Pattern->AddTypedTextChunk("import");
5323 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
5324 Pattern->AddTextChunk("<");
5325 Pattern->AddPlaceholderChunk("header");
5326 Pattern->AddTextChunk(">");
5327 Results.AddResult(Pattern);
5328 }
5329
5330 // #include_next "header"
5331 Pattern = new CodeCompletionString;
5332 Pattern->AddTypedTextChunk("include_next");
5333 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
5334 Pattern->AddTextChunk("\"");
5335 Pattern->AddPlaceholderChunk("header");
5336 Pattern->AddTextChunk("\"");
5337 Results.AddResult(Pattern);
5338
5339 // #include_next <header>
5340 Pattern = new CodeCompletionString;
5341 Pattern->AddTypedTextChunk("include_next");
5342 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
5343 Pattern->AddTextChunk("<");
5344 Pattern->AddPlaceholderChunk("header");
5345 Pattern->AddTextChunk(">");
5346 Results.AddResult(Pattern);
5347
5348 // #warning <message>
5349 Pattern = new CodeCompletionString;
5350 Pattern->AddTypedTextChunk("warning");
5351 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
5352 Pattern->AddPlaceholderChunk("message");
5353 Results.AddResult(Pattern);
5354
5355 // Note: #ident and #sccs are such crazy anachronisms that we don't provide
5356 // completions for them. And __include_macros is a Clang-internal extension
5357 // that we don't want to encourage anyone to use.
5358
5359 // FIXME: we don't support #assert or #unassert, so don't suggest them.
5360 Results.ExitScope();
5361
Douglas Gregorf44e8542010-08-24 19:08:16 +00005362 HandleCodeCompleteResults(this, CodeCompleter,
Douglas Gregor721f3592010-08-25 18:41:16 +00005363 CodeCompletionContext::CCC_PreprocessorDirective,
Douglas Gregorf44e8542010-08-24 19:08:16 +00005364 Results.data(), Results.size());
5365}
5366
5367void Sema::CodeCompleteInPreprocessorConditionalExclusion(Scope *S) {
Douglas Gregorf29c5232010-08-24 22:20:20 +00005368 CodeCompleteOrdinaryName(S,
John McCallf312b1e2010-08-26 23:41:50 +00005369 S->getFnParent()? Sema::PCC_RecoveryInFunction
5370 : Sema::PCC_Namespace);
Douglas Gregorf44e8542010-08-24 19:08:16 +00005371}
5372
Douglas Gregorf29c5232010-08-24 22:20:20 +00005373void Sema::CodeCompletePreprocessorMacroName(bool IsDefinition) {
Douglas Gregor1fbb4472010-08-24 20:21:13 +00005374 ResultBuilder Results(*this);
5375 if (!IsDefinition && (!CodeCompleter || CodeCompleter->includeMacros())) {
5376 // Add just the names of macros, not their arguments.
5377 Results.EnterNewScope();
5378 for (Preprocessor::macro_iterator M = PP.macro_begin(),
5379 MEnd = PP.macro_end();
5380 M != MEnd; ++M) {
5381 CodeCompletionString *Pattern = new CodeCompletionString;
5382 Pattern->AddTypedTextChunk(M->first->getName());
5383 Results.AddResult(Pattern);
5384 }
5385 Results.ExitScope();
5386 } else if (IsDefinition) {
5387 // FIXME: Can we detect when the user just wrote an include guard above?
5388 }
5389
5390 HandleCodeCompleteResults(this, CodeCompleter,
5391 IsDefinition? CodeCompletionContext::CCC_MacroName
5392 : CodeCompletionContext::CCC_MacroNameUse,
5393 Results.data(), Results.size());
5394}
5395
Douglas Gregorf29c5232010-08-24 22:20:20 +00005396void Sema::CodeCompletePreprocessorExpression() {
5397 ResultBuilder Results(*this);
5398
5399 if (!CodeCompleter || CodeCompleter->includeMacros())
5400 AddMacroResults(PP, Results);
5401
5402 // defined (<macro>)
5403 Results.EnterNewScope();
5404 CodeCompletionString *Pattern = new CodeCompletionString;
5405 Pattern->AddTypedTextChunk("defined");
5406 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
5407 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
5408 Pattern->AddPlaceholderChunk("macro");
5409 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
5410 Results.AddResult(Pattern);
5411 Results.ExitScope();
5412
5413 HandleCodeCompleteResults(this, CodeCompleter,
5414 CodeCompletionContext::CCC_PreprocessorExpression,
5415 Results.data(), Results.size());
5416}
5417
5418void Sema::CodeCompletePreprocessorMacroArgument(Scope *S,
5419 IdentifierInfo *Macro,
5420 MacroInfo *MacroInfo,
5421 unsigned Argument) {
5422 // FIXME: In the future, we could provide "overload" results, much like we
5423 // do for function calls.
5424
5425 CodeCompleteOrdinaryName(S,
John McCallf312b1e2010-08-26 23:41:50 +00005426 S->getFnParent()? Sema::PCC_RecoveryInFunction
5427 : Sema::PCC_Namespace);
Douglas Gregorf29c5232010-08-24 22:20:20 +00005428}
5429
Douglas Gregor55817af2010-08-25 17:04:25 +00005430void Sema::CodeCompleteNaturalLanguage() {
Douglas Gregor55817af2010-08-25 17:04:25 +00005431 HandleCodeCompleteResults(this, CodeCompleter,
Douglas Gregoraf1c6b52010-08-25 17:10:00 +00005432 CodeCompletionContext::CCC_NaturalLanguage,
Douglas Gregor55817af2010-08-25 17:04:25 +00005433 0, 0);
5434}
5435
Douglas Gregor87c08a52010-08-13 22:48:40 +00005436void Sema::GatherGlobalCodeCompletions(
John McCall0a2c5e22010-08-25 06:19:51 +00005437 llvm::SmallVectorImpl<CodeCompletionResult> &Results) {
Douglas Gregor87c08a52010-08-13 22:48:40 +00005438 ResultBuilder Builder(*this);
5439
Douglas Gregor8071e422010-08-15 06:18:01 +00005440 if (!CodeCompleter || CodeCompleter->includeGlobals()) {
5441 CodeCompletionDeclConsumer Consumer(Builder,
5442 Context.getTranslationUnitDecl());
5443 LookupVisibleDecls(Context.getTranslationUnitDecl(), LookupAnyName,
5444 Consumer);
5445 }
Douglas Gregor87c08a52010-08-13 22:48:40 +00005446
5447 if (!CodeCompleter || CodeCompleter->includeMacros())
5448 AddMacroResults(PP, Builder);
5449
5450 Results.clear();
5451 Results.insert(Results.end(),
5452 Builder.data(), Builder.data() + Builder.size());
5453}