blob: 7dc2cb3609d1c24b28161a21d6096cd2c15f516e [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 Gregor2ccccb32010-08-23 18:23:48 +00002629void Sema::CodeCompleteDeclarator(Scope *S,
2630 bool AllowNonIdentifiers,
2631 bool AllowNestedNameSpecifiers) {
John McCall0a2c5e22010-08-25 06:19:51 +00002632 typedef CodeCompletionResult Result;
Douglas Gregor2ccccb32010-08-23 18:23:48 +00002633 ResultBuilder Results(*this);
2634 Results.EnterNewScope();
2635
2636 // Type qualifiers can come after names.
2637 Results.AddResult(Result("const"));
2638 Results.AddResult(Result("volatile"));
2639 if (getLangOptions().C99)
2640 Results.AddResult(Result("restrict"));
2641
2642 if (getLangOptions().CPlusPlus) {
2643 if (AllowNonIdentifiers) {
2644 Results.AddResult(Result("operator"));
2645 }
2646
2647 // Add nested-name-specifiers.
2648 if (AllowNestedNameSpecifiers) {
2649 Results.allowNestedNameSpecifiers();
2650 CodeCompletionDeclConsumer Consumer(Results, CurContext);
2651 LookupVisibleDecls(S, LookupNestedNameSpecifierName, Consumer,
2652 CodeCompleter->includeGlobals());
2653 }
2654 }
2655 Results.ExitScope();
2656
Douglas Gregor4497dd42010-08-24 04:59:56 +00002657 // Note that we intentionally suppress macro results here, since we do not
2658 // encourage using macros to produce the names of entities.
2659
Douglas Gregor2ccccb32010-08-23 18:23:48 +00002660 HandleCodeCompleteResults(this, CodeCompleter,
2661 AllowNestedNameSpecifiers
2662 ? CodeCompletionContext::CCC_PotentiallyQualifiedName
2663 : CodeCompletionContext::CCC_Name,
2664 Results.data(), Results.size());
2665}
2666
Douglas Gregorfb629412010-08-23 21:17:50 +00002667struct Sema::CodeCompleteExpressionData {
2668 CodeCompleteExpressionData(QualType PreferredType = QualType())
2669 : PreferredType(PreferredType), IntegralConstantExpression(false),
2670 ObjCCollection(false) { }
2671
2672 QualType PreferredType;
2673 bool IntegralConstantExpression;
2674 bool ObjCCollection;
2675 llvm::SmallVector<Decl *, 4> IgnoreDecls;
2676};
2677
Douglas Gregor5ac3bdb2010-05-30 01:49:25 +00002678/// \brief Perform code-completion in an expression context when we know what
2679/// type we're looking for.
Douglas Gregorf9578432010-07-28 21:50:18 +00002680///
2681/// \param IntegralConstantExpression Only permit integral constant
2682/// expressions.
Douglas Gregorfb629412010-08-23 21:17:50 +00002683void Sema::CodeCompleteExpression(Scope *S,
2684 const CodeCompleteExpressionData &Data) {
John McCall0a2c5e22010-08-25 06:19:51 +00002685 typedef CodeCompletionResult Result;
Douglas Gregor5ac3bdb2010-05-30 01:49:25 +00002686 ResultBuilder Results(*this);
2687
Douglas Gregorfb629412010-08-23 21:17:50 +00002688 if (Data.ObjCCollection)
2689 Results.setFilter(&ResultBuilder::IsObjCCollection);
2690 else if (Data.IntegralConstantExpression)
Douglas Gregorf9578432010-07-28 21:50:18 +00002691 Results.setFilter(&ResultBuilder::IsIntegralConstantValue);
Douglas Gregore6b1bb62010-08-11 21:23:17 +00002692 else if (WantTypesInContext(PCC_Expression, getLangOptions()))
Douglas Gregor5ac3bdb2010-05-30 01:49:25 +00002693 Results.setFilter(&ResultBuilder::IsOrdinaryName);
2694 else
2695 Results.setFilter(&ResultBuilder::IsOrdinaryNonTypeName);
Douglas Gregorfb629412010-08-23 21:17:50 +00002696
2697 if (!Data.PreferredType.isNull())
2698 Results.setPreferredType(Data.PreferredType.getNonReferenceType());
2699
2700 // Ignore any declarations that we were told that we don't care about.
2701 for (unsigned I = 0, N = Data.IgnoreDecls.size(); I != N; ++I)
2702 Results.Ignore(Data.IgnoreDecls[I]);
Douglas Gregor5ac3bdb2010-05-30 01:49:25 +00002703
2704 CodeCompletionDeclConsumer Consumer(Results, CurContext);
Douglas Gregor8071e422010-08-15 06:18:01 +00002705 LookupVisibleDecls(S, LookupOrdinaryName, Consumer,
2706 CodeCompleter->includeGlobals());
Douglas Gregor5ac3bdb2010-05-30 01:49:25 +00002707
2708 Results.EnterNewScope();
Douglas Gregore6b1bb62010-08-11 21:23:17 +00002709 AddOrdinaryNameResults(PCC_Expression, S, *this, Results);
Douglas Gregor5ac3bdb2010-05-30 01:49:25 +00002710 Results.ExitScope();
2711
Douglas Gregor590c7d52010-07-08 20:55:51 +00002712 bool PreferredTypeIsPointer = false;
Douglas Gregorfb629412010-08-23 21:17:50 +00002713 if (!Data.PreferredType.isNull())
2714 PreferredTypeIsPointer = Data.PreferredType->isAnyPointerType()
2715 || Data.PreferredType->isMemberPointerType()
2716 || Data.PreferredType->isBlockPointerType();
Douglas Gregor590c7d52010-07-08 20:55:51 +00002717
Douglas Gregoraa5f77b2010-08-23 21:54:33 +00002718 if (S->getFnParent() &&
2719 !Data.ObjCCollection &&
2720 !Data.IntegralConstantExpression)
2721 AddPrettyFunctionResults(PP.getLangOptions(), Results);
2722
Douglas Gregor5ac3bdb2010-05-30 01:49:25 +00002723 if (CodeCompleter->includeMacros())
Douglas Gregor590c7d52010-07-08 20:55:51 +00002724 AddMacroResults(PP, Results, PreferredTypeIsPointer);
Douglas Gregore6b1bb62010-08-11 21:23:17 +00002725 HandleCodeCompleteResults(this, CodeCompleter,
Douglas Gregorfb629412010-08-23 21:17:50 +00002726 CodeCompletionContext(CodeCompletionContext::CCC_Expression,
2727 Data.PreferredType),
Douglas Gregore6b1bb62010-08-11 21:23:17 +00002728 Results.data(),Results.size());
Douglas Gregor5ac3bdb2010-05-30 01:49:25 +00002729}
2730
2731
Douglas Gregor95ac6552009-11-18 01:29:26 +00002732static void AddObjCProperties(ObjCContainerDecl *Container,
Douglas Gregor322328b2009-11-18 22:32:06 +00002733 bool AllowCategories,
Douglas Gregor95ac6552009-11-18 01:29:26 +00002734 DeclContext *CurContext,
2735 ResultBuilder &Results) {
John McCall0a2c5e22010-08-25 06:19:51 +00002736 typedef CodeCompletionResult Result;
Douglas Gregor95ac6552009-11-18 01:29:26 +00002737
2738 // Add properties in this container.
2739 for (ObjCContainerDecl::prop_iterator P = Container->prop_begin(),
2740 PEnd = Container->prop_end();
2741 P != PEnd;
2742 ++P)
2743 Results.MaybeAddResult(Result(*P, 0), CurContext);
2744
2745 // Add properties in referenced protocols.
2746 if (ObjCProtocolDecl *Protocol = dyn_cast<ObjCProtocolDecl>(Container)) {
2747 for (ObjCProtocolDecl::protocol_iterator P = Protocol->protocol_begin(),
2748 PEnd = Protocol->protocol_end();
2749 P != PEnd; ++P)
Douglas Gregor322328b2009-11-18 22:32:06 +00002750 AddObjCProperties(*P, AllowCategories, CurContext, Results);
Douglas Gregor95ac6552009-11-18 01:29:26 +00002751 } else if (ObjCInterfaceDecl *IFace = dyn_cast<ObjCInterfaceDecl>(Container)){
Douglas Gregor322328b2009-11-18 22:32:06 +00002752 if (AllowCategories) {
2753 // Look through categories.
2754 for (ObjCCategoryDecl *Category = IFace->getCategoryList();
2755 Category; Category = Category->getNextClassCategory())
2756 AddObjCProperties(Category, AllowCategories, CurContext, Results);
2757 }
Douglas Gregor95ac6552009-11-18 01:29:26 +00002758
2759 // Look through protocols.
Ted Kremenek53b94412010-09-01 01:21:15 +00002760 for (ObjCInterfaceDecl::all_protocol_iterator
2761 I = IFace->all_referenced_protocol_begin(),
2762 E = IFace->all_referenced_protocol_end(); I != E; ++I)
Douglas Gregor322328b2009-11-18 22:32:06 +00002763 AddObjCProperties(*I, AllowCategories, CurContext, Results);
Douglas Gregor95ac6552009-11-18 01:29:26 +00002764
2765 // Look in the superclass.
2766 if (IFace->getSuperClass())
Douglas Gregor322328b2009-11-18 22:32:06 +00002767 AddObjCProperties(IFace->getSuperClass(), AllowCategories, CurContext,
2768 Results);
Douglas Gregor95ac6552009-11-18 01:29:26 +00002769 } else if (const ObjCCategoryDecl *Category
2770 = dyn_cast<ObjCCategoryDecl>(Container)) {
2771 // Look through protocols.
Ted Kremenek53b94412010-09-01 01:21:15 +00002772 for (ObjCCategoryDecl::protocol_iterator P = Category->protocol_begin(),
2773 PEnd = Category->protocol_end();
Douglas Gregor95ac6552009-11-18 01:29:26 +00002774 P != PEnd; ++P)
Douglas Gregor322328b2009-11-18 22:32:06 +00002775 AddObjCProperties(*P, AllowCategories, CurContext, Results);
Douglas Gregor95ac6552009-11-18 01:29:26 +00002776 }
2777}
2778
Douglas Gregor81b747b2009-09-17 21:32:03 +00002779void Sema::CodeCompleteMemberReferenceExpr(Scope *S, ExprTy *BaseE,
2780 SourceLocation OpLoc,
2781 bool IsArrow) {
2782 if (!BaseE || !CodeCompleter)
2783 return;
2784
John McCall0a2c5e22010-08-25 06:19:51 +00002785 typedef CodeCompletionResult Result;
Douglas Gregor86d9a522009-09-21 16:56:56 +00002786
Douglas Gregor81b747b2009-09-17 21:32:03 +00002787 Expr *Base = static_cast<Expr *>(BaseE);
2788 QualType BaseType = Base->getType();
Douglas Gregor86d9a522009-09-21 16:56:56 +00002789
2790 if (IsArrow) {
2791 if (const PointerType *Ptr = BaseType->getAs<PointerType>())
2792 BaseType = Ptr->getPointeeType();
2793 else if (BaseType->isObjCObjectPointerType())
Douglas Gregor3cdee122010-08-26 16:36:48 +00002794 /*Do nothing*/ ;
Douglas Gregor86d9a522009-09-21 16:56:56 +00002795 else
2796 return;
2797 }
2798
Douglas Gregoreb5758b2009-09-23 22:26:46 +00002799 ResultBuilder Results(*this, &ResultBuilder::IsMember);
Douglas Gregor95ac6552009-11-18 01:29:26 +00002800 Results.EnterNewScope();
2801 if (const RecordType *Record = BaseType->getAs<RecordType>()) {
Douglas Gregor3cdee122010-08-26 16:36:48 +00002802 // Indicate that we are performing a member access, and the cv-qualifiers
2803 // for the base object type.
2804 Results.setObjectTypeQualifiers(BaseType.getQualifiers());
2805
Douglas Gregor95ac6552009-11-18 01:29:26 +00002806 // Access to a C/C++ class, struct, or union.
Douglas Gregor45bcd432010-01-14 03:21:49 +00002807 Results.allowNestedNameSpecifiers();
Douglas Gregor0cc84042010-01-14 15:47:35 +00002808 CodeCompletionDeclConsumer Consumer(Results, CurContext);
Douglas Gregor8071e422010-08-15 06:18:01 +00002809 LookupVisibleDecls(Record->getDecl(), LookupMemberName, Consumer,
2810 CodeCompleter->includeGlobals());
Daniel Dunbar3a2838d2009-11-13 08:58:20 +00002811
Douglas Gregor95ac6552009-11-18 01:29:26 +00002812 if (getLangOptions().CPlusPlus) {
2813 if (!Results.empty()) {
2814 // The "template" keyword can follow "->" or "." in the grammar.
2815 // However, we only want to suggest the template keyword if something
2816 // is dependent.
2817 bool IsDependent = BaseType->isDependentType();
2818 if (!IsDependent) {
2819 for (Scope *DepScope = S; DepScope; DepScope = DepScope->getParent())
2820 if (DeclContext *Ctx = (DeclContext *)DepScope->getEntity()) {
2821 IsDependent = Ctx->isDependentContext();
2822 break;
2823 }
2824 }
Daniel Dunbar3a2838d2009-11-13 08:58:20 +00002825
Douglas Gregor95ac6552009-11-18 01:29:26 +00002826 if (IsDependent)
Douglas Gregora4477812010-01-14 16:01:26 +00002827 Results.AddResult(Result("template"));
Daniel Dunbar3a2838d2009-11-13 08:58:20 +00002828 }
Daniel Dunbar3a2838d2009-11-13 08:58:20 +00002829 }
Douglas Gregor95ac6552009-11-18 01:29:26 +00002830 } else if (!IsArrow && BaseType->getAsObjCInterfacePointerType()) {
2831 // Objective-C property reference.
2832
2833 // Add property results based on our interface.
2834 const ObjCObjectPointerType *ObjCPtr
2835 = BaseType->getAsObjCInterfacePointerType();
2836 assert(ObjCPtr && "Non-NULL pointer guaranteed above!");
Douglas Gregor322328b2009-11-18 22:32:06 +00002837 AddObjCProperties(ObjCPtr->getInterfaceDecl(), true, CurContext, Results);
Douglas Gregor95ac6552009-11-18 01:29:26 +00002838
2839 // Add properties from the protocols in a qualified interface.
2840 for (ObjCObjectPointerType::qual_iterator I = ObjCPtr->qual_begin(),
2841 E = ObjCPtr->qual_end();
2842 I != E; ++I)
Douglas Gregor322328b2009-11-18 22:32:06 +00002843 AddObjCProperties(*I, true, CurContext, Results);
Douglas Gregor95ac6552009-11-18 01:29:26 +00002844 } else if ((IsArrow && BaseType->isObjCObjectPointerType()) ||
John McCallc12c5bb2010-05-15 11:32:37 +00002845 (!IsArrow && BaseType->isObjCObjectType())) {
Douglas Gregor95ac6552009-11-18 01:29:26 +00002846 // Objective-C instance variable access.
2847 ObjCInterfaceDecl *Class = 0;
2848 if (const ObjCObjectPointerType *ObjCPtr
2849 = BaseType->getAs<ObjCObjectPointerType>())
2850 Class = ObjCPtr->getInterfaceDecl();
2851 else
John McCallc12c5bb2010-05-15 11:32:37 +00002852 Class = BaseType->getAs<ObjCObjectType>()->getInterface();
Douglas Gregor95ac6552009-11-18 01:29:26 +00002853
2854 // Add all ivars from this class and its superclasses.
Douglas Gregor80f4f4c2010-01-14 16:08:12 +00002855 if (Class) {
2856 CodeCompletionDeclConsumer Consumer(Results, CurContext);
2857 Results.setFilter(&ResultBuilder::IsObjCIvar);
Douglas Gregor8071e422010-08-15 06:18:01 +00002858 LookupVisibleDecls(Class, LookupMemberName, Consumer,
2859 CodeCompleter->includeGlobals());
Douglas Gregor95ac6552009-11-18 01:29:26 +00002860 }
Douglas Gregor86d9a522009-09-21 16:56:56 +00002861 }
Douglas Gregor95ac6552009-11-18 01:29:26 +00002862
2863 // FIXME: How do we cope with isa?
2864
2865 Results.ExitScope();
Daniel Dunbar3a2838d2009-11-13 08:58:20 +00002866
Daniel Dunbar3a2838d2009-11-13 08:58:20 +00002867 // Hand off the results found for code completion.
Douglas Gregore6b1bb62010-08-11 21:23:17 +00002868 HandleCodeCompleteResults(this, CodeCompleter,
2869 CodeCompletionContext(CodeCompletionContext::CCC_MemberAccess,
2870 BaseType),
2871 Results.data(),Results.size());
Douglas Gregor81b747b2009-09-17 21:32:03 +00002872}
2873
Douglas Gregor374929f2009-09-18 15:37:17 +00002874void Sema::CodeCompleteTag(Scope *S, unsigned TagSpec) {
2875 if (!CodeCompleter)
2876 return;
2877
John McCall0a2c5e22010-08-25 06:19:51 +00002878 typedef CodeCompletionResult Result;
Douglas Gregor86d9a522009-09-21 16:56:56 +00002879 ResultBuilder::LookupFilter Filter = 0;
Douglas Gregore6b1bb62010-08-11 21:23:17 +00002880 enum CodeCompletionContext::Kind ContextKind
2881 = CodeCompletionContext::CCC_Other;
Douglas Gregor374929f2009-09-18 15:37:17 +00002882 switch ((DeclSpec::TST)TagSpec) {
2883 case DeclSpec::TST_enum:
Douglas Gregor86d9a522009-09-21 16:56:56 +00002884 Filter = &ResultBuilder::IsEnum;
Douglas Gregore6b1bb62010-08-11 21:23:17 +00002885 ContextKind = CodeCompletionContext::CCC_EnumTag;
Douglas Gregor374929f2009-09-18 15:37:17 +00002886 break;
2887
2888 case DeclSpec::TST_union:
Douglas Gregor86d9a522009-09-21 16:56:56 +00002889 Filter = &ResultBuilder::IsUnion;
Douglas Gregore6b1bb62010-08-11 21:23:17 +00002890 ContextKind = CodeCompletionContext::CCC_UnionTag;
Douglas Gregor374929f2009-09-18 15:37:17 +00002891 break;
2892
2893 case DeclSpec::TST_struct:
Douglas Gregor374929f2009-09-18 15:37:17 +00002894 case DeclSpec::TST_class:
Douglas Gregor86d9a522009-09-21 16:56:56 +00002895 Filter = &ResultBuilder::IsClassOrStruct;
Douglas Gregore6b1bb62010-08-11 21:23:17 +00002896 ContextKind = CodeCompletionContext::CCC_ClassOrStructTag;
Douglas Gregor374929f2009-09-18 15:37:17 +00002897 break;
2898
2899 default:
2900 assert(false && "Unknown type specifier kind in CodeCompleteTag");
2901 return;
2902 }
Douglas Gregor86d9a522009-09-21 16:56:56 +00002903
John McCall0d6b1642010-04-23 18:46:30 +00002904 ResultBuilder Results(*this);
Douglas Gregor5d2fc402010-01-14 03:27:13 +00002905 CodeCompletionDeclConsumer Consumer(Results, CurContext);
John McCall0d6b1642010-04-23 18:46:30 +00002906
2907 // First pass: look for tags.
2908 Results.setFilter(Filter);
Douglas Gregor8071e422010-08-15 06:18:01 +00002909 LookupVisibleDecls(S, LookupTagName, Consumer,
2910 CodeCompleter->includeGlobals());
John McCall0d6b1642010-04-23 18:46:30 +00002911
Douglas Gregor8071e422010-08-15 06:18:01 +00002912 if (CodeCompleter->includeGlobals()) {
2913 // Second pass: look for nested name specifiers.
2914 Results.setFilter(&ResultBuilder::IsNestedNameSpecifier);
2915 LookupVisibleDecls(S, LookupNestedNameSpecifierName, Consumer);
2916 }
Douglas Gregor86d9a522009-09-21 16:56:56 +00002917
Douglas Gregore6b1bb62010-08-11 21:23:17 +00002918 HandleCodeCompleteResults(this, CodeCompleter, ContextKind,
2919 Results.data(),Results.size());
Douglas Gregor374929f2009-09-18 15:37:17 +00002920}
2921
Douglas Gregor1a480c42010-08-27 17:35:51 +00002922void Sema::CodeCompleteTypeQualifiers(DeclSpec &DS) {
2923 ResultBuilder Results(*this);
2924 Results.EnterNewScope();
2925 if (!(DS.getTypeQualifiers() & DeclSpec::TQ_const))
2926 Results.AddResult("const");
2927 if (!(DS.getTypeQualifiers() & DeclSpec::TQ_volatile))
2928 Results.AddResult("volatile");
2929 if (getLangOptions().C99 &&
2930 !(DS.getTypeQualifiers() & DeclSpec::TQ_restrict))
2931 Results.AddResult("restrict");
2932 Results.ExitScope();
2933 HandleCodeCompleteResults(this, CodeCompleter,
2934 CodeCompletionContext::CCC_TypeQualifiers,
2935 Results.data(), Results.size());
2936}
2937
Douglas Gregor3e1005f2009-09-21 18:10:23 +00002938void Sema::CodeCompleteCase(Scope *S) {
John McCall781472f2010-08-25 08:40:02 +00002939 if (getCurFunction()->SwitchStack.empty() || !CodeCompleter)
Douglas Gregor3e1005f2009-09-21 18:10:23 +00002940 return;
2941
John McCall781472f2010-08-25 08:40:02 +00002942 SwitchStmt *Switch = getCurFunction()->SwitchStack.back();
Douglas Gregorf9578432010-07-28 21:50:18 +00002943 if (!Switch->getCond()->getType()->isEnumeralType()) {
Douglas Gregorfb629412010-08-23 21:17:50 +00002944 CodeCompleteExpressionData Data(Switch->getCond()->getType());
2945 Data.IntegralConstantExpression = true;
2946 CodeCompleteExpression(S, Data);
Douglas Gregor3e1005f2009-09-21 18:10:23 +00002947 return;
Douglas Gregorf9578432010-07-28 21:50:18 +00002948 }
Douglas Gregor3e1005f2009-09-21 18:10:23 +00002949
2950 // Code-complete the cases of a switch statement over an enumeration type
2951 // by providing the list of
2952 EnumDecl *Enum = Switch->getCond()->getType()->getAs<EnumType>()->getDecl();
2953
2954 // Determine which enumerators we have already seen in the switch statement.
2955 // FIXME: Ideally, we would also be able to look *past* the code-completion
2956 // token, in case we are code-completing in the middle of the switch and not
2957 // at the end. However, we aren't able to do so at the moment.
2958 llvm::SmallPtrSet<EnumConstantDecl *, 8> EnumeratorsSeen;
Douglas Gregorb9d0ef72009-09-21 19:57:38 +00002959 NestedNameSpecifier *Qualifier = 0;
Douglas Gregor3e1005f2009-09-21 18:10:23 +00002960 for (SwitchCase *SC = Switch->getSwitchCaseList(); SC;
2961 SC = SC->getNextSwitchCase()) {
2962 CaseStmt *Case = dyn_cast<CaseStmt>(SC);
2963 if (!Case)
2964 continue;
2965
2966 Expr *CaseVal = Case->getLHS()->IgnoreParenCasts();
2967 if (DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(CaseVal))
2968 if (EnumConstantDecl *Enumerator
2969 = dyn_cast<EnumConstantDecl>(DRE->getDecl())) {
2970 // We look into the AST of the case statement to determine which
2971 // enumerator was named. Alternatively, we could compute the value of
2972 // the integral constant expression, then compare it against the
2973 // values of each enumerator. However, value-based approach would not
2974 // work as well with C++ templates where enumerators declared within a
2975 // template are type- and value-dependent.
2976 EnumeratorsSeen.insert(Enumerator);
2977
Douglas Gregorb9d0ef72009-09-21 19:57:38 +00002978 // If this is a qualified-id, keep track of the nested-name-specifier
2979 // so that we can reproduce it as part of code completion, e.g.,
Douglas Gregor3e1005f2009-09-21 18:10:23 +00002980 //
2981 // switch (TagD.getKind()) {
2982 // case TagDecl::TK_enum:
2983 // break;
2984 // case XXX
2985 //
Douglas Gregorb9d0ef72009-09-21 19:57:38 +00002986 // At the XXX, our completions are TagDecl::TK_union,
Douglas Gregor3e1005f2009-09-21 18:10:23 +00002987 // TagDecl::TK_struct, and TagDecl::TK_class, rather than TK_union,
2988 // TK_struct, and TK_class.
Douglas Gregora2813ce2009-10-23 18:54:35 +00002989 Qualifier = DRE->getQualifier();
Douglas Gregor3e1005f2009-09-21 18:10:23 +00002990 }
2991 }
2992
Douglas Gregorb9d0ef72009-09-21 19:57:38 +00002993 if (getLangOptions().CPlusPlus && !Qualifier && EnumeratorsSeen.empty()) {
2994 // If there are no prior enumerators in C++, check whether we have to
2995 // qualify the names of the enumerators that we suggest, because they
2996 // may not be visible in this scope.
2997 Qualifier = getRequiredQualification(Context, CurContext,
2998 Enum->getDeclContext());
2999
3000 // FIXME: Scoped enums need to start with "EnumDecl" as the context!
3001 }
3002
Douglas Gregor3e1005f2009-09-21 18:10:23 +00003003 // Add any enumerators that have not yet been mentioned.
3004 ResultBuilder Results(*this);
3005 Results.EnterNewScope();
3006 for (EnumDecl::enumerator_iterator E = Enum->enumerator_begin(),
3007 EEnd = Enum->enumerator_end();
3008 E != EEnd; ++E) {
3009 if (EnumeratorsSeen.count(*E))
3010 continue;
3011
John McCall0a2c5e22010-08-25 06:19:51 +00003012 Results.AddResult(CodeCompletionResult(*E, Qualifier),
Douglas Gregor608300b2010-01-14 16:14:35 +00003013 CurContext, 0, false);
Douglas Gregor3e1005f2009-09-21 18:10:23 +00003014 }
3015 Results.ExitScope();
Douglas Gregor2f880e42010-04-06 20:02:15 +00003016
Douglas Gregor0c8296d2009-11-07 00:00:49 +00003017 if (CodeCompleter->includeMacros())
Douglas Gregorbca403c2010-01-13 23:51:12 +00003018 AddMacroResults(PP, Results);
Douglas Gregore6b1bb62010-08-11 21:23:17 +00003019 HandleCodeCompleteResults(this, CodeCompleter,
3020 CodeCompletionContext::CCC_Expression,
3021 Results.data(),Results.size());
Douglas Gregor3e1005f2009-09-21 18:10:23 +00003022}
3023
Douglas Gregor9c6a0e92009-09-22 15:41:20 +00003024namespace {
3025 struct IsBetterOverloadCandidate {
3026 Sema &S;
John McCall5769d612010-02-08 23:07:23 +00003027 SourceLocation Loc;
Douglas Gregor9c6a0e92009-09-22 15:41:20 +00003028
3029 public:
John McCall5769d612010-02-08 23:07:23 +00003030 explicit IsBetterOverloadCandidate(Sema &S, SourceLocation Loc)
3031 : S(S), Loc(Loc) { }
Douglas Gregor9c6a0e92009-09-22 15:41:20 +00003032
3033 bool
3034 operator()(const OverloadCandidate &X, const OverloadCandidate &Y) const {
John McCall120d63c2010-08-24 20:38:10 +00003035 return isBetterOverloadCandidate(S, X, Y, Loc);
Douglas Gregor9c6a0e92009-09-22 15:41:20 +00003036 }
3037 };
3038}
3039
Douglas Gregord28dcd72010-05-30 06:10:08 +00003040static bool anyNullArguments(Expr **Args, unsigned NumArgs) {
3041 if (NumArgs && !Args)
3042 return true;
3043
3044 for (unsigned I = 0; I != NumArgs; ++I)
3045 if (!Args[I])
3046 return true;
3047
3048 return false;
3049}
3050
Douglas Gregor9c6a0e92009-09-22 15:41:20 +00003051void Sema::CodeCompleteCall(Scope *S, ExprTy *FnIn,
3052 ExprTy **ArgsIn, unsigned NumArgs) {
3053 if (!CodeCompleter)
3054 return;
Douglas Gregoref96eac2009-12-11 19:06:04 +00003055
3056 // When we're code-completing for a call, we fall back to ordinary
3057 // name code-completion whenever we can't produce specific
3058 // results. We may want to revisit this strategy in the future,
3059 // e.g., by merging the two kinds of results.
3060
Douglas Gregor9c6a0e92009-09-22 15:41:20 +00003061 Expr *Fn = (Expr *)FnIn;
3062 Expr **Args = (Expr **)ArgsIn;
Douglas Gregoref96eac2009-12-11 19:06:04 +00003063
Douglas Gregor9c6a0e92009-09-22 15:41:20 +00003064 // Ignore type-dependent call expressions entirely.
Douglas Gregord28dcd72010-05-30 06:10:08 +00003065 if (!Fn || Fn->isTypeDependent() || anyNullArguments(Args, NumArgs) ||
Douglas Gregoref96eac2009-12-11 19:06:04 +00003066 Expr::hasAnyTypeDependentArguments(Args, NumArgs)) {
Douglas Gregore6b1bb62010-08-11 21:23:17 +00003067 CodeCompleteOrdinaryName(S, PCC_Expression);
Douglas Gregor9c6a0e92009-09-22 15:41:20 +00003068 return;
Douglas Gregoref96eac2009-12-11 19:06:04 +00003069 }
Douglas Gregor9c6a0e92009-09-22 15:41:20 +00003070
John McCall3b4294e2009-12-16 12:17:52 +00003071 // Build an overload candidate set based on the functions we find.
John McCall5769d612010-02-08 23:07:23 +00003072 SourceLocation Loc = Fn->getExprLoc();
3073 OverloadCandidateSet CandidateSet(Loc);
John McCall3b4294e2009-12-16 12:17:52 +00003074
Douglas Gregor9c6a0e92009-09-22 15:41:20 +00003075 // FIXME: What if we're calling something that isn't a function declaration?
3076 // FIXME: What if we're calling a pseudo-destructor?
3077 // FIXME: What if we're calling a member function?
3078
Douglas Gregorc0265402010-01-21 15:46:19 +00003079 typedef CodeCompleteConsumer::OverloadCandidate ResultCandidate;
3080 llvm::SmallVector<ResultCandidate, 8> Results;
3081
John McCall3b4294e2009-12-16 12:17:52 +00003082 Expr *NakedFn = Fn->IgnoreParenCasts();
3083 if (UnresolvedLookupExpr *ULE = dyn_cast<UnresolvedLookupExpr>(NakedFn))
3084 AddOverloadedCallCandidates(ULE, Args, NumArgs, CandidateSet,
3085 /*PartialOverloading=*/ true);
3086 else if (DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(NakedFn)) {
3087 FunctionDecl *FDecl = dyn_cast<FunctionDecl>(DRE->getDecl());
Douglas Gregorc0265402010-01-21 15:46:19 +00003088 if (FDecl) {
Douglas Gregord28dcd72010-05-30 06:10:08 +00003089 if (!getLangOptions().CPlusPlus ||
3090 !FDecl->getType()->getAs<FunctionProtoType>())
Douglas Gregorc0265402010-01-21 15:46:19 +00003091 Results.push_back(ResultCandidate(FDecl));
3092 else
John McCall86820f52010-01-26 01:37:31 +00003093 // FIXME: access?
John McCall9aa472c2010-03-19 07:35:19 +00003094 AddOverloadCandidate(FDecl, DeclAccessPair::make(FDecl, AS_none),
3095 Args, NumArgs, CandidateSet,
Douglas Gregorc27d6c52010-04-16 17:41:49 +00003096 false, /*PartialOverloading*/true);
Douglas Gregorc0265402010-01-21 15:46:19 +00003097 }
John McCall3b4294e2009-12-16 12:17:52 +00003098 }
Douglas Gregor9c6a0e92009-09-22 15:41:20 +00003099
Douglas Gregor5ac3bdb2010-05-30 01:49:25 +00003100 QualType ParamType;
3101
Douglas Gregorc0265402010-01-21 15:46:19 +00003102 if (!CandidateSet.empty()) {
3103 // Sort the overload candidate set by placing the best overloads first.
3104 std::stable_sort(CandidateSet.begin(), CandidateSet.end(),
John McCall5769d612010-02-08 23:07:23 +00003105 IsBetterOverloadCandidate(*this, Loc));
Douglas Gregor9c6a0e92009-09-22 15:41:20 +00003106
Douglas Gregorc0265402010-01-21 15:46:19 +00003107 // Add the remaining viable overload candidates as code-completion reslults.
3108 for (OverloadCandidateSet::iterator Cand = CandidateSet.begin(),
3109 CandEnd = CandidateSet.end();
3110 Cand != CandEnd; ++Cand) {
3111 if (Cand->Viable)
3112 Results.push_back(ResultCandidate(Cand->Function));
3113 }
Douglas Gregor5ac3bdb2010-05-30 01:49:25 +00003114
3115 // From the viable candidates, try to determine the type of this parameter.
3116 for (unsigned I = 0, N = Results.size(); I != N; ++I) {
3117 if (const FunctionType *FType = Results[I].getFunctionType())
3118 if (const FunctionProtoType *Proto = dyn_cast<FunctionProtoType>(FType))
3119 if (NumArgs < Proto->getNumArgs()) {
3120 if (ParamType.isNull())
3121 ParamType = Proto->getArgType(NumArgs);
3122 else if (!Context.hasSameUnqualifiedType(
3123 ParamType.getNonReferenceType(),
3124 Proto->getArgType(NumArgs).getNonReferenceType())) {
3125 ParamType = QualType();
3126 break;
3127 }
3128 }
3129 }
3130 } else {
3131 // Try to determine the parameter type from the type of the expression
3132 // being called.
3133 QualType FunctionType = Fn->getType();
3134 if (const PointerType *Ptr = FunctionType->getAs<PointerType>())
3135 FunctionType = Ptr->getPointeeType();
3136 else if (const BlockPointerType *BlockPtr
3137 = FunctionType->getAs<BlockPointerType>())
3138 FunctionType = BlockPtr->getPointeeType();
3139 else if (const MemberPointerType *MemPtr
3140 = FunctionType->getAs<MemberPointerType>())
3141 FunctionType = MemPtr->getPointeeType();
3142
3143 if (const FunctionProtoType *Proto
3144 = FunctionType->getAs<FunctionProtoType>()) {
3145 if (NumArgs < Proto->getNumArgs())
3146 ParamType = Proto->getArgType(NumArgs);
3147 }
Douglas Gregor9c6a0e92009-09-22 15:41:20 +00003148 }
Douglas Gregoref96eac2009-12-11 19:06:04 +00003149
Douglas Gregor5ac3bdb2010-05-30 01:49:25 +00003150 if (ParamType.isNull())
Douglas Gregore6b1bb62010-08-11 21:23:17 +00003151 CodeCompleteOrdinaryName(S, PCC_Expression);
Douglas Gregor5ac3bdb2010-05-30 01:49:25 +00003152 else
3153 CodeCompleteExpression(S, ParamType);
3154
Douglas Gregor2e4c7a52010-04-06 20:19:47 +00003155 if (!Results.empty())
Douglas Gregoref96eac2009-12-11 19:06:04 +00003156 CodeCompleter->ProcessOverloadCandidates(*this, NumArgs, Results.data(),
3157 Results.size());
Douglas Gregor9c6a0e92009-09-22 15:41:20 +00003158}
3159
John McCalld226f652010-08-21 09:40:31 +00003160void Sema::CodeCompleteInitializer(Scope *S, Decl *D) {
3161 ValueDecl *VD = dyn_cast_or_null<ValueDecl>(D);
Douglas Gregor5ac3bdb2010-05-30 01:49:25 +00003162 if (!VD) {
Douglas Gregore6b1bb62010-08-11 21:23:17 +00003163 CodeCompleteOrdinaryName(S, PCC_Expression);
Douglas Gregor5ac3bdb2010-05-30 01:49:25 +00003164 return;
3165 }
3166
3167 CodeCompleteExpression(S, VD->getType());
3168}
3169
3170void Sema::CodeCompleteReturn(Scope *S) {
3171 QualType ResultType;
3172 if (isa<BlockDecl>(CurContext)) {
3173 if (BlockScopeInfo *BSI = getCurBlock())
3174 ResultType = BSI->ReturnType;
3175 } else if (FunctionDecl *Function = dyn_cast<FunctionDecl>(CurContext))
3176 ResultType = Function->getResultType();
3177 else if (ObjCMethodDecl *Method = dyn_cast<ObjCMethodDecl>(CurContext))
3178 ResultType = Method->getResultType();
3179
3180 if (ResultType.isNull())
Douglas Gregore6b1bb62010-08-11 21:23:17 +00003181 CodeCompleteOrdinaryName(S, PCC_Expression);
Douglas Gregor5ac3bdb2010-05-30 01:49:25 +00003182 else
3183 CodeCompleteExpression(S, ResultType);
3184}
3185
3186void Sema::CodeCompleteAssignmentRHS(Scope *S, ExprTy *LHS) {
3187 if (LHS)
3188 CodeCompleteExpression(S, static_cast<Expr *>(LHS)->getType());
3189 else
Douglas Gregore6b1bb62010-08-11 21:23:17 +00003190 CodeCompleteOrdinaryName(S, PCC_Expression);
Douglas Gregor5ac3bdb2010-05-30 01:49:25 +00003191}
3192
Jeffrey Yasskin9ab14542010-04-08 16:38:48 +00003193void Sema::CodeCompleteQualifiedId(Scope *S, CXXScopeSpec &SS,
Douglas Gregor81b747b2009-09-17 21:32:03 +00003194 bool EnteringContext) {
3195 if (!SS.getScopeRep() || !CodeCompleter)
3196 return;
3197
Douglas Gregor86d9a522009-09-21 16:56:56 +00003198 DeclContext *Ctx = computeDeclContext(SS, EnteringContext);
3199 if (!Ctx)
3200 return;
Douglas Gregord1cd31a2009-12-11 18:28:39 +00003201
3202 // Try to instantiate any non-dependent declaration contexts before
3203 // we look in them.
John McCall77bb1aa2010-05-01 00:40:08 +00003204 if (!isDependentScopeSpecifier(SS) && RequireCompleteDeclContext(SS, Ctx))
Douglas Gregord1cd31a2009-12-11 18:28:39 +00003205 return;
3206
Douglas Gregor86d9a522009-09-21 16:56:56 +00003207 ResultBuilder Results(*this);
Douglas Gregor86d9a522009-09-21 16:56:56 +00003208
Douglas Gregorf6961522010-08-27 21:18:54 +00003209 Results.EnterNewScope();
Douglas Gregor86d9a522009-09-21 16:56:56 +00003210 // The "template" keyword can follow "::" in the grammar, but only
3211 // put it into the grammar if the nested-name-specifier is dependent.
3212 NestedNameSpecifier *NNS = (NestedNameSpecifier *)SS.getScopeRep();
3213 if (!Results.empty() && NNS->isDependent())
Douglas Gregora4477812010-01-14 16:01:26 +00003214 Results.AddResult("template");
Douglas Gregorf6961522010-08-27 21:18:54 +00003215
3216 // Add calls to overridden virtual functions, if there are any.
3217 //
3218 // FIXME: This isn't wonderful, because we don't know whether we're actually
3219 // in a context that permits expressions. This is a general issue with
3220 // qualified-id completions.
3221 if (!EnteringContext)
3222 MaybeAddOverrideCalls(*this, Ctx, Results);
3223 Results.ExitScope();
Douglas Gregor86d9a522009-09-21 16:56:56 +00003224
Douglas Gregorf6961522010-08-27 21:18:54 +00003225 CodeCompletionDeclConsumer Consumer(Results, CurContext);
3226 LookupVisibleDecls(Ctx, LookupOrdinaryName, Consumer);
3227
Douglas Gregore6b1bb62010-08-11 21:23:17 +00003228 HandleCodeCompleteResults(this, CodeCompleter,
Douglas Gregorf6961522010-08-27 21:18:54 +00003229 CodeCompletionContext::CCC_Name,
Douglas Gregore6b1bb62010-08-11 21:23:17 +00003230 Results.data(),Results.size());
Douglas Gregor81b747b2009-09-17 21:32:03 +00003231}
Douglas Gregor49f40bd2009-09-18 19:03:04 +00003232
3233void Sema::CodeCompleteUsing(Scope *S) {
3234 if (!CodeCompleter)
3235 return;
3236
Douglas Gregor86d9a522009-09-21 16:56:56 +00003237 ResultBuilder Results(*this, &ResultBuilder::IsNestedNameSpecifier);
Douglas Gregor8e0a0e42009-09-22 23:31:26 +00003238 Results.EnterNewScope();
Douglas Gregor86d9a522009-09-21 16:56:56 +00003239
3240 // If we aren't in class scope, we could see the "namespace" keyword.
3241 if (!S->isClassScope())
John McCall0a2c5e22010-08-25 06:19:51 +00003242 Results.AddResult(CodeCompletionResult("namespace"));
Douglas Gregor86d9a522009-09-21 16:56:56 +00003243
3244 // After "using", we can see anything that would start a
3245 // nested-name-specifier.
Douglas Gregor5d2fc402010-01-14 03:27:13 +00003246 CodeCompletionDeclConsumer Consumer(Results, CurContext);
Douglas Gregor8071e422010-08-15 06:18:01 +00003247 LookupVisibleDecls(S, LookupOrdinaryName, Consumer,
3248 CodeCompleter->includeGlobals());
Douglas Gregor8e0a0e42009-09-22 23:31:26 +00003249 Results.ExitScope();
Douglas Gregor86d9a522009-09-21 16:56:56 +00003250
Douglas Gregore6b1bb62010-08-11 21:23:17 +00003251 HandleCodeCompleteResults(this, CodeCompleter,
3252 CodeCompletionContext::CCC_Other,
3253 Results.data(),Results.size());
Douglas Gregor49f40bd2009-09-18 19:03:04 +00003254}
3255
3256void Sema::CodeCompleteUsingDirective(Scope *S) {
3257 if (!CodeCompleter)
3258 return;
3259
Douglas Gregor86d9a522009-09-21 16:56:56 +00003260 // After "using namespace", we expect to see a namespace name or namespace
3261 // alias.
3262 ResultBuilder Results(*this, &ResultBuilder::IsNamespaceOrAlias);
Douglas Gregor8e0a0e42009-09-22 23:31:26 +00003263 Results.EnterNewScope();
Douglas Gregor5d2fc402010-01-14 03:27:13 +00003264 CodeCompletionDeclConsumer Consumer(Results, CurContext);
Douglas Gregor8071e422010-08-15 06:18:01 +00003265 LookupVisibleDecls(S, LookupOrdinaryName, Consumer,
3266 CodeCompleter->includeGlobals());
Douglas Gregor8e0a0e42009-09-22 23:31:26 +00003267 Results.ExitScope();
Douglas Gregore6b1bb62010-08-11 21:23:17 +00003268 HandleCodeCompleteResults(this, CodeCompleter,
Douglas Gregor8071e422010-08-15 06:18:01 +00003269 CodeCompletionContext::CCC_Namespace,
Douglas Gregore6b1bb62010-08-11 21:23:17 +00003270 Results.data(),Results.size());
Douglas Gregor49f40bd2009-09-18 19:03:04 +00003271}
3272
3273void Sema::CodeCompleteNamespaceDecl(Scope *S) {
3274 if (!CodeCompleter)
3275 return;
3276
Douglas Gregor86d9a522009-09-21 16:56:56 +00003277 ResultBuilder Results(*this, &ResultBuilder::IsNamespace);
3278 DeclContext *Ctx = (DeclContext *)S->getEntity();
3279 if (!S->getParent())
3280 Ctx = Context.getTranslationUnitDecl();
3281
3282 if (Ctx && Ctx->isFileContext()) {
3283 // We only want to see those namespaces that have already been defined
3284 // within this scope, because its likely that the user is creating an
3285 // extended namespace declaration. Keep track of the most recent
3286 // definition of each namespace.
3287 std::map<NamespaceDecl *, NamespaceDecl *> OrigToLatest;
3288 for (DeclContext::specific_decl_iterator<NamespaceDecl>
3289 NS(Ctx->decls_begin()), NSEnd(Ctx->decls_end());
3290 NS != NSEnd; ++NS)
3291 OrigToLatest[NS->getOriginalNamespace()] = *NS;
3292
3293 // Add the most recent definition (or extended definition) of each
3294 // namespace to the list of results.
Douglas Gregor8e0a0e42009-09-22 23:31:26 +00003295 Results.EnterNewScope();
Douglas Gregor86d9a522009-09-21 16:56:56 +00003296 for (std::map<NamespaceDecl *, NamespaceDecl *>::iterator
3297 NS = OrigToLatest.begin(), NSEnd = OrigToLatest.end();
3298 NS != NSEnd; ++NS)
John McCall0a2c5e22010-08-25 06:19:51 +00003299 Results.AddResult(CodeCompletionResult(NS->second, 0),
Douglas Gregor608300b2010-01-14 16:14:35 +00003300 CurContext, 0, false);
Douglas Gregor8e0a0e42009-09-22 23:31:26 +00003301 Results.ExitScope();
Douglas Gregor86d9a522009-09-21 16:56:56 +00003302 }
3303
Douglas Gregore6b1bb62010-08-11 21:23:17 +00003304 HandleCodeCompleteResults(this, CodeCompleter,
3305 CodeCompletionContext::CCC_Other,
3306 Results.data(),Results.size());
Douglas Gregor49f40bd2009-09-18 19:03:04 +00003307}
3308
3309void Sema::CodeCompleteNamespaceAliasDecl(Scope *S) {
3310 if (!CodeCompleter)
3311 return;
3312
Douglas Gregor86d9a522009-09-21 16:56:56 +00003313 // After "namespace", we expect to see a namespace or alias.
3314 ResultBuilder Results(*this, &ResultBuilder::IsNamespaceOrAlias);
Douglas Gregor5d2fc402010-01-14 03:27:13 +00003315 CodeCompletionDeclConsumer Consumer(Results, CurContext);
Douglas Gregor8071e422010-08-15 06:18:01 +00003316 LookupVisibleDecls(S, LookupOrdinaryName, Consumer,
3317 CodeCompleter->includeGlobals());
Douglas Gregore6b1bb62010-08-11 21:23:17 +00003318 HandleCodeCompleteResults(this, CodeCompleter,
Douglas Gregor8071e422010-08-15 06:18:01 +00003319 CodeCompletionContext::CCC_Namespace,
Douglas Gregore6b1bb62010-08-11 21:23:17 +00003320 Results.data(),Results.size());
Douglas Gregor49f40bd2009-09-18 19:03:04 +00003321}
3322
Douglas Gregored8d3222009-09-18 20:05:18 +00003323void Sema::CodeCompleteOperatorName(Scope *S) {
3324 if (!CodeCompleter)
3325 return;
Douglas Gregor86d9a522009-09-21 16:56:56 +00003326
John McCall0a2c5e22010-08-25 06:19:51 +00003327 typedef CodeCompletionResult Result;
Douglas Gregor86d9a522009-09-21 16:56:56 +00003328 ResultBuilder Results(*this, &ResultBuilder::IsType);
Douglas Gregor8e0a0e42009-09-22 23:31:26 +00003329 Results.EnterNewScope();
Douglas Gregored8d3222009-09-18 20:05:18 +00003330
Douglas Gregor86d9a522009-09-21 16:56:56 +00003331 // Add the names of overloadable operators.
3332#define OVERLOADED_OPERATOR(Name,Spelling,Token,Unary,Binary,MemberOnly) \
3333 if (std::strcmp(Spelling, "?")) \
Douglas Gregora4477812010-01-14 16:01:26 +00003334 Results.AddResult(Result(Spelling));
Douglas Gregor86d9a522009-09-21 16:56:56 +00003335#include "clang/Basic/OperatorKinds.def"
3336
3337 // Add any type names visible from the current scope
Douglas Gregor45bcd432010-01-14 03:21:49 +00003338 Results.allowNestedNameSpecifiers();
Douglas Gregor5d2fc402010-01-14 03:27:13 +00003339 CodeCompletionDeclConsumer Consumer(Results, CurContext);
Douglas Gregor8071e422010-08-15 06:18:01 +00003340 LookupVisibleDecls(S, LookupOrdinaryName, Consumer,
3341 CodeCompleter->includeGlobals());
Douglas Gregor86d9a522009-09-21 16:56:56 +00003342
3343 // Add any type specifiers
Douglas Gregorbca403c2010-01-13 23:51:12 +00003344 AddTypeSpecifierResults(getLangOptions(), Results);
Douglas Gregor8e0a0e42009-09-22 23:31:26 +00003345 Results.ExitScope();
Douglas Gregor86d9a522009-09-21 16:56:56 +00003346
Douglas Gregore6b1bb62010-08-11 21:23:17 +00003347 HandleCodeCompleteResults(this, CodeCompleter,
Douglas Gregor8071e422010-08-15 06:18:01 +00003348 CodeCompletionContext::CCC_Type,
Douglas Gregore6b1bb62010-08-11 21:23:17 +00003349 Results.data(),Results.size());
Douglas Gregored8d3222009-09-18 20:05:18 +00003350}
Douglas Gregor49f40bd2009-09-18 19:03:04 +00003351
Douglas Gregor0133f522010-08-28 00:00:50 +00003352void Sema::CodeCompleteConstructorInitializer(Decl *ConstructorD,
3353 CXXBaseOrMemberInitializer** Initializers,
3354 unsigned NumInitializers) {
3355 CXXConstructorDecl *Constructor
3356 = static_cast<CXXConstructorDecl *>(ConstructorD);
3357 if (!Constructor)
3358 return;
3359
3360 ResultBuilder Results(*this);
3361 Results.EnterNewScope();
3362
3363 // Fill in any already-initialized fields or base classes.
3364 llvm::SmallPtrSet<FieldDecl *, 4> InitializedFields;
3365 llvm::SmallPtrSet<CanQualType, 4> InitializedBases;
3366 for (unsigned I = 0; I != NumInitializers; ++I) {
3367 if (Initializers[I]->isBaseInitializer())
3368 InitializedBases.insert(
3369 Context.getCanonicalType(QualType(Initializers[I]->getBaseClass(), 0)));
3370 else
3371 InitializedFields.insert(cast<FieldDecl>(Initializers[I]->getMember()));
3372 }
3373
3374 // Add completions for base classes.
Douglas Gregor0c431c82010-08-29 19:27:27 +00003375 bool SawLastInitializer = (NumInitializers == 0);
Douglas Gregor0133f522010-08-28 00:00:50 +00003376 CXXRecordDecl *ClassDecl = Constructor->getParent();
3377 for (CXXRecordDecl::base_class_iterator Base = ClassDecl->bases_begin(),
3378 BaseEnd = ClassDecl->bases_end();
3379 Base != BaseEnd; ++Base) {
Douglas Gregor0c431c82010-08-29 19:27:27 +00003380 if (!InitializedBases.insert(Context.getCanonicalType(Base->getType()))) {
3381 SawLastInitializer
3382 = NumInitializers > 0 &&
3383 Initializers[NumInitializers - 1]->isBaseInitializer() &&
3384 Context.hasSameUnqualifiedType(Base->getType(),
3385 QualType(Initializers[NumInitializers - 1]->getBaseClass(), 0));
Douglas Gregor0133f522010-08-28 00:00:50 +00003386 continue;
Douglas Gregor0c431c82010-08-29 19:27:27 +00003387 }
Douglas Gregor0133f522010-08-28 00:00:50 +00003388
3389 CodeCompletionString *Pattern = new CodeCompletionString;
3390 Pattern->AddTypedTextChunk(
3391 Base->getType().getAsString(Context.PrintingPolicy));
3392 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
3393 Pattern->AddPlaceholderChunk("args");
3394 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
Douglas Gregor0c431c82010-08-29 19:27:27 +00003395 Results.AddResult(CodeCompletionResult(Pattern,
3396 SawLastInitializer? CCP_NextInitializer
3397 : CCP_MemberDeclaration));
3398 SawLastInitializer = false;
Douglas Gregor0133f522010-08-28 00:00:50 +00003399 }
3400
3401 // Add completions for virtual base classes.
3402 for (CXXRecordDecl::base_class_iterator Base = ClassDecl->vbases_begin(),
3403 BaseEnd = ClassDecl->vbases_end();
3404 Base != BaseEnd; ++Base) {
Douglas Gregor0c431c82010-08-29 19:27:27 +00003405 if (!InitializedBases.insert(Context.getCanonicalType(Base->getType()))) {
3406 SawLastInitializer
3407 = NumInitializers > 0 &&
3408 Initializers[NumInitializers - 1]->isBaseInitializer() &&
3409 Context.hasSameUnqualifiedType(Base->getType(),
3410 QualType(Initializers[NumInitializers - 1]->getBaseClass(), 0));
Douglas Gregor0133f522010-08-28 00:00:50 +00003411 continue;
Douglas Gregor0c431c82010-08-29 19:27:27 +00003412 }
Douglas Gregor0133f522010-08-28 00:00:50 +00003413
3414 CodeCompletionString *Pattern = new CodeCompletionString;
3415 Pattern->AddTypedTextChunk(
3416 Base->getType().getAsString(Context.PrintingPolicy));
3417 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
3418 Pattern->AddPlaceholderChunk("args");
3419 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
Douglas Gregor0c431c82010-08-29 19:27:27 +00003420 Results.AddResult(CodeCompletionResult(Pattern,
3421 SawLastInitializer? CCP_NextInitializer
3422 : CCP_MemberDeclaration));
3423 SawLastInitializer = false;
Douglas Gregor0133f522010-08-28 00:00:50 +00003424 }
3425
3426 // Add completions for members.
3427 for (CXXRecordDecl::field_iterator Field = ClassDecl->field_begin(),
3428 FieldEnd = ClassDecl->field_end();
3429 Field != FieldEnd; ++Field) {
Douglas Gregor0c431c82010-08-29 19:27:27 +00003430 if (!InitializedFields.insert(cast<FieldDecl>(Field->getCanonicalDecl()))) {
3431 SawLastInitializer
3432 = NumInitializers > 0 &&
3433 Initializers[NumInitializers - 1]->isMemberInitializer() &&
3434 Initializers[NumInitializers - 1]->getMember() == *Field;
Douglas Gregor0133f522010-08-28 00:00:50 +00003435 continue;
Douglas Gregor0c431c82010-08-29 19:27:27 +00003436 }
Douglas Gregor0133f522010-08-28 00:00:50 +00003437
3438 if (!Field->getDeclName())
3439 continue;
3440
3441 CodeCompletionString *Pattern = new CodeCompletionString;
3442 Pattern->AddTypedTextChunk(Field->getIdentifier()->getName());
3443 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
3444 Pattern->AddPlaceholderChunk("args");
3445 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
Douglas Gregor0c431c82010-08-29 19:27:27 +00003446 Results.AddResult(CodeCompletionResult(Pattern,
3447 SawLastInitializer? CCP_NextInitializer
Douglas Gregora67e03f2010-09-09 21:42:20 +00003448 : CCP_MemberDeclaration,
3449 CXCursor_MemberRef));
Douglas Gregor0c431c82010-08-29 19:27:27 +00003450 SawLastInitializer = false;
Douglas Gregor0133f522010-08-28 00:00:50 +00003451 }
3452 Results.ExitScope();
3453
3454 HandleCodeCompleteResults(this, CodeCompleter,
3455 CodeCompletionContext::CCC_Name,
3456 Results.data(), Results.size());
3457}
3458
Douglas Gregorb6ac2452010-01-13 21:24:21 +00003459// Macro that expands to @Keyword or Keyword, depending on whether NeedAt is
3460// true or false.
3461#define OBJC_AT_KEYWORD_NAME(NeedAt,Keyword) NeedAt? "@" #Keyword : #Keyword
Douglas Gregorbca403c2010-01-13 23:51:12 +00003462static void AddObjCImplementationResults(const LangOptions &LangOpts,
Douglas Gregorb6ac2452010-01-13 21:24:21 +00003463 ResultBuilder &Results,
3464 bool NeedAt) {
John McCall0a2c5e22010-08-25 06:19:51 +00003465 typedef CodeCompletionResult Result;
Douglas Gregorb6ac2452010-01-13 21:24:21 +00003466 // Since we have an implementation, we can end it.
Douglas Gregora4477812010-01-14 16:01:26 +00003467 Results.AddResult(Result(OBJC_AT_KEYWORD_NAME(NeedAt,end)));
Douglas Gregorb6ac2452010-01-13 21:24:21 +00003468
3469 CodeCompletionString *Pattern = 0;
3470 if (LangOpts.ObjC2) {
3471 // @dynamic
3472 Pattern = new CodeCompletionString;
3473 Pattern->AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt,dynamic));
3474 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
3475 Pattern->AddPlaceholderChunk("property");
Douglas Gregora4477812010-01-14 16:01:26 +00003476 Results.AddResult(Result(Pattern));
Douglas Gregorb6ac2452010-01-13 21:24:21 +00003477
3478 // @synthesize
3479 Pattern = new CodeCompletionString;
3480 Pattern->AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt,synthesize));
3481 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
3482 Pattern->AddPlaceholderChunk("property");
Douglas Gregora4477812010-01-14 16:01:26 +00003483 Results.AddResult(Result(Pattern));
Douglas Gregorb6ac2452010-01-13 21:24:21 +00003484 }
3485}
3486
Douglas Gregorbca403c2010-01-13 23:51:12 +00003487static void AddObjCInterfaceResults(const LangOptions &LangOpts,
Douglas Gregorb6ac2452010-01-13 21:24:21 +00003488 ResultBuilder &Results,
3489 bool NeedAt) {
John McCall0a2c5e22010-08-25 06:19:51 +00003490 typedef CodeCompletionResult Result;
Douglas Gregorb6ac2452010-01-13 21:24:21 +00003491
3492 // Since we have an interface or protocol, we can end it.
Douglas Gregora4477812010-01-14 16:01:26 +00003493 Results.AddResult(Result(OBJC_AT_KEYWORD_NAME(NeedAt,end)));
Douglas Gregorb6ac2452010-01-13 21:24:21 +00003494
3495 if (LangOpts.ObjC2) {
3496 // @property
Douglas Gregora4477812010-01-14 16:01:26 +00003497 Results.AddResult(Result(OBJC_AT_KEYWORD_NAME(NeedAt,property)));
Douglas Gregorb6ac2452010-01-13 21:24:21 +00003498
3499 // @required
Douglas Gregora4477812010-01-14 16:01:26 +00003500 Results.AddResult(Result(OBJC_AT_KEYWORD_NAME(NeedAt,required)));
Douglas Gregorb6ac2452010-01-13 21:24:21 +00003501
3502 // @optional
Douglas Gregora4477812010-01-14 16:01:26 +00003503 Results.AddResult(Result(OBJC_AT_KEYWORD_NAME(NeedAt,optional)));
Douglas Gregorb6ac2452010-01-13 21:24:21 +00003504 }
3505}
3506
Douglas Gregorbca403c2010-01-13 23:51:12 +00003507static void AddObjCTopLevelResults(ResultBuilder &Results, bool NeedAt) {
John McCall0a2c5e22010-08-25 06:19:51 +00003508 typedef CodeCompletionResult Result;
Douglas Gregorb6ac2452010-01-13 21:24:21 +00003509 CodeCompletionString *Pattern = 0;
3510
3511 // @class name ;
3512 Pattern = new CodeCompletionString;
3513 Pattern->AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt,class));
3514 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
Douglas Gregorc8bddde2010-05-28 00:22:41 +00003515 Pattern->AddPlaceholderChunk("name");
Douglas Gregora4477812010-01-14 16:01:26 +00003516 Results.AddResult(Result(Pattern));
Douglas Gregorb6ac2452010-01-13 21:24:21 +00003517
Douglas Gregorc8bddde2010-05-28 00:22:41 +00003518 if (Results.includeCodePatterns()) {
3519 // @interface name
3520 // FIXME: Could introduce the whole pattern, including superclasses and
3521 // such.
3522 Pattern = new CodeCompletionString;
3523 Pattern->AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt,interface));
3524 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
3525 Pattern->AddPlaceholderChunk("class");
3526 Results.AddResult(Result(Pattern));
Douglas Gregorb6ac2452010-01-13 21:24:21 +00003527
Douglas Gregorc8bddde2010-05-28 00:22:41 +00003528 // @protocol name
3529 Pattern = new CodeCompletionString;
3530 Pattern->AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt,protocol));
3531 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
3532 Pattern->AddPlaceholderChunk("protocol");
3533 Results.AddResult(Result(Pattern));
3534
3535 // @implementation name
3536 Pattern = new CodeCompletionString;
3537 Pattern->AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt,implementation));
3538 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
3539 Pattern->AddPlaceholderChunk("class");
3540 Results.AddResult(Result(Pattern));
3541 }
Douglas Gregorb6ac2452010-01-13 21:24:21 +00003542
3543 // @compatibility_alias name
3544 Pattern = new CodeCompletionString;
3545 Pattern->AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt,compatibility_alias));
3546 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
3547 Pattern->AddPlaceholderChunk("alias");
3548 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
3549 Pattern->AddPlaceholderChunk("class");
Douglas Gregora4477812010-01-14 16:01:26 +00003550 Results.AddResult(Result(Pattern));
Douglas Gregorb6ac2452010-01-13 21:24:21 +00003551}
3552
John McCalld226f652010-08-21 09:40:31 +00003553void Sema::CodeCompleteObjCAtDirective(Scope *S, Decl *ObjCImpDecl,
Douglas Gregorc464ae82009-12-07 09:27:33 +00003554 bool InInterface) {
John McCall0a2c5e22010-08-25 06:19:51 +00003555 typedef CodeCompletionResult Result;
Douglas Gregorc464ae82009-12-07 09:27:33 +00003556 ResultBuilder Results(*this);
3557 Results.EnterNewScope();
Douglas Gregorb6ac2452010-01-13 21:24:21 +00003558 if (ObjCImpDecl)
Douglas Gregorbca403c2010-01-13 23:51:12 +00003559 AddObjCImplementationResults(getLangOptions(), Results, false);
Douglas Gregorb6ac2452010-01-13 21:24:21 +00003560 else if (InInterface)
Douglas Gregorbca403c2010-01-13 23:51:12 +00003561 AddObjCInterfaceResults(getLangOptions(), Results, false);
Douglas Gregorb6ac2452010-01-13 21:24:21 +00003562 else
Douglas Gregorbca403c2010-01-13 23:51:12 +00003563 AddObjCTopLevelResults(Results, false);
Douglas Gregorc464ae82009-12-07 09:27:33 +00003564 Results.ExitScope();
Douglas Gregore6b1bb62010-08-11 21:23:17 +00003565 HandleCodeCompleteResults(this, CodeCompleter,
3566 CodeCompletionContext::CCC_Other,
3567 Results.data(),Results.size());
Douglas Gregorc464ae82009-12-07 09:27:33 +00003568}
3569
Douglas Gregorbca403c2010-01-13 23:51:12 +00003570static void AddObjCExpressionResults(ResultBuilder &Results, bool NeedAt) {
John McCall0a2c5e22010-08-25 06:19:51 +00003571 typedef CodeCompletionResult Result;
Douglas Gregor9a0c85e2009-12-07 09:51:25 +00003572 CodeCompletionString *Pattern = 0;
3573
3574 // @encode ( type-name )
3575 Pattern = new CodeCompletionString;
Douglas Gregorb6ac2452010-01-13 21:24:21 +00003576 Pattern->AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt,encode));
Douglas Gregor9a0c85e2009-12-07 09:51:25 +00003577 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
3578 Pattern->AddPlaceholderChunk("type-name");
3579 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
Douglas Gregora4477812010-01-14 16:01:26 +00003580 Results.AddResult(Result(Pattern));
Douglas Gregor9a0c85e2009-12-07 09:51:25 +00003581
3582 // @protocol ( protocol-name )
3583 Pattern = new CodeCompletionString;
Douglas Gregorb6ac2452010-01-13 21:24:21 +00003584 Pattern->AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt,protocol));
Douglas Gregor9a0c85e2009-12-07 09:51:25 +00003585 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
3586 Pattern->AddPlaceholderChunk("protocol-name");
3587 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
Douglas Gregora4477812010-01-14 16:01:26 +00003588 Results.AddResult(Result(Pattern));
Douglas Gregor9a0c85e2009-12-07 09:51:25 +00003589
3590 // @selector ( selector )
3591 Pattern = new CodeCompletionString;
Douglas Gregorb6ac2452010-01-13 21:24:21 +00003592 Pattern->AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt,selector));
Douglas Gregor9a0c85e2009-12-07 09:51:25 +00003593 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
3594 Pattern->AddPlaceholderChunk("selector");
3595 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
Douglas Gregora4477812010-01-14 16:01:26 +00003596 Results.AddResult(Result(Pattern));
Douglas Gregor9a0c85e2009-12-07 09:51:25 +00003597}
3598
Douglas Gregorbca403c2010-01-13 23:51:12 +00003599static void AddObjCStatementResults(ResultBuilder &Results, bool NeedAt) {
John McCall0a2c5e22010-08-25 06:19:51 +00003600 typedef CodeCompletionResult Result;
Douglas Gregor9a0c85e2009-12-07 09:51:25 +00003601 CodeCompletionString *Pattern = 0;
Douglas Gregorb6ac2452010-01-13 21:24:21 +00003602
Douglas Gregorc8bddde2010-05-28 00:22:41 +00003603 if (Results.includeCodePatterns()) {
3604 // @try { statements } @catch ( declaration ) { statements } @finally
3605 // { statements }
3606 Pattern = new CodeCompletionString;
3607 Pattern->AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt,try));
3608 Pattern->AddChunk(CodeCompletionString::CK_LeftBrace);
3609 Pattern->AddPlaceholderChunk("statements");
3610 Pattern->AddChunk(CodeCompletionString::CK_RightBrace);
3611 Pattern->AddTextChunk("@catch");
3612 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
3613 Pattern->AddPlaceholderChunk("parameter");
3614 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
3615 Pattern->AddChunk(CodeCompletionString::CK_LeftBrace);
3616 Pattern->AddPlaceholderChunk("statements");
3617 Pattern->AddChunk(CodeCompletionString::CK_RightBrace);
3618 Pattern->AddTextChunk("@finally");
3619 Pattern->AddChunk(CodeCompletionString::CK_LeftBrace);
3620 Pattern->AddPlaceholderChunk("statements");
3621 Pattern->AddChunk(CodeCompletionString::CK_RightBrace);
3622 Results.AddResult(Result(Pattern));
3623 }
Douglas Gregorb6ac2452010-01-13 21:24:21 +00003624
Douglas Gregor9a0c85e2009-12-07 09:51:25 +00003625 // @throw
3626 Pattern = new CodeCompletionString;
Douglas Gregorb6ac2452010-01-13 21:24:21 +00003627 Pattern->AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt,throw));
Douglas Gregor834389b2010-01-12 06:38:28 +00003628 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
Douglas Gregor9a0c85e2009-12-07 09:51:25 +00003629 Pattern->AddPlaceholderChunk("expression");
Douglas Gregora4477812010-01-14 16:01:26 +00003630 Results.AddResult(Result(Pattern));
Douglas Gregorb6ac2452010-01-13 21:24:21 +00003631
Douglas Gregorc8bddde2010-05-28 00:22:41 +00003632 if (Results.includeCodePatterns()) {
3633 // @synchronized ( expression ) { statements }
3634 Pattern = new CodeCompletionString;
3635 Pattern->AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt,synchronized));
3636 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
3637 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
3638 Pattern->AddPlaceholderChunk("expression");
3639 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
3640 Pattern->AddChunk(CodeCompletionString::CK_LeftBrace);
3641 Pattern->AddPlaceholderChunk("statements");
3642 Pattern->AddChunk(CodeCompletionString::CK_RightBrace);
3643 Results.AddResult(Result(Pattern));
3644 }
Douglas Gregorb6ac2452010-01-13 21:24:21 +00003645}
Douglas Gregor9a0c85e2009-12-07 09:51:25 +00003646
Douglas Gregorbca403c2010-01-13 23:51:12 +00003647static void AddObjCVisibilityResults(const LangOptions &LangOpts,
Douglas Gregorc38c3e12010-01-13 21:54:15 +00003648 ResultBuilder &Results,
3649 bool NeedAt) {
John McCall0a2c5e22010-08-25 06:19:51 +00003650 typedef CodeCompletionResult Result;
Douglas Gregora4477812010-01-14 16:01:26 +00003651 Results.AddResult(Result(OBJC_AT_KEYWORD_NAME(NeedAt,private)));
3652 Results.AddResult(Result(OBJC_AT_KEYWORD_NAME(NeedAt,protected)));
3653 Results.AddResult(Result(OBJC_AT_KEYWORD_NAME(NeedAt,public)));
Douglas Gregorc38c3e12010-01-13 21:54:15 +00003654 if (LangOpts.ObjC2)
Douglas Gregora4477812010-01-14 16:01:26 +00003655 Results.AddResult(Result(OBJC_AT_KEYWORD_NAME(NeedAt,package)));
Douglas Gregorc38c3e12010-01-13 21:54:15 +00003656}
3657
3658void Sema::CodeCompleteObjCAtVisibility(Scope *S) {
3659 ResultBuilder Results(*this);
3660 Results.EnterNewScope();
Douglas Gregorbca403c2010-01-13 23:51:12 +00003661 AddObjCVisibilityResults(getLangOptions(), Results, false);
Douglas Gregorc38c3e12010-01-13 21:54:15 +00003662 Results.ExitScope();
Douglas Gregore6b1bb62010-08-11 21:23:17 +00003663 HandleCodeCompleteResults(this, CodeCompleter,
3664 CodeCompletionContext::CCC_Other,
3665 Results.data(),Results.size());
Douglas Gregorc38c3e12010-01-13 21:54:15 +00003666}
3667
3668void Sema::CodeCompleteObjCAtStatement(Scope *S) {
Douglas Gregorb6ac2452010-01-13 21:24:21 +00003669 ResultBuilder Results(*this);
3670 Results.EnterNewScope();
Douglas Gregorbca403c2010-01-13 23:51:12 +00003671 AddObjCStatementResults(Results, false);
3672 AddObjCExpressionResults(Results, false);
Douglas Gregor9a0c85e2009-12-07 09:51:25 +00003673 Results.ExitScope();
Douglas Gregore6b1bb62010-08-11 21:23:17 +00003674 HandleCodeCompleteResults(this, CodeCompleter,
3675 CodeCompletionContext::CCC_Other,
3676 Results.data(),Results.size());
Douglas Gregor9a0c85e2009-12-07 09:51:25 +00003677}
3678
3679void Sema::CodeCompleteObjCAtExpression(Scope *S) {
3680 ResultBuilder Results(*this);
3681 Results.EnterNewScope();
Douglas Gregorbca403c2010-01-13 23:51:12 +00003682 AddObjCExpressionResults(Results, false);
Douglas Gregor9a0c85e2009-12-07 09:51:25 +00003683 Results.ExitScope();
Douglas Gregore6b1bb62010-08-11 21:23:17 +00003684 HandleCodeCompleteResults(this, CodeCompleter,
3685 CodeCompletionContext::CCC_Other,
3686 Results.data(),Results.size());
Douglas Gregor9a0c85e2009-12-07 09:51:25 +00003687}
3688
Douglas Gregor988358f2009-11-19 00:14:45 +00003689/// \brief Determine whether the addition of the given flag to an Objective-C
3690/// property's attributes will cause a conflict.
3691static bool ObjCPropertyFlagConflicts(unsigned Attributes, unsigned NewFlag) {
3692 // Check if we've already added this flag.
3693 if (Attributes & NewFlag)
3694 return true;
3695
3696 Attributes |= NewFlag;
3697
3698 // Check for collisions with "readonly".
3699 if ((Attributes & ObjCDeclSpec::DQ_PR_readonly) &&
3700 (Attributes & (ObjCDeclSpec::DQ_PR_readwrite |
3701 ObjCDeclSpec::DQ_PR_assign |
3702 ObjCDeclSpec::DQ_PR_copy |
3703 ObjCDeclSpec::DQ_PR_retain)))
3704 return true;
3705
3706 // Check for more than one of { assign, copy, retain }.
3707 unsigned AssignCopyRetMask = Attributes & (ObjCDeclSpec::DQ_PR_assign |
3708 ObjCDeclSpec::DQ_PR_copy |
3709 ObjCDeclSpec::DQ_PR_retain);
3710 if (AssignCopyRetMask &&
3711 AssignCopyRetMask != ObjCDeclSpec::DQ_PR_assign &&
3712 AssignCopyRetMask != ObjCDeclSpec::DQ_PR_copy &&
3713 AssignCopyRetMask != ObjCDeclSpec::DQ_PR_retain)
3714 return true;
3715
3716 return false;
3717}
3718
Douglas Gregora93b1082009-11-18 23:08:07 +00003719void Sema::CodeCompleteObjCPropertyFlags(Scope *S, ObjCDeclSpec &ODS) {
Steve Naroffece8e712009-10-08 21:55:05 +00003720 if (!CodeCompleter)
3721 return;
Douglas Gregord3c68542009-11-19 01:08:35 +00003722
Steve Naroffece8e712009-10-08 21:55:05 +00003723 unsigned Attributes = ODS.getPropertyAttributes();
3724
John McCall0a2c5e22010-08-25 06:19:51 +00003725 typedef CodeCompletionResult Result;
Steve Naroffece8e712009-10-08 21:55:05 +00003726 ResultBuilder Results(*this);
3727 Results.EnterNewScope();
Douglas Gregor988358f2009-11-19 00:14:45 +00003728 if (!ObjCPropertyFlagConflicts(Attributes, ObjCDeclSpec::DQ_PR_readonly))
John McCall0a2c5e22010-08-25 06:19:51 +00003729 Results.AddResult(CodeCompletionResult("readonly"));
Douglas Gregor988358f2009-11-19 00:14:45 +00003730 if (!ObjCPropertyFlagConflicts(Attributes, ObjCDeclSpec::DQ_PR_assign))
John McCall0a2c5e22010-08-25 06:19:51 +00003731 Results.AddResult(CodeCompletionResult("assign"));
Douglas Gregor988358f2009-11-19 00:14:45 +00003732 if (!ObjCPropertyFlagConflicts(Attributes, ObjCDeclSpec::DQ_PR_readwrite))
John McCall0a2c5e22010-08-25 06:19:51 +00003733 Results.AddResult(CodeCompletionResult("readwrite"));
Douglas Gregor988358f2009-11-19 00:14:45 +00003734 if (!ObjCPropertyFlagConflicts(Attributes, ObjCDeclSpec::DQ_PR_retain))
John McCall0a2c5e22010-08-25 06:19:51 +00003735 Results.AddResult(CodeCompletionResult("retain"));
Douglas Gregor988358f2009-11-19 00:14:45 +00003736 if (!ObjCPropertyFlagConflicts(Attributes, ObjCDeclSpec::DQ_PR_copy))
John McCall0a2c5e22010-08-25 06:19:51 +00003737 Results.AddResult(CodeCompletionResult("copy"));
Douglas Gregor988358f2009-11-19 00:14:45 +00003738 if (!ObjCPropertyFlagConflicts(Attributes, ObjCDeclSpec::DQ_PR_nonatomic))
John McCall0a2c5e22010-08-25 06:19:51 +00003739 Results.AddResult(CodeCompletionResult("nonatomic"));
Douglas Gregor988358f2009-11-19 00:14:45 +00003740 if (!ObjCPropertyFlagConflicts(Attributes, ObjCDeclSpec::DQ_PR_setter)) {
Douglas Gregor54f01612009-11-19 00:01:57 +00003741 CodeCompletionString *Setter = new CodeCompletionString;
3742 Setter->AddTypedTextChunk("setter");
3743 Setter->AddTextChunk(" = ");
3744 Setter->AddPlaceholderChunk("method");
John McCall0a2c5e22010-08-25 06:19:51 +00003745 Results.AddResult(CodeCompletionResult(Setter));
Douglas Gregor54f01612009-11-19 00:01:57 +00003746 }
Douglas Gregor988358f2009-11-19 00:14:45 +00003747 if (!ObjCPropertyFlagConflicts(Attributes, ObjCDeclSpec::DQ_PR_getter)) {
Douglas Gregor54f01612009-11-19 00:01:57 +00003748 CodeCompletionString *Getter = new CodeCompletionString;
3749 Getter->AddTypedTextChunk("getter");
3750 Getter->AddTextChunk(" = ");
3751 Getter->AddPlaceholderChunk("method");
John McCall0a2c5e22010-08-25 06:19:51 +00003752 Results.AddResult(CodeCompletionResult(Getter));
Douglas Gregor54f01612009-11-19 00:01:57 +00003753 }
Steve Naroffece8e712009-10-08 21:55:05 +00003754 Results.ExitScope();
Douglas Gregore6b1bb62010-08-11 21:23:17 +00003755 HandleCodeCompleteResults(this, CodeCompleter,
3756 CodeCompletionContext::CCC_Other,
3757 Results.data(),Results.size());
Steve Naroffece8e712009-10-08 21:55:05 +00003758}
Steve Naroffc4df6d22009-11-07 02:08:14 +00003759
Douglas Gregor4ad96852009-11-19 07:41:15 +00003760/// \brief Descripts the kind of Objective-C method that we want to find
3761/// via code completion.
3762enum ObjCMethodKind {
3763 MK_Any, //< Any kind of method, provided it means other specified criteria.
3764 MK_ZeroArgSelector, //< Zero-argument (unary) selector.
3765 MK_OneArgSelector //< One-argument selector.
3766};
3767
Douglas Gregor458433d2010-08-26 15:07:07 +00003768static bool isAcceptableObjCSelector(Selector Sel,
3769 ObjCMethodKind WantKind,
3770 IdentifierInfo **SelIdents,
3771 unsigned NumSelIdents) {
3772 if (NumSelIdents > Sel.getNumArgs())
3773 return false;
3774
3775 switch (WantKind) {
3776 case MK_Any: break;
3777 case MK_ZeroArgSelector: return Sel.isUnarySelector();
3778 case MK_OneArgSelector: return Sel.getNumArgs() == 1;
3779 }
3780
3781 for (unsigned I = 0; I != NumSelIdents; ++I)
3782 if (SelIdents[I] != Sel.getIdentifierInfoForSlot(I))
3783 return false;
3784
3785 return true;
3786}
3787
Douglas Gregor4ad96852009-11-19 07:41:15 +00003788static bool isAcceptableObjCMethod(ObjCMethodDecl *Method,
3789 ObjCMethodKind WantKind,
3790 IdentifierInfo **SelIdents,
3791 unsigned NumSelIdents) {
Douglas Gregor458433d2010-08-26 15:07:07 +00003792 return isAcceptableObjCSelector(Method->getSelector(), WantKind, SelIdents,
3793 NumSelIdents);
Douglas Gregor4ad96852009-11-19 07:41:15 +00003794}
3795
Douglas Gregor36ecb042009-11-17 23:22:23 +00003796/// \brief Add all of the Objective-C methods in the given Objective-C
3797/// container to the set of results.
3798///
3799/// The container will be a class, protocol, category, or implementation of
3800/// any of the above. This mether will recurse to include methods from
3801/// the superclasses of classes along with their categories, protocols, and
3802/// implementations.
3803///
3804/// \param Container the container in which we'll look to find methods.
3805///
3806/// \param WantInstance whether to add instance methods (only); if false, this
3807/// routine will add factory methods (only).
3808///
3809/// \param CurContext the context in which we're performing the lookup that
3810/// finds methods.
3811///
3812/// \param Results the structure into which we'll add results.
3813static void AddObjCMethods(ObjCContainerDecl *Container,
3814 bool WantInstanceMethods,
Douglas Gregor4ad96852009-11-19 07:41:15 +00003815 ObjCMethodKind WantKind,
Douglas Gregord3c68542009-11-19 01:08:35 +00003816 IdentifierInfo **SelIdents,
3817 unsigned NumSelIdents,
Douglas Gregor36ecb042009-11-17 23:22:23 +00003818 DeclContext *CurContext,
Douglas Gregor408be5a2010-08-25 01:08:01 +00003819 ResultBuilder &Results,
3820 bool InOriginalClass = true) {
John McCall0a2c5e22010-08-25 06:19:51 +00003821 typedef CodeCompletionResult Result;
Douglas Gregor36ecb042009-11-17 23:22:23 +00003822 for (ObjCContainerDecl::method_iterator M = Container->meth_begin(),
3823 MEnd = Container->meth_end();
3824 M != MEnd; ++M) {
Douglas Gregord3c68542009-11-19 01:08:35 +00003825 if ((*M)->isInstanceMethod() == WantInstanceMethods) {
3826 // Check whether the selector identifiers we've been given are a
3827 // subset of the identifiers for this particular method.
Douglas Gregor4ad96852009-11-19 07:41:15 +00003828 if (!isAcceptableObjCMethod(*M, WantKind, SelIdents, NumSelIdents))
Douglas Gregord3c68542009-11-19 01:08:35 +00003829 continue;
Douglas Gregor4ad96852009-11-19 07:41:15 +00003830
Douglas Gregord3c68542009-11-19 01:08:35 +00003831 Result R = Result(*M, 0);
3832 R.StartParameter = NumSelIdents;
Douglas Gregor4ad96852009-11-19 07:41:15 +00003833 R.AllParametersAreInformative = (WantKind != MK_Any);
Douglas Gregor408be5a2010-08-25 01:08:01 +00003834 if (!InOriginalClass)
3835 R.Priority += CCD_InBaseClass;
Douglas Gregord3c68542009-11-19 01:08:35 +00003836 Results.MaybeAddResult(R, CurContext);
3837 }
Douglas Gregor36ecb042009-11-17 23:22:23 +00003838 }
3839
3840 ObjCInterfaceDecl *IFace = dyn_cast<ObjCInterfaceDecl>(Container);
3841 if (!IFace)
3842 return;
3843
3844 // Add methods in protocols.
3845 const ObjCList<ObjCProtocolDecl> &Protocols= IFace->getReferencedProtocols();
3846 for (ObjCList<ObjCProtocolDecl>::iterator I = Protocols.begin(),
3847 E = Protocols.end();
3848 I != E; ++I)
Douglas Gregor4ad96852009-11-19 07:41:15 +00003849 AddObjCMethods(*I, WantInstanceMethods, WantKind, SelIdents, NumSelIdents,
Douglas Gregor408be5a2010-08-25 01:08:01 +00003850 CurContext, Results, false);
Douglas Gregor36ecb042009-11-17 23:22:23 +00003851
3852 // Add methods in categories.
3853 for (ObjCCategoryDecl *CatDecl = IFace->getCategoryList(); CatDecl;
3854 CatDecl = CatDecl->getNextClassCategory()) {
Douglas Gregor4ad96852009-11-19 07:41:15 +00003855 AddObjCMethods(CatDecl, WantInstanceMethods, WantKind, SelIdents,
Douglas Gregor408be5a2010-08-25 01:08:01 +00003856 NumSelIdents, CurContext, Results, InOriginalClass);
Douglas Gregor36ecb042009-11-17 23:22:23 +00003857
3858 // Add a categories protocol methods.
3859 const ObjCList<ObjCProtocolDecl> &Protocols
3860 = CatDecl->getReferencedProtocols();
3861 for (ObjCList<ObjCProtocolDecl>::iterator I = Protocols.begin(),
3862 E = Protocols.end();
3863 I != E; ++I)
Douglas Gregor4ad96852009-11-19 07:41:15 +00003864 AddObjCMethods(*I, WantInstanceMethods, WantKind, SelIdents,
Douglas Gregor408be5a2010-08-25 01:08:01 +00003865 NumSelIdents, CurContext, Results, false);
Douglas Gregor36ecb042009-11-17 23:22:23 +00003866
3867 // Add methods in category implementations.
3868 if (ObjCCategoryImplDecl *Impl = CatDecl->getImplementation())
Douglas Gregor4ad96852009-11-19 07:41:15 +00003869 AddObjCMethods(Impl, WantInstanceMethods, WantKind, SelIdents,
Douglas Gregor408be5a2010-08-25 01:08:01 +00003870 NumSelIdents, CurContext, Results, InOriginalClass);
Douglas Gregor36ecb042009-11-17 23:22:23 +00003871 }
3872
3873 // Add methods in superclass.
3874 if (IFace->getSuperClass())
Douglas Gregor4ad96852009-11-19 07:41:15 +00003875 AddObjCMethods(IFace->getSuperClass(), WantInstanceMethods, WantKind,
Douglas Gregor408be5a2010-08-25 01:08:01 +00003876 SelIdents, NumSelIdents, CurContext, Results, false);
Douglas Gregor36ecb042009-11-17 23:22:23 +00003877
3878 // Add methods in our implementation, if any.
3879 if (ObjCImplementationDecl *Impl = IFace->getImplementation())
Douglas Gregor4ad96852009-11-19 07:41:15 +00003880 AddObjCMethods(Impl, WantInstanceMethods, WantKind, SelIdents,
Douglas Gregor408be5a2010-08-25 01:08:01 +00003881 NumSelIdents, CurContext, Results, InOriginalClass);
Douglas Gregor4ad96852009-11-19 07:41:15 +00003882}
3883
3884
John McCalld226f652010-08-21 09:40:31 +00003885void Sema::CodeCompleteObjCPropertyGetter(Scope *S, Decl *ClassDecl,
3886 Decl **Methods,
Douglas Gregor4ad96852009-11-19 07:41:15 +00003887 unsigned NumMethods) {
John McCall0a2c5e22010-08-25 06:19:51 +00003888 typedef CodeCompletionResult Result;
Douglas Gregor4ad96852009-11-19 07:41:15 +00003889
3890 // Try to find the interface where getters might live.
John McCalld226f652010-08-21 09:40:31 +00003891 ObjCInterfaceDecl *Class = dyn_cast_or_null<ObjCInterfaceDecl>(ClassDecl);
Douglas Gregor4ad96852009-11-19 07:41:15 +00003892 if (!Class) {
3893 if (ObjCCategoryDecl *Category
John McCalld226f652010-08-21 09:40:31 +00003894 = dyn_cast_or_null<ObjCCategoryDecl>(ClassDecl))
Douglas Gregor4ad96852009-11-19 07:41:15 +00003895 Class = Category->getClassInterface();
3896
3897 if (!Class)
3898 return;
3899 }
3900
3901 // Find all of the potential getters.
3902 ResultBuilder Results(*this);
3903 Results.EnterNewScope();
3904
3905 // FIXME: We need to do this because Objective-C methods don't get
3906 // pushed into DeclContexts early enough. Argh!
3907 for (unsigned I = 0; I != NumMethods; ++I) {
3908 if (ObjCMethodDecl *Method
John McCalld226f652010-08-21 09:40:31 +00003909 = dyn_cast_or_null<ObjCMethodDecl>(Methods[I]))
Douglas Gregor4ad96852009-11-19 07:41:15 +00003910 if (Method->isInstanceMethod() &&
3911 isAcceptableObjCMethod(Method, MK_ZeroArgSelector, 0, 0)) {
3912 Result R = Result(Method, 0);
3913 R.AllParametersAreInformative = true;
3914 Results.MaybeAddResult(R, CurContext);
3915 }
3916 }
3917
3918 AddObjCMethods(Class, true, MK_ZeroArgSelector, 0, 0, CurContext, Results);
3919 Results.ExitScope();
Douglas Gregore6b1bb62010-08-11 21:23:17 +00003920 HandleCodeCompleteResults(this, CodeCompleter,
3921 CodeCompletionContext::CCC_Other,
3922 Results.data(),Results.size());
Douglas Gregor4ad96852009-11-19 07:41:15 +00003923}
3924
John McCalld226f652010-08-21 09:40:31 +00003925void Sema::CodeCompleteObjCPropertySetter(Scope *S, Decl *ObjCImplDecl,
3926 Decl **Methods,
Douglas Gregor4ad96852009-11-19 07:41:15 +00003927 unsigned NumMethods) {
John McCall0a2c5e22010-08-25 06:19:51 +00003928 typedef CodeCompletionResult Result;
Douglas Gregor4ad96852009-11-19 07:41:15 +00003929
3930 // Try to find the interface where setters might live.
3931 ObjCInterfaceDecl *Class
John McCalld226f652010-08-21 09:40:31 +00003932 = dyn_cast_or_null<ObjCInterfaceDecl>(ObjCImplDecl);
Douglas Gregor4ad96852009-11-19 07:41:15 +00003933 if (!Class) {
3934 if (ObjCCategoryDecl *Category
John McCalld226f652010-08-21 09:40:31 +00003935 = dyn_cast_or_null<ObjCCategoryDecl>(ObjCImplDecl))
Douglas Gregor4ad96852009-11-19 07:41:15 +00003936 Class = Category->getClassInterface();
3937
3938 if (!Class)
3939 return;
3940 }
3941
3942 // Find all of the potential getters.
3943 ResultBuilder Results(*this);
3944 Results.EnterNewScope();
3945
3946 // FIXME: We need to do this because Objective-C methods don't get
3947 // pushed into DeclContexts early enough. Argh!
3948 for (unsigned I = 0; I != NumMethods; ++I) {
3949 if (ObjCMethodDecl *Method
John McCalld226f652010-08-21 09:40:31 +00003950 = dyn_cast_or_null<ObjCMethodDecl>(Methods[I]))
Douglas Gregor4ad96852009-11-19 07:41:15 +00003951 if (Method->isInstanceMethod() &&
3952 isAcceptableObjCMethod(Method, MK_OneArgSelector, 0, 0)) {
3953 Result R = Result(Method, 0);
3954 R.AllParametersAreInformative = true;
3955 Results.MaybeAddResult(R, CurContext);
3956 }
3957 }
3958
3959 AddObjCMethods(Class, true, MK_OneArgSelector, 0, 0, CurContext, Results);
3960
3961 Results.ExitScope();
Douglas Gregore6b1bb62010-08-11 21:23:17 +00003962 HandleCodeCompleteResults(this, CodeCompleter,
3963 CodeCompletionContext::CCC_Other,
3964 Results.data(),Results.size());
Douglas Gregor36ecb042009-11-17 23:22:23 +00003965}
3966
Douglas Gregord32b0222010-08-24 01:06:58 +00003967void Sema::CodeCompleteObjCPassingType(Scope *S, ObjCDeclSpec &DS) {
John McCall0a2c5e22010-08-25 06:19:51 +00003968 typedef CodeCompletionResult Result;
Douglas Gregord32b0222010-08-24 01:06:58 +00003969 ResultBuilder Results(*this);
3970 Results.EnterNewScope();
3971
3972 // Add context-sensitive, Objective-C parameter-passing keywords.
3973 bool AddedInOut = false;
3974 if ((DS.getObjCDeclQualifier() &
3975 (ObjCDeclSpec::DQ_In | ObjCDeclSpec::DQ_Inout)) == 0) {
3976 Results.AddResult("in");
3977 Results.AddResult("inout");
3978 AddedInOut = true;
3979 }
3980 if ((DS.getObjCDeclQualifier() &
3981 (ObjCDeclSpec::DQ_Out | ObjCDeclSpec::DQ_Inout)) == 0) {
3982 Results.AddResult("out");
3983 if (!AddedInOut)
3984 Results.AddResult("inout");
3985 }
3986 if ((DS.getObjCDeclQualifier() &
3987 (ObjCDeclSpec::DQ_Bycopy | ObjCDeclSpec::DQ_Byref |
3988 ObjCDeclSpec::DQ_Oneway)) == 0) {
3989 Results.AddResult("bycopy");
3990 Results.AddResult("byref");
3991 Results.AddResult("oneway");
3992 }
3993
3994 // Add various builtin type names and specifiers.
3995 AddOrdinaryNameResults(PCC_Type, S, *this, Results);
3996 Results.ExitScope();
3997
3998 // Add the various type names
3999 Results.setFilter(&ResultBuilder::IsOrdinaryNonValueName);
4000 CodeCompletionDeclConsumer Consumer(Results, CurContext);
4001 LookupVisibleDecls(S, LookupOrdinaryName, Consumer,
4002 CodeCompleter->includeGlobals());
4003
4004 if (CodeCompleter->includeMacros())
4005 AddMacroResults(PP, Results);
4006
4007 HandleCodeCompleteResults(this, CodeCompleter,
4008 CodeCompletionContext::CCC_Type,
4009 Results.data(), Results.size());
4010}
4011
Douglas Gregor22f56992010-04-06 19:22:33 +00004012/// \brief When we have an expression with type "id", we may assume
4013/// that it has some more-specific class type based on knowledge of
4014/// common uses of Objective-C. This routine returns that class type,
4015/// or NULL if no better result could be determined.
4016static ObjCInterfaceDecl *GetAssumedMessageSendExprType(Expr *E) {
4017 ObjCMessageExpr *Msg = dyn_cast<ObjCMessageExpr>(E);
4018 if (!Msg)
4019 return 0;
4020
4021 Selector Sel = Msg->getSelector();
4022 if (Sel.isNull())
4023 return 0;
4024
4025 IdentifierInfo *Id = Sel.getIdentifierInfoForSlot(0);
4026 if (!Id)
4027 return 0;
4028
4029 ObjCMethodDecl *Method = Msg->getMethodDecl();
4030 if (!Method)
4031 return 0;
4032
4033 // Determine the class that we're sending the message to.
Douglas Gregor04badcf2010-04-21 00:45:42 +00004034 ObjCInterfaceDecl *IFace = 0;
4035 switch (Msg->getReceiverKind()) {
4036 case ObjCMessageExpr::Class:
John McCallc12c5bb2010-05-15 11:32:37 +00004037 if (const ObjCObjectType *ObjType
4038 = Msg->getClassReceiver()->getAs<ObjCObjectType>())
4039 IFace = ObjType->getInterface();
Douglas Gregor04badcf2010-04-21 00:45:42 +00004040 break;
4041
4042 case ObjCMessageExpr::Instance: {
4043 QualType T = Msg->getInstanceReceiver()->getType();
4044 if (const ObjCObjectPointerType *Ptr = T->getAs<ObjCObjectPointerType>())
4045 IFace = Ptr->getInterfaceDecl();
4046 break;
4047 }
4048
4049 case ObjCMessageExpr::SuperInstance:
4050 case ObjCMessageExpr::SuperClass:
4051 break;
Douglas Gregor22f56992010-04-06 19:22:33 +00004052 }
4053
4054 if (!IFace)
4055 return 0;
4056
4057 ObjCInterfaceDecl *Super = IFace->getSuperClass();
4058 if (Method->isInstanceMethod())
4059 return llvm::StringSwitch<ObjCInterfaceDecl *>(Id->getName())
4060 .Case("retain", IFace)
4061 .Case("autorelease", IFace)
4062 .Case("copy", IFace)
4063 .Case("copyWithZone", IFace)
4064 .Case("mutableCopy", IFace)
4065 .Case("mutableCopyWithZone", IFace)
4066 .Case("awakeFromCoder", IFace)
4067 .Case("replacementObjectFromCoder", IFace)
4068 .Case("class", IFace)
4069 .Case("classForCoder", IFace)
4070 .Case("superclass", Super)
4071 .Default(0);
4072
4073 return llvm::StringSwitch<ObjCInterfaceDecl *>(Id->getName())
4074 .Case("new", IFace)
4075 .Case("alloc", IFace)
4076 .Case("allocWithZone", IFace)
4077 .Case("class", IFace)
4078 .Case("superclass", Super)
4079 .Default(0);
4080}
4081
Douglas Gregor03d8aec2010-08-27 15:10:57 +00004082// Add a special completion for a message send to "super", which fills in the
4083// most likely case of forwarding all of our arguments to the superclass
4084// function.
4085///
4086/// \param S The semantic analysis object.
4087///
4088/// \param S NeedSuperKeyword Whether we need to prefix this completion with
4089/// the "super" keyword. Otherwise, we just need to provide the arguments.
4090///
4091/// \param SelIdents The identifiers in the selector that have already been
4092/// provided as arguments for a send to "super".
4093///
4094/// \param NumSelIdents The number of identifiers in \p SelIdents.
4095///
4096/// \param Results The set of results to augment.
4097///
4098/// \returns the Objective-C method declaration that would be invoked by
4099/// this "super" completion. If NULL, no completion was added.
4100static ObjCMethodDecl *AddSuperSendCompletion(Sema &S, bool NeedSuperKeyword,
4101 IdentifierInfo **SelIdents,
4102 unsigned NumSelIdents,
4103 ResultBuilder &Results) {
4104 ObjCMethodDecl *CurMethod = S.getCurMethodDecl();
4105 if (!CurMethod)
4106 return 0;
4107
4108 ObjCInterfaceDecl *Class = CurMethod->getClassInterface();
4109 if (!Class)
4110 return 0;
4111
4112 // Try to find a superclass method with the same selector.
4113 ObjCMethodDecl *SuperMethod = 0;
4114 while ((Class = Class->getSuperClass()) && !SuperMethod)
4115 SuperMethod = Class->getMethod(CurMethod->getSelector(),
4116 CurMethod->isInstanceMethod());
4117
4118 if (!SuperMethod)
4119 return 0;
4120
4121 // Check whether the superclass method has the same signature.
4122 if (CurMethod->param_size() != SuperMethod->param_size() ||
4123 CurMethod->isVariadic() != SuperMethod->isVariadic())
4124 return 0;
4125
4126 for (ObjCMethodDecl::param_iterator CurP = CurMethod->param_begin(),
4127 CurPEnd = CurMethod->param_end(),
4128 SuperP = SuperMethod->param_begin();
4129 CurP != CurPEnd; ++CurP, ++SuperP) {
4130 // Make sure the parameter types are compatible.
4131 if (!S.Context.hasSameUnqualifiedType((*CurP)->getType(),
4132 (*SuperP)->getType()))
4133 return 0;
4134
4135 // Make sure we have a parameter name to forward!
4136 if (!(*CurP)->getIdentifier())
4137 return 0;
4138 }
4139
4140 // We have a superclass method. Now, form the send-to-super completion.
4141 CodeCompletionString *Pattern = new CodeCompletionString;
4142
4143 // Give this completion a return type.
4144 AddResultTypeChunk(S.Context, SuperMethod, Pattern);
4145
4146 // If we need the "super" keyword, add it (plus some spacing).
4147 if (NeedSuperKeyword) {
4148 Pattern->AddTypedTextChunk("super");
4149 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
4150 }
4151
4152 Selector Sel = CurMethod->getSelector();
4153 if (Sel.isUnarySelector()) {
4154 if (NeedSuperKeyword)
4155 Pattern->AddTextChunk(Sel.getIdentifierInfoForSlot(0)->getName());
4156 else
4157 Pattern->AddTypedTextChunk(Sel.getIdentifierInfoForSlot(0)->getName());
4158 } else {
4159 ObjCMethodDecl::param_iterator CurP = CurMethod->param_begin();
4160 for (unsigned I = 0, N = Sel.getNumArgs(); I != N; ++I, ++CurP) {
4161 if (I > NumSelIdents)
4162 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
4163
4164 if (I < NumSelIdents)
4165 Pattern->AddInformativeChunk(
4166 Sel.getIdentifierInfoForSlot(I)->getName().str() + ":");
4167 else if (NeedSuperKeyword || I > NumSelIdents) {
4168 Pattern->AddTextChunk(
4169 Sel.getIdentifierInfoForSlot(I)->getName().str() + ":");
4170 Pattern->AddPlaceholderChunk((*CurP)->getIdentifier()->getName());
4171 } else {
4172 Pattern->AddTypedTextChunk(
4173 Sel.getIdentifierInfoForSlot(I)->getName().str() + ":");
4174 Pattern->AddPlaceholderChunk((*CurP)->getIdentifier()->getName());
4175 }
4176 }
4177 }
4178
4179 Results.AddResult(CodeCompletionResult(Pattern, CCP_SuperCompletion,
4180 SuperMethod->isInstanceMethod()
4181 ? CXCursor_ObjCInstanceMethodDecl
4182 : CXCursor_ObjCClassMethodDecl));
4183 return SuperMethod;
4184}
4185
Douglas Gregor8e254cf2010-05-27 23:06:34 +00004186void Sema::CodeCompleteObjCMessageReceiver(Scope *S) {
John McCall0a2c5e22010-08-25 06:19:51 +00004187 typedef CodeCompletionResult Result;
Douglas Gregor8e254cf2010-05-27 23:06:34 +00004188 ResultBuilder Results(*this);
4189
4190 // Find anything that looks like it could be a message receiver.
4191 Results.setFilter(&ResultBuilder::IsObjCMessageReceiver);
4192 CodeCompletionDeclConsumer Consumer(Results, CurContext);
4193 Results.EnterNewScope();
Douglas Gregor8071e422010-08-15 06:18:01 +00004194 LookupVisibleDecls(S, LookupOrdinaryName, Consumer,
4195 CodeCompleter->includeGlobals());
Douglas Gregor8e254cf2010-05-27 23:06:34 +00004196
4197 // If we are in an Objective-C method inside a class that has a superclass,
4198 // add "super" as an option.
4199 if (ObjCMethodDecl *Method = getCurMethodDecl())
4200 if (ObjCInterfaceDecl *Iface = Method->getClassInterface())
Douglas Gregor03d8aec2010-08-27 15:10:57 +00004201 if (Iface->getSuperClass()) {
Douglas Gregor8e254cf2010-05-27 23:06:34 +00004202 Results.AddResult(Result("super"));
Douglas Gregor03d8aec2010-08-27 15:10:57 +00004203
4204 AddSuperSendCompletion(*this, /*NeedSuperKeyword=*/true, 0, 0, Results);
4205 }
Douglas Gregor8e254cf2010-05-27 23:06:34 +00004206
4207 Results.ExitScope();
4208
4209 if (CodeCompleter->includeMacros())
4210 AddMacroResults(PP, Results);
Douglas Gregore6b1bb62010-08-11 21:23:17 +00004211 HandleCodeCompleteResults(this, CodeCompleter,
4212 CodeCompletionContext::CCC_ObjCMessageReceiver,
4213 Results.data(), Results.size());
Douglas Gregor8e254cf2010-05-27 23:06:34 +00004214
4215}
4216
Douglas Gregor2725ca82010-04-21 19:57:20 +00004217void Sema::CodeCompleteObjCSuperMessage(Scope *S, SourceLocation SuperLoc,
4218 IdentifierInfo **SelIdents,
4219 unsigned NumSelIdents) {
4220 ObjCInterfaceDecl *CDecl = 0;
4221 if (ObjCMethodDecl *CurMethod = getCurMethodDecl()) {
4222 // Figure out which interface we're in.
4223 CDecl = CurMethod->getClassInterface();
4224 if (!CDecl)
4225 return;
4226
4227 // Find the superclass of this class.
4228 CDecl = CDecl->getSuperClass();
4229 if (!CDecl)
4230 return;
4231
4232 if (CurMethod->isInstanceMethod()) {
4233 // We are inside an instance method, which means that the message
4234 // send [super ...] is actually calling an instance method on the
4235 // current object. Build the super expression and handle this like
4236 // an instance method.
4237 QualType SuperTy = Context.getObjCInterfaceType(CDecl);
4238 SuperTy = Context.getObjCObjectPointerType(SuperTy);
John McCall60d7b3a2010-08-24 06:29:42 +00004239 ExprResult Super
Douglas Gregor2725ca82010-04-21 19:57:20 +00004240 = Owned(new (Context) ObjCSuperExpr(SuperLoc, SuperTy));
4241 return CodeCompleteObjCInstanceMessage(S, (Expr *)Super.get(),
Douglas Gregor03d8aec2010-08-27 15:10:57 +00004242 SelIdents, NumSelIdents,
4243 /*IsSuper=*/true);
Douglas Gregor2725ca82010-04-21 19:57:20 +00004244 }
4245
4246 // Fall through to send to the superclass in CDecl.
4247 } else {
4248 // "super" may be the name of a type or variable. Figure out which
4249 // it is.
4250 IdentifierInfo *Super = &Context.Idents.get("super");
4251 NamedDecl *ND = LookupSingleName(S, Super, SuperLoc,
4252 LookupOrdinaryName);
4253 if ((CDecl = dyn_cast_or_null<ObjCInterfaceDecl>(ND))) {
4254 // "super" names an interface. Use it.
4255 } else if (TypeDecl *TD = dyn_cast_or_null<TypeDecl>(ND)) {
John McCallc12c5bb2010-05-15 11:32:37 +00004256 if (const ObjCObjectType *Iface
4257 = Context.getTypeDeclType(TD)->getAs<ObjCObjectType>())
4258 CDecl = Iface->getInterface();
Douglas Gregor2725ca82010-04-21 19:57:20 +00004259 } else if (ND && isa<UnresolvedUsingTypenameDecl>(ND)) {
4260 // "super" names an unresolved type; we can't be more specific.
4261 } else {
4262 // Assume that "super" names some kind of value and parse that way.
4263 CXXScopeSpec SS;
4264 UnqualifiedId id;
4265 id.setIdentifier(Super, SuperLoc);
John McCall60d7b3a2010-08-24 06:29:42 +00004266 ExprResult SuperExpr = ActOnIdExpression(S, SS, id, false, false);
Douglas Gregor2725ca82010-04-21 19:57:20 +00004267 return CodeCompleteObjCInstanceMessage(S, (Expr *)SuperExpr.get(),
4268 SelIdents, NumSelIdents);
4269 }
4270
4271 // Fall through
4272 }
4273
John McCallb3d87482010-08-24 05:47:05 +00004274 ParsedType Receiver;
Douglas Gregor2725ca82010-04-21 19:57:20 +00004275 if (CDecl)
John McCallb3d87482010-08-24 05:47:05 +00004276 Receiver = ParsedType::make(Context.getObjCInterfaceType(CDecl));
Douglas Gregor2725ca82010-04-21 19:57:20 +00004277 return CodeCompleteObjCClassMessage(S, Receiver, SelIdents,
Douglas Gregor03d8aec2010-08-27 15:10:57 +00004278 NumSelIdents, /*IsSuper=*/true);
Douglas Gregor2725ca82010-04-21 19:57:20 +00004279}
4280
John McCallb3d87482010-08-24 05:47:05 +00004281void Sema::CodeCompleteObjCClassMessage(Scope *S, ParsedType Receiver,
Douglas Gregord3c68542009-11-19 01:08:35 +00004282 IdentifierInfo **SelIdents,
4283 unsigned NumSelIdents) {
Douglas Gregor03d8aec2010-08-27 15:10:57 +00004284 CodeCompleteObjCClassMessage(S, Receiver, SelIdents, NumSelIdents, false);
4285}
4286
4287void Sema::CodeCompleteObjCClassMessage(Scope *S, ParsedType Receiver,
4288 IdentifierInfo **SelIdents,
4289 unsigned NumSelIdents,
4290 bool IsSuper) {
John McCall0a2c5e22010-08-25 06:19:51 +00004291 typedef CodeCompletionResult Result;
Douglas Gregor24a069f2009-11-17 17:59:40 +00004292 ObjCInterfaceDecl *CDecl = 0;
4293
Douglas Gregor24a069f2009-11-17 17:59:40 +00004294 // If the given name refers to an interface type, retrieve the
4295 // corresponding declaration.
Douglas Gregor2725ca82010-04-21 19:57:20 +00004296 if (Receiver) {
4297 QualType T = GetTypeFromParser(Receiver, 0);
4298 if (!T.isNull())
John McCallc12c5bb2010-05-15 11:32:37 +00004299 if (const ObjCObjectType *Interface = T->getAs<ObjCObjectType>())
4300 CDecl = Interface->getInterface();
Douglas Gregor24a069f2009-11-17 17:59:40 +00004301 }
4302
Douglas Gregor36ecb042009-11-17 23:22:23 +00004303 // Add all of the factory methods in this Objective-C class, its protocols,
4304 // superclasses, categories, implementation, etc.
Steve Naroffc4df6d22009-11-07 02:08:14 +00004305 ResultBuilder Results(*this);
4306 Results.EnterNewScope();
Douglas Gregor13438f92010-04-06 16:40:00 +00004307
Douglas Gregor03d8aec2010-08-27 15:10:57 +00004308 // If this is a send-to-super, try to add the special "super" send
4309 // completion.
4310 if (IsSuper) {
4311 if (ObjCMethodDecl *SuperMethod
4312 = AddSuperSendCompletion(*this, false, SelIdents, NumSelIdents,
4313 Results))
4314 Results.Ignore(SuperMethod);
4315 }
4316
Douglas Gregor265f7492010-08-27 15:29:55 +00004317 // If we're inside an Objective-C method definition, prefer its selector to
4318 // others.
4319 if (ObjCMethodDecl *CurMethod = getCurMethodDecl())
4320 Results.setPreferredSelector(CurMethod->getSelector());
4321
Douglas Gregor13438f92010-04-06 16:40:00 +00004322 if (CDecl)
4323 AddObjCMethods(CDecl, false, MK_Any, SelIdents, NumSelIdents, CurContext,
4324 Results);
Douglas Gregor2725ca82010-04-21 19:57:20 +00004325 else {
Douglas Gregor13438f92010-04-06 16:40:00 +00004326 // We're messaging "id" as a type; provide all class/factory methods.
4327
Douglas Gregor719770d2010-04-06 17:30:22 +00004328 // If we have an external source, load the entire class method
Sebastian Redl3c7f4132010-08-18 23:57:06 +00004329 // pool from the AST file.
Douglas Gregor719770d2010-04-06 17:30:22 +00004330 if (ExternalSource) {
John McCall76bd1f32010-06-01 09:23:16 +00004331 for (uint32_t I = 0, N = ExternalSource->GetNumExternalSelectors();
4332 I != N; ++I) {
4333 Selector Sel = ExternalSource->GetExternalSelector(I);
Sebastian Redldb9d2142010-08-02 23:18:59 +00004334 if (Sel.isNull() || MethodPool.count(Sel))
Douglas Gregor719770d2010-04-06 17:30:22 +00004335 continue;
4336
Sebastian Redldb9d2142010-08-02 23:18:59 +00004337 ReadMethodPool(Sel);
Douglas Gregor719770d2010-04-06 17:30:22 +00004338 }
4339 }
4340
Sebastian Redldb9d2142010-08-02 23:18:59 +00004341 for (GlobalMethodPool::iterator M = MethodPool.begin(),
4342 MEnd = MethodPool.end();
4343 M != MEnd; ++M) {
4344 for (ObjCMethodList *MethList = &M->second.second;
4345 MethList && MethList->Method;
Douglas Gregor13438f92010-04-06 16:40:00 +00004346 MethList = MethList->Next) {
4347 if (!isAcceptableObjCMethod(MethList->Method, MK_Any, SelIdents,
4348 NumSelIdents))
4349 continue;
4350
4351 Result R(MethList->Method, 0);
4352 R.StartParameter = NumSelIdents;
4353 R.AllParametersAreInformative = false;
4354 Results.MaybeAddResult(R, CurContext);
4355 }
4356 }
4357 }
4358
Steve Naroffc4df6d22009-11-07 02:08:14 +00004359 Results.ExitScope();
Douglas Gregore6b1bb62010-08-11 21:23:17 +00004360 HandleCodeCompleteResults(this, CodeCompleter,
4361 CodeCompletionContext::CCC_Other,
Douglas Gregor03d8aec2010-08-27 15:10:57 +00004362 Results.data(), Results.size());
Steve Naroffc4df6d22009-11-07 02:08:14 +00004363}
4364
Douglas Gregord3c68542009-11-19 01:08:35 +00004365void Sema::CodeCompleteObjCInstanceMessage(Scope *S, ExprTy *Receiver,
4366 IdentifierInfo **SelIdents,
4367 unsigned NumSelIdents) {
Douglas Gregor03d8aec2010-08-27 15:10:57 +00004368 CodeCompleteObjCInstanceMessage(S, Receiver, SelIdents, NumSelIdents, false);
4369}
4370
4371void Sema::CodeCompleteObjCInstanceMessage(Scope *S, ExprTy *Receiver,
4372 IdentifierInfo **SelIdents,
4373 unsigned NumSelIdents,
4374 bool IsSuper) {
John McCall0a2c5e22010-08-25 06:19:51 +00004375 typedef CodeCompletionResult Result;
Steve Naroffc4df6d22009-11-07 02:08:14 +00004376
4377 Expr *RecExpr = static_cast<Expr *>(Receiver);
Steve Naroffc4df6d22009-11-07 02:08:14 +00004378
Douglas Gregor36ecb042009-11-17 23:22:23 +00004379 // If necessary, apply function/array conversion to the receiver.
4380 // C99 6.7.5.3p[7,8].
Douglas Gregora873dfc2010-02-03 00:27:59 +00004381 DefaultFunctionArrayLvalueConversion(RecExpr);
Douglas Gregor36ecb042009-11-17 23:22:23 +00004382 QualType ReceiverType = RecExpr->getType();
Steve Naroffc4df6d22009-11-07 02:08:14 +00004383
Douglas Gregor36ecb042009-11-17 23:22:23 +00004384 // Build the set of methods we can see.
4385 ResultBuilder Results(*this);
4386 Results.EnterNewScope();
Douglas Gregor22f56992010-04-06 19:22:33 +00004387
Douglas Gregor03d8aec2010-08-27 15:10:57 +00004388 // If this is a send-to-super, try to add the special "super" send
4389 // completion.
4390 if (IsSuper) {
4391 if (ObjCMethodDecl *SuperMethod
4392 = AddSuperSendCompletion(*this, false, SelIdents, NumSelIdents,
4393 Results))
4394 Results.Ignore(SuperMethod);
4395 }
4396
Douglas Gregor265f7492010-08-27 15:29:55 +00004397 // If we're inside an Objective-C method definition, prefer its selector to
4398 // others.
4399 if (ObjCMethodDecl *CurMethod = getCurMethodDecl())
4400 Results.setPreferredSelector(CurMethod->getSelector());
4401
Douglas Gregor22f56992010-04-06 19:22:33 +00004402 // If we're messaging an expression with type "id" or "Class", check
4403 // whether we know something special about the receiver that allows
4404 // us to assume a more-specific receiver type.
4405 if (ReceiverType->isObjCIdType() || ReceiverType->isObjCClassType())
4406 if (ObjCInterfaceDecl *IFace = GetAssumedMessageSendExprType(RecExpr))
4407 ReceiverType = Context.getObjCObjectPointerType(
4408 Context.getObjCInterfaceType(IFace));
Douglas Gregor36ecb042009-11-17 23:22:23 +00004409
Douglas Gregorf74a4192009-11-18 00:06:18 +00004410 // Handle messages to Class. This really isn't a message to an instance
4411 // method, so we treat it the same way we would treat a message send to a
4412 // class method.
4413 if (ReceiverType->isObjCClassType() ||
4414 ReceiverType->isObjCQualifiedClassType()) {
4415 if (ObjCMethodDecl *CurMethod = getCurMethodDecl()) {
4416 if (ObjCInterfaceDecl *ClassDecl = CurMethod->getClassInterface())
Douglas Gregor4ad96852009-11-19 07:41:15 +00004417 AddObjCMethods(ClassDecl, false, MK_Any, SelIdents, NumSelIdents,
4418 CurContext, Results);
Douglas Gregorf74a4192009-11-18 00:06:18 +00004419 }
4420 }
4421 // Handle messages to a qualified ID ("id<foo>").
4422 else if (const ObjCObjectPointerType *QualID
4423 = ReceiverType->getAsObjCQualifiedIdType()) {
4424 // Search protocols for instance methods.
4425 for (ObjCObjectPointerType::qual_iterator I = QualID->qual_begin(),
4426 E = QualID->qual_end();
4427 I != E; ++I)
Douglas Gregor4ad96852009-11-19 07:41:15 +00004428 AddObjCMethods(*I, true, MK_Any, SelIdents, NumSelIdents, CurContext,
4429 Results);
Douglas Gregorf74a4192009-11-18 00:06:18 +00004430 }
4431 // Handle messages to a pointer to interface type.
4432 else if (const ObjCObjectPointerType *IFacePtr
4433 = ReceiverType->getAsObjCInterfacePointerType()) {
4434 // Search the class, its superclasses, etc., for instance methods.
Douglas Gregor4ad96852009-11-19 07:41:15 +00004435 AddObjCMethods(IFacePtr->getInterfaceDecl(), true, MK_Any, SelIdents,
4436 NumSelIdents, CurContext, Results);
Douglas Gregorf74a4192009-11-18 00:06:18 +00004437
4438 // Search protocols for instance methods.
4439 for (ObjCObjectPointerType::qual_iterator I = IFacePtr->qual_begin(),
4440 E = IFacePtr->qual_end();
4441 I != E; ++I)
Douglas Gregor4ad96852009-11-19 07:41:15 +00004442 AddObjCMethods(*I, true, MK_Any, SelIdents, NumSelIdents, CurContext,
4443 Results);
Douglas Gregorf74a4192009-11-18 00:06:18 +00004444 }
Douglas Gregor13438f92010-04-06 16:40:00 +00004445 // Handle messages to "id".
4446 else if (ReceiverType->isObjCIdType()) {
Douglas Gregor719770d2010-04-06 17:30:22 +00004447 // We're messaging "id", so provide all instance methods we know
4448 // about as code-completion results.
4449
4450 // If we have an external source, load the entire class method
Sebastian Redl3c7f4132010-08-18 23:57:06 +00004451 // pool from the AST file.
Douglas Gregor719770d2010-04-06 17:30:22 +00004452 if (ExternalSource) {
John McCall76bd1f32010-06-01 09:23:16 +00004453 for (uint32_t I = 0, N = ExternalSource->GetNumExternalSelectors();
4454 I != N; ++I) {
4455 Selector Sel = ExternalSource->GetExternalSelector(I);
Sebastian Redldb9d2142010-08-02 23:18:59 +00004456 if (Sel.isNull() || MethodPool.count(Sel))
Douglas Gregor719770d2010-04-06 17:30:22 +00004457 continue;
4458
Sebastian Redldb9d2142010-08-02 23:18:59 +00004459 ReadMethodPool(Sel);
Douglas Gregor719770d2010-04-06 17:30:22 +00004460 }
4461 }
4462
Sebastian Redldb9d2142010-08-02 23:18:59 +00004463 for (GlobalMethodPool::iterator M = MethodPool.begin(),
4464 MEnd = MethodPool.end();
4465 M != MEnd; ++M) {
4466 for (ObjCMethodList *MethList = &M->second.first;
4467 MethList && MethList->Method;
Douglas Gregor13438f92010-04-06 16:40:00 +00004468 MethList = MethList->Next) {
4469 if (!isAcceptableObjCMethod(MethList->Method, MK_Any, SelIdents,
4470 NumSelIdents))
4471 continue;
4472
4473 Result R(MethList->Method, 0);
4474 R.StartParameter = NumSelIdents;
4475 R.AllParametersAreInformative = false;
4476 Results.MaybeAddResult(R, CurContext);
4477 }
4478 }
4479 }
4480
Steve Naroffc4df6d22009-11-07 02:08:14 +00004481 Results.ExitScope();
Douglas Gregore6b1bb62010-08-11 21:23:17 +00004482 HandleCodeCompleteResults(this, CodeCompleter,
4483 CodeCompletionContext::CCC_Other,
4484 Results.data(),Results.size());
Steve Naroffc4df6d22009-11-07 02:08:14 +00004485}
Douglas Gregor55385fe2009-11-18 04:19:12 +00004486
Douglas Gregorfb629412010-08-23 21:17:50 +00004487void Sema::CodeCompleteObjCForCollection(Scope *S,
4488 DeclGroupPtrTy IterationVar) {
4489 CodeCompleteExpressionData Data;
4490 Data.ObjCCollection = true;
4491
4492 if (IterationVar.getAsOpaquePtr()) {
4493 DeclGroupRef DG = IterationVar.getAsVal<DeclGroupRef>();
4494 for (DeclGroupRef::iterator I = DG.begin(), End = DG.end(); I != End; ++I) {
4495 if (*I)
4496 Data.IgnoreDecls.push_back(*I);
4497 }
4498 }
4499
4500 CodeCompleteExpression(S, Data);
4501}
4502
Douglas Gregor458433d2010-08-26 15:07:07 +00004503void Sema::CodeCompleteObjCSelector(Scope *S, IdentifierInfo **SelIdents,
4504 unsigned NumSelIdents) {
4505 // If we have an external source, load the entire class method
4506 // pool from the AST file.
4507 if (ExternalSource) {
4508 for (uint32_t I = 0, N = ExternalSource->GetNumExternalSelectors();
4509 I != N; ++I) {
4510 Selector Sel = ExternalSource->GetExternalSelector(I);
4511 if (Sel.isNull() || MethodPool.count(Sel))
4512 continue;
4513
4514 ReadMethodPool(Sel);
4515 }
4516 }
4517
4518 ResultBuilder Results(*this);
4519 Results.EnterNewScope();
4520 for (GlobalMethodPool::iterator M = MethodPool.begin(),
4521 MEnd = MethodPool.end();
4522 M != MEnd; ++M) {
4523
4524 Selector Sel = M->first;
4525 if (!isAcceptableObjCSelector(Sel, MK_Any, SelIdents, NumSelIdents))
4526 continue;
4527
4528 CodeCompletionString *Pattern = new CodeCompletionString;
4529 if (Sel.isUnarySelector()) {
4530 Pattern->AddTypedTextChunk(Sel.getIdentifierInfoForSlot(0)->getName());
4531 Results.AddResult(Pattern);
4532 continue;
4533 }
4534
Douglas Gregor2d9e21f2010-08-26 16:46:39 +00004535 std::string Accumulator;
Douglas Gregor458433d2010-08-26 15:07:07 +00004536 for (unsigned I = 0, N = Sel.getNumArgs(); I != N; ++I) {
Douglas Gregor2d9e21f2010-08-26 16:46:39 +00004537 if (I == NumSelIdents) {
4538 if (!Accumulator.empty()) {
4539 Pattern->AddInformativeChunk(Accumulator);
4540 Accumulator.clear();
4541 }
4542 }
4543
4544 Accumulator += Sel.getIdentifierInfoForSlot(I)->getName().str();
4545 Accumulator += ':';
Douglas Gregor458433d2010-08-26 15:07:07 +00004546 }
Douglas Gregor2d9e21f2010-08-26 16:46:39 +00004547 Pattern->AddTypedTextChunk(Accumulator);
Douglas Gregor458433d2010-08-26 15:07:07 +00004548 Results.AddResult(Pattern);
4549 }
4550 Results.ExitScope();
4551
4552 HandleCodeCompleteResults(this, CodeCompleter,
4553 CodeCompletionContext::CCC_SelectorName,
4554 Results.data(), Results.size());
4555}
4556
Douglas Gregor55385fe2009-11-18 04:19:12 +00004557/// \brief Add all of the protocol declarations that we find in the given
4558/// (translation unit) context.
4559static void AddProtocolResults(DeclContext *Ctx, DeclContext *CurContext,
Douglas Gregor083128f2009-11-18 04:49:41 +00004560 bool OnlyForwardDeclarations,
Douglas Gregor55385fe2009-11-18 04:19:12 +00004561 ResultBuilder &Results) {
John McCall0a2c5e22010-08-25 06:19:51 +00004562 typedef CodeCompletionResult Result;
Douglas Gregor55385fe2009-11-18 04:19:12 +00004563
4564 for (DeclContext::decl_iterator D = Ctx->decls_begin(),
4565 DEnd = Ctx->decls_end();
4566 D != DEnd; ++D) {
4567 // Record any protocols we find.
4568 if (ObjCProtocolDecl *Proto = dyn_cast<ObjCProtocolDecl>(*D))
Douglas Gregor083128f2009-11-18 04:49:41 +00004569 if (!OnlyForwardDeclarations || Proto->isForwardDecl())
Douglas Gregor608300b2010-01-14 16:14:35 +00004570 Results.AddResult(Result(Proto, 0), CurContext, 0, false);
Douglas Gregor55385fe2009-11-18 04:19:12 +00004571
4572 // Record any forward-declared protocols we find.
4573 if (ObjCForwardProtocolDecl *Forward
4574 = dyn_cast<ObjCForwardProtocolDecl>(*D)) {
4575 for (ObjCForwardProtocolDecl::protocol_iterator
4576 P = Forward->protocol_begin(),
4577 PEnd = Forward->protocol_end();
4578 P != PEnd; ++P)
Douglas Gregor083128f2009-11-18 04:49:41 +00004579 if (!OnlyForwardDeclarations || (*P)->isForwardDecl())
Douglas Gregor608300b2010-01-14 16:14:35 +00004580 Results.AddResult(Result(*P, 0), CurContext, 0, false);
Douglas Gregor55385fe2009-11-18 04:19:12 +00004581 }
4582 }
4583}
4584
4585void Sema::CodeCompleteObjCProtocolReferences(IdentifierLocPair *Protocols,
4586 unsigned NumProtocols) {
4587 ResultBuilder Results(*this);
4588 Results.EnterNewScope();
4589
4590 // Tell the result set to ignore all of the protocols we have
4591 // already seen.
4592 for (unsigned I = 0; I != NumProtocols; ++I)
Douglas Gregorc83c6872010-04-15 22:33:43 +00004593 if (ObjCProtocolDecl *Protocol = LookupProtocol(Protocols[I].first,
4594 Protocols[I].second))
Douglas Gregor55385fe2009-11-18 04:19:12 +00004595 Results.Ignore(Protocol);
4596
4597 // Add all protocols.
Douglas Gregor083128f2009-11-18 04:49:41 +00004598 AddProtocolResults(Context.getTranslationUnitDecl(), CurContext, false,
4599 Results);
4600
4601 Results.ExitScope();
Douglas Gregore6b1bb62010-08-11 21:23:17 +00004602 HandleCodeCompleteResults(this, CodeCompleter,
4603 CodeCompletionContext::CCC_ObjCProtocolName,
4604 Results.data(),Results.size());
Douglas Gregor083128f2009-11-18 04:49:41 +00004605}
4606
4607void Sema::CodeCompleteObjCProtocolDecl(Scope *) {
4608 ResultBuilder Results(*this);
4609 Results.EnterNewScope();
4610
4611 // Add all protocols.
4612 AddProtocolResults(Context.getTranslationUnitDecl(), CurContext, true,
4613 Results);
Douglas Gregor55385fe2009-11-18 04:19:12 +00004614
4615 Results.ExitScope();
Douglas Gregore6b1bb62010-08-11 21:23:17 +00004616 HandleCodeCompleteResults(this, CodeCompleter,
4617 CodeCompletionContext::CCC_ObjCProtocolName,
4618 Results.data(),Results.size());
Douglas Gregor55385fe2009-11-18 04:19:12 +00004619}
Douglas Gregor3b49aca2009-11-18 16:26:39 +00004620
4621/// \brief Add all of the Objective-C interface declarations that we find in
4622/// the given (translation unit) context.
4623static void AddInterfaceResults(DeclContext *Ctx, DeclContext *CurContext,
4624 bool OnlyForwardDeclarations,
4625 bool OnlyUnimplemented,
4626 ResultBuilder &Results) {
John McCall0a2c5e22010-08-25 06:19:51 +00004627 typedef CodeCompletionResult Result;
Douglas Gregor3b49aca2009-11-18 16:26:39 +00004628
4629 for (DeclContext::decl_iterator D = Ctx->decls_begin(),
4630 DEnd = Ctx->decls_end();
4631 D != DEnd; ++D) {
Douglas Gregordeacbdc2010-08-11 12:19:30 +00004632 // Record any interfaces we find.
4633 if (ObjCInterfaceDecl *Class = dyn_cast<ObjCInterfaceDecl>(*D))
4634 if ((!OnlyForwardDeclarations || Class->isForwardDecl()) &&
4635 (!OnlyUnimplemented || !Class->getImplementation()))
4636 Results.AddResult(Result(Class, 0), CurContext, 0, false);
Douglas Gregor3b49aca2009-11-18 16:26:39 +00004637
4638 // Record any forward-declared interfaces we find.
4639 if (ObjCClassDecl *Forward = dyn_cast<ObjCClassDecl>(*D)) {
4640 for (ObjCClassDecl::iterator C = Forward->begin(), CEnd = Forward->end();
Douglas Gregordeacbdc2010-08-11 12:19:30 +00004641 C != CEnd; ++C)
4642 if ((!OnlyForwardDeclarations || C->getInterface()->isForwardDecl()) &&
4643 (!OnlyUnimplemented || !C->getInterface()->getImplementation()))
4644 Results.AddResult(Result(C->getInterface(), 0), CurContext,
Douglas Gregor608300b2010-01-14 16:14:35 +00004645 0, false);
Douglas Gregor3b49aca2009-11-18 16:26:39 +00004646 }
4647 }
4648}
4649
4650void Sema::CodeCompleteObjCInterfaceDecl(Scope *S) {
4651 ResultBuilder Results(*this);
4652 Results.EnterNewScope();
4653
4654 // Add all classes.
4655 AddInterfaceResults(Context.getTranslationUnitDecl(), CurContext, true,
4656 false, Results);
4657
4658 Results.ExitScope();
Douglas Gregore6b1bb62010-08-11 21:23:17 +00004659 HandleCodeCompleteResults(this, CodeCompleter,
4660 CodeCompletionContext::CCC_Other,
4661 Results.data(),Results.size());
Douglas Gregor3b49aca2009-11-18 16:26:39 +00004662}
4663
Douglas Gregorc83c6872010-04-15 22:33:43 +00004664void Sema::CodeCompleteObjCSuperclass(Scope *S, IdentifierInfo *ClassName,
4665 SourceLocation ClassNameLoc) {
Douglas Gregor3b49aca2009-11-18 16:26:39 +00004666 ResultBuilder Results(*this);
4667 Results.EnterNewScope();
4668
4669 // Make sure that we ignore the class we're currently defining.
4670 NamedDecl *CurClass
Douglas Gregorc83c6872010-04-15 22:33:43 +00004671 = LookupSingleName(TUScope, ClassName, ClassNameLoc, LookupOrdinaryName);
Douglas Gregor33ced0b2009-11-18 19:08:43 +00004672 if (CurClass && isa<ObjCInterfaceDecl>(CurClass))
Douglas Gregor3b49aca2009-11-18 16:26:39 +00004673 Results.Ignore(CurClass);
4674
4675 // Add all classes.
4676 AddInterfaceResults(Context.getTranslationUnitDecl(), CurContext, false,
4677 false, Results);
4678
4679 Results.ExitScope();
Douglas Gregore6b1bb62010-08-11 21:23:17 +00004680 HandleCodeCompleteResults(this, CodeCompleter,
4681 CodeCompletionContext::CCC_Other,
4682 Results.data(),Results.size());
Douglas Gregor3b49aca2009-11-18 16:26:39 +00004683}
4684
4685void Sema::CodeCompleteObjCImplementationDecl(Scope *S) {
4686 ResultBuilder Results(*this);
4687 Results.EnterNewScope();
4688
4689 // Add all unimplemented classes.
4690 AddInterfaceResults(Context.getTranslationUnitDecl(), CurContext, false,
4691 true, Results);
4692
4693 Results.ExitScope();
Douglas Gregore6b1bb62010-08-11 21:23:17 +00004694 HandleCodeCompleteResults(this, CodeCompleter,
4695 CodeCompletionContext::CCC_Other,
4696 Results.data(),Results.size());
Douglas Gregor3b49aca2009-11-18 16:26:39 +00004697}
Douglas Gregor33ced0b2009-11-18 19:08:43 +00004698
4699void Sema::CodeCompleteObjCInterfaceCategory(Scope *S,
Douglas Gregorc83c6872010-04-15 22:33:43 +00004700 IdentifierInfo *ClassName,
4701 SourceLocation ClassNameLoc) {
John McCall0a2c5e22010-08-25 06:19:51 +00004702 typedef CodeCompletionResult Result;
Douglas Gregor33ced0b2009-11-18 19:08:43 +00004703
4704 ResultBuilder Results(*this);
4705
4706 // Ignore any categories we find that have already been implemented by this
4707 // interface.
4708 llvm::SmallPtrSet<IdentifierInfo *, 16> CategoryNames;
4709 NamedDecl *CurClass
Douglas Gregorc83c6872010-04-15 22:33:43 +00004710 = LookupSingleName(TUScope, ClassName, ClassNameLoc, LookupOrdinaryName);
Douglas Gregor33ced0b2009-11-18 19:08:43 +00004711 if (ObjCInterfaceDecl *Class = dyn_cast_or_null<ObjCInterfaceDecl>(CurClass))
4712 for (ObjCCategoryDecl *Category = Class->getCategoryList(); Category;
4713 Category = Category->getNextClassCategory())
4714 CategoryNames.insert(Category->getIdentifier());
4715
4716 // Add all of the categories we know about.
4717 Results.EnterNewScope();
4718 TranslationUnitDecl *TU = Context.getTranslationUnitDecl();
4719 for (DeclContext::decl_iterator D = TU->decls_begin(),
4720 DEnd = TU->decls_end();
4721 D != DEnd; ++D)
4722 if (ObjCCategoryDecl *Category = dyn_cast<ObjCCategoryDecl>(*D))
4723 if (CategoryNames.insert(Category->getIdentifier()))
Douglas Gregor608300b2010-01-14 16:14:35 +00004724 Results.AddResult(Result(Category, 0), CurContext, 0, false);
Douglas Gregor33ced0b2009-11-18 19:08:43 +00004725 Results.ExitScope();
4726
Douglas Gregore6b1bb62010-08-11 21:23:17 +00004727 HandleCodeCompleteResults(this, CodeCompleter,
4728 CodeCompletionContext::CCC_Other,
4729 Results.data(),Results.size());
Douglas Gregor33ced0b2009-11-18 19:08:43 +00004730}
4731
4732void Sema::CodeCompleteObjCImplementationCategory(Scope *S,
Douglas Gregorc83c6872010-04-15 22:33:43 +00004733 IdentifierInfo *ClassName,
4734 SourceLocation ClassNameLoc) {
John McCall0a2c5e22010-08-25 06:19:51 +00004735 typedef CodeCompletionResult Result;
Douglas Gregor33ced0b2009-11-18 19:08:43 +00004736
4737 // Find the corresponding interface. If we couldn't find the interface, the
4738 // program itself is ill-formed. However, we'll try to be helpful still by
4739 // providing the list of all of the categories we know about.
4740 NamedDecl *CurClass
Douglas Gregorc83c6872010-04-15 22:33:43 +00004741 = LookupSingleName(TUScope, ClassName, ClassNameLoc, LookupOrdinaryName);
Douglas Gregor33ced0b2009-11-18 19:08:43 +00004742 ObjCInterfaceDecl *Class = dyn_cast_or_null<ObjCInterfaceDecl>(CurClass);
4743 if (!Class)
Douglas Gregorc83c6872010-04-15 22:33:43 +00004744 return CodeCompleteObjCInterfaceCategory(S, ClassName, ClassNameLoc);
Douglas Gregor33ced0b2009-11-18 19:08:43 +00004745
4746 ResultBuilder Results(*this);
4747
4748 // Add all of the categories that have have corresponding interface
4749 // declarations in this class and any of its superclasses, except for
4750 // already-implemented categories in the class itself.
4751 llvm::SmallPtrSet<IdentifierInfo *, 16> CategoryNames;
4752 Results.EnterNewScope();
4753 bool IgnoreImplemented = true;
4754 while (Class) {
4755 for (ObjCCategoryDecl *Category = Class->getCategoryList(); Category;
4756 Category = Category->getNextClassCategory())
4757 if ((!IgnoreImplemented || !Category->getImplementation()) &&
4758 CategoryNames.insert(Category->getIdentifier()))
Douglas Gregor608300b2010-01-14 16:14:35 +00004759 Results.AddResult(Result(Category, 0), CurContext, 0, false);
Douglas Gregor33ced0b2009-11-18 19:08:43 +00004760
4761 Class = Class->getSuperClass();
4762 IgnoreImplemented = false;
4763 }
4764 Results.ExitScope();
4765
Douglas Gregore6b1bb62010-08-11 21:23:17 +00004766 HandleCodeCompleteResults(this, CodeCompleter,
4767 CodeCompletionContext::CCC_Other,
4768 Results.data(),Results.size());
Douglas Gregor33ced0b2009-11-18 19:08:43 +00004769}
Douglas Gregor322328b2009-11-18 22:32:06 +00004770
John McCalld226f652010-08-21 09:40:31 +00004771void Sema::CodeCompleteObjCPropertyDefinition(Scope *S, Decl *ObjCImpDecl) {
John McCall0a2c5e22010-08-25 06:19:51 +00004772 typedef CodeCompletionResult Result;
Douglas Gregor322328b2009-11-18 22:32:06 +00004773 ResultBuilder Results(*this);
4774
4775 // Figure out where this @synthesize lives.
4776 ObjCContainerDecl *Container
John McCalld226f652010-08-21 09:40:31 +00004777 = dyn_cast_or_null<ObjCContainerDecl>(ObjCImpDecl);
Douglas Gregor322328b2009-11-18 22:32:06 +00004778 if (!Container ||
4779 (!isa<ObjCImplementationDecl>(Container) &&
4780 !isa<ObjCCategoryImplDecl>(Container)))
4781 return;
4782
4783 // Ignore any properties that have already been implemented.
4784 for (DeclContext::decl_iterator D = Container->decls_begin(),
4785 DEnd = Container->decls_end();
4786 D != DEnd; ++D)
4787 if (ObjCPropertyImplDecl *PropertyImpl = dyn_cast<ObjCPropertyImplDecl>(*D))
4788 Results.Ignore(PropertyImpl->getPropertyDecl());
4789
4790 // Add any properties that we find.
4791 Results.EnterNewScope();
4792 if (ObjCImplementationDecl *ClassImpl
4793 = dyn_cast<ObjCImplementationDecl>(Container))
4794 AddObjCProperties(ClassImpl->getClassInterface(), false, CurContext,
4795 Results);
4796 else
4797 AddObjCProperties(cast<ObjCCategoryImplDecl>(Container)->getCategoryDecl(),
4798 false, CurContext, Results);
4799 Results.ExitScope();
4800
Douglas Gregore6b1bb62010-08-11 21:23:17 +00004801 HandleCodeCompleteResults(this, CodeCompleter,
4802 CodeCompletionContext::CCC_Other,
4803 Results.data(),Results.size());
Douglas Gregor322328b2009-11-18 22:32:06 +00004804}
4805
4806void Sema::CodeCompleteObjCPropertySynthesizeIvar(Scope *S,
4807 IdentifierInfo *PropertyName,
John McCalld226f652010-08-21 09:40:31 +00004808 Decl *ObjCImpDecl) {
John McCall0a2c5e22010-08-25 06:19:51 +00004809 typedef CodeCompletionResult Result;
Douglas Gregor322328b2009-11-18 22:32:06 +00004810 ResultBuilder Results(*this);
4811
4812 // Figure out where this @synthesize lives.
4813 ObjCContainerDecl *Container
John McCalld226f652010-08-21 09:40:31 +00004814 = dyn_cast_or_null<ObjCContainerDecl>(ObjCImpDecl);
Douglas Gregor322328b2009-11-18 22:32:06 +00004815 if (!Container ||
4816 (!isa<ObjCImplementationDecl>(Container) &&
4817 !isa<ObjCCategoryImplDecl>(Container)))
4818 return;
4819
4820 // Figure out which interface we're looking into.
4821 ObjCInterfaceDecl *Class = 0;
4822 if (ObjCImplementationDecl *ClassImpl
4823 = dyn_cast<ObjCImplementationDecl>(Container))
4824 Class = ClassImpl->getClassInterface();
4825 else
4826 Class = cast<ObjCCategoryImplDecl>(Container)->getCategoryDecl()
4827 ->getClassInterface();
4828
4829 // Add all of the instance variables in this class and its superclasses.
4830 Results.EnterNewScope();
4831 for(; Class; Class = Class->getSuperClass()) {
4832 // FIXME: We could screen the type of each ivar for compatibility with
4833 // the property, but is that being too paternal?
4834 for (ObjCInterfaceDecl::ivar_iterator IVar = Class->ivar_begin(),
4835 IVarEnd = Class->ivar_end();
4836 IVar != IVarEnd; ++IVar)
Douglas Gregor608300b2010-01-14 16:14:35 +00004837 Results.AddResult(Result(*IVar, 0), CurContext, 0, false);
Douglas Gregor322328b2009-11-18 22:32:06 +00004838 }
4839 Results.ExitScope();
4840
Douglas Gregore6b1bb62010-08-11 21:23:17 +00004841 HandleCodeCompleteResults(this, CodeCompleter,
4842 CodeCompletionContext::CCC_Other,
4843 Results.data(),Results.size());
Douglas Gregor322328b2009-11-18 22:32:06 +00004844}
Douglas Gregore8f5a172010-04-07 00:21:17 +00004845
Douglas Gregor408be5a2010-08-25 01:08:01 +00004846// Mapping from selectors to the methods that implement that selector, along
4847// with the "in original class" flag.
4848typedef llvm::DenseMap<Selector, std::pair<ObjCMethodDecl *, bool> >
4849 KnownMethodsMap;
Douglas Gregore8f5a172010-04-07 00:21:17 +00004850
4851/// \brief Find all of the methods that reside in the given container
4852/// (and its superclasses, protocols, etc.) that meet the given
4853/// criteria. Insert those methods into the map of known methods,
4854/// indexed by selector so they can be easily found.
4855static void FindImplementableMethods(ASTContext &Context,
4856 ObjCContainerDecl *Container,
4857 bool WantInstanceMethods,
4858 QualType ReturnType,
4859 bool IsInImplementation,
Douglas Gregor408be5a2010-08-25 01:08:01 +00004860 KnownMethodsMap &KnownMethods,
4861 bool InOriginalClass = true) {
Douglas Gregore8f5a172010-04-07 00:21:17 +00004862 if (ObjCInterfaceDecl *IFace = dyn_cast<ObjCInterfaceDecl>(Container)) {
4863 // Recurse into protocols.
4864 const ObjCList<ObjCProtocolDecl> &Protocols
4865 = IFace->getReferencedProtocols();
4866 for (ObjCList<ObjCProtocolDecl>::iterator I = Protocols.begin(),
4867 E = Protocols.end();
4868 I != E; ++I)
4869 FindImplementableMethods(Context, *I, WantInstanceMethods, ReturnType,
Douglas Gregor408be5a2010-08-25 01:08:01 +00004870 IsInImplementation, KnownMethods,
4871 InOriginalClass);
Douglas Gregore8f5a172010-04-07 00:21:17 +00004872
4873 // If we're not in the implementation of a class, also visit the
4874 // superclass.
4875 if (!IsInImplementation && IFace->getSuperClass())
4876 FindImplementableMethods(Context, IFace->getSuperClass(),
4877 WantInstanceMethods, ReturnType,
Douglas Gregor408be5a2010-08-25 01:08:01 +00004878 IsInImplementation, KnownMethods,
4879 false);
Douglas Gregore8f5a172010-04-07 00:21:17 +00004880
4881 // Add methods from any class extensions (but not from categories;
4882 // those should go into category implementations).
Fariborz Jahanian80aa1cd2010-06-22 23:20:40 +00004883 for (const ObjCCategoryDecl *Cat = IFace->getFirstClassExtension(); Cat;
4884 Cat = Cat->getNextClassExtension())
4885 FindImplementableMethods(Context, const_cast<ObjCCategoryDecl*>(Cat),
4886 WantInstanceMethods, ReturnType,
Douglas Gregor408be5a2010-08-25 01:08:01 +00004887 IsInImplementation, KnownMethods,
4888 InOriginalClass);
Douglas Gregore8f5a172010-04-07 00:21:17 +00004889 }
4890
4891 if (ObjCCategoryDecl *Category = dyn_cast<ObjCCategoryDecl>(Container)) {
4892 // Recurse into protocols.
4893 const ObjCList<ObjCProtocolDecl> &Protocols
4894 = Category->getReferencedProtocols();
4895 for (ObjCList<ObjCProtocolDecl>::iterator I = Protocols.begin(),
4896 E = Protocols.end();
4897 I != E; ++I)
4898 FindImplementableMethods(Context, *I, WantInstanceMethods, ReturnType,
Douglas Gregor408be5a2010-08-25 01:08:01 +00004899 IsInImplementation, KnownMethods,
4900 InOriginalClass);
Douglas Gregore8f5a172010-04-07 00:21:17 +00004901 }
4902
4903 if (ObjCProtocolDecl *Protocol = dyn_cast<ObjCProtocolDecl>(Container)) {
4904 // Recurse into protocols.
4905 const ObjCList<ObjCProtocolDecl> &Protocols
4906 = Protocol->getReferencedProtocols();
4907 for (ObjCList<ObjCProtocolDecl>::iterator I = Protocols.begin(),
4908 E = Protocols.end();
4909 I != E; ++I)
4910 FindImplementableMethods(Context, *I, WantInstanceMethods, ReturnType,
Douglas Gregor408be5a2010-08-25 01:08:01 +00004911 IsInImplementation, KnownMethods, false);
Douglas Gregore8f5a172010-04-07 00:21:17 +00004912 }
4913
4914 // Add methods in this container. This operation occurs last because
4915 // we want the methods from this container to override any methods
4916 // we've previously seen with the same selector.
4917 for (ObjCContainerDecl::method_iterator M = Container->meth_begin(),
4918 MEnd = Container->meth_end();
4919 M != MEnd; ++M) {
4920 if ((*M)->isInstanceMethod() == WantInstanceMethods) {
4921 if (!ReturnType.isNull() &&
4922 !Context.hasSameUnqualifiedType(ReturnType, (*M)->getResultType()))
4923 continue;
4924
Douglas Gregor408be5a2010-08-25 01:08:01 +00004925 KnownMethods[(*M)->getSelector()] = std::make_pair(*M, InOriginalClass);
Douglas Gregore8f5a172010-04-07 00:21:17 +00004926 }
4927 }
4928}
4929
4930void Sema::CodeCompleteObjCMethodDecl(Scope *S,
4931 bool IsInstanceMethod,
John McCallb3d87482010-08-24 05:47:05 +00004932 ParsedType ReturnTy,
John McCalld226f652010-08-21 09:40:31 +00004933 Decl *IDecl) {
Douglas Gregore8f5a172010-04-07 00:21:17 +00004934 // Determine the return type of the method we're declaring, if
4935 // provided.
4936 QualType ReturnType = GetTypeFromParser(ReturnTy);
4937
4938 // Determine where we should start searching for methods, and where we
4939 ObjCContainerDecl *SearchDecl = 0, *CurrentDecl = 0;
4940 bool IsInImplementation = false;
John McCalld226f652010-08-21 09:40:31 +00004941 if (Decl *D = IDecl) {
Douglas Gregore8f5a172010-04-07 00:21:17 +00004942 if (ObjCImplementationDecl *Impl = dyn_cast<ObjCImplementationDecl>(D)) {
4943 SearchDecl = Impl->getClassInterface();
4944 CurrentDecl = Impl;
4945 IsInImplementation = true;
4946 } else if (ObjCCategoryImplDecl *CatImpl
4947 = dyn_cast<ObjCCategoryImplDecl>(D)) {
4948 SearchDecl = CatImpl->getCategoryDecl();
4949 CurrentDecl = CatImpl;
4950 IsInImplementation = true;
4951 } else {
4952 SearchDecl = dyn_cast<ObjCContainerDecl>(D);
4953 CurrentDecl = SearchDecl;
4954 }
4955 }
4956
4957 if (!SearchDecl && S) {
4958 if (DeclContext *DC = static_cast<DeclContext *>(S->getEntity())) {
4959 SearchDecl = dyn_cast<ObjCContainerDecl>(DC);
4960 CurrentDecl = SearchDecl;
4961 }
4962 }
4963
4964 if (!SearchDecl || !CurrentDecl) {
Douglas Gregore6b1bb62010-08-11 21:23:17 +00004965 HandleCodeCompleteResults(this, CodeCompleter,
4966 CodeCompletionContext::CCC_Other,
4967 0, 0);
Douglas Gregore8f5a172010-04-07 00:21:17 +00004968 return;
4969 }
4970
4971 // Find all of the methods that we could declare/implement here.
4972 KnownMethodsMap KnownMethods;
4973 FindImplementableMethods(Context, SearchDecl, IsInstanceMethod,
4974 ReturnType, IsInImplementation, KnownMethods);
4975
4976 // Erase any methods that have already been declared or
4977 // implemented here.
4978 for (ObjCContainerDecl::method_iterator M = CurrentDecl->meth_begin(),
4979 MEnd = CurrentDecl->meth_end();
4980 M != MEnd; ++M) {
4981 if ((*M)->isInstanceMethod() != IsInstanceMethod)
4982 continue;
4983
4984 KnownMethodsMap::iterator Pos = KnownMethods.find((*M)->getSelector());
4985 if (Pos != KnownMethods.end())
4986 KnownMethods.erase(Pos);
4987 }
4988
4989 // Add declarations or definitions for each of the known methods.
John McCall0a2c5e22010-08-25 06:19:51 +00004990 typedef CodeCompletionResult Result;
Douglas Gregore8f5a172010-04-07 00:21:17 +00004991 ResultBuilder Results(*this);
4992 Results.EnterNewScope();
4993 PrintingPolicy Policy(Context.PrintingPolicy);
4994 Policy.AnonymousTagLocations = false;
4995 for (KnownMethodsMap::iterator M = KnownMethods.begin(),
4996 MEnd = KnownMethods.end();
4997 M != MEnd; ++M) {
Douglas Gregor408be5a2010-08-25 01:08:01 +00004998 ObjCMethodDecl *Method = M->second.first;
Douglas Gregore8f5a172010-04-07 00:21:17 +00004999 CodeCompletionString *Pattern = new CodeCompletionString;
5000
5001 // If the result type was not already provided, add it to the
5002 // pattern as (type).
5003 if (ReturnType.isNull()) {
5004 std::string TypeStr;
5005 Method->getResultType().getAsStringInternal(TypeStr, Policy);
5006 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
5007 Pattern->AddTextChunk(TypeStr);
5008 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
5009 }
5010
5011 Selector Sel = Method->getSelector();
5012
5013 // Add the first part of the selector to the pattern.
5014 Pattern->AddTypedTextChunk(Sel.getIdentifierInfoForSlot(0)->getName());
5015
5016 // Add parameters to the pattern.
5017 unsigned I = 0;
5018 for (ObjCMethodDecl::param_iterator P = Method->param_begin(),
5019 PEnd = Method->param_end();
5020 P != PEnd; (void)++P, ++I) {
5021 // Add the part of the selector name.
5022 if (I == 0)
5023 Pattern->AddChunk(CodeCompletionString::CK_Colon);
5024 else if (I < Sel.getNumArgs()) {
5025 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
Douglas Gregor47c03a72010-08-17 15:53:35 +00005026 Pattern->AddTextChunk(Sel.getIdentifierInfoForSlot(I)->getName());
Douglas Gregore8f5a172010-04-07 00:21:17 +00005027 Pattern->AddChunk(CodeCompletionString::CK_Colon);
5028 } else
5029 break;
5030
5031 // Add the parameter type.
5032 std::string TypeStr;
5033 (*P)->getOriginalType().getAsStringInternal(TypeStr, Policy);
5034 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
5035 Pattern->AddTextChunk(TypeStr);
5036 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
5037
5038 if (IdentifierInfo *Id = (*P)->getIdentifier())
Douglas Gregore17794f2010-08-31 05:13:43 +00005039 Pattern->AddTextChunk(Id->getName());
Douglas Gregore8f5a172010-04-07 00:21:17 +00005040 }
5041
5042 if (Method->isVariadic()) {
5043 if (Method->param_size() > 0)
5044 Pattern->AddChunk(CodeCompletionString::CK_Comma);
5045 Pattern->AddTextChunk("...");
Douglas Gregore17794f2010-08-31 05:13:43 +00005046 }
Douglas Gregore8f5a172010-04-07 00:21:17 +00005047
Douglas Gregor447107d2010-05-28 00:57:46 +00005048 if (IsInImplementation && Results.includeCodePatterns()) {
Douglas Gregore8f5a172010-04-07 00:21:17 +00005049 // We will be defining the method here, so add a compound statement.
5050 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
5051 Pattern->AddChunk(CodeCompletionString::CK_LeftBrace);
5052 Pattern->AddChunk(CodeCompletionString::CK_VerticalSpace);
5053 if (!Method->getResultType()->isVoidType()) {
5054 // If the result type is not void, add a return clause.
5055 Pattern->AddTextChunk("return");
5056 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
5057 Pattern->AddPlaceholderChunk("expression");
5058 Pattern->AddChunk(CodeCompletionString::CK_SemiColon);
5059 } else
5060 Pattern->AddPlaceholderChunk("statements");
5061
5062 Pattern->AddChunk(CodeCompletionString::CK_VerticalSpace);
5063 Pattern->AddChunk(CodeCompletionString::CK_RightBrace);
5064 }
5065
Douglas Gregor408be5a2010-08-25 01:08:01 +00005066 unsigned Priority = CCP_CodePattern;
5067 if (!M->second.second)
5068 Priority += CCD_InBaseClass;
5069
5070 Results.AddResult(Result(Pattern, Priority,
Douglas Gregor16ed9ad2010-08-17 16:06:07 +00005071 Method->isInstanceMethod()
5072 ? CXCursor_ObjCInstanceMethodDecl
5073 : CXCursor_ObjCClassMethodDecl));
Douglas Gregore8f5a172010-04-07 00:21:17 +00005074 }
5075
5076 Results.ExitScope();
5077
Douglas Gregore6b1bb62010-08-11 21:23:17 +00005078 HandleCodeCompleteResults(this, CodeCompleter,
5079 CodeCompletionContext::CCC_Other,
5080 Results.data(),Results.size());
Douglas Gregore8f5a172010-04-07 00:21:17 +00005081}
Douglas Gregor1f5537a2010-07-08 23:20:03 +00005082
5083void Sema::CodeCompleteObjCMethodDeclSelector(Scope *S,
5084 bool IsInstanceMethod,
Douglas Gregor40ed9a12010-07-08 23:37:41 +00005085 bool AtParameterName,
John McCallb3d87482010-08-24 05:47:05 +00005086 ParsedType ReturnTy,
Douglas Gregor1f5537a2010-07-08 23:20:03 +00005087 IdentifierInfo **SelIdents,
5088 unsigned NumSelIdents) {
Douglas Gregor1f5537a2010-07-08 23:20:03 +00005089 // If we have an external source, load the entire class method
Sebastian Redl3c7f4132010-08-18 23:57:06 +00005090 // pool from the AST file.
Douglas Gregor1f5537a2010-07-08 23:20:03 +00005091 if (ExternalSource) {
5092 for (uint32_t I = 0, N = ExternalSource->GetNumExternalSelectors();
5093 I != N; ++I) {
5094 Selector Sel = ExternalSource->GetExternalSelector(I);
Sebastian Redldb9d2142010-08-02 23:18:59 +00005095 if (Sel.isNull() || MethodPool.count(Sel))
Douglas Gregor1f5537a2010-07-08 23:20:03 +00005096 continue;
Sebastian Redldb9d2142010-08-02 23:18:59 +00005097
5098 ReadMethodPool(Sel);
Douglas Gregor1f5537a2010-07-08 23:20:03 +00005099 }
5100 }
5101
5102 // Build the set of methods we can see.
John McCall0a2c5e22010-08-25 06:19:51 +00005103 typedef CodeCompletionResult Result;
Douglas Gregor1f5537a2010-07-08 23:20:03 +00005104 ResultBuilder Results(*this);
5105
5106 if (ReturnTy)
5107 Results.setPreferredType(GetTypeFromParser(ReturnTy).getNonReferenceType());
Sebastian Redldb9d2142010-08-02 23:18:59 +00005108
Douglas Gregor1f5537a2010-07-08 23:20:03 +00005109 Results.EnterNewScope();
Sebastian Redldb9d2142010-08-02 23:18:59 +00005110 for (GlobalMethodPool::iterator M = MethodPool.begin(),
5111 MEnd = MethodPool.end();
5112 M != MEnd; ++M) {
5113 for (ObjCMethodList *MethList = IsInstanceMethod ? &M->second.first :
5114 &M->second.second;
5115 MethList && MethList->Method;
Douglas Gregor1f5537a2010-07-08 23:20:03 +00005116 MethList = MethList->Next) {
5117 if (!isAcceptableObjCMethod(MethList->Method, MK_Any, SelIdents,
5118 NumSelIdents))
5119 continue;
5120
Douglas Gregor40ed9a12010-07-08 23:37:41 +00005121 if (AtParameterName) {
5122 // Suggest parameter names we've seen before.
5123 if (NumSelIdents && NumSelIdents <= MethList->Method->param_size()) {
5124 ParmVarDecl *Param = MethList->Method->param_begin()[NumSelIdents-1];
5125 if (Param->getIdentifier()) {
5126 CodeCompletionString *Pattern = new CodeCompletionString;
5127 Pattern->AddTypedTextChunk(Param->getIdentifier()->getName());
5128 Results.AddResult(Pattern);
5129 }
5130 }
5131
5132 continue;
5133 }
5134
Douglas Gregor1f5537a2010-07-08 23:20:03 +00005135 Result R(MethList->Method, 0);
5136 R.StartParameter = NumSelIdents;
5137 R.AllParametersAreInformative = false;
5138 R.DeclaringEntity = true;
5139 Results.MaybeAddResult(R, CurContext);
5140 }
5141 }
5142
5143 Results.ExitScope();
Douglas Gregore6b1bb62010-08-11 21:23:17 +00005144 HandleCodeCompleteResults(this, CodeCompleter,
5145 CodeCompletionContext::CCC_Other,
5146 Results.data(),Results.size());
Douglas Gregor1f5537a2010-07-08 23:20:03 +00005147}
Douglas Gregor87c08a52010-08-13 22:48:40 +00005148
Douglas Gregorf29c5232010-08-24 22:20:20 +00005149void Sema::CodeCompletePreprocessorDirective(bool InConditional) {
Douglas Gregorf44e8542010-08-24 19:08:16 +00005150 ResultBuilder Results(*this);
5151 Results.EnterNewScope();
5152
5153 // #if <condition>
5154 CodeCompletionString *Pattern = new CodeCompletionString;
5155 Pattern->AddTypedTextChunk("if");
5156 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
5157 Pattern->AddPlaceholderChunk("condition");
5158 Results.AddResult(Pattern);
5159
5160 // #ifdef <macro>
5161 Pattern = new CodeCompletionString;
5162 Pattern->AddTypedTextChunk("ifdef");
5163 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
5164 Pattern->AddPlaceholderChunk("macro");
5165 Results.AddResult(Pattern);
5166
5167 // #ifndef <macro>
5168 Pattern = new CodeCompletionString;
5169 Pattern->AddTypedTextChunk("ifndef");
5170 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
5171 Pattern->AddPlaceholderChunk("macro");
5172 Results.AddResult(Pattern);
5173
5174 if (InConditional) {
5175 // #elif <condition>
5176 Pattern = new CodeCompletionString;
5177 Pattern->AddTypedTextChunk("elif");
5178 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
5179 Pattern->AddPlaceholderChunk("condition");
5180 Results.AddResult(Pattern);
5181
5182 // #else
5183 Pattern = new CodeCompletionString;
5184 Pattern->AddTypedTextChunk("else");
5185 Results.AddResult(Pattern);
5186
5187 // #endif
5188 Pattern = new CodeCompletionString;
5189 Pattern->AddTypedTextChunk("endif");
5190 Results.AddResult(Pattern);
5191 }
5192
5193 // #include "header"
5194 Pattern = new CodeCompletionString;
5195 Pattern->AddTypedTextChunk("include");
5196 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
5197 Pattern->AddTextChunk("\"");
5198 Pattern->AddPlaceholderChunk("header");
5199 Pattern->AddTextChunk("\"");
5200 Results.AddResult(Pattern);
5201
5202 // #include <header>
5203 Pattern = new CodeCompletionString;
5204 Pattern->AddTypedTextChunk("include");
5205 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
5206 Pattern->AddTextChunk("<");
5207 Pattern->AddPlaceholderChunk("header");
5208 Pattern->AddTextChunk(">");
5209 Results.AddResult(Pattern);
5210
5211 // #define <macro>
5212 Pattern = new CodeCompletionString;
5213 Pattern->AddTypedTextChunk("define");
5214 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
5215 Pattern->AddPlaceholderChunk("macro");
5216 Results.AddResult(Pattern);
5217
5218 // #define <macro>(<args>)
5219 Pattern = new CodeCompletionString;
5220 Pattern->AddTypedTextChunk("define");
5221 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
5222 Pattern->AddPlaceholderChunk("macro");
5223 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
5224 Pattern->AddPlaceholderChunk("args");
5225 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
5226 Results.AddResult(Pattern);
5227
5228 // #undef <macro>
5229 Pattern = new CodeCompletionString;
5230 Pattern->AddTypedTextChunk("undef");
5231 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
5232 Pattern->AddPlaceholderChunk("macro");
5233 Results.AddResult(Pattern);
5234
5235 // #line <number>
5236 Pattern = new CodeCompletionString;
5237 Pattern->AddTypedTextChunk("line");
5238 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
5239 Pattern->AddPlaceholderChunk("number");
5240 Results.AddResult(Pattern);
5241
5242 // #line <number> "filename"
5243 Pattern = new CodeCompletionString;
5244 Pattern->AddTypedTextChunk("line");
5245 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
5246 Pattern->AddPlaceholderChunk("number");
5247 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
5248 Pattern->AddTextChunk("\"");
5249 Pattern->AddPlaceholderChunk("filename");
5250 Pattern->AddTextChunk("\"");
5251 Results.AddResult(Pattern);
5252
5253 // #error <message>
5254 Pattern = new CodeCompletionString;
5255 Pattern->AddTypedTextChunk("error");
5256 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
5257 Pattern->AddPlaceholderChunk("message");
5258 Results.AddResult(Pattern);
5259
5260 // #pragma <arguments>
5261 Pattern = new CodeCompletionString;
5262 Pattern->AddTypedTextChunk("pragma");
5263 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
5264 Pattern->AddPlaceholderChunk("arguments");
5265 Results.AddResult(Pattern);
5266
5267 if (getLangOptions().ObjC1) {
5268 // #import "header"
5269 Pattern = new CodeCompletionString;
5270 Pattern->AddTypedTextChunk("import");
5271 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
5272 Pattern->AddTextChunk("\"");
5273 Pattern->AddPlaceholderChunk("header");
5274 Pattern->AddTextChunk("\"");
5275 Results.AddResult(Pattern);
5276
5277 // #import <header>
5278 Pattern = new CodeCompletionString;
5279 Pattern->AddTypedTextChunk("import");
5280 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
5281 Pattern->AddTextChunk("<");
5282 Pattern->AddPlaceholderChunk("header");
5283 Pattern->AddTextChunk(">");
5284 Results.AddResult(Pattern);
5285 }
5286
5287 // #include_next "header"
5288 Pattern = new CodeCompletionString;
5289 Pattern->AddTypedTextChunk("include_next");
5290 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
5291 Pattern->AddTextChunk("\"");
5292 Pattern->AddPlaceholderChunk("header");
5293 Pattern->AddTextChunk("\"");
5294 Results.AddResult(Pattern);
5295
5296 // #include_next <header>
5297 Pattern = new CodeCompletionString;
5298 Pattern->AddTypedTextChunk("include_next");
5299 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
5300 Pattern->AddTextChunk("<");
5301 Pattern->AddPlaceholderChunk("header");
5302 Pattern->AddTextChunk(">");
5303 Results.AddResult(Pattern);
5304
5305 // #warning <message>
5306 Pattern = new CodeCompletionString;
5307 Pattern->AddTypedTextChunk("warning");
5308 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
5309 Pattern->AddPlaceholderChunk("message");
5310 Results.AddResult(Pattern);
5311
5312 // Note: #ident and #sccs are such crazy anachronisms that we don't provide
5313 // completions for them. And __include_macros is a Clang-internal extension
5314 // that we don't want to encourage anyone to use.
5315
5316 // FIXME: we don't support #assert or #unassert, so don't suggest them.
5317 Results.ExitScope();
5318
Douglas Gregorf44e8542010-08-24 19:08:16 +00005319 HandleCodeCompleteResults(this, CodeCompleter,
Douglas Gregor721f3592010-08-25 18:41:16 +00005320 CodeCompletionContext::CCC_PreprocessorDirective,
Douglas Gregorf44e8542010-08-24 19:08:16 +00005321 Results.data(), Results.size());
5322}
5323
5324void Sema::CodeCompleteInPreprocessorConditionalExclusion(Scope *S) {
Douglas Gregorf29c5232010-08-24 22:20:20 +00005325 CodeCompleteOrdinaryName(S,
John McCallf312b1e2010-08-26 23:41:50 +00005326 S->getFnParent()? Sema::PCC_RecoveryInFunction
5327 : Sema::PCC_Namespace);
Douglas Gregorf44e8542010-08-24 19:08:16 +00005328}
5329
Douglas Gregorf29c5232010-08-24 22:20:20 +00005330void Sema::CodeCompletePreprocessorMacroName(bool IsDefinition) {
Douglas Gregor1fbb4472010-08-24 20:21:13 +00005331 ResultBuilder Results(*this);
5332 if (!IsDefinition && (!CodeCompleter || CodeCompleter->includeMacros())) {
5333 // Add just the names of macros, not their arguments.
5334 Results.EnterNewScope();
5335 for (Preprocessor::macro_iterator M = PP.macro_begin(),
5336 MEnd = PP.macro_end();
5337 M != MEnd; ++M) {
5338 CodeCompletionString *Pattern = new CodeCompletionString;
5339 Pattern->AddTypedTextChunk(M->first->getName());
5340 Results.AddResult(Pattern);
5341 }
5342 Results.ExitScope();
5343 } else if (IsDefinition) {
5344 // FIXME: Can we detect when the user just wrote an include guard above?
5345 }
5346
5347 HandleCodeCompleteResults(this, CodeCompleter,
5348 IsDefinition? CodeCompletionContext::CCC_MacroName
5349 : CodeCompletionContext::CCC_MacroNameUse,
5350 Results.data(), Results.size());
5351}
5352
Douglas Gregorf29c5232010-08-24 22:20:20 +00005353void Sema::CodeCompletePreprocessorExpression() {
5354 ResultBuilder Results(*this);
5355
5356 if (!CodeCompleter || CodeCompleter->includeMacros())
5357 AddMacroResults(PP, Results);
5358
5359 // defined (<macro>)
5360 Results.EnterNewScope();
5361 CodeCompletionString *Pattern = new CodeCompletionString;
5362 Pattern->AddTypedTextChunk("defined");
5363 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
5364 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
5365 Pattern->AddPlaceholderChunk("macro");
5366 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
5367 Results.AddResult(Pattern);
5368 Results.ExitScope();
5369
5370 HandleCodeCompleteResults(this, CodeCompleter,
5371 CodeCompletionContext::CCC_PreprocessorExpression,
5372 Results.data(), Results.size());
5373}
5374
5375void Sema::CodeCompletePreprocessorMacroArgument(Scope *S,
5376 IdentifierInfo *Macro,
5377 MacroInfo *MacroInfo,
5378 unsigned Argument) {
5379 // FIXME: In the future, we could provide "overload" results, much like we
5380 // do for function calls.
5381
5382 CodeCompleteOrdinaryName(S,
John McCallf312b1e2010-08-26 23:41:50 +00005383 S->getFnParent()? Sema::PCC_RecoveryInFunction
5384 : Sema::PCC_Namespace);
Douglas Gregorf29c5232010-08-24 22:20:20 +00005385}
5386
Douglas Gregor55817af2010-08-25 17:04:25 +00005387void Sema::CodeCompleteNaturalLanguage() {
Douglas Gregor55817af2010-08-25 17:04:25 +00005388 HandleCodeCompleteResults(this, CodeCompleter,
Douglas Gregoraf1c6b52010-08-25 17:10:00 +00005389 CodeCompletionContext::CCC_NaturalLanguage,
Douglas Gregor55817af2010-08-25 17:04:25 +00005390 0, 0);
5391}
5392
Douglas Gregor87c08a52010-08-13 22:48:40 +00005393void Sema::GatherGlobalCodeCompletions(
John McCall0a2c5e22010-08-25 06:19:51 +00005394 llvm::SmallVectorImpl<CodeCompletionResult> &Results) {
Douglas Gregor87c08a52010-08-13 22:48:40 +00005395 ResultBuilder Builder(*this);
5396
Douglas Gregor8071e422010-08-15 06:18:01 +00005397 if (!CodeCompleter || CodeCompleter->includeGlobals()) {
5398 CodeCompletionDeclConsumer Consumer(Builder,
5399 Context.getTranslationUnitDecl());
5400 LookupVisibleDecls(Context.getTranslationUnitDecl(), LookupAnyName,
5401 Consumer);
5402 }
Douglas Gregor87c08a52010-08-13 22:48:40 +00005403
5404 if (!CodeCompleter || CodeCompleter->includeMacros())
5405 AddMacroResults(PP, Builder);
5406
5407 Results.clear();
5408 Results.insert(Results.end(),
5409 Builder.data(), Builder.data() + Builder.size());
5410}