blob: fd6b5518d7023d69ed4a091bf1ddb480bbeadbbf [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
Douglas Gregor78edf512010-09-15 16:23:04 +00002731void Sema::CodeCompletePostfixExpression(Scope *S, Expr *E) {
2732 if (getLangOptions().ObjC1)
2733 CodeCompleteObjCInstanceMessage(S, E, 0, 0, false);
2734}
Douglas Gregor5ac3bdb2010-05-30 01:49:25 +00002735
Douglas Gregor95ac6552009-11-18 01:29:26 +00002736static void AddObjCProperties(ObjCContainerDecl *Container,
Douglas Gregor322328b2009-11-18 22:32:06 +00002737 bool AllowCategories,
Douglas Gregor95ac6552009-11-18 01:29:26 +00002738 DeclContext *CurContext,
2739 ResultBuilder &Results) {
John McCall0a2c5e22010-08-25 06:19:51 +00002740 typedef CodeCompletionResult Result;
Douglas Gregor95ac6552009-11-18 01:29:26 +00002741
2742 // Add properties in this container.
2743 for (ObjCContainerDecl::prop_iterator P = Container->prop_begin(),
2744 PEnd = Container->prop_end();
2745 P != PEnd;
2746 ++P)
2747 Results.MaybeAddResult(Result(*P, 0), CurContext);
2748
2749 // Add properties in referenced protocols.
2750 if (ObjCProtocolDecl *Protocol = dyn_cast<ObjCProtocolDecl>(Container)) {
2751 for (ObjCProtocolDecl::protocol_iterator P = Protocol->protocol_begin(),
2752 PEnd = Protocol->protocol_end();
2753 P != PEnd; ++P)
Douglas Gregor322328b2009-11-18 22:32:06 +00002754 AddObjCProperties(*P, AllowCategories, CurContext, Results);
Douglas Gregor95ac6552009-11-18 01:29:26 +00002755 } else if (ObjCInterfaceDecl *IFace = dyn_cast<ObjCInterfaceDecl>(Container)){
Douglas Gregor322328b2009-11-18 22:32:06 +00002756 if (AllowCategories) {
2757 // Look through categories.
2758 for (ObjCCategoryDecl *Category = IFace->getCategoryList();
2759 Category; Category = Category->getNextClassCategory())
2760 AddObjCProperties(Category, AllowCategories, CurContext, Results);
2761 }
Douglas Gregor95ac6552009-11-18 01:29:26 +00002762
2763 // Look through protocols.
Ted Kremenek53b94412010-09-01 01:21:15 +00002764 for (ObjCInterfaceDecl::all_protocol_iterator
2765 I = IFace->all_referenced_protocol_begin(),
2766 E = IFace->all_referenced_protocol_end(); I != E; ++I)
Douglas Gregor322328b2009-11-18 22:32:06 +00002767 AddObjCProperties(*I, AllowCategories, CurContext, Results);
Douglas Gregor95ac6552009-11-18 01:29:26 +00002768
2769 // Look in the superclass.
2770 if (IFace->getSuperClass())
Douglas Gregor322328b2009-11-18 22:32:06 +00002771 AddObjCProperties(IFace->getSuperClass(), AllowCategories, CurContext,
2772 Results);
Douglas Gregor95ac6552009-11-18 01:29:26 +00002773 } else if (const ObjCCategoryDecl *Category
2774 = dyn_cast<ObjCCategoryDecl>(Container)) {
2775 // Look through protocols.
Ted Kremenek53b94412010-09-01 01:21:15 +00002776 for (ObjCCategoryDecl::protocol_iterator P = Category->protocol_begin(),
2777 PEnd = Category->protocol_end();
Douglas Gregor95ac6552009-11-18 01:29:26 +00002778 P != PEnd; ++P)
Douglas Gregor322328b2009-11-18 22:32:06 +00002779 AddObjCProperties(*P, AllowCategories, CurContext, Results);
Douglas Gregor95ac6552009-11-18 01:29:26 +00002780 }
2781}
2782
Douglas Gregor81b747b2009-09-17 21:32:03 +00002783void Sema::CodeCompleteMemberReferenceExpr(Scope *S, ExprTy *BaseE,
2784 SourceLocation OpLoc,
2785 bool IsArrow) {
2786 if (!BaseE || !CodeCompleter)
2787 return;
2788
John McCall0a2c5e22010-08-25 06:19:51 +00002789 typedef CodeCompletionResult Result;
Douglas Gregor86d9a522009-09-21 16:56:56 +00002790
Douglas Gregor81b747b2009-09-17 21:32:03 +00002791 Expr *Base = static_cast<Expr *>(BaseE);
2792 QualType BaseType = Base->getType();
Douglas Gregor86d9a522009-09-21 16:56:56 +00002793
2794 if (IsArrow) {
2795 if (const PointerType *Ptr = BaseType->getAs<PointerType>())
2796 BaseType = Ptr->getPointeeType();
2797 else if (BaseType->isObjCObjectPointerType())
Douglas Gregor3cdee122010-08-26 16:36:48 +00002798 /*Do nothing*/ ;
Douglas Gregor86d9a522009-09-21 16:56:56 +00002799 else
2800 return;
2801 }
2802
Douglas Gregoreb5758b2009-09-23 22:26:46 +00002803 ResultBuilder Results(*this, &ResultBuilder::IsMember);
Douglas Gregor95ac6552009-11-18 01:29:26 +00002804 Results.EnterNewScope();
2805 if (const RecordType *Record = BaseType->getAs<RecordType>()) {
Douglas Gregor3cdee122010-08-26 16:36:48 +00002806 // Indicate that we are performing a member access, and the cv-qualifiers
2807 // for the base object type.
2808 Results.setObjectTypeQualifiers(BaseType.getQualifiers());
2809
Douglas Gregor95ac6552009-11-18 01:29:26 +00002810 // Access to a C/C++ class, struct, or union.
Douglas Gregor45bcd432010-01-14 03:21:49 +00002811 Results.allowNestedNameSpecifiers();
Douglas Gregor0cc84042010-01-14 15:47:35 +00002812 CodeCompletionDeclConsumer Consumer(Results, CurContext);
Douglas Gregor8071e422010-08-15 06:18:01 +00002813 LookupVisibleDecls(Record->getDecl(), LookupMemberName, Consumer,
2814 CodeCompleter->includeGlobals());
Daniel Dunbar3a2838d2009-11-13 08:58:20 +00002815
Douglas Gregor95ac6552009-11-18 01:29:26 +00002816 if (getLangOptions().CPlusPlus) {
2817 if (!Results.empty()) {
2818 // The "template" keyword can follow "->" or "." in the grammar.
2819 // However, we only want to suggest the template keyword if something
2820 // is dependent.
2821 bool IsDependent = BaseType->isDependentType();
2822 if (!IsDependent) {
2823 for (Scope *DepScope = S; DepScope; DepScope = DepScope->getParent())
2824 if (DeclContext *Ctx = (DeclContext *)DepScope->getEntity()) {
2825 IsDependent = Ctx->isDependentContext();
2826 break;
2827 }
2828 }
Daniel Dunbar3a2838d2009-11-13 08:58:20 +00002829
Douglas Gregor95ac6552009-11-18 01:29:26 +00002830 if (IsDependent)
Douglas Gregora4477812010-01-14 16:01:26 +00002831 Results.AddResult(Result("template"));
Daniel Dunbar3a2838d2009-11-13 08:58:20 +00002832 }
Daniel Dunbar3a2838d2009-11-13 08:58:20 +00002833 }
Douglas Gregor95ac6552009-11-18 01:29:26 +00002834 } else if (!IsArrow && BaseType->getAsObjCInterfacePointerType()) {
2835 // Objective-C property reference.
2836
2837 // Add property results based on our interface.
2838 const ObjCObjectPointerType *ObjCPtr
2839 = BaseType->getAsObjCInterfacePointerType();
2840 assert(ObjCPtr && "Non-NULL pointer guaranteed above!");
Douglas Gregor322328b2009-11-18 22:32:06 +00002841 AddObjCProperties(ObjCPtr->getInterfaceDecl(), true, CurContext, Results);
Douglas Gregor95ac6552009-11-18 01:29:26 +00002842
2843 // Add properties from the protocols in a qualified interface.
2844 for (ObjCObjectPointerType::qual_iterator I = ObjCPtr->qual_begin(),
2845 E = ObjCPtr->qual_end();
2846 I != E; ++I)
Douglas Gregor322328b2009-11-18 22:32:06 +00002847 AddObjCProperties(*I, true, CurContext, Results);
Douglas Gregor95ac6552009-11-18 01:29:26 +00002848 } else if ((IsArrow && BaseType->isObjCObjectPointerType()) ||
John McCallc12c5bb2010-05-15 11:32:37 +00002849 (!IsArrow && BaseType->isObjCObjectType())) {
Douglas Gregor95ac6552009-11-18 01:29:26 +00002850 // Objective-C instance variable access.
2851 ObjCInterfaceDecl *Class = 0;
2852 if (const ObjCObjectPointerType *ObjCPtr
2853 = BaseType->getAs<ObjCObjectPointerType>())
2854 Class = ObjCPtr->getInterfaceDecl();
2855 else
John McCallc12c5bb2010-05-15 11:32:37 +00002856 Class = BaseType->getAs<ObjCObjectType>()->getInterface();
Douglas Gregor95ac6552009-11-18 01:29:26 +00002857
2858 // Add all ivars from this class and its superclasses.
Douglas Gregor80f4f4c2010-01-14 16:08:12 +00002859 if (Class) {
2860 CodeCompletionDeclConsumer Consumer(Results, CurContext);
2861 Results.setFilter(&ResultBuilder::IsObjCIvar);
Douglas Gregor8071e422010-08-15 06:18:01 +00002862 LookupVisibleDecls(Class, LookupMemberName, Consumer,
2863 CodeCompleter->includeGlobals());
Douglas Gregor95ac6552009-11-18 01:29:26 +00002864 }
Douglas Gregor86d9a522009-09-21 16:56:56 +00002865 }
Douglas Gregor95ac6552009-11-18 01:29:26 +00002866
2867 // FIXME: How do we cope with isa?
2868
2869 Results.ExitScope();
Daniel Dunbar3a2838d2009-11-13 08:58:20 +00002870
Daniel Dunbar3a2838d2009-11-13 08:58:20 +00002871 // Hand off the results found for code completion.
Douglas Gregore6b1bb62010-08-11 21:23:17 +00002872 HandleCodeCompleteResults(this, CodeCompleter,
2873 CodeCompletionContext(CodeCompletionContext::CCC_MemberAccess,
2874 BaseType),
2875 Results.data(),Results.size());
Douglas Gregor81b747b2009-09-17 21:32:03 +00002876}
2877
Douglas Gregor374929f2009-09-18 15:37:17 +00002878void Sema::CodeCompleteTag(Scope *S, unsigned TagSpec) {
2879 if (!CodeCompleter)
2880 return;
2881
John McCall0a2c5e22010-08-25 06:19:51 +00002882 typedef CodeCompletionResult Result;
Douglas Gregor86d9a522009-09-21 16:56:56 +00002883 ResultBuilder::LookupFilter Filter = 0;
Douglas Gregore6b1bb62010-08-11 21:23:17 +00002884 enum CodeCompletionContext::Kind ContextKind
2885 = CodeCompletionContext::CCC_Other;
Douglas Gregor374929f2009-09-18 15:37:17 +00002886 switch ((DeclSpec::TST)TagSpec) {
2887 case DeclSpec::TST_enum:
Douglas Gregor86d9a522009-09-21 16:56:56 +00002888 Filter = &ResultBuilder::IsEnum;
Douglas Gregore6b1bb62010-08-11 21:23:17 +00002889 ContextKind = CodeCompletionContext::CCC_EnumTag;
Douglas Gregor374929f2009-09-18 15:37:17 +00002890 break;
2891
2892 case DeclSpec::TST_union:
Douglas Gregor86d9a522009-09-21 16:56:56 +00002893 Filter = &ResultBuilder::IsUnion;
Douglas Gregore6b1bb62010-08-11 21:23:17 +00002894 ContextKind = CodeCompletionContext::CCC_UnionTag;
Douglas Gregor374929f2009-09-18 15:37:17 +00002895 break;
2896
2897 case DeclSpec::TST_struct:
Douglas Gregor374929f2009-09-18 15:37:17 +00002898 case DeclSpec::TST_class:
Douglas Gregor86d9a522009-09-21 16:56:56 +00002899 Filter = &ResultBuilder::IsClassOrStruct;
Douglas Gregore6b1bb62010-08-11 21:23:17 +00002900 ContextKind = CodeCompletionContext::CCC_ClassOrStructTag;
Douglas Gregor374929f2009-09-18 15:37:17 +00002901 break;
2902
2903 default:
2904 assert(false && "Unknown type specifier kind in CodeCompleteTag");
2905 return;
2906 }
Douglas Gregor86d9a522009-09-21 16:56:56 +00002907
John McCall0d6b1642010-04-23 18:46:30 +00002908 ResultBuilder Results(*this);
Douglas Gregor5d2fc402010-01-14 03:27:13 +00002909 CodeCompletionDeclConsumer Consumer(Results, CurContext);
John McCall0d6b1642010-04-23 18:46:30 +00002910
2911 // First pass: look for tags.
2912 Results.setFilter(Filter);
Douglas Gregor8071e422010-08-15 06:18:01 +00002913 LookupVisibleDecls(S, LookupTagName, Consumer,
2914 CodeCompleter->includeGlobals());
John McCall0d6b1642010-04-23 18:46:30 +00002915
Douglas Gregor8071e422010-08-15 06:18:01 +00002916 if (CodeCompleter->includeGlobals()) {
2917 // Second pass: look for nested name specifiers.
2918 Results.setFilter(&ResultBuilder::IsNestedNameSpecifier);
2919 LookupVisibleDecls(S, LookupNestedNameSpecifierName, Consumer);
2920 }
Douglas Gregor86d9a522009-09-21 16:56:56 +00002921
Douglas Gregore6b1bb62010-08-11 21:23:17 +00002922 HandleCodeCompleteResults(this, CodeCompleter, ContextKind,
2923 Results.data(),Results.size());
Douglas Gregor374929f2009-09-18 15:37:17 +00002924}
2925
Douglas Gregor1a480c42010-08-27 17:35:51 +00002926void Sema::CodeCompleteTypeQualifiers(DeclSpec &DS) {
2927 ResultBuilder Results(*this);
2928 Results.EnterNewScope();
2929 if (!(DS.getTypeQualifiers() & DeclSpec::TQ_const))
2930 Results.AddResult("const");
2931 if (!(DS.getTypeQualifiers() & DeclSpec::TQ_volatile))
2932 Results.AddResult("volatile");
2933 if (getLangOptions().C99 &&
2934 !(DS.getTypeQualifiers() & DeclSpec::TQ_restrict))
2935 Results.AddResult("restrict");
2936 Results.ExitScope();
2937 HandleCodeCompleteResults(this, CodeCompleter,
2938 CodeCompletionContext::CCC_TypeQualifiers,
2939 Results.data(), Results.size());
2940}
2941
Douglas Gregor3e1005f2009-09-21 18:10:23 +00002942void Sema::CodeCompleteCase(Scope *S) {
John McCall781472f2010-08-25 08:40:02 +00002943 if (getCurFunction()->SwitchStack.empty() || !CodeCompleter)
Douglas Gregor3e1005f2009-09-21 18:10:23 +00002944 return;
2945
John McCall781472f2010-08-25 08:40:02 +00002946 SwitchStmt *Switch = getCurFunction()->SwitchStack.back();
Douglas Gregorf9578432010-07-28 21:50:18 +00002947 if (!Switch->getCond()->getType()->isEnumeralType()) {
Douglas Gregorfb629412010-08-23 21:17:50 +00002948 CodeCompleteExpressionData Data(Switch->getCond()->getType());
2949 Data.IntegralConstantExpression = true;
2950 CodeCompleteExpression(S, Data);
Douglas Gregor3e1005f2009-09-21 18:10:23 +00002951 return;
Douglas Gregorf9578432010-07-28 21:50:18 +00002952 }
Douglas Gregor3e1005f2009-09-21 18:10:23 +00002953
2954 // Code-complete the cases of a switch statement over an enumeration type
2955 // by providing the list of
2956 EnumDecl *Enum = Switch->getCond()->getType()->getAs<EnumType>()->getDecl();
2957
2958 // Determine which enumerators we have already seen in the switch statement.
2959 // FIXME: Ideally, we would also be able to look *past* the code-completion
2960 // token, in case we are code-completing in the middle of the switch and not
2961 // at the end. However, we aren't able to do so at the moment.
2962 llvm::SmallPtrSet<EnumConstantDecl *, 8> EnumeratorsSeen;
Douglas Gregorb9d0ef72009-09-21 19:57:38 +00002963 NestedNameSpecifier *Qualifier = 0;
Douglas Gregor3e1005f2009-09-21 18:10:23 +00002964 for (SwitchCase *SC = Switch->getSwitchCaseList(); SC;
2965 SC = SC->getNextSwitchCase()) {
2966 CaseStmt *Case = dyn_cast<CaseStmt>(SC);
2967 if (!Case)
2968 continue;
2969
2970 Expr *CaseVal = Case->getLHS()->IgnoreParenCasts();
2971 if (DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(CaseVal))
2972 if (EnumConstantDecl *Enumerator
2973 = dyn_cast<EnumConstantDecl>(DRE->getDecl())) {
2974 // We look into the AST of the case statement to determine which
2975 // enumerator was named. Alternatively, we could compute the value of
2976 // the integral constant expression, then compare it against the
2977 // values of each enumerator. However, value-based approach would not
2978 // work as well with C++ templates where enumerators declared within a
2979 // template are type- and value-dependent.
2980 EnumeratorsSeen.insert(Enumerator);
2981
Douglas Gregorb9d0ef72009-09-21 19:57:38 +00002982 // If this is a qualified-id, keep track of the nested-name-specifier
2983 // so that we can reproduce it as part of code completion, e.g.,
Douglas Gregor3e1005f2009-09-21 18:10:23 +00002984 //
2985 // switch (TagD.getKind()) {
2986 // case TagDecl::TK_enum:
2987 // break;
2988 // case XXX
2989 //
Douglas Gregorb9d0ef72009-09-21 19:57:38 +00002990 // At the XXX, our completions are TagDecl::TK_union,
Douglas Gregor3e1005f2009-09-21 18:10:23 +00002991 // TagDecl::TK_struct, and TagDecl::TK_class, rather than TK_union,
2992 // TK_struct, and TK_class.
Douglas Gregora2813ce2009-10-23 18:54:35 +00002993 Qualifier = DRE->getQualifier();
Douglas Gregor3e1005f2009-09-21 18:10:23 +00002994 }
2995 }
2996
Douglas Gregorb9d0ef72009-09-21 19:57:38 +00002997 if (getLangOptions().CPlusPlus && !Qualifier && EnumeratorsSeen.empty()) {
2998 // If there are no prior enumerators in C++, check whether we have to
2999 // qualify the names of the enumerators that we suggest, because they
3000 // may not be visible in this scope.
3001 Qualifier = getRequiredQualification(Context, CurContext,
3002 Enum->getDeclContext());
3003
3004 // FIXME: Scoped enums need to start with "EnumDecl" as the context!
3005 }
3006
Douglas Gregor3e1005f2009-09-21 18:10:23 +00003007 // Add any enumerators that have not yet been mentioned.
3008 ResultBuilder Results(*this);
3009 Results.EnterNewScope();
3010 for (EnumDecl::enumerator_iterator E = Enum->enumerator_begin(),
3011 EEnd = Enum->enumerator_end();
3012 E != EEnd; ++E) {
3013 if (EnumeratorsSeen.count(*E))
3014 continue;
3015
John McCall0a2c5e22010-08-25 06:19:51 +00003016 Results.AddResult(CodeCompletionResult(*E, Qualifier),
Douglas Gregor608300b2010-01-14 16:14:35 +00003017 CurContext, 0, false);
Douglas Gregor3e1005f2009-09-21 18:10:23 +00003018 }
3019 Results.ExitScope();
Douglas Gregor2f880e42010-04-06 20:02:15 +00003020
Douglas Gregor0c8296d2009-11-07 00:00:49 +00003021 if (CodeCompleter->includeMacros())
Douglas Gregorbca403c2010-01-13 23:51:12 +00003022 AddMacroResults(PP, Results);
Douglas Gregore6b1bb62010-08-11 21:23:17 +00003023 HandleCodeCompleteResults(this, CodeCompleter,
3024 CodeCompletionContext::CCC_Expression,
3025 Results.data(),Results.size());
Douglas Gregor3e1005f2009-09-21 18:10:23 +00003026}
3027
Douglas Gregor9c6a0e92009-09-22 15:41:20 +00003028namespace {
3029 struct IsBetterOverloadCandidate {
3030 Sema &S;
John McCall5769d612010-02-08 23:07:23 +00003031 SourceLocation Loc;
Douglas Gregor9c6a0e92009-09-22 15:41:20 +00003032
3033 public:
John McCall5769d612010-02-08 23:07:23 +00003034 explicit IsBetterOverloadCandidate(Sema &S, SourceLocation Loc)
3035 : S(S), Loc(Loc) { }
Douglas Gregor9c6a0e92009-09-22 15:41:20 +00003036
3037 bool
3038 operator()(const OverloadCandidate &X, const OverloadCandidate &Y) const {
John McCall120d63c2010-08-24 20:38:10 +00003039 return isBetterOverloadCandidate(S, X, Y, Loc);
Douglas Gregor9c6a0e92009-09-22 15:41:20 +00003040 }
3041 };
3042}
3043
Douglas Gregord28dcd72010-05-30 06:10:08 +00003044static bool anyNullArguments(Expr **Args, unsigned NumArgs) {
3045 if (NumArgs && !Args)
3046 return true;
3047
3048 for (unsigned I = 0; I != NumArgs; ++I)
3049 if (!Args[I])
3050 return true;
3051
3052 return false;
3053}
3054
Douglas Gregor9c6a0e92009-09-22 15:41:20 +00003055void Sema::CodeCompleteCall(Scope *S, ExprTy *FnIn,
3056 ExprTy **ArgsIn, unsigned NumArgs) {
3057 if (!CodeCompleter)
3058 return;
Douglas Gregoref96eac2009-12-11 19:06:04 +00003059
3060 // When we're code-completing for a call, we fall back to ordinary
3061 // name code-completion whenever we can't produce specific
3062 // results. We may want to revisit this strategy in the future,
3063 // e.g., by merging the two kinds of results.
3064
Douglas Gregor9c6a0e92009-09-22 15:41:20 +00003065 Expr *Fn = (Expr *)FnIn;
3066 Expr **Args = (Expr **)ArgsIn;
Douglas Gregoref96eac2009-12-11 19:06:04 +00003067
Douglas Gregor9c6a0e92009-09-22 15:41:20 +00003068 // Ignore type-dependent call expressions entirely.
Douglas Gregord28dcd72010-05-30 06:10:08 +00003069 if (!Fn || Fn->isTypeDependent() || anyNullArguments(Args, NumArgs) ||
Douglas Gregoref96eac2009-12-11 19:06:04 +00003070 Expr::hasAnyTypeDependentArguments(Args, NumArgs)) {
Douglas Gregore6b1bb62010-08-11 21:23:17 +00003071 CodeCompleteOrdinaryName(S, PCC_Expression);
Douglas Gregor9c6a0e92009-09-22 15:41:20 +00003072 return;
Douglas Gregoref96eac2009-12-11 19:06:04 +00003073 }
Douglas Gregor9c6a0e92009-09-22 15:41:20 +00003074
John McCall3b4294e2009-12-16 12:17:52 +00003075 // Build an overload candidate set based on the functions we find.
John McCall5769d612010-02-08 23:07:23 +00003076 SourceLocation Loc = Fn->getExprLoc();
3077 OverloadCandidateSet CandidateSet(Loc);
John McCall3b4294e2009-12-16 12:17:52 +00003078
Douglas Gregor9c6a0e92009-09-22 15:41:20 +00003079 // FIXME: What if we're calling something that isn't a function declaration?
3080 // FIXME: What if we're calling a pseudo-destructor?
3081 // FIXME: What if we're calling a member function?
3082
Douglas Gregorc0265402010-01-21 15:46:19 +00003083 typedef CodeCompleteConsumer::OverloadCandidate ResultCandidate;
3084 llvm::SmallVector<ResultCandidate, 8> Results;
3085
John McCall3b4294e2009-12-16 12:17:52 +00003086 Expr *NakedFn = Fn->IgnoreParenCasts();
3087 if (UnresolvedLookupExpr *ULE = dyn_cast<UnresolvedLookupExpr>(NakedFn))
3088 AddOverloadedCallCandidates(ULE, Args, NumArgs, CandidateSet,
3089 /*PartialOverloading=*/ true);
3090 else if (DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(NakedFn)) {
3091 FunctionDecl *FDecl = dyn_cast<FunctionDecl>(DRE->getDecl());
Douglas Gregorc0265402010-01-21 15:46:19 +00003092 if (FDecl) {
Douglas Gregord28dcd72010-05-30 06:10:08 +00003093 if (!getLangOptions().CPlusPlus ||
3094 !FDecl->getType()->getAs<FunctionProtoType>())
Douglas Gregorc0265402010-01-21 15:46:19 +00003095 Results.push_back(ResultCandidate(FDecl));
3096 else
John McCall86820f52010-01-26 01:37:31 +00003097 // FIXME: access?
John McCall9aa472c2010-03-19 07:35:19 +00003098 AddOverloadCandidate(FDecl, DeclAccessPair::make(FDecl, AS_none),
3099 Args, NumArgs, CandidateSet,
Douglas Gregorc27d6c52010-04-16 17:41:49 +00003100 false, /*PartialOverloading*/true);
Douglas Gregorc0265402010-01-21 15:46:19 +00003101 }
John McCall3b4294e2009-12-16 12:17:52 +00003102 }
Douglas Gregor9c6a0e92009-09-22 15:41:20 +00003103
Douglas Gregor5ac3bdb2010-05-30 01:49:25 +00003104 QualType ParamType;
3105
Douglas Gregorc0265402010-01-21 15:46:19 +00003106 if (!CandidateSet.empty()) {
3107 // Sort the overload candidate set by placing the best overloads first.
3108 std::stable_sort(CandidateSet.begin(), CandidateSet.end(),
John McCall5769d612010-02-08 23:07:23 +00003109 IsBetterOverloadCandidate(*this, Loc));
Douglas Gregor9c6a0e92009-09-22 15:41:20 +00003110
Douglas Gregorc0265402010-01-21 15:46:19 +00003111 // Add the remaining viable overload candidates as code-completion reslults.
3112 for (OverloadCandidateSet::iterator Cand = CandidateSet.begin(),
3113 CandEnd = CandidateSet.end();
3114 Cand != CandEnd; ++Cand) {
3115 if (Cand->Viable)
3116 Results.push_back(ResultCandidate(Cand->Function));
3117 }
Douglas Gregor5ac3bdb2010-05-30 01:49:25 +00003118
3119 // From the viable candidates, try to determine the type of this parameter.
3120 for (unsigned I = 0, N = Results.size(); I != N; ++I) {
3121 if (const FunctionType *FType = Results[I].getFunctionType())
3122 if (const FunctionProtoType *Proto = dyn_cast<FunctionProtoType>(FType))
3123 if (NumArgs < Proto->getNumArgs()) {
3124 if (ParamType.isNull())
3125 ParamType = Proto->getArgType(NumArgs);
3126 else if (!Context.hasSameUnqualifiedType(
3127 ParamType.getNonReferenceType(),
3128 Proto->getArgType(NumArgs).getNonReferenceType())) {
3129 ParamType = QualType();
3130 break;
3131 }
3132 }
3133 }
3134 } else {
3135 // Try to determine the parameter type from the type of the expression
3136 // being called.
3137 QualType FunctionType = Fn->getType();
3138 if (const PointerType *Ptr = FunctionType->getAs<PointerType>())
3139 FunctionType = Ptr->getPointeeType();
3140 else if (const BlockPointerType *BlockPtr
3141 = FunctionType->getAs<BlockPointerType>())
3142 FunctionType = BlockPtr->getPointeeType();
3143 else if (const MemberPointerType *MemPtr
3144 = FunctionType->getAs<MemberPointerType>())
3145 FunctionType = MemPtr->getPointeeType();
3146
3147 if (const FunctionProtoType *Proto
3148 = FunctionType->getAs<FunctionProtoType>()) {
3149 if (NumArgs < Proto->getNumArgs())
3150 ParamType = Proto->getArgType(NumArgs);
3151 }
Douglas Gregor9c6a0e92009-09-22 15:41:20 +00003152 }
Douglas Gregoref96eac2009-12-11 19:06:04 +00003153
Douglas Gregor5ac3bdb2010-05-30 01:49:25 +00003154 if (ParamType.isNull())
Douglas Gregore6b1bb62010-08-11 21:23:17 +00003155 CodeCompleteOrdinaryName(S, PCC_Expression);
Douglas Gregor5ac3bdb2010-05-30 01:49:25 +00003156 else
3157 CodeCompleteExpression(S, ParamType);
3158
Douglas Gregor2e4c7a52010-04-06 20:19:47 +00003159 if (!Results.empty())
Douglas Gregoref96eac2009-12-11 19:06:04 +00003160 CodeCompleter->ProcessOverloadCandidates(*this, NumArgs, Results.data(),
3161 Results.size());
Douglas Gregor9c6a0e92009-09-22 15:41:20 +00003162}
3163
John McCalld226f652010-08-21 09:40:31 +00003164void Sema::CodeCompleteInitializer(Scope *S, Decl *D) {
3165 ValueDecl *VD = dyn_cast_or_null<ValueDecl>(D);
Douglas Gregor5ac3bdb2010-05-30 01:49:25 +00003166 if (!VD) {
Douglas Gregore6b1bb62010-08-11 21:23:17 +00003167 CodeCompleteOrdinaryName(S, PCC_Expression);
Douglas Gregor5ac3bdb2010-05-30 01:49:25 +00003168 return;
3169 }
3170
3171 CodeCompleteExpression(S, VD->getType());
3172}
3173
3174void Sema::CodeCompleteReturn(Scope *S) {
3175 QualType ResultType;
3176 if (isa<BlockDecl>(CurContext)) {
3177 if (BlockScopeInfo *BSI = getCurBlock())
3178 ResultType = BSI->ReturnType;
3179 } else if (FunctionDecl *Function = dyn_cast<FunctionDecl>(CurContext))
3180 ResultType = Function->getResultType();
3181 else if (ObjCMethodDecl *Method = dyn_cast<ObjCMethodDecl>(CurContext))
3182 ResultType = Method->getResultType();
3183
3184 if (ResultType.isNull())
Douglas Gregore6b1bb62010-08-11 21:23:17 +00003185 CodeCompleteOrdinaryName(S, PCC_Expression);
Douglas Gregor5ac3bdb2010-05-30 01:49:25 +00003186 else
3187 CodeCompleteExpression(S, ResultType);
3188}
3189
3190void Sema::CodeCompleteAssignmentRHS(Scope *S, ExprTy *LHS) {
3191 if (LHS)
3192 CodeCompleteExpression(S, static_cast<Expr *>(LHS)->getType());
3193 else
Douglas Gregore6b1bb62010-08-11 21:23:17 +00003194 CodeCompleteOrdinaryName(S, PCC_Expression);
Douglas Gregor5ac3bdb2010-05-30 01:49:25 +00003195}
3196
Jeffrey Yasskin9ab14542010-04-08 16:38:48 +00003197void Sema::CodeCompleteQualifiedId(Scope *S, CXXScopeSpec &SS,
Douglas Gregor81b747b2009-09-17 21:32:03 +00003198 bool EnteringContext) {
3199 if (!SS.getScopeRep() || !CodeCompleter)
3200 return;
3201
Douglas Gregor86d9a522009-09-21 16:56:56 +00003202 DeclContext *Ctx = computeDeclContext(SS, EnteringContext);
3203 if (!Ctx)
3204 return;
Douglas Gregord1cd31a2009-12-11 18:28:39 +00003205
3206 // Try to instantiate any non-dependent declaration contexts before
3207 // we look in them.
John McCall77bb1aa2010-05-01 00:40:08 +00003208 if (!isDependentScopeSpecifier(SS) && RequireCompleteDeclContext(SS, Ctx))
Douglas Gregord1cd31a2009-12-11 18:28:39 +00003209 return;
3210
Douglas Gregor86d9a522009-09-21 16:56:56 +00003211 ResultBuilder Results(*this);
Douglas Gregor86d9a522009-09-21 16:56:56 +00003212
Douglas Gregorf6961522010-08-27 21:18:54 +00003213 Results.EnterNewScope();
Douglas Gregor86d9a522009-09-21 16:56:56 +00003214 // The "template" keyword can follow "::" in the grammar, but only
3215 // put it into the grammar if the nested-name-specifier is dependent.
3216 NestedNameSpecifier *NNS = (NestedNameSpecifier *)SS.getScopeRep();
3217 if (!Results.empty() && NNS->isDependent())
Douglas Gregora4477812010-01-14 16:01:26 +00003218 Results.AddResult("template");
Douglas Gregorf6961522010-08-27 21:18:54 +00003219
3220 // Add calls to overridden virtual functions, if there are any.
3221 //
3222 // FIXME: This isn't wonderful, because we don't know whether we're actually
3223 // in a context that permits expressions. This is a general issue with
3224 // qualified-id completions.
3225 if (!EnteringContext)
3226 MaybeAddOverrideCalls(*this, Ctx, Results);
3227 Results.ExitScope();
Douglas Gregor86d9a522009-09-21 16:56:56 +00003228
Douglas Gregorf6961522010-08-27 21:18:54 +00003229 CodeCompletionDeclConsumer Consumer(Results, CurContext);
3230 LookupVisibleDecls(Ctx, LookupOrdinaryName, Consumer);
3231
Douglas Gregore6b1bb62010-08-11 21:23:17 +00003232 HandleCodeCompleteResults(this, CodeCompleter,
Douglas Gregorf6961522010-08-27 21:18:54 +00003233 CodeCompletionContext::CCC_Name,
Douglas Gregore6b1bb62010-08-11 21:23:17 +00003234 Results.data(),Results.size());
Douglas Gregor81b747b2009-09-17 21:32:03 +00003235}
Douglas Gregor49f40bd2009-09-18 19:03:04 +00003236
3237void Sema::CodeCompleteUsing(Scope *S) {
3238 if (!CodeCompleter)
3239 return;
3240
Douglas Gregor86d9a522009-09-21 16:56:56 +00003241 ResultBuilder Results(*this, &ResultBuilder::IsNestedNameSpecifier);
Douglas Gregor8e0a0e42009-09-22 23:31:26 +00003242 Results.EnterNewScope();
Douglas Gregor86d9a522009-09-21 16:56:56 +00003243
3244 // If we aren't in class scope, we could see the "namespace" keyword.
3245 if (!S->isClassScope())
John McCall0a2c5e22010-08-25 06:19:51 +00003246 Results.AddResult(CodeCompletionResult("namespace"));
Douglas Gregor86d9a522009-09-21 16:56:56 +00003247
3248 // After "using", we can see anything that would start a
3249 // nested-name-specifier.
Douglas Gregor5d2fc402010-01-14 03:27:13 +00003250 CodeCompletionDeclConsumer Consumer(Results, CurContext);
Douglas Gregor8071e422010-08-15 06:18:01 +00003251 LookupVisibleDecls(S, LookupOrdinaryName, Consumer,
3252 CodeCompleter->includeGlobals());
Douglas Gregor8e0a0e42009-09-22 23:31:26 +00003253 Results.ExitScope();
Douglas Gregor86d9a522009-09-21 16:56:56 +00003254
Douglas Gregore6b1bb62010-08-11 21:23:17 +00003255 HandleCodeCompleteResults(this, CodeCompleter,
3256 CodeCompletionContext::CCC_Other,
3257 Results.data(),Results.size());
Douglas Gregor49f40bd2009-09-18 19:03:04 +00003258}
3259
3260void Sema::CodeCompleteUsingDirective(Scope *S) {
3261 if (!CodeCompleter)
3262 return;
3263
Douglas Gregor86d9a522009-09-21 16:56:56 +00003264 // After "using namespace", we expect to see a namespace name or namespace
3265 // alias.
3266 ResultBuilder Results(*this, &ResultBuilder::IsNamespaceOrAlias);
Douglas Gregor8e0a0e42009-09-22 23:31:26 +00003267 Results.EnterNewScope();
Douglas Gregor5d2fc402010-01-14 03:27:13 +00003268 CodeCompletionDeclConsumer Consumer(Results, CurContext);
Douglas Gregor8071e422010-08-15 06:18:01 +00003269 LookupVisibleDecls(S, LookupOrdinaryName, Consumer,
3270 CodeCompleter->includeGlobals());
Douglas Gregor8e0a0e42009-09-22 23:31:26 +00003271 Results.ExitScope();
Douglas Gregore6b1bb62010-08-11 21:23:17 +00003272 HandleCodeCompleteResults(this, CodeCompleter,
Douglas Gregor8071e422010-08-15 06:18:01 +00003273 CodeCompletionContext::CCC_Namespace,
Douglas Gregore6b1bb62010-08-11 21:23:17 +00003274 Results.data(),Results.size());
Douglas Gregor49f40bd2009-09-18 19:03:04 +00003275}
3276
3277void Sema::CodeCompleteNamespaceDecl(Scope *S) {
3278 if (!CodeCompleter)
3279 return;
3280
Douglas Gregor86d9a522009-09-21 16:56:56 +00003281 ResultBuilder Results(*this, &ResultBuilder::IsNamespace);
3282 DeclContext *Ctx = (DeclContext *)S->getEntity();
3283 if (!S->getParent())
3284 Ctx = Context.getTranslationUnitDecl();
3285
3286 if (Ctx && Ctx->isFileContext()) {
3287 // We only want to see those namespaces that have already been defined
3288 // within this scope, because its likely that the user is creating an
3289 // extended namespace declaration. Keep track of the most recent
3290 // definition of each namespace.
3291 std::map<NamespaceDecl *, NamespaceDecl *> OrigToLatest;
3292 for (DeclContext::specific_decl_iterator<NamespaceDecl>
3293 NS(Ctx->decls_begin()), NSEnd(Ctx->decls_end());
3294 NS != NSEnd; ++NS)
3295 OrigToLatest[NS->getOriginalNamespace()] = *NS;
3296
3297 // Add the most recent definition (or extended definition) of each
3298 // namespace to the list of results.
Douglas Gregor8e0a0e42009-09-22 23:31:26 +00003299 Results.EnterNewScope();
Douglas Gregor86d9a522009-09-21 16:56:56 +00003300 for (std::map<NamespaceDecl *, NamespaceDecl *>::iterator
3301 NS = OrigToLatest.begin(), NSEnd = OrigToLatest.end();
3302 NS != NSEnd; ++NS)
John McCall0a2c5e22010-08-25 06:19:51 +00003303 Results.AddResult(CodeCompletionResult(NS->second, 0),
Douglas Gregor608300b2010-01-14 16:14:35 +00003304 CurContext, 0, false);
Douglas Gregor8e0a0e42009-09-22 23:31:26 +00003305 Results.ExitScope();
Douglas Gregor86d9a522009-09-21 16:56:56 +00003306 }
3307
Douglas Gregore6b1bb62010-08-11 21:23:17 +00003308 HandleCodeCompleteResults(this, CodeCompleter,
3309 CodeCompletionContext::CCC_Other,
3310 Results.data(),Results.size());
Douglas Gregor49f40bd2009-09-18 19:03:04 +00003311}
3312
3313void Sema::CodeCompleteNamespaceAliasDecl(Scope *S) {
3314 if (!CodeCompleter)
3315 return;
3316
Douglas Gregor86d9a522009-09-21 16:56:56 +00003317 // After "namespace", we expect to see a namespace or alias.
3318 ResultBuilder Results(*this, &ResultBuilder::IsNamespaceOrAlias);
Douglas Gregor5d2fc402010-01-14 03:27:13 +00003319 CodeCompletionDeclConsumer Consumer(Results, CurContext);
Douglas Gregor8071e422010-08-15 06:18:01 +00003320 LookupVisibleDecls(S, LookupOrdinaryName, Consumer,
3321 CodeCompleter->includeGlobals());
Douglas Gregore6b1bb62010-08-11 21:23:17 +00003322 HandleCodeCompleteResults(this, CodeCompleter,
Douglas Gregor8071e422010-08-15 06:18:01 +00003323 CodeCompletionContext::CCC_Namespace,
Douglas Gregore6b1bb62010-08-11 21:23:17 +00003324 Results.data(),Results.size());
Douglas Gregor49f40bd2009-09-18 19:03:04 +00003325}
3326
Douglas Gregored8d3222009-09-18 20:05:18 +00003327void Sema::CodeCompleteOperatorName(Scope *S) {
3328 if (!CodeCompleter)
3329 return;
Douglas Gregor86d9a522009-09-21 16:56:56 +00003330
John McCall0a2c5e22010-08-25 06:19:51 +00003331 typedef CodeCompletionResult Result;
Douglas Gregor86d9a522009-09-21 16:56:56 +00003332 ResultBuilder Results(*this, &ResultBuilder::IsType);
Douglas Gregor8e0a0e42009-09-22 23:31:26 +00003333 Results.EnterNewScope();
Douglas Gregored8d3222009-09-18 20:05:18 +00003334
Douglas Gregor86d9a522009-09-21 16:56:56 +00003335 // Add the names of overloadable operators.
3336#define OVERLOADED_OPERATOR(Name,Spelling,Token,Unary,Binary,MemberOnly) \
3337 if (std::strcmp(Spelling, "?")) \
Douglas Gregora4477812010-01-14 16:01:26 +00003338 Results.AddResult(Result(Spelling));
Douglas Gregor86d9a522009-09-21 16:56:56 +00003339#include "clang/Basic/OperatorKinds.def"
3340
3341 // Add any type names visible from the current scope
Douglas Gregor45bcd432010-01-14 03:21:49 +00003342 Results.allowNestedNameSpecifiers();
Douglas Gregor5d2fc402010-01-14 03:27:13 +00003343 CodeCompletionDeclConsumer Consumer(Results, CurContext);
Douglas Gregor8071e422010-08-15 06:18:01 +00003344 LookupVisibleDecls(S, LookupOrdinaryName, Consumer,
3345 CodeCompleter->includeGlobals());
Douglas Gregor86d9a522009-09-21 16:56:56 +00003346
3347 // Add any type specifiers
Douglas Gregorbca403c2010-01-13 23:51:12 +00003348 AddTypeSpecifierResults(getLangOptions(), Results);
Douglas Gregor8e0a0e42009-09-22 23:31:26 +00003349 Results.ExitScope();
Douglas Gregor86d9a522009-09-21 16:56:56 +00003350
Douglas Gregore6b1bb62010-08-11 21:23:17 +00003351 HandleCodeCompleteResults(this, CodeCompleter,
Douglas Gregor8071e422010-08-15 06:18:01 +00003352 CodeCompletionContext::CCC_Type,
Douglas Gregore6b1bb62010-08-11 21:23:17 +00003353 Results.data(),Results.size());
Douglas Gregored8d3222009-09-18 20:05:18 +00003354}
Douglas Gregor49f40bd2009-09-18 19:03:04 +00003355
Douglas Gregor0133f522010-08-28 00:00:50 +00003356void Sema::CodeCompleteConstructorInitializer(Decl *ConstructorD,
3357 CXXBaseOrMemberInitializer** Initializers,
3358 unsigned NumInitializers) {
3359 CXXConstructorDecl *Constructor
3360 = static_cast<CXXConstructorDecl *>(ConstructorD);
3361 if (!Constructor)
3362 return;
3363
3364 ResultBuilder Results(*this);
3365 Results.EnterNewScope();
3366
3367 // Fill in any already-initialized fields or base classes.
3368 llvm::SmallPtrSet<FieldDecl *, 4> InitializedFields;
3369 llvm::SmallPtrSet<CanQualType, 4> InitializedBases;
3370 for (unsigned I = 0; I != NumInitializers; ++I) {
3371 if (Initializers[I]->isBaseInitializer())
3372 InitializedBases.insert(
3373 Context.getCanonicalType(QualType(Initializers[I]->getBaseClass(), 0)));
3374 else
3375 InitializedFields.insert(cast<FieldDecl>(Initializers[I]->getMember()));
3376 }
3377
3378 // Add completions for base classes.
Douglas Gregor0c431c82010-08-29 19:27:27 +00003379 bool SawLastInitializer = (NumInitializers == 0);
Douglas Gregor0133f522010-08-28 00:00:50 +00003380 CXXRecordDecl *ClassDecl = Constructor->getParent();
3381 for (CXXRecordDecl::base_class_iterator Base = ClassDecl->bases_begin(),
3382 BaseEnd = ClassDecl->bases_end();
3383 Base != BaseEnd; ++Base) {
Douglas Gregor0c431c82010-08-29 19:27:27 +00003384 if (!InitializedBases.insert(Context.getCanonicalType(Base->getType()))) {
3385 SawLastInitializer
3386 = NumInitializers > 0 &&
3387 Initializers[NumInitializers - 1]->isBaseInitializer() &&
3388 Context.hasSameUnqualifiedType(Base->getType(),
3389 QualType(Initializers[NumInitializers - 1]->getBaseClass(), 0));
Douglas Gregor0133f522010-08-28 00:00:50 +00003390 continue;
Douglas Gregor0c431c82010-08-29 19:27:27 +00003391 }
Douglas Gregor0133f522010-08-28 00:00:50 +00003392
3393 CodeCompletionString *Pattern = new CodeCompletionString;
3394 Pattern->AddTypedTextChunk(
3395 Base->getType().getAsString(Context.PrintingPolicy));
3396 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
3397 Pattern->AddPlaceholderChunk("args");
3398 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
Douglas Gregor0c431c82010-08-29 19:27:27 +00003399 Results.AddResult(CodeCompletionResult(Pattern,
3400 SawLastInitializer? CCP_NextInitializer
3401 : CCP_MemberDeclaration));
3402 SawLastInitializer = false;
Douglas Gregor0133f522010-08-28 00:00:50 +00003403 }
3404
3405 // Add completions for virtual base classes.
3406 for (CXXRecordDecl::base_class_iterator Base = ClassDecl->vbases_begin(),
3407 BaseEnd = ClassDecl->vbases_end();
3408 Base != BaseEnd; ++Base) {
Douglas Gregor0c431c82010-08-29 19:27:27 +00003409 if (!InitializedBases.insert(Context.getCanonicalType(Base->getType()))) {
3410 SawLastInitializer
3411 = NumInitializers > 0 &&
3412 Initializers[NumInitializers - 1]->isBaseInitializer() &&
3413 Context.hasSameUnqualifiedType(Base->getType(),
3414 QualType(Initializers[NumInitializers - 1]->getBaseClass(), 0));
Douglas Gregor0133f522010-08-28 00:00:50 +00003415 continue;
Douglas Gregor0c431c82010-08-29 19:27:27 +00003416 }
Douglas Gregor0133f522010-08-28 00:00:50 +00003417
3418 CodeCompletionString *Pattern = new CodeCompletionString;
3419 Pattern->AddTypedTextChunk(
3420 Base->getType().getAsString(Context.PrintingPolicy));
3421 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
3422 Pattern->AddPlaceholderChunk("args");
3423 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
Douglas Gregor0c431c82010-08-29 19:27:27 +00003424 Results.AddResult(CodeCompletionResult(Pattern,
3425 SawLastInitializer? CCP_NextInitializer
3426 : CCP_MemberDeclaration));
3427 SawLastInitializer = false;
Douglas Gregor0133f522010-08-28 00:00:50 +00003428 }
3429
3430 // Add completions for members.
3431 for (CXXRecordDecl::field_iterator Field = ClassDecl->field_begin(),
3432 FieldEnd = ClassDecl->field_end();
3433 Field != FieldEnd; ++Field) {
Douglas Gregor0c431c82010-08-29 19:27:27 +00003434 if (!InitializedFields.insert(cast<FieldDecl>(Field->getCanonicalDecl()))) {
3435 SawLastInitializer
3436 = NumInitializers > 0 &&
3437 Initializers[NumInitializers - 1]->isMemberInitializer() &&
3438 Initializers[NumInitializers - 1]->getMember() == *Field;
Douglas Gregor0133f522010-08-28 00:00:50 +00003439 continue;
Douglas Gregor0c431c82010-08-29 19:27:27 +00003440 }
Douglas Gregor0133f522010-08-28 00:00:50 +00003441
3442 if (!Field->getDeclName())
3443 continue;
3444
3445 CodeCompletionString *Pattern = new CodeCompletionString;
3446 Pattern->AddTypedTextChunk(Field->getIdentifier()->getName());
3447 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
3448 Pattern->AddPlaceholderChunk("args");
3449 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
Douglas Gregor0c431c82010-08-29 19:27:27 +00003450 Results.AddResult(CodeCompletionResult(Pattern,
3451 SawLastInitializer? CCP_NextInitializer
Douglas Gregora67e03f2010-09-09 21:42:20 +00003452 : CCP_MemberDeclaration,
3453 CXCursor_MemberRef));
Douglas Gregor0c431c82010-08-29 19:27:27 +00003454 SawLastInitializer = false;
Douglas Gregor0133f522010-08-28 00:00:50 +00003455 }
3456 Results.ExitScope();
3457
3458 HandleCodeCompleteResults(this, CodeCompleter,
3459 CodeCompletionContext::CCC_Name,
3460 Results.data(), Results.size());
3461}
3462
Douglas Gregorb6ac2452010-01-13 21:24:21 +00003463// Macro that expands to @Keyword or Keyword, depending on whether NeedAt is
3464// true or false.
3465#define OBJC_AT_KEYWORD_NAME(NeedAt,Keyword) NeedAt? "@" #Keyword : #Keyword
Douglas Gregorbca403c2010-01-13 23:51:12 +00003466static void AddObjCImplementationResults(const LangOptions &LangOpts,
Douglas Gregorb6ac2452010-01-13 21:24:21 +00003467 ResultBuilder &Results,
3468 bool NeedAt) {
John McCall0a2c5e22010-08-25 06:19:51 +00003469 typedef CodeCompletionResult Result;
Douglas Gregorb6ac2452010-01-13 21:24:21 +00003470 // Since we have an implementation, we can end it.
Douglas Gregora4477812010-01-14 16:01:26 +00003471 Results.AddResult(Result(OBJC_AT_KEYWORD_NAME(NeedAt,end)));
Douglas Gregorb6ac2452010-01-13 21:24:21 +00003472
3473 CodeCompletionString *Pattern = 0;
3474 if (LangOpts.ObjC2) {
3475 // @dynamic
3476 Pattern = new CodeCompletionString;
3477 Pattern->AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt,dynamic));
3478 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
3479 Pattern->AddPlaceholderChunk("property");
Douglas Gregora4477812010-01-14 16:01:26 +00003480 Results.AddResult(Result(Pattern));
Douglas Gregorb6ac2452010-01-13 21:24:21 +00003481
3482 // @synthesize
3483 Pattern = new CodeCompletionString;
3484 Pattern->AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt,synthesize));
3485 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
3486 Pattern->AddPlaceholderChunk("property");
Douglas Gregora4477812010-01-14 16:01:26 +00003487 Results.AddResult(Result(Pattern));
Douglas Gregorb6ac2452010-01-13 21:24:21 +00003488 }
3489}
3490
Douglas Gregorbca403c2010-01-13 23:51:12 +00003491static void AddObjCInterfaceResults(const LangOptions &LangOpts,
Douglas Gregorb6ac2452010-01-13 21:24:21 +00003492 ResultBuilder &Results,
3493 bool NeedAt) {
John McCall0a2c5e22010-08-25 06:19:51 +00003494 typedef CodeCompletionResult Result;
Douglas Gregorb6ac2452010-01-13 21:24:21 +00003495
3496 // Since we have an interface or protocol, we can end it.
Douglas Gregora4477812010-01-14 16:01:26 +00003497 Results.AddResult(Result(OBJC_AT_KEYWORD_NAME(NeedAt,end)));
Douglas Gregorb6ac2452010-01-13 21:24:21 +00003498
3499 if (LangOpts.ObjC2) {
3500 // @property
Douglas Gregora4477812010-01-14 16:01:26 +00003501 Results.AddResult(Result(OBJC_AT_KEYWORD_NAME(NeedAt,property)));
Douglas Gregorb6ac2452010-01-13 21:24:21 +00003502
3503 // @required
Douglas Gregora4477812010-01-14 16:01:26 +00003504 Results.AddResult(Result(OBJC_AT_KEYWORD_NAME(NeedAt,required)));
Douglas Gregorb6ac2452010-01-13 21:24:21 +00003505
3506 // @optional
Douglas Gregora4477812010-01-14 16:01:26 +00003507 Results.AddResult(Result(OBJC_AT_KEYWORD_NAME(NeedAt,optional)));
Douglas Gregorb6ac2452010-01-13 21:24:21 +00003508 }
3509}
3510
Douglas Gregorbca403c2010-01-13 23:51:12 +00003511static void AddObjCTopLevelResults(ResultBuilder &Results, bool NeedAt) {
John McCall0a2c5e22010-08-25 06:19:51 +00003512 typedef CodeCompletionResult Result;
Douglas Gregorb6ac2452010-01-13 21:24:21 +00003513 CodeCompletionString *Pattern = 0;
3514
3515 // @class name ;
3516 Pattern = new CodeCompletionString;
3517 Pattern->AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt,class));
3518 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
Douglas Gregorc8bddde2010-05-28 00:22:41 +00003519 Pattern->AddPlaceholderChunk("name");
Douglas Gregora4477812010-01-14 16:01:26 +00003520 Results.AddResult(Result(Pattern));
Douglas Gregorb6ac2452010-01-13 21:24:21 +00003521
Douglas Gregorc8bddde2010-05-28 00:22:41 +00003522 if (Results.includeCodePatterns()) {
3523 // @interface name
3524 // FIXME: Could introduce the whole pattern, including superclasses and
3525 // such.
3526 Pattern = new CodeCompletionString;
3527 Pattern->AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt,interface));
3528 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
3529 Pattern->AddPlaceholderChunk("class");
3530 Results.AddResult(Result(Pattern));
Douglas Gregorb6ac2452010-01-13 21:24:21 +00003531
Douglas Gregorc8bddde2010-05-28 00:22:41 +00003532 // @protocol name
3533 Pattern = new CodeCompletionString;
3534 Pattern->AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt,protocol));
3535 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
3536 Pattern->AddPlaceholderChunk("protocol");
3537 Results.AddResult(Result(Pattern));
3538
3539 // @implementation name
3540 Pattern = new CodeCompletionString;
3541 Pattern->AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt,implementation));
3542 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
3543 Pattern->AddPlaceholderChunk("class");
3544 Results.AddResult(Result(Pattern));
3545 }
Douglas Gregorb6ac2452010-01-13 21:24:21 +00003546
3547 // @compatibility_alias name
3548 Pattern = new CodeCompletionString;
3549 Pattern->AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt,compatibility_alias));
3550 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
3551 Pattern->AddPlaceholderChunk("alias");
3552 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
3553 Pattern->AddPlaceholderChunk("class");
Douglas Gregora4477812010-01-14 16:01:26 +00003554 Results.AddResult(Result(Pattern));
Douglas Gregorb6ac2452010-01-13 21:24:21 +00003555}
3556
John McCalld226f652010-08-21 09:40:31 +00003557void Sema::CodeCompleteObjCAtDirective(Scope *S, Decl *ObjCImpDecl,
Douglas Gregorc464ae82009-12-07 09:27:33 +00003558 bool InInterface) {
John McCall0a2c5e22010-08-25 06:19:51 +00003559 typedef CodeCompletionResult Result;
Douglas Gregorc464ae82009-12-07 09:27:33 +00003560 ResultBuilder Results(*this);
3561 Results.EnterNewScope();
Douglas Gregorb6ac2452010-01-13 21:24:21 +00003562 if (ObjCImpDecl)
Douglas Gregorbca403c2010-01-13 23:51:12 +00003563 AddObjCImplementationResults(getLangOptions(), Results, false);
Douglas Gregorb6ac2452010-01-13 21:24:21 +00003564 else if (InInterface)
Douglas Gregorbca403c2010-01-13 23:51:12 +00003565 AddObjCInterfaceResults(getLangOptions(), Results, false);
Douglas Gregorb6ac2452010-01-13 21:24:21 +00003566 else
Douglas Gregorbca403c2010-01-13 23:51:12 +00003567 AddObjCTopLevelResults(Results, false);
Douglas Gregorc464ae82009-12-07 09:27:33 +00003568 Results.ExitScope();
Douglas Gregore6b1bb62010-08-11 21:23:17 +00003569 HandleCodeCompleteResults(this, CodeCompleter,
3570 CodeCompletionContext::CCC_Other,
3571 Results.data(),Results.size());
Douglas Gregorc464ae82009-12-07 09:27:33 +00003572}
3573
Douglas Gregorbca403c2010-01-13 23:51:12 +00003574static void AddObjCExpressionResults(ResultBuilder &Results, bool NeedAt) {
John McCall0a2c5e22010-08-25 06:19:51 +00003575 typedef CodeCompletionResult Result;
Douglas Gregor9a0c85e2009-12-07 09:51:25 +00003576 CodeCompletionString *Pattern = 0;
3577
3578 // @encode ( type-name )
3579 Pattern = new CodeCompletionString;
Douglas Gregorb6ac2452010-01-13 21:24:21 +00003580 Pattern->AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt,encode));
Douglas Gregor9a0c85e2009-12-07 09:51:25 +00003581 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
3582 Pattern->AddPlaceholderChunk("type-name");
3583 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
Douglas Gregora4477812010-01-14 16:01:26 +00003584 Results.AddResult(Result(Pattern));
Douglas Gregor9a0c85e2009-12-07 09:51:25 +00003585
3586 // @protocol ( protocol-name )
3587 Pattern = new CodeCompletionString;
Douglas Gregorb6ac2452010-01-13 21:24:21 +00003588 Pattern->AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt,protocol));
Douglas Gregor9a0c85e2009-12-07 09:51:25 +00003589 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
3590 Pattern->AddPlaceholderChunk("protocol-name");
3591 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
Douglas Gregora4477812010-01-14 16:01:26 +00003592 Results.AddResult(Result(Pattern));
Douglas Gregor9a0c85e2009-12-07 09:51:25 +00003593
3594 // @selector ( selector )
3595 Pattern = new CodeCompletionString;
Douglas Gregorb6ac2452010-01-13 21:24:21 +00003596 Pattern->AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt,selector));
Douglas Gregor9a0c85e2009-12-07 09:51:25 +00003597 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
3598 Pattern->AddPlaceholderChunk("selector");
3599 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
Douglas Gregora4477812010-01-14 16:01:26 +00003600 Results.AddResult(Result(Pattern));
Douglas Gregor9a0c85e2009-12-07 09:51:25 +00003601}
3602
Douglas Gregorbca403c2010-01-13 23:51:12 +00003603static void AddObjCStatementResults(ResultBuilder &Results, bool NeedAt) {
John McCall0a2c5e22010-08-25 06:19:51 +00003604 typedef CodeCompletionResult Result;
Douglas Gregor9a0c85e2009-12-07 09:51:25 +00003605 CodeCompletionString *Pattern = 0;
Douglas Gregorb6ac2452010-01-13 21:24:21 +00003606
Douglas Gregorc8bddde2010-05-28 00:22:41 +00003607 if (Results.includeCodePatterns()) {
3608 // @try { statements } @catch ( declaration ) { statements } @finally
3609 // { statements }
3610 Pattern = new CodeCompletionString;
3611 Pattern->AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt,try));
3612 Pattern->AddChunk(CodeCompletionString::CK_LeftBrace);
3613 Pattern->AddPlaceholderChunk("statements");
3614 Pattern->AddChunk(CodeCompletionString::CK_RightBrace);
3615 Pattern->AddTextChunk("@catch");
3616 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
3617 Pattern->AddPlaceholderChunk("parameter");
3618 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
3619 Pattern->AddChunk(CodeCompletionString::CK_LeftBrace);
3620 Pattern->AddPlaceholderChunk("statements");
3621 Pattern->AddChunk(CodeCompletionString::CK_RightBrace);
3622 Pattern->AddTextChunk("@finally");
3623 Pattern->AddChunk(CodeCompletionString::CK_LeftBrace);
3624 Pattern->AddPlaceholderChunk("statements");
3625 Pattern->AddChunk(CodeCompletionString::CK_RightBrace);
3626 Results.AddResult(Result(Pattern));
3627 }
Douglas Gregorb6ac2452010-01-13 21:24:21 +00003628
Douglas Gregor9a0c85e2009-12-07 09:51:25 +00003629 // @throw
3630 Pattern = new CodeCompletionString;
Douglas Gregorb6ac2452010-01-13 21:24:21 +00003631 Pattern->AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt,throw));
Douglas Gregor834389b2010-01-12 06:38:28 +00003632 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
Douglas Gregor9a0c85e2009-12-07 09:51:25 +00003633 Pattern->AddPlaceholderChunk("expression");
Douglas Gregora4477812010-01-14 16:01:26 +00003634 Results.AddResult(Result(Pattern));
Douglas Gregorb6ac2452010-01-13 21:24:21 +00003635
Douglas Gregorc8bddde2010-05-28 00:22:41 +00003636 if (Results.includeCodePatterns()) {
3637 // @synchronized ( expression ) { statements }
3638 Pattern = new CodeCompletionString;
3639 Pattern->AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt,synchronized));
3640 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
3641 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
3642 Pattern->AddPlaceholderChunk("expression");
3643 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
3644 Pattern->AddChunk(CodeCompletionString::CK_LeftBrace);
3645 Pattern->AddPlaceholderChunk("statements");
3646 Pattern->AddChunk(CodeCompletionString::CK_RightBrace);
3647 Results.AddResult(Result(Pattern));
3648 }
Douglas Gregorb6ac2452010-01-13 21:24:21 +00003649}
Douglas Gregor9a0c85e2009-12-07 09:51:25 +00003650
Douglas Gregorbca403c2010-01-13 23:51:12 +00003651static void AddObjCVisibilityResults(const LangOptions &LangOpts,
Douglas Gregorc38c3e12010-01-13 21:54:15 +00003652 ResultBuilder &Results,
3653 bool NeedAt) {
John McCall0a2c5e22010-08-25 06:19:51 +00003654 typedef CodeCompletionResult Result;
Douglas Gregora4477812010-01-14 16:01:26 +00003655 Results.AddResult(Result(OBJC_AT_KEYWORD_NAME(NeedAt,private)));
3656 Results.AddResult(Result(OBJC_AT_KEYWORD_NAME(NeedAt,protected)));
3657 Results.AddResult(Result(OBJC_AT_KEYWORD_NAME(NeedAt,public)));
Douglas Gregorc38c3e12010-01-13 21:54:15 +00003658 if (LangOpts.ObjC2)
Douglas Gregora4477812010-01-14 16:01:26 +00003659 Results.AddResult(Result(OBJC_AT_KEYWORD_NAME(NeedAt,package)));
Douglas Gregorc38c3e12010-01-13 21:54:15 +00003660}
3661
3662void Sema::CodeCompleteObjCAtVisibility(Scope *S) {
3663 ResultBuilder Results(*this);
3664 Results.EnterNewScope();
Douglas Gregorbca403c2010-01-13 23:51:12 +00003665 AddObjCVisibilityResults(getLangOptions(), Results, false);
Douglas Gregorc38c3e12010-01-13 21:54:15 +00003666 Results.ExitScope();
Douglas Gregore6b1bb62010-08-11 21:23:17 +00003667 HandleCodeCompleteResults(this, CodeCompleter,
3668 CodeCompletionContext::CCC_Other,
3669 Results.data(),Results.size());
Douglas Gregorc38c3e12010-01-13 21:54:15 +00003670}
3671
3672void Sema::CodeCompleteObjCAtStatement(Scope *S) {
Douglas Gregorb6ac2452010-01-13 21:24:21 +00003673 ResultBuilder Results(*this);
3674 Results.EnterNewScope();
Douglas Gregorbca403c2010-01-13 23:51:12 +00003675 AddObjCStatementResults(Results, false);
3676 AddObjCExpressionResults(Results, false);
Douglas Gregor9a0c85e2009-12-07 09:51:25 +00003677 Results.ExitScope();
Douglas Gregore6b1bb62010-08-11 21:23:17 +00003678 HandleCodeCompleteResults(this, CodeCompleter,
3679 CodeCompletionContext::CCC_Other,
3680 Results.data(),Results.size());
Douglas Gregor9a0c85e2009-12-07 09:51:25 +00003681}
3682
3683void Sema::CodeCompleteObjCAtExpression(Scope *S) {
3684 ResultBuilder Results(*this);
3685 Results.EnterNewScope();
Douglas Gregorbca403c2010-01-13 23:51:12 +00003686 AddObjCExpressionResults(Results, false);
Douglas Gregor9a0c85e2009-12-07 09:51:25 +00003687 Results.ExitScope();
Douglas Gregore6b1bb62010-08-11 21:23:17 +00003688 HandleCodeCompleteResults(this, CodeCompleter,
3689 CodeCompletionContext::CCC_Other,
3690 Results.data(),Results.size());
Douglas Gregor9a0c85e2009-12-07 09:51:25 +00003691}
3692
Douglas Gregor988358f2009-11-19 00:14:45 +00003693/// \brief Determine whether the addition of the given flag to an Objective-C
3694/// property's attributes will cause a conflict.
3695static bool ObjCPropertyFlagConflicts(unsigned Attributes, unsigned NewFlag) {
3696 // Check if we've already added this flag.
3697 if (Attributes & NewFlag)
3698 return true;
3699
3700 Attributes |= NewFlag;
3701
3702 // Check for collisions with "readonly".
3703 if ((Attributes & ObjCDeclSpec::DQ_PR_readonly) &&
3704 (Attributes & (ObjCDeclSpec::DQ_PR_readwrite |
3705 ObjCDeclSpec::DQ_PR_assign |
3706 ObjCDeclSpec::DQ_PR_copy |
3707 ObjCDeclSpec::DQ_PR_retain)))
3708 return true;
3709
3710 // Check for more than one of { assign, copy, retain }.
3711 unsigned AssignCopyRetMask = Attributes & (ObjCDeclSpec::DQ_PR_assign |
3712 ObjCDeclSpec::DQ_PR_copy |
3713 ObjCDeclSpec::DQ_PR_retain);
3714 if (AssignCopyRetMask &&
3715 AssignCopyRetMask != ObjCDeclSpec::DQ_PR_assign &&
3716 AssignCopyRetMask != ObjCDeclSpec::DQ_PR_copy &&
3717 AssignCopyRetMask != ObjCDeclSpec::DQ_PR_retain)
3718 return true;
3719
3720 return false;
3721}
3722
Douglas Gregora93b1082009-11-18 23:08:07 +00003723void Sema::CodeCompleteObjCPropertyFlags(Scope *S, ObjCDeclSpec &ODS) {
Steve Naroffece8e712009-10-08 21:55:05 +00003724 if (!CodeCompleter)
3725 return;
Douglas Gregord3c68542009-11-19 01:08:35 +00003726
Steve Naroffece8e712009-10-08 21:55:05 +00003727 unsigned Attributes = ODS.getPropertyAttributes();
3728
John McCall0a2c5e22010-08-25 06:19:51 +00003729 typedef CodeCompletionResult Result;
Steve Naroffece8e712009-10-08 21:55:05 +00003730 ResultBuilder Results(*this);
3731 Results.EnterNewScope();
Douglas Gregor988358f2009-11-19 00:14:45 +00003732 if (!ObjCPropertyFlagConflicts(Attributes, ObjCDeclSpec::DQ_PR_readonly))
John McCall0a2c5e22010-08-25 06:19:51 +00003733 Results.AddResult(CodeCompletionResult("readonly"));
Douglas Gregor988358f2009-11-19 00:14:45 +00003734 if (!ObjCPropertyFlagConflicts(Attributes, ObjCDeclSpec::DQ_PR_assign))
John McCall0a2c5e22010-08-25 06:19:51 +00003735 Results.AddResult(CodeCompletionResult("assign"));
Douglas Gregor988358f2009-11-19 00:14:45 +00003736 if (!ObjCPropertyFlagConflicts(Attributes, ObjCDeclSpec::DQ_PR_readwrite))
John McCall0a2c5e22010-08-25 06:19:51 +00003737 Results.AddResult(CodeCompletionResult("readwrite"));
Douglas Gregor988358f2009-11-19 00:14:45 +00003738 if (!ObjCPropertyFlagConflicts(Attributes, ObjCDeclSpec::DQ_PR_retain))
John McCall0a2c5e22010-08-25 06:19:51 +00003739 Results.AddResult(CodeCompletionResult("retain"));
Douglas Gregor988358f2009-11-19 00:14:45 +00003740 if (!ObjCPropertyFlagConflicts(Attributes, ObjCDeclSpec::DQ_PR_copy))
John McCall0a2c5e22010-08-25 06:19:51 +00003741 Results.AddResult(CodeCompletionResult("copy"));
Douglas Gregor988358f2009-11-19 00:14:45 +00003742 if (!ObjCPropertyFlagConflicts(Attributes, ObjCDeclSpec::DQ_PR_nonatomic))
John McCall0a2c5e22010-08-25 06:19:51 +00003743 Results.AddResult(CodeCompletionResult("nonatomic"));
Douglas Gregor988358f2009-11-19 00:14:45 +00003744 if (!ObjCPropertyFlagConflicts(Attributes, ObjCDeclSpec::DQ_PR_setter)) {
Douglas Gregor54f01612009-11-19 00:01:57 +00003745 CodeCompletionString *Setter = new CodeCompletionString;
3746 Setter->AddTypedTextChunk("setter");
3747 Setter->AddTextChunk(" = ");
3748 Setter->AddPlaceholderChunk("method");
John McCall0a2c5e22010-08-25 06:19:51 +00003749 Results.AddResult(CodeCompletionResult(Setter));
Douglas Gregor54f01612009-11-19 00:01:57 +00003750 }
Douglas Gregor988358f2009-11-19 00:14:45 +00003751 if (!ObjCPropertyFlagConflicts(Attributes, ObjCDeclSpec::DQ_PR_getter)) {
Douglas Gregor54f01612009-11-19 00:01:57 +00003752 CodeCompletionString *Getter = new CodeCompletionString;
3753 Getter->AddTypedTextChunk("getter");
3754 Getter->AddTextChunk(" = ");
3755 Getter->AddPlaceholderChunk("method");
John McCall0a2c5e22010-08-25 06:19:51 +00003756 Results.AddResult(CodeCompletionResult(Getter));
Douglas Gregor54f01612009-11-19 00:01:57 +00003757 }
Steve Naroffece8e712009-10-08 21:55:05 +00003758 Results.ExitScope();
Douglas Gregore6b1bb62010-08-11 21:23:17 +00003759 HandleCodeCompleteResults(this, CodeCompleter,
3760 CodeCompletionContext::CCC_Other,
3761 Results.data(),Results.size());
Steve Naroffece8e712009-10-08 21:55:05 +00003762}
Steve Naroffc4df6d22009-11-07 02:08:14 +00003763
Douglas Gregor4ad96852009-11-19 07:41:15 +00003764/// \brief Descripts the kind of Objective-C method that we want to find
3765/// via code completion.
3766enum ObjCMethodKind {
3767 MK_Any, //< Any kind of method, provided it means other specified criteria.
3768 MK_ZeroArgSelector, //< Zero-argument (unary) selector.
3769 MK_OneArgSelector //< One-argument selector.
3770};
3771
Douglas Gregor458433d2010-08-26 15:07:07 +00003772static bool isAcceptableObjCSelector(Selector Sel,
3773 ObjCMethodKind WantKind,
3774 IdentifierInfo **SelIdents,
3775 unsigned NumSelIdents) {
3776 if (NumSelIdents > Sel.getNumArgs())
3777 return false;
3778
3779 switch (WantKind) {
3780 case MK_Any: break;
3781 case MK_ZeroArgSelector: return Sel.isUnarySelector();
3782 case MK_OneArgSelector: return Sel.getNumArgs() == 1;
3783 }
3784
3785 for (unsigned I = 0; I != NumSelIdents; ++I)
3786 if (SelIdents[I] != Sel.getIdentifierInfoForSlot(I))
3787 return false;
3788
3789 return true;
3790}
3791
Douglas Gregor4ad96852009-11-19 07:41:15 +00003792static bool isAcceptableObjCMethod(ObjCMethodDecl *Method,
3793 ObjCMethodKind WantKind,
3794 IdentifierInfo **SelIdents,
3795 unsigned NumSelIdents) {
Douglas Gregor458433d2010-08-26 15:07:07 +00003796 return isAcceptableObjCSelector(Method->getSelector(), WantKind, SelIdents,
3797 NumSelIdents);
Douglas Gregor4ad96852009-11-19 07:41:15 +00003798}
3799
Douglas Gregor36ecb042009-11-17 23:22:23 +00003800/// \brief Add all of the Objective-C methods in the given Objective-C
3801/// container to the set of results.
3802///
3803/// The container will be a class, protocol, category, or implementation of
3804/// any of the above. This mether will recurse to include methods from
3805/// the superclasses of classes along with their categories, protocols, and
3806/// implementations.
3807///
3808/// \param Container the container in which we'll look to find methods.
3809///
3810/// \param WantInstance whether to add instance methods (only); if false, this
3811/// routine will add factory methods (only).
3812///
3813/// \param CurContext the context in which we're performing the lookup that
3814/// finds methods.
3815///
3816/// \param Results the structure into which we'll add results.
3817static void AddObjCMethods(ObjCContainerDecl *Container,
3818 bool WantInstanceMethods,
Douglas Gregor4ad96852009-11-19 07:41:15 +00003819 ObjCMethodKind WantKind,
Douglas Gregord3c68542009-11-19 01:08:35 +00003820 IdentifierInfo **SelIdents,
3821 unsigned NumSelIdents,
Douglas Gregor36ecb042009-11-17 23:22:23 +00003822 DeclContext *CurContext,
Douglas Gregor408be5a2010-08-25 01:08:01 +00003823 ResultBuilder &Results,
3824 bool InOriginalClass = true) {
John McCall0a2c5e22010-08-25 06:19:51 +00003825 typedef CodeCompletionResult Result;
Douglas Gregor36ecb042009-11-17 23:22:23 +00003826 for (ObjCContainerDecl::method_iterator M = Container->meth_begin(),
3827 MEnd = Container->meth_end();
3828 M != MEnd; ++M) {
Douglas Gregord3c68542009-11-19 01:08:35 +00003829 if ((*M)->isInstanceMethod() == WantInstanceMethods) {
3830 // Check whether the selector identifiers we've been given are a
3831 // subset of the identifiers for this particular method.
Douglas Gregor4ad96852009-11-19 07:41:15 +00003832 if (!isAcceptableObjCMethod(*M, WantKind, SelIdents, NumSelIdents))
Douglas Gregord3c68542009-11-19 01:08:35 +00003833 continue;
Douglas Gregor4ad96852009-11-19 07:41:15 +00003834
Douglas Gregord3c68542009-11-19 01:08:35 +00003835 Result R = Result(*M, 0);
3836 R.StartParameter = NumSelIdents;
Douglas Gregor4ad96852009-11-19 07:41:15 +00003837 R.AllParametersAreInformative = (WantKind != MK_Any);
Douglas Gregor408be5a2010-08-25 01:08:01 +00003838 if (!InOriginalClass)
3839 R.Priority += CCD_InBaseClass;
Douglas Gregord3c68542009-11-19 01:08:35 +00003840 Results.MaybeAddResult(R, CurContext);
3841 }
Douglas Gregor36ecb042009-11-17 23:22:23 +00003842 }
3843
3844 ObjCInterfaceDecl *IFace = dyn_cast<ObjCInterfaceDecl>(Container);
3845 if (!IFace)
3846 return;
3847
3848 // Add methods in protocols.
3849 const ObjCList<ObjCProtocolDecl> &Protocols= IFace->getReferencedProtocols();
3850 for (ObjCList<ObjCProtocolDecl>::iterator I = Protocols.begin(),
3851 E = Protocols.end();
3852 I != E; ++I)
Douglas Gregor4ad96852009-11-19 07:41:15 +00003853 AddObjCMethods(*I, WantInstanceMethods, WantKind, SelIdents, NumSelIdents,
Douglas Gregor408be5a2010-08-25 01:08:01 +00003854 CurContext, Results, false);
Douglas Gregor36ecb042009-11-17 23:22:23 +00003855
3856 // Add methods in categories.
3857 for (ObjCCategoryDecl *CatDecl = IFace->getCategoryList(); CatDecl;
3858 CatDecl = CatDecl->getNextClassCategory()) {
Douglas Gregor4ad96852009-11-19 07:41:15 +00003859 AddObjCMethods(CatDecl, WantInstanceMethods, WantKind, SelIdents,
Douglas Gregor408be5a2010-08-25 01:08:01 +00003860 NumSelIdents, CurContext, Results, InOriginalClass);
Douglas Gregor36ecb042009-11-17 23:22:23 +00003861
3862 // Add a categories protocol methods.
3863 const ObjCList<ObjCProtocolDecl> &Protocols
3864 = CatDecl->getReferencedProtocols();
3865 for (ObjCList<ObjCProtocolDecl>::iterator I = Protocols.begin(),
3866 E = Protocols.end();
3867 I != E; ++I)
Douglas Gregor4ad96852009-11-19 07:41:15 +00003868 AddObjCMethods(*I, WantInstanceMethods, WantKind, SelIdents,
Douglas Gregor408be5a2010-08-25 01:08:01 +00003869 NumSelIdents, CurContext, Results, false);
Douglas Gregor36ecb042009-11-17 23:22:23 +00003870
3871 // Add methods in category implementations.
3872 if (ObjCCategoryImplDecl *Impl = CatDecl->getImplementation())
Douglas Gregor4ad96852009-11-19 07:41:15 +00003873 AddObjCMethods(Impl, WantInstanceMethods, WantKind, SelIdents,
Douglas Gregor408be5a2010-08-25 01:08:01 +00003874 NumSelIdents, CurContext, Results, InOriginalClass);
Douglas Gregor36ecb042009-11-17 23:22:23 +00003875 }
3876
3877 // Add methods in superclass.
3878 if (IFace->getSuperClass())
Douglas Gregor4ad96852009-11-19 07:41:15 +00003879 AddObjCMethods(IFace->getSuperClass(), WantInstanceMethods, WantKind,
Douglas Gregor408be5a2010-08-25 01:08:01 +00003880 SelIdents, NumSelIdents, CurContext, Results, false);
Douglas Gregor36ecb042009-11-17 23:22:23 +00003881
3882 // Add methods in our implementation, if any.
3883 if (ObjCImplementationDecl *Impl = IFace->getImplementation())
Douglas Gregor4ad96852009-11-19 07:41:15 +00003884 AddObjCMethods(Impl, WantInstanceMethods, WantKind, SelIdents,
Douglas Gregor408be5a2010-08-25 01:08:01 +00003885 NumSelIdents, CurContext, Results, InOriginalClass);
Douglas Gregor4ad96852009-11-19 07:41:15 +00003886}
3887
3888
John McCalld226f652010-08-21 09:40:31 +00003889void Sema::CodeCompleteObjCPropertyGetter(Scope *S, Decl *ClassDecl,
3890 Decl **Methods,
Douglas Gregor4ad96852009-11-19 07:41:15 +00003891 unsigned NumMethods) {
John McCall0a2c5e22010-08-25 06:19:51 +00003892 typedef CodeCompletionResult Result;
Douglas Gregor4ad96852009-11-19 07:41:15 +00003893
3894 // Try to find the interface where getters might live.
John McCalld226f652010-08-21 09:40:31 +00003895 ObjCInterfaceDecl *Class = dyn_cast_or_null<ObjCInterfaceDecl>(ClassDecl);
Douglas Gregor4ad96852009-11-19 07:41:15 +00003896 if (!Class) {
3897 if (ObjCCategoryDecl *Category
John McCalld226f652010-08-21 09:40:31 +00003898 = dyn_cast_or_null<ObjCCategoryDecl>(ClassDecl))
Douglas Gregor4ad96852009-11-19 07:41:15 +00003899 Class = Category->getClassInterface();
3900
3901 if (!Class)
3902 return;
3903 }
3904
3905 // Find all of the potential getters.
3906 ResultBuilder Results(*this);
3907 Results.EnterNewScope();
3908
3909 // FIXME: We need to do this because Objective-C methods don't get
3910 // pushed into DeclContexts early enough. Argh!
3911 for (unsigned I = 0; I != NumMethods; ++I) {
3912 if (ObjCMethodDecl *Method
John McCalld226f652010-08-21 09:40:31 +00003913 = dyn_cast_or_null<ObjCMethodDecl>(Methods[I]))
Douglas Gregor4ad96852009-11-19 07:41:15 +00003914 if (Method->isInstanceMethod() &&
3915 isAcceptableObjCMethod(Method, MK_ZeroArgSelector, 0, 0)) {
3916 Result R = Result(Method, 0);
3917 R.AllParametersAreInformative = true;
3918 Results.MaybeAddResult(R, CurContext);
3919 }
3920 }
3921
3922 AddObjCMethods(Class, true, MK_ZeroArgSelector, 0, 0, CurContext, Results);
3923 Results.ExitScope();
Douglas Gregore6b1bb62010-08-11 21:23:17 +00003924 HandleCodeCompleteResults(this, CodeCompleter,
3925 CodeCompletionContext::CCC_Other,
3926 Results.data(),Results.size());
Douglas Gregor4ad96852009-11-19 07:41:15 +00003927}
3928
John McCalld226f652010-08-21 09:40:31 +00003929void Sema::CodeCompleteObjCPropertySetter(Scope *S, Decl *ObjCImplDecl,
3930 Decl **Methods,
Douglas Gregor4ad96852009-11-19 07:41:15 +00003931 unsigned NumMethods) {
John McCall0a2c5e22010-08-25 06:19:51 +00003932 typedef CodeCompletionResult Result;
Douglas Gregor4ad96852009-11-19 07:41:15 +00003933
3934 // Try to find the interface where setters might live.
3935 ObjCInterfaceDecl *Class
John McCalld226f652010-08-21 09:40:31 +00003936 = dyn_cast_or_null<ObjCInterfaceDecl>(ObjCImplDecl);
Douglas Gregor4ad96852009-11-19 07:41:15 +00003937 if (!Class) {
3938 if (ObjCCategoryDecl *Category
John McCalld226f652010-08-21 09:40:31 +00003939 = dyn_cast_or_null<ObjCCategoryDecl>(ObjCImplDecl))
Douglas Gregor4ad96852009-11-19 07:41:15 +00003940 Class = Category->getClassInterface();
3941
3942 if (!Class)
3943 return;
3944 }
3945
3946 // Find all of the potential getters.
3947 ResultBuilder Results(*this);
3948 Results.EnterNewScope();
3949
3950 // FIXME: We need to do this because Objective-C methods don't get
3951 // pushed into DeclContexts early enough. Argh!
3952 for (unsigned I = 0; I != NumMethods; ++I) {
3953 if (ObjCMethodDecl *Method
John McCalld226f652010-08-21 09:40:31 +00003954 = dyn_cast_or_null<ObjCMethodDecl>(Methods[I]))
Douglas Gregor4ad96852009-11-19 07:41:15 +00003955 if (Method->isInstanceMethod() &&
3956 isAcceptableObjCMethod(Method, MK_OneArgSelector, 0, 0)) {
3957 Result R = Result(Method, 0);
3958 R.AllParametersAreInformative = true;
3959 Results.MaybeAddResult(R, CurContext);
3960 }
3961 }
3962
3963 AddObjCMethods(Class, true, MK_OneArgSelector, 0, 0, CurContext, Results);
3964
3965 Results.ExitScope();
Douglas Gregore6b1bb62010-08-11 21:23:17 +00003966 HandleCodeCompleteResults(this, CodeCompleter,
3967 CodeCompletionContext::CCC_Other,
3968 Results.data(),Results.size());
Douglas Gregor36ecb042009-11-17 23:22:23 +00003969}
3970
Douglas Gregord32b0222010-08-24 01:06:58 +00003971void Sema::CodeCompleteObjCPassingType(Scope *S, ObjCDeclSpec &DS) {
John McCall0a2c5e22010-08-25 06:19:51 +00003972 typedef CodeCompletionResult Result;
Douglas Gregord32b0222010-08-24 01:06:58 +00003973 ResultBuilder Results(*this);
3974 Results.EnterNewScope();
3975
3976 // Add context-sensitive, Objective-C parameter-passing keywords.
3977 bool AddedInOut = false;
3978 if ((DS.getObjCDeclQualifier() &
3979 (ObjCDeclSpec::DQ_In | ObjCDeclSpec::DQ_Inout)) == 0) {
3980 Results.AddResult("in");
3981 Results.AddResult("inout");
3982 AddedInOut = true;
3983 }
3984 if ((DS.getObjCDeclQualifier() &
3985 (ObjCDeclSpec::DQ_Out | ObjCDeclSpec::DQ_Inout)) == 0) {
3986 Results.AddResult("out");
3987 if (!AddedInOut)
3988 Results.AddResult("inout");
3989 }
3990 if ((DS.getObjCDeclQualifier() &
3991 (ObjCDeclSpec::DQ_Bycopy | ObjCDeclSpec::DQ_Byref |
3992 ObjCDeclSpec::DQ_Oneway)) == 0) {
3993 Results.AddResult("bycopy");
3994 Results.AddResult("byref");
3995 Results.AddResult("oneway");
3996 }
3997
3998 // Add various builtin type names and specifiers.
3999 AddOrdinaryNameResults(PCC_Type, S, *this, Results);
4000 Results.ExitScope();
4001
4002 // Add the various type names
4003 Results.setFilter(&ResultBuilder::IsOrdinaryNonValueName);
4004 CodeCompletionDeclConsumer Consumer(Results, CurContext);
4005 LookupVisibleDecls(S, LookupOrdinaryName, Consumer,
4006 CodeCompleter->includeGlobals());
4007
4008 if (CodeCompleter->includeMacros())
4009 AddMacroResults(PP, Results);
4010
4011 HandleCodeCompleteResults(this, CodeCompleter,
4012 CodeCompletionContext::CCC_Type,
4013 Results.data(), Results.size());
4014}
4015
Douglas Gregor22f56992010-04-06 19:22:33 +00004016/// \brief When we have an expression with type "id", we may assume
4017/// that it has some more-specific class type based on knowledge of
4018/// common uses of Objective-C. This routine returns that class type,
4019/// or NULL if no better result could be determined.
4020static ObjCInterfaceDecl *GetAssumedMessageSendExprType(Expr *E) {
Douglas Gregor78edf512010-09-15 16:23:04 +00004021 ObjCMessageExpr *Msg = dyn_cast_or_null<ObjCMessageExpr>(E);
Douglas Gregor22f56992010-04-06 19:22:33 +00004022 if (!Msg)
4023 return 0;
4024
4025 Selector Sel = Msg->getSelector();
4026 if (Sel.isNull())
4027 return 0;
4028
4029 IdentifierInfo *Id = Sel.getIdentifierInfoForSlot(0);
4030 if (!Id)
4031 return 0;
4032
4033 ObjCMethodDecl *Method = Msg->getMethodDecl();
4034 if (!Method)
4035 return 0;
4036
4037 // Determine the class that we're sending the message to.
Douglas Gregor04badcf2010-04-21 00:45:42 +00004038 ObjCInterfaceDecl *IFace = 0;
4039 switch (Msg->getReceiverKind()) {
4040 case ObjCMessageExpr::Class:
John McCallc12c5bb2010-05-15 11:32:37 +00004041 if (const ObjCObjectType *ObjType
4042 = Msg->getClassReceiver()->getAs<ObjCObjectType>())
4043 IFace = ObjType->getInterface();
Douglas Gregor04badcf2010-04-21 00:45:42 +00004044 break;
4045
4046 case ObjCMessageExpr::Instance: {
4047 QualType T = Msg->getInstanceReceiver()->getType();
4048 if (const ObjCObjectPointerType *Ptr = T->getAs<ObjCObjectPointerType>())
4049 IFace = Ptr->getInterfaceDecl();
4050 break;
4051 }
4052
4053 case ObjCMessageExpr::SuperInstance:
4054 case ObjCMessageExpr::SuperClass:
4055 break;
Douglas Gregor22f56992010-04-06 19:22:33 +00004056 }
4057
4058 if (!IFace)
4059 return 0;
4060
4061 ObjCInterfaceDecl *Super = IFace->getSuperClass();
4062 if (Method->isInstanceMethod())
4063 return llvm::StringSwitch<ObjCInterfaceDecl *>(Id->getName())
4064 .Case("retain", IFace)
4065 .Case("autorelease", IFace)
4066 .Case("copy", IFace)
4067 .Case("copyWithZone", IFace)
4068 .Case("mutableCopy", IFace)
4069 .Case("mutableCopyWithZone", IFace)
4070 .Case("awakeFromCoder", IFace)
4071 .Case("replacementObjectFromCoder", IFace)
4072 .Case("class", IFace)
4073 .Case("classForCoder", IFace)
4074 .Case("superclass", Super)
4075 .Default(0);
4076
4077 return llvm::StringSwitch<ObjCInterfaceDecl *>(Id->getName())
4078 .Case("new", IFace)
4079 .Case("alloc", IFace)
4080 .Case("allocWithZone", IFace)
4081 .Case("class", IFace)
4082 .Case("superclass", Super)
4083 .Default(0);
4084}
4085
Douglas Gregor03d8aec2010-08-27 15:10:57 +00004086// Add a special completion for a message send to "super", which fills in the
4087// most likely case of forwarding all of our arguments to the superclass
4088// function.
4089///
4090/// \param S The semantic analysis object.
4091///
4092/// \param S NeedSuperKeyword Whether we need to prefix this completion with
4093/// the "super" keyword. Otherwise, we just need to provide the arguments.
4094///
4095/// \param SelIdents The identifiers in the selector that have already been
4096/// provided as arguments for a send to "super".
4097///
4098/// \param NumSelIdents The number of identifiers in \p SelIdents.
4099///
4100/// \param Results The set of results to augment.
4101///
4102/// \returns the Objective-C method declaration that would be invoked by
4103/// this "super" completion. If NULL, no completion was added.
4104static ObjCMethodDecl *AddSuperSendCompletion(Sema &S, bool NeedSuperKeyword,
4105 IdentifierInfo **SelIdents,
4106 unsigned NumSelIdents,
4107 ResultBuilder &Results) {
4108 ObjCMethodDecl *CurMethod = S.getCurMethodDecl();
4109 if (!CurMethod)
4110 return 0;
4111
4112 ObjCInterfaceDecl *Class = CurMethod->getClassInterface();
4113 if (!Class)
4114 return 0;
4115
4116 // Try to find a superclass method with the same selector.
4117 ObjCMethodDecl *SuperMethod = 0;
4118 while ((Class = Class->getSuperClass()) && !SuperMethod)
4119 SuperMethod = Class->getMethod(CurMethod->getSelector(),
4120 CurMethod->isInstanceMethod());
4121
4122 if (!SuperMethod)
4123 return 0;
4124
4125 // Check whether the superclass method has the same signature.
4126 if (CurMethod->param_size() != SuperMethod->param_size() ||
4127 CurMethod->isVariadic() != SuperMethod->isVariadic())
4128 return 0;
4129
4130 for (ObjCMethodDecl::param_iterator CurP = CurMethod->param_begin(),
4131 CurPEnd = CurMethod->param_end(),
4132 SuperP = SuperMethod->param_begin();
4133 CurP != CurPEnd; ++CurP, ++SuperP) {
4134 // Make sure the parameter types are compatible.
4135 if (!S.Context.hasSameUnqualifiedType((*CurP)->getType(),
4136 (*SuperP)->getType()))
4137 return 0;
4138
4139 // Make sure we have a parameter name to forward!
4140 if (!(*CurP)->getIdentifier())
4141 return 0;
4142 }
4143
4144 // We have a superclass method. Now, form the send-to-super completion.
4145 CodeCompletionString *Pattern = new CodeCompletionString;
4146
4147 // Give this completion a return type.
4148 AddResultTypeChunk(S.Context, SuperMethod, Pattern);
4149
4150 // If we need the "super" keyword, add it (plus some spacing).
4151 if (NeedSuperKeyword) {
4152 Pattern->AddTypedTextChunk("super");
4153 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
4154 }
4155
4156 Selector Sel = CurMethod->getSelector();
4157 if (Sel.isUnarySelector()) {
4158 if (NeedSuperKeyword)
4159 Pattern->AddTextChunk(Sel.getIdentifierInfoForSlot(0)->getName());
4160 else
4161 Pattern->AddTypedTextChunk(Sel.getIdentifierInfoForSlot(0)->getName());
4162 } else {
4163 ObjCMethodDecl::param_iterator CurP = CurMethod->param_begin();
4164 for (unsigned I = 0, N = Sel.getNumArgs(); I != N; ++I, ++CurP) {
4165 if (I > NumSelIdents)
4166 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
4167
4168 if (I < NumSelIdents)
4169 Pattern->AddInformativeChunk(
4170 Sel.getIdentifierInfoForSlot(I)->getName().str() + ":");
4171 else if (NeedSuperKeyword || I > NumSelIdents) {
4172 Pattern->AddTextChunk(
4173 Sel.getIdentifierInfoForSlot(I)->getName().str() + ":");
4174 Pattern->AddPlaceholderChunk((*CurP)->getIdentifier()->getName());
4175 } else {
4176 Pattern->AddTypedTextChunk(
4177 Sel.getIdentifierInfoForSlot(I)->getName().str() + ":");
4178 Pattern->AddPlaceholderChunk((*CurP)->getIdentifier()->getName());
4179 }
4180 }
4181 }
4182
4183 Results.AddResult(CodeCompletionResult(Pattern, CCP_SuperCompletion,
4184 SuperMethod->isInstanceMethod()
4185 ? CXCursor_ObjCInstanceMethodDecl
4186 : CXCursor_ObjCClassMethodDecl));
4187 return SuperMethod;
4188}
4189
Douglas Gregor8e254cf2010-05-27 23:06:34 +00004190void Sema::CodeCompleteObjCMessageReceiver(Scope *S) {
John McCall0a2c5e22010-08-25 06:19:51 +00004191 typedef CodeCompletionResult Result;
Douglas Gregor8e254cf2010-05-27 23:06:34 +00004192 ResultBuilder Results(*this);
4193
4194 // Find anything that looks like it could be a message receiver.
4195 Results.setFilter(&ResultBuilder::IsObjCMessageReceiver);
4196 CodeCompletionDeclConsumer Consumer(Results, CurContext);
4197 Results.EnterNewScope();
Douglas Gregor8071e422010-08-15 06:18:01 +00004198 LookupVisibleDecls(S, LookupOrdinaryName, Consumer,
4199 CodeCompleter->includeGlobals());
Douglas Gregor8e254cf2010-05-27 23:06:34 +00004200
4201 // If we are in an Objective-C method inside a class that has a superclass,
4202 // add "super" as an option.
4203 if (ObjCMethodDecl *Method = getCurMethodDecl())
4204 if (ObjCInterfaceDecl *Iface = Method->getClassInterface())
Douglas Gregor03d8aec2010-08-27 15:10:57 +00004205 if (Iface->getSuperClass()) {
Douglas Gregor8e254cf2010-05-27 23:06:34 +00004206 Results.AddResult(Result("super"));
Douglas Gregor03d8aec2010-08-27 15:10:57 +00004207
4208 AddSuperSendCompletion(*this, /*NeedSuperKeyword=*/true, 0, 0, Results);
4209 }
Douglas Gregor8e254cf2010-05-27 23:06:34 +00004210
4211 Results.ExitScope();
4212
4213 if (CodeCompleter->includeMacros())
4214 AddMacroResults(PP, Results);
Douglas Gregore6b1bb62010-08-11 21:23:17 +00004215 HandleCodeCompleteResults(this, CodeCompleter,
4216 CodeCompletionContext::CCC_ObjCMessageReceiver,
4217 Results.data(), Results.size());
Douglas Gregor8e254cf2010-05-27 23:06:34 +00004218
4219}
4220
Douglas Gregor2725ca82010-04-21 19:57:20 +00004221void Sema::CodeCompleteObjCSuperMessage(Scope *S, SourceLocation SuperLoc,
4222 IdentifierInfo **SelIdents,
4223 unsigned NumSelIdents) {
4224 ObjCInterfaceDecl *CDecl = 0;
4225 if (ObjCMethodDecl *CurMethod = getCurMethodDecl()) {
4226 // Figure out which interface we're in.
4227 CDecl = CurMethod->getClassInterface();
4228 if (!CDecl)
4229 return;
4230
4231 // Find the superclass of this class.
4232 CDecl = CDecl->getSuperClass();
4233 if (!CDecl)
4234 return;
4235
4236 if (CurMethod->isInstanceMethod()) {
4237 // We are inside an instance method, which means that the message
4238 // send [super ...] is actually calling an instance method on the
4239 // current object. Build the super expression and handle this like
4240 // an instance method.
4241 QualType SuperTy = Context.getObjCInterfaceType(CDecl);
4242 SuperTy = Context.getObjCObjectPointerType(SuperTy);
John McCall60d7b3a2010-08-24 06:29:42 +00004243 ExprResult Super
Douglas Gregor2725ca82010-04-21 19:57:20 +00004244 = Owned(new (Context) ObjCSuperExpr(SuperLoc, SuperTy));
4245 return CodeCompleteObjCInstanceMessage(S, (Expr *)Super.get(),
Douglas Gregor03d8aec2010-08-27 15:10:57 +00004246 SelIdents, NumSelIdents,
4247 /*IsSuper=*/true);
Douglas Gregor2725ca82010-04-21 19:57:20 +00004248 }
4249
4250 // Fall through to send to the superclass in CDecl.
4251 } else {
4252 // "super" may be the name of a type or variable. Figure out which
4253 // it is.
4254 IdentifierInfo *Super = &Context.Idents.get("super");
4255 NamedDecl *ND = LookupSingleName(S, Super, SuperLoc,
4256 LookupOrdinaryName);
4257 if ((CDecl = dyn_cast_or_null<ObjCInterfaceDecl>(ND))) {
4258 // "super" names an interface. Use it.
4259 } else if (TypeDecl *TD = dyn_cast_or_null<TypeDecl>(ND)) {
John McCallc12c5bb2010-05-15 11:32:37 +00004260 if (const ObjCObjectType *Iface
4261 = Context.getTypeDeclType(TD)->getAs<ObjCObjectType>())
4262 CDecl = Iface->getInterface();
Douglas Gregor2725ca82010-04-21 19:57:20 +00004263 } else if (ND && isa<UnresolvedUsingTypenameDecl>(ND)) {
4264 // "super" names an unresolved type; we can't be more specific.
4265 } else {
4266 // Assume that "super" names some kind of value and parse that way.
4267 CXXScopeSpec SS;
4268 UnqualifiedId id;
4269 id.setIdentifier(Super, SuperLoc);
John McCall60d7b3a2010-08-24 06:29:42 +00004270 ExprResult SuperExpr = ActOnIdExpression(S, SS, id, false, false);
Douglas Gregor2725ca82010-04-21 19:57:20 +00004271 return CodeCompleteObjCInstanceMessage(S, (Expr *)SuperExpr.get(),
4272 SelIdents, NumSelIdents);
4273 }
4274
4275 // Fall through
4276 }
4277
John McCallb3d87482010-08-24 05:47:05 +00004278 ParsedType Receiver;
Douglas Gregor2725ca82010-04-21 19:57:20 +00004279 if (CDecl)
John McCallb3d87482010-08-24 05:47:05 +00004280 Receiver = ParsedType::make(Context.getObjCInterfaceType(CDecl));
Douglas Gregor2725ca82010-04-21 19:57:20 +00004281 return CodeCompleteObjCClassMessage(S, Receiver, SelIdents,
Douglas Gregor03d8aec2010-08-27 15:10:57 +00004282 NumSelIdents, /*IsSuper=*/true);
Douglas Gregor2725ca82010-04-21 19:57:20 +00004283}
4284
John McCallb3d87482010-08-24 05:47:05 +00004285void Sema::CodeCompleteObjCClassMessage(Scope *S, ParsedType Receiver,
Douglas Gregord3c68542009-11-19 01:08:35 +00004286 IdentifierInfo **SelIdents,
Douglas Gregor03d8aec2010-08-27 15:10:57 +00004287 unsigned NumSelIdents,
4288 bool IsSuper) {
John McCall0a2c5e22010-08-25 06:19:51 +00004289 typedef CodeCompletionResult Result;
Douglas Gregor24a069f2009-11-17 17:59:40 +00004290 ObjCInterfaceDecl *CDecl = 0;
4291
Douglas Gregor24a069f2009-11-17 17:59:40 +00004292 // If the given name refers to an interface type, retrieve the
4293 // corresponding declaration.
Douglas Gregor2725ca82010-04-21 19:57:20 +00004294 if (Receiver) {
4295 QualType T = GetTypeFromParser(Receiver, 0);
4296 if (!T.isNull())
John McCallc12c5bb2010-05-15 11:32:37 +00004297 if (const ObjCObjectType *Interface = T->getAs<ObjCObjectType>())
4298 CDecl = Interface->getInterface();
Douglas Gregor24a069f2009-11-17 17:59:40 +00004299 }
4300
Douglas Gregor36ecb042009-11-17 23:22:23 +00004301 // Add all of the factory methods in this Objective-C class, its protocols,
4302 // superclasses, categories, implementation, etc.
Steve Naroffc4df6d22009-11-07 02:08:14 +00004303 ResultBuilder Results(*this);
4304 Results.EnterNewScope();
Douglas Gregor13438f92010-04-06 16:40:00 +00004305
Douglas Gregor03d8aec2010-08-27 15:10:57 +00004306 // If this is a send-to-super, try to add the special "super" send
4307 // completion.
4308 if (IsSuper) {
4309 if (ObjCMethodDecl *SuperMethod
4310 = AddSuperSendCompletion(*this, false, SelIdents, NumSelIdents,
4311 Results))
4312 Results.Ignore(SuperMethod);
4313 }
4314
Douglas Gregor265f7492010-08-27 15:29:55 +00004315 // If we're inside an Objective-C method definition, prefer its selector to
4316 // others.
4317 if (ObjCMethodDecl *CurMethod = getCurMethodDecl())
4318 Results.setPreferredSelector(CurMethod->getSelector());
4319
Douglas Gregor13438f92010-04-06 16:40:00 +00004320 if (CDecl)
4321 AddObjCMethods(CDecl, false, MK_Any, SelIdents, NumSelIdents, CurContext,
4322 Results);
Douglas Gregor2725ca82010-04-21 19:57:20 +00004323 else {
Douglas Gregor13438f92010-04-06 16:40:00 +00004324 // We're messaging "id" as a type; provide all class/factory methods.
4325
Douglas Gregor719770d2010-04-06 17:30:22 +00004326 // If we have an external source, load the entire class method
Sebastian Redl3c7f4132010-08-18 23:57:06 +00004327 // pool from the AST file.
Douglas Gregor719770d2010-04-06 17:30:22 +00004328 if (ExternalSource) {
John McCall76bd1f32010-06-01 09:23:16 +00004329 for (uint32_t I = 0, N = ExternalSource->GetNumExternalSelectors();
4330 I != N; ++I) {
4331 Selector Sel = ExternalSource->GetExternalSelector(I);
Sebastian Redldb9d2142010-08-02 23:18:59 +00004332 if (Sel.isNull() || MethodPool.count(Sel))
Douglas Gregor719770d2010-04-06 17:30:22 +00004333 continue;
4334
Sebastian Redldb9d2142010-08-02 23:18:59 +00004335 ReadMethodPool(Sel);
Douglas Gregor719770d2010-04-06 17:30:22 +00004336 }
4337 }
4338
Sebastian Redldb9d2142010-08-02 23:18:59 +00004339 for (GlobalMethodPool::iterator M = MethodPool.begin(),
4340 MEnd = MethodPool.end();
4341 M != MEnd; ++M) {
4342 for (ObjCMethodList *MethList = &M->second.second;
4343 MethList && MethList->Method;
Douglas Gregor13438f92010-04-06 16:40:00 +00004344 MethList = MethList->Next) {
4345 if (!isAcceptableObjCMethod(MethList->Method, MK_Any, SelIdents,
4346 NumSelIdents))
4347 continue;
4348
4349 Result R(MethList->Method, 0);
4350 R.StartParameter = NumSelIdents;
4351 R.AllParametersAreInformative = false;
4352 Results.MaybeAddResult(R, CurContext);
4353 }
4354 }
4355 }
4356
Steve Naroffc4df6d22009-11-07 02:08:14 +00004357 Results.ExitScope();
Douglas Gregore6b1bb62010-08-11 21:23:17 +00004358 HandleCodeCompleteResults(this, CodeCompleter,
4359 CodeCompletionContext::CCC_Other,
Douglas Gregor03d8aec2010-08-27 15:10:57 +00004360 Results.data(), Results.size());
Steve Naroffc4df6d22009-11-07 02:08:14 +00004361}
4362
Douglas Gregord3c68542009-11-19 01:08:35 +00004363void Sema::CodeCompleteObjCInstanceMessage(Scope *S, ExprTy *Receiver,
4364 IdentifierInfo **SelIdents,
Douglas Gregor03d8aec2010-08-27 15:10:57 +00004365 unsigned NumSelIdents,
4366 bool IsSuper) {
John McCall0a2c5e22010-08-25 06:19:51 +00004367 typedef CodeCompletionResult Result;
Steve Naroffc4df6d22009-11-07 02:08:14 +00004368
4369 Expr *RecExpr = static_cast<Expr *>(Receiver);
Steve Naroffc4df6d22009-11-07 02:08:14 +00004370
Douglas Gregor36ecb042009-11-17 23:22:23 +00004371 // If necessary, apply function/array conversion to the receiver.
4372 // C99 6.7.5.3p[7,8].
Douglas Gregor78edf512010-09-15 16:23:04 +00004373 if (RecExpr)
4374 DefaultFunctionArrayLvalueConversion(RecExpr);
4375 QualType ReceiverType = RecExpr? RecExpr->getType() : Context.getObjCIdType();
Steve Naroffc4df6d22009-11-07 02:08:14 +00004376
Douglas Gregor36ecb042009-11-17 23:22:23 +00004377 // Build the set of methods we can see.
4378 ResultBuilder Results(*this);
4379 Results.EnterNewScope();
Douglas Gregor22f56992010-04-06 19:22:33 +00004380
Douglas Gregor03d8aec2010-08-27 15:10:57 +00004381 // If this is a send-to-super, try to add the special "super" send
4382 // completion.
4383 if (IsSuper) {
4384 if (ObjCMethodDecl *SuperMethod
4385 = AddSuperSendCompletion(*this, false, SelIdents, NumSelIdents,
4386 Results))
4387 Results.Ignore(SuperMethod);
4388 }
4389
Douglas Gregor265f7492010-08-27 15:29:55 +00004390 // If we're inside an Objective-C method definition, prefer its selector to
4391 // others.
4392 if (ObjCMethodDecl *CurMethod = getCurMethodDecl())
4393 Results.setPreferredSelector(CurMethod->getSelector());
4394
Douglas Gregor22f56992010-04-06 19:22:33 +00004395 // If we're messaging an expression with type "id" or "Class", check
4396 // whether we know something special about the receiver that allows
4397 // us to assume a more-specific receiver type.
4398 if (ReceiverType->isObjCIdType() || ReceiverType->isObjCClassType())
4399 if (ObjCInterfaceDecl *IFace = GetAssumedMessageSendExprType(RecExpr))
4400 ReceiverType = Context.getObjCObjectPointerType(
4401 Context.getObjCInterfaceType(IFace));
Douglas Gregor36ecb042009-11-17 23:22:23 +00004402
Douglas Gregorf74a4192009-11-18 00:06:18 +00004403 // Handle messages to Class. This really isn't a message to an instance
4404 // method, so we treat it the same way we would treat a message send to a
4405 // class method.
4406 if (ReceiverType->isObjCClassType() ||
4407 ReceiverType->isObjCQualifiedClassType()) {
4408 if (ObjCMethodDecl *CurMethod = getCurMethodDecl()) {
4409 if (ObjCInterfaceDecl *ClassDecl = CurMethod->getClassInterface())
Douglas Gregor4ad96852009-11-19 07:41:15 +00004410 AddObjCMethods(ClassDecl, false, MK_Any, SelIdents, NumSelIdents,
4411 CurContext, Results);
Douglas Gregorf74a4192009-11-18 00:06:18 +00004412 }
4413 }
4414 // Handle messages to a qualified ID ("id<foo>").
4415 else if (const ObjCObjectPointerType *QualID
4416 = ReceiverType->getAsObjCQualifiedIdType()) {
4417 // Search protocols for instance methods.
4418 for (ObjCObjectPointerType::qual_iterator I = QualID->qual_begin(),
4419 E = QualID->qual_end();
4420 I != E; ++I)
Douglas Gregor4ad96852009-11-19 07:41:15 +00004421 AddObjCMethods(*I, true, MK_Any, SelIdents, NumSelIdents, CurContext,
4422 Results);
Douglas Gregorf74a4192009-11-18 00:06:18 +00004423 }
4424 // Handle messages to a pointer to interface type.
4425 else if (const ObjCObjectPointerType *IFacePtr
4426 = ReceiverType->getAsObjCInterfacePointerType()) {
4427 // Search the class, its superclasses, etc., for instance methods.
Douglas Gregor4ad96852009-11-19 07:41:15 +00004428 AddObjCMethods(IFacePtr->getInterfaceDecl(), true, MK_Any, SelIdents,
4429 NumSelIdents, CurContext, Results);
Douglas Gregorf74a4192009-11-18 00:06:18 +00004430
4431 // Search protocols for instance methods.
4432 for (ObjCObjectPointerType::qual_iterator I = IFacePtr->qual_begin(),
4433 E = IFacePtr->qual_end();
4434 I != E; ++I)
Douglas Gregor4ad96852009-11-19 07:41:15 +00004435 AddObjCMethods(*I, true, MK_Any, SelIdents, NumSelIdents, CurContext,
4436 Results);
Douglas Gregorf74a4192009-11-18 00:06:18 +00004437 }
Douglas Gregor13438f92010-04-06 16:40:00 +00004438 // Handle messages to "id".
4439 else if (ReceiverType->isObjCIdType()) {
Douglas Gregor719770d2010-04-06 17:30:22 +00004440 // We're messaging "id", so provide all instance methods we know
4441 // about as code-completion results.
4442
4443 // If we have an external source, load the entire class method
Sebastian Redl3c7f4132010-08-18 23:57:06 +00004444 // pool from the AST file.
Douglas Gregor719770d2010-04-06 17:30:22 +00004445 if (ExternalSource) {
John McCall76bd1f32010-06-01 09:23:16 +00004446 for (uint32_t I = 0, N = ExternalSource->GetNumExternalSelectors();
4447 I != N; ++I) {
4448 Selector Sel = ExternalSource->GetExternalSelector(I);
Sebastian Redldb9d2142010-08-02 23:18:59 +00004449 if (Sel.isNull() || MethodPool.count(Sel))
Douglas Gregor719770d2010-04-06 17:30:22 +00004450 continue;
4451
Sebastian Redldb9d2142010-08-02 23:18:59 +00004452 ReadMethodPool(Sel);
Douglas Gregor719770d2010-04-06 17:30:22 +00004453 }
4454 }
4455
Sebastian Redldb9d2142010-08-02 23:18:59 +00004456 for (GlobalMethodPool::iterator M = MethodPool.begin(),
4457 MEnd = MethodPool.end();
4458 M != MEnd; ++M) {
4459 for (ObjCMethodList *MethList = &M->second.first;
4460 MethList && MethList->Method;
Douglas Gregor13438f92010-04-06 16:40:00 +00004461 MethList = MethList->Next) {
4462 if (!isAcceptableObjCMethod(MethList->Method, MK_Any, SelIdents,
4463 NumSelIdents))
4464 continue;
4465
4466 Result R(MethList->Method, 0);
4467 R.StartParameter = NumSelIdents;
4468 R.AllParametersAreInformative = false;
4469 Results.MaybeAddResult(R, CurContext);
4470 }
4471 }
4472 }
4473
Steve Naroffc4df6d22009-11-07 02:08:14 +00004474 Results.ExitScope();
Douglas Gregore6b1bb62010-08-11 21:23:17 +00004475 HandleCodeCompleteResults(this, CodeCompleter,
4476 CodeCompletionContext::CCC_Other,
4477 Results.data(),Results.size());
Steve Naroffc4df6d22009-11-07 02:08:14 +00004478}
Douglas Gregor55385fe2009-11-18 04:19:12 +00004479
Douglas Gregorfb629412010-08-23 21:17:50 +00004480void Sema::CodeCompleteObjCForCollection(Scope *S,
4481 DeclGroupPtrTy IterationVar) {
4482 CodeCompleteExpressionData Data;
4483 Data.ObjCCollection = true;
4484
4485 if (IterationVar.getAsOpaquePtr()) {
4486 DeclGroupRef DG = IterationVar.getAsVal<DeclGroupRef>();
4487 for (DeclGroupRef::iterator I = DG.begin(), End = DG.end(); I != End; ++I) {
4488 if (*I)
4489 Data.IgnoreDecls.push_back(*I);
4490 }
4491 }
4492
4493 CodeCompleteExpression(S, Data);
4494}
4495
Douglas Gregor458433d2010-08-26 15:07:07 +00004496void Sema::CodeCompleteObjCSelector(Scope *S, IdentifierInfo **SelIdents,
4497 unsigned NumSelIdents) {
4498 // If we have an external source, load the entire class method
4499 // pool from the AST file.
4500 if (ExternalSource) {
4501 for (uint32_t I = 0, N = ExternalSource->GetNumExternalSelectors();
4502 I != N; ++I) {
4503 Selector Sel = ExternalSource->GetExternalSelector(I);
4504 if (Sel.isNull() || MethodPool.count(Sel))
4505 continue;
4506
4507 ReadMethodPool(Sel);
4508 }
4509 }
4510
4511 ResultBuilder Results(*this);
4512 Results.EnterNewScope();
4513 for (GlobalMethodPool::iterator M = MethodPool.begin(),
4514 MEnd = MethodPool.end();
4515 M != MEnd; ++M) {
4516
4517 Selector Sel = M->first;
4518 if (!isAcceptableObjCSelector(Sel, MK_Any, SelIdents, NumSelIdents))
4519 continue;
4520
4521 CodeCompletionString *Pattern = new CodeCompletionString;
4522 if (Sel.isUnarySelector()) {
4523 Pattern->AddTypedTextChunk(Sel.getIdentifierInfoForSlot(0)->getName());
4524 Results.AddResult(Pattern);
4525 continue;
4526 }
4527
Douglas Gregor2d9e21f2010-08-26 16:46:39 +00004528 std::string Accumulator;
Douglas Gregor458433d2010-08-26 15:07:07 +00004529 for (unsigned I = 0, N = Sel.getNumArgs(); I != N; ++I) {
Douglas Gregor2d9e21f2010-08-26 16:46:39 +00004530 if (I == NumSelIdents) {
4531 if (!Accumulator.empty()) {
4532 Pattern->AddInformativeChunk(Accumulator);
4533 Accumulator.clear();
4534 }
4535 }
4536
4537 Accumulator += Sel.getIdentifierInfoForSlot(I)->getName().str();
4538 Accumulator += ':';
Douglas Gregor458433d2010-08-26 15:07:07 +00004539 }
Douglas Gregor2d9e21f2010-08-26 16:46:39 +00004540 Pattern->AddTypedTextChunk(Accumulator);
Douglas Gregor458433d2010-08-26 15:07:07 +00004541 Results.AddResult(Pattern);
4542 }
4543 Results.ExitScope();
4544
4545 HandleCodeCompleteResults(this, CodeCompleter,
4546 CodeCompletionContext::CCC_SelectorName,
4547 Results.data(), Results.size());
4548}
4549
Douglas Gregor55385fe2009-11-18 04:19:12 +00004550/// \brief Add all of the protocol declarations that we find in the given
4551/// (translation unit) context.
4552static void AddProtocolResults(DeclContext *Ctx, DeclContext *CurContext,
Douglas Gregor083128f2009-11-18 04:49:41 +00004553 bool OnlyForwardDeclarations,
Douglas Gregor55385fe2009-11-18 04:19:12 +00004554 ResultBuilder &Results) {
John McCall0a2c5e22010-08-25 06:19:51 +00004555 typedef CodeCompletionResult Result;
Douglas Gregor55385fe2009-11-18 04:19:12 +00004556
4557 for (DeclContext::decl_iterator D = Ctx->decls_begin(),
4558 DEnd = Ctx->decls_end();
4559 D != DEnd; ++D) {
4560 // Record any protocols we find.
4561 if (ObjCProtocolDecl *Proto = dyn_cast<ObjCProtocolDecl>(*D))
Douglas Gregor083128f2009-11-18 04:49:41 +00004562 if (!OnlyForwardDeclarations || Proto->isForwardDecl())
Douglas Gregor608300b2010-01-14 16:14:35 +00004563 Results.AddResult(Result(Proto, 0), CurContext, 0, false);
Douglas Gregor55385fe2009-11-18 04:19:12 +00004564
4565 // Record any forward-declared protocols we find.
4566 if (ObjCForwardProtocolDecl *Forward
4567 = dyn_cast<ObjCForwardProtocolDecl>(*D)) {
4568 for (ObjCForwardProtocolDecl::protocol_iterator
4569 P = Forward->protocol_begin(),
4570 PEnd = Forward->protocol_end();
4571 P != PEnd; ++P)
Douglas Gregor083128f2009-11-18 04:49:41 +00004572 if (!OnlyForwardDeclarations || (*P)->isForwardDecl())
Douglas Gregor608300b2010-01-14 16:14:35 +00004573 Results.AddResult(Result(*P, 0), CurContext, 0, false);
Douglas Gregor55385fe2009-11-18 04:19:12 +00004574 }
4575 }
4576}
4577
4578void Sema::CodeCompleteObjCProtocolReferences(IdentifierLocPair *Protocols,
4579 unsigned NumProtocols) {
4580 ResultBuilder Results(*this);
4581 Results.EnterNewScope();
4582
4583 // Tell the result set to ignore all of the protocols we have
4584 // already seen.
4585 for (unsigned I = 0; I != NumProtocols; ++I)
Douglas Gregorc83c6872010-04-15 22:33:43 +00004586 if (ObjCProtocolDecl *Protocol = LookupProtocol(Protocols[I].first,
4587 Protocols[I].second))
Douglas Gregor55385fe2009-11-18 04:19:12 +00004588 Results.Ignore(Protocol);
4589
4590 // Add all protocols.
Douglas Gregor083128f2009-11-18 04:49:41 +00004591 AddProtocolResults(Context.getTranslationUnitDecl(), CurContext, false,
4592 Results);
4593
4594 Results.ExitScope();
Douglas Gregore6b1bb62010-08-11 21:23:17 +00004595 HandleCodeCompleteResults(this, CodeCompleter,
4596 CodeCompletionContext::CCC_ObjCProtocolName,
4597 Results.data(),Results.size());
Douglas Gregor083128f2009-11-18 04:49:41 +00004598}
4599
4600void Sema::CodeCompleteObjCProtocolDecl(Scope *) {
4601 ResultBuilder Results(*this);
4602 Results.EnterNewScope();
4603
4604 // Add all protocols.
4605 AddProtocolResults(Context.getTranslationUnitDecl(), CurContext, true,
4606 Results);
Douglas Gregor55385fe2009-11-18 04:19:12 +00004607
4608 Results.ExitScope();
Douglas Gregore6b1bb62010-08-11 21:23:17 +00004609 HandleCodeCompleteResults(this, CodeCompleter,
4610 CodeCompletionContext::CCC_ObjCProtocolName,
4611 Results.data(),Results.size());
Douglas Gregor55385fe2009-11-18 04:19:12 +00004612}
Douglas Gregor3b49aca2009-11-18 16:26:39 +00004613
4614/// \brief Add all of the Objective-C interface declarations that we find in
4615/// the given (translation unit) context.
4616static void AddInterfaceResults(DeclContext *Ctx, DeclContext *CurContext,
4617 bool OnlyForwardDeclarations,
4618 bool OnlyUnimplemented,
4619 ResultBuilder &Results) {
John McCall0a2c5e22010-08-25 06:19:51 +00004620 typedef CodeCompletionResult Result;
Douglas Gregor3b49aca2009-11-18 16:26:39 +00004621
4622 for (DeclContext::decl_iterator D = Ctx->decls_begin(),
4623 DEnd = Ctx->decls_end();
4624 D != DEnd; ++D) {
Douglas Gregordeacbdc2010-08-11 12:19:30 +00004625 // Record any interfaces we find.
4626 if (ObjCInterfaceDecl *Class = dyn_cast<ObjCInterfaceDecl>(*D))
4627 if ((!OnlyForwardDeclarations || Class->isForwardDecl()) &&
4628 (!OnlyUnimplemented || !Class->getImplementation()))
4629 Results.AddResult(Result(Class, 0), CurContext, 0, false);
Douglas Gregor3b49aca2009-11-18 16:26:39 +00004630
4631 // Record any forward-declared interfaces we find.
4632 if (ObjCClassDecl *Forward = dyn_cast<ObjCClassDecl>(*D)) {
4633 for (ObjCClassDecl::iterator C = Forward->begin(), CEnd = Forward->end();
Douglas Gregordeacbdc2010-08-11 12:19:30 +00004634 C != CEnd; ++C)
4635 if ((!OnlyForwardDeclarations || C->getInterface()->isForwardDecl()) &&
4636 (!OnlyUnimplemented || !C->getInterface()->getImplementation()))
4637 Results.AddResult(Result(C->getInterface(), 0), CurContext,
Douglas Gregor608300b2010-01-14 16:14:35 +00004638 0, false);
Douglas Gregor3b49aca2009-11-18 16:26:39 +00004639 }
4640 }
4641}
4642
4643void Sema::CodeCompleteObjCInterfaceDecl(Scope *S) {
4644 ResultBuilder Results(*this);
4645 Results.EnterNewScope();
4646
4647 // Add all classes.
4648 AddInterfaceResults(Context.getTranslationUnitDecl(), CurContext, true,
4649 false, Results);
4650
4651 Results.ExitScope();
Douglas Gregore6b1bb62010-08-11 21:23:17 +00004652 HandleCodeCompleteResults(this, CodeCompleter,
4653 CodeCompletionContext::CCC_Other,
4654 Results.data(),Results.size());
Douglas Gregor3b49aca2009-11-18 16:26:39 +00004655}
4656
Douglas Gregorc83c6872010-04-15 22:33:43 +00004657void Sema::CodeCompleteObjCSuperclass(Scope *S, IdentifierInfo *ClassName,
4658 SourceLocation ClassNameLoc) {
Douglas Gregor3b49aca2009-11-18 16:26:39 +00004659 ResultBuilder Results(*this);
4660 Results.EnterNewScope();
4661
4662 // Make sure that we ignore the class we're currently defining.
4663 NamedDecl *CurClass
Douglas Gregorc83c6872010-04-15 22:33:43 +00004664 = LookupSingleName(TUScope, ClassName, ClassNameLoc, LookupOrdinaryName);
Douglas Gregor33ced0b2009-11-18 19:08:43 +00004665 if (CurClass && isa<ObjCInterfaceDecl>(CurClass))
Douglas Gregor3b49aca2009-11-18 16:26:39 +00004666 Results.Ignore(CurClass);
4667
4668 // Add all classes.
4669 AddInterfaceResults(Context.getTranslationUnitDecl(), CurContext, false,
4670 false, Results);
4671
4672 Results.ExitScope();
Douglas Gregore6b1bb62010-08-11 21:23:17 +00004673 HandleCodeCompleteResults(this, CodeCompleter,
4674 CodeCompletionContext::CCC_Other,
4675 Results.data(),Results.size());
Douglas Gregor3b49aca2009-11-18 16:26:39 +00004676}
4677
4678void Sema::CodeCompleteObjCImplementationDecl(Scope *S) {
4679 ResultBuilder Results(*this);
4680 Results.EnterNewScope();
4681
4682 // Add all unimplemented classes.
4683 AddInterfaceResults(Context.getTranslationUnitDecl(), CurContext, false,
4684 true, Results);
4685
4686 Results.ExitScope();
Douglas Gregore6b1bb62010-08-11 21:23:17 +00004687 HandleCodeCompleteResults(this, CodeCompleter,
4688 CodeCompletionContext::CCC_Other,
4689 Results.data(),Results.size());
Douglas Gregor3b49aca2009-11-18 16:26:39 +00004690}
Douglas Gregor33ced0b2009-11-18 19:08:43 +00004691
4692void Sema::CodeCompleteObjCInterfaceCategory(Scope *S,
Douglas Gregorc83c6872010-04-15 22:33:43 +00004693 IdentifierInfo *ClassName,
4694 SourceLocation ClassNameLoc) {
John McCall0a2c5e22010-08-25 06:19:51 +00004695 typedef CodeCompletionResult Result;
Douglas Gregor33ced0b2009-11-18 19:08:43 +00004696
4697 ResultBuilder Results(*this);
4698
4699 // Ignore any categories we find that have already been implemented by this
4700 // interface.
4701 llvm::SmallPtrSet<IdentifierInfo *, 16> CategoryNames;
4702 NamedDecl *CurClass
Douglas Gregorc83c6872010-04-15 22:33:43 +00004703 = LookupSingleName(TUScope, ClassName, ClassNameLoc, LookupOrdinaryName);
Douglas Gregor33ced0b2009-11-18 19:08:43 +00004704 if (ObjCInterfaceDecl *Class = dyn_cast_or_null<ObjCInterfaceDecl>(CurClass))
4705 for (ObjCCategoryDecl *Category = Class->getCategoryList(); Category;
4706 Category = Category->getNextClassCategory())
4707 CategoryNames.insert(Category->getIdentifier());
4708
4709 // Add all of the categories we know about.
4710 Results.EnterNewScope();
4711 TranslationUnitDecl *TU = Context.getTranslationUnitDecl();
4712 for (DeclContext::decl_iterator D = TU->decls_begin(),
4713 DEnd = TU->decls_end();
4714 D != DEnd; ++D)
4715 if (ObjCCategoryDecl *Category = dyn_cast<ObjCCategoryDecl>(*D))
4716 if (CategoryNames.insert(Category->getIdentifier()))
Douglas Gregor608300b2010-01-14 16:14:35 +00004717 Results.AddResult(Result(Category, 0), CurContext, 0, false);
Douglas Gregor33ced0b2009-11-18 19:08:43 +00004718 Results.ExitScope();
4719
Douglas Gregore6b1bb62010-08-11 21:23:17 +00004720 HandleCodeCompleteResults(this, CodeCompleter,
4721 CodeCompletionContext::CCC_Other,
4722 Results.data(),Results.size());
Douglas Gregor33ced0b2009-11-18 19:08:43 +00004723}
4724
4725void Sema::CodeCompleteObjCImplementationCategory(Scope *S,
Douglas Gregorc83c6872010-04-15 22:33:43 +00004726 IdentifierInfo *ClassName,
4727 SourceLocation ClassNameLoc) {
John McCall0a2c5e22010-08-25 06:19:51 +00004728 typedef CodeCompletionResult Result;
Douglas Gregor33ced0b2009-11-18 19:08:43 +00004729
4730 // Find the corresponding interface. If we couldn't find the interface, the
4731 // program itself is ill-formed. However, we'll try to be helpful still by
4732 // providing the list of all of the categories we know about.
4733 NamedDecl *CurClass
Douglas Gregorc83c6872010-04-15 22:33:43 +00004734 = LookupSingleName(TUScope, ClassName, ClassNameLoc, LookupOrdinaryName);
Douglas Gregor33ced0b2009-11-18 19:08:43 +00004735 ObjCInterfaceDecl *Class = dyn_cast_or_null<ObjCInterfaceDecl>(CurClass);
4736 if (!Class)
Douglas Gregorc83c6872010-04-15 22:33:43 +00004737 return CodeCompleteObjCInterfaceCategory(S, ClassName, ClassNameLoc);
Douglas Gregor33ced0b2009-11-18 19:08:43 +00004738
4739 ResultBuilder Results(*this);
4740
4741 // Add all of the categories that have have corresponding interface
4742 // declarations in this class and any of its superclasses, except for
4743 // already-implemented categories in the class itself.
4744 llvm::SmallPtrSet<IdentifierInfo *, 16> CategoryNames;
4745 Results.EnterNewScope();
4746 bool IgnoreImplemented = true;
4747 while (Class) {
4748 for (ObjCCategoryDecl *Category = Class->getCategoryList(); Category;
4749 Category = Category->getNextClassCategory())
4750 if ((!IgnoreImplemented || !Category->getImplementation()) &&
4751 CategoryNames.insert(Category->getIdentifier()))
Douglas Gregor608300b2010-01-14 16:14:35 +00004752 Results.AddResult(Result(Category, 0), CurContext, 0, false);
Douglas Gregor33ced0b2009-11-18 19:08:43 +00004753
4754 Class = Class->getSuperClass();
4755 IgnoreImplemented = false;
4756 }
4757 Results.ExitScope();
4758
Douglas Gregore6b1bb62010-08-11 21:23:17 +00004759 HandleCodeCompleteResults(this, CodeCompleter,
4760 CodeCompletionContext::CCC_Other,
4761 Results.data(),Results.size());
Douglas Gregor33ced0b2009-11-18 19:08:43 +00004762}
Douglas Gregor322328b2009-11-18 22:32:06 +00004763
John McCalld226f652010-08-21 09:40:31 +00004764void Sema::CodeCompleteObjCPropertyDefinition(Scope *S, Decl *ObjCImpDecl) {
John McCall0a2c5e22010-08-25 06:19:51 +00004765 typedef CodeCompletionResult Result;
Douglas Gregor322328b2009-11-18 22:32:06 +00004766 ResultBuilder Results(*this);
4767
4768 // Figure out where this @synthesize lives.
4769 ObjCContainerDecl *Container
John McCalld226f652010-08-21 09:40:31 +00004770 = dyn_cast_or_null<ObjCContainerDecl>(ObjCImpDecl);
Douglas Gregor322328b2009-11-18 22:32:06 +00004771 if (!Container ||
4772 (!isa<ObjCImplementationDecl>(Container) &&
4773 !isa<ObjCCategoryImplDecl>(Container)))
4774 return;
4775
4776 // Ignore any properties that have already been implemented.
4777 for (DeclContext::decl_iterator D = Container->decls_begin(),
4778 DEnd = Container->decls_end();
4779 D != DEnd; ++D)
4780 if (ObjCPropertyImplDecl *PropertyImpl = dyn_cast<ObjCPropertyImplDecl>(*D))
4781 Results.Ignore(PropertyImpl->getPropertyDecl());
4782
4783 // Add any properties that we find.
4784 Results.EnterNewScope();
4785 if (ObjCImplementationDecl *ClassImpl
4786 = dyn_cast<ObjCImplementationDecl>(Container))
4787 AddObjCProperties(ClassImpl->getClassInterface(), false, CurContext,
4788 Results);
4789 else
4790 AddObjCProperties(cast<ObjCCategoryImplDecl>(Container)->getCategoryDecl(),
4791 false, CurContext, Results);
4792 Results.ExitScope();
4793
Douglas Gregore6b1bb62010-08-11 21:23:17 +00004794 HandleCodeCompleteResults(this, CodeCompleter,
4795 CodeCompletionContext::CCC_Other,
4796 Results.data(),Results.size());
Douglas Gregor322328b2009-11-18 22:32:06 +00004797}
4798
4799void Sema::CodeCompleteObjCPropertySynthesizeIvar(Scope *S,
4800 IdentifierInfo *PropertyName,
John McCalld226f652010-08-21 09:40:31 +00004801 Decl *ObjCImpDecl) {
John McCall0a2c5e22010-08-25 06:19:51 +00004802 typedef CodeCompletionResult Result;
Douglas Gregor322328b2009-11-18 22:32:06 +00004803 ResultBuilder Results(*this);
4804
4805 // Figure out where this @synthesize lives.
4806 ObjCContainerDecl *Container
John McCalld226f652010-08-21 09:40:31 +00004807 = dyn_cast_or_null<ObjCContainerDecl>(ObjCImpDecl);
Douglas Gregor322328b2009-11-18 22:32:06 +00004808 if (!Container ||
4809 (!isa<ObjCImplementationDecl>(Container) &&
4810 !isa<ObjCCategoryImplDecl>(Container)))
4811 return;
4812
4813 // Figure out which interface we're looking into.
4814 ObjCInterfaceDecl *Class = 0;
4815 if (ObjCImplementationDecl *ClassImpl
4816 = dyn_cast<ObjCImplementationDecl>(Container))
4817 Class = ClassImpl->getClassInterface();
4818 else
4819 Class = cast<ObjCCategoryImplDecl>(Container)->getCategoryDecl()
4820 ->getClassInterface();
4821
4822 // Add all of the instance variables in this class and its superclasses.
4823 Results.EnterNewScope();
4824 for(; Class; Class = Class->getSuperClass()) {
4825 // FIXME: We could screen the type of each ivar for compatibility with
4826 // the property, but is that being too paternal?
4827 for (ObjCInterfaceDecl::ivar_iterator IVar = Class->ivar_begin(),
4828 IVarEnd = Class->ivar_end();
4829 IVar != IVarEnd; ++IVar)
Douglas Gregor608300b2010-01-14 16:14:35 +00004830 Results.AddResult(Result(*IVar, 0), CurContext, 0, false);
Douglas Gregor322328b2009-11-18 22:32:06 +00004831 }
4832 Results.ExitScope();
4833
Douglas Gregore6b1bb62010-08-11 21:23:17 +00004834 HandleCodeCompleteResults(this, CodeCompleter,
4835 CodeCompletionContext::CCC_Other,
4836 Results.data(),Results.size());
Douglas Gregor322328b2009-11-18 22:32:06 +00004837}
Douglas Gregore8f5a172010-04-07 00:21:17 +00004838
Douglas Gregor408be5a2010-08-25 01:08:01 +00004839// Mapping from selectors to the methods that implement that selector, along
4840// with the "in original class" flag.
4841typedef llvm::DenseMap<Selector, std::pair<ObjCMethodDecl *, bool> >
4842 KnownMethodsMap;
Douglas Gregore8f5a172010-04-07 00:21:17 +00004843
4844/// \brief Find all of the methods that reside in the given container
4845/// (and its superclasses, protocols, etc.) that meet the given
4846/// criteria. Insert those methods into the map of known methods,
4847/// indexed by selector so they can be easily found.
4848static void FindImplementableMethods(ASTContext &Context,
4849 ObjCContainerDecl *Container,
4850 bool WantInstanceMethods,
4851 QualType ReturnType,
4852 bool IsInImplementation,
Douglas Gregor408be5a2010-08-25 01:08:01 +00004853 KnownMethodsMap &KnownMethods,
4854 bool InOriginalClass = true) {
Douglas Gregore8f5a172010-04-07 00:21:17 +00004855 if (ObjCInterfaceDecl *IFace = dyn_cast<ObjCInterfaceDecl>(Container)) {
4856 // Recurse into protocols.
4857 const ObjCList<ObjCProtocolDecl> &Protocols
4858 = IFace->getReferencedProtocols();
4859 for (ObjCList<ObjCProtocolDecl>::iterator I = Protocols.begin(),
4860 E = Protocols.end();
4861 I != E; ++I)
4862 FindImplementableMethods(Context, *I, WantInstanceMethods, ReturnType,
Douglas Gregor408be5a2010-08-25 01:08:01 +00004863 IsInImplementation, KnownMethods,
4864 InOriginalClass);
Douglas Gregore8f5a172010-04-07 00:21:17 +00004865
4866 // If we're not in the implementation of a class, also visit the
4867 // superclass.
4868 if (!IsInImplementation && IFace->getSuperClass())
4869 FindImplementableMethods(Context, IFace->getSuperClass(),
4870 WantInstanceMethods, ReturnType,
Douglas Gregor408be5a2010-08-25 01:08:01 +00004871 IsInImplementation, KnownMethods,
4872 false);
Douglas Gregore8f5a172010-04-07 00:21:17 +00004873
4874 // Add methods from any class extensions (but not from categories;
4875 // those should go into category implementations).
Fariborz Jahanian80aa1cd2010-06-22 23:20:40 +00004876 for (const ObjCCategoryDecl *Cat = IFace->getFirstClassExtension(); Cat;
4877 Cat = Cat->getNextClassExtension())
4878 FindImplementableMethods(Context, const_cast<ObjCCategoryDecl*>(Cat),
4879 WantInstanceMethods, ReturnType,
Douglas Gregor408be5a2010-08-25 01:08:01 +00004880 IsInImplementation, KnownMethods,
4881 InOriginalClass);
Douglas Gregore8f5a172010-04-07 00:21:17 +00004882 }
4883
4884 if (ObjCCategoryDecl *Category = dyn_cast<ObjCCategoryDecl>(Container)) {
4885 // Recurse into protocols.
4886 const ObjCList<ObjCProtocolDecl> &Protocols
4887 = Category->getReferencedProtocols();
4888 for (ObjCList<ObjCProtocolDecl>::iterator I = Protocols.begin(),
4889 E = Protocols.end();
4890 I != E; ++I)
4891 FindImplementableMethods(Context, *I, WantInstanceMethods, ReturnType,
Douglas Gregor408be5a2010-08-25 01:08:01 +00004892 IsInImplementation, KnownMethods,
4893 InOriginalClass);
Douglas Gregore8f5a172010-04-07 00:21:17 +00004894 }
4895
4896 if (ObjCProtocolDecl *Protocol = dyn_cast<ObjCProtocolDecl>(Container)) {
4897 // Recurse into protocols.
4898 const ObjCList<ObjCProtocolDecl> &Protocols
4899 = Protocol->getReferencedProtocols();
4900 for (ObjCList<ObjCProtocolDecl>::iterator I = Protocols.begin(),
4901 E = Protocols.end();
4902 I != E; ++I)
4903 FindImplementableMethods(Context, *I, WantInstanceMethods, ReturnType,
Douglas Gregor408be5a2010-08-25 01:08:01 +00004904 IsInImplementation, KnownMethods, false);
Douglas Gregore8f5a172010-04-07 00:21:17 +00004905 }
4906
4907 // Add methods in this container. This operation occurs last because
4908 // we want the methods from this container to override any methods
4909 // we've previously seen with the same selector.
4910 for (ObjCContainerDecl::method_iterator M = Container->meth_begin(),
4911 MEnd = Container->meth_end();
4912 M != MEnd; ++M) {
4913 if ((*M)->isInstanceMethod() == WantInstanceMethods) {
4914 if (!ReturnType.isNull() &&
4915 !Context.hasSameUnqualifiedType(ReturnType, (*M)->getResultType()))
4916 continue;
4917
Douglas Gregor408be5a2010-08-25 01:08:01 +00004918 KnownMethods[(*M)->getSelector()] = std::make_pair(*M, InOriginalClass);
Douglas Gregore8f5a172010-04-07 00:21:17 +00004919 }
4920 }
4921}
4922
4923void Sema::CodeCompleteObjCMethodDecl(Scope *S,
4924 bool IsInstanceMethod,
John McCallb3d87482010-08-24 05:47:05 +00004925 ParsedType ReturnTy,
John McCalld226f652010-08-21 09:40:31 +00004926 Decl *IDecl) {
Douglas Gregore8f5a172010-04-07 00:21:17 +00004927 // Determine the return type of the method we're declaring, if
4928 // provided.
4929 QualType ReturnType = GetTypeFromParser(ReturnTy);
4930
4931 // Determine where we should start searching for methods, and where we
4932 ObjCContainerDecl *SearchDecl = 0, *CurrentDecl = 0;
4933 bool IsInImplementation = false;
John McCalld226f652010-08-21 09:40:31 +00004934 if (Decl *D = IDecl) {
Douglas Gregore8f5a172010-04-07 00:21:17 +00004935 if (ObjCImplementationDecl *Impl = dyn_cast<ObjCImplementationDecl>(D)) {
4936 SearchDecl = Impl->getClassInterface();
4937 CurrentDecl = Impl;
4938 IsInImplementation = true;
4939 } else if (ObjCCategoryImplDecl *CatImpl
4940 = dyn_cast<ObjCCategoryImplDecl>(D)) {
4941 SearchDecl = CatImpl->getCategoryDecl();
4942 CurrentDecl = CatImpl;
4943 IsInImplementation = true;
4944 } else {
4945 SearchDecl = dyn_cast<ObjCContainerDecl>(D);
4946 CurrentDecl = SearchDecl;
4947 }
4948 }
4949
4950 if (!SearchDecl && S) {
4951 if (DeclContext *DC = static_cast<DeclContext *>(S->getEntity())) {
4952 SearchDecl = dyn_cast<ObjCContainerDecl>(DC);
4953 CurrentDecl = SearchDecl;
4954 }
4955 }
4956
4957 if (!SearchDecl || !CurrentDecl) {
Douglas Gregore6b1bb62010-08-11 21:23:17 +00004958 HandleCodeCompleteResults(this, CodeCompleter,
4959 CodeCompletionContext::CCC_Other,
4960 0, 0);
Douglas Gregore8f5a172010-04-07 00:21:17 +00004961 return;
4962 }
4963
4964 // Find all of the methods that we could declare/implement here.
4965 KnownMethodsMap KnownMethods;
4966 FindImplementableMethods(Context, SearchDecl, IsInstanceMethod,
4967 ReturnType, IsInImplementation, KnownMethods);
4968
4969 // Erase any methods that have already been declared or
4970 // implemented here.
4971 for (ObjCContainerDecl::method_iterator M = CurrentDecl->meth_begin(),
4972 MEnd = CurrentDecl->meth_end();
4973 M != MEnd; ++M) {
4974 if ((*M)->isInstanceMethod() != IsInstanceMethod)
4975 continue;
4976
4977 KnownMethodsMap::iterator Pos = KnownMethods.find((*M)->getSelector());
4978 if (Pos != KnownMethods.end())
4979 KnownMethods.erase(Pos);
4980 }
4981
4982 // Add declarations or definitions for each of the known methods.
John McCall0a2c5e22010-08-25 06:19:51 +00004983 typedef CodeCompletionResult Result;
Douglas Gregore8f5a172010-04-07 00:21:17 +00004984 ResultBuilder Results(*this);
4985 Results.EnterNewScope();
4986 PrintingPolicy Policy(Context.PrintingPolicy);
4987 Policy.AnonymousTagLocations = false;
4988 for (KnownMethodsMap::iterator M = KnownMethods.begin(),
4989 MEnd = KnownMethods.end();
4990 M != MEnd; ++M) {
Douglas Gregor408be5a2010-08-25 01:08:01 +00004991 ObjCMethodDecl *Method = M->second.first;
Douglas Gregore8f5a172010-04-07 00:21:17 +00004992 CodeCompletionString *Pattern = new CodeCompletionString;
4993
4994 // If the result type was not already provided, add it to the
4995 // pattern as (type).
4996 if (ReturnType.isNull()) {
4997 std::string TypeStr;
4998 Method->getResultType().getAsStringInternal(TypeStr, Policy);
4999 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
5000 Pattern->AddTextChunk(TypeStr);
5001 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
5002 }
5003
5004 Selector Sel = Method->getSelector();
5005
5006 // Add the first part of the selector to the pattern.
5007 Pattern->AddTypedTextChunk(Sel.getIdentifierInfoForSlot(0)->getName());
5008
5009 // Add parameters to the pattern.
5010 unsigned I = 0;
5011 for (ObjCMethodDecl::param_iterator P = Method->param_begin(),
5012 PEnd = Method->param_end();
5013 P != PEnd; (void)++P, ++I) {
5014 // Add the part of the selector name.
5015 if (I == 0)
5016 Pattern->AddChunk(CodeCompletionString::CK_Colon);
5017 else if (I < Sel.getNumArgs()) {
5018 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
Douglas Gregor47c03a72010-08-17 15:53:35 +00005019 Pattern->AddTextChunk(Sel.getIdentifierInfoForSlot(I)->getName());
Douglas Gregore8f5a172010-04-07 00:21:17 +00005020 Pattern->AddChunk(CodeCompletionString::CK_Colon);
5021 } else
5022 break;
5023
5024 // Add the parameter type.
5025 std::string TypeStr;
5026 (*P)->getOriginalType().getAsStringInternal(TypeStr, Policy);
5027 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
5028 Pattern->AddTextChunk(TypeStr);
5029 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
5030
5031 if (IdentifierInfo *Id = (*P)->getIdentifier())
Douglas Gregore17794f2010-08-31 05:13:43 +00005032 Pattern->AddTextChunk(Id->getName());
Douglas Gregore8f5a172010-04-07 00:21:17 +00005033 }
5034
5035 if (Method->isVariadic()) {
5036 if (Method->param_size() > 0)
5037 Pattern->AddChunk(CodeCompletionString::CK_Comma);
5038 Pattern->AddTextChunk("...");
Douglas Gregore17794f2010-08-31 05:13:43 +00005039 }
Douglas Gregore8f5a172010-04-07 00:21:17 +00005040
Douglas Gregor447107d2010-05-28 00:57:46 +00005041 if (IsInImplementation && Results.includeCodePatterns()) {
Douglas Gregore8f5a172010-04-07 00:21:17 +00005042 // We will be defining the method here, so add a compound statement.
5043 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
5044 Pattern->AddChunk(CodeCompletionString::CK_LeftBrace);
5045 Pattern->AddChunk(CodeCompletionString::CK_VerticalSpace);
5046 if (!Method->getResultType()->isVoidType()) {
5047 // If the result type is not void, add a return clause.
5048 Pattern->AddTextChunk("return");
5049 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
5050 Pattern->AddPlaceholderChunk("expression");
5051 Pattern->AddChunk(CodeCompletionString::CK_SemiColon);
5052 } else
5053 Pattern->AddPlaceholderChunk("statements");
5054
5055 Pattern->AddChunk(CodeCompletionString::CK_VerticalSpace);
5056 Pattern->AddChunk(CodeCompletionString::CK_RightBrace);
5057 }
5058
Douglas Gregor408be5a2010-08-25 01:08:01 +00005059 unsigned Priority = CCP_CodePattern;
5060 if (!M->second.second)
5061 Priority += CCD_InBaseClass;
5062
5063 Results.AddResult(Result(Pattern, Priority,
Douglas Gregor16ed9ad2010-08-17 16:06:07 +00005064 Method->isInstanceMethod()
5065 ? CXCursor_ObjCInstanceMethodDecl
5066 : CXCursor_ObjCClassMethodDecl));
Douglas Gregore8f5a172010-04-07 00:21:17 +00005067 }
5068
5069 Results.ExitScope();
5070
Douglas Gregore6b1bb62010-08-11 21:23:17 +00005071 HandleCodeCompleteResults(this, CodeCompleter,
5072 CodeCompletionContext::CCC_Other,
5073 Results.data(),Results.size());
Douglas Gregore8f5a172010-04-07 00:21:17 +00005074}
Douglas Gregor1f5537a2010-07-08 23:20:03 +00005075
5076void Sema::CodeCompleteObjCMethodDeclSelector(Scope *S,
5077 bool IsInstanceMethod,
Douglas Gregor40ed9a12010-07-08 23:37:41 +00005078 bool AtParameterName,
John McCallb3d87482010-08-24 05:47:05 +00005079 ParsedType ReturnTy,
Douglas Gregor1f5537a2010-07-08 23:20:03 +00005080 IdentifierInfo **SelIdents,
5081 unsigned NumSelIdents) {
Douglas Gregor1f5537a2010-07-08 23:20:03 +00005082 // If we have an external source, load the entire class method
Sebastian Redl3c7f4132010-08-18 23:57:06 +00005083 // pool from the AST file.
Douglas Gregor1f5537a2010-07-08 23:20:03 +00005084 if (ExternalSource) {
5085 for (uint32_t I = 0, N = ExternalSource->GetNumExternalSelectors();
5086 I != N; ++I) {
5087 Selector Sel = ExternalSource->GetExternalSelector(I);
Sebastian Redldb9d2142010-08-02 23:18:59 +00005088 if (Sel.isNull() || MethodPool.count(Sel))
Douglas Gregor1f5537a2010-07-08 23:20:03 +00005089 continue;
Sebastian Redldb9d2142010-08-02 23:18:59 +00005090
5091 ReadMethodPool(Sel);
Douglas Gregor1f5537a2010-07-08 23:20:03 +00005092 }
5093 }
5094
5095 // Build the set of methods we can see.
John McCall0a2c5e22010-08-25 06:19:51 +00005096 typedef CodeCompletionResult Result;
Douglas Gregor1f5537a2010-07-08 23:20:03 +00005097 ResultBuilder Results(*this);
5098
5099 if (ReturnTy)
5100 Results.setPreferredType(GetTypeFromParser(ReturnTy).getNonReferenceType());
Sebastian Redldb9d2142010-08-02 23:18:59 +00005101
Douglas Gregor1f5537a2010-07-08 23:20:03 +00005102 Results.EnterNewScope();
Sebastian Redldb9d2142010-08-02 23:18:59 +00005103 for (GlobalMethodPool::iterator M = MethodPool.begin(),
5104 MEnd = MethodPool.end();
5105 M != MEnd; ++M) {
5106 for (ObjCMethodList *MethList = IsInstanceMethod ? &M->second.first :
5107 &M->second.second;
5108 MethList && MethList->Method;
Douglas Gregor1f5537a2010-07-08 23:20:03 +00005109 MethList = MethList->Next) {
5110 if (!isAcceptableObjCMethod(MethList->Method, MK_Any, SelIdents,
5111 NumSelIdents))
5112 continue;
5113
Douglas Gregor40ed9a12010-07-08 23:37:41 +00005114 if (AtParameterName) {
5115 // Suggest parameter names we've seen before.
5116 if (NumSelIdents && NumSelIdents <= MethList->Method->param_size()) {
5117 ParmVarDecl *Param = MethList->Method->param_begin()[NumSelIdents-1];
5118 if (Param->getIdentifier()) {
5119 CodeCompletionString *Pattern = new CodeCompletionString;
5120 Pattern->AddTypedTextChunk(Param->getIdentifier()->getName());
5121 Results.AddResult(Pattern);
5122 }
5123 }
5124
5125 continue;
5126 }
5127
Douglas Gregor1f5537a2010-07-08 23:20:03 +00005128 Result R(MethList->Method, 0);
5129 R.StartParameter = NumSelIdents;
5130 R.AllParametersAreInformative = false;
5131 R.DeclaringEntity = true;
5132 Results.MaybeAddResult(R, CurContext);
5133 }
5134 }
5135
5136 Results.ExitScope();
Douglas Gregore6b1bb62010-08-11 21:23:17 +00005137 HandleCodeCompleteResults(this, CodeCompleter,
5138 CodeCompletionContext::CCC_Other,
5139 Results.data(),Results.size());
Douglas Gregor1f5537a2010-07-08 23:20:03 +00005140}
Douglas Gregor87c08a52010-08-13 22:48:40 +00005141
Douglas Gregorf29c5232010-08-24 22:20:20 +00005142void Sema::CodeCompletePreprocessorDirective(bool InConditional) {
Douglas Gregorf44e8542010-08-24 19:08:16 +00005143 ResultBuilder Results(*this);
5144 Results.EnterNewScope();
5145
5146 // #if <condition>
5147 CodeCompletionString *Pattern = new CodeCompletionString;
5148 Pattern->AddTypedTextChunk("if");
5149 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
5150 Pattern->AddPlaceholderChunk("condition");
5151 Results.AddResult(Pattern);
5152
5153 // #ifdef <macro>
5154 Pattern = new CodeCompletionString;
5155 Pattern->AddTypedTextChunk("ifdef");
5156 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
5157 Pattern->AddPlaceholderChunk("macro");
5158 Results.AddResult(Pattern);
5159
5160 // #ifndef <macro>
5161 Pattern = new CodeCompletionString;
5162 Pattern->AddTypedTextChunk("ifndef");
5163 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
5164 Pattern->AddPlaceholderChunk("macro");
5165 Results.AddResult(Pattern);
5166
5167 if (InConditional) {
5168 // #elif <condition>
5169 Pattern = new CodeCompletionString;
5170 Pattern->AddTypedTextChunk("elif");
5171 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
5172 Pattern->AddPlaceholderChunk("condition");
5173 Results.AddResult(Pattern);
5174
5175 // #else
5176 Pattern = new CodeCompletionString;
5177 Pattern->AddTypedTextChunk("else");
5178 Results.AddResult(Pattern);
5179
5180 // #endif
5181 Pattern = new CodeCompletionString;
5182 Pattern->AddTypedTextChunk("endif");
5183 Results.AddResult(Pattern);
5184 }
5185
5186 // #include "header"
5187 Pattern = new CodeCompletionString;
5188 Pattern->AddTypedTextChunk("include");
5189 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
5190 Pattern->AddTextChunk("\"");
5191 Pattern->AddPlaceholderChunk("header");
5192 Pattern->AddTextChunk("\"");
5193 Results.AddResult(Pattern);
5194
5195 // #include <header>
5196 Pattern = new CodeCompletionString;
5197 Pattern->AddTypedTextChunk("include");
5198 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
5199 Pattern->AddTextChunk("<");
5200 Pattern->AddPlaceholderChunk("header");
5201 Pattern->AddTextChunk(">");
5202 Results.AddResult(Pattern);
5203
5204 // #define <macro>
5205 Pattern = new CodeCompletionString;
5206 Pattern->AddTypedTextChunk("define");
5207 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
5208 Pattern->AddPlaceholderChunk("macro");
5209 Results.AddResult(Pattern);
5210
5211 // #define <macro>(<args>)
5212 Pattern = new CodeCompletionString;
5213 Pattern->AddTypedTextChunk("define");
5214 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
5215 Pattern->AddPlaceholderChunk("macro");
5216 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
5217 Pattern->AddPlaceholderChunk("args");
5218 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
5219 Results.AddResult(Pattern);
5220
5221 // #undef <macro>
5222 Pattern = new CodeCompletionString;
5223 Pattern->AddTypedTextChunk("undef");
5224 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
5225 Pattern->AddPlaceholderChunk("macro");
5226 Results.AddResult(Pattern);
5227
5228 // #line <number>
5229 Pattern = new CodeCompletionString;
5230 Pattern->AddTypedTextChunk("line");
5231 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
5232 Pattern->AddPlaceholderChunk("number");
5233 Results.AddResult(Pattern);
5234
5235 // #line <number> "filename"
5236 Pattern = new CodeCompletionString;
5237 Pattern->AddTypedTextChunk("line");
5238 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
5239 Pattern->AddPlaceholderChunk("number");
5240 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
5241 Pattern->AddTextChunk("\"");
5242 Pattern->AddPlaceholderChunk("filename");
5243 Pattern->AddTextChunk("\"");
5244 Results.AddResult(Pattern);
5245
5246 // #error <message>
5247 Pattern = new CodeCompletionString;
5248 Pattern->AddTypedTextChunk("error");
5249 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
5250 Pattern->AddPlaceholderChunk("message");
5251 Results.AddResult(Pattern);
5252
5253 // #pragma <arguments>
5254 Pattern = new CodeCompletionString;
5255 Pattern->AddTypedTextChunk("pragma");
5256 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
5257 Pattern->AddPlaceholderChunk("arguments");
5258 Results.AddResult(Pattern);
5259
5260 if (getLangOptions().ObjC1) {
5261 // #import "header"
5262 Pattern = new CodeCompletionString;
5263 Pattern->AddTypedTextChunk("import");
5264 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
5265 Pattern->AddTextChunk("\"");
5266 Pattern->AddPlaceholderChunk("header");
5267 Pattern->AddTextChunk("\"");
5268 Results.AddResult(Pattern);
5269
5270 // #import <header>
5271 Pattern = new CodeCompletionString;
5272 Pattern->AddTypedTextChunk("import");
5273 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
5274 Pattern->AddTextChunk("<");
5275 Pattern->AddPlaceholderChunk("header");
5276 Pattern->AddTextChunk(">");
5277 Results.AddResult(Pattern);
5278 }
5279
5280 // #include_next "header"
5281 Pattern = new CodeCompletionString;
5282 Pattern->AddTypedTextChunk("include_next");
5283 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
5284 Pattern->AddTextChunk("\"");
5285 Pattern->AddPlaceholderChunk("header");
5286 Pattern->AddTextChunk("\"");
5287 Results.AddResult(Pattern);
5288
5289 // #include_next <header>
5290 Pattern = new CodeCompletionString;
5291 Pattern->AddTypedTextChunk("include_next");
5292 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
5293 Pattern->AddTextChunk("<");
5294 Pattern->AddPlaceholderChunk("header");
5295 Pattern->AddTextChunk(">");
5296 Results.AddResult(Pattern);
5297
5298 // #warning <message>
5299 Pattern = new CodeCompletionString;
5300 Pattern->AddTypedTextChunk("warning");
5301 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
5302 Pattern->AddPlaceholderChunk("message");
5303 Results.AddResult(Pattern);
5304
5305 // Note: #ident and #sccs are such crazy anachronisms that we don't provide
5306 // completions for them. And __include_macros is a Clang-internal extension
5307 // that we don't want to encourage anyone to use.
5308
5309 // FIXME: we don't support #assert or #unassert, so don't suggest them.
5310 Results.ExitScope();
5311
Douglas Gregorf44e8542010-08-24 19:08:16 +00005312 HandleCodeCompleteResults(this, CodeCompleter,
Douglas Gregor721f3592010-08-25 18:41:16 +00005313 CodeCompletionContext::CCC_PreprocessorDirective,
Douglas Gregorf44e8542010-08-24 19:08:16 +00005314 Results.data(), Results.size());
5315}
5316
5317void Sema::CodeCompleteInPreprocessorConditionalExclusion(Scope *S) {
Douglas Gregorf29c5232010-08-24 22:20:20 +00005318 CodeCompleteOrdinaryName(S,
John McCallf312b1e2010-08-26 23:41:50 +00005319 S->getFnParent()? Sema::PCC_RecoveryInFunction
5320 : Sema::PCC_Namespace);
Douglas Gregorf44e8542010-08-24 19:08:16 +00005321}
5322
Douglas Gregorf29c5232010-08-24 22:20:20 +00005323void Sema::CodeCompletePreprocessorMacroName(bool IsDefinition) {
Douglas Gregor1fbb4472010-08-24 20:21:13 +00005324 ResultBuilder Results(*this);
5325 if (!IsDefinition && (!CodeCompleter || CodeCompleter->includeMacros())) {
5326 // Add just the names of macros, not their arguments.
5327 Results.EnterNewScope();
5328 for (Preprocessor::macro_iterator M = PP.macro_begin(),
5329 MEnd = PP.macro_end();
5330 M != MEnd; ++M) {
5331 CodeCompletionString *Pattern = new CodeCompletionString;
5332 Pattern->AddTypedTextChunk(M->first->getName());
5333 Results.AddResult(Pattern);
5334 }
5335 Results.ExitScope();
5336 } else if (IsDefinition) {
5337 // FIXME: Can we detect when the user just wrote an include guard above?
5338 }
5339
5340 HandleCodeCompleteResults(this, CodeCompleter,
5341 IsDefinition? CodeCompletionContext::CCC_MacroName
5342 : CodeCompletionContext::CCC_MacroNameUse,
5343 Results.data(), Results.size());
5344}
5345
Douglas Gregorf29c5232010-08-24 22:20:20 +00005346void Sema::CodeCompletePreprocessorExpression() {
5347 ResultBuilder Results(*this);
5348
5349 if (!CodeCompleter || CodeCompleter->includeMacros())
5350 AddMacroResults(PP, Results);
5351
5352 // defined (<macro>)
5353 Results.EnterNewScope();
5354 CodeCompletionString *Pattern = new CodeCompletionString;
5355 Pattern->AddTypedTextChunk("defined");
5356 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
5357 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
5358 Pattern->AddPlaceholderChunk("macro");
5359 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
5360 Results.AddResult(Pattern);
5361 Results.ExitScope();
5362
5363 HandleCodeCompleteResults(this, CodeCompleter,
5364 CodeCompletionContext::CCC_PreprocessorExpression,
5365 Results.data(), Results.size());
5366}
5367
5368void Sema::CodeCompletePreprocessorMacroArgument(Scope *S,
5369 IdentifierInfo *Macro,
5370 MacroInfo *MacroInfo,
5371 unsigned Argument) {
5372 // FIXME: In the future, we could provide "overload" results, much like we
5373 // do for function calls.
5374
5375 CodeCompleteOrdinaryName(S,
John McCallf312b1e2010-08-26 23:41:50 +00005376 S->getFnParent()? Sema::PCC_RecoveryInFunction
5377 : Sema::PCC_Namespace);
Douglas Gregorf29c5232010-08-24 22:20:20 +00005378}
5379
Douglas Gregor55817af2010-08-25 17:04:25 +00005380void Sema::CodeCompleteNaturalLanguage() {
Douglas Gregor55817af2010-08-25 17:04:25 +00005381 HandleCodeCompleteResults(this, CodeCompleter,
Douglas Gregoraf1c6b52010-08-25 17:10:00 +00005382 CodeCompletionContext::CCC_NaturalLanguage,
Douglas Gregor55817af2010-08-25 17:04:25 +00005383 0, 0);
5384}
5385
Douglas Gregor87c08a52010-08-13 22:48:40 +00005386void Sema::GatherGlobalCodeCompletions(
John McCall0a2c5e22010-08-25 06:19:51 +00005387 llvm::SmallVectorImpl<CodeCompletionResult> &Results) {
Douglas Gregor87c08a52010-08-13 22:48:40 +00005388 ResultBuilder Builder(*this);
5389
Douglas Gregor8071e422010-08-15 06:18:01 +00005390 if (!CodeCompleter || CodeCompleter->includeGlobals()) {
5391 CodeCompletionDeclConsumer Consumer(Builder,
5392 Context.getTranslationUnitDecl());
5393 LookupVisibleDecls(Context.getTranslationUnitDecl(), LookupAnyName,
5394 Consumer);
5395 }
Douglas Gregor87c08a52010-08-13 22:48:40 +00005396
5397 if (!CodeCompleter || CodeCompleter->includeMacros())
5398 AddMacroResults(PP, Builder);
5399
5400 Results.clear();
5401 Results.insert(Results.end(),
5402 Builder.data(), Builder.data() + Builder.size());
5403}