blob: c367d52704bbdd319f020065507fbdd0da6d1bbb [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 Gregor01dfea02010-01-10 23:08:15 +00001179 break;
1180 }
1181}
1182
Douglas Gregorbca403c2010-01-13 23:51:12 +00001183static void AddObjCExpressionResults(ResultBuilder &Results, bool NeedAt);
1184static void AddObjCStatementResults(ResultBuilder &Results, bool NeedAt);
1185static void AddObjCVisibilityResults(const LangOptions &LangOpts,
Douglas Gregorc38c3e12010-01-13 21:54:15 +00001186 ResultBuilder &Results,
1187 bool NeedAt);
Douglas Gregorbca403c2010-01-13 23:51:12 +00001188static void AddObjCImplementationResults(const LangOptions &LangOpts,
Douglas Gregorb6ac2452010-01-13 21:24:21 +00001189 ResultBuilder &Results,
1190 bool NeedAt);
Douglas Gregorbca403c2010-01-13 23:51:12 +00001191static void AddObjCInterfaceResults(const LangOptions &LangOpts,
Douglas Gregorb6ac2452010-01-13 21:24:21 +00001192 ResultBuilder &Results,
1193 bool NeedAt);
Douglas Gregorbca403c2010-01-13 23:51:12 +00001194static void AddObjCTopLevelResults(ResultBuilder &Results, bool NeedAt);
Douglas Gregorb6ac2452010-01-13 21:24:21 +00001195
Douglas Gregorc8bddde2010-05-28 00:22:41 +00001196static void AddTypedefResult(ResultBuilder &Results) {
1197 CodeCompletionString *Pattern = new CodeCompletionString;
1198 Pattern->AddTypedTextChunk("typedef");
1199 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
1200 Pattern->AddPlaceholderChunk("type");
1201 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
1202 Pattern->AddPlaceholderChunk("name");
John McCall0a2c5e22010-08-25 06:19:51 +00001203 Results.AddResult(CodeCompletionResult(Pattern));
Douglas Gregorc8bddde2010-05-28 00:22:41 +00001204}
1205
John McCallf312b1e2010-08-26 23:41:50 +00001206static bool WantTypesInContext(Sema::ParserCompletionContext CCC,
Douglas Gregor4710e5b2010-05-28 00:49:12 +00001207 const LangOptions &LangOpts) {
1208 if (LangOpts.CPlusPlus)
1209 return true;
1210
1211 switch (CCC) {
John McCallf312b1e2010-08-26 23:41:50 +00001212 case Sema::PCC_Namespace:
1213 case Sema::PCC_Class:
1214 case Sema::PCC_ObjCInstanceVariableList:
1215 case Sema::PCC_Template:
1216 case Sema::PCC_MemberTemplate:
1217 case Sema::PCC_Statement:
1218 case Sema::PCC_RecoveryInFunction:
1219 case Sema::PCC_Type:
Douglas Gregor4710e5b2010-05-28 00:49:12 +00001220 return true;
1221
John McCallf312b1e2010-08-26 23:41:50 +00001222 case Sema::PCC_ObjCInterface:
1223 case Sema::PCC_ObjCImplementation:
1224 case Sema::PCC_Expression:
1225 case Sema::PCC_Condition:
Douglas Gregor4710e5b2010-05-28 00:49:12 +00001226 return false;
1227
John McCallf312b1e2010-08-26 23:41:50 +00001228 case Sema::PCC_ForInit:
Douglas Gregor4710e5b2010-05-28 00:49:12 +00001229 return LangOpts.ObjC1 || LangOpts.C99;
1230 }
1231
1232 return false;
1233}
1234
Douglas Gregor01dfea02010-01-10 23:08:15 +00001235/// \brief Add language constructs that show up for "ordinary" names.
John McCallf312b1e2010-08-26 23:41:50 +00001236static void AddOrdinaryNameResults(Sema::ParserCompletionContext CCC,
Douglas Gregor01dfea02010-01-10 23:08:15 +00001237 Scope *S,
1238 Sema &SemaRef,
Douglas Gregor01dfea02010-01-10 23:08:15 +00001239 ResultBuilder &Results) {
John McCall0a2c5e22010-08-25 06:19:51 +00001240 typedef CodeCompletionResult Result;
Douglas Gregor01dfea02010-01-10 23:08:15 +00001241 switch (CCC) {
John McCallf312b1e2010-08-26 23:41:50 +00001242 case Sema::PCC_Namespace:
Douglas Gregorc8bddde2010-05-28 00:22:41 +00001243 if (SemaRef.getLangOptions().CPlusPlus) {
1244 CodeCompletionString *Pattern = 0;
1245
1246 if (Results.includeCodePatterns()) {
1247 // namespace <identifier> { declarations }
1248 CodeCompletionString *Pattern = new CodeCompletionString;
1249 Pattern->AddTypedTextChunk("namespace");
1250 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
1251 Pattern->AddPlaceholderChunk("identifier");
1252 Pattern->AddChunk(CodeCompletionString::CK_LeftBrace);
1253 Pattern->AddPlaceholderChunk("declarations");
1254 Pattern->AddChunk(CodeCompletionString::CK_VerticalSpace);
1255 Pattern->AddChunk(CodeCompletionString::CK_RightBrace);
1256 Results.AddResult(Result(Pattern));
1257 }
1258
Douglas Gregor01dfea02010-01-10 23:08:15 +00001259 // namespace identifier = identifier ;
1260 Pattern = new CodeCompletionString;
1261 Pattern->AddTypedTextChunk("namespace");
1262 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
Douglas Gregorc8bddde2010-05-28 00:22:41 +00001263 Pattern->AddPlaceholderChunk("name");
Douglas Gregor01dfea02010-01-10 23:08:15 +00001264 Pattern->AddChunk(CodeCompletionString::CK_Equal);
Douglas Gregorc8bddde2010-05-28 00:22:41 +00001265 Pattern->AddPlaceholderChunk("namespace");
Douglas Gregora4477812010-01-14 16:01:26 +00001266 Results.AddResult(Result(Pattern));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001267
1268 // Using directives
1269 Pattern = new CodeCompletionString;
1270 Pattern->AddTypedTextChunk("using");
1271 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
1272 Pattern->AddTextChunk("namespace");
1273 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
1274 Pattern->AddPlaceholderChunk("identifier");
Douglas Gregora4477812010-01-14 16:01:26 +00001275 Results.AddResult(Result(Pattern));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001276
1277 // asm(string-literal)
1278 Pattern = new CodeCompletionString;
1279 Pattern->AddTypedTextChunk("asm");
1280 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
1281 Pattern->AddPlaceholderChunk("string-literal");
1282 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
Douglas Gregora4477812010-01-14 16:01:26 +00001283 Results.AddResult(Result(Pattern));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001284
Douglas Gregorc8bddde2010-05-28 00:22:41 +00001285 if (Results.includeCodePatterns()) {
1286 // Explicit template instantiation
1287 Pattern = new CodeCompletionString;
1288 Pattern->AddTypedTextChunk("template");
1289 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
1290 Pattern->AddPlaceholderChunk("declaration");
1291 Results.AddResult(Result(Pattern));
1292 }
Douglas Gregor01dfea02010-01-10 23:08:15 +00001293 }
Douglas Gregorb6ac2452010-01-13 21:24:21 +00001294
1295 if (SemaRef.getLangOptions().ObjC1)
Douglas Gregorbca403c2010-01-13 23:51:12 +00001296 AddObjCTopLevelResults(Results, true);
Douglas Gregorb6ac2452010-01-13 21:24:21 +00001297
Douglas Gregorc8bddde2010-05-28 00:22:41 +00001298 AddTypedefResult(Results);
Douglas Gregor01dfea02010-01-10 23:08:15 +00001299 // Fall through
1300
John McCallf312b1e2010-08-26 23:41:50 +00001301 case Sema::PCC_Class:
Douglas Gregorc8bddde2010-05-28 00:22:41 +00001302 if (SemaRef.getLangOptions().CPlusPlus) {
Douglas Gregor01dfea02010-01-10 23:08:15 +00001303 // Using declaration
1304 CodeCompletionString *Pattern = new CodeCompletionString;
1305 Pattern->AddTypedTextChunk("using");
1306 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
Douglas Gregorc8bddde2010-05-28 00:22:41 +00001307 Pattern->AddPlaceholderChunk("qualifier");
1308 Pattern->AddTextChunk("::");
1309 Pattern->AddPlaceholderChunk("name");
Douglas Gregora4477812010-01-14 16:01:26 +00001310 Results.AddResult(Result(Pattern));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001311
Douglas Gregorc8bddde2010-05-28 00:22:41 +00001312 // using typename qualifier::name (only in a dependent context)
Douglas Gregor01dfea02010-01-10 23:08:15 +00001313 if (SemaRef.CurContext->isDependentContext()) {
1314 Pattern = new CodeCompletionString;
1315 Pattern->AddTypedTextChunk("using");
1316 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
1317 Pattern->AddTextChunk("typename");
1318 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
Douglas Gregorc8bddde2010-05-28 00:22:41 +00001319 Pattern->AddPlaceholderChunk("qualifier");
1320 Pattern->AddTextChunk("::");
1321 Pattern->AddPlaceholderChunk("name");
Douglas Gregora4477812010-01-14 16:01:26 +00001322 Results.AddResult(Result(Pattern));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001323 }
1324
John McCallf312b1e2010-08-26 23:41:50 +00001325 if (CCC == Sema::PCC_Class) {
Douglas Gregorc8bddde2010-05-28 00:22:41 +00001326 AddTypedefResult(Results);
1327
Douglas Gregor01dfea02010-01-10 23:08:15 +00001328 // public:
1329 Pattern = new CodeCompletionString;
1330 Pattern->AddTypedTextChunk("public");
1331 Pattern->AddChunk(CodeCompletionString::CK_Colon);
Douglas Gregora4477812010-01-14 16:01:26 +00001332 Results.AddResult(Result(Pattern));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001333
1334 // protected:
1335 Pattern = new CodeCompletionString;
1336 Pattern->AddTypedTextChunk("protected");
1337 Pattern->AddChunk(CodeCompletionString::CK_Colon);
Douglas Gregora4477812010-01-14 16:01:26 +00001338 Results.AddResult(Result(Pattern));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001339
1340 // private:
1341 Pattern = new CodeCompletionString;
1342 Pattern->AddTypedTextChunk("private");
1343 Pattern->AddChunk(CodeCompletionString::CK_Colon);
Douglas Gregora4477812010-01-14 16:01:26 +00001344 Results.AddResult(Result(Pattern));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001345 }
1346 }
1347 // Fall through
1348
John McCallf312b1e2010-08-26 23:41:50 +00001349 case Sema::PCC_Template:
1350 case Sema::PCC_MemberTemplate:
Douglas Gregord8e8a582010-05-25 21:41:55 +00001351 if (SemaRef.getLangOptions().CPlusPlus && Results.includeCodePatterns()) {
Douglas Gregor01dfea02010-01-10 23:08:15 +00001352 // template < parameters >
1353 CodeCompletionString *Pattern = new CodeCompletionString;
1354 Pattern->AddTypedTextChunk("template");
1355 Pattern->AddChunk(CodeCompletionString::CK_LeftAngle);
1356 Pattern->AddPlaceholderChunk("parameters");
1357 Pattern->AddChunk(CodeCompletionString::CK_RightAngle);
Douglas Gregora4477812010-01-14 16:01:26 +00001358 Results.AddResult(Result(Pattern));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001359 }
1360
Douglas Gregorbca403c2010-01-13 23:51:12 +00001361 AddStorageSpecifiers(CCC, SemaRef.getLangOptions(), Results);
1362 AddFunctionSpecifiers(CCC, SemaRef.getLangOptions(), Results);
Douglas Gregor01dfea02010-01-10 23:08:15 +00001363 break;
1364
John McCallf312b1e2010-08-26 23:41:50 +00001365 case Sema::PCC_ObjCInterface:
Douglas Gregorbca403c2010-01-13 23:51:12 +00001366 AddObjCInterfaceResults(SemaRef.getLangOptions(), Results, true);
1367 AddStorageSpecifiers(CCC, SemaRef.getLangOptions(), Results);
1368 AddFunctionSpecifiers(CCC, SemaRef.getLangOptions(), Results);
Douglas Gregorb6ac2452010-01-13 21:24:21 +00001369 break;
1370
John McCallf312b1e2010-08-26 23:41:50 +00001371 case Sema::PCC_ObjCImplementation:
Douglas Gregorbca403c2010-01-13 23:51:12 +00001372 AddObjCImplementationResults(SemaRef.getLangOptions(), Results, true);
1373 AddStorageSpecifiers(CCC, SemaRef.getLangOptions(), Results);
1374 AddFunctionSpecifiers(CCC, SemaRef.getLangOptions(), Results);
Douglas Gregorb6ac2452010-01-13 21:24:21 +00001375 break;
1376
John McCallf312b1e2010-08-26 23:41:50 +00001377 case Sema::PCC_ObjCInstanceVariableList:
Douglas Gregorbca403c2010-01-13 23:51:12 +00001378 AddObjCVisibilityResults(SemaRef.getLangOptions(), Results, true);
Douglas Gregorc38c3e12010-01-13 21:54:15 +00001379 break;
1380
John McCallf312b1e2010-08-26 23:41:50 +00001381 case Sema::PCC_RecoveryInFunction:
1382 case Sema::PCC_Statement: {
Douglas Gregorc8bddde2010-05-28 00:22:41 +00001383 AddTypedefResult(Results);
Douglas Gregor01dfea02010-01-10 23:08:15 +00001384
1385 CodeCompletionString *Pattern = 0;
Douglas Gregord8e8a582010-05-25 21:41:55 +00001386 if (SemaRef.getLangOptions().CPlusPlus && Results.includeCodePatterns()) {
Douglas Gregor01dfea02010-01-10 23:08:15 +00001387 Pattern = new CodeCompletionString;
1388 Pattern->AddTypedTextChunk("try");
1389 Pattern->AddChunk(CodeCompletionString::CK_LeftBrace);
1390 Pattern->AddPlaceholderChunk("statements");
1391 Pattern->AddChunk(CodeCompletionString::CK_VerticalSpace);
1392 Pattern->AddChunk(CodeCompletionString::CK_RightBrace);
1393 Pattern->AddTextChunk("catch");
1394 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
1395 Pattern->AddPlaceholderChunk("declaration");
1396 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
1397 Pattern->AddChunk(CodeCompletionString::CK_LeftBrace);
1398 Pattern->AddPlaceholderChunk("statements");
1399 Pattern->AddChunk(CodeCompletionString::CK_VerticalSpace);
1400 Pattern->AddChunk(CodeCompletionString::CK_RightBrace);
Douglas Gregora4477812010-01-14 16:01:26 +00001401 Results.AddResult(Result(Pattern));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001402 }
Douglas Gregorb6ac2452010-01-13 21:24:21 +00001403 if (SemaRef.getLangOptions().ObjC1)
Douglas Gregorbca403c2010-01-13 23:51:12 +00001404 AddObjCStatementResults(Results, true);
Douglas Gregorb6ac2452010-01-13 21:24:21 +00001405
Douglas Gregord8e8a582010-05-25 21:41:55 +00001406 if (Results.includeCodePatterns()) {
1407 // if (condition) { statements }
1408 Pattern = new CodeCompletionString;
1409 Pattern->AddTypedTextChunk("if");
1410 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
1411 if (SemaRef.getLangOptions().CPlusPlus)
1412 Pattern->AddPlaceholderChunk("condition");
1413 else
1414 Pattern->AddPlaceholderChunk("expression");
1415 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
1416 Pattern->AddChunk(CodeCompletionString::CK_LeftBrace);
1417 Pattern->AddPlaceholderChunk("statements");
1418 Pattern->AddChunk(CodeCompletionString::CK_VerticalSpace);
1419 Pattern->AddChunk(CodeCompletionString::CK_RightBrace);
1420 Results.AddResult(Result(Pattern));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001421
Douglas Gregord8e8a582010-05-25 21:41:55 +00001422 // switch (condition) { }
1423 Pattern = new CodeCompletionString;
1424 Pattern->AddTypedTextChunk("switch");
1425 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
1426 if (SemaRef.getLangOptions().CPlusPlus)
1427 Pattern->AddPlaceholderChunk("condition");
1428 else
1429 Pattern->AddPlaceholderChunk("expression");
1430 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
1431 Pattern->AddChunk(CodeCompletionString::CK_LeftBrace);
1432 Pattern->AddChunk(CodeCompletionString::CK_VerticalSpace);
1433 Pattern->AddChunk(CodeCompletionString::CK_RightBrace);
1434 Results.AddResult(Result(Pattern));
1435 }
1436
Douglas Gregor01dfea02010-01-10 23:08:15 +00001437 // Switch-specific statements.
John McCall781472f2010-08-25 08:40:02 +00001438 if (!SemaRef.getCurFunction()->SwitchStack.empty()) {
Douglas Gregor01dfea02010-01-10 23:08:15 +00001439 // case expression:
1440 Pattern = new CodeCompletionString;
1441 Pattern->AddTypedTextChunk("case");
Douglas Gregorc8bddde2010-05-28 00:22:41 +00001442 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
Douglas Gregor01dfea02010-01-10 23:08:15 +00001443 Pattern->AddPlaceholderChunk("expression");
1444 Pattern->AddChunk(CodeCompletionString::CK_Colon);
Douglas Gregora4477812010-01-14 16:01:26 +00001445 Results.AddResult(Result(Pattern));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001446
1447 // default:
1448 Pattern = new CodeCompletionString;
1449 Pattern->AddTypedTextChunk("default");
1450 Pattern->AddChunk(CodeCompletionString::CK_Colon);
Douglas Gregora4477812010-01-14 16:01:26 +00001451 Results.AddResult(Result(Pattern));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001452 }
1453
Douglas Gregord8e8a582010-05-25 21:41:55 +00001454 if (Results.includeCodePatterns()) {
1455 /// while (condition) { statements }
1456 Pattern = new CodeCompletionString;
1457 Pattern->AddTypedTextChunk("while");
1458 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
1459 if (SemaRef.getLangOptions().CPlusPlus)
1460 Pattern->AddPlaceholderChunk("condition");
1461 else
1462 Pattern->AddPlaceholderChunk("expression");
1463 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
1464 Pattern->AddChunk(CodeCompletionString::CK_LeftBrace);
1465 Pattern->AddPlaceholderChunk("statements");
1466 Pattern->AddChunk(CodeCompletionString::CK_VerticalSpace);
1467 Pattern->AddChunk(CodeCompletionString::CK_RightBrace);
1468 Results.AddResult(Result(Pattern));
1469
1470 // do { statements } while ( expression );
1471 Pattern = new CodeCompletionString;
1472 Pattern->AddTypedTextChunk("do");
1473 Pattern->AddChunk(CodeCompletionString::CK_LeftBrace);
1474 Pattern->AddPlaceholderChunk("statements");
1475 Pattern->AddChunk(CodeCompletionString::CK_VerticalSpace);
1476 Pattern->AddChunk(CodeCompletionString::CK_RightBrace);
1477 Pattern->AddTextChunk("while");
1478 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
Douglas Gregor01dfea02010-01-10 23:08:15 +00001479 Pattern->AddPlaceholderChunk("expression");
Douglas Gregord8e8a582010-05-25 21:41:55 +00001480 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
1481 Results.AddResult(Result(Pattern));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001482
Douglas Gregord8e8a582010-05-25 21:41:55 +00001483 // for ( for-init-statement ; condition ; expression ) { statements }
1484 Pattern = new CodeCompletionString;
1485 Pattern->AddTypedTextChunk("for");
1486 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
1487 if (SemaRef.getLangOptions().CPlusPlus || SemaRef.getLangOptions().C99)
1488 Pattern->AddPlaceholderChunk("init-statement");
1489 else
1490 Pattern->AddPlaceholderChunk("init-expression");
1491 Pattern->AddChunk(CodeCompletionString::CK_SemiColon);
1492 Pattern->AddPlaceholderChunk("condition");
1493 Pattern->AddChunk(CodeCompletionString::CK_SemiColon);
1494 Pattern->AddPlaceholderChunk("inc-expression");
1495 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
1496 Pattern->AddChunk(CodeCompletionString::CK_LeftBrace);
1497 Pattern->AddPlaceholderChunk("statements");
1498 Pattern->AddChunk(CodeCompletionString::CK_VerticalSpace);
1499 Pattern->AddChunk(CodeCompletionString::CK_RightBrace);
1500 Results.AddResult(Result(Pattern));
1501 }
Douglas Gregor01dfea02010-01-10 23:08:15 +00001502
1503 if (S->getContinueParent()) {
1504 // continue ;
1505 Pattern = new CodeCompletionString;
1506 Pattern->AddTypedTextChunk("continue");
Douglas Gregora4477812010-01-14 16:01:26 +00001507 Results.AddResult(Result(Pattern));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001508 }
1509
1510 if (S->getBreakParent()) {
1511 // break ;
1512 Pattern = new CodeCompletionString;
1513 Pattern->AddTypedTextChunk("break");
Douglas Gregora4477812010-01-14 16:01:26 +00001514 Results.AddResult(Result(Pattern));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001515 }
1516
1517 // "return expression ;" or "return ;", depending on whether we
1518 // know the function is void or not.
1519 bool isVoid = false;
1520 if (FunctionDecl *Function = dyn_cast<FunctionDecl>(SemaRef.CurContext))
1521 isVoid = Function->getResultType()->isVoidType();
1522 else if (ObjCMethodDecl *Method
1523 = dyn_cast<ObjCMethodDecl>(SemaRef.CurContext))
1524 isVoid = Method->getResultType()->isVoidType();
Douglas Gregor9ea9bdb2010-03-01 23:15:13 +00001525 else if (SemaRef.getCurBlock() &&
1526 !SemaRef.getCurBlock()->ReturnType.isNull())
1527 isVoid = SemaRef.getCurBlock()->ReturnType->isVoidType();
Douglas Gregor01dfea02010-01-10 23:08:15 +00001528 Pattern = new CodeCompletionString;
1529 Pattern->AddTypedTextChunk("return");
Douglas Gregor93298002010-02-18 04:06:48 +00001530 if (!isVoid) {
1531 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
Douglas Gregor01dfea02010-01-10 23:08:15 +00001532 Pattern->AddPlaceholderChunk("expression");
Douglas Gregor93298002010-02-18 04:06:48 +00001533 }
Douglas Gregora4477812010-01-14 16:01:26 +00001534 Results.AddResult(Result(Pattern));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001535
Douglas Gregorc8bddde2010-05-28 00:22:41 +00001536 // goto identifier ;
1537 Pattern = new CodeCompletionString;
1538 Pattern->AddTypedTextChunk("goto");
1539 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
1540 Pattern->AddPlaceholderChunk("label");
1541 Results.AddResult(Result(Pattern));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001542
Douglas Gregorc8bddde2010-05-28 00:22:41 +00001543 // Using directives
1544 Pattern = new CodeCompletionString;
1545 Pattern->AddTypedTextChunk("using");
1546 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
1547 Pattern->AddTextChunk("namespace");
1548 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
1549 Pattern->AddPlaceholderChunk("identifier");
1550 Results.AddResult(Result(Pattern));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001551 }
1552
1553 // Fall through (for statement expressions).
John McCallf312b1e2010-08-26 23:41:50 +00001554 case Sema::PCC_ForInit:
1555 case Sema::PCC_Condition:
Douglas Gregorbca403c2010-01-13 23:51:12 +00001556 AddStorageSpecifiers(CCC, SemaRef.getLangOptions(), Results);
Douglas Gregor01dfea02010-01-10 23:08:15 +00001557 // Fall through: conditions and statements can have expressions.
1558
John McCallf312b1e2010-08-26 23:41:50 +00001559 case Sema::PCC_Expression: {
Douglas Gregor01dfea02010-01-10 23:08:15 +00001560 CodeCompletionString *Pattern = 0;
1561 if (SemaRef.getLangOptions().CPlusPlus) {
1562 // 'this', if we're in a non-static member function.
1563 if (CXXMethodDecl *Method = dyn_cast<CXXMethodDecl>(SemaRef.CurContext))
1564 if (!Method->isStatic())
Douglas Gregora4477812010-01-14 16:01:26 +00001565 Results.AddResult(Result("this"));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001566
1567 // true, false
Douglas Gregora4477812010-01-14 16:01:26 +00001568 Results.AddResult(Result("true"));
1569 Results.AddResult(Result("false"));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001570
Douglas Gregorc8bddde2010-05-28 00:22:41 +00001571 // dynamic_cast < type-id > ( expression )
1572 Pattern = new CodeCompletionString;
1573 Pattern->AddTypedTextChunk("dynamic_cast");
1574 Pattern->AddChunk(CodeCompletionString::CK_LeftAngle);
1575 Pattern->AddPlaceholderChunk("type");
1576 Pattern->AddChunk(CodeCompletionString::CK_RightAngle);
1577 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
1578 Pattern->AddPlaceholderChunk("expression");
1579 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
1580 Results.AddResult(Result(Pattern));
1581
1582 // static_cast < type-id > ( expression )
1583 Pattern = new CodeCompletionString;
1584 Pattern->AddTypedTextChunk("static_cast");
1585 Pattern->AddChunk(CodeCompletionString::CK_LeftAngle);
1586 Pattern->AddPlaceholderChunk("type");
1587 Pattern->AddChunk(CodeCompletionString::CK_RightAngle);
1588 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
1589 Pattern->AddPlaceholderChunk("expression");
1590 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
1591 Results.AddResult(Result(Pattern));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001592
Douglas Gregorc8bddde2010-05-28 00:22:41 +00001593 // reinterpret_cast < type-id > ( expression )
1594 Pattern = new CodeCompletionString;
1595 Pattern->AddTypedTextChunk("reinterpret_cast");
1596 Pattern->AddChunk(CodeCompletionString::CK_LeftAngle);
1597 Pattern->AddPlaceholderChunk("type");
1598 Pattern->AddChunk(CodeCompletionString::CK_RightAngle);
1599 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
1600 Pattern->AddPlaceholderChunk("expression");
1601 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
1602 Results.AddResult(Result(Pattern));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001603
Douglas Gregorc8bddde2010-05-28 00:22:41 +00001604 // const_cast < type-id > ( expression )
1605 Pattern = new CodeCompletionString;
1606 Pattern->AddTypedTextChunk("const_cast");
1607 Pattern->AddChunk(CodeCompletionString::CK_LeftAngle);
1608 Pattern->AddPlaceholderChunk("type");
1609 Pattern->AddChunk(CodeCompletionString::CK_RightAngle);
1610 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
1611 Pattern->AddPlaceholderChunk("expression");
1612 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
1613 Results.AddResult(Result(Pattern));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001614
Douglas Gregorc8bddde2010-05-28 00:22:41 +00001615 // typeid ( expression-or-type )
1616 Pattern = new CodeCompletionString;
1617 Pattern->AddTypedTextChunk("typeid");
1618 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
1619 Pattern->AddPlaceholderChunk("expression-or-type");
1620 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
1621 Results.AddResult(Result(Pattern));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001622
Douglas Gregorc8bddde2010-05-28 00:22:41 +00001623 // new T ( ... )
1624 Pattern = new CodeCompletionString;
1625 Pattern->AddTypedTextChunk("new");
1626 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
1627 Pattern->AddPlaceholderChunk("type");
1628 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
1629 Pattern->AddPlaceholderChunk("expressions");
1630 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
1631 Results.AddResult(Result(Pattern));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001632
Douglas Gregorc8bddde2010-05-28 00:22:41 +00001633 // new T [ ] ( ... )
1634 Pattern = new CodeCompletionString;
1635 Pattern->AddTypedTextChunk("new");
1636 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
1637 Pattern->AddPlaceholderChunk("type");
1638 Pattern->AddChunk(CodeCompletionString::CK_LeftBracket);
1639 Pattern->AddPlaceholderChunk("size");
1640 Pattern->AddChunk(CodeCompletionString::CK_RightBracket);
1641 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
1642 Pattern->AddPlaceholderChunk("expressions");
1643 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
1644 Results.AddResult(Result(Pattern));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001645
Douglas Gregorc8bddde2010-05-28 00:22:41 +00001646 // delete expression
1647 Pattern = new CodeCompletionString;
1648 Pattern->AddTypedTextChunk("delete");
1649 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
1650 Pattern->AddPlaceholderChunk("expression");
1651 Results.AddResult(Result(Pattern));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001652
Douglas Gregorc8bddde2010-05-28 00:22:41 +00001653 // delete [] expression
1654 Pattern = new CodeCompletionString;
1655 Pattern->AddTypedTextChunk("delete");
1656 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
1657 Pattern->AddChunk(CodeCompletionString::CK_LeftBracket);
1658 Pattern->AddChunk(CodeCompletionString::CK_RightBracket);
1659 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
1660 Pattern->AddPlaceholderChunk("expression");
1661 Results.AddResult(Result(Pattern));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001662
Douglas Gregorc8bddde2010-05-28 00:22:41 +00001663 // throw expression
1664 Pattern = new CodeCompletionString;
1665 Pattern->AddTypedTextChunk("throw");
1666 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
1667 Pattern->AddPlaceholderChunk("expression");
1668 Results.AddResult(Result(Pattern));
Douglas Gregor12e13132010-05-26 22:00:08 +00001669
1670 // FIXME: Rethrow?
Douglas Gregor01dfea02010-01-10 23:08:15 +00001671 }
1672
1673 if (SemaRef.getLangOptions().ObjC1) {
1674 // Add "super", if we're in an Objective-C class with a superclass.
Ted Kremenek681e2562010-05-31 21:43:10 +00001675 if (ObjCMethodDecl *Method = SemaRef.getCurMethodDecl()) {
1676 // The interface can be NULL.
1677 if (ObjCInterfaceDecl *ID = Method->getClassInterface())
1678 if (ID->getSuperClass())
1679 Results.AddResult(Result("super"));
1680 }
1681
Douglas Gregorbca403c2010-01-13 23:51:12 +00001682 AddObjCExpressionResults(Results, true);
Douglas Gregor01dfea02010-01-10 23:08:15 +00001683 }
1684
Douglas Gregorc8bddde2010-05-28 00:22:41 +00001685 // sizeof expression
1686 Pattern = new CodeCompletionString;
1687 Pattern->AddTypedTextChunk("sizeof");
1688 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
1689 Pattern->AddPlaceholderChunk("expression-or-type");
1690 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
1691 Results.AddResult(Result(Pattern));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001692 break;
1693 }
Douglas Gregord32b0222010-08-24 01:06:58 +00001694
John McCallf312b1e2010-08-26 23:41:50 +00001695 case Sema::PCC_Type:
Douglas Gregord32b0222010-08-24 01:06:58 +00001696 break;
Douglas Gregor01dfea02010-01-10 23:08:15 +00001697 }
1698
Douglas Gregor4710e5b2010-05-28 00:49:12 +00001699 if (WantTypesInContext(CCC, SemaRef.getLangOptions()))
1700 AddTypeSpecifierResults(SemaRef.getLangOptions(), Results);
Douglas Gregor01dfea02010-01-10 23:08:15 +00001701
John McCallf312b1e2010-08-26 23:41:50 +00001702 if (SemaRef.getLangOptions().CPlusPlus && CCC != Sema::PCC_Type)
Douglas Gregora4477812010-01-14 16:01:26 +00001703 Results.AddResult(Result("operator"));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001704}
1705
Douglas Gregorff5ce6e2009-12-18 18:53:37 +00001706/// \brief If the given declaration has an associated type, add it as a result
1707/// type chunk.
1708static void AddResultTypeChunk(ASTContext &Context,
1709 NamedDecl *ND,
1710 CodeCompletionString *Result) {
1711 if (!ND)
1712 return;
1713
1714 // Determine the type of the declaration (if it has a type).
1715 QualType T;
1716 if (FunctionDecl *Function = dyn_cast<FunctionDecl>(ND))
1717 T = Function->getResultType();
1718 else if (ObjCMethodDecl *Method = dyn_cast<ObjCMethodDecl>(ND))
1719 T = Method->getResultType();
1720 else if (FunctionTemplateDecl *FunTmpl = dyn_cast<FunctionTemplateDecl>(ND))
1721 T = FunTmpl->getTemplatedDecl()->getResultType();
1722 else if (EnumConstantDecl *Enumerator = dyn_cast<EnumConstantDecl>(ND))
1723 T = Context.getTypeDeclType(cast<TypeDecl>(Enumerator->getDeclContext()));
1724 else if (isa<UnresolvedUsingValueDecl>(ND)) {
1725 /* Do nothing: ignore unresolved using declarations*/
1726 } else if (ValueDecl *Value = dyn_cast<ValueDecl>(ND))
1727 T = Value->getType();
1728 else if (ObjCPropertyDecl *Property = dyn_cast<ObjCPropertyDecl>(ND))
1729 T = Property->getType();
1730
1731 if (T.isNull() || Context.hasSameType(T, Context.DependentTy))
1732 return;
1733
Douglas Gregor84139d62010-04-05 21:25:31 +00001734 PrintingPolicy Policy(Context.PrintingPolicy);
1735 Policy.AnonymousTagLocations = false;
1736
Douglas Gregorff5ce6e2009-12-18 18:53:37 +00001737 std::string TypeStr;
Douglas Gregor84139d62010-04-05 21:25:31 +00001738 T.getAsStringInternal(TypeStr, Policy);
Douglas Gregorff5ce6e2009-12-18 18:53:37 +00001739 Result->AddResultTypeChunk(TypeStr);
1740}
1741
Douglas Gregoraaa107a2010-08-23 23:51:41 +00001742static void MaybeAddSentinel(ASTContext &Context, NamedDecl *FunctionOrMethod,
1743 CodeCompletionString *Result) {
1744 if (SentinelAttr *Sentinel = FunctionOrMethod->getAttr<SentinelAttr>())
1745 if (Sentinel->getSentinel() == 0) {
1746 if (Context.getLangOptions().ObjC1 &&
1747 Context.Idents.get("nil").hasMacroDefinition())
1748 Result->AddTextChunk(", nil");
1749 else if (Context.Idents.get("NULL").hasMacroDefinition())
1750 Result->AddTextChunk(", NULL");
1751 else
1752 Result->AddTextChunk(", (void*)0");
1753 }
1754}
1755
Douglas Gregor83482d12010-08-24 16:15:59 +00001756static std::string FormatFunctionParameter(ASTContext &Context,
Douglas Gregoraba48082010-08-29 19:47:46 +00001757 ParmVarDecl *Param,
1758 bool SuppressName = false) {
Douglas Gregor83482d12010-08-24 16:15:59 +00001759 bool ObjCMethodParam = isa<ObjCMethodDecl>(Param->getDeclContext());
1760 if (Param->getType()->isDependentType() ||
1761 !Param->getType()->isBlockPointerType()) {
1762 // The argument for a dependent or non-block parameter is a placeholder
1763 // containing that parameter's type.
1764 std::string Result;
1765
Douglas Gregoraba48082010-08-29 19:47:46 +00001766 if (Param->getIdentifier() && !ObjCMethodParam && !SuppressName)
Douglas Gregor83482d12010-08-24 16:15:59 +00001767 Result = Param->getIdentifier()->getName();
1768
1769 Param->getType().getAsStringInternal(Result,
1770 Context.PrintingPolicy);
1771
1772 if (ObjCMethodParam) {
1773 Result = "(" + Result;
1774 Result += ")";
Douglas Gregoraba48082010-08-29 19:47:46 +00001775 if (Param->getIdentifier() && !SuppressName)
Douglas Gregor83482d12010-08-24 16:15:59 +00001776 Result += Param->getIdentifier()->getName();
1777 }
1778 return Result;
1779 }
1780
1781 // The argument for a block pointer parameter is a block literal with
1782 // the appropriate type.
1783 FunctionProtoTypeLoc *Block = 0;
1784 TypeLoc TL;
1785 if (TypeSourceInfo *TSInfo = Param->getTypeSourceInfo()) {
1786 TL = TSInfo->getTypeLoc().getUnqualifiedLoc();
1787 while (true) {
1788 // Look through typedefs.
1789 if (TypedefTypeLoc *TypedefTL = dyn_cast<TypedefTypeLoc>(&TL)) {
1790 if (TypeSourceInfo *InnerTSInfo
1791 = TypedefTL->getTypedefDecl()->getTypeSourceInfo()) {
1792 TL = InnerTSInfo->getTypeLoc().getUnqualifiedLoc();
1793 continue;
1794 }
1795 }
1796
1797 // Look through qualified types
1798 if (QualifiedTypeLoc *QualifiedTL = dyn_cast<QualifiedTypeLoc>(&TL)) {
1799 TL = QualifiedTL->getUnqualifiedLoc();
1800 continue;
1801 }
1802
1803 // Try to get the function prototype behind the block pointer type,
1804 // then we're done.
1805 if (BlockPointerTypeLoc *BlockPtr
1806 = dyn_cast<BlockPointerTypeLoc>(&TL)) {
1807 TL = BlockPtr->getPointeeLoc();
1808 Block = dyn_cast<FunctionProtoTypeLoc>(&TL);
1809 }
1810 break;
1811 }
1812 }
1813
1814 if (!Block) {
1815 // We were unable to find a FunctionProtoTypeLoc with parameter names
1816 // for the block; just use the parameter type as a placeholder.
1817 std::string Result;
1818 Param->getType().getUnqualifiedType().
1819 getAsStringInternal(Result, Context.PrintingPolicy);
1820
1821 if (ObjCMethodParam) {
1822 Result = "(" + Result;
1823 Result += ")";
1824 if (Param->getIdentifier())
1825 Result += Param->getIdentifier()->getName();
1826 }
1827
1828 return Result;
1829 }
1830
1831 // We have the function prototype behind the block pointer type, as it was
1832 // written in the source.
1833 std::string Result = "(^)(";
1834 for (unsigned I = 0, N = Block->getNumArgs(); I != N; ++I) {
1835 if (I)
1836 Result += ", ";
1837 Result += FormatFunctionParameter(Context, Block->getArg(I));
Douglas Gregore17794f2010-08-31 05:13:43 +00001838
1839 if (I == N - 1 && Block->getTypePtr()->isVariadic())
Douglas Gregor83482d12010-08-24 16:15:59 +00001840 Result += ", ...";
Douglas Gregore17794f2010-08-31 05:13:43 +00001841 }
1842 if (Block->getTypePtr()->isVariadic() && Block->getNumArgs() == 0)
1843 Result += "...";
1844 else if (Block->getNumArgs() == 0 && !Context.getLangOptions().CPlusPlus)
Douglas Gregor83482d12010-08-24 16:15:59 +00001845 Result += "void";
1846
1847 Result += ")";
1848 Block->getTypePtr()->getResultType().getAsStringInternal(Result,
1849 Context.PrintingPolicy);
1850 return Result;
1851}
1852
Douglas Gregor86d9a522009-09-21 16:56:56 +00001853/// \brief Add function parameter chunks to the given code completion string.
1854static void AddFunctionParameterChunks(ASTContext &Context,
1855 FunctionDecl *Function,
1856 CodeCompletionString *Result) {
Douglas Gregor0c8296d2009-11-07 00:00:49 +00001857 typedef CodeCompletionString::Chunk Chunk;
1858
Douglas Gregor86d9a522009-09-21 16:56:56 +00001859 CodeCompletionString *CCStr = Result;
1860
1861 for (unsigned P = 0, N = Function->getNumParams(); P != N; ++P) {
1862 ParmVarDecl *Param = Function->getParamDecl(P);
1863
1864 if (Param->hasDefaultArg()) {
1865 // When we see an optional default argument, put that argument and
1866 // the remaining default arguments into a new, optional string.
1867 CodeCompletionString *Opt = new CodeCompletionString;
1868 CCStr->AddOptionalChunk(std::auto_ptr<CodeCompletionString>(Opt));
1869 CCStr = Opt;
1870 }
1871
1872 if (P != 0)
Douglas Gregor0c8296d2009-11-07 00:00:49 +00001873 CCStr->AddChunk(Chunk(CodeCompletionString::CK_Comma));
Douglas Gregor86d9a522009-09-21 16:56:56 +00001874
1875 // Format the placeholder string.
Douglas Gregor83482d12010-08-24 16:15:59 +00001876 std::string PlaceholderStr = FormatFunctionParameter(Context, Param);
1877
Douglas Gregore17794f2010-08-31 05:13:43 +00001878 if (Function->isVariadic() && P == N - 1)
1879 PlaceholderStr += ", ...";
1880
Douglas Gregor86d9a522009-09-21 16:56:56 +00001881 // Add the placeholder string.
Benjamin Kramer660cc182009-11-29 20:18:50 +00001882 CCStr->AddPlaceholderChunk(PlaceholderStr);
Douglas Gregor86d9a522009-09-21 16:56:56 +00001883 }
Douglas Gregorb3d45252009-09-22 21:42:17 +00001884
1885 if (const FunctionProtoType *Proto
1886 = Function->getType()->getAs<FunctionProtoType>())
Douglas Gregoraaa107a2010-08-23 23:51:41 +00001887 if (Proto->isVariadic()) {
Douglas Gregore17794f2010-08-31 05:13:43 +00001888 if (Proto->getNumArgs() == 0)
1889 CCStr->AddPlaceholderChunk("...");
Douglas Gregoraaa107a2010-08-23 23:51:41 +00001890
1891 MaybeAddSentinel(Context, Function, CCStr);
1892 }
Douglas Gregor86d9a522009-09-21 16:56:56 +00001893}
1894
1895/// \brief Add template parameter chunks to the given code completion string.
1896static void AddTemplateParameterChunks(ASTContext &Context,
1897 TemplateDecl *Template,
1898 CodeCompletionString *Result,
1899 unsigned MaxParameters = 0) {
Douglas Gregor0c8296d2009-11-07 00:00:49 +00001900 typedef CodeCompletionString::Chunk Chunk;
1901
Douglas Gregor86d9a522009-09-21 16:56:56 +00001902 CodeCompletionString *CCStr = Result;
1903 bool FirstParameter = true;
1904
1905 TemplateParameterList *Params = Template->getTemplateParameters();
1906 TemplateParameterList::iterator PEnd = Params->end();
1907 if (MaxParameters)
1908 PEnd = Params->begin() + MaxParameters;
1909 for (TemplateParameterList::iterator P = Params->begin(); P != PEnd; ++P) {
1910 bool HasDefaultArg = false;
1911 std::string PlaceholderStr;
1912 if (TemplateTypeParmDecl *TTP = dyn_cast<TemplateTypeParmDecl>(*P)) {
1913 if (TTP->wasDeclaredWithTypename())
1914 PlaceholderStr = "typename";
1915 else
1916 PlaceholderStr = "class";
1917
1918 if (TTP->getIdentifier()) {
1919 PlaceholderStr += ' ';
1920 PlaceholderStr += TTP->getIdentifier()->getName();
1921 }
1922
1923 HasDefaultArg = TTP->hasDefaultArgument();
1924 } else if (NonTypeTemplateParmDecl *NTTP
1925 = dyn_cast<NonTypeTemplateParmDecl>(*P)) {
1926 if (NTTP->getIdentifier())
1927 PlaceholderStr = NTTP->getIdentifier()->getName();
1928 NTTP->getType().getAsStringInternal(PlaceholderStr,
1929 Context.PrintingPolicy);
1930 HasDefaultArg = NTTP->hasDefaultArgument();
1931 } else {
1932 assert(isa<TemplateTemplateParmDecl>(*P));
1933 TemplateTemplateParmDecl *TTP = cast<TemplateTemplateParmDecl>(*P);
1934
1935 // Since putting the template argument list into the placeholder would
1936 // be very, very long, we just use an abbreviation.
1937 PlaceholderStr = "template<...> class";
1938 if (TTP->getIdentifier()) {
1939 PlaceholderStr += ' ';
1940 PlaceholderStr += TTP->getIdentifier()->getName();
1941 }
1942
1943 HasDefaultArg = TTP->hasDefaultArgument();
1944 }
1945
1946 if (HasDefaultArg) {
1947 // When we see an optional default argument, put that argument and
1948 // the remaining default arguments into a new, optional string.
1949 CodeCompletionString *Opt = new CodeCompletionString;
1950 CCStr->AddOptionalChunk(std::auto_ptr<CodeCompletionString>(Opt));
1951 CCStr = Opt;
1952 }
1953
1954 if (FirstParameter)
1955 FirstParameter = false;
1956 else
Douglas Gregor0c8296d2009-11-07 00:00:49 +00001957 CCStr->AddChunk(Chunk(CodeCompletionString::CK_Comma));
Douglas Gregor86d9a522009-09-21 16:56:56 +00001958
1959 // Add the placeholder string.
Benjamin Kramer660cc182009-11-29 20:18:50 +00001960 CCStr->AddPlaceholderChunk(PlaceholderStr);
Douglas Gregor86d9a522009-09-21 16:56:56 +00001961 }
1962}
1963
Douglas Gregorb9d0ef72009-09-21 19:57:38 +00001964/// \brief Add a qualifier to the given code-completion string, if the
1965/// provided nested-name-specifier is non-NULL.
Douglas Gregora61a8792009-12-11 18:44:16 +00001966static void
1967AddQualifierToCompletionString(CodeCompletionString *Result,
1968 NestedNameSpecifier *Qualifier,
1969 bool QualifierIsInformative,
1970 ASTContext &Context) {
Douglas Gregorb9d0ef72009-09-21 19:57:38 +00001971 if (!Qualifier)
1972 return;
1973
1974 std::string PrintedNNS;
1975 {
1976 llvm::raw_string_ostream OS(PrintedNNS);
1977 Qualifier->print(OS, Context.PrintingPolicy);
1978 }
Douglas Gregor0563c262009-09-22 23:15:58 +00001979 if (QualifierIsInformative)
Benjamin Kramer660cc182009-11-29 20:18:50 +00001980 Result->AddInformativeChunk(PrintedNNS);
Douglas Gregor0563c262009-09-22 23:15:58 +00001981 else
Benjamin Kramer660cc182009-11-29 20:18:50 +00001982 Result->AddTextChunk(PrintedNNS);
Douglas Gregorb9d0ef72009-09-21 19:57:38 +00001983}
1984
Douglas Gregora61a8792009-12-11 18:44:16 +00001985static void AddFunctionTypeQualsToCompletionString(CodeCompletionString *Result,
1986 FunctionDecl *Function) {
1987 const FunctionProtoType *Proto
1988 = Function->getType()->getAs<FunctionProtoType>();
1989 if (!Proto || !Proto->getTypeQuals())
1990 return;
1991
1992 std::string QualsStr;
1993 if (Proto->getTypeQuals() & Qualifiers::Const)
1994 QualsStr += " const";
1995 if (Proto->getTypeQuals() & Qualifiers::Volatile)
1996 QualsStr += " volatile";
1997 if (Proto->getTypeQuals() & Qualifiers::Restrict)
1998 QualsStr += " restrict";
1999 Result->AddInformativeChunk(QualsStr);
2000}
2001
Douglas Gregor86d9a522009-09-21 16:56:56 +00002002/// \brief If possible, create a new code completion string for the given
2003/// result.
2004///
2005/// \returns Either a new, heap-allocated code completion string describing
2006/// how to use this result, or NULL to indicate that the string or name of the
2007/// result is all that is needed.
2008CodeCompletionString *
John McCall0a2c5e22010-08-25 06:19:51 +00002009CodeCompletionResult::CreateCodeCompletionString(Sema &S,
Douglas Gregor1abc6bc2010-08-04 16:47:14 +00002010 CodeCompletionString *Result) {
Douglas Gregor0c8296d2009-11-07 00:00:49 +00002011 typedef CodeCompletionString::Chunk Chunk;
2012
Douglas Gregor2b4074f2009-12-01 05:55:20 +00002013 if (Kind == RK_Pattern)
Douglas Gregor1abc6bc2010-08-04 16:47:14 +00002014 return Pattern->Clone(Result);
Douglas Gregor2b4074f2009-12-01 05:55:20 +00002015
Douglas Gregor1abc6bc2010-08-04 16:47:14 +00002016 if (!Result)
2017 Result = new CodeCompletionString;
Douglas Gregor2b4074f2009-12-01 05:55:20 +00002018
2019 if (Kind == RK_Keyword) {
2020 Result->AddTypedTextChunk(Keyword);
2021 return Result;
2022 }
Douglas Gregor86d9a522009-09-21 16:56:56 +00002023
Douglas Gregor3f7c7f42009-10-30 16:50:04 +00002024 if (Kind == RK_Macro) {
2025 MacroInfo *MI = S.PP.getMacroInfo(Macro);
Douglas Gregor2b4074f2009-12-01 05:55:20 +00002026 assert(MI && "Not a macro?");
2027
2028 Result->AddTypedTextChunk(Macro->getName());
2029
2030 if (!MI->isFunctionLike())
2031 return Result;
Douglas Gregor3f7c7f42009-10-30 16:50:04 +00002032
2033 // Format a function-like macro with placeholders for the arguments.
Douglas Gregor0c8296d2009-11-07 00:00:49 +00002034 Result->AddChunk(Chunk(CodeCompletionString::CK_LeftParen));
Douglas Gregor3f7c7f42009-10-30 16:50:04 +00002035 for (MacroInfo::arg_iterator A = MI->arg_begin(), AEnd = MI->arg_end();
2036 A != AEnd; ++A) {
2037 if (A != MI->arg_begin())
Douglas Gregor0c8296d2009-11-07 00:00:49 +00002038 Result->AddChunk(Chunk(CodeCompletionString::CK_Comma));
Douglas Gregor3f7c7f42009-10-30 16:50:04 +00002039
2040 if (!MI->isVariadic() || A != AEnd - 1) {
2041 // Non-variadic argument.
Benjamin Kramer660cc182009-11-29 20:18:50 +00002042 Result->AddPlaceholderChunk((*A)->getName());
Douglas Gregor3f7c7f42009-10-30 16:50:04 +00002043 continue;
2044 }
2045
2046 // Variadic argument; cope with the different between GNU and C99
2047 // variadic macros, providing a single placeholder for the rest of the
2048 // arguments.
2049 if ((*A)->isStr("__VA_ARGS__"))
2050 Result->AddPlaceholderChunk("...");
2051 else {
2052 std::string Arg = (*A)->getName();
2053 Arg += "...";
Benjamin Kramer660cc182009-11-29 20:18:50 +00002054 Result->AddPlaceholderChunk(Arg);
Douglas Gregor3f7c7f42009-10-30 16:50:04 +00002055 }
2056 }
Douglas Gregor0c8296d2009-11-07 00:00:49 +00002057 Result->AddChunk(Chunk(CodeCompletionString::CK_RightParen));
Douglas Gregor3f7c7f42009-10-30 16:50:04 +00002058 return Result;
2059 }
2060
Douglas Gregord8e8a582010-05-25 21:41:55 +00002061 assert(Kind == RK_Declaration && "Missed a result kind?");
Douglas Gregor86d9a522009-09-21 16:56:56 +00002062 NamedDecl *ND = Declaration;
2063
Douglas Gregor0c8296d2009-11-07 00:00:49 +00002064 if (StartsNestedNameSpecifier) {
Benjamin Kramer660cc182009-11-29 20:18:50 +00002065 Result->AddTypedTextChunk(ND->getNameAsString());
Douglas Gregor0c8296d2009-11-07 00:00:49 +00002066 Result->AddTextChunk("::");
2067 return Result;
2068 }
2069
Douglas Gregorff5ce6e2009-12-18 18:53:37 +00002070 AddResultTypeChunk(S.Context, ND, Result);
2071
Douglas Gregor86d9a522009-09-21 16:56:56 +00002072 if (FunctionDecl *Function = dyn_cast<FunctionDecl>(ND)) {
Douglas Gregor0563c262009-09-22 23:15:58 +00002073 AddQualifierToCompletionString(Result, Qualifier, QualifierIsInformative,
2074 S.Context);
Benjamin Kramer660cc182009-11-29 20:18:50 +00002075 Result->AddTypedTextChunk(Function->getNameAsString());
Douglas Gregor0c8296d2009-11-07 00:00:49 +00002076 Result->AddChunk(Chunk(CodeCompletionString::CK_LeftParen));
Douglas Gregor86d9a522009-09-21 16:56:56 +00002077 AddFunctionParameterChunks(S.Context, Function, Result);
Douglas Gregor0c8296d2009-11-07 00:00:49 +00002078 Result->AddChunk(Chunk(CodeCompletionString::CK_RightParen));
Douglas Gregora61a8792009-12-11 18:44:16 +00002079 AddFunctionTypeQualsToCompletionString(Result, Function);
Douglas Gregor86d9a522009-09-21 16:56:56 +00002080 return Result;
2081 }
2082
2083 if (FunctionTemplateDecl *FunTmpl = dyn_cast<FunctionTemplateDecl>(ND)) {
Douglas Gregor0563c262009-09-22 23:15:58 +00002084 AddQualifierToCompletionString(Result, Qualifier, QualifierIsInformative,
2085 S.Context);
Douglas Gregor86d9a522009-09-21 16:56:56 +00002086 FunctionDecl *Function = FunTmpl->getTemplatedDecl();
Benjamin Kramer660cc182009-11-29 20:18:50 +00002087 Result->AddTypedTextChunk(Function->getNameAsString());
Douglas Gregor86d9a522009-09-21 16:56:56 +00002088
2089 // Figure out which template parameters are deduced (or have default
2090 // arguments).
2091 llvm::SmallVector<bool, 16> Deduced;
2092 S.MarkDeducedTemplateParameters(FunTmpl, Deduced);
2093 unsigned LastDeducibleArgument;
2094 for (LastDeducibleArgument = Deduced.size(); LastDeducibleArgument > 0;
2095 --LastDeducibleArgument) {
2096 if (!Deduced[LastDeducibleArgument - 1]) {
2097 // C++0x: Figure out if the template argument has a default. If so,
2098 // the user doesn't need to type this argument.
2099 // FIXME: We need to abstract template parameters better!
2100 bool HasDefaultArg = false;
2101 NamedDecl *Param = FunTmpl->getTemplateParameters()->getParam(
2102 LastDeducibleArgument - 1);
2103 if (TemplateTypeParmDecl *TTP = dyn_cast<TemplateTypeParmDecl>(Param))
2104 HasDefaultArg = TTP->hasDefaultArgument();
2105 else if (NonTypeTemplateParmDecl *NTTP
2106 = dyn_cast<NonTypeTemplateParmDecl>(Param))
2107 HasDefaultArg = NTTP->hasDefaultArgument();
2108 else {
2109 assert(isa<TemplateTemplateParmDecl>(Param));
2110 HasDefaultArg
Douglas Gregor0c8296d2009-11-07 00:00:49 +00002111 = cast<TemplateTemplateParmDecl>(Param)->hasDefaultArgument();
Douglas Gregor86d9a522009-09-21 16:56:56 +00002112 }
2113
2114 if (!HasDefaultArg)
2115 break;
2116 }
2117 }
2118
2119 if (LastDeducibleArgument) {
2120 // Some of the function template arguments cannot be deduced from a
2121 // function call, so we introduce an explicit template argument list
2122 // containing all of the arguments up to the first deducible argument.
Douglas Gregor0c8296d2009-11-07 00:00:49 +00002123 Result->AddChunk(Chunk(CodeCompletionString::CK_LeftAngle));
Douglas Gregor86d9a522009-09-21 16:56:56 +00002124 AddTemplateParameterChunks(S.Context, FunTmpl, Result,
2125 LastDeducibleArgument);
Douglas Gregor0c8296d2009-11-07 00:00:49 +00002126 Result->AddChunk(Chunk(CodeCompletionString::CK_RightAngle));
Douglas Gregor86d9a522009-09-21 16:56:56 +00002127 }
2128
2129 // Add the function parameters
Douglas Gregor0c8296d2009-11-07 00:00:49 +00002130 Result->AddChunk(Chunk(CodeCompletionString::CK_LeftParen));
Douglas Gregor86d9a522009-09-21 16:56:56 +00002131 AddFunctionParameterChunks(S.Context, Function, Result);
Douglas Gregor0c8296d2009-11-07 00:00:49 +00002132 Result->AddChunk(Chunk(CodeCompletionString::CK_RightParen));
Douglas Gregora61a8792009-12-11 18:44:16 +00002133 AddFunctionTypeQualsToCompletionString(Result, Function);
Douglas Gregor86d9a522009-09-21 16:56:56 +00002134 return Result;
2135 }
2136
2137 if (TemplateDecl *Template = dyn_cast<TemplateDecl>(ND)) {
Douglas Gregor0563c262009-09-22 23:15:58 +00002138 AddQualifierToCompletionString(Result, Qualifier, QualifierIsInformative,
2139 S.Context);
Benjamin Kramer660cc182009-11-29 20:18:50 +00002140 Result->AddTypedTextChunk(Template->getNameAsString());
Douglas Gregor0c8296d2009-11-07 00:00:49 +00002141 Result->AddChunk(Chunk(CodeCompletionString::CK_LeftAngle));
Douglas Gregor86d9a522009-09-21 16:56:56 +00002142 AddTemplateParameterChunks(S.Context, Template, Result);
Douglas Gregor0c8296d2009-11-07 00:00:49 +00002143 Result->AddChunk(Chunk(CodeCompletionString::CK_RightAngle));
Douglas Gregor86d9a522009-09-21 16:56:56 +00002144 return Result;
2145 }
2146
Douglas Gregor9630eb62009-11-17 16:44:22 +00002147 if (ObjCMethodDecl *Method = dyn_cast<ObjCMethodDecl>(ND)) {
Douglas Gregor9630eb62009-11-17 16:44:22 +00002148 Selector Sel = Method->getSelector();
2149 if (Sel.isUnarySelector()) {
2150 Result->AddTypedTextChunk(Sel.getIdentifierInfoForSlot(0)->getName());
2151 return Result;
2152 }
2153
Douglas Gregord3c68542009-11-19 01:08:35 +00002154 std::string SelName = Sel.getIdentifierInfoForSlot(0)->getName().str();
2155 SelName += ':';
2156 if (StartParameter == 0)
2157 Result->AddTypedTextChunk(SelName);
2158 else {
2159 Result->AddInformativeChunk(SelName);
2160
2161 // If there is only one parameter, and we're past it, add an empty
2162 // typed-text chunk since there is nothing to type.
2163 if (Method->param_size() == 1)
2164 Result->AddTypedTextChunk("");
2165 }
Douglas Gregor9630eb62009-11-17 16:44:22 +00002166 unsigned Idx = 0;
2167 for (ObjCMethodDecl::param_iterator P = Method->param_begin(),
2168 PEnd = Method->param_end();
2169 P != PEnd; (void)++P, ++Idx) {
2170 if (Idx > 0) {
Douglas Gregord3c68542009-11-19 01:08:35 +00002171 std::string Keyword;
2172 if (Idx > StartParameter)
Douglas Gregor834389b2010-01-12 06:38:28 +00002173 Result->AddChunk(CodeCompletionString::CK_HorizontalSpace);
Douglas Gregor9630eb62009-11-17 16:44:22 +00002174 if (IdentifierInfo *II = Sel.getIdentifierInfoForSlot(Idx))
2175 Keyword += II->getName().str();
2176 Keyword += ":";
Douglas Gregor1f5537a2010-07-08 23:20:03 +00002177 if (Idx < StartParameter || AllParametersAreInformative)
Douglas Gregord3c68542009-11-19 01:08:35 +00002178 Result->AddInformativeChunk(Keyword);
Douglas Gregor1f5537a2010-07-08 23:20:03 +00002179 else if (Idx == StartParameter)
Douglas Gregord3c68542009-11-19 01:08:35 +00002180 Result->AddTypedTextChunk(Keyword);
2181 else
2182 Result->AddTextChunk(Keyword);
Douglas Gregor9630eb62009-11-17 16:44:22 +00002183 }
Douglas Gregord3c68542009-11-19 01:08:35 +00002184
2185 // If we're before the starting parameter, skip the placeholder.
2186 if (Idx < StartParameter)
2187 continue;
Douglas Gregor9630eb62009-11-17 16:44:22 +00002188
2189 std::string Arg;
Douglas Gregor83482d12010-08-24 16:15:59 +00002190
2191 if ((*P)->getType()->isBlockPointerType() && !DeclaringEntity)
Douglas Gregoraba48082010-08-29 19:47:46 +00002192 Arg = FormatFunctionParameter(S.Context, *P, true);
Douglas Gregor83482d12010-08-24 16:15:59 +00002193 else {
2194 (*P)->getType().getAsStringInternal(Arg, S.Context.PrintingPolicy);
2195 Arg = "(" + Arg + ")";
2196 if (IdentifierInfo *II = (*P)->getIdentifier())
Douglas Gregoraba48082010-08-29 19:47:46 +00002197 if (DeclaringEntity || AllParametersAreInformative)
2198 Arg += II->getName().str();
Douglas Gregor83482d12010-08-24 16:15:59 +00002199 }
2200
Douglas Gregore17794f2010-08-31 05:13:43 +00002201 if (Method->isVariadic() && (P + 1) == PEnd)
2202 Arg += ", ...";
2203
Douglas Gregor1f5537a2010-07-08 23:20:03 +00002204 if (DeclaringEntity)
2205 Result->AddTextChunk(Arg);
2206 else if (AllParametersAreInformative)
Douglas Gregor4ad96852009-11-19 07:41:15 +00002207 Result->AddInformativeChunk(Arg);
2208 else
2209 Result->AddPlaceholderChunk(Arg);
Douglas Gregor9630eb62009-11-17 16:44:22 +00002210 }
2211
Douglas Gregor2a17af02009-12-23 00:21:46 +00002212 if (Method->isVariadic()) {
Douglas Gregore17794f2010-08-31 05:13:43 +00002213 if (Method->param_size() == 0) {
2214 if (DeclaringEntity)
2215 Result->AddTextChunk(", ...");
2216 else if (AllParametersAreInformative)
2217 Result->AddInformativeChunk(", ...");
2218 else
2219 Result->AddPlaceholderChunk(", ...");
2220 }
Douglas Gregoraaa107a2010-08-23 23:51:41 +00002221
2222 MaybeAddSentinel(S.Context, Method, Result);
Douglas Gregor2a17af02009-12-23 00:21:46 +00002223 }
2224
Douglas Gregor9630eb62009-11-17 16:44:22 +00002225 return Result;
2226 }
2227
Douglas Gregor2b4074f2009-12-01 05:55:20 +00002228 if (Qualifier)
Douglas Gregor0563c262009-09-22 23:15:58 +00002229 AddQualifierToCompletionString(Result, Qualifier, QualifierIsInformative,
2230 S.Context);
Douglas Gregor2b4074f2009-12-01 05:55:20 +00002231
2232 Result->AddTypedTextChunk(ND->getNameAsString());
2233 return Result;
Douglas Gregor86d9a522009-09-21 16:56:56 +00002234}
2235
Douglas Gregor86d802e2009-09-23 00:34:09 +00002236CodeCompletionString *
2237CodeCompleteConsumer::OverloadCandidate::CreateSignatureString(
2238 unsigned CurrentArg,
2239 Sema &S) const {
Douglas Gregor0c8296d2009-11-07 00:00:49 +00002240 typedef CodeCompletionString::Chunk Chunk;
2241
Douglas Gregor86d802e2009-09-23 00:34:09 +00002242 CodeCompletionString *Result = new CodeCompletionString;
2243 FunctionDecl *FDecl = getFunction();
Douglas Gregorff5ce6e2009-12-18 18:53:37 +00002244 AddResultTypeChunk(S.Context, FDecl, Result);
Douglas Gregor86d802e2009-09-23 00:34:09 +00002245 const FunctionProtoType *Proto
2246 = dyn_cast<FunctionProtoType>(getFunctionType());
2247 if (!FDecl && !Proto) {
2248 // Function without a prototype. Just give the return type and a
2249 // highlighted ellipsis.
2250 const FunctionType *FT = getFunctionType();
2251 Result->AddTextChunk(
Benjamin Kramer660cc182009-11-29 20:18:50 +00002252 FT->getResultType().getAsString(S.Context.PrintingPolicy));
Douglas Gregor0c8296d2009-11-07 00:00:49 +00002253 Result->AddChunk(Chunk(CodeCompletionString::CK_LeftParen));
2254 Result->AddChunk(Chunk(CodeCompletionString::CK_CurrentParameter, "..."));
2255 Result->AddChunk(Chunk(CodeCompletionString::CK_RightParen));
Douglas Gregor86d802e2009-09-23 00:34:09 +00002256 return Result;
2257 }
2258
2259 if (FDecl)
Benjamin Kramer660cc182009-11-29 20:18:50 +00002260 Result->AddTextChunk(FDecl->getNameAsString());
Douglas Gregor86d802e2009-09-23 00:34:09 +00002261 else
2262 Result->AddTextChunk(
Benjamin Kramer660cc182009-11-29 20:18:50 +00002263 Proto->getResultType().getAsString(S.Context.PrintingPolicy));
Douglas Gregor86d802e2009-09-23 00:34:09 +00002264
Douglas Gregor0c8296d2009-11-07 00:00:49 +00002265 Result->AddChunk(Chunk(CodeCompletionString::CK_LeftParen));
Douglas Gregor86d802e2009-09-23 00:34:09 +00002266 unsigned NumParams = FDecl? FDecl->getNumParams() : Proto->getNumArgs();
2267 for (unsigned I = 0; I != NumParams; ++I) {
2268 if (I)
Douglas Gregor0c8296d2009-11-07 00:00:49 +00002269 Result->AddChunk(Chunk(CodeCompletionString::CK_Comma));
Douglas Gregor86d802e2009-09-23 00:34:09 +00002270
2271 std::string ArgString;
2272 QualType ArgType;
2273
2274 if (FDecl) {
2275 ArgString = FDecl->getParamDecl(I)->getNameAsString();
2276 ArgType = FDecl->getParamDecl(I)->getOriginalType();
2277 } else {
2278 ArgType = Proto->getArgType(I);
2279 }
2280
2281 ArgType.getAsStringInternal(ArgString, S.Context.PrintingPolicy);
2282
2283 if (I == CurrentArg)
Douglas Gregor0c8296d2009-11-07 00:00:49 +00002284 Result->AddChunk(Chunk(CodeCompletionString::CK_CurrentParameter,
Benjamin Kramer660cc182009-11-29 20:18:50 +00002285 ArgString));
Douglas Gregor86d802e2009-09-23 00:34:09 +00002286 else
Benjamin Kramer660cc182009-11-29 20:18:50 +00002287 Result->AddTextChunk(ArgString);
Douglas Gregor86d802e2009-09-23 00:34:09 +00002288 }
2289
2290 if (Proto && Proto->isVariadic()) {
Douglas Gregor0c8296d2009-11-07 00:00:49 +00002291 Result->AddChunk(Chunk(CodeCompletionString::CK_Comma));
Douglas Gregor86d802e2009-09-23 00:34:09 +00002292 if (CurrentArg < NumParams)
2293 Result->AddTextChunk("...");
2294 else
Douglas Gregor0c8296d2009-11-07 00:00:49 +00002295 Result->AddChunk(Chunk(CodeCompletionString::CK_CurrentParameter, "..."));
Douglas Gregor86d802e2009-09-23 00:34:09 +00002296 }
Douglas Gregor0c8296d2009-11-07 00:00:49 +00002297 Result->AddChunk(Chunk(CodeCompletionString::CK_RightParen));
Douglas Gregor86d802e2009-09-23 00:34:09 +00002298
2299 return Result;
2300}
2301
Douglas Gregor1827e102010-08-16 16:18:59 +00002302unsigned clang::getMacroUsagePriority(llvm::StringRef MacroName,
2303 bool PreferredTypeIsPointer) {
2304 unsigned Priority = CCP_Macro;
2305
2306 // Treat the "nil" and "NULL" macros as null pointer constants.
2307 if (MacroName.equals("nil") || MacroName.equals("NULL")) {
2308 Priority = CCP_Constant;
2309 if (PreferredTypeIsPointer)
2310 Priority = Priority / CCF_SimilarTypeMatch;
2311 }
2312
2313 return Priority;
2314}
2315
Douglas Gregore8d7beb2010-09-03 23:30:36 +00002316CXCursorKind clang::getCursorKindForDecl(Decl *D) {
2317 if (!D)
2318 return CXCursor_UnexposedDecl;
2319
2320 switch (D->getKind()) {
2321 case Decl::Enum: return CXCursor_EnumDecl;
2322 case Decl::EnumConstant: return CXCursor_EnumConstantDecl;
2323 case Decl::Field: return CXCursor_FieldDecl;
2324 case Decl::Function:
2325 return CXCursor_FunctionDecl;
2326 case Decl::ObjCCategory: return CXCursor_ObjCCategoryDecl;
2327 case Decl::ObjCCategoryImpl: return CXCursor_ObjCCategoryImplDecl;
2328 case Decl::ObjCClass:
2329 // FIXME
2330 return CXCursor_UnexposedDecl;
2331 case Decl::ObjCForwardProtocol:
2332 // FIXME
2333 return CXCursor_UnexposedDecl;
2334 case Decl::ObjCImplementation: return CXCursor_ObjCImplementationDecl;
2335 case Decl::ObjCInterface: return CXCursor_ObjCInterfaceDecl;
2336 case Decl::ObjCIvar: return CXCursor_ObjCIvarDecl;
2337 case Decl::ObjCMethod:
2338 return cast<ObjCMethodDecl>(D)->isInstanceMethod()
2339 ? CXCursor_ObjCInstanceMethodDecl : CXCursor_ObjCClassMethodDecl;
2340 case Decl::CXXMethod: return CXCursor_CXXMethod;
2341 case Decl::CXXConstructor: return CXCursor_Constructor;
2342 case Decl::CXXDestructor: return CXCursor_Destructor;
2343 case Decl::CXXConversion: return CXCursor_ConversionFunction;
2344 case Decl::ObjCProperty: return CXCursor_ObjCPropertyDecl;
2345 case Decl::ObjCProtocol: return CXCursor_ObjCProtocolDecl;
2346 case Decl::ParmVar: return CXCursor_ParmDecl;
2347 case Decl::Typedef: return CXCursor_TypedefDecl;
2348 case Decl::Var: return CXCursor_VarDecl;
2349 case Decl::Namespace: return CXCursor_Namespace;
2350 case Decl::NamespaceAlias: return CXCursor_NamespaceAlias;
2351 case Decl::TemplateTypeParm: return CXCursor_TemplateTypeParameter;
2352 case Decl::NonTypeTemplateParm:return CXCursor_NonTypeTemplateParameter;
2353 case Decl::TemplateTemplateParm:return CXCursor_TemplateTemplateParameter;
2354 case Decl::FunctionTemplate: return CXCursor_FunctionTemplate;
2355 case Decl::ClassTemplate: return CXCursor_ClassTemplate;
2356 case Decl::ClassTemplatePartialSpecialization:
2357 return CXCursor_ClassTemplatePartialSpecialization;
2358 case Decl::UsingDirective: return CXCursor_UsingDirective;
2359
2360 case Decl::Using:
2361 case Decl::UnresolvedUsingValue:
2362 case Decl::UnresolvedUsingTypename:
2363 return CXCursor_UsingDeclaration;
2364
2365 default:
2366 if (TagDecl *TD = dyn_cast<TagDecl>(D)) {
2367 switch (TD->getTagKind()) {
2368 case TTK_Struct: return CXCursor_StructDecl;
2369 case TTK_Class: return CXCursor_ClassDecl;
2370 case TTK_Union: return CXCursor_UnionDecl;
2371 case TTK_Enum: return CXCursor_EnumDecl;
2372 }
2373 }
2374 }
2375
2376 return CXCursor_UnexposedDecl;
2377}
2378
Douglas Gregor590c7d52010-07-08 20:55:51 +00002379static void AddMacroResults(Preprocessor &PP, ResultBuilder &Results,
2380 bool TargetTypeIsPointer = false) {
John McCall0a2c5e22010-08-25 06:19:51 +00002381 typedef CodeCompletionResult Result;
Douglas Gregor590c7d52010-07-08 20:55:51 +00002382
Douglas Gregor3f7c7f42009-10-30 16:50:04 +00002383 Results.EnterNewScope();
Douglas Gregor0c8296d2009-11-07 00:00:49 +00002384 for (Preprocessor::macro_iterator M = PP.macro_begin(),
2385 MEnd = PP.macro_end();
Douglas Gregor590c7d52010-07-08 20:55:51 +00002386 M != MEnd; ++M) {
Douglas Gregor1827e102010-08-16 16:18:59 +00002387 Results.AddResult(Result(M->first,
2388 getMacroUsagePriority(M->first->getName(),
2389 TargetTypeIsPointer)));
Douglas Gregor590c7d52010-07-08 20:55:51 +00002390 }
Douglas Gregor3f7c7f42009-10-30 16:50:04 +00002391 Results.ExitScope();
2392}
2393
Douglas Gregoraa5f77b2010-08-23 21:54:33 +00002394static void AddPrettyFunctionResults(const LangOptions &LangOpts,
2395 ResultBuilder &Results) {
John McCall0a2c5e22010-08-25 06:19:51 +00002396 typedef CodeCompletionResult Result;
Douglas Gregoraa5f77b2010-08-23 21:54:33 +00002397
2398 Results.EnterNewScope();
2399 Results.AddResult(Result("__PRETTY_FUNCTION__", CCP_Constant));
2400 Results.AddResult(Result("__FUNCTION__", CCP_Constant));
2401 if (LangOpts.C99 || LangOpts.CPlusPlus0x)
2402 Results.AddResult(Result("__func__", CCP_Constant));
2403 Results.ExitScope();
2404}
2405
Daniel Dunbar3a2838d2009-11-13 08:58:20 +00002406static void HandleCodeCompleteResults(Sema *S,
2407 CodeCompleteConsumer *CodeCompleter,
Douglas Gregore6b1bb62010-08-11 21:23:17 +00002408 CodeCompletionContext Context,
John McCall0a2c5e22010-08-25 06:19:51 +00002409 CodeCompletionResult *Results,
Douglas Gregore6b1bb62010-08-11 21:23:17 +00002410 unsigned NumResults) {
Douglas Gregor86d9a522009-09-21 16:56:56 +00002411 if (CodeCompleter)
Douglas Gregore6b1bb62010-08-11 21:23:17 +00002412 CodeCompleter->ProcessCodeCompleteResults(*S, Context, Results, NumResults);
Douglas Gregor54f01612009-11-19 00:01:57 +00002413
2414 for (unsigned I = 0; I != NumResults; ++I)
2415 Results[I].Destroy();
Douglas Gregor86d9a522009-09-21 16:56:56 +00002416}
2417
Douglas Gregore6b1bb62010-08-11 21:23:17 +00002418static enum CodeCompletionContext::Kind mapCodeCompletionContext(Sema &S,
2419 Sema::ParserCompletionContext PCC) {
2420 switch (PCC) {
John McCallf312b1e2010-08-26 23:41:50 +00002421 case Sema::PCC_Namespace:
Douglas Gregore6b1bb62010-08-11 21:23:17 +00002422 return CodeCompletionContext::CCC_TopLevel;
2423
John McCallf312b1e2010-08-26 23:41:50 +00002424 case Sema::PCC_Class:
Douglas Gregore6b1bb62010-08-11 21:23:17 +00002425 return CodeCompletionContext::CCC_ClassStructUnion;
2426
John McCallf312b1e2010-08-26 23:41:50 +00002427 case Sema::PCC_ObjCInterface:
Douglas Gregore6b1bb62010-08-11 21:23:17 +00002428 return CodeCompletionContext::CCC_ObjCInterface;
2429
John McCallf312b1e2010-08-26 23:41:50 +00002430 case Sema::PCC_ObjCImplementation:
Douglas Gregore6b1bb62010-08-11 21:23:17 +00002431 return CodeCompletionContext::CCC_ObjCImplementation;
2432
John McCallf312b1e2010-08-26 23:41:50 +00002433 case Sema::PCC_ObjCInstanceVariableList:
Douglas Gregore6b1bb62010-08-11 21:23:17 +00002434 return CodeCompletionContext::CCC_ObjCIvarList;
2435
John McCallf312b1e2010-08-26 23:41:50 +00002436 case Sema::PCC_Template:
2437 case Sema::PCC_MemberTemplate:
2438 case Sema::PCC_RecoveryInFunction:
Douglas Gregore6b1bb62010-08-11 21:23:17 +00002439 return CodeCompletionContext::CCC_Other;
2440
John McCallf312b1e2010-08-26 23:41:50 +00002441 case Sema::PCC_Expression:
2442 case Sema::PCC_ForInit:
2443 case Sema::PCC_Condition:
Douglas Gregore6b1bb62010-08-11 21:23:17 +00002444 return CodeCompletionContext::CCC_Expression;
2445
John McCallf312b1e2010-08-26 23:41:50 +00002446 case Sema::PCC_Statement:
Douglas Gregore6b1bb62010-08-11 21:23:17 +00002447 return CodeCompletionContext::CCC_Statement;
Douglas Gregor72db1082010-08-24 01:11:00 +00002448
John McCallf312b1e2010-08-26 23:41:50 +00002449 case Sema::PCC_Type:
Douglas Gregor72db1082010-08-24 01:11:00 +00002450 return CodeCompletionContext::CCC_Type;
Douglas Gregore6b1bb62010-08-11 21:23:17 +00002451 }
2452
2453 return CodeCompletionContext::CCC_Other;
2454}
2455
Douglas Gregorf6961522010-08-27 21:18:54 +00002456/// \brief If we're in a C++ virtual member function, add completion results
2457/// that invoke the functions we override, since it's common to invoke the
2458/// overridden function as well as adding new functionality.
2459///
2460/// \param S The semantic analysis object for which we are generating results.
2461///
2462/// \param InContext This context in which the nested-name-specifier preceding
2463/// the code-completion point
2464static void MaybeAddOverrideCalls(Sema &S, DeclContext *InContext,
2465 ResultBuilder &Results) {
2466 // Look through blocks.
2467 DeclContext *CurContext = S.CurContext;
2468 while (isa<BlockDecl>(CurContext))
2469 CurContext = CurContext->getParent();
2470
2471
2472 CXXMethodDecl *Method = dyn_cast<CXXMethodDecl>(CurContext);
2473 if (!Method || !Method->isVirtual())
2474 return;
2475
2476 // We need to have names for all of the parameters, if we're going to
2477 // generate a forwarding call.
2478 for (CXXMethodDecl::param_iterator P = Method->param_begin(),
2479 PEnd = Method->param_end();
2480 P != PEnd;
2481 ++P) {
2482 if (!(*P)->getDeclName())
2483 return;
2484 }
2485
2486 for (CXXMethodDecl::method_iterator M = Method->begin_overridden_methods(),
2487 MEnd = Method->end_overridden_methods();
2488 M != MEnd; ++M) {
2489 CodeCompletionString *Pattern = new CodeCompletionString;
2490 CXXMethodDecl *Overridden = const_cast<CXXMethodDecl *>(*M);
2491 if (Overridden->getCanonicalDecl() == Method->getCanonicalDecl())
2492 continue;
2493
2494 // If we need a nested-name-specifier, add one now.
2495 if (!InContext) {
2496 NestedNameSpecifier *NNS
2497 = getRequiredQualification(S.Context, CurContext,
2498 Overridden->getDeclContext());
2499 if (NNS) {
2500 std::string Str;
2501 llvm::raw_string_ostream OS(Str);
2502 NNS->print(OS, S.Context.PrintingPolicy);
2503 Pattern->AddTextChunk(OS.str());
2504 }
2505 } else if (!InContext->Equals(Overridden->getDeclContext()))
2506 continue;
2507
2508 Pattern->AddTypedTextChunk(Overridden->getNameAsString());
2509 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
2510 bool FirstParam = true;
2511 for (CXXMethodDecl::param_iterator P = Method->param_begin(),
2512 PEnd = Method->param_end();
2513 P != PEnd; ++P) {
2514 if (FirstParam)
2515 FirstParam = false;
2516 else
2517 Pattern->AddChunk(CodeCompletionString::CK_Comma);
2518
2519 Pattern->AddPlaceholderChunk((*P)->getIdentifier()->getName());
2520 }
2521 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
2522 Results.AddResult(CodeCompletionResult(Pattern,
2523 CCP_SuperCompletion,
2524 CXCursor_CXXMethod));
2525 Results.Ignore(Overridden);
2526 }
2527}
2528
Douglas Gregor01dfea02010-01-10 23:08:15 +00002529void Sema::CodeCompleteOrdinaryName(Scope *S,
Douglas Gregore6b1bb62010-08-11 21:23:17 +00002530 ParserCompletionContext CompletionContext) {
John McCall0a2c5e22010-08-25 06:19:51 +00002531 typedef CodeCompletionResult Result;
Douglas Gregor2ccccb32010-08-23 18:23:48 +00002532 ResultBuilder Results(*this);
Douglas Gregorf6961522010-08-27 21:18:54 +00002533 Results.EnterNewScope();
Douglas Gregor01dfea02010-01-10 23:08:15 +00002534
2535 // Determine how to filter results, e.g., so that the names of
2536 // values (functions, enumerators, function templates, etc.) are
2537 // only allowed where we can have an expression.
2538 switch (CompletionContext) {
Douglas Gregore6b1bb62010-08-11 21:23:17 +00002539 case PCC_Namespace:
2540 case PCC_Class:
2541 case PCC_ObjCInterface:
2542 case PCC_ObjCImplementation:
2543 case PCC_ObjCInstanceVariableList:
2544 case PCC_Template:
2545 case PCC_MemberTemplate:
Douglas Gregor72db1082010-08-24 01:11:00 +00002546 case PCC_Type:
Douglas Gregor01dfea02010-01-10 23:08:15 +00002547 Results.setFilter(&ResultBuilder::IsOrdinaryNonValueName);
2548 break;
2549
Douglas Gregore6b1bb62010-08-11 21:23:17 +00002550 case PCC_Statement:
Douglas Gregoreb0d0142010-08-24 23:58:17 +00002551 // For statements that are expressions, we prefer to call 'void' functions
2552 // rather than functions that return a result, since then the result would
2553 // be ignored.
2554 Results.setPreferredType(Context.VoidTy);
2555 // Fall through
2556
2557 case PCC_Expression:
Douglas Gregore6b1bb62010-08-11 21:23:17 +00002558 case PCC_ForInit:
2559 case PCC_Condition:
Douglas Gregor4710e5b2010-05-28 00:49:12 +00002560 if (WantTypesInContext(CompletionContext, getLangOptions()))
2561 Results.setFilter(&ResultBuilder::IsOrdinaryName);
2562 else
2563 Results.setFilter(&ResultBuilder::IsOrdinaryNonTypeName);
Douglas Gregorf6961522010-08-27 21:18:54 +00002564
2565 if (getLangOptions().CPlusPlus)
2566 MaybeAddOverrideCalls(*this, /*InContext=*/0, Results);
Douglas Gregor01dfea02010-01-10 23:08:15 +00002567 break;
Douglas Gregordc845342010-05-25 05:58:43 +00002568
Douglas Gregore6b1bb62010-08-11 21:23:17 +00002569 case PCC_RecoveryInFunction:
Douglas Gregordc845342010-05-25 05:58:43 +00002570 // Unfiltered
2571 break;
Douglas Gregor01dfea02010-01-10 23:08:15 +00002572 }
2573
Douglas Gregor3cdee122010-08-26 16:36:48 +00002574 // If we are in a C++ non-static member function, check the qualifiers on
2575 // the member function to filter/prioritize the results list.
2576 if (CXXMethodDecl *CurMethod = dyn_cast<CXXMethodDecl>(CurContext))
2577 if (CurMethod->isInstance())
2578 Results.setObjectTypeQualifiers(
2579 Qualifiers::fromCVRMask(CurMethod->getTypeQualifiers()));
2580
Douglas Gregor1ca6ae82010-01-14 01:09:38 +00002581 CodeCompletionDeclConsumer Consumer(Results, CurContext);
Douglas Gregor8071e422010-08-15 06:18:01 +00002582 LookupVisibleDecls(S, LookupOrdinaryName, Consumer,
2583 CodeCompleter->includeGlobals());
Douglas Gregor2a7925c2009-12-07 09:54:55 +00002584
Douglas Gregorbca403c2010-01-13 23:51:12 +00002585 AddOrdinaryNameResults(CompletionContext, S, *this, Results);
Douglas Gregor2a7925c2009-12-07 09:54:55 +00002586 Results.ExitScope();
2587
Douglas Gregoraa5f77b2010-08-23 21:54:33 +00002588 switch (CompletionContext) {
Douglas Gregor72db1082010-08-24 01:11:00 +00002589 case PCC_Expression:
2590 case PCC_Statement:
2591 case PCC_RecoveryInFunction:
2592 if (S->getFnParent())
2593 AddPrettyFunctionResults(PP.getLangOptions(), Results);
2594 break;
2595
2596 case PCC_Namespace:
2597 case PCC_Class:
2598 case PCC_ObjCInterface:
2599 case PCC_ObjCImplementation:
2600 case PCC_ObjCInstanceVariableList:
2601 case PCC_Template:
2602 case PCC_MemberTemplate:
2603 case PCC_ForInit:
2604 case PCC_Condition:
2605 case PCC_Type:
2606 break;
Douglas Gregoraa5f77b2010-08-23 21:54:33 +00002607 }
2608
Douglas Gregor0c8296d2009-11-07 00:00:49 +00002609 if (CodeCompleter->includeMacros())
Douglas Gregorbca403c2010-01-13 23:51:12 +00002610 AddMacroResults(PP, Results);
Douglas Gregoraa5f77b2010-08-23 21:54:33 +00002611
Douglas Gregore6b1bb62010-08-11 21:23:17 +00002612 HandleCodeCompleteResults(this, CodeCompleter,
2613 mapCodeCompletionContext(*this, CompletionContext),
2614 Results.data(),Results.size());
Douglas Gregor791215b2009-09-21 20:51:25 +00002615}
2616
Douglas Gregor2ccccb32010-08-23 18:23:48 +00002617void Sema::CodeCompleteDeclarator(Scope *S,
2618 bool AllowNonIdentifiers,
2619 bool AllowNestedNameSpecifiers) {
John McCall0a2c5e22010-08-25 06:19:51 +00002620 typedef CodeCompletionResult Result;
Douglas Gregor2ccccb32010-08-23 18:23:48 +00002621 ResultBuilder Results(*this);
2622 Results.EnterNewScope();
2623
2624 // Type qualifiers can come after names.
2625 Results.AddResult(Result("const"));
2626 Results.AddResult(Result("volatile"));
2627 if (getLangOptions().C99)
2628 Results.AddResult(Result("restrict"));
2629
2630 if (getLangOptions().CPlusPlus) {
2631 if (AllowNonIdentifiers) {
2632 Results.AddResult(Result("operator"));
2633 }
2634
2635 // Add nested-name-specifiers.
2636 if (AllowNestedNameSpecifiers) {
2637 Results.allowNestedNameSpecifiers();
2638 CodeCompletionDeclConsumer Consumer(Results, CurContext);
2639 LookupVisibleDecls(S, LookupNestedNameSpecifierName, Consumer,
2640 CodeCompleter->includeGlobals());
2641 }
2642 }
2643 Results.ExitScope();
2644
Douglas Gregor4497dd42010-08-24 04:59:56 +00002645 // Note that we intentionally suppress macro results here, since we do not
2646 // encourage using macros to produce the names of entities.
2647
Douglas Gregor2ccccb32010-08-23 18:23:48 +00002648 HandleCodeCompleteResults(this, CodeCompleter,
2649 AllowNestedNameSpecifiers
2650 ? CodeCompletionContext::CCC_PotentiallyQualifiedName
2651 : CodeCompletionContext::CCC_Name,
2652 Results.data(), Results.size());
2653}
2654
Douglas Gregorfb629412010-08-23 21:17:50 +00002655struct Sema::CodeCompleteExpressionData {
2656 CodeCompleteExpressionData(QualType PreferredType = QualType())
2657 : PreferredType(PreferredType), IntegralConstantExpression(false),
2658 ObjCCollection(false) { }
2659
2660 QualType PreferredType;
2661 bool IntegralConstantExpression;
2662 bool ObjCCollection;
2663 llvm::SmallVector<Decl *, 4> IgnoreDecls;
2664};
2665
Douglas Gregor5ac3bdb2010-05-30 01:49:25 +00002666/// \brief Perform code-completion in an expression context when we know what
2667/// type we're looking for.
Douglas Gregorf9578432010-07-28 21:50:18 +00002668///
2669/// \param IntegralConstantExpression Only permit integral constant
2670/// expressions.
Douglas Gregorfb629412010-08-23 21:17:50 +00002671void Sema::CodeCompleteExpression(Scope *S,
2672 const CodeCompleteExpressionData &Data) {
John McCall0a2c5e22010-08-25 06:19:51 +00002673 typedef CodeCompletionResult Result;
Douglas Gregor5ac3bdb2010-05-30 01:49:25 +00002674 ResultBuilder Results(*this);
2675
Douglas Gregorfb629412010-08-23 21:17:50 +00002676 if (Data.ObjCCollection)
2677 Results.setFilter(&ResultBuilder::IsObjCCollection);
2678 else if (Data.IntegralConstantExpression)
Douglas Gregorf9578432010-07-28 21:50:18 +00002679 Results.setFilter(&ResultBuilder::IsIntegralConstantValue);
Douglas Gregore6b1bb62010-08-11 21:23:17 +00002680 else if (WantTypesInContext(PCC_Expression, getLangOptions()))
Douglas Gregor5ac3bdb2010-05-30 01:49:25 +00002681 Results.setFilter(&ResultBuilder::IsOrdinaryName);
2682 else
2683 Results.setFilter(&ResultBuilder::IsOrdinaryNonTypeName);
Douglas Gregorfb629412010-08-23 21:17:50 +00002684
2685 if (!Data.PreferredType.isNull())
2686 Results.setPreferredType(Data.PreferredType.getNonReferenceType());
2687
2688 // Ignore any declarations that we were told that we don't care about.
2689 for (unsigned I = 0, N = Data.IgnoreDecls.size(); I != N; ++I)
2690 Results.Ignore(Data.IgnoreDecls[I]);
Douglas Gregor5ac3bdb2010-05-30 01:49:25 +00002691
2692 CodeCompletionDeclConsumer Consumer(Results, CurContext);
Douglas Gregor8071e422010-08-15 06:18:01 +00002693 LookupVisibleDecls(S, LookupOrdinaryName, Consumer,
2694 CodeCompleter->includeGlobals());
Douglas Gregor5ac3bdb2010-05-30 01:49:25 +00002695
2696 Results.EnterNewScope();
Douglas Gregore6b1bb62010-08-11 21:23:17 +00002697 AddOrdinaryNameResults(PCC_Expression, S, *this, Results);
Douglas Gregor5ac3bdb2010-05-30 01:49:25 +00002698 Results.ExitScope();
2699
Douglas Gregor590c7d52010-07-08 20:55:51 +00002700 bool PreferredTypeIsPointer = false;
Douglas Gregorfb629412010-08-23 21:17:50 +00002701 if (!Data.PreferredType.isNull())
2702 PreferredTypeIsPointer = Data.PreferredType->isAnyPointerType()
2703 || Data.PreferredType->isMemberPointerType()
2704 || Data.PreferredType->isBlockPointerType();
Douglas Gregor590c7d52010-07-08 20:55:51 +00002705
Douglas Gregoraa5f77b2010-08-23 21:54:33 +00002706 if (S->getFnParent() &&
2707 !Data.ObjCCollection &&
2708 !Data.IntegralConstantExpression)
2709 AddPrettyFunctionResults(PP.getLangOptions(), Results);
2710
Douglas Gregor5ac3bdb2010-05-30 01:49:25 +00002711 if (CodeCompleter->includeMacros())
Douglas Gregor590c7d52010-07-08 20:55:51 +00002712 AddMacroResults(PP, Results, PreferredTypeIsPointer);
Douglas Gregore6b1bb62010-08-11 21:23:17 +00002713 HandleCodeCompleteResults(this, CodeCompleter,
Douglas Gregorfb629412010-08-23 21:17:50 +00002714 CodeCompletionContext(CodeCompletionContext::CCC_Expression,
2715 Data.PreferredType),
Douglas Gregore6b1bb62010-08-11 21:23:17 +00002716 Results.data(),Results.size());
Douglas Gregor5ac3bdb2010-05-30 01:49:25 +00002717}
2718
2719
Douglas Gregor95ac6552009-11-18 01:29:26 +00002720static void AddObjCProperties(ObjCContainerDecl *Container,
Douglas Gregor322328b2009-11-18 22:32:06 +00002721 bool AllowCategories,
Douglas Gregor95ac6552009-11-18 01:29:26 +00002722 DeclContext *CurContext,
2723 ResultBuilder &Results) {
John McCall0a2c5e22010-08-25 06:19:51 +00002724 typedef CodeCompletionResult Result;
Douglas Gregor95ac6552009-11-18 01:29:26 +00002725
2726 // Add properties in this container.
2727 for (ObjCContainerDecl::prop_iterator P = Container->prop_begin(),
2728 PEnd = Container->prop_end();
2729 P != PEnd;
2730 ++P)
2731 Results.MaybeAddResult(Result(*P, 0), CurContext);
2732
2733 // Add properties in referenced protocols.
2734 if (ObjCProtocolDecl *Protocol = dyn_cast<ObjCProtocolDecl>(Container)) {
2735 for (ObjCProtocolDecl::protocol_iterator P = Protocol->protocol_begin(),
2736 PEnd = Protocol->protocol_end();
2737 P != PEnd; ++P)
Douglas Gregor322328b2009-11-18 22:32:06 +00002738 AddObjCProperties(*P, AllowCategories, CurContext, Results);
Douglas Gregor95ac6552009-11-18 01:29:26 +00002739 } else if (ObjCInterfaceDecl *IFace = dyn_cast<ObjCInterfaceDecl>(Container)){
Douglas Gregor322328b2009-11-18 22:32:06 +00002740 if (AllowCategories) {
2741 // Look through categories.
2742 for (ObjCCategoryDecl *Category = IFace->getCategoryList();
2743 Category; Category = Category->getNextClassCategory())
2744 AddObjCProperties(Category, AllowCategories, CurContext, Results);
2745 }
Douglas Gregor95ac6552009-11-18 01:29:26 +00002746
2747 // Look through protocols.
Ted Kremenek53b94412010-09-01 01:21:15 +00002748 for (ObjCInterfaceDecl::all_protocol_iterator
2749 I = IFace->all_referenced_protocol_begin(),
2750 E = IFace->all_referenced_protocol_end(); I != E; ++I)
Douglas Gregor322328b2009-11-18 22:32:06 +00002751 AddObjCProperties(*I, AllowCategories, CurContext, Results);
Douglas Gregor95ac6552009-11-18 01:29:26 +00002752
2753 // Look in the superclass.
2754 if (IFace->getSuperClass())
Douglas Gregor322328b2009-11-18 22:32:06 +00002755 AddObjCProperties(IFace->getSuperClass(), AllowCategories, CurContext,
2756 Results);
Douglas Gregor95ac6552009-11-18 01:29:26 +00002757 } else if (const ObjCCategoryDecl *Category
2758 = dyn_cast<ObjCCategoryDecl>(Container)) {
2759 // Look through protocols.
Ted Kremenek53b94412010-09-01 01:21:15 +00002760 for (ObjCCategoryDecl::protocol_iterator P = Category->protocol_begin(),
2761 PEnd = Category->protocol_end();
Douglas Gregor95ac6552009-11-18 01:29:26 +00002762 P != PEnd; ++P)
Douglas Gregor322328b2009-11-18 22:32:06 +00002763 AddObjCProperties(*P, AllowCategories, CurContext, Results);
Douglas Gregor95ac6552009-11-18 01:29:26 +00002764 }
2765}
2766
Douglas Gregor81b747b2009-09-17 21:32:03 +00002767void Sema::CodeCompleteMemberReferenceExpr(Scope *S, ExprTy *BaseE,
2768 SourceLocation OpLoc,
2769 bool IsArrow) {
2770 if (!BaseE || !CodeCompleter)
2771 return;
2772
John McCall0a2c5e22010-08-25 06:19:51 +00002773 typedef CodeCompletionResult Result;
Douglas Gregor86d9a522009-09-21 16:56:56 +00002774
Douglas Gregor81b747b2009-09-17 21:32:03 +00002775 Expr *Base = static_cast<Expr *>(BaseE);
2776 QualType BaseType = Base->getType();
Douglas Gregor86d9a522009-09-21 16:56:56 +00002777
2778 if (IsArrow) {
2779 if (const PointerType *Ptr = BaseType->getAs<PointerType>())
2780 BaseType = Ptr->getPointeeType();
2781 else if (BaseType->isObjCObjectPointerType())
Douglas Gregor3cdee122010-08-26 16:36:48 +00002782 /*Do nothing*/ ;
Douglas Gregor86d9a522009-09-21 16:56:56 +00002783 else
2784 return;
2785 }
2786
Douglas Gregoreb5758b2009-09-23 22:26:46 +00002787 ResultBuilder Results(*this, &ResultBuilder::IsMember);
Douglas Gregor95ac6552009-11-18 01:29:26 +00002788 Results.EnterNewScope();
2789 if (const RecordType *Record = BaseType->getAs<RecordType>()) {
Douglas Gregor3cdee122010-08-26 16:36:48 +00002790 // Indicate that we are performing a member access, and the cv-qualifiers
2791 // for the base object type.
2792 Results.setObjectTypeQualifiers(BaseType.getQualifiers());
2793
Douglas Gregor95ac6552009-11-18 01:29:26 +00002794 // Access to a C/C++ class, struct, or union.
Douglas Gregor45bcd432010-01-14 03:21:49 +00002795 Results.allowNestedNameSpecifiers();
Douglas Gregor0cc84042010-01-14 15:47:35 +00002796 CodeCompletionDeclConsumer Consumer(Results, CurContext);
Douglas Gregor8071e422010-08-15 06:18:01 +00002797 LookupVisibleDecls(Record->getDecl(), LookupMemberName, Consumer,
2798 CodeCompleter->includeGlobals());
Daniel Dunbar3a2838d2009-11-13 08:58:20 +00002799
Douglas Gregor95ac6552009-11-18 01:29:26 +00002800 if (getLangOptions().CPlusPlus) {
2801 if (!Results.empty()) {
2802 // The "template" keyword can follow "->" or "." in the grammar.
2803 // However, we only want to suggest the template keyword if something
2804 // is dependent.
2805 bool IsDependent = BaseType->isDependentType();
2806 if (!IsDependent) {
2807 for (Scope *DepScope = S; DepScope; DepScope = DepScope->getParent())
2808 if (DeclContext *Ctx = (DeclContext *)DepScope->getEntity()) {
2809 IsDependent = Ctx->isDependentContext();
2810 break;
2811 }
2812 }
Daniel Dunbar3a2838d2009-11-13 08:58:20 +00002813
Douglas Gregor95ac6552009-11-18 01:29:26 +00002814 if (IsDependent)
Douglas Gregora4477812010-01-14 16:01:26 +00002815 Results.AddResult(Result("template"));
Daniel Dunbar3a2838d2009-11-13 08:58:20 +00002816 }
Daniel Dunbar3a2838d2009-11-13 08:58:20 +00002817 }
Douglas Gregor95ac6552009-11-18 01:29:26 +00002818 } else if (!IsArrow && BaseType->getAsObjCInterfacePointerType()) {
2819 // Objective-C property reference.
2820
2821 // Add property results based on our interface.
2822 const ObjCObjectPointerType *ObjCPtr
2823 = BaseType->getAsObjCInterfacePointerType();
2824 assert(ObjCPtr && "Non-NULL pointer guaranteed above!");
Douglas Gregor322328b2009-11-18 22:32:06 +00002825 AddObjCProperties(ObjCPtr->getInterfaceDecl(), true, CurContext, Results);
Douglas Gregor95ac6552009-11-18 01:29:26 +00002826
2827 // Add properties from the protocols in a qualified interface.
2828 for (ObjCObjectPointerType::qual_iterator I = ObjCPtr->qual_begin(),
2829 E = ObjCPtr->qual_end();
2830 I != E; ++I)
Douglas Gregor322328b2009-11-18 22:32:06 +00002831 AddObjCProperties(*I, true, CurContext, Results);
Douglas Gregor95ac6552009-11-18 01:29:26 +00002832 } else if ((IsArrow && BaseType->isObjCObjectPointerType()) ||
John McCallc12c5bb2010-05-15 11:32:37 +00002833 (!IsArrow && BaseType->isObjCObjectType())) {
Douglas Gregor95ac6552009-11-18 01:29:26 +00002834 // Objective-C instance variable access.
2835 ObjCInterfaceDecl *Class = 0;
2836 if (const ObjCObjectPointerType *ObjCPtr
2837 = BaseType->getAs<ObjCObjectPointerType>())
2838 Class = ObjCPtr->getInterfaceDecl();
2839 else
John McCallc12c5bb2010-05-15 11:32:37 +00002840 Class = BaseType->getAs<ObjCObjectType>()->getInterface();
Douglas Gregor95ac6552009-11-18 01:29:26 +00002841
2842 // Add all ivars from this class and its superclasses.
Douglas Gregor80f4f4c2010-01-14 16:08:12 +00002843 if (Class) {
2844 CodeCompletionDeclConsumer Consumer(Results, CurContext);
2845 Results.setFilter(&ResultBuilder::IsObjCIvar);
Douglas Gregor8071e422010-08-15 06:18:01 +00002846 LookupVisibleDecls(Class, LookupMemberName, Consumer,
2847 CodeCompleter->includeGlobals());
Douglas Gregor95ac6552009-11-18 01:29:26 +00002848 }
Douglas Gregor86d9a522009-09-21 16:56:56 +00002849 }
Douglas Gregor95ac6552009-11-18 01:29:26 +00002850
2851 // FIXME: How do we cope with isa?
2852
2853 Results.ExitScope();
Daniel Dunbar3a2838d2009-11-13 08:58:20 +00002854
Daniel Dunbar3a2838d2009-11-13 08:58:20 +00002855 // Hand off the results found for code completion.
Douglas Gregore6b1bb62010-08-11 21:23:17 +00002856 HandleCodeCompleteResults(this, CodeCompleter,
2857 CodeCompletionContext(CodeCompletionContext::CCC_MemberAccess,
2858 BaseType),
2859 Results.data(),Results.size());
Douglas Gregor81b747b2009-09-17 21:32:03 +00002860}
2861
Douglas Gregor374929f2009-09-18 15:37:17 +00002862void Sema::CodeCompleteTag(Scope *S, unsigned TagSpec) {
2863 if (!CodeCompleter)
2864 return;
2865
John McCall0a2c5e22010-08-25 06:19:51 +00002866 typedef CodeCompletionResult Result;
Douglas Gregor86d9a522009-09-21 16:56:56 +00002867 ResultBuilder::LookupFilter Filter = 0;
Douglas Gregore6b1bb62010-08-11 21:23:17 +00002868 enum CodeCompletionContext::Kind ContextKind
2869 = CodeCompletionContext::CCC_Other;
Douglas Gregor374929f2009-09-18 15:37:17 +00002870 switch ((DeclSpec::TST)TagSpec) {
2871 case DeclSpec::TST_enum:
Douglas Gregor86d9a522009-09-21 16:56:56 +00002872 Filter = &ResultBuilder::IsEnum;
Douglas Gregore6b1bb62010-08-11 21:23:17 +00002873 ContextKind = CodeCompletionContext::CCC_EnumTag;
Douglas Gregor374929f2009-09-18 15:37:17 +00002874 break;
2875
2876 case DeclSpec::TST_union:
Douglas Gregor86d9a522009-09-21 16:56:56 +00002877 Filter = &ResultBuilder::IsUnion;
Douglas Gregore6b1bb62010-08-11 21:23:17 +00002878 ContextKind = CodeCompletionContext::CCC_UnionTag;
Douglas Gregor374929f2009-09-18 15:37:17 +00002879 break;
2880
2881 case DeclSpec::TST_struct:
Douglas Gregor374929f2009-09-18 15:37:17 +00002882 case DeclSpec::TST_class:
Douglas Gregor86d9a522009-09-21 16:56:56 +00002883 Filter = &ResultBuilder::IsClassOrStruct;
Douglas Gregore6b1bb62010-08-11 21:23:17 +00002884 ContextKind = CodeCompletionContext::CCC_ClassOrStructTag;
Douglas Gregor374929f2009-09-18 15:37:17 +00002885 break;
2886
2887 default:
2888 assert(false && "Unknown type specifier kind in CodeCompleteTag");
2889 return;
2890 }
Douglas Gregor86d9a522009-09-21 16:56:56 +00002891
John McCall0d6b1642010-04-23 18:46:30 +00002892 ResultBuilder Results(*this);
Douglas Gregor5d2fc402010-01-14 03:27:13 +00002893 CodeCompletionDeclConsumer Consumer(Results, CurContext);
John McCall0d6b1642010-04-23 18:46:30 +00002894
2895 // First pass: look for tags.
2896 Results.setFilter(Filter);
Douglas Gregor8071e422010-08-15 06:18:01 +00002897 LookupVisibleDecls(S, LookupTagName, Consumer,
2898 CodeCompleter->includeGlobals());
John McCall0d6b1642010-04-23 18:46:30 +00002899
Douglas Gregor8071e422010-08-15 06:18:01 +00002900 if (CodeCompleter->includeGlobals()) {
2901 // Second pass: look for nested name specifiers.
2902 Results.setFilter(&ResultBuilder::IsNestedNameSpecifier);
2903 LookupVisibleDecls(S, LookupNestedNameSpecifierName, Consumer);
2904 }
Douglas Gregor86d9a522009-09-21 16:56:56 +00002905
Douglas Gregore6b1bb62010-08-11 21:23:17 +00002906 HandleCodeCompleteResults(this, CodeCompleter, ContextKind,
2907 Results.data(),Results.size());
Douglas Gregor374929f2009-09-18 15:37:17 +00002908}
2909
Douglas Gregor1a480c42010-08-27 17:35:51 +00002910void Sema::CodeCompleteTypeQualifiers(DeclSpec &DS) {
2911 ResultBuilder Results(*this);
2912 Results.EnterNewScope();
2913 if (!(DS.getTypeQualifiers() & DeclSpec::TQ_const))
2914 Results.AddResult("const");
2915 if (!(DS.getTypeQualifiers() & DeclSpec::TQ_volatile))
2916 Results.AddResult("volatile");
2917 if (getLangOptions().C99 &&
2918 !(DS.getTypeQualifiers() & DeclSpec::TQ_restrict))
2919 Results.AddResult("restrict");
2920 Results.ExitScope();
2921 HandleCodeCompleteResults(this, CodeCompleter,
2922 CodeCompletionContext::CCC_TypeQualifiers,
2923 Results.data(), Results.size());
2924}
2925
Douglas Gregor3e1005f2009-09-21 18:10:23 +00002926void Sema::CodeCompleteCase(Scope *S) {
John McCall781472f2010-08-25 08:40:02 +00002927 if (getCurFunction()->SwitchStack.empty() || !CodeCompleter)
Douglas Gregor3e1005f2009-09-21 18:10:23 +00002928 return;
2929
John McCall781472f2010-08-25 08:40:02 +00002930 SwitchStmt *Switch = getCurFunction()->SwitchStack.back();
Douglas Gregorf9578432010-07-28 21:50:18 +00002931 if (!Switch->getCond()->getType()->isEnumeralType()) {
Douglas Gregorfb629412010-08-23 21:17:50 +00002932 CodeCompleteExpressionData Data(Switch->getCond()->getType());
2933 Data.IntegralConstantExpression = true;
2934 CodeCompleteExpression(S, Data);
Douglas Gregor3e1005f2009-09-21 18:10:23 +00002935 return;
Douglas Gregorf9578432010-07-28 21:50:18 +00002936 }
Douglas Gregor3e1005f2009-09-21 18:10:23 +00002937
2938 // Code-complete the cases of a switch statement over an enumeration type
2939 // by providing the list of
2940 EnumDecl *Enum = Switch->getCond()->getType()->getAs<EnumType>()->getDecl();
2941
2942 // Determine which enumerators we have already seen in the switch statement.
2943 // FIXME: Ideally, we would also be able to look *past* the code-completion
2944 // token, in case we are code-completing in the middle of the switch and not
2945 // at the end. However, we aren't able to do so at the moment.
2946 llvm::SmallPtrSet<EnumConstantDecl *, 8> EnumeratorsSeen;
Douglas Gregorb9d0ef72009-09-21 19:57:38 +00002947 NestedNameSpecifier *Qualifier = 0;
Douglas Gregor3e1005f2009-09-21 18:10:23 +00002948 for (SwitchCase *SC = Switch->getSwitchCaseList(); SC;
2949 SC = SC->getNextSwitchCase()) {
2950 CaseStmt *Case = dyn_cast<CaseStmt>(SC);
2951 if (!Case)
2952 continue;
2953
2954 Expr *CaseVal = Case->getLHS()->IgnoreParenCasts();
2955 if (DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(CaseVal))
2956 if (EnumConstantDecl *Enumerator
2957 = dyn_cast<EnumConstantDecl>(DRE->getDecl())) {
2958 // We look into the AST of the case statement to determine which
2959 // enumerator was named. Alternatively, we could compute the value of
2960 // the integral constant expression, then compare it against the
2961 // values of each enumerator. However, value-based approach would not
2962 // work as well with C++ templates where enumerators declared within a
2963 // template are type- and value-dependent.
2964 EnumeratorsSeen.insert(Enumerator);
2965
Douglas Gregorb9d0ef72009-09-21 19:57:38 +00002966 // If this is a qualified-id, keep track of the nested-name-specifier
2967 // so that we can reproduce it as part of code completion, e.g.,
Douglas Gregor3e1005f2009-09-21 18:10:23 +00002968 //
2969 // switch (TagD.getKind()) {
2970 // case TagDecl::TK_enum:
2971 // break;
2972 // case XXX
2973 //
Douglas Gregorb9d0ef72009-09-21 19:57:38 +00002974 // At the XXX, our completions are TagDecl::TK_union,
Douglas Gregor3e1005f2009-09-21 18:10:23 +00002975 // TagDecl::TK_struct, and TagDecl::TK_class, rather than TK_union,
2976 // TK_struct, and TK_class.
Douglas Gregora2813ce2009-10-23 18:54:35 +00002977 Qualifier = DRE->getQualifier();
Douglas Gregor3e1005f2009-09-21 18:10:23 +00002978 }
2979 }
2980
Douglas Gregorb9d0ef72009-09-21 19:57:38 +00002981 if (getLangOptions().CPlusPlus && !Qualifier && EnumeratorsSeen.empty()) {
2982 // If there are no prior enumerators in C++, check whether we have to
2983 // qualify the names of the enumerators that we suggest, because they
2984 // may not be visible in this scope.
2985 Qualifier = getRequiredQualification(Context, CurContext,
2986 Enum->getDeclContext());
2987
2988 // FIXME: Scoped enums need to start with "EnumDecl" as the context!
2989 }
2990
Douglas Gregor3e1005f2009-09-21 18:10:23 +00002991 // Add any enumerators that have not yet been mentioned.
2992 ResultBuilder Results(*this);
2993 Results.EnterNewScope();
2994 for (EnumDecl::enumerator_iterator E = Enum->enumerator_begin(),
2995 EEnd = Enum->enumerator_end();
2996 E != EEnd; ++E) {
2997 if (EnumeratorsSeen.count(*E))
2998 continue;
2999
John McCall0a2c5e22010-08-25 06:19:51 +00003000 Results.AddResult(CodeCompletionResult(*E, Qualifier),
Douglas Gregor608300b2010-01-14 16:14:35 +00003001 CurContext, 0, false);
Douglas Gregor3e1005f2009-09-21 18:10:23 +00003002 }
3003 Results.ExitScope();
Douglas Gregor2f880e42010-04-06 20:02:15 +00003004
Douglas Gregor0c8296d2009-11-07 00:00:49 +00003005 if (CodeCompleter->includeMacros())
Douglas Gregorbca403c2010-01-13 23:51:12 +00003006 AddMacroResults(PP, Results);
Douglas Gregore6b1bb62010-08-11 21:23:17 +00003007 HandleCodeCompleteResults(this, CodeCompleter,
3008 CodeCompletionContext::CCC_Expression,
3009 Results.data(),Results.size());
Douglas Gregor3e1005f2009-09-21 18:10:23 +00003010}
3011
Douglas Gregor9c6a0e92009-09-22 15:41:20 +00003012namespace {
3013 struct IsBetterOverloadCandidate {
3014 Sema &S;
John McCall5769d612010-02-08 23:07:23 +00003015 SourceLocation Loc;
Douglas Gregor9c6a0e92009-09-22 15:41:20 +00003016
3017 public:
John McCall5769d612010-02-08 23:07:23 +00003018 explicit IsBetterOverloadCandidate(Sema &S, SourceLocation Loc)
3019 : S(S), Loc(Loc) { }
Douglas Gregor9c6a0e92009-09-22 15:41:20 +00003020
3021 bool
3022 operator()(const OverloadCandidate &X, const OverloadCandidate &Y) const {
John McCall120d63c2010-08-24 20:38:10 +00003023 return isBetterOverloadCandidate(S, X, Y, Loc);
Douglas Gregor9c6a0e92009-09-22 15:41:20 +00003024 }
3025 };
3026}
3027
Douglas Gregord28dcd72010-05-30 06:10:08 +00003028static bool anyNullArguments(Expr **Args, unsigned NumArgs) {
3029 if (NumArgs && !Args)
3030 return true;
3031
3032 for (unsigned I = 0; I != NumArgs; ++I)
3033 if (!Args[I])
3034 return true;
3035
3036 return false;
3037}
3038
Douglas Gregor9c6a0e92009-09-22 15:41:20 +00003039void Sema::CodeCompleteCall(Scope *S, ExprTy *FnIn,
3040 ExprTy **ArgsIn, unsigned NumArgs) {
3041 if (!CodeCompleter)
3042 return;
Douglas Gregoref96eac2009-12-11 19:06:04 +00003043
3044 // When we're code-completing for a call, we fall back to ordinary
3045 // name code-completion whenever we can't produce specific
3046 // results. We may want to revisit this strategy in the future,
3047 // e.g., by merging the two kinds of results.
3048
Douglas Gregor9c6a0e92009-09-22 15:41:20 +00003049 Expr *Fn = (Expr *)FnIn;
3050 Expr **Args = (Expr **)ArgsIn;
Douglas Gregoref96eac2009-12-11 19:06:04 +00003051
Douglas Gregor9c6a0e92009-09-22 15:41:20 +00003052 // Ignore type-dependent call expressions entirely.
Douglas Gregord28dcd72010-05-30 06:10:08 +00003053 if (!Fn || Fn->isTypeDependent() || anyNullArguments(Args, NumArgs) ||
Douglas Gregoref96eac2009-12-11 19:06:04 +00003054 Expr::hasAnyTypeDependentArguments(Args, NumArgs)) {
Douglas Gregore6b1bb62010-08-11 21:23:17 +00003055 CodeCompleteOrdinaryName(S, PCC_Expression);
Douglas Gregor9c6a0e92009-09-22 15:41:20 +00003056 return;
Douglas Gregoref96eac2009-12-11 19:06:04 +00003057 }
Douglas Gregor9c6a0e92009-09-22 15:41:20 +00003058
John McCall3b4294e2009-12-16 12:17:52 +00003059 // Build an overload candidate set based on the functions we find.
John McCall5769d612010-02-08 23:07:23 +00003060 SourceLocation Loc = Fn->getExprLoc();
3061 OverloadCandidateSet CandidateSet(Loc);
John McCall3b4294e2009-12-16 12:17:52 +00003062
Douglas Gregor9c6a0e92009-09-22 15:41:20 +00003063 // FIXME: What if we're calling something that isn't a function declaration?
3064 // FIXME: What if we're calling a pseudo-destructor?
3065 // FIXME: What if we're calling a member function?
3066
Douglas Gregorc0265402010-01-21 15:46:19 +00003067 typedef CodeCompleteConsumer::OverloadCandidate ResultCandidate;
3068 llvm::SmallVector<ResultCandidate, 8> Results;
3069
John McCall3b4294e2009-12-16 12:17:52 +00003070 Expr *NakedFn = Fn->IgnoreParenCasts();
3071 if (UnresolvedLookupExpr *ULE = dyn_cast<UnresolvedLookupExpr>(NakedFn))
3072 AddOverloadedCallCandidates(ULE, Args, NumArgs, CandidateSet,
3073 /*PartialOverloading=*/ true);
3074 else if (DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(NakedFn)) {
3075 FunctionDecl *FDecl = dyn_cast<FunctionDecl>(DRE->getDecl());
Douglas Gregorc0265402010-01-21 15:46:19 +00003076 if (FDecl) {
Douglas Gregord28dcd72010-05-30 06:10:08 +00003077 if (!getLangOptions().CPlusPlus ||
3078 !FDecl->getType()->getAs<FunctionProtoType>())
Douglas Gregorc0265402010-01-21 15:46:19 +00003079 Results.push_back(ResultCandidate(FDecl));
3080 else
John McCall86820f52010-01-26 01:37:31 +00003081 // FIXME: access?
John McCall9aa472c2010-03-19 07:35:19 +00003082 AddOverloadCandidate(FDecl, DeclAccessPair::make(FDecl, AS_none),
3083 Args, NumArgs, CandidateSet,
Douglas Gregorc27d6c52010-04-16 17:41:49 +00003084 false, /*PartialOverloading*/true);
Douglas Gregorc0265402010-01-21 15:46:19 +00003085 }
John McCall3b4294e2009-12-16 12:17:52 +00003086 }
Douglas Gregor9c6a0e92009-09-22 15:41:20 +00003087
Douglas Gregor5ac3bdb2010-05-30 01:49:25 +00003088 QualType ParamType;
3089
Douglas Gregorc0265402010-01-21 15:46:19 +00003090 if (!CandidateSet.empty()) {
3091 // Sort the overload candidate set by placing the best overloads first.
3092 std::stable_sort(CandidateSet.begin(), CandidateSet.end(),
John McCall5769d612010-02-08 23:07:23 +00003093 IsBetterOverloadCandidate(*this, Loc));
Douglas Gregor9c6a0e92009-09-22 15:41:20 +00003094
Douglas Gregorc0265402010-01-21 15:46:19 +00003095 // Add the remaining viable overload candidates as code-completion reslults.
3096 for (OverloadCandidateSet::iterator Cand = CandidateSet.begin(),
3097 CandEnd = CandidateSet.end();
3098 Cand != CandEnd; ++Cand) {
3099 if (Cand->Viable)
3100 Results.push_back(ResultCandidate(Cand->Function));
3101 }
Douglas Gregor5ac3bdb2010-05-30 01:49:25 +00003102
3103 // From the viable candidates, try to determine the type of this parameter.
3104 for (unsigned I = 0, N = Results.size(); I != N; ++I) {
3105 if (const FunctionType *FType = Results[I].getFunctionType())
3106 if (const FunctionProtoType *Proto = dyn_cast<FunctionProtoType>(FType))
3107 if (NumArgs < Proto->getNumArgs()) {
3108 if (ParamType.isNull())
3109 ParamType = Proto->getArgType(NumArgs);
3110 else if (!Context.hasSameUnqualifiedType(
3111 ParamType.getNonReferenceType(),
3112 Proto->getArgType(NumArgs).getNonReferenceType())) {
3113 ParamType = QualType();
3114 break;
3115 }
3116 }
3117 }
3118 } else {
3119 // Try to determine the parameter type from the type of the expression
3120 // being called.
3121 QualType FunctionType = Fn->getType();
3122 if (const PointerType *Ptr = FunctionType->getAs<PointerType>())
3123 FunctionType = Ptr->getPointeeType();
3124 else if (const BlockPointerType *BlockPtr
3125 = FunctionType->getAs<BlockPointerType>())
3126 FunctionType = BlockPtr->getPointeeType();
3127 else if (const MemberPointerType *MemPtr
3128 = FunctionType->getAs<MemberPointerType>())
3129 FunctionType = MemPtr->getPointeeType();
3130
3131 if (const FunctionProtoType *Proto
3132 = FunctionType->getAs<FunctionProtoType>()) {
3133 if (NumArgs < Proto->getNumArgs())
3134 ParamType = Proto->getArgType(NumArgs);
3135 }
Douglas Gregor9c6a0e92009-09-22 15:41:20 +00003136 }
Douglas Gregoref96eac2009-12-11 19:06:04 +00003137
Douglas Gregor5ac3bdb2010-05-30 01:49:25 +00003138 if (ParamType.isNull())
Douglas Gregore6b1bb62010-08-11 21:23:17 +00003139 CodeCompleteOrdinaryName(S, PCC_Expression);
Douglas Gregor5ac3bdb2010-05-30 01:49:25 +00003140 else
3141 CodeCompleteExpression(S, ParamType);
3142
Douglas Gregor2e4c7a52010-04-06 20:19:47 +00003143 if (!Results.empty())
Douglas Gregoref96eac2009-12-11 19:06:04 +00003144 CodeCompleter->ProcessOverloadCandidates(*this, NumArgs, Results.data(),
3145 Results.size());
Douglas Gregor9c6a0e92009-09-22 15:41:20 +00003146}
3147
John McCalld226f652010-08-21 09:40:31 +00003148void Sema::CodeCompleteInitializer(Scope *S, Decl *D) {
3149 ValueDecl *VD = dyn_cast_or_null<ValueDecl>(D);
Douglas Gregor5ac3bdb2010-05-30 01:49:25 +00003150 if (!VD) {
Douglas Gregore6b1bb62010-08-11 21:23:17 +00003151 CodeCompleteOrdinaryName(S, PCC_Expression);
Douglas Gregor5ac3bdb2010-05-30 01:49:25 +00003152 return;
3153 }
3154
3155 CodeCompleteExpression(S, VD->getType());
3156}
3157
3158void Sema::CodeCompleteReturn(Scope *S) {
3159 QualType ResultType;
3160 if (isa<BlockDecl>(CurContext)) {
3161 if (BlockScopeInfo *BSI = getCurBlock())
3162 ResultType = BSI->ReturnType;
3163 } else if (FunctionDecl *Function = dyn_cast<FunctionDecl>(CurContext))
3164 ResultType = Function->getResultType();
3165 else if (ObjCMethodDecl *Method = dyn_cast<ObjCMethodDecl>(CurContext))
3166 ResultType = Method->getResultType();
3167
3168 if (ResultType.isNull())
Douglas Gregore6b1bb62010-08-11 21:23:17 +00003169 CodeCompleteOrdinaryName(S, PCC_Expression);
Douglas Gregor5ac3bdb2010-05-30 01:49:25 +00003170 else
3171 CodeCompleteExpression(S, ResultType);
3172}
3173
3174void Sema::CodeCompleteAssignmentRHS(Scope *S, ExprTy *LHS) {
3175 if (LHS)
3176 CodeCompleteExpression(S, static_cast<Expr *>(LHS)->getType());
3177 else
Douglas Gregore6b1bb62010-08-11 21:23:17 +00003178 CodeCompleteOrdinaryName(S, PCC_Expression);
Douglas Gregor5ac3bdb2010-05-30 01:49:25 +00003179}
3180
Jeffrey Yasskin9ab14542010-04-08 16:38:48 +00003181void Sema::CodeCompleteQualifiedId(Scope *S, CXXScopeSpec &SS,
Douglas Gregor81b747b2009-09-17 21:32:03 +00003182 bool EnteringContext) {
3183 if (!SS.getScopeRep() || !CodeCompleter)
3184 return;
3185
Douglas Gregor86d9a522009-09-21 16:56:56 +00003186 DeclContext *Ctx = computeDeclContext(SS, EnteringContext);
3187 if (!Ctx)
3188 return;
Douglas Gregord1cd31a2009-12-11 18:28:39 +00003189
3190 // Try to instantiate any non-dependent declaration contexts before
3191 // we look in them.
John McCall77bb1aa2010-05-01 00:40:08 +00003192 if (!isDependentScopeSpecifier(SS) && RequireCompleteDeclContext(SS, Ctx))
Douglas Gregord1cd31a2009-12-11 18:28:39 +00003193 return;
3194
Douglas Gregor86d9a522009-09-21 16:56:56 +00003195 ResultBuilder Results(*this);
Douglas Gregor86d9a522009-09-21 16:56:56 +00003196
Douglas Gregorf6961522010-08-27 21:18:54 +00003197 Results.EnterNewScope();
Douglas Gregor86d9a522009-09-21 16:56:56 +00003198 // The "template" keyword can follow "::" in the grammar, but only
3199 // put it into the grammar if the nested-name-specifier is dependent.
3200 NestedNameSpecifier *NNS = (NestedNameSpecifier *)SS.getScopeRep();
3201 if (!Results.empty() && NNS->isDependent())
Douglas Gregora4477812010-01-14 16:01:26 +00003202 Results.AddResult("template");
Douglas Gregorf6961522010-08-27 21:18:54 +00003203
3204 // Add calls to overridden virtual functions, if there are any.
3205 //
3206 // FIXME: This isn't wonderful, because we don't know whether we're actually
3207 // in a context that permits expressions. This is a general issue with
3208 // qualified-id completions.
3209 if (!EnteringContext)
3210 MaybeAddOverrideCalls(*this, Ctx, Results);
3211 Results.ExitScope();
Douglas Gregor86d9a522009-09-21 16:56:56 +00003212
Douglas Gregorf6961522010-08-27 21:18:54 +00003213 CodeCompletionDeclConsumer Consumer(Results, CurContext);
3214 LookupVisibleDecls(Ctx, LookupOrdinaryName, Consumer);
3215
Douglas Gregore6b1bb62010-08-11 21:23:17 +00003216 HandleCodeCompleteResults(this, CodeCompleter,
Douglas Gregorf6961522010-08-27 21:18:54 +00003217 CodeCompletionContext::CCC_Name,
Douglas Gregore6b1bb62010-08-11 21:23:17 +00003218 Results.data(),Results.size());
Douglas Gregor81b747b2009-09-17 21:32:03 +00003219}
Douglas Gregor49f40bd2009-09-18 19:03:04 +00003220
3221void Sema::CodeCompleteUsing(Scope *S) {
3222 if (!CodeCompleter)
3223 return;
3224
Douglas Gregor86d9a522009-09-21 16:56:56 +00003225 ResultBuilder Results(*this, &ResultBuilder::IsNestedNameSpecifier);
Douglas Gregor8e0a0e42009-09-22 23:31:26 +00003226 Results.EnterNewScope();
Douglas Gregor86d9a522009-09-21 16:56:56 +00003227
3228 // If we aren't in class scope, we could see the "namespace" keyword.
3229 if (!S->isClassScope())
John McCall0a2c5e22010-08-25 06:19:51 +00003230 Results.AddResult(CodeCompletionResult("namespace"));
Douglas Gregor86d9a522009-09-21 16:56:56 +00003231
3232 // After "using", we can see anything that would start a
3233 // nested-name-specifier.
Douglas Gregor5d2fc402010-01-14 03:27:13 +00003234 CodeCompletionDeclConsumer Consumer(Results, CurContext);
Douglas Gregor8071e422010-08-15 06:18:01 +00003235 LookupVisibleDecls(S, LookupOrdinaryName, Consumer,
3236 CodeCompleter->includeGlobals());
Douglas Gregor8e0a0e42009-09-22 23:31:26 +00003237 Results.ExitScope();
Douglas Gregor86d9a522009-09-21 16:56:56 +00003238
Douglas Gregore6b1bb62010-08-11 21:23:17 +00003239 HandleCodeCompleteResults(this, CodeCompleter,
3240 CodeCompletionContext::CCC_Other,
3241 Results.data(),Results.size());
Douglas Gregor49f40bd2009-09-18 19:03:04 +00003242}
3243
3244void Sema::CodeCompleteUsingDirective(Scope *S) {
3245 if (!CodeCompleter)
3246 return;
3247
Douglas Gregor86d9a522009-09-21 16:56:56 +00003248 // After "using namespace", we expect to see a namespace name or namespace
3249 // alias.
3250 ResultBuilder Results(*this, &ResultBuilder::IsNamespaceOrAlias);
Douglas Gregor8e0a0e42009-09-22 23:31:26 +00003251 Results.EnterNewScope();
Douglas Gregor5d2fc402010-01-14 03:27:13 +00003252 CodeCompletionDeclConsumer Consumer(Results, CurContext);
Douglas Gregor8071e422010-08-15 06:18:01 +00003253 LookupVisibleDecls(S, LookupOrdinaryName, Consumer,
3254 CodeCompleter->includeGlobals());
Douglas Gregor8e0a0e42009-09-22 23:31:26 +00003255 Results.ExitScope();
Douglas Gregore6b1bb62010-08-11 21:23:17 +00003256 HandleCodeCompleteResults(this, CodeCompleter,
Douglas Gregor8071e422010-08-15 06:18:01 +00003257 CodeCompletionContext::CCC_Namespace,
Douglas Gregore6b1bb62010-08-11 21:23:17 +00003258 Results.data(),Results.size());
Douglas Gregor49f40bd2009-09-18 19:03:04 +00003259}
3260
3261void Sema::CodeCompleteNamespaceDecl(Scope *S) {
3262 if (!CodeCompleter)
3263 return;
3264
Douglas Gregor86d9a522009-09-21 16:56:56 +00003265 ResultBuilder Results(*this, &ResultBuilder::IsNamespace);
3266 DeclContext *Ctx = (DeclContext *)S->getEntity();
3267 if (!S->getParent())
3268 Ctx = Context.getTranslationUnitDecl();
3269
3270 if (Ctx && Ctx->isFileContext()) {
3271 // We only want to see those namespaces that have already been defined
3272 // within this scope, because its likely that the user is creating an
3273 // extended namespace declaration. Keep track of the most recent
3274 // definition of each namespace.
3275 std::map<NamespaceDecl *, NamespaceDecl *> OrigToLatest;
3276 for (DeclContext::specific_decl_iterator<NamespaceDecl>
3277 NS(Ctx->decls_begin()), NSEnd(Ctx->decls_end());
3278 NS != NSEnd; ++NS)
3279 OrigToLatest[NS->getOriginalNamespace()] = *NS;
3280
3281 // Add the most recent definition (or extended definition) of each
3282 // namespace to the list of results.
Douglas Gregor8e0a0e42009-09-22 23:31:26 +00003283 Results.EnterNewScope();
Douglas Gregor86d9a522009-09-21 16:56:56 +00003284 for (std::map<NamespaceDecl *, NamespaceDecl *>::iterator
3285 NS = OrigToLatest.begin(), NSEnd = OrigToLatest.end();
3286 NS != NSEnd; ++NS)
John McCall0a2c5e22010-08-25 06:19:51 +00003287 Results.AddResult(CodeCompletionResult(NS->second, 0),
Douglas Gregor608300b2010-01-14 16:14:35 +00003288 CurContext, 0, false);
Douglas Gregor8e0a0e42009-09-22 23:31:26 +00003289 Results.ExitScope();
Douglas Gregor86d9a522009-09-21 16:56:56 +00003290 }
3291
Douglas Gregore6b1bb62010-08-11 21:23:17 +00003292 HandleCodeCompleteResults(this, CodeCompleter,
3293 CodeCompletionContext::CCC_Other,
3294 Results.data(),Results.size());
Douglas Gregor49f40bd2009-09-18 19:03:04 +00003295}
3296
3297void Sema::CodeCompleteNamespaceAliasDecl(Scope *S) {
3298 if (!CodeCompleter)
3299 return;
3300
Douglas Gregor86d9a522009-09-21 16:56:56 +00003301 // After "namespace", we expect to see a namespace or alias.
3302 ResultBuilder Results(*this, &ResultBuilder::IsNamespaceOrAlias);
Douglas Gregor5d2fc402010-01-14 03:27:13 +00003303 CodeCompletionDeclConsumer Consumer(Results, CurContext);
Douglas Gregor8071e422010-08-15 06:18:01 +00003304 LookupVisibleDecls(S, LookupOrdinaryName, Consumer,
3305 CodeCompleter->includeGlobals());
Douglas Gregore6b1bb62010-08-11 21:23:17 +00003306 HandleCodeCompleteResults(this, CodeCompleter,
Douglas Gregor8071e422010-08-15 06:18:01 +00003307 CodeCompletionContext::CCC_Namespace,
Douglas Gregore6b1bb62010-08-11 21:23:17 +00003308 Results.data(),Results.size());
Douglas Gregor49f40bd2009-09-18 19:03:04 +00003309}
3310
Douglas Gregored8d3222009-09-18 20:05:18 +00003311void Sema::CodeCompleteOperatorName(Scope *S) {
3312 if (!CodeCompleter)
3313 return;
Douglas Gregor86d9a522009-09-21 16:56:56 +00003314
John McCall0a2c5e22010-08-25 06:19:51 +00003315 typedef CodeCompletionResult Result;
Douglas Gregor86d9a522009-09-21 16:56:56 +00003316 ResultBuilder Results(*this, &ResultBuilder::IsType);
Douglas Gregor8e0a0e42009-09-22 23:31:26 +00003317 Results.EnterNewScope();
Douglas Gregored8d3222009-09-18 20:05:18 +00003318
Douglas Gregor86d9a522009-09-21 16:56:56 +00003319 // Add the names of overloadable operators.
3320#define OVERLOADED_OPERATOR(Name,Spelling,Token,Unary,Binary,MemberOnly) \
3321 if (std::strcmp(Spelling, "?")) \
Douglas Gregora4477812010-01-14 16:01:26 +00003322 Results.AddResult(Result(Spelling));
Douglas Gregor86d9a522009-09-21 16:56:56 +00003323#include "clang/Basic/OperatorKinds.def"
3324
3325 // Add any type names visible from the current scope
Douglas Gregor45bcd432010-01-14 03:21:49 +00003326 Results.allowNestedNameSpecifiers();
Douglas Gregor5d2fc402010-01-14 03:27:13 +00003327 CodeCompletionDeclConsumer Consumer(Results, CurContext);
Douglas Gregor8071e422010-08-15 06:18:01 +00003328 LookupVisibleDecls(S, LookupOrdinaryName, Consumer,
3329 CodeCompleter->includeGlobals());
Douglas Gregor86d9a522009-09-21 16:56:56 +00003330
3331 // Add any type specifiers
Douglas Gregorbca403c2010-01-13 23:51:12 +00003332 AddTypeSpecifierResults(getLangOptions(), Results);
Douglas Gregor8e0a0e42009-09-22 23:31:26 +00003333 Results.ExitScope();
Douglas Gregor86d9a522009-09-21 16:56:56 +00003334
Douglas Gregore6b1bb62010-08-11 21:23:17 +00003335 HandleCodeCompleteResults(this, CodeCompleter,
Douglas Gregor8071e422010-08-15 06:18:01 +00003336 CodeCompletionContext::CCC_Type,
Douglas Gregore6b1bb62010-08-11 21:23:17 +00003337 Results.data(),Results.size());
Douglas Gregored8d3222009-09-18 20:05:18 +00003338}
Douglas Gregor49f40bd2009-09-18 19:03:04 +00003339
Douglas Gregor0133f522010-08-28 00:00:50 +00003340void Sema::CodeCompleteConstructorInitializer(Decl *ConstructorD,
3341 CXXBaseOrMemberInitializer** Initializers,
3342 unsigned NumInitializers) {
3343 CXXConstructorDecl *Constructor
3344 = static_cast<CXXConstructorDecl *>(ConstructorD);
3345 if (!Constructor)
3346 return;
3347
3348 ResultBuilder Results(*this);
3349 Results.EnterNewScope();
3350
3351 // Fill in any already-initialized fields or base classes.
3352 llvm::SmallPtrSet<FieldDecl *, 4> InitializedFields;
3353 llvm::SmallPtrSet<CanQualType, 4> InitializedBases;
3354 for (unsigned I = 0; I != NumInitializers; ++I) {
3355 if (Initializers[I]->isBaseInitializer())
3356 InitializedBases.insert(
3357 Context.getCanonicalType(QualType(Initializers[I]->getBaseClass(), 0)));
3358 else
3359 InitializedFields.insert(cast<FieldDecl>(Initializers[I]->getMember()));
3360 }
3361
3362 // Add completions for base classes.
Douglas Gregor0c431c82010-08-29 19:27:27 +00003363 bool SawLastInitializer = (NumInitializers == 0);
Douglas Gregor0133f522010-08-28 00:00:50 +00003364 CXXRecordDecl *ClassDecl = Constructor->getParent();
3365 for (CXXRecordDecl::base_class_iterator Base = ClassDecl->bases_begin(),
3366 BaseEnd = ClassDecl->bases_end();
3367 Base != BaseEnd; ++Base) {
Douglas Gregor0c431c82010-08-29 19:27:27 +00003368 if (!InitializedBases.insert(Context.getCanonicalType(Base->getType()))) {
3369 SawLastInitializer
3370 = NumInitializers > 0 &&
3371 Initializers[NumInitializers - 1]->isBaseInitializer() &&
3372 Context.hasSameUnqualifiedType(Base->getType(),
3373 QualType(Initializers[NumInitializers - 1]->getBaseClass(), 0));
Douglas Gregor0133f522010-08-28 00:00:50 +00003374 continue;
Douglas Gregor0c431c82010-08-29 19:27:27 +00003375 }
Douglas Gregor0133f522010-08-28 00:00:50 +00003376
3377 CodeCompletionString *Pattern = new CodeCompletionString;
3378 Pattern->AddTypedTextChunk(
3379 Base->getType().getAsString(Context.PrintingPolicy));
3380 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
3381 Pattern->AddPlaceholderChunk("args");
3382 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
Douglas Gregor0c431c82010-08-29 19:27:27 +00003383 Results.AddResult(CodeCompletionResult(Pattern,
3384 SawLastInitializer? CCP_NextInitializer
3385 : CCP_MemberDeclaration));
3386 SawLastInitializer = false;
Douglas Gregor0133f522010-08-28 00:00:50 +00003387 }
3388
3389 // Add completions for virtual base classes.
3390 for (CXXRecordDecl::base_class_iterator Base = ClassDecl->vbases_begin(),
3391 BaseEnd = ClassDecl->vbases_end();
3392 Base != BaseEnd; ++Base) {
Douglas Gregor0c431c82010-08-29 19:27:27 +00003393 if (!InitializedBases.insert(Context.getCanonicalType(Base->getType()))) {
3394 SawLastInitializer
3395 = NumInitializers > 0 &&
3396 Initializers[NumInitializers - 1]->isBaseInitializer() &&
3397 Context.hasSameUnqualifiedType(Base->getType(),
3398 QualType(Initializers[NumInitializers - 1]->getBaseClass(), 0));
Douglas Gregor0133f522010-08-28 00:00:50 +00003399 continue;
Douglas Gregor0c431c82010-08-29 19:27:27 +00003400 }
Douglas Gregor0133f522010-08-28 00:00:50 +00003401
3402 CodeCompletionString *Pattern = new CodeCompletionString;
3403 Pattern->AddTypedTextChunk(
3404 Base->getType().getAsString(Context.PrintingPolicy));
3405 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
3406 Pattern->AddPlaceholderChunk("args");
3407 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
Douglas Gregor0c431c82010-08-29 19:27:27 +00003408 Results.AddResult(CodeCompletionResult(Pattern,
3409 SawLastInitializer? CCP_NextInitializer
3410 : CCP_MemberDeclaration));
3411 SawLastInitializer = false;
Douglas Gregor0133f522010-08-28 00:00:50 +00003412 }
3413
3414 // Add completions for members.
3415 for (CXXRecordDecl::field_iterator Field = ClassDecl->field_begin(),
3416 FieldEnd = ClassDecl->field_end();
3417 Field != FieldEnd; ++Field) {
Douglas Gregor0c431c82010-08-29 19:27:27 +00003418 if (!InitializedFields.insert(cast<FieldDecl>(Field->getCanonicalDecl()))) {
3419 SawLastInitializer
3420 = NumInitializers > 0 &&
3421 Initializers[NumInitializers - 1]->isMemberInitializer() &&
3422 Initializers[NumInitializers - 1]->getMember() == *Field;
Douglas Gregor0133f522010-08-28 00:00:50 +00003423 continue;
Douglas Gregor0c431c82010-08-29 19:27:27 +00003424 }
Douglas Gregor0133f522010-08-28 00:00:50 +00003425
3426 if (!Field->getDeclName())
3427 continue;
3428
3429 CodeCompletionString *Pattern = new CodeCompletionString;
3430 Pattern->AddTypedTextChunk(Field->getIdentifier()->getName());
3431 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
3432 Pattern->AddPlaceholderChunk("args");
3433 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
Douglas Gregor0c431c82010-08-29 19:27:27 +00003434 Results.AddResult(CodeCompletionResult(Pattern,
3435 SawLastInitializer? CCP_NextInitializer
3436 : CCP_MemberDeclaration));
3437 SawLastInitializer = false;
Douglas Gregor0133f522010-08-28 00:00:50 +00003438 }
3439 Results.ExitScope();
3440
3441 HandleCodeCompleteResults(this, CodeCompleter,
3442 CodeCompletionContext::CCC_Name,
3443 Results.data(), Results.size());
3444}
3445
Douglas Gregorb6ac2452010-01-13 21:24:21 +00003446// Macro that expands to @Keyword or Keyword, depending on whether NeedAt is
3447// true or false.
3448#define OBJC_AT_KEYWORD_NAME(NeedAt,Keyword) NeedAt? "@" #Keyword : #Keyword
Douglas Gregorbca403c2010-01-13 23:51:12 +00003449static void AddObjCImplementationResults(const LangOptions &LangOpts,
Douglas Gregorb6ac2452010-01-13 21:24:21 +00003450 ResultBuilder &Results,
3451 bool NeedAt) {
John McCall0a2c5e22010-08-25 06:19:51 +00003452 typedef CodeCompletionResult Result;
Douglas Gregorb6ac2452010-01-13 21:24:21 +00003453 // Since we have an implementation, we can end it.
Douglas Gregora4477812010-01-14 16:01:26 +00003454 Results.AddResult(Result(OBJC_AT_KEYWORD_NAME(NeedAt,end)));
Douglas Gregorb6ac2452010-01-13 21:24:21 +00003455
3456 CodeCompletionString *Pattern = 0;
3457 if (LangOpts.ObjC2) {
3458 // @dynamic
3459 Pattern = new CodeCompletionString;
3460 Pattern->AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt,dynamic));
3461 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
3462 Pattern->AddPlaceholderChunk("property");
Douglas Gregora4477812010-01-14 16:01:26 +00003463 Results.AddResult(Result(Pattern));
Douglas Gregorb6ac2452010-01-13 21:24:21 +00003464
3465 // @synthesize
3466 Pattern = new CodeCompletionString;
3467 Pattern->AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt,synthesize));
3468 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
3469 Pattern->AddPlaceholderChunk("property");
Douglas Gregora4477812010-01-14 16:01:26 +00003470 Results.AddResult(Result(Pattern));
Douglas Gregorb6ac2452010-01-13 21:24:21 +00003471 }
3472}
3473
Douglas Gregorbca403c2010-01-13 23:51:12 +00003474static void AddObjCInterfaceResults(const LangOptions &LangOpts,
Douglas Gregorb6ac2452010-01-13 21:24:21 +00003475 ResultBuilder &Results,
3476 bool NeedAt) {
John McCall0a2c5e22010-08-25 06:19:51 +00003477 typedef CodeCompletionResult Result;
Douglas Gregorb6ac2452010-01-13 21:24:21 +00003478
3479 // Since we have an interface or protocol, we can end it.
Douglas Gregora4477812010-01-14 16:01:26 +00003480 Results.AddResult(Result(OBJC_AT_KEYWORD_NAME(NeedAt,end)));
Douglas Gregorb6ac2452010-01-13 21:24:21 +00003481
3482 if (LangOpts.ObjC2) {
3483 // @property
Douglas Gregora4477812010-01-14 16:01:26 +00003484 Results.AddResult(Result(OBJC_AT_KEYWORD_NAME(NeedAt,property)));
Douglas Gregorb6ac2452010-01-13 21:24:21 +00003485
3486 // @required
Douglas Gregora4477812010-01-14 16:01:26 +00003487 Results.AddResult(Result(OBJC_AT_KEYWORD_NAME(NeedAt,required)));
Douglas Gregorb6ac2452010-01-13 21:24:21 +00003488
3489 // @optional
Douglas Gregora4477812010-01-14 16:01:26 +00003490 Results.AddResult(Result(OBJC_AT_KEYWORD_NAME(NeedAt,optional)));
Douglas Gregorb6ac2452010-01-13 21:24:21 +00003491 }
3492}
3493
Douglas Gregorbca403c2010-01-13 23:51:12 +00003494static void AddObjCTopLevelResults(ResultBuilder &Results, bool NeedAt) {
John McCall0a2c5e22010-08-25 06:19:51 +00003495 typedef CodeCompletionResult Result;
Douglas Gregorb6ac2452010-01-13 21:24:21 +00003496 CodeCompletionString *Pattern = 0;
3497
3498 // @class name ;
3499 Pattern = new CodeCompletionString;
3500 Pattern->AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt,class));
3501 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
Douglas Gregorc8bddde2010-05-28 00:22:41 +00003502 Pattern->AddPlaceholderChunk("name");
Douglas Gregora4477812010-01-14 16:01:26 +00003503 Results.AddResult(Result(Pattern));
Douglas Gregorb6ac2452010-01-13 21:24:21 +00003504
Douglas Gregorc8bddde2010-05-28 00:22:41 +00003505 if (Results.includeCodePatterns()) {
3506 // @interface name
3507 // FIXME: Could introduce the whole pattern, including superclasses and
3508 // such.
3509 Pattern = new CodeCompletionString;
3510 Pattern->AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt,interface));
3511 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
3512 Pattern->AddPlaceholderChunk("class");
3513 Results.AddResult(Result(Pattern));
Douglas Gregorb6ac2452010-01-13 21:24:21 +00003514
Douglas Gregorc8bddde2010-05-28 00:22:41 +00003515 // @protocol name
3516 Pattern = new CodeCompletionString;
3517 Pattern->AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt,protocol));
3518 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
3519 Pattern->AddPlaceholderChunk("protocol");
3520 Results.AddResult(Result(Pattern));
3521
3522 // @implementation name
3523 Pattern = new CodeCompletionString;
3524 Pattern->AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt,implementation));
3525 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
3526 Pattern->AddPlaceholderChunk("class");
3527 Results.AddResult(Result(Pattern));
3528 }
Douglas Gregorb6ac2452010-01-13 21:24:21 +00003529
3530 // @compatibility_alias name
3531 Pattern = new CodeCompletionString;
3532 Pattern->AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt,compatibility_alias));
3533 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
3534 Pattern->AddPlaceholderChunk("alias");
3535 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
3536 Pattern->AddPlaceholderChunk("class");
Douglas Gregora4477812010-01-14 16:01:26 +00003537 Results.AddResult(Result(Pattern));
Douglas Gregorb6ac2452010-01-13 21:24:21 +00003538}
3539
John McCalld226f652010-08-21 09:40:31 +00003540void Sema::CodeCompleteObjCAtDirective(Scope *S, Decl *ObjCImpDecl,
Douglas Gregorc464ae82009-12-07 09:27:33 +00003541 bool InInterface) {
John McCall0a2c5e22010-08-25 06:19:51 +00003542 typedef CodeCompletionResult Result;
Douglas Gregorc464ae82009-12-07 09:27:33 +00003543 ResultBuilder Results(*this);
3544 Results.EnterNewScope();
Douglas Gregorb6ac2452010-01-13 21:24:21 +00003545 if (ObjCImpDecl)
Douglas Gregorbca403c2010-01-13 23:51:12 +00003546 AddObjCImplementationResults(getLangOptions(), Results, false);
Douglas Gregorb6ac2452010-01-13 21:24:21 +00003547 else if (InInterface)
Douglas Gregorbca403c2010-01-13 23:51:12 +00003548 AddObjCInterfaceResults(getLangOptions(), Results, false);
Douglas Gregorb6ac2452010-01-13 21:24:21 +00003549 else
Douglas Gregorbca403c2010-01-13 23:51:12 +00003550 AddObjCTopLevelResults(Results, false);
Douglas Gregorc464ae82009-12-07 09:27:33 +00003551 Results.ExitScope();
Douglas Gregore6b1bb62010-08-11 21:23:17 +00003552 HandleCodeCompleteResults(this, CodeCompleter,
3553 CodeCompletionContext::CCC_Other,
3554 Results.data(),Results.size());
Douglas Gregorc464ae82009-12-07 09:27:33 +00003555}
3556
Douglas Gregorbca403c2010-01-13 23:51:12 +00003557static void AddObjCExpressionResults(ResultBuilder &Results, bool NeedAt) {
John McCall0a2c5e22010-08-25 06:19:51 +00003558 typedef CodeCompletionResult Result;
Douglas Gregor9a0c85e2009-12-07 09:51:25 +00003559 CodeCompletionString *Pattern = 0;
3560
3561 // @encode ( type-name )
3562 Pattern = new CodeCompletionString;
Douglas Gregorb6ac2452010-01-13 21:24:21 +00003563 Pattern->AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt,encode));
Douglas Gregor9a0c85e2009-12-07 09:51:25 +00003564 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
3565 Pattern->AddPlaceholderChunk("type-name");
3566 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
Douglas Gregora4477812010-01-14 16:01:26 +00003567 Results.AddResult(Result(Pattern));
Douglas Gregor9a0c85e2009-12-07 09:51:25 +00003568
3569 // @protocol ( protocol-name )
3570 Pattern = new CodeCompletionString;
Douglas Gregorb6ac2452010-01-13 21:24:21 +00003571 Pattern->AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt,protocol));
Douglas Gregor9a0c85e2009-12-07 09:51:25 +00003572 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
3573 Pattern->AddPlaceholderChunk("protocol-name");
3574 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
Douglas Gregora4477812010-01-14 16:01:26 +00003575 Results.AddResult(Result(Pattern));
Douglas Gregor9a0c85e2009-12-07 09:51:25 +00003576
3577 // @selector ( selector )
3578 Pattern = new CodeCompletionString;
Douglas Gregorb6ac2452010-01-13 21:24:21 +00003579 Pattern->AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt,selector));
Douglas Gregor9a0c85e2009-12-07 09:51:25 +00003580 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
3581 Pattern->AddPlaceholderChunk("selector");
3582 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
Douglas Gregora4477812010-01-14 16:01:26 +00003583 Results.AddResult(Result(Pattern));
Douglas Gregor9a0c85e2009-12-07 09:51:25 +00003584}
3585
Douglas Gregorbca403c2010-01-13 23:51:12 +00003586static void AddObjCStatementResults(ResultBuilder &Results, bool NeedAt) {
John McCall0a2c5e22010-08-25 06:19:51 +00003587 typedef CodeCompletionResult Result;
Douglas Gregor9a0c85e2009-12-07 09:51:25 +00003588 CodeCompletionString *Pattern = 0;
Douglas Gregorb6ac2452010-01-13 21:24:21 +00003589
Douglas Gregorc8bddde2010-05-28 00:22:41 +00003590 if (Results.includeCodePatterns()) {
3591 // @try { statements } @catch ( declaration ) { statements } @finally
3592 // { statements }
3593 Pattern = new CodeCompletionString;
3594 Pattern->AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt,try));
3595 Pattern->AddChunk(CodeCompletionString::CK_LeftBrace);
3596 Pattern->AddPlaceholderChunk("statements");
3597 Pattern->AddChunk(CodeCompletionString::CK_RightBrace);
3598 Pattern->AddTextChunk("@catch");
3599 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
3600 Pattern->AddPlaceholderChunk("parameter");
3601 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
3602 Pattern->AddChunk(CodeCompletionString::CK_LeftBrace);
3603 Pattern->AddPlaceholderChunk("statements");
3604 Pattern->AddChunk(CodeCompletionString::CK_RightBrace);
3605 Pattern->AddTextChunk("@finally");
3606 Pattern->AddChunk(CodeCompletionString::CK_LeftBrace);
3607 Pattern->AddPlaceholderChunk("statements");
3608 Pattern->AddChunk(CodeCompletionString::CK_RightBrace);
3609 Results.AddResult(Result(Pattern));
3610 }
Douglas Gregorb6ac2452010-01-13 21:24:21 +00003611
Douglas Gregor9a0c85e2009-12-07 09:51:25 +00003612 // @throw
3613 Pattern = new CodeCompletionString;
Douglas Gregorb6ac2452010-01-13 21:24:21 +00003614 Pattern->AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt,throw));
Douglas Gregor834389b2010-01-12 06:38:28 +00003615 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
Douglas Gregor9a0c85e2009-12-07 09:51:25 +00003616 Pattern->AddPlaceholderChunk("expression");
Douglas Gregora4477812010-01-14 16:01:26 +00003617 Results.AddResult(Result(Pattern));
Douglas Gregorb6ac2452010-01-13 21:24:21 +00003618
Douglas Gregorc8bddde2010-05-28 00:22:41 +00003619 if (Results.includeCodePatterns()) {
3620 // @synchronized ( expression ) { statements }
3621 Pattern = new CodeCompletionString;
3622 Pattern->AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt,synchronized));
3623 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
3624 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
3625 Pattern->AddPlaceholderChunk("expression");
3626 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
3627 Pattern->AddChunk(CodeCompletionString::CK_LeftBrace);
3628 Pattern->AddPlaceholderChunk("statements");
3629 Pattern->AddChunk(CodeCompletionString::CK_RightBrace);
3630 Results.AddResult(Result(Pattern));
3631 }
Douglas Gregorb6ac2452010-01-13 21:24:21 +00003632}
Douglas Gregor9a0c85e2009-12-07 09:51:25 +00003633
Douglas Gregorbca403c2010-01-13 23:51:12 +00003634static void AddObjCVisibilityResults(const LangOptions &LangOpts,
Douglas Gregorc38c3e12010-01-13 21:54:15 +00003635 ResultBuilder &Results,
3636 bool NeedAt) {
John McCall0a2c5e22010-08-25 06:19:51 +00003637 typedef CodeCompletionResult Result;
Douglas Gregora4477812010-01-14 16:01:26 +00003638 Results.AddResult(Result(OBJC_AT_KEYWORD_NAME(NeedAt,private)));
3639 Results.AddResult(Result(OBJC_AT_KEYWORD_NAME(NeedAt,protected)));
3640 Results.AddResult(Result(OBJC_AT_KEYWORD_NAME(NeedAt,public)));
Douglas Gregorc38c3e12010-01-13 21:54:15 +00003641 if (LangOpts.ObjC2)
Douglas Gregora4477812010-01-14 16:01:26 +00003642 Results.AddResult(Result(OBJC_AT_KEYWORD_NAME(NeedAt,package)));
Douglas Gregorc38c3e12010-01-13 21:54:15 +00003643}
3644
3645void Sema::CodeCompleteObjCAtVisibility(Scope *S) {
3646 ResultBuilder Results(*this);
3647 Results.EnterNewScope();
Douglas Gregorbca403c2010-01-13 23:51:12 +00003648 AddObjCVisibilityResults(getLangOptions(), Results, false);
Douglas Gregorc38c3e12010-01-13 21:54:15 +00003649 Results.ExitScope();
Douglas Gregore6b1bb62010-08-11 21:23:17 +00003650 HandleCodeCompleteResults(this, CodeCompleter,
3651 CodeCompletionContext::CCC_Other,
3652 Results.data(),Results.size());
Douglas Gregorc38c3e12010-01-13 21:54:15 +00003653}
3654
3655void Sema::CodeCompleteObjCAtStatement(Scope *S) {
Douglas Gregorb6ac2452010-01-13 21:24:21 +00003656 ResultBuilder Results(*this);
3657 Results.EnterNewScope();
Douglas Gregorbca403c2010-01-13 23:51:12 +00003658 AddObjCStatementResults(Results, false);
3659 AddObjCExpressionResults(Results, false);
Douglas Gregor9a0c85e2009-12-07 09:51:25 +00003660 Results.ExitScope();
Douglas Gregore6b1bb62010-08-11 21:23:17 +00003661 HandleCodeCompleteResults(this, CodeCompleter,
3662 CodeCompletionContext::CCC_Other,
3663 Results.data(),Results.size());
Douglas Gregor9a0c85e2009-12-07 09:51:25 +00003664}
3665
3666void Sema::CodeCompleteObjCAtExpression(Scope *S) {
3667 ResultBuilder Results(*this);
3668 Results.EnterNewScope();
Douglas Gregorbca403c2010-01-13 23:51:12 +00003669 AddObjCExpressionResults(Results, false);
Douglas Gregor9a0c85e2009-12-07 09:51:25 +00003670 Results.ExitScope();
Douglas Gregore6b1bb62010-08-11 21:23:17 +00003671 HandleCodeCompleteResults(this, CodeCompleter,
3672 CodeCompletionContext::CCC_Other,
3673 Results.data(),Results.size());
Douglas Gregor9a0c85e2009-12-07 09:51:25 +00003674}
3675
Douglas Gregor988358f2009-11-19 00:14:45 +00003676/// \brief Determine whether the addition of the given flag to an Objective-C
3677/// property's attributes will cause a conflict.
3678static bool ObjCPropertyFlagConflicts(unsigned Attributes, unsigned NewFlag) {
3679 // Check if we've already added this flag.
3680 if (Attributes & NewFlag)
3681 return true;
3682
3683 Attributes |= NewFlag;
3684
3685 // Check for collisions with "readonly".
3686 if ((Attributes & ObjCDeclSpec::DQ_PR_readonly) &&
3687 (Attributes & (ObjCDeclSpec::DQ_PR_readwrite |
3688 ObjCDeclSpec::DQ_PR_assign |
3689 ObjCDeclSpec::DQ_PR_copy |
3690 ObjCDeclSpec::DQ_PR_retain)))
3691 return true;
3692
3693 // Check for more than one of { assign, copy, retain }.
3694 unsigned AssignCopyRetMask = Attributes & (ObjCDeclSpec::DQ_PR_assign |
3695 ObjCDeclSpec::DQ_PR_copy |
3696 ObjCDeclSpec::DQ_PR_retain);
3697 if (AssignCopyRetMask &&
3698 AssignCopyRetMask != ObjCDeclSpec::DQ_PR_assign &&
3699 AssignCopyRetMask != ObjCDeclSpec::DQ_PR_copy &&
3700 AssignCopyRetMask != ObjCDeclSpec::DQ_PR_retain)
3701 return true;
3702
3703 return false;
3704}
3705
Douglas Gregora93b1082009-11-18 23:08:07 +00003706void Sema::CodeCompleteObjCPropertyFlags(Scope *S, ObjCDeclSpec &ODS) {
Steve Naroffece8e712009-10-08 21:55:05 +00003707 if (!CodeCompleter)
3708 return;
Douglas Gregord3c68542009-11-19 01:08:35 +00003709
Steve Naroffece8e712009-10-08 21:55:05 +00003710 unsigned Attributes = ODS.getPropertyAttributes();
3711
John McCall0a2c5e22010-08-25 06:19:51 +00003712 typedef CodeCompletionResult Result;
Steve Naroffece8e712009-10-08 21:55:05 +00003713 ResultBuilder Results(*this);
3714 Results.EnterNewScope();
Douglas Gregor988358f2009-11-19 00:14:45 +00003715 if (!ObjCPropertyFlagConflicts(Attributes, ObjCDeclSpec::DQ_PR_readonly))
John McCall0a2c5e22010-08-25 06:19:51 +00003716 Results.AddResult(CodeCompletionResult("readonly"));
Douglas Gregor988358f2009-11-19 00:14:45 +00003717 if (!ObjCPropertyFlagConflicts(Attributes, ObjCDeclSpec::DQ_PR_assign))
John McCall0a2c5e22010-08-25 06:19:51 +00003718 Results.AddResult(CodeCompletionResult("assign"));
Douglas Gregor988358f2009-11-19 00:14:45 +00003719 if (!ObjCPropertyFlagConflicts(Attributes, ObjCDeclSpec::DQ_PR_readwrite))
John McCall0a2c5e22010-08-25 06:19:51 +00003720 Results.AddResult(CodeCompletionResult("readwrite"));
Douglas Gregor988358f2009-11-19 00:14:45 +00003721 if (!ObjCPropertyFlagConflicts(Attributes, ObjCDeclSpec::DQ_PR_retain))
John McCall0a2c5e22010-08-25 06:19:51 +00003722 Results.AddResult(CodeCompletionResult("retain"));
Douglas Gregor988358f2009-11-19 00:14:45 +00003723 if (!ObjCPropertyFlagConflicts(Attributes, ObjCDeclSpec::DQ_PR_copy))
John McCall0a2c5e22010-08-25 06:19:51 +00003724 Results.AddResult(CodeCompletionResult("copy"));
Douglas Gregor988358f2009-11-19 00:14:45 +00003725 if (!ObjCPropertyFlagConflicts(Attributes, ObjCDeclSpec::DQ_PR_nonatomic))
John McCall0a2c5e22010-08-25 06:19:51 +00003726 Results.AddResult(CodeCompletionResult("nonatomic"));
Douglas Gregor988358f2009-11-19 00:14:45 +00003727 if (!ObjCPropertyFlagConflicts(Attributes, ObjCDeclSpec::DQ_PR_setter)) {
Douglas Gregor54f01612009-11-19 00:01:57 +00003728 CodeCompletionString *Setter = new CodeCompletionString;
3729 Setter->AddTypedTextChunk("setter");
3730 Setter->AddTextChunk(" = ");
3731 Setter->AddPlaceholderChunk("method");
John McCall0a2c5e22010-08-25 06:19:51 +00003732 Results.AddResult(CodeCompletionResult(Setter));
Douglas Gregor54f01612009-11-19 00:01:57 +00003733 }
Douglas Gregor988358f2009-11-19 00:14:45 +00003734 if (!ObjCPropertyFlagConflicts(Attributes, ObjCDeclSpec::DQ_PR_getter)) {
Douglas Gregor54f01612009-11-19 00:01:57 +00003735 CodeCompletionString *Getter = new CodeCompletionString;
3736 Getter->AddTypedTextChunk("getter");
3737 Getter->AddTextChunk(" = ");
3738 Getter->AddPlaceholderChunk("method");
John McCall0a2c5e22010-08-25 06:19:51 +00003739 Results.AddResult(CodeCompletionResult(Getter));
Douglas Gregor54f01612009-11-19 00:01:57 +00003740 }
Steve Naroffece8e712009-10-08 21:55:05 +00003741 Results.ExitScope();
Douglas Gregore6b1bb62010-08-11 21:23:17 +00003742 HandleCodeCompleteResults(this, CodeCompleter,
3743 CodeCompletionContext::CCC_Other,
3744 Results.data(),Results.size());
Steve Naroffece8e712009-10-08 21:55:05 +00003745}
Steve Naroffc4df6d22009-11-07 02:08:14 +00003746
Douglas Gregor4ad96852009-11-19 07:41:15 +00003747/// \brief Descripts the kind of Objective-C method that we want to find
3748/// via code completion.
3749enum ObjCMethodKind {
3750 MK_Any, //< Any kind of method, provided it means other specified criteria.
3751 MK_ZeroArgSelector, //< Zero-argument (unary) selector.
3752 MK_OneArgSelector //< One-argument selector.
3753};
3754
Douglas Gregor458433d2010-08-26 15:07:07 +00003755static bool isAcceptableObjCSelector(Selector Sel,
3756 ObjCMethodKind WantKind,
3757 IdentifierInfo **SelIdents,
3758 unsigned NumSelIdents) {
3759 if (NumSelIdents > Sel.getNumArgs())
3760 return false;
3761
3762 switch (WantKind) {
3763 case MK_Any: break;
3764 case MK_ZeroArgSelector: return Sel.isUnarySelector();
3765 case MK_OneArgSelector: return Sel.getNumArgs() == 1;
3766 }
3767
3768 for (unsigned I = 0; I != NumSelIdents; ++I)
3769 if (SelIdents[I] != Sel.getIdentifierInfoForSlot(I))
3770 return false;
3771
3772 return true;
3773}
3774
Douglas Gregor4ad96852009-11-19 07:41:15 +00003775static bool isAcceptableObjCMethod(ObjCMethodDecl *Method,
3776 ObjCMethodKind WantKind,
3777 IdentifierInfo **SelIdents,
3778 unsigned NumSelIdents) {
Douglas Gregor458433d2010-08-26 15:07:07 +00003779 return isAcceptableObjCSelector(Method->getSelector(), WantKind, SelIdents,
3780 NumSelIdents);
Douglas Gregor4ad96852009-11-19 07:41:15 +00003781}
3782
Douglas Gregor36ecb042009-11-17 23:22:23 +00003783/// \brief Add all of the Objective-C methods in the given Objective-C
3784/// container to the set of results.
3785///
3786/// The container will be a class, protocol, category, or implementation of
3787/// any of the above. This mether will recurse to include methods from
3788/// the superclasses of classes along with their categories, protocols, and
3789/// implementations.
3790///
3791/// \param Container the container in which we'll look to find methods.
3792///
3793/// \param WantInstance whether to add instance methods (only); if false, this
3794/// routine will add factory methods (only).
3795///
3796/// \param CurContext the context in which we're performing the lookup that
3797/// finds methods.
3798///
3799/// \param Results the structure into which we'll add results.
3800static void AddObjCMethods(ObjCContainerDecl *Container,
3801 bool WantInstanceMethods,
Douglas Gregor4ad96852009-11-19 07:41:15 +00003802 ObjCMethodKind WantKind,
Douglas Gregord3c68542009-11-19 01:08:35 +00003803 IdentifierInfo **SelIdents,
3804 unsigned NumSelIdents,
Douglas Gregor36ecb042009-11-17 23:22:23 +00003805 DeclContext *CurContext,
Douglas Gregor408be5a2010-08-25 01:08:01 +00003806 ResultBuilder &Results,
3807 bool InOriginalClass = true) {
John McCall0a2c5e22010-08-25 06:19:51 +00003808 typedef CodeCompletionResult Result;
Douglas Gregor36ecb042009-11-17 23:22:23 +00003809 for (ObjCContainerDecl::method_iterator M = Container->meth_begin(),
3810 MEnd = Container->meth_end();
3811 M != MEnd; ++M) {
Douglas Gregord3c68542009-11-19 01:08:35 +00003812 if ((*M)->isInstanceMethod() == WantInstanceMethods) {
3813 // Check whether the selector identifiers we've been given are a
3814 // subset of the identifiers for this particular method.
Douglas Gregor4ad96852009-11-19 07:41:15 +00003815 if (!isAcceptableObjCMethod(*M, WantKind, SelIdents, NumSelIdents))
Douglas Gregord3c68542009-11-19 01:08:35 +00003816 continue;
Douglas Gregor4ad96852009-11-19 07:41:15 +00003817
Douglas Gregord3c68542009-11-19 01:08:35 +00003818 Result R = Result(*M, 0);
3819 R.StartParameter = NumSelIdents;
Douglas Gregor4ad96852009-11-19 07:41:15 +00003820 R.AllParametersAreInformative = (WantKind != MK_Any);
Douglas Gregor408be5a2010-08-25 01:08:01 +00003821 if (!InOriginalClass)
3822 R.Priority += CCD_InBaseClass;
Douglas Gregord3c68542009-11-19 01:08:35 +00003823 Results.MaybeAddResult(R, CurContext);
3824 }
Douglas Gregor36ecb042009-11-17 23:22:23 +00003825 }
3826
3827 ObjCInterfaceDecl *IFace = dyn_cast<ObjCInterfaceDecl>(Container);
3828 if (!IFace)
3829 return;
3830
3831 // Add methods in protocols.
3832 const ObjCList<ObjCProtocolDecl> &Protocols= IFace->getReferencedProtocols();
3833 for (ObjCList<ObjCProtocolDecl>::iterator I = Protocols.begin(),
3834 E = Protocols.end();
3835 I != E; ++I)
Douglas Gregor4ad96852009-11-19 07:41:15 +00003836 AddObjCMethods(*I, WantInstanceMethods, WantKind, SelIdents, NumSelIdents,
Douglas Gregor408be5a2010-08-25 01:08:01 +00003837 CurContext, Results, false);
Douglas Gregor36ecb042009-11-17 23:22:23 +00003838
3839 // Add methods in categories.
3840 for (ObjCCategoryDecl *CatDecl = IFace->getCategoryList(); CatDecl;
3841 CatDecl = CatDecl->getNextClassCategory()) {
Douglas Gregor4ad96852009-11-19 07:41:15 +00003842 AddObjCMethods(CatDecl, WantInstanceMethods, WantKind, SelIdents,
Douglas Gregor408be5a2010-08-25 01:08:01 +00003843 NumSelIdents, CurContext, Results, InOriginalClass);
Douglas Gregor36ecb042009-11-17 23:22:23 +00003844
3845 // Add a categories protocol methods.
3846 const ObjCList<ObjCProtocolDecl> &Protocols
3847 = CatDecl->getReferencedProtocols();
3848 for (ObjCList<ObjCProtocolDecl>::iterator I = Protocols.begin(),
3849 E = Protocols.end();
3850 I != E; ++I)
Douglas Gregor4ad96852009-11-19 07:41:15 +00003851 AddObjCMethods(*I, WantInstanceMethods, WantKind, SelIdents,
Douglas Gregor408be5a2010-08-25 01:08:01 +00003852 NumSelIdents, CurContext, Results, false);
Douglas Gregor36ecb042009-11-17 23:22:23 +00003853
3854 // Add methods in category implementations.
3855 if (ObjCCategoryImplDecl *Impl = CatDecl->getImplementation())
Douglas Gregor4ad96852009-11-19 07:41:15 +00003856 AddObjCMethods(Impl, WantInstanceMethods, WantKind, SelIdents,
Douglas Gregor408be5a2010-08-25 01:08:01 +00003857 NumSelIdents, CurContext, Results, InOriginalClass);
Douglas Gregor36ecb042009-11-17 23:22:23 +00003858 }
3859
3860 // Add methods in superclass.
3861 if (IFace->getSuperClass())
Douglas Gregor4ad96852009-11-19 07:41:15 +00003862 AddObjCMethods(IFace->getSuperClass(), WantInstanceMethods, WantKind,
Douglas Gregor408be5a2010-08-25 01:08:01 +00003863 SelIdents, NumSelIdents, CurContext, Results, false);
Douglas Gregor36ecb042009-11-17 23:22:23 +00003864
3865 // Add methods in our implementation, if any.
3866 if (ObjCImplementationDecl *Impl = IFace->getImplementation())
Douglas Gregor4ad96852009-11-19 07:41:15 +00003867 AddObjCMethods(Impl, WantInstanceMethods, WantKind, SelIdents,
Douglas Gregor408be5a2010-08-25 01:08:01 +00003868 NumSelIdents, CurContext, Results, InOriginalClass);
Douglas Gregor4ad96852009-11-19 07:41:15 +00003869}
3870
3871
John McCalld226f652010-08-21 09:40:31 +00003872void Sema::CodeCompleteObjCPropertyGetter(Scope *S, Decl *ClassDecl,
3873 Decl **Methods,
Douglas Gregor4ad96852009-11-19 07:41:15 +00003874 unsigned NumMethods) {
John McCall0a2c5e22010-08-25 06:19:51 +00003875 typedef CodeCompletionResult Result;
Douglas Gregor4ad96852009-11-19 07:41:15 +00003876
3877 // Try to find the interface where getters might live.
John McCalld226f652010-08-21 09:40:31 +00003878 ObjCInterfaceDecl *Class = dyn_cast_or_null<ObjCInterfaceDecl>(ClassDecl);
Douglas Gregor4ad96852009-11-19 07:41:15 +00003879 if (!Class) {
3880 if (ObjCCategoryDecl *Category
John McCalld226f652010-08-21 09:40:31 +00003881 = dyn_cast_or_null<ObjCCategoryDecl>(ClassDecl))
Douglas Gregor4ad96852009-11-19 07:41:15 +00003882 Class = Category->getClassInterface();
3883
3884 if (!Class)
3885 return;
3886 }
3887
3888 // Find all of the potential getters.
3889 ResultBuilder Results(*this);
3890 Results.EnterNewScope();
3891
3892 // FIXME: We need to do this because Objective-C methods don't get
3893 // pushed into DeclContexts early enough. Argh!
3894 for (unsigned I = 0; I != NumMethods; ++I) {
3895 if (ObjCMethodDecl *Method
John McCalld226f652010-08-21 09:40:31 +00003896 = dyn_cast_or_null<ObjCMethodDecl>(Methods[I]))
Douglas Gregor4ad96852009-11-19 07:41:15 +00003897 if (Method->isInstanceMethod() &&
3898 isAcceptableObjCMethod(Method, MK_ZeroArgSelector, 0, 0)) {
3899 Result R = Result(Method, 0);
3900 R.AllParametersAreInformative = true;
3901 Results.MaybeAddResult(R, CurContext);
3902 }
3903 }
3904
3905 AddObjCMethods(Class, true, MK_ZeroArgSelector, 0, 0, CurContext, Results);
3906 Results.ExitScope();
Douglas Gregore6b1bb62010-08-11 21:23:17 +00003907 HandleCodeCompleteResults(this, CodeCompleter,
3908 CodeCompletionContext::CCC_Other,
3909 Results.data(),Results.size());
Douglas Gregor4ad96852009-11-19 07:41:15 +00003910}
3911
John McCalld226f652010-08-21 09:40:31 +00003912void Sema::CodeCompleteObjCPropertySetter(Scope *S, Decl *ObjCImplDecl,
3913 Decl **Methods,
Douglas Gregor4ad96852009-11-19 07:41:15 +00003914 unsigned NumMethods) {
John McCall0a2c5e22010-08-25 06:19:51 +00003915 typedef CodeCompletionResult Result;
Douglas Gregor4ad96852009-11-19 07:41:15 +00003916
3917 // Try to find the interface where setters might live.
3918 ObjCInterfaceDecl *Class
John McCalld226f652010-08-21 09:40:31 +00003919 = dyn_cast_or_null<ObjCInterfaceDecl>(ObjCImplDecl);
Douglas Gregor4ad96852009-11-19 07:41:15 +00003920 if (!Class) {
3921 if (ObjCCategoryDecl *Category
John McCalld226f652010-08-21 09:40:31 +00003922 = dyn_cast_or_null<ObjCCategoryDecl>(ObjCImplDecl))
Douglas Gregor4ad96852009-11-19 07:41:15 +00003923 Class = Category->getClassInterface();
3924
3925 if (!Class)
3926 return;
3927 }
3928
3929 // Find all of the potential getters.
3930 ResultBuilder Results(*this);
3931 Results.EnterNewScope();
3932
3933 // FIXME: We need to do this because Objective-C methods don't get
3934 // pushed into DeclContexts early enough. Argh!
3935 for (unsigned I = 0; I != NumMethods; ++I) {
3936 if (ObjCMethodDecl *Method
John McCalld226f652010-08-21 09:40:31 +00003937 = dyn_cast_or_null<ObjCMethodDecl>(Methods[I]))
Douglas Gregor4ad96852009-11-19 07:41:15 +00003938 if (Method->isInstanceMethod() &&
3939 isAcceptableObjCMethod(Method, MK_OneArgSelector, 0, 0)) {
3940 Result R = Result(Method, 0);
3941 R.AllParametersAreInformative = true;
3942 Results.MaybeAddResult(R, CurContext);
3943 }
3944 }
3945
3946 AddObjCMethods(Class, true, MK_OneArgSelector, 0, 0, CurContext, Results);
3947
3948 Results.ExitScope();
Douglas Gregore6b1bb62010-08-11 21:23:17 +00003949 HandleCodeCompleteResults(this, CodeCompleter,
3950 CodeCompletionContext::CCC_Other,
3951 Results.data(),Results.size());
Douglas Gregor36ecb042009-11-17 23:22:23 +00003952}
3953
Douglas Gregord32b0222010-08-24 01:06:58 +00003954void Sema::CodeCompleteObjCPassingType(Scope *S, ObjCDeclSpec &DS) {
John McCall0a2c5e22010-08-25 06:19:51 +00003955 typedef CodeCompletionResult Result;
Douglas Gregord32b0222010-08-24 01:06:58 +00003956 ResultBuilder Results(*this);
3957 Results.EnterNewScope();
3958
3959 // Add context-sensitive, Objective-C parameter-passing keywords.
3960 bool AddedInOut = false;
3961 if ((DS.getObjCDeclQualifier() &
3962 (ObjCDeclSpec::DQ_In | ObjCDeclSpec::DQ_Inout)) == 0) {
3963 Results.AddResult("in");
3964 Results.AddResult("inout");
3965 AddedInOut = true;
3966 }
3967 if ((DS.getObjCDeclQualifier() &
3968 (ObjCDeclSpec::DQ_Out | ObjCDeclSpec::DQ_Inout)) == 0) {
3969 Results.AddResult("out");
3970 if (!AddedInOut)
3971 Results.AddResult("inout");
3972 }
3973 if ((DS.getObjCDeclQualifier() &
3974 (ObjCDeclSpec::DQ_Bycopy | ObjCDeclSpec::DQ_Byref |
3975 ObjCDeclSpec::DQ_Oneway)) == 0) {
3976 Results.AddResult("bycopy");
3977 Results.AddResult("byref");
3978 Results.AddResult("oneway");
3979 }
3980
3981 // Add various builtin type names and specifiers.
3982 AddOrdinaryNameResults(PCC_Type, S, *this, Results);
3983 Results.ExitScope();
3984
3985 // Add the various type names
3986 Results.setFilter(&ResultBuilder::IsOrdinaryNonValueName);
3987 CodeCompletionDeclConsumer Consumer(Results, CurContext);
3988 LookupVisibleDecls(S, LookupOrdinaryName, Consumer,
3989 CodeCompleter->includeGlobals());
3990
3991 if (CodeCompleter->includeMacros())
3992 AddMacroResults(PP, Results);
3993
3994 HandleCodeCompleteResults(this, CodeCompleter,
3995 CodeCompletionContext::CCC_Type,
3996 Results.data(), Results.size());
3997}
3998
Douglas Gregor22f56992010-04-06 19:22:33 +00003999/// \brief When we have an expression with type "id", we may assume
4000/// that it has some more-specific class type based on knowledge of
4001/// common uses of Objective-C. This routine returns that class type,
4002/// or NULL if no better result could be determined.
4003static ObjCInterfaceDecl *GetAssumedMessageSendExprType(Expr *E) {
4004 ObjCMessageExpr *Msg = dyn_cast<ObjCMessageExpr>(E);
4005 if (!Msg)
4006 return 0;
4007
4008 Selector Sel = Msg->getSelector();
4009 if (Sel.isNull())
4010 return 0;
4011
4012 IdentifierInfo *Id = Sel.getIdentifierInfoForSlot(0);
4013 if (!Id)
4014 return 0;
4015
4016 ObjCMethodDecl *Method = Msg->getMethodDecl();
4017 if (!Method)
4018 return 0;
4019
4020 // Determine the class that we're sending the message to.
Douglas Gregor04badcf2010-04-21 00:45:42 +00004021 ObjCInterfaceDecl *IFace = 0;
4022 switch (Msg->getReceiverKind()) {
4023 case ObjCMessageExpr::Class:
John McCallc12c5bb2010-05-15 11:32:37 +00004024 if (const ObjCObjectType *ObjType
4025 = Msg->getClassReceiver()->getAs<ObjCObjectType>())
4026 IFace = ObjType->getInterface();
Douglas Gregor04badcf2010-04-21 00:45:42 +00004027 break;
4028
4029 case ObjCMessageExpr::Instance: {
4030 QualType T = Msg->getInstanceReceiver()->getType();
4031 if (const ObjCObjectPointerType *Ptr = T->getAs<ObjCObjectPointerType>())
4032 IFace = Ptr->getInterfaceDecl();
4033 break;
4034 }
4035
4036 case ObjCMessageExpr::SuperInstance:
4037 case ObjCMessageExpr::SuperClass:
4038 break;
Douglas Gregor22f56992010-04-06 19:22:33 +00004039 }
4040
4041 if (!IFace)
4042 return 0;
4043
4044 ObjCInterfaceDecl *Super = IFace->getSuperClass();
4045 if (Method->isInstanceMethod())
4046 return llvm::StringSwitch<ObjCInterfaceDecl *>(Id->getName())
4047 .Case("retain", IFace)
4048 .Case("autorelease", IFace)
4049 .Case("copy", IFace)
4050 .Case("copyWithZone", IFace)
4051 .Case("mutableCopy", IFace)
4052 .Case("mutableCopyWithZone", IFace)
4053 .Case("awakeFromCoder", IFace)
4054 .Case("replacementObjectFromCoder", IFace)
4055 .Case("class", IFace)
4056 .Case("classForCoder", IFace)
4057 .Case("superclass", Super)
4058 .Default(0);
4059
4060 return llvm::StringSwitch<ObjCInterfaceDecl *>(Id->getName())
4061 .Case("new", IFace)
4062 .Case("alloc", IFace)
4063 .Case("allocWithZone", IFace)
4064 .Case("class", IFace)
4065 .Case("superclass", Super)
4066 .Default(0);
4067}
4068
Douglas Gregor03d8aec2010-08-27 15:10:57 +00004069// Add a special completion for a message send to "super", which fills in the
4070// most likely case of forwarding all of our arguments to the superclass
4071// function.
4072///
4073/// \param S The semantic analysis object.
4074///
4075/// \param S NeedSuperKeyword Whether we need to prefix this completion with
4076/// the "super" keyword. Otherwise, we just need to provide the arguments.
4077///
4078/// \param SelIdents The identifiers in the selector that have already been
4079/// provided as arguments for a send to "super".
4080///
4081/// \param NumSelIdents The number of identifiers in \p SelIdents.
4082///
4083/// \param Results The set of results to augment.
4084///
4085/// \returns the Objective-C method declaration that would be invoked by
4086/// this "super" completion. If NULL, no completion was added.
4087static ObjCMethodDecl *AddSuperSendCompletion(Sema &S, bool NeedSuperKeyword,
4088 IdentifierInfo **SelIdents,
4089 unsigned NumSelIdents,
4090 ResultBuilder &Results) {
4091 ObjCMethodDecl *CurMethod = S.getCurMethodDecl();
4092 if (!CurMethod)
4093 return 0;
4094
4095 ObjCInterfaceDecl *Class = CurMethod->getClassInterface();
4096 if (!Class)
4097 return 0;
4098
4099 // Try to find a superclass method with the same selector.
4100 ObjCMethodDecl *SuperMethod = 0;
4101 while ((Class = Class->getSuperClass()) && !SuperMethod)
4102 SuperMethod = Class->getMethod(CurMethod->getSelector(),
4103 CurMethod->isInstanceMethod());
4104
4105 if (!SuperMethod)
4106 return 0;
4107
4108 // Check whether the superclass method has the same signature.
4109 if (CurMethod->param_size() != SuperMethod->param_size() ||
4110 CurMethod->isVariadic() != SuperMethod->isVariadic())
4111 return 0;
4112
4113 for (ObjCMethodDecl::param_iterator CurP = CurMethod->param_begin(),
4114 CurPEnd = CurMethod->param_end(),
4115 SuperP = SuperMethod->param_begin();
4116 CurP != CurPEnd; ++CurP, ++SuperP) {
4117 // Make sure the parameter types are compatible.
4118 if (!S.Context.hasSameUnqualifiedType((*CurP)->getType(),
4119 (*SuperP)->getType()))
4120 return 0;
4121
4122 // Make sure we have a parameter name to forward!
4123 if (!(*CurP)->getIdentifier())
4124 return 0;
4125 }
4126
4127 // We have a superclass method. Now, form the send-to-super completion.
4128 CodeCompletionString *Pattern = new CodeCompletionString;
4129
4130 // Give this completion a return type.
4131 AddResultTypeChunk(S.Context, SuperMethod, Pattern);
4132
4133 // If we need the "super" keyword, add it (plus some spacing).
4134 if (NeedSuperKeyword) {
4135 Pattern->AddTypedTextChunk("super");
4136 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
4137 }
4138
4139 Selector Sel = CurMethod->getSelector();
4140 if (Sel.isUnarySelector()) {
4141 if (NeedSuperKeyword)
4142 Pattern->AddTextChunk(Sel.getIdentifierInfoForSlot(0)->getName());
4143 else
4144 Pattern->AddTypedTextChunk(Sel.getIdentifierInfoForSlot(0)->getName());
4145 } else {
4146 ObjCMethodDecl::param_iterator CurP = CurMethod->param_begin();
4147 for (unsigned I = 0, N = Sel.getNumArgs(); I != N; ++I, ++CurP) {
4148 if (I > NumSelIdents)
4149 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
4150
4151 if (I < NumSelIdents)
4152 Pattern->AddInformativeChunk(
4153 Sel.getIdentifierInfoForSlot(I)->getName().str() + ":");
4154 else if (NeedSuperKeyword || I > NumSelIdents) {
4155 Pattern->AddTextChunk(
4156 Sel.getIdentifierInfoForSlot(I)->getName().str() + ":");
4157 Pattern->AddPlaceholderChunk((*CurP)->getIdentifier()->getName());
4158 } else {
4159 Pattern->AddTypedTextChunk(
4160 Sel.getIdentifierInfoForSlot(I)->getName().str() + ":");
4161 Pattern->AddPlaceholderChunk((*CurP)->getIdentifier()->getName());
4162 }
4163 }
4164 }
4165
4166 Results.AddResult(CodeCompletionResult(Pattern, CCP_SuperCompletion,
4167 SuperMethod->isInstanceMethod()
4168 ? CXCursor_ObjCInstanceMethodDecl
4169 : CXCursor_ObjCClassMethodDecl));
4170 return SuperMethod;
4171}
4172
Douglas Gregor8e254cf2010-05-27 23:06:34 +00004173void Sema::CodeCompleteObjCMessageReceiver(Scope *S) {
John McCall0a2c5e22010-08-25 06:19:51 +00004174 typedef CodeCompletionResult Result;
Douglas Gregor8e254cf2010-05-27 23:06:34 +00004175 ResultBuilder Results(*this);
4176
4177 // Find anything that looks like it could be a message receiver.
4178 Results.setFilter(&ResultBuilder::IsObjCMessageReceiver);
4179 CodeCompletionDeclConsumer Consumer(Results, CurContext);
4180 Results.EnterNewScope();
Douglas Gregor8071e422010-08-15 06:18:01 +00004181 LookupVisibleDecls(S, LookupOrdinaryName, Consumer,
4182 CodeCompleter->includeGlobals());
Douglas Gregor8e254cf2010-05-27 23:06:34 +00004183
4184 // If we are in an Objective-C method inside a class that has a superclass,
4185 // add "super" as an option.
4186 if (ObjCMethodDecl *Method = getCurMethodDecl())
4187 if (ObjCInterfaceDecl *Iface = Method->getClassInterface())
Douglas Gregor03d8aec2010-08-27 15:10:57 +00004188 if (Iface->getSuperClass()) {
Douglas Gregor8e254cf2010-05-27 23:06:34 +00004189 Results.AddResult(Result("super"));
Douglas Gregor03d8aec2010-08-27 15:10:57 +00004190
4191 AddSuperSendCompletion(*this, /*NeedSuperKeyword=*/true, 0, 0, Results);
4192 }
Douglas Gregor8e254cf2010-05-27 23:06:34 +00004193
4194 Results.ExitScope();
4195
4196 if (CodeCompleter->includeMacros())
4197 AddMacroResults(PP, Results);
Douglas Gregore6b1bb62010-08-11 21:23:17 +00004198 HandleCodeCompleteResults(this, CodeCompleter,
4199 CodeCompletionContext::CCC_ObjCMessageReceiver,
4200 Results.data(), Results.size());
Douglas Gregor8e254cf2010-05-27 23:06:34 +00004201
4202}
4203
Douglas Gregor2725ca82010-04-21 19:57:20 +00004204void Sema::CodeCompleteObjCSuperMessage(Scope *S, SourceLocation SuperLoc,
4205 IdentifierInfo **SelIdents,
4206 unsigned NumSelIdents) {
4207 ObjCInterfaceDecl *CDecl = 0;
4208 if (ObjCMethodDecl *CurMethod = getCurMethodDecl()) {
4209 // Figure out which interface we're in.
4210 CDecl = CurMethod->getClassInterface();
4211 if (!CDecl)
4212 return;
4213
4214 // Find the superclass of this class.
4215 CDecl = CDecl->getSuperClass();
4216 if (!CDecl)
4217 return;
4218
4219 if (CurMethod->isInstanceMethod()) {
4220 // We are inside an instance method, which means that the message
4221 // send [super ...] is actually calling an instance method on the
4222 // current object. Build the super expression and handle this like
4223 // an instance method.
4224 QualType SuperTy = Context.getObjCInterfaceType(CDecl);
4225 SuperTy = Context.getObjCObjectPointerType(SuperTy);
John McCall60d7b3a2010-08-24 06:29:42 +00004226 ExprResult Super
Douglas Gregor2725ca82010-04-21 19:57:20 +00004227 = Owned(new (Context) ObjCSuperExpr(SuperLoc, SuperTy));
4228 return CodeCompleteObjCInstanceMessage(S, (Expr *)Super.get(),
Douglas Gregor03d8aec2010-08-27 15:10:57 +00004229 SelIdents, NumSelIdents,
4230 /*IsSuper=*/true);
Douglas Gregor2725ca82010-04-21 19:57:20 +00004231 }
4232
4233 // Fall through to send to the superclass in CDecl.
4234 } else {
4235 // "super" may be the name of a type or variable. Figure out which
4236 // it is.
4237 IdentifierInfo *Super = &Context.Idents.get("super");
4238 NamedDecl *ND = LookupSingleName(S, Super, SuperLoc,
4239 LookupOrdinaryName);
4240 if ((CDecl = dyn_cast_or_null<ObjCInterfaceDecl>(ND))) {
4241 // "super" names an interface. Use it.
4242 } else if (TypeDecl *TD = dyn_cast_or_null<TypeDecl>(ND)) {
John McCallc12c5bb2010-05-15 11:32:37 +00004243 if (const ObjCObjectType *Iface
4244 = Context.getTypeDeclType(TD)->getAs<ObjCObjectType>())
4245 CDecl = Iface->getInterface();
Douglas Gregor2725ca82010-04-21 19:57:20 +00004246 } else if (ND && isa<UnresolvedUsingTypenameDecl>(ND)) {
4247 // "super" names an unresolved type; we can't be more specific.
4248 } else {
4249 // Assume that "super" names some kind of value and parse that way.
4250 CXXScopeSpec SS;
4251 UnqualifiedId id;
4252 id.setIdentifier(Super, SuperLoc);
John McCall60d7b3a2010-08-24 06:29:42 +00004253 ExprResult SuperExpr = ActOnIdExpression(S, SS, id, false, false);
Douglas Gregor2725ca82010-04-21 19:57:20 +00004254 return CodeCompleteObjCInstanceMessage(S, (Expr *)SuperExpr.get(),
4255 SelIdents, NumSelIdents);
4256 }
4257
4258 // Fall through
4259 }
4260
John McCallb3d87482010-08-24 05:47:05 +00004261 ParsedType Receiver;
Douglas Gregor2725ca82010-04-21 19:57:20 +00004262 if (CDecl)
John McCallb3d87482010-08-24 05:47:05 +00004263 Receiver = ParsedType::make(Context.getObjCInterfaceType(CDecl));
Douglas Gregor2725ca82010-04-21 19:57:20 +00004264 return CodeCompleteObjCClassMessage(S, Receiver, SelIdents,
Douglas Gregor03d8aec2010-08-27 15:10:57 +00004265 NumSelIdents, /*IsSuper=*/true);
Douglas Gregor2725ca82010-04-21 19:57:20 +00004266}
4267
John McCallb3d87482010-08-24 05:47:05 +00004268void Sema::CodeCompleteObjCClassMessage(Scope *S, ParsedType Receiver,
Douglas Gregord3c68542009-11-19 01:08:35 +00004269 IdentifierInfo **SelIdents,
4270 unsigned NumSelIdents) {
Douglas Gregor03d8aec2010-08-27 15:10:57 +00004271 CodeCompleteObjCClassMessage(S, Receiver, SelIdents, NumSelIdents, false);
4272}
4273
4274void Sema::CodeCompleteObjCClassMessage(Scope *S, ParsedType Receiver,
4275 IdentifierInfo **SelIdents,
4276 unsigned NumSelIdents,
4277 bool IsSuper) {
John McCall0a2c5e22010-08-25 06:19:51 +00004278 typedef CodeCompletionResult Result;
Douglas Gregor24a069f2009-11-17 17:59:40 +00004279 ObjCInterfaceDecl *CDecl = 0;
4280
Douglas Gregor24a069f2009-11-17 17:59:40 +00004281 // If the given name refers to an interface type, retrieve the
4282 // corresponding declaration.
Douglas Gregor2725ca82010-04-21 19:57:20 +00004283 if (Receiver) {
4284 QualType T = GetTypeFromParser(Receiver, 0);
4285 if (!T.isNull())
John McCallc12c5bb2010-05-15 11:32:37 +00004286 if (const ObjCObjectType *Interface = T->getAs<ObjCObjectType>())
4287 CDecl = Interface->getInterface();
Douglas Gregor24a069f2009-11-17 17:59:40 +00004288 }
4289
Douglas Gregor36ecb042009-11-17 23:22:23 +00004290 // Add all of the factory methods in this Objective-C class, its protocols,
4291 // superclasses, categories, implementation, etc.
Steve Naroffc4df6d22009-11-07 02:08:14 +00004292 ResultBuilder Results(*this);
4293 Results.EnterNewScope();
Douglas Gregor13438f92010-04-06 16:40:00 +00004294
Douglas Gregor03d8aec2010-08-27 15:10:57 +00004295 // If this is a send-to-super, try to add the special "super" send
4296 // completion.
4297 if (IsSuper) {
4298 if (ObjCMethodDecl *SuperMethod
4299 = AddSuperSendCompletion(*this, false, SelIdents, NumSelIdents,
4300 Results))
4301 Results.Ignore(SuperMethod);
4302 }
4303
Douglas Gregor265f7492010-08-27 15:29:55 +00004304 // If we're inside an Objective-C method definition, prefer its selector to
4305 // others.
4306 if (ObjCMethodDecl *CurMethod = getCurMethodDecl())
4307 Results.setPreferredSelector(CurMethod->getSelector());
4308
Douglas Gregor13438f92010-04-06 16:40:00 +00004309 if (CDecl)
4310 AddObjCMethods(CDecl, false, MK_Any, SelIdents, NumSelIdents, CurContext,
4311 Results);
Douglas Gregor2725ca82010-04-21 19:57:20 +00004312 else {
Douglas Gregor13438f92010-04-06 16:40:00 +00004313 // We're messaging "id" as a type; provide all class/factory methods.
4314
Douglas Gregor719770d2010-04-06 17:30:22 +00004315 // If we have an external source, load the entire class method
Sebastian Redl3c7f4132010-08-18 23:57:06 +00004316 // pool from the AST file.
Douglas Gregor719770d2010-04-06 17:30:22 +00004317 if (ExternalSource) {
John McCall76bd1f32010-06-01 09:23:16 +00004318 for (uint32_t I = 0, N = ExternalSource->GetNumExternalSelectors();
4319 I != N; ++I) {
4320 Selector Sel = ExternalSource->GetExternalSelector(I);
Sebastian Redldb9d2142010-08-02 23:18:59 +00004321 if (Sel.isNull() || MethodPool.count(Sel))
Douglas Gregor719770d2010-04-06 17:30:22 +00004322 continue;
4323
Sebastian Redldb9d2142010-08-02 23:18:59 +00004324 ReadMethodPool(Sel);
Douglas Gregor719770d2010-04-06 17:30:22 +00004325 }
4326 }
4327
Sebastian Redldb9d2142010-08-02 23:18:59 +00004328 for (GlobalMethodPool::iterator M = MethodPool.begin(),
4329 MEnd = MethodPool.end();
4330 M != MEnd; ++M) {
4331 for (ObjCMethodList *MethList = &M->second.second;
4332 MethList && MethList->Method;
Douglas Gregor13438f92010-04-06 16:40:00 +00004333 MethList = MethList->Next) {
4334 if (!isAcceptableObjCMethod(MethList->Method, MK_Any, SelIdents,
4335 NumSelIdents))
4336 continue;
4337
4338 Result R(MethList->Method, 0);
4339 R.StartParameter = NumSelIdents;
4340 R.AllParametersAreInformative = false;
4341 Results.MaybeAddResult(R, CurContext);
4342 }
4343 }
4344 }
4345
Steve Naroffc4df6d22009-11-07 02:08:14 +00004346 Results.ExitScope();
Douglas Gregore6b1bb62010-08-11 21:23:17 +00004347 HandleCodeCompleteResults(this, CodeCompleter,
4348 CodeCompletionContext::CCC_Other,
Douglas Gregor03d8aec2010-08-27 15:10:57 +00004349 Results.data(), Results.size());
Steve Naroffc4df6d22009-11-07 02:08:14 +00004350}
4351
Douglas Gregord3c68542009-11-19 01:08:35 +00004352void Sema::CodeCompleteObjCInstanceMessage(Scope *S, ExprTy *Receiver,
4353 IdentifierInfo **SelIdents,
4354 unsigned NumSelIdents) {
Douglas Gregor03d8aec2010-08-27 15:10:57 +00004355 CodeCompleteObjCInstanceMessage(S, Receiver, SelIdents, NumSelIdents, false);
4356}
4357
4358void Sema::CodeCompleteObjCInstanceMessage(Scope *S, ExprTy *Receiver,
4359 IdentifierInfo **SelIdents,
4360 unsigned NumSelIdents,
4361 bool IsSuper) {
John McCall0a2c5e22010-08-25 06:19:51 +00004362 typedef CodeCompletionResult Result;
Steve Naroffc4df6d22009-11-07 02:08:14 +00004363
4364 Expr *RecExpr = static_cast<Expr *>(Receiver);
Steve Naroffc4df6d22009-11-07 02:08:14 +00004365
Douglas Gregor36ecb042009-11-17 23:22:23 +00004366 // If necessary, apply function/array conversion to the receiver.
4367 // C99 6.7.5.3p[7,8].
Douglas Gregora873dfc2010-02-03 00:27:59 +00004368 DefaultFunctionArrayLvalueConversion(RecExpr);
Douglas Gregor36ecb042009-11-17 23:22:23 +00004369 QualType ReceiverType = RecExpr->getType();
Steve Naroffc4df6d22009-11-07 02:08:14 +00004370
Douglas Gregor36ecb042009-11-17 23:22:23 +00004371 // Build the set of methods we can see.
4372 ResultBuilder Results(*this);
4373 Results.EnterNewScope();
Douglas Gregor22f56992010-04-06 19:22:33 +00004374
Douglas Gregor03d8aec2010-08-27 15:10:57 +00004375 // If this is a send-to-super, try to add the special "super" send
4376 // completion.
4377 if (IsSuper) {
4378 if (ObjCMethodDecl *SuperMethod
4379 = AddSuperSendCompletion(*this, false, SelIdents, NumSelIdents,
4380 Results))
4381 Results.Ignore(SuperMethod);
4382 }
4383
Douglas Gregor265f7492010-08-27 15:29:55 +00004384 // If we're inside an Objective-C method definition, prefer its selector to
4385 // others.
4386 if (ObjCMethodDecl *CurMethod = getCurMethodDecl())
4387 Results.setPreferredSelector(CurMethod->getSelector());
4388
Douglas Gregor22f56992010-04-06 19:22:33 +00004389 // If we're messaging an expression with type "id" or "Class", check
4390 // whether we know something special about the receiver that allows
4391 // us to assume a more-specific receiver type.
4392 if (ReceiverType->isObjCIdType() || ReceiverType->isObjCClassType())
4393 if (ObjCInterfaceDecl *IFace = GetAssumedMessageSendExprType(RecExpr))
4394 ReceiverType = Context.getObjCObjectPointerType(
4395 Context.getObjCInterfaceType(IFace));
Douglas Gregor36ecb042009-11-17 23:22:23 +00004396
Douglas Gregorf74a4192009-11-18 00:06:18 +00004397 // Handle messages to Class. This really isn't a message to an instance
4398 // method, so we treat it the same way we would treat a message send to a
4399 // class method.
4400 if (ReceiverType->isObjCClassType() ||
4401 ReceiverType->isObjCQualifiedClassType()) {
4402 if (ObjCMethodDecl *CurMethod = getCurMethodDecl()) {
4403 if (ObjCInterfaceDecl *ClassDecl = CurMethod->getClassInterface())
Douglas Gregor4ad96852009-11-19 07:41:15 +00004404 AddObjCMethods(ClassDecl, false, MK_Any, SelIdents, NumSelIdents,
4405 CurContext, Results);
Douglas Gregorf74a4192009-11-18 00:06:18 +00004406 }
4407 }
4408 // Handle messages to a qualified ID ("id<foo>").
4409 else if (const ObjCObjectPointerType *QualID
4410 = ReceiverType->getAsObjCQualifiedIdType()) {
4411 // Search protocols for instance methods.
4412 for (ObjCObjectPointerType::qual_iterator I = QualID->qual_begin(),
4413 E = QualID->qual_end();
4414 I != E; ++I)
Douglas Gregor4ad96852009-11-19 07:41:15 +00004415 AddObjCMethods(*I, true, MK_Any, SelIdents, NumSelIdents, CurContext,
4416 Results);
Douglas Gregorf74a4192009-11-18 00:06:18 +00004417 }
4418 // Handle messages to a pointer to interface type.
4419 else if (const ObjCObjectPointerType *IFacePtr
4420 = ReceiverType->getAsObjCInterfacePointerType()) {
4421 // Search the class, its superclasses, etc., for instance methods.
Douglas Gregor4ad96852009-11-19 07:41:15 +00004422 AddObjCMethods(IFacePtr->getInterfaceDecl(), true, MK_Any, SelIdents,
4423 NumSelIdents, CurContext, Results);
Douglas Gregorf74a4192009-11-18 00:06:18 +00004424
4425 // Search protocols for instance methods.
4426 for (ObjCObjectPointerType::qual_iterator I = IFacePtr->qual_begin(),
4427 E = IFacePtr->qual_end();
4428 I != E; ++I)
Douglas Gregor4ad96852009-11-19 07:41:15 +00004429 AddObjCMethods(*I, true, MK_Any, SelIdents, NumSelIdents, CurContext,
4430 Results);
Douglas Gregorf74a4192009-11-18 00:06:18 +00004431 }
Douglas Gregor13438f92010-04-06 16:40:00 +00004432 // Handle messages to "id".
4433 else if (ReceiverType->isObjCIdType()) {
Douglas Gregor719770d2010-04-06 17:30:22 +00004434 // We're messaging "id", so provide all instance methods we know
4435 // about as code-completion results.
4436
4437 // If we have an external source, load the entire class method
Sebastian Redl3c7f4132010-08-18 23:57:06 +00004438 // pool from the AST file.
Douglas Gregor719770d2010-04-06 17:30:22 +00004439 if (ExternalSource) {
John McCall76bd1f32010-06-01 09:23:16 +00004440 for (uint32_t I = 0, N = ExternalSource->GetNumExternalSelectors();
4441 I != N; ++I) {
4442 Selector Sel = ExternalSource->GetExternalSelector(I);
Sebastian Redldb9d2142010-08-02 23:18:59 +00004443 if (Sel.isNull() || MethodPool.count(Sel))
Douglas Gregor719770d2010-04-06 17:30:22 +00004444 continue;
4445
Sebastian Redldb9d2142010-08-02 23:18:59 +00004446 ReadMethodPool(Sel);
Douglas Gregor719770d2010-04-06 17:30:22 +00004447 }
4448 }
4449
Sebastian Redldb9d2142010-08-02 23:18:59 +00004450 for (GlobalMethodPool::iterator M = MethodPool.begin(),
4451 MEnd = MethodPool.end();
4452 M != MEnd; ++M) {
4453 for (ObjCMethodList *MethList = &M->second.first;
4454 MethList && MethList->Method;
Douglas Gregor13438f92010-04-06 16:40:00 +00004455 MethList = MethList->Next) {
4456 if (!isAcceptableObjCMethod(MethList->Method, MK_Any, SelIdents,
4457 NumSelIdents))
4458 continue;
4459
4460 Result R(MethList->Method, 0);
4461 R.StartParameter = NumSelIdents;
4462 R.AllParametersAreInformative = false;
4463 Results.MaybeAddResult(R, CurContext);
4464 }
4465 }
4466 }
4467
Steve Naroffc4df6d22009-11-07 02:08:14 +00004468 Results.ExitScope();
Douglas Gregore6b1bb62010-08-11 21:23:17 +00004469 HandleCodeCompleteResults(this, CodeCompleter,
4470 CodeCompletionContext::CCC_Other,
4471 Results.data(),Results.size());
Steve Naroffc4df6d22009-11-07 02:08:14 +00004472}
Douglas Gregor55385fe2009-11-18 04:19:12 +00004473
Douglas Gregorfb629412010-08-23 21:17:50 +00004474void Sema::CodeCompleteObjCForCollection(Scope *S,
4475 DeclGroupPtrTy IterationVar) {
4476 CodeCompleteExpressionData Data;
4477 Data.ObjCCollection = true;
4478
4479 if (IterationVar.getAsOpaquePtr()) {
4480 DeclGroupRef DG = IterationVar.getAsVal<DeclGroupRef>();
4481 for (DeclGroupRef::iterator I = DG.begin(), End = DG.end(); I != End; ++I) {
4482 if (*I)
4483 Data.IgnoreDecls.push_back(*I);
4484 }
4485 }
4486
4487 CodeCompleteExpression(S, Data);
4488}
4489
Douglas Gregor458433d2010-08-26 15:07:07 +00004490void Sema::CodeCompleteObjCSelector(Scope *S, IdentifierInfo **SelIdents,
4491 unsigned NumSelIdents) {
4492 // If we have an external source, load the entire class method
4493 // pool from the AST file.
4494 if (ExternalSource) {
4495 for (uint32_t I = 0, N = ExternalSource->GetNumExternalSelectors();
4496 I != N; ++I) {
4497 Selector Sel = ExternalSource->GetExternalSelector(I);
4498 if (Sel.isNull() || MethodPool.count(Sel))
4499 continue;
4500
4501 ReadMethodPool(Sel);
4502 }
4503 }
4504
4505 ResultBuilder Results(*this);
4506 Results.EnterNewScope();
4507 for (GlobalMethodPool::iterator M = MethodPool.begin(),
4508 MEnd = MethodPool.end();
4509 M != MEnd; ++M) {
4510
4511 Selector Sel = M->first;
4512 if (!isAcceptableObjCSelector(Sel, MK_Any, SelIdents, NumSelIdents))
4513 continue;
4514
4515 CodeCompletionString *Pattern = new CodeCompletionString;
4516 if (Sel.isUnarySelector()) {
4517 Pattern->AddTypedTextChunk(Sel.getIdentifierInfoForSlot(0)->getName());
4518 Results.AddResult(Pattern);
4519 continue;
4520 }
4521
Douglas Gregor2d9e21f2010-08-26 16:46:39 +00004522 std::string Accumulator;
Douglas Gregor458433d2010-08-26 15:07:07 +00004523 for (unsigned I = 0, N = Sel.getNumArgs(); I != N; ++I) {
Douglas Gregor2d9e21f2010-08-26 16:46:39 +00004524 if (I == NumSelIdents) {
4525 if (!Accumulator.empty()) {
4526 Pattern->AddInformativeChunk(Accumulator);
4527 Accumulator.clear();
4528 }
4529 }
4530
4531 Accumulator += Sel.getIdentifierInfoForSlot(I)->getName().str();
4532 Accumulator += ':';
Douglas Gregor458433d2010-08-26 15:07:07 +00004533 }
Douglas Gregor2d9e21f2010-08-26 16:46:39 +00004534 Pattern->AddTypedTextChunk(Accumulator);
Douglas Gregor458433d2010-08-26 15:07:07 +00004535 Results.AddResult(Pattern);
4536 }
4537 Results.ExitScope();
4538
4539 HandleCodeCompleteResults(this, CodeCompleter,
4540 CodeCompletionContext::CCC_SelectorName,
4541 Results.data(), Results.size());
4542}
4543
Douglas Gregor55385fe2009-11-18 04:19:12 +00004544/// \brief Add all of the protocol declarations that we find in the given
4545/// (translation unit) context.
4546static void AddProtocolResults(DeclContext *Ctx, DeclContext *CurContext,
Douglas Gregor083128f2009-11-18 04:49:41 +00004547 bool OnlyForwardDeclarations,
Douglas Gregor55385fe2009-11-18 04:19:12 +00004548 ResultBuilder &Results) {
John McCall0a2c5e22010-08-25 06:19:51 +00004549 typedef CodeCompletionResult Result;
Douglas Gregor55385fe2009-11-18 04:19:12 +00004550
4551 for (DeclContext::decl_iterator D = Ctx->decls_begin(),
4552 DEnd = Ctx->decls_end();
4553 D != DEnd; ++D) {
4554 // Record any protocols we find.
4555 if (ObjCProtocolDecl *Proto = dyn_cast<ObjCProtocolDecl>(*D))
Douglas Gregor083128f2009-11-18 04:49:41 +00004556 if (!OnlyForwardDeclarations || Proto->isForwardDecl())
Douglas Gregor608300b2010-01-14 16:14:35 +00004557 Results.AddResult(Result(Proto, 0), CurContext, 0, false);
Douglas Gregor55385fe2009-11-18 04:19:12 +00004558
4559 // Record any forward-declared protocols we find.
4560 if (ObjCForwardProtocolDecl *Forward
4561 = dyn_cast<ObjCForwardProtocolDecl>(*D)) {
4562 for (ObjCForwardProtocolDecl::protocol_iterator
4563 P = Forward->protocol_begin(),
4564 PEnd = Forward->protocol_end();
4565 P != PEnd; ++P)
Douglas Gregor083128f2009-11-18 04:49:41 +00004566 if (!OnlyForwardDeclarations || (*P)->isForwardDecl())
Douglas Gregor608300b2010-01-14 16:14:35 +00004567 Results.AddResult(Result(*P, 0), CurContext, 0, false);
Douglas Gregor55385fe2009-11-18 04:19:12 +00004568 }
4569 }
4570}
4571
4572void Sema::CodeCompleteObjCProtocolReferences(IdentifierLocPair *Protocols,
4573 unsigned NumProtocols) {
4574 ResultBuilder Results(*this);
4575 Results.EnterNewScope();
4576
4577 // Tell the result set to ignore all of the protocols we have
4578 // already seen.
4579 for (unsigned I = 0; I != NumProtocols; ++I)
Douglas Gregorc83c6872010-04-15 22:33:43 +00004580 if (ObjCProtocolDecl *Protocol = LookupProtocol(Protocols[I].first,
4581 Protocols[I].second))
Douglas Gregor55385fe2009-11-18 04:19:12 +00004582 Results.Ignore(Protocol);
4583
4584 // Add all protocols.
Douglas Gregor083128f2009-11-18 04:49:41 +00004585 AddProtocolResults(Context.getTranslationUnitDecl(), CurContext, false,
4586 Results);
4587
4588 Results.ExitScope();
Douglas Gregore6b1bb62010-08-11 21:23:17 +00004589 HandleCodeCompleteResults(this, CodeCompleter,
4590 CodeCompletionContext::CCC_ObjCProtocolName,
4591 Results.data(),Results.size());
Douglas Gregor083128f2009-11-18 04:49:41 +00004592}
4593
4594void Sema::CodeCompleteObjCProtocolDecl(Scope *) {
4595 ResultBuilder Results(*this);
4596 Results.EnterNewScope();
4597
4598 // Add all protocols.
4599 AddProtocolResults(Context.getTranslationUnitDecl(), CurContext, true,
4600 Results);
Douglas Gregor55385fe2009-11-18 04:19:12 +00004601
4602 Results.ExitScope();
Douglas Gregore6b1bb62010-08-11 21:23:17 +00004603 HandleCodeCompleteResults(this, CodeCompleter,
4604 CodeCompletionContext::CCC_ObjCProtocolName,
4605 Results.data(),Results.size());
Douglas Gregor55385fe2009-11-18 04:19:12 +00004606}
Douglas Gregor3b49aca2009-11-18 16:26:39 +00004607
4608/// \brief Add all of the Objective-C interface declarations that we find in
4609/// the given (translation unit) context.
4610static void AddInterfaceResults(DeclContext *Ctx, DeclContext *CurContext,
4611 bool OnlyForwardDeclarations,
4612 bool OnlyUnimplemented,
4613 ResultBuilder &Results) {
John McCall0a2c5e22010-08-25 06:19:51 +00004614 typedef CodeCompletionResult Result;
Douglas Gregor3b49aca2009-11-18 16:26:39 +00004615
4616 for (DeclContext::decl_iterator D = Ctx->decls_begin(),
4617 DEnd = Ctx->decls_end();
4618 D != DEnd; ++D) {
Douglas Gregordeacbdc2010-08-11 12:19:30 +00004619 // Record any interfaces we find.
4620 if (ObjCInterfaceDecl *Class = dyn_cast<ObjCInterfaceDecl>(*D))
4621 if ((!OnlyForwardDeclarations || Class->isForwardDecl()) &&
4622 (!OnlyUnimplemented || !Class->getImplementation()))
4623 Results.AddResult(Result(Class, 0), CurContext, 0, false);
Douglas Gregor3b49aca2009-11-18 16:26:39 +00004624
4625 // Record any forward-declared interfaces we find.
4626 if (ObjCClassDecl *Forward = dyn_cast<ObjCClassDecl>(*D)) {
4627 for (ObjCClassDecl::iterator C = Forward->begin(), CEnd = Forward->end();
Douglas Gregordeacbdc2010-08-11 12:19:30 +00004628 C != CEnd; ++C)
4629 if ((!OnlyForwardDeclarations || C->getInterface()->isForwardDecl()) &&
4630 (!OnlyUnimplemented || !C->getInterface()->getImplementation()))
4631 Results.AddResult(Result(C->getInterface(), 0), CurContext,
Douglas Gregor608300b2010-01-14 16:14:35 +00004632 0, false);
Douglas Gregor3b49aca2009-11-18 16:26:39 +00004633 }
4634 }
4635}
4636
4637void Sema::CodeCompleteObjCInterfaceDecl(Scope *S) {
4638 ResultBuilder Results(*this);
4639 Results.EnterNewScope();
4640
4641 // Add all classes.
4642 AddInterfaceResults(Context.getTranslationUnitDecl(), CurContext, true,
4643 false, Results);
4644
4645 Results.ExitScope();
Douglas Gregore6b1bb62010-08-11 21:23:17 +00004646 HandleCodeCompleteResults(this, CodeCompleter,
4647 CodeCompletionContext::CCC_Other,
4648 Results.data(),Results.size());
Douglas Gregor3b49aca2009-11-18 16:26:39 +00004649}
4650
Douglas Gregorc83c6872010-04-15 22:33:43 +00004651void Sema::CodeCompleteObjCSuperclass(Scope *S, IdentifierInfo *ClassName,
4652 SourceLocation ClassNameLoc) {
Douglas Gregor3b49aca2009-11-18 16:26:39 +00004653 ResultBuilder Results(*this);
4654 Results.EnterNewScope();
4655
4656 // Make sure that we ignore the class we're currently defining.
4657 NamedDecl *CurClass
Douglas Gregorc83c6872010-04-15 22:33:43 +00004658 = LookupSingleName(TUScope, ClassName, ClassNameLoc, LookupOrdinaryName);
Douglas Gregor33ced0b2009-11-18 19:08:43 +00004659 if (CurClass && isa<ObjCInterfaceDecl>(CurClass))
Douglas Gregor3b49aca2009-11-18 16:26:39 +00004660 Results.Ignore(CurClass);
4661
4662 // Add all classes.
4663 AddInterfaceResults(Context.getTranslationUnitDecl(), CurContext, false,
4664 false, Results);
4665
4666 Results.ExitScope();
Douglas Gregore6b1bb62010-08-11 21:23:17 +00004667 HandleCodeCompleteResults(this, CodeCompleter,
4668 CodeCompletionContext::CCC_Other,
4669 Results.data(),Results.size());
Douglas Gregor3b49aca2009-11-18 16:26:39 +00004670}
4671
4672void Sema::CodeCompleteObjCImplementationDecl(Scope *S) {
4673 ResultBuilder Results(*this);
4674 Results.EnterNewScope();
4675
4676 // Add all unimplemented classes.
4677 AddInterfaceResults(Context.getTranslationUnitDecl(), CurContext, false,
4678 true, Results);
4679
4680 Results.ExitScope();
Douglas Gregore6b1bb62010-08-11 21:23:17 +00004681 HandleCodeCompleteResults(this, CodeCompleter,
4682 CodeCompletionContext::CCC_Other,
4683 Results.data(),Results.size());
Douglas Gregor3b49aca2009-11-18 16:26:39 +00004684}
Douglas Gregor33ced0b2009-11-18 19:08:43 +00004685
4686void Sema::CodeCompleteObjCInterfaceCategory(Scope *S,
Douglas Gregorc83c6872010-04-15 22:33:43 +00004687 IdentifierInfo *ClassName,
4688 SourceLocation ClassNameLoc) {
John McCall0a2c5e22010-08-25 06:19:51 +00004689 typedef CodeCompletionResult Result;
Douglas Gregor33ced0b2009-11-18 19:08:43 +00004690
4691 ResultBuilder Results(*this);
4692
4693 // Ignore any categories we find that have already been implemented by this
4694 // interface.
4695 llvm::SmallPtrSet<IdentifierInfo *, 16> CategoryNames;
4696 NamedDecl *CurClass
Douglas Gregorc83c6872010-04-15 22:33:43 +00004697 = LookupSingleName(TUScope, ClassName, ClassNameLoc, LookupOrdinaryName);
Douglas Gregor33ced0b2009-11-18 19:08:43 +00004698 if (ObjCInterfaceDecl *Class = dyn_cast_or_null<ObjCInterfaceDecl>(CurClass))
4699 for (ObjCCategoryDecl *Category = Class->getCategoryList(); Category;
4700 Category = Category->getNextClassCategory())
4701 CategoryNames.insert(Category->getIdentifier());
4702
4703 // Add all of the categories we know about.
4704 Results.EnterNewScope();
4705 TranslationUnitDecl *TU = Context.getTranslationUnitDecl();
4706 for (DeclContext::decl_iterator D = TU->decls_begin(),
4707 DEnd = TU->decls_end();
4708 D != DEnd; ++D)
4709 if (ObjCCategoryDecl *Category = dyn_cast<ObjCCategoryDecl>(*D))
4710 if (CategoryNames.insert(Category->getIdentifier()))
Douglas Gregor608300b2010-01-14 16:14:35 +00004711 Results.AddResult(Result(Category, 0), CurContext, 0, false);
Douglas Gregor33ced0b2009-11-18 19:08:43 +00004712 Results.ExitScope();
4713
Douglas Gregore6b1bb62010-08-11 21:23:17 +00004714 HandleCodeCompleteResults(this, CodeCompleter,
4715 CodeCompletionContext::CCC_Other,
4716 Results.data(),Results.size());
Douglas Gregor33ced0b2009-11-18 19:08:43 +00004717}
4718
4719void Sema::CodeCompleteObjCImplementationCategory(Scope *S,
Douglas Gregorc83c6872010-04-15 22:33:43 +00004720 IdentifierInfo *ClassName,
4721 SourceLocation ClassNameLoc) {
John McCall0a2c5e22010-08-25 06:19:51 +00004722 typedef CodeCompletionResult Result;
Douglas Gregor33ced0b2009-11-18 19:08:43 +00004723
4724 // Find the corresponding interface. If we couldn't find the interface, the
4725 // program itself is ill-formed. However, we'll try to be helpful still by
4726 // providing the list of all of the categories we know about.
4727 NamedDecl *CurClass
Douglas Gregorc83c6872010-04-15 22:33:43 +00004728 = LookupSingleName(TUScope, ClassName, ClassNameLoc, LookupOrdinaryName);
Douglas Gregor33ced0b2009-11-18 19:08:43 +00004729 ObjCInterfaceDecl *Class = dyn_cast_or_null<ObjCInterfaceDecl>(CurClass);
4730 if (!Class)
Douglas Gregorc83c6872010-04-15 22:33:43 +00004731 return CodeCompleteObjCInterfaceCategory(S, ClassName, ClassNameLoc);
Douglas Gregor33ced0b2009-11-18 19:08:43 +00004732
4733 ResultBuilder Results(*this);
4734
4735 // Add all of the categories that have have corresponding interface
4736 // declarations in this class and any of its superclasses, except for
4737 // already-implemented categories in the class itself.
4738 llvm::SmallPtrSet<IdentifierInfo *, 16> CategoryNames;
4739 Results.EnterNewScope();
4740 bool IgnoreImplemented = true;
4741 while (Class) {
4742 for (ObjCCategoryDecl *Category = Class->getCategoryList(); Category;
4743 Category = Category->getNextClassCategory())
4744 if ((!IgnoreImplemented || !Category->getImplementation()) &&
4745 CategoryNames.insert(Category->getIdentifier()))
Douglas Gregor608300b2010-01-14 16:14:35 +00004746 Results.AddResult(Result(Category, 0), CurContext, 0, false);
Douglas Gregor33ced0b2009-11-18 19:08:43 +00004747
4748 Class = Class->getSuperClass();
4749 IgnoreImplemented = false;
4750 }
4751 Results.ExitScope();
4752
Douglas Gregore6b1bb62010-08-11 21:23:17 +00004753 HandleCodeCompleteResults(this, CodeCompleter,
4754 CodeCompletionContext::CCC_Other,
4755 Results.data(),Results.size());
Douglas Gregor33ced0b2009-11-18 19:08:43 +00004756}
Douglas Gregor322328b2009-11-18 22:32:06 +00004757
John McCalld226f652010-08-21 09:40:31 +00004758void Sema::CodeCompleteObjCPropertyDefinition(Scope *S, Decl *ObjCImpDecl) {
John McCall0a2c5e22010-08-25 06:19:51 +00004759 typedef CodeCompletionResult Result;
Douglas Gregor322328b2009-11-18 22:32:06 +00004760 ResultBuilder Results(*this);
4761
4762 // Figure out where this @synthesize lives.
4763 ObjCContainerDecl *Container
John McCalld226f652010-08-21 09:40:31 +00004764 = dyn_cast_or_null<ObjCContainerDecl>(ObjCImpDecl);
Douglas Gregor322328b2009-11-18 22:32:06 +00004765 if (!Container ||
4766 (!isa<ObjCImplementationDecl>(Container) &&
4767 !isa<ObjCCategoryImplDecl>(Container)))
4768 return;
4769
4770 // Ignore any properties that have already been implemented.
4771 for (DeclContext::decl_iterator D = Container->decls_begin(),
4772 DEnd = Container->decls_end();
4773 D != DEnd; ++D)
4774 if (ObjCPropertyImplDecl *PropertyImpl = dyn_cast<ObjCPropertyImplDecl>(*D))
4775 Results.Ignore(PropertyImpl->getPropertyDecl());
4776
4777 // Add any properties that we find.
4778 Results.EnterNewScope();
4779 if (ObjCImplementationDecl *ClassImpl
4780 = dyn_cast<ObjCImplementationDecl>(Container))
4781 AddObjCProperties(ClassImpl->getClassInterface(), false, CurContext,
4782 Results);
4783 else
4784 AddObjCProperties(cast<ObjCCategoryImplDecl>(Container)->getCategoryDecl(),
4785 false, CurContext, Results);
4786 Results.ExitScope();
4787
Douglas Gregore6b1bb62010-08-11 21:23:17 +00004788 HandleCodeCompleteResults(this, CodeCompleter,
4789 CodeCompletionContext::CCC_Other,
4790 Results.data(),Results.size());
Douglas Gregor322328b2009-11-18 22:32:06 +00004791}
4792
4793void Sema::CodeCompleteObjCPropertySynthesizeIvar(Scope *S,
4794 IdentifierInfo *PropertyName,
John McCalld226f652010-08-21 09:40:31 +00004795 Decl *ObjCImpDecl) {
John McCall0a2c5e22010-08-25 06:19:51 +00004796 typedef CodeCompletionResult Result;
Douglas Gregor322328b2009-11-18 22:32:06 +00004797 ResultBuilder Results(*this);
4798
4799 // Figure out where this @synthesize lives.
4800 ObjCContainerDecl *Container
John McCalld226f652010-08-21 09:40:31 +00004801 = dyn_cast_or_null<ObjCContainerDecl>(ObjCImpDecl);
Douglas Gregor322328b2009-11-18 22:32:06 +00004802 if (!Container ||
4803 (!isa<ObjCImplementationDecl>(Container) &&
4804 !isa<ObjCCategoryImplDecl>(Container)))
4805 return;
4806
4807 // Figure out which interface we're looking into.
4808 ObjCInterfaceDecl *Class = 0;
4809 if (ObjCImplementationDecl *ClassImpl
4810 = dyn_cast<ObjCImplementationDecl>(Container))
4811 Class = ClassImpl->getClassInterface();
4812 else
4813 Class = cast<ObjCCategoryImplDecl>(Container)->getCategoryDecl()
4814 ->getClassInterface();
4815
4816 // Add all of the instance variables in this class and its superclasses.
4817 Results.EnterNewScope();
4818 for(; Class; Class = Class->getSuperClass()) {
4819 // FIXME: We could screen the type of each ivar for compatibility with
4820 // the property, but is that being too paternal?
4821 for (ObjCInterfaceDecl::ivar_iterator IVar = Class->ivar_begin(),
4822 IVarEnd = Class->ivar_end();
4823 IVar != IVarEnd; ++IVar)
Douglas Gregor608300b2010-01-14 16:14:35 +00004824 Results.AddResult(Result(*IVar, 0), CurContext, 0, false);
Douglas Gregor322328b2009-11-18 22:32:06 +00004825 }
4826 Results.ExitScope();
4827
Douglas Gregore6b1bb62010-08-11 21:23:17 +00004828 HandleCodeCompleteResults(this, CodeCompleter,
4829 CodeCompletionContext::CCC_Other,
4830 Results.data(),Results.size());
Douglas Gregor322328b2009-11-18 22:32:06 +00004831}
Douglas Gregore8f5a172010-04-07 00:21:17 +00004832
Douglas Gregor408be5a2010-08-25 01:08:01 +00004833// Mapping from selectors to the methods that implement that selector, along
4834// with the "in original class" flag.
4835typedef llvm::DenseMap<Selector, std::pair<ObjCMethodDecl *, bool> >
4836 KnownMethodsMap;
Douglas Gregore8f5a172010-04-07 00:21:17 +00004837
4838/// \brief Find all of the methods that reside in the given container
4839/// (and its superclasses, protocols, etc.) that meet the given
4840/// criteria. Insert those methods into the map of known methods,
4841/// indexed by selector so they can be easily found.
4842static void FindImplementableMethods(ASTContext &Context,
4843 ObjCContainerDecl *Container,
4844 bool WantInstanceMethods,
4845 QualType ReturnType,
4846 bool IsInImplementation,
Douglas Gregor408be5a2010-08-25 01:08:01 +00004847 KnownMethodsMap &KnownMethods,
4848 bool InOriginalClass = true) {
Douglas Gregore8f5a172010-04-07 00:21:17 +00004849 if (ObjCInterfaceDecl *IFace = dyn_cast<ObjCInterfaceDecl>(Container)) {
4850 // Recurse into protocols.
4851 const ObjCList<ObjCProtocolDecl> &Protocols
4852 = IFace->getReferencedProtocols();
4853 for (ObjCList<ObjCProtocolDecl>::iterator I = Protocols.begin(),
4854 E = Protocols.end();
4855 I != E; ++I)
4856 FindImplementableMethods(Context, *I, WantInstanceMethods, ReturnType,
Douglas Gregor408be5a2010-08-25 01:08:01 +00004857 IsInImplementation, KnownMethods,
4858 InOriginalClass);
Douglas Gregore8f5a172010-04-07 00:21:17 +00004859
4860 // If we're not in the implementation of a class, also visit the
4861 // superclass.
4862 if (!IsInImplementation && IFace->getSuperClass())
4863 FindImplementableMethods(Context, IFace->getSuperClass(),
4864 WantInstanceMethods, ReturnType,
Douglas Gregor408be5a2010-08-25 01:08:01 +00004865 IsInImplementation, KnownMethods,
4866 false);
Douglas Gregore8f5a172010-04-07 00:21:17 +00004867
4868 // Add methods from any class extensions (but not from categories;
4869 // those should go into category implementations).
Fariborz Jahanian80aa1cd2010-06-22 23:20:40 +00004870 for (const ObjCCategoryDecl *Cat = IFace->getFirstClassExtension(); Cat;
4871 Cat = Cat->getNextClassExtension())
4872 FindImplementableMethods(Context, const_cast<ObjCCategoryDecl*>(Cat),
4873 WantInstanceMethods, ReturnType,
Douglas Gregor408be5a2010-08-25 01:08:01 +00004874 IsInImplementation, KnownMethods,
4875 InOriginalClass);
Douglas Gregore8f5a172010-04-07 00:21:17 +00004876 }
4877
4878 if (ObjCCategoryDecl *Category = dyn_cast<ObjCCategoryDecl>(Container)) {
4879 // Recurse into protocols.
4880 const ObjCList<ObjCProtocolDecl> &Protocols
4881 = Category->getReferencedProtocols();
4882 for (ObjCList<ObjCProtocolDecl>::iterator I = Protocols.begin(),
4883 E = Protocols.end();
4884 I != E; ++I)
4885 FindImplementableMethods(Context, *I, WantInstanceMethods, ReturnType,
Douglas Gregor408be5a2010-08-25 01:08:01 +00004886 IsInImplementation, KnownMethods,
4887 InOriginalClass);
Douglas Gregore8f5a172010-04-07 00:21:17 +00004888 }
4889
4890 if (ObjCProtocolDecl *Protocol = dyn_cast<ObjCProtocolDecl>(Container)) {
4891 // Recurse into protocols.
4892 const ObjCList<ObjCProtocolDecl> &Protocols
4893 = Protocol->getReferencedProtocols();
4894 for (ObjCList<ObjCProtocolDecl>::iterator I = Protocols.begin(),
4895 E = Protocols.end();
4896 I != E; ++I)
4897 FindImplementableMethods(Context, *I, WantInstanceMethods, ReturnType,
Douglas Gregor408be5a2010-08-25 01:08:01 +00004898 IsInImplementation, KnownMethods, false);
Douglas Gregore8f5a172010-04-07 00:21:17 +00004899 }
4900
4901 // Add methods in this container. This operation occurs last because
4902 // we want the methods from this container to override any methods
4903 // we've previously seen with the same selector.
4904 for (ObjCContainerDecl::method_iterator M = Container->meth_begin(),
4905 MEnd = Container->meth_end();
4906 M != MEnd; ++M) {
4907 if ((*M)->isInstanceMethod() == WantInstanceMethods) {
4908 if (!ReturnType.isNull() &&
4909 !Context.hasSameUnqualifiedType(ReturnType, (*M)->getResultType()))
4910 continue;
4911
Douglas Gregor408be5a2010-08-25 01:08:01 +00004912 KnownMethods[(*M)->getSelector()] = std::make_pair(*M, InOriginalClass);
Douglas Gregore8f5a172010-04-07 00:21:17 +00004913 }
4914 }
4915}
4916
4917void Sema::CodeCompleteObjCMethodDecl(Scope *S,
4918 bool IsInstanceMethod,
John McCallb3d87482010-08-24 05:47:05 +00004919 ParsedType ReturnTy,
John McCalld226f652010-08-21 09:40:31 +00004920 Decl *IDecl) {
Douglas Gregore8f5a172010-04-07 00:21:17 +00004921 // Determine the return type of the method we're declaring, if
4922 // provided.
4923 QualType ReturnType = GetTypeFromParser(ReturnTy);
4924
4925 // Determine where we should start searching for methods, and where we
4926 ObjCContainerDecl *SearchDecl = 0, *CurrentDecl = 0;
4927 bool IsInImplementation = false;
John McCalld226f652010-08-21 09:40:31 +00004928 if (Decl *D = IDecl) {
Douglas Gregore8f5a172010-04-07 00:21:17 +00004929 if (ObjCImplementationDecl *Impl = dyn_cast<ObjCImplementationDecl>(D)) {
4930 SearchDecl = Impl->getClassInterface();
4931 CurrentDecl = Impl;
4932 IsInImplementation = true;
4933 } else if (ObjCCategoryImplDecl *CatImpl
4934 = dyn_cast<ObjCCategoryImplDecl>(D)) {
4935 SearchDecl = CatImpl->getCategoryDecl();
4936 CurrentDecl = CatImpl;
4937 IsInImplementation = true;
4938 } else {
4939 SearchDecl = dyn_cast<ObjCContainerDecl>(D);
4940 CurrentDecl = SearchDecl;
4941 }
4942 }
4943
4944 if (!SearchDecl && S) {
4945 if (DeclContext *DC = static_cast<DeclContext *>(S->getEntity())) {
4946 SearchDecl = dyn_cast<ObjCContainerDecl>(DC);
4947 CurrentDecl = SearchDecl;
4948 }
4949 }
4950
4951 if (!SearchDecl || !CurrentDecl) {
Douglas Gregore6b1bb62010-08-11 21:23:17 +00004952 HandleCodeCompleteResults(this, CodeCompleter,
4953 CodeCompletionContext::CCC_Other,
4954 0, 0);
Douglas Gregore8f5a172010-04-07 00:21:17 +00004955 return;
4956 }
4957
4958 // Find all of the methods that we could declare/implement here.
4959 KnownMethodsMap KnownMethods;
4960 FindImplementableMethods(Context, SearchDecl, IsInstanceMethod,
4961 ReturnType, IsInImplementation, KnownMethods);
4962
4963 // Erase any methods that have already been declared or
4964 // implemented here.
4965 for (ObjCContainerDecl::method_iterator M = CurrentDecl->meth_begin(),
4966 MEnd = CurrentDecl->meth_end();
4967 M != MEnd; ++M) {
4968 if ((*M)->isInstanceMethod() != IsInstanceMethod)
4969 continue;
4970
4971 KnownMethodsMap::iterator Pos = KnownMethods.find((*M)->getSelector());
4972 if (Pos != KnownMethods.end())
4973 KnownMethods.erase(Pos);
4974 }
4975
4976 // Add declarations or definitions for each of the known methods.
John McCall0a2c5e22010-08-25 06:19:51 +00004977 typedef CodeCompletionResult Result;
Douglas Gregore8f5a172010-04-07 00:21:17 +00004978 ResultBuilder Results(*this);
4979 Results.EnterNewScope();
4980 PrintingPolicy Policy(Context.PrintingPolicy);
4981 Policy.AnonymousTagLocations = false;
4982 for (KnownMethodsMap::iterator M = KnownMethods.begin(),
4983 MEnd = KnownMethods.end();
4984 M != MEnd; ++M) {
Douglas Gregor408be5a2010-08-25 01:08:01 +00004985 ObjCMethodDecl *Method = M->second.first;
Douglas Gregore8f5a172010-04-07 00:21:17 +00004986 CodeCompletionString *Pattern = new CodeCompletionString;
4987
4988 // If the result type was not already provided, add it to the
4989 // pattern as (type).
4990 if (ReturnType.isNull()) {
4991 std::string TypeStr;
4992 Method->getResultType().getAsStringInternal(TypeStr, Policy);
4993 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
4994 Pattern->AddTextChunk(TypeStr);
4995 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
4996 }
4997
4998 Selector Sel = Method->getSelector();
4999
5000 // Add the first part of the selector to the pattern.
5001 Pattern->AddTypedTextChunk(Sel.getIdentifierInfoForSlot(0)->getName());
5002
5003 // Add parameters to the pattern.
5004 unsigned I = 0;
5005 for (ObjCMethodDecl::param_iterator P = Method->param_begin(),
5006 PEnd = Method->param_end();
5007 P != PEnd; (void)++P, ++I) {
5008 // Add the part of the selector name.
5009 if (I == 0)
5010 Pattern->AddChunk(CodeCompletionString::CK_Colon);
5011 else if (I < Sel.getNumArgs()) {
5012 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
Douglas Gregor47c03a72010-08-17 15:53:35 +00005013 Pattern->AddTextChunk(Sel.getIdentifierInfoForSlot(I)->getName());
Douglas Gregore8f5a172010-04-07 00:21:17 +00005014 Pattern->AddChunk(CodeCompletionString::CK_Colon);
5015 } else
5016 break;
5017
5018 // Add the parameter type.
5019 std::string TypeStr;
5020 (*P)->getOriginalType().getAsStringInternal(TypeStr, Policy);
5021 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
5022 Pattern->AddTextChunk(TypeStr);
5023 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
5024
5025 if (IdentifierInfo *Id = (*P)->getIdentifier())
Douglas Gregore17794f2010-08-31 05:13:43 +00005026 Pattern->AddTextChunk(Id->getName());
Douglas Gregore8f5a172010-04-07 00:21:17 +00005027 }
5028
5029 if (Method->isVariadic()) {
5030 if (Method->param_size() > 0)
5031 Pattern->AddChunk(CodeCompletionString::CK_Comma);
5032 Pattern->AddTextChunk("...");
Douglas Gregore17794f2010-08-31 05:13:43 +00005033 }
Douglas Gregore8f5a172010-04-07 00:21:17 +00005034
Douglas Gregor447107d2010-05-28 00:57:46 +00005035 if (IsInImplementation && Results.includeCodePatterns()) {
Douglas Gregore8f5a172010-04-07 00:21:17 +00005036 // We will be defining the method here, so add a compound statement.
5037 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
5038 Pattern->AddChunk(CodeCompletionString::CK_LeftBrace);
5039 Pattern->AddChunk(CodeCompletionString::CK_VerticalSpace);
5040 if (!Method->getResultType()->isVoidType()) {
5041 // If the result type is not void, add a return clause.
5042 Pattern->AddTextChunk("return");
5043 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
5044 Pattern->AddPlaceholderChunk("expression");
5045 Pattern->AddChunk(CodeCompletionString::CK_SemiColon);
5046 } else
5047 Pattern->AddPlaceholderChunk("statements");
5048
5049 Pattern->AddChunk(CodeCompletionString::CK_VerticalSpace);
5050 Pattern->AddChunk(CodeCompletionString::CK_RightBrace);
5051 }
5052
Douglas Gregor408be5a2010-08-25 01:08:01 +00005053 unsigned Priority = CCP_CodePattern;
5054 if (!M->second.second)
5055 Priority += CCD_InBaseClass;
5056
5057 Results.AddResult(Result(Pattern, Priority,
Douglas Gregor16ed9ad2010-08-17 16:06:07 +00005058 Method->isInstanceMethod()
5059 ? CXCursor_ObjCInstanceMethodDecl
5060 : CXCursor_ObjCClassMethodDecl));
Douglas Gregore8f5a172010-04-07 00:21:17 +00005061 }
5062
5063 Results.ExitScope();
5064
Douglas Gregore6b1bb62010-08-11 21:23:17 +00005065 HandleCodeCompleteResults(this, CodeCompleter,
5066 CodeCompletionContext::CCC_Other,
5067 Results.data(),Results.size());
Douglas Gregore8f5a172010-04-07 00:21:17 +00005068}
Douglas Gregor1f5537a2010-07-08 23:20:03 +00005069
5070void Sema::CodeCompleteObjCMethodDeclSelector(Scope *S,
5071 bool IsInstanceMethod,
Douglas Gregor40ed9a12010-07-08 23:37:41 +00005072 bool AtParameterName,
John McCallb3d87482010-08-24 05:47:05 +00005073 ParsedType ReturnTy,
Douglas Gregor1f5537a2010-07-08 23:20:03 +00005074 IdentifierInfo **SelIdents,
5075 unsigned NumSelIdents) {
Douglas Gregor1f5537a2010-07-08 23:20:03 +00005076 // If we have an external source, load the entire class method
Sebastian Redl3c7f4132010-08-18 23:57:06 +00005077 // pool from the AST file.
Douglas Gregor1f5537a2010-07-08 23:20:03 +00005078 if (ExternalSource) {
5079 for (uint32_t I = 0, N = ExternalSource->GetNumExternalSelectors();
5080 I != N; ++I) {
5081 Selector Sel = ExternalSource->GetExternalSelector(I);
Sebastian Redldb9d2142010-08-02 23:18:59 +00005082 if (Sel.isNull() || MethodPool.count(Sel))
Douglas Gregor1f5537a2010-07-08 23:20:03 +00005083 continue;
Sebastian Redldb9d2142010-08-02 23:18:59 +00005084
5085 ReadMethodPool(Sel);
Douglas Gregor1f5537a2010-07-08 23:20:03 +00005086 }
5087 }
5088
5089 // Build the set of methods we can see.
John McCall0a2c5e22010-08-25 06:19:51 +00005090 typedef CodeCompletionResult Result;
Douglas Gregor1f5537a2010-07-08 23:20:03 +00005091 ResultBuilder Results(*this);
5092
5093 if (ReturnTy)
5094 Results.setPreferredType(GetTypeFromParser(ReturnTy).getNonReferenceType());
Sebastian Redldb9d2142010-08-02 23:18:59 +00005095
Douglas Gregor1f5537a2010-07-08 23:20:03 +00005096 Results.EnterNewScope();
Sebastian Redldb9d2142010-08-02 23:18:59 +00005097 for (GlobalMethodPool::iterator M = MethodPool.begin(),
5098 MEnd = MethodPool.end();
5099 M != MEnd; ++M) {
5100 for (ObjCMethodList *MethList = IsInstanceMethod ? &M->second.first :
5101 &M->second.second;
5102 MethList && MethList->Method;
Douglas Gregor1f5537a2010-07-08 23:20:03 +00005103 MethList = MethList->Next) {
5104 if (!isAcceptableObjCMethod(MethList->Method, MK_Any, SelIdents,
5105 NumSelIdents))
5106 continue;
5107
Douglas Gregor40ed9a12010-07-08 23:37:41 +00005108 if (AtParameterName) {
5109 // Suggest parameter names we've seen before.
5110 if (NumSelIdents && NumSelIdents <= MethList->Method->param_size()) {
5111 ParmVarDecl *Param = MethList->Method->param_begin()[NumSelIdents-1];
5112 if (Param->getIdentifier()) {
5113 CodeCompletionString *Pattern = new CodeCompletionString;
5114 Pattern->AddTypedTextChunk(Param->getIdentifier()->getName());
5115 Results.AddResult(Pattern);
5116 }
5117 }
5118
5119 continue;
5120 }
5121
Douglas Gregor1f5537a2010-07-08 23:20:03 +00005122 Result R(MethList->Method, 0);
5123 R.StartParameter = NumSelIdents;
5124 R.AllParametersAreInformative = false;
5125 R.DeclaringEntity = true;
5126 Results.MaybeAddResult(R, CurContext);
5127 }
5128 }
5129
5130 Results.ExitScope();
Douglas Gregore6b1bb62010-08-11 21:23:17 +00005131 HandleCodeCompleteResults(this, CodeCompleter,
5132 CodeCompletionContext::CCC_Other,
5133 Results.data(),Results.size());
Douglas Gregor1f5537a2010-07-08 23:20:03 +00005134}
Douglas Gregor87c08a52010-08-13 22:48:40 +00005135
Douglas Gregorf29c5232010-08-24 22:20:20 +00005136void Sema::CodeCompletePreprocessorDirective(bool InConditional) {
Douglas Gregorf44e8542010-08-24 19:08:16 +00005137 ResultBuilder Results(*this);
5138 Results.EnterNewScope();
5139
5140 // #if <condition>
5141 CodeCompletionString *Pattern = new CodeCompletionString;
5142 Pattern->AddTypedTextChunk("if");
5143 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
5144 Pattern->AddPlaceholderChunk("condition");
5145 Results.AddResult(Pattern);
5146
5147 // #ifdef <macro>
5148 Pattern = new CodeCompletionString;
5149 Pattern->AddTypedTextChunk("ifdef");
5150 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
5151 Pattern->AddPlaceholderChunk("macro");
5152 Results.AddResult(Pattern);
5153
5154 // #ifndef <macro>
5155 Pattern = new CodeCompletionString;
5156 Pattern->AddTypedTextChunk("ifndef");
5157 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
5158 Pattern->AddPlaceholderChunk("macro");
5159 Results.AddResult(Pattern);
5160
5161 if (InConditional) {
5162 // #elif <condition>
5163 Pattern = new CodeCompletionString;
5164 Pattern->AddTypedTextChunk("elif");
5165 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
5166 Pattern->AddPlaceholderChunk("condition");
5167 Results.AddResult(Pattern);
5168
5169 // #else
5170 Pattern = new CodeCompletionString;
5171 Pattern->AddTypedTextChunk("else");
5172 Results.AddResult(Pattern);
5173
5174 // #endif
5175 Pattern = new CodeCompletionString;
5176 Pattern->AddTypedTextChunk("endif");
5177 Results.AddResult(Pattern);
5178 }
5179
5180 // #include "header"
5181 Pattern = new CodeCompletionString;
5182 Pattern->AddTypedTextChunk("include");
5183 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
5184 Pattern->AddTextChunk("\"");
5185 Pattern->AddPlaceholderChunk("header");
5186 Pattern->AddTextChunk("\"");
5187 Results.AddResult(Pattern);
5188
5189 // #include <header>
5190 Pattern = new CodeCompletionString;
5191 Pattern->AddTypedTextChunk("include");
5192 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
5193 Pattern->AddTextChunk("<");
5194 Pattern->AddPlaceholderChunk("header");
5195 Pattern->AddTextChunk(">");
5196 Results.AddResult(Pattern);
5197
5198 // #define <macro>
5199 Pattern = new CodeCompletionString;
5200 Pattern->AddTypedTextChunk("define");
5201 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
5202 Pattern->AddPlaceholderChunk("macro");
5203 Results.AddResult(Pattern);
5204
5205 // #define <macro>(<args>)
5206 Pattern = new CodeCompletionString;
5207 Pattern->AddTypedTextChunk("define");
5208 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
5209 Pattern->AddPlaceholderChunk("macro");
5210 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
5211 Pattern->AddPlaceholderChunk("args");
5212 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
5213 Results.AddResult(Pattern);
5214
5215 // #undef <macro>
5216 Pattern = new CodeCompletionString;
5217 Pattern->AddTypedTextChunk("undef");
5218 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
5219 Pattern->AddPlaceholderChunk("macro");
5220 Results.AddResult(Pattern);
5221
5222 // #line <number>
5223 Pattern = new CodeCompletionString;
5224 Pattern->AddTypedTextChunk("line");
5225 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
5226 Pattern->AddPlaceholderChunk("number");
5227 Results.AddResult(Pattern);
5228
5229 // #line <number> "filename"
5230 Pattern = new CodeCompletionString;
5231 Pattern->AddTypedTextChunk("line");
5232 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
5233 Pattern->AddPlaceholderChunk("number");
5234 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
5235 Pattern->AddTextChunk("\"");
5236 Pattern->AddPlaceholderChunk("filename");
5237 Pattern->AddTextChunk("\"");
5238 Results.AddResult(Pattern);
5239
5240 // #error <message>
5241 Pattern = new CodeCompletionString;
5242 Pattern->AddTypedTextChunk("error");
5243 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
5244 Pattern->AddPlaceholderChunk("message");
5245 Results.AddResult(Pattern);
5246
5247 // #pragma <arguments>
5248 Pattern = new CodeCompletionString;
5249 Pattern->AddTypedTextChunk("pragma");
5250 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
5251 Pattern->AddPlaceholderChunk("arguments");
5252 Results.AddResult(Pattern);
5253
5254 if (getLangOptions().ObjC1) {
5255 // #import "header"
5256 Pattern = new CodeCompletionString;
5257 Pattern->AddTypedTextChunk("import");
5258 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
5259 Pattern->AddTextChunk("\"");
5260 Pattern->AddPlaceholderChunk("header");
5261 Pattern->AddTextChunk("\"");
5262 Results.AddResult(Pattern);
5263
5264 // #import <header>
5265 Pattern = new CodeCompletionString;
5266 Pattern->AddTypedTextChunk("import");
5267 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
5268 Pattern->AddTextChunk("<");
5269 Pattern->AddPlaceholderChunk("header");
5270 Pattern->AddTextChunk(">");
5271 Results.AddResult(Pattern);
5272 }
5273
5274 // #include_next "header"
5275 Pattern = new CodeCompletionString;
5276 Pattern->AddTypedTextChunk("include_next");
5277 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
5278 Pattern->AddTextChunk("\"");
5279 Pattern->AddPlaceholderChunk("header");
5280 Pattern->AddTextChunk("\"");
5281 Results.AddResult(Pattern);
5282
5283 // #include_next <header>
5284 Pattern = new CodeCompletionString;
5285 Pattern->AddTypedTextChunk("include_next");
5286 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
5287 Pattern->AddTextChunk("<");
5288 Pattern->AddPlaceholderChunk("header");
5289 Pattern->AddTextChunk(">");
5290 Results.AddResult(Pattern);
5291
5292 // #warning <message>
5293 Pattern = new CodeCompletionString;
5294 Pattern->AddTypedTextChunk("warning");
5295 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
5296 Pattern->AddPlaceholderChunk("message");
5297 Results.AddResult(Pattern);
5298
5299 // Note: #ident and #sccs are such crazy anachronisms that we don't provide
5300 // completions for them. And __include_macros is a Clang-internal extension
5301 // that we don't want to encourage anyone to use.
5302
5303 // FIXME: we don't support #assert or #unassert, so don't suggest them.
5304 Results.ExitScope();
5305
Douglas Gregorf44e8542010-08-24 19:08:16 +00005306 HandleCodeCompleteResults(this, CodeCompleter,
Douglas Gregor721f3592010-08-25 18:41:16 +00005307 CodeCompletionContext::CCC_PreprocessorDirective,
Douglas Gregorf44e8542010-08-24 19:08:16 +00005308 Results.data(), Results.size());
5309}
5310
5311void Sema::CodeCompleteInPreprocessorConditionalExclusion(Scope *S) {
Douglas Gregorf29c5232010-08-24 22:20:20 +00005312 CodeCompleteOrdinaryName(S,
John McCallf312b1e2010-08-26 23:41:50 +00005313 S->getFnParent()? Sema::PCC_RecoveryInFunction
5314 : Sema::PCC_Namespace);
Douglas Gregorf44e8542010-08-24 19:08:16 +00005315}
5316
Douglas Gregorf29c5232010-08-24 22:20:20 +00005317void Sema::CodeCompletePreprocessorMacroName(bool IsDefinition) {
Douglas Gregor1fbb4472010-08-24 20:21:13 +00005318 ResultBuilder Results(*this);
5319 if (!IsDefinition && (!CodeCompleter || CodeCompleter->includeMacros())) {
5320 // Add just the names of macros, not their arguments.
5321 Results.EnterNewScope();
5322 for (Preprocessor::macro_iterator M = PP.macro_begin(),
5323 MEnd = PP.macro_end();
5324 M != MEnd; ++M) {
5325 CodeCompletionString *Pattern = new CodeCompletionString;
5326 Pattern->AddTypedTextChunk(M->first->getName());
5327 Results.AddResult(Pattern);
5328 }
5329 Results.ExitScope();
5330 } else if (IsDefinition) {
5331 // FIXME: Can we detect when the user just wrote an include guard above?
5332 }
5333
5334 HandleCodeCompleteResults(this, CodeCompleter,
5335 IsDefinition? CodeCompletionContext::CCC_MacroName
5336 : CodeCompletionContext::CCC_MacroNameUse,
5337 Results.data(), Results.size());
5338}
5339
Douglas Gregorf29c5232010-08-24 22:20:20 +00005340void Sema::CodeCompletePreprocessorExpression() {
5341 ResultBuilder Results(*this);
5342
5343 if (!CodeCompleter || CodeCompleter->includeMacros())
5344 AddMacroResults(PP, Results);
5345
5346 // defined (<macro>)
5347 Results.EnterNewScope();
5348 CodeCompletionString *Pattern = new CodeCompletionString;
5349 Pattern->AddTypedTextChunk("defined");
5350 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
5351 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
5352 Pattern->AddPlaceholderChunk("macro");
5353 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
5354 Results.AddResult(Pattern);
5355 Results.ExitScope();
5356
5357 HandleCodeCompleteResults(this, CodeCompleter,
5358 CodeCompletionContext::CCC_PreprocessorExpression,
5359 Results.data(), Results.size());
5360}
5361
5362void Sema::CodeCompletePreprocessorMacroArgument(Scope *S,
5363 IdentifierInfo *Macro,
5364 MacroInfo *MacroInfo,
5365 unsigned Argument) {
5366 // FIXME: In the future, we could provide "overload" results, much like we
5367 // do for function calls.
5368
5369 CodeCompleteOrdinaryName(S,
John McCallf312b1e2010-08-26 23:41:50 +00005370 S->getFnParent()? Sema::PCC_RecoveryInFunction
5371 : Sema::PCC_Namespace);
Douglas Gregorf29c5232010-08-24 22:20:20 +00005372}
5373
Douglas Gregor55817af2010-08-25 17:04:25 +00005374void Sema::CodeCompleteNaturalLanguage() {
Douglas Gregor55817af2010-08-25 17:04:25 +00005375 HandleCodeCompleteResults(this, CodeCompleter,
Douglas Gregoraf1c6b52010-08-25 17:10:00 +00005376 CodeCompletionContext::CCC_NaturalLanguage,
Douglas Gregor55817af2010-08-25 17:04:25 +00005377 0, 0);
5378}
5379
Douglas Gregor87c08a52010-08-13 22:48:40 +00005380void Sema::GatherGlobalCodeCompletions(
John McCall0a2c5e22010-08-25 06:19:51 +00005381 llvm::SmallVectorImpl<CodeCompletionResult> &Results) {
Douglas Gregor87c08a52010-08-13 22:48:40 +00005382 ResultBuilder Builder(*this);
5383
Douglas Gregor8071e422010-08-15 06:18:01 +00005384 if (!CodeCompleter || CodeCompleter->includeGlobals()) {
5385 CodeCompletionDeclConsumer Consumer(Builder,
5386 Context.getTranslationUnitDecl());
5387 LookupVisibleDecls(Context.getTranslationUnitDecl(), LookupAnyName,
5388 Consumer);
5389 }
Douglas Gregor87c08a52010-08-13 22:48:40 +00005390
5391 if (!CodeCompleter || CodeCompleter->includeMacros())
5392 AddMacroResults(PP, Builder);
5393
5394 Results.clear();
5395 Results.insert(Results.end(),
5396 Builder.data(), Builder.data() + Builder.size());
5397}