blob: 135c59365b79d07e75f2eb74117d0da4b07b8155 [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.
Douglas Gregor38276252010-09-08 22:47:51 +00001833 std::string Result;
1834 QualType ResultType = Block->getTypePtr()->getResultType();
1835 if (!ResultType->isVoidType())
1836 ResultType.getAsStringInternal(Result, Context.PrintingPolicy);
1837
1838 Result = '^' + Result;
1839 if (Block->getNumArgs() == 0) {
1840 if (Block->getTypePtr()->isVariadic())
1841 Result += "(...)";
1842 } else {
1843 Result += "(";
1844 for (unsigned I = 0, N = Block->getNumArgs(); I != N; ++I) {
1845 if (I)
1846 Result += ", ";
1847 Result += FormatFunctionParameter(Context, Block->getArg(I));
1848
1849 if (I == N - 1 && Block->getTypePtr()->isVariadic())
1850 Result += ", ...";
1851 }
1852 Result += ")";
Douglas Gregore17794f2010-08-31 05:13:43 +00001853 }
Douglas Gregor38276252010-09-08 22:47:51 +00001854
Douglas Gregor83482d12010-08-24 16:15:59 +00001855 return Result;
1856}
1857
Douglas Gregor86d9a522009-09-21 16:56:56 +00001858/// \brief Add function parameter chunks to the given code completion string.
1859static void AddFunctionParameterChunks(ASTContext &Context,
1860 FunctionDecl *Function,
1861 CodeCompletionString *Result) {
Douglas Gregor0c8296d2009-11-07 00:00:49 +00001862 typedef CodeCompletionString::Chunk Chunk;
1863
Douglas Gregor86d9a522009-09-21 16:56:56 +00001864 CodeCompletionString *CCStr = Result;
1865
1866 for (unsigned P = 0, N = Function->getNumParams(); P != N; ++P) {
1867 ParmVarDecl *Param = Function->getParamDecl(P);
1868
1869 if (Param->hasDefaultArg()) {
1870 // When we see an optional default argument, put that argument and
1871 // the remaining default arguments into a new, optional string.
1872 CodeCompletionString *Opt = new CodeCompletionString;
1873 CCStr->AddOptionalChunk(std::auto_ptr<CodeCompletionString>(Opt));
1874 CCStr = Opt;
1875 }
1876
1877 if (P != 0)
Douglas Gregor0c8296d2009-11-07 00:00:49 +00001878 CCStr->AddChunk(Chunk(CodeCompletionString::CK_Comma));
Douglas Gregor86d9a522009-09-21 16:56:56 +00001879
1880 // Format the placeholder string.
Douglas Gregor83482d12010-08-24 16:15:59 +00001881 std::string PlaceholderStr = FormatFunctionParameter(Context, Param);
1882
Douglas Gregore17794f2010-08-31 05:13:43 +00001883 if (Function->isVariadic() && P == N - 1)
1884 PlaceholderStr += ", ...";
1885
Douglas Gregor86d9a522009-09-21 16:56:56 +00001886 // Add the placeholder string.
Benjamin Kramer660cc182009-11-29 20:18:50 +00001887 CCStr->AddPlaceholderChunk(PlaceholderStr);
Douglas Gregor86d9a522009-09-21 16:56:56 +00001888 }
Douglas Gregorb3d45252009-09-22 21:42:17 +00001889
1890 if (const FunctionProtoType *Proto
1891 = Function->getType()->getAs<FunctionProtoType>())
Douglas Gregoraaa107a2010-08-23 23:51:41 +00001892 if (Proto->isVariadic()) {
Douglas Gregore17794f2010-08-31 05:13:43 +00001893 if (Proto->getNumArgs() == 0)
1894 CCStr->AddPlaceholderChunk("...");
Douglas Gregoraaa107a2010-08-23 23:51:41 +00001895
1896 MaybeAddSentinel(Context, Function, CCStr);
1897 }
Douglas Gregor86d9a522009-09-21 16:56:56 +00001898}
1899
1900/// \brief Add template parameter chunks to the given code completion string.
1901static void AddTemplateParameterChunks(ASTContext &Context,
1902 TemplateDecl *Template,
1903 CodeCompletionString *Result,
1904 unsigned MaxParameters = 0) {
Douglas Gregor0c8296d2009-11-07 00:00:49 +00001905 typedef CodeCompletionString::Chunk Chunk;
1906
Douglas Gregor86d9a522009-09-21 16:56:56 +00001907 CodeCompletionString *CCStr = Result;
1908 bool FirstParameter = true;
1909
1910 TemplateParameterList *Params = Template->getTemplateParameters();
1911 TemplateParameterList::iterator PEnd = Params->end();
1912 if (MaxParameters)
1913 PEnd = Params->begin() + MaxParameters;
1914 for (TemplateParameterList::iterator P = Params->begin(); P != PEnd; ++P) {
1915 bool HasDefaultArg = false;
1916 std::string PlaceholderStr;
1917 if (TemplateTypeParmDecl *TTP = dyn_cast<TemplateTypeParmDecl>(*P)) {
1918 if (TTP->wasDeclaredWithTypename())
1919 PlaceholderStr = "typename";
1920 else
1921 PlaceholderStr = "class";
1922
1923 if (TTP->getIdentifier()) {
1924 PlaceholderStr += ' ';
1925 PlaceholderStr += TTP->getIdentifier()->getName();
1926 }
1927
1928 HasDefaultArg = TTP->hasDefaultArgument();
1929 } else if (NonTypeTemplateParmDecl *NTTP
1930 = dyn_cast<NonTypeTemplateParmDecl>(*P)) {
1931 if (NTTP->getIdentifier())
1932 PlaceholderStr = NTTP->getIdentifier()->getName();
1933 NTTP->getType().getAsStringInternal(PlaceholderStr,
1934 Context.PrintingPolicy);
1935 HasDefaultArg = NTTP->hasDefaultArgument();
1936 } else {
1937 assert(isa<TemplateTemplateParmDecl>(*P));
1938 TemplateTemplateParmDecl *TTP = cast<TemplateTemplateParmDecl>(*P);
1939
1940 // Since putting the template argument list into the placeholder would
1941 // be very, very long, we just use an abbreviation.
1942 PlaceholderStr = "template<...> class";
1943 if (TTP->getIdentifier()) {
1944 PlaceholderStr += ' ';
1945 PlaceholderStr += TTP->getIdentifier()->getName();
1946 }
1947
1948 HasDefaultArg = TTP->hasDefaultArgument();
1949 }
1950
1951 if (HasDefaultArg) {
1952 // When we see an optional default argument, put that argument and
1953 // the remaining default arguments into a new, optional string.
1954 CodeCompletionString *Opt = new CodeCompletionString;
1955 CCStr->AddOptionalChunk(std::auto_ptr<CodeCompletionString>(Opt));
1956 CCStr = Opt;
1957 }
1958
1959 if (FirstParameter)
1960 FirstParameter = false;
1961 else
Douglas Gregor0c8296d2009-11-07 00:00:49 +00001962 CCStr->AddChunk(Chunk(CodeCompletionString::CK_Comma));
Douglas Gregor86d9a522009-09-21 16:56:56 +00001963
1964 // Add the placeholder string.
Benjamin Kramer660cc182009-11-29 20:18:50 +00001965 CCStr->AddPlaceholderChunk(PlaceholderStr);
Douglas Gregor86d9a522009-09-21 16:56:56 +00001966 }
1967}
1968
Douglas Gregorb9d0ef72009-09-21 19:57:38 +00001969/// \brief Add a qualifier to the given code-completion string, if the
1970/// provided nested-name-specifier is non-NULL.
Douglas Gregora61a8792009-12-11 18:44:16 +00001971static void
1972AddQualifierToCompletionString(CodeCompletionString *Result,
1973 NestedNameSpecifier *Qualifier,
1974 bool QualifierIsInformative,
1975 ASTContext &Context) {
Douglas Gregorb9d0ef72009-09-21 19:57:38 +00001976 if (!Qualifier)
1977 return;
1978
1979 std::string PrintedNNS;
1980 {
1981 llvm::raw_string_ostream OS(PrintedNNS);
1982 Qualifier->print(OS, Context.PrintingPolicy);
1983 }
Douglas Gregor0563c262009-09-22 23:15:58 +00001984 if (QualifierIsInformative)
Benjamin Kramer660cc182009-11-29 20:18:50 +00001985 Result->AddInformativeChunk(PrintedNNS);
Douglas Gregor0563c262009-09-22 23:15:58 +00001986 else
Benjamin Kramer660cc182009-11-29 20:18:50 +00001987 Result->AddTextChunk(PrintedNNS);
Douglas Gregorb9d0ef72009-09-21 19:57:38 +00001988}
1989
Douglas Gregora61a8792009-12-11 18:44:16 +00001990static void AddFunctionTypeQualsToCompletionString(CodeCompletionString *Result,
1991 FunctionDecl *Function) {
1992 const FunctionProtoType *Proto
1993 = Function->getType()->getAs<FunctionProtoType>();
1994 if (!Proto || !Proto->getTypeQuals())
1995 return;
1996
1997 std::string QualsStr;
1998 if (Proto->getTypeQuals() & Qualifiers::Const)
1999 QualsStr += " const";
2000 if (Proto->getTypeQuals() & Qualifiers::Volatile)
2001 QualsStr += " volatile";
2002 if (Proto->getTypeQuals() & Qualifiers::Restrict)
2003 QualsStr += " restrict";
2004 Result->AddInformativeChunk(QualsStr);
2005}
2006
Douglas Gregor86d9a522009-09-21 16:56:56 +00002007/// \brief If possible, create a new code completion string for the given
2008/// result.
2009///
2010/// \returns Either a new, heap-allocated code completion string describing
2011/// how to use this result, or NULL to indicate that the string or name of the
2012/// result is all that is needed.
2013CodeCompletionString *
John McCall0a2c5e22010-08-25 06:19:51 +00002014CodeCompletionResult::CreateCodeCompletionString(Sema &S,
Douglas Gregor1abc6bc2010-08-04 16:47:14 +00002015 CodeCompletionString *Result) {
Douglas Gregor0c8296d2009-11-07 00:00:49 +00002016 typedef CodeCompletionString::Chunk Chunk;
2017
Douglas Gregor2b4074f2009-12-01 05:55:20 +00002018 if (Kind == RK_Pattern)
Douglas Gregor1abc6bc2010-08-04 16:47:14 +00002019 return Pattern->Clone(Result);
Douglas Gregor2b4074f2009-12-01 05:55:20 +00002020
Douglas Gregor1abc6bc2010-08-04 16:47:14 +00002021 if (!Result)
2022 Result = new CodeCompletionString;
Douglas Gregor2b4074f2009-12-01 05:55:20 +00002023
2024 if (Kind == RK_Keyword) {
2025 Result->AddTypedTextChunk(Keyword);
2026 return Result;
2027 }
Douglas Gregor86d9a522009-09-21 16:56:56 +00002028
Douglas Gregor3f7c7f42009-10-30 16:50:04 +00002029 if (Kind == RK_Macro) {
2030 MacroInfo *MI = S.PP.getMacroInfo(Macro);
Douglas Gregor2b4074f2009-12-01 05:55:20 +00002031 assert(MI && "Not a macro?");
2032
2033 Result->AddTypedTextChunk(Macro->getName());
2034
2035 if (!MI->isFunctionLike())
2036 return Result;
Douglas Gregor3f7c7f42009-10-30 16:50:04 +00002037
2038 // Format a function-like macro with placeholders for the arguments.
Douglas Gregor0c8296d2009-11-07 00:00:49 +00002039 Result->AddChunk(Chunk(CodeCompletionString::CK_LeftParen));
Douglas Gregor3f7c7f42009-10-30 16:50:04 +00002040 for (MacroInfo::arg_iterator A = MI->arg_begin(), AEnd = MI->arg_end();
2041 A != AEnd; ++A) {
2042 if (A != MI->arg_begin())
Douglas Gregor0c8296d2009-11-07 00:00:49 +00002043 Result->AddChunk(Chunk(CodeCompletionString::CK_Comma));
Douglas Gregor3f7c7f42009-10-30 16:50:04 +00002044
2045 if (!MI->isVariadic() || A != AEnd - 1) {
2046 // Non-variadic argument.
Benjamin Kramer660cc182009-11-29 20:18:50 +00002047 Result->AddPlaceholderChunk((*A)->getName());
Douglas Gregor3f7c7f42009-10-30 16:50:04 +00002048 continue;
2049 }
2050
2051 // Variadic argument; cope with the different between GNU and C99
2052 // variadic macros, providing a single placeholder for the rest of the
2053 // arguments.
2054 if ((*A)->isStr("__VA_ARGS__"))
2055 Result->AddPlaceholderChunk("...");
2056 else {
2057 std::string Arg = (*A)->getName();
2058 Arg += "...";
Benjamin Kramer660cc182009-11-29 20:18:50 +00002059 Result->AddPlaceholderChunk(Arg);
Douglas Gregor3f7c7f42009-10-30 16:50:04 +00002060 }
2061 }
Douglas Gregor0c8296d2009-11-07 00:00:49 +00002062 Result->AddChunk(Chunk(CodeCompletionString::CK_RightParen));
Douglas Gregor3f7c7f42009-10-30 16:50:04 +00002063 return Result;
2064 }
2065
Douglas Gregord8e8a582010-05-25 21:41:55 +00002066 assert(Kind == RK_Declaration && "Missed a result kind?");
Douglas Gregor86d9a522009-09-21 16:56:56 +00002067 NamedDecl *ND = Declaration;
2068
Douglas Gregor0c8296d2009-11-07 00:00:49 +00002069 if (StartsNestedNameSpecifier) {
Benjamin Kramer660cc182009-11-29 20:18:50 +00002070 Result->AddTypedTextChunk(ND->getNameAsString());
Douglas Gregor0c8296d2009-11-07 00:00:49 +00002071 Result->AddTextChunk("::");
2072 return Result;
2073 }
2074
Douglas Gregorff5ce6e2009-12-18 18:53:37 +00002075 AddResultTypeChunk(S.Context, ND, Result);
2076
Douglas Gregor86d9a522009-09-21 16:56:56 +00002077 if (FunctionDecl *Function = dyn_cast<FunctionDecl>(ND)) {
Douglas Gregor0563c262009-09-22 23:15:58 +00002078 AddQualifierToCompletionString(Result, Qualifier, QualifierIsInformative,
2079 S.Context);
Benjamin Kramer660cc182009-11-29 20:18:50 +00002080 Result->AddTypedTextChunk(Function->getNameAsString());
Douglas Gregor0c8296d2009-11-07 00:00:49 +00002081 Result->AddChunk(Chunk(CodeCompletionString::CK_LeftParen));
Douglas Gregor86d9a522009-09-21 16:56:56 +00002082 AddFunctionParameterChunks(S.Context, Function, Result);
Douglas Gregor0c8296d2009-11-07 00:00:49 +00002083 Result->AddChunk(Chunk(CodeCompletionString::CK_RightParen));
Douglas Gregora61a8792009-12-11 18:44:16 +00002084 AddFunctionTypeQualsToCompletionString(Result, Function);
Douglas Gregor86d9a522009-09-21 16:56:56 +00002085 return Result;
2086 }
2087
2088 if (FunctionTemplateDecl *FunTmpl = dyn_cast<FunctionTemplateDecl>(ND)) {
Douglas Gregor0563c262009-09-22 23:15:58 +00002089 AddQualifierToCompletionString(Result, Qualifier, QualifierIsInformative,
2090 S.Context);
Douglas Gregor86d9a522009-09-21 16:56:56 +00002091 FunctionDecl *Function = FunTmpl->getTemplatedDecl();
Benjamin Kramer660cc182009-11-29 20:18:50 +00002092 Result->AddTypedTextChunk(Function->getNameAsString());
Douglas Gregor86d9a522009-09-21 16:56:56 +00002093
2094 // Figure out which template parameters are deduced (or have default
2095 // arguments).
2096 llvm::SmallVector<bool, 16> Deduced;
2097 S.MarkDeducedTemplateParameters(FunTmpl, Deduced);
2098 unsigned LastDeducibleArgument;
2099 for (LastDeducibleArgument = Deduced.size(); LastDeducibleArgument > 0;
2100 --LastDeducibleArgument) {
2101 if (!Deduced[LastDeducibleArgument - 1]) {
2102 // C++0x: Figure out if the template argument has a default. If so,
2103 // the user doesn't need to type this argument.
2104 // FIXME: We need to abstract template parameters better!
2105 bool HasDefaultArg = false;
2106 NamedDecl *Param = FunTmpl->getTemplateParameters()->getParam(
2107 LastDeducibleArgument - 1);
2108 if (TemplateTypeParmDecl *TTP = dyn_cast<TemplateTypeParmDecl>(Param))
2109 HasDefaultArg = TTP->hasDefaultArgument();
2110 else if (NonTypeTemplateParmDecl *NTTP
2111 = dyn_cast<NonTypeTemplateParmDecl>(Param))
2112 HasDefaultArg = NTTP->hasDefaultArgument();
2113 else {
2114 assert(isa<TemplateTemplateParmDecl>(Param));
2115 HasDefaultArg
Douglas Gregor0c8296d2009-11-07 00:00:49 +00002116 = cast<TemplateTemplateParmDecl>(Param)->hasDefaultArgument();
Douglas Gregor86d9a522009-09-21 16:56:56 +00002117 }
2118
2119 if (!HasDefaultArg)
2120 break;
2121 }
2122 }
2123
2124 if (LastDeducibleArgument) {
2125 // Some of the function template arguments cannot be deduced from a
2126 // function call, so we introduce an explicit template argument list
2127 // containing all of the arguments up to the first deducible argument.
Douglas Gregor0c8296d2009-11-07 00:00:49 +00002128 Result->AddChunk(Chunk(CodeCompletionString::CK_LeftAngle));
Douglas Gregor86d9a522009-09-21 16:56:56 +00002129 AddTemplateParameterChunks(S.Context, FunTmpl, Result,
2130 LastDeducibleArgument);
Douglas Gregor0c8296d2009-11-07 00:00:49 +00002131 Result->AddChunk(Chunk(CodeCompletionString::CK_RightAngle));
Douglas Gregor86d9a522009-09-21 16:56:56 +00002132 }
2133
2134 // Add the function parameters
Douglas Gregor0c8296d2009-11-07 00:00:49 +00002135 Result->AddChunk(Chunk(CodeCompletionString::CK_LeftParen));
Douglas Gregor86d9a522009-09-21 16:56:56 +00002136 AddFunctionParameterChunks(S.Context, Function, Result);
Douglas Gregor0c8296d2009-11-07 00:00:49 +00002137 Result->AddChunk(Chunk(CodeCompletionString::CK_RightParen));
Douglas Gregora61a8792009-12-11 18:44:16 +00002138 AddFunctionTypeQualsToCompletionString(Result, Function);
Douglas Gregor86d9a522009-09-21 16:56:56 +00002139 return Result;
2140 }
2141
2142 if (TemplateDecl *Template = dyn_cast<TemplateDecl>(ND)) {
Douglas Gregor0563c262009-09-22 23:15:58 +00002143 AddQualifierToCompletionString(Result, Qualifier, QualifierIsInformative,
2144 S.Context);
Benjamin Kramer660cc182009-11-29 20:18:50 +00002145 Result->AddTypedTextChunk(Template->getNameAsString());
Douglas Gregor0c8296d2009-11-07 00:00:49 +00002146 Result->AddChunk(Chunk(CodeCompletionString::CK_LeftAngle));
Douglas Gregor86d9a522009-09-21 16:56:56 +00002147 AddTemplateParameterChunks(S.Context, Template, Result);
Douglas Gregor0c8296d2009-11-07 00:00:49 +00002148 Result->AddChunk(Chunk(CodeCompletionString::CK_RightAngle));
Douglas Gregor86d9a522009-09-21 16:56:56 +00002149 return Result;
2150 }
2151
Douglas Gregor9630eb62009-11-17 16:44:22 +00002152 if (ObjCMethodDecl *Method = dyn_cast<ObjCMethodDecl>(ND)) {
Douglas Gregor9630eb62009-11-17 16:44:22 +00002153 Selector Sel = Method->getSelector();
2154 if (Sel.isUnarySelector()) {
2155 Result->AddTypedTextChunk(Sel.getIdentifierInfoForSlot(0)->getName());
2156 return Result;
2157 }
2158
Douglas Gregord3c68542009-11-19 01:08:35 +00002159 std::string SelName = Sel.getIdentifierInfoForSlot(0)->getName().str();
2160 SelName += ':';
2161 if (StartParameter == 0)
2162 Result->AddTypedTextChunk(SelName);
2163 else {
2164 Result->AddInformativeChunk(SelName);
2165
2166 // If there is only one parameter, and we're past it, add an empty
2167 // typed-text chunk since there is nothing to type.
2168 if (Method->param_size() == 1)
2169 Result->AddTypedTextChunk("");
2170 }
Douglas Gregor9630eb62009-11-17 16:44:22 +00002171 unsigned Idx = 0;
2172 for (ObjCMethodDecl::param_iterator P = Method->param_begin(),
2173 PEnd = Method->param_end();
2174 P != PEnd; (void)++P, ++Idx) {
2175 if (Idx > 0) {
Douglas Gregord3c68542009-11-19 01:08:35 +00002176 std::string Keyword;
2177 if (Idx > StartParameter)
Douglas Gregor834389b2010-01-12 06:38:28 +00002178 Result->AddChunk(CodeCompletionString::CK_HorizontalSpace);
Douglas Gregor9630eb62009-11-17 16:44:22 +00002179 if (IdentifierInfo *II = Sel.getIdentifierInfoForSlot(Idx))
2180 Keyword += II->getName().str();
2181 Keyword += ":";
Douglas Gregor1f5537a2010-07-08 23:20:03 +00002182 if (Idx < StartParameter || AllParametersAreInformative)
Douglas Gregord3c68542009-11-19 01:08:35 +00002183 Result->AddInformativeChunk(Keyword);
Douglas Gregor1f5537a2010-07-08 23:20:03 +00002184 else if (Idx == StartParameter)
Douglas Gregord3c68542009-11-19 01:08:35 +00002185 Result->AddTypedTextChunk(Keyword);
2186 else
2187 Result->AddTextChunk(Keyword);
Douglas Gregor9630eb62009-11-17 16:44:22 +00002188 }
Douglas Gregord3c68542009-11-19 01:08:35 +00002189
2190 // If we're before the starting parameter, skip the placeholder.
2191 if (Idx < StartParameter)
2192 continue;
Douglas Gregor9630eb62009-11-17 16:44:22 +00002193
2194 std::string Arg;
Douglas Gregor83482d12010-08-24 16:15:59 +00002195
2196 if ((*P)->getType()->isBlockPointerType() && !DeclaringEntity)
Douglas Gregoraba48082010-08-29 19:47:46 +00002197 Arg = FormatFunctionParameter(S.Context, *P, true);
Douglas Gregor83482d12010-08-24 16:15:59 +00002198 else {
2199 (*P)->getType().getAsStringInternal(Arg, S.Context.PrintingPolicy);
2200 Arg = "(" + Arg + ")";
2201 if (IdentifierInfo *II = (*P)->getIdentifier())
Douglas Gregoraba48082010-08-29 19:47:46 +00002202 if (DeclaringEntity || AllParametersAreInformative)
2203 Arg += II->getName().str();
Douglas Gregor83482d12010-08-24 16:15:59 +00002204 }
2205
Douglas Gregore17794f2010-08-31 05:13:43 +00002206 if (Method->isVariadic() && (P + 1) == PEnd)
2207 Arg += ", ...";
2208
Douglas Gregor1f5537a2010-07-08 23:20:03 +00002209 if (DeclaringEntity)
2210 Result->AddTextChunk(Arg);
2211 else if (AllParametersAreInformative)
Douglas Gregor4ad96852009-11-19 07:41:15 +00002212 Result->AddInformativeChunk(Arg);
2213 else
2214 Result->AddPlaceholderChunk(Arg);
Douglas Gregor9630eb62009-11-17 16:44:22 +00002215 }
2216
Douglas Gregor2a17af02009-12-23 00:21:46 +00002217 if (Method->isVariadic()) {
Douglas Gregore17794f2010-08-31 05:13:43 +00002218 if (Method->param_size() == 0) {
2219 if (DeclaringEntity)
2220 Result->AddTextChunk(", ...");
2221 else if (AllParametersAreInformative)
2222 Result->AddInformativeChunk(", ...");
2223 else
2224 Result->AddPlaceholderChunk(", ...");
2225 }
Douglas Gregoraaa107a2010-08-23 23:51:41 +00002226
2227 MaybeAddSentinel(S.Context, Method, Result);
Douglas Gregor2a17af02009-12-23 00:21:46 +00002228 }
2229
Douglas Gregor9630eb62009-11-17 16:44:22 +00002230 return Result;
2231 }
2232
Douglas Gregor2b4074f2009-12-01 05:55:20 +00002233 if (Qualifier)
Douglas Gregor0563c262009-09-22 23:15:58 +00002234 AddQualifierToCompletionString(Result, Qualifier, QualifierIsInformative,
2235 S.Context);
Douglas Gregor2b4074f2009-12-01 05:55:20 +00002236
2237 Result->AddTypedTextChunk(ND->getNameAsString());
2238 return Result;
Douglas Gregor86d9a522009-09-21 16:56:56 +00002239}
2240
Douglas Gregor86d802e2009-09-23 00:34:09 +00002241CodeCompletionString *
2242CodeCompleteConsumer::OverloadCandidate::CreateSignatureString(
2243 unsigned CurrentArg,
2244 Sema &S) const {
Douglas Gregor0c8296d2009-11-07 00:00:49 +00002245 typedef CodeCompletionString::Chunk Chunk;
2246
Douglas Gregor86d802e2009-09-23 00:34:09 +00002247 CodeCompletionString *Result = new CodeCompletionString;
2248 FunctionDecl *FDecl = getFunction();
Douglas Gregorff5ce6e2009-12-18 18:53:37 +00002249 AddResultTypeChunk(S.Context, FDecl, Result);
Douglas Gregor86d802e2009-09-23 00:34:09 +00002250 const FunctionProtoType *Proto
2251 = dyn_cast<FunctionProtoType>(getFunctionType());
2252 if (!FDecl && !Proto) {
2253 // Function without a prototype. Just give the return type and a
2254 // highlighted ellipsis.
2255 const FunctionType *FT = getFunctionType();
2256 Result->AddTextChunk(
Benjamin Kramer660cc182009-11-29 20:18:50 +00002257 FT->getResultType().getAsString(S.Context.PrintingPolicy));
Douglas Gregor0c8296d2009-11-07 00:00:49 +00002258 Result->AddChunk(Chunk(CodeCompletionString::CK_LeftParen));
2259 Result->AddChunk(Chunk(CodeCompletionString::CK_CurrentParameter, "..."));
2260 Result->AddChunk(Chunk(CodeCompletionString::CK_RightParen));
Douglas Gregor86d802e2009-09-23 00:34:09 +00002261 return Result;
2262 }
2263
2264 if (FDecl)
Benjamin Kramer660cc182009-11-29 20:18:50 +00002265 Result->AddTextChunk(FDecl->getNameAsString());
Douglas Gregor86d802e2009-09-23 00:34:09 +00002266 else
2267 Result->AddTextChunk(
Benjamin Kramer660cc182009-11-29 20:18:50 +00002268 Proto->getResultType().getAsString(S.Context.PrintingPolicy));
Douglas Gregor86d802e2009-09-23 00:34:09 +00002269
Douglas Gregor0c8296d2009-11-07 00:00:49 +00002270 Result->AddChunk(Chunk(CodeCompletionString::CK_LeftParen));
Douglas Gregor86d802e2009-09-23 00:34:09 +00002271 unsigned NumParams = FDecl? FDecl->getNumParams() : Proto->getNumArgs();
2272 for (unsigned I = 0; I != NumParams; ++I) {
2273 if (I)
Douglas Gregor0c8296d2009-11-07 00:00:49 +00002274 Result->AddChunk(Chunk(CodeCompletionString::CK_Comma));
Douglas Gregor86d802e2009-09-23 00:34:09 +00002275
2276 std::string ArgString;
2277 QualType ArgType;
2278
2279 if (FDecl) {
2280 ArgString = FDecl->getParamDecl(I)->getNameAsString();
2281 ArgType = FDecl->getParamDecl(I)->getOriginalType();
2282 } else {
2283 ArgType = Proto->getArgType(I);
2284 }
2285
2286 ArgType.getAsStringInternal(ArgString, S.Context.PrintingPolicy);
2287
2288 if (I == CurrentArg)
Douglas Gregor0c8296d2009-11-07 00:00:49 +00002289 Result->AddChunk(Chunk(CodeCompletionString::CK_CurrentParameter,
Benjamin Kramer660cc182009-11-29 20:18:50 +00002290 ArgString));
Douglas Gregor86d802e2009-09-23 00:34:09 +00002291 else
Benjamin Kramer660cc182009-11-29 20:18:50 +00002292 Result->AddTextChunk(ArgString);
Douglas Gregor86d802e2009-09-23 00:34:09 +00002293 }
2294
2295 if (Proto && Proto->isVariadic()) {
Douglas Gregor0c8296d2009-11-07 00:00:49 +00002296 Result->AddChunk(Chunk(CodeCompletionString::CK_Comma));
Douglas Gregor86d802e2009-09-23 00:34:09 +00002297 if (CurrentArg < NumParams)
2298 Result->AddTextChunk("...");
2299 else
Douglas Gregor0c8296d2009-11-07 00:00:49 +00002300 Result->AddChunk(Chunk(CodeCompletionString::CK_CurrentParameter, "..."));
Douglas Gregor86d802e2009-09-23 00:34:09 +00002301 }
Douglas Gregor0c8296d2009-11-07 00:00:49 +00002302 Result->AddChunk(Chunk(CodeCompletionString::CK_RightParen));
Douglas Gregor86d802e2009-09-23 00:34:09 +00002303
2304 return Result;
2305}
2306
Douglas Gregor1827e102010-08-16 16:18:59 +00002307unsigned clang::getMacroUsagePriority(llvm::StringRef MacroName,
2308 bool PreferredTypeIsPointer) {
2309 unsigned Priority = CCP_Macro;
2310
2311 // Treat the "nil" and "NULL" macros as null pointer constants.
2312 if (MacroName.equals("nil") || MacroName.equals("NULL")) {
2313 Priority = CCP_Constant;
2314 if (PreferredTypeIsPointer)
2315 Priority = Priority / CCF_SimilarTypeMatch;
2316 }
2317
2318 return Priority;
2319}
2320
Douglas Gregore8d7beb2010-09-03 23:30:36 +00002321CXCursorKind clang::getCursorKindForDecl(Decl *D) {
2322 if (!D)
2323 return CXCursor_UnexposedDecl;
2324
2325 switch (D->getKind()) {
2326 case Decl::Enum: return CXCursor_EnumDecl;
2327 case Decl::EnumConstant: return CXCursor_EnumConstantDecl;
2328 case Decl::Field: return CXCursor_FieldDecl;
2329 case Decl::Function:
2330 return CXCursor_FunctionDecl;
2331 case Decl::ObjCCategory: return CXCursor_ObjCCategoryDecl;
2332 case Decl::ObjCCategoryImpl: return CXCursor_ObjCCategoryImplDecl;
2333 case Decl::ObjCClass:
2334 // FIXME
2335 return CXCursor_UnexposedDecl;
2336 case Decl::ObjCForwardProtocol:
2337 // FIXME
2338 return CXCursor_UnexposedDecl;
2339 case Decl::ObjCImplementation: return CXCursor_ObjCImplementationDecl;
2340 case Decl::ObjCInterface: return CXCursor_ObjCInterfaceDecl;
2341 case Decl::ObjCIvar: return CXCursor_ObjCIvarDecl;
2342 case Decl::ObjCMethod:
2343 return cast<ObjCMethodDecl>(D)->isInstanceMethod()
2344 ? CXCursor_ObjCInstanceMethodDecl : CXCursor_ObjCClassMethodDecl;
2345 case Decl::CXXMethod: return CXCursor_CXXMethod;
2346 case Decl::CXXConstructor: return CXCursor_Constructor;
2347 case Decl::CXXDestructor: return CXCursor_Destructor;
2348 case Decl::CXXConversion: return CXCursor_ConversionFunction;
2349 case Decl::ObjCProperty: return CXCursor_ObjCPropertyDecl;
2350 case Decl::ObjCProtocol: return CXCursor_ObjCProtocolDecl;
2351 case Decl::ParmVar: return CXCursor_ParmDecl;
2352 case Decl::Typedef: return CXCursor_TypedefDecl;
2353 case Decl::Var: return CXCursor_VarDecl;
2354 case Decl::Namespace: return CXCursor_Namespace;
2355 case Decl::NamespaceAlias: return CXCursor_NamespaceAlias;
2356 case Decl::TemplateTypeParm: return CXCursor_TemplateTypeParameter;
2357 case Decl::NonTypeTemplateParm:return CXCursor_NonTypeTemplateParameter;
2358 case Decl::TemplateTemplateParm:return CXCursor_TemplateTemplateParameter;
2359 case Decl::FunctionTemplate: return CXCursor_FunctionTemplate;
2360 case Decl::ClassTemplate: return CXCursor_ClassTemplate;
2361 case Decl::ClassTemplatePartialSpecialization:
2362 return CXCursor_ClassTemplatePartialSpecialization;
2363 case Decl::UsingDirective: return CXCursor_UsingDirective;
2364
2365 case Decl::Using:
2366 case Decl::UnresolvedUsingValue:
2367 case Decl::UnresolvedUsingTypename:
2368 return CXCursor_UsingDeclaration;
2369
2370 default:
2371 if (TagDecl *TD = dyn_cast<TagDecl>(D)) {
2372 switch (TD->getTagKind()) {
2373 case TTK_Struct: return CXCursor_StructDecl;
2374 case TTK_Class: return CXCursor_ClassDecl;
2375 case TTK_Union: return CXCursor_UnionDecl;
2376 case TTK_Enum: return CXCursor_EnumDecl;
2377 }
2378 }
2379 }
2380
2381 return CXCursor_UnexposedDecl;
2382}
2383
Douglas Gregor590c7d52010-07-08 20:55:51 +00002384static void AddMacroResults(Preprocessor &PP, ResultBuilder &Results,
2385 bool TargetTypeIsPointer = false) {
John McCall0a2c5e22010-08-25 06:19:51 +00002386 typedef CodeCompletionResult Result;
Douglas Gregor590c7d52010-07-08 20:55:51 +00002387
Douglas Gregor3f7c7f42009-10-30 16:50:04 +00002388 Results.EnterNewScope();
Douglas Gregor0c8296d2009-11-07 00:00:49 +00002389 for (Preprocessor::macro_iterator M = PP.macro_begin(),
2390 MEnd = PP.macro_end();
Douglas Gregor590c7d52010-07-08 20:55:51 +00002391 M != MEnd; ++M) {
Douglas Gregor1827e102010-08-16 16:18:59 +00002392 Results.AddResult(Result(M->first,
2393 getMacroUsagePriority(M->first->getName(),
2394 TargetTypeIsPointer)));
Douglas Gregor590c7d52010-07-08 20:55:51 +00002395 }
Douglas Gregor3f7c7f42009-10-30 16:50:04 +00002396 Results.ExitScope();
2397}
2398
Douglas Gregoraa5f77b2010-08-23 21:54:33 +00002399static void AddPrettyFunctionResults(const LangOptions &LangOpts,
2400 ResultBuilder &Results) {
John McCall0a2c5e22010-08-25 06:19:51 +00002401 typedef CodeCompletionResult Result;
Douglas Gregoraa5f77b2010-08-23 21:54:33 +00002402
2403 Results.EnterNewScope();
2404 Results.AddResult(Result("__PRETTY_FUNCTION__", CCP_Constant));
2405 Results.AddResult(Result("__FUNCTION__", CCP_Constant));
2406 if (LangOpts.C99 || LangOpts.CPlusPlus0x)
2407 Results.AddResult(Result("__func__", CCP_Constant));
2408 Results.ExitScope();
2409}
2410
Daniel Dunbar3a2838d2009-11-13 08:58:20 +00002411static void HandleCodeCompleteResults(Sema *S,
2412 CodeCompleteConsumer *CodeCompleter,
Douglas Gregore6b1bb62010-08-11 21:23:17 +00002413 CodeCompletionContext Context,
John McCall0a2c5e22010-08-25 06:19:51 +00002414 CodeCompletionResult *Results,
Douglas Gregore6b1bb62010-08-11 21:23:17 +00002415 unsigned NumResults) {
Douglas Gregor86d9a522009-09-21 16:56:56 +00002416 if (CodeCompleter)
Douglas Gregore6b1bb62010-08-11 21:23:17 +00002417 CodeCompleter->ProcessCodeCompleteResults(*S, Context, Results, NumResults);
Douglas Gregor54f01612009-11-19 00:01:57 +00002418
2419 for (unsigned I = 0; I != NumResults; ++I)
2420 Results[I].Destroy();
Douglas Gregor86d9a522009-09-21 16:56:56 +00002421}
2422
Douglas Gregore6b1bb62010-08-11 21:23:17 +00002423static enum CodeCompletionContext::Kind mapCodeCompletionContext(Sema &S,
2424 Sema::ParserCompletionContext PCC) {
2425 switch (PCC) {
John McCallf312b1e2010-08-26 23:41:50 +00002426 case Sema::PCC_Namespace:
Douglas Gregore6b1bb62010-08-11 21:23:17 +00002427 return CodeCompletionContext::CCC_TopLevel;
2428
John McCallf312b1e2010-08-26 23:41:50 +00002429 case Sema::PCC_Class:
Douglas Gregore6b1bb62010-08-11 21:23:17 +00002430 return CodeCompletionContext::CCC_ClassStructUnion;
2431
John McCallf312b1e2010-08-26 23:41:50 +00002432 case Sema::PCC_ObjCInterface:
Douglas Gregore6b1bb62010-08-11 21:23:17 +00002433 return CodeCompletionContext::CCC_ObjCInterface;
2434
John McCallf312b1e2010-08-26 23:41:50 +00002435 case Sema::PCC_ObjCImplementation:
Douglas Gregore6b1bb62010-08-11 21:23:17 +00002436 return CodeCompletionContext::CCC_ObjCImplementation;
2437
John McCallf312b1e2010-08-26 23:41:50 +00002438 case Sema::PCC_ObjCInstanceVariableList:
Douglas Gregore6b1bb62010-08-11 21:23:17 +00002439 return CodeCompletionContext::CCC_ObjCIvarList;
2440
John McCallf312b1e2010-08-26 23:41:50 +00002441 case Sema::PCC_Template:
2442 case Sema::PCC_MemberTemplate:
2443 case Sema::PCC_RecoveryInFunction:
Douglas Gregore6b1bb62010-08-11 21:23:17 +00002444 return CodeCompletionContext::CCC_Other;
2445
John McCallf312b1e2010-08-26 23:41:50 +00002446 case Sema::PCC_Expression:
2447 case Sema::PCC_ForInit:
2448 case Sema::PCC_Condition:
Douglas Gregore6b1bb62010-08-11 21:23:17 +00002449 return CodeCompletionContext::CCC_Expression;
2450
John McCallf312b1e2010-08-26 23:41:50 +00002451 case Sema::PCC_Statement:
Douglas Gregore6b1bb62010-08-11 21:23:17 +00002452 return CodeCompletionContext::CCC_Statement;
Douglas Gregor72db1082010-08-24 01:11:00 +00002453
John McCallf312b1e2010-08-26 23:41:50 +00002454 case Sema::PCC_Type:
Douglas Gregor72db1082010-08-24 01:11:00 +00002455 return CodeCompletionContext::CCC_Type;
Douglas Gregore6b1bb62010-08-11 21:23:17 +00002456 }
2457
2458 return CodeCompletionContext::CCC_Other;
2459}
2460
Douglas Gregorf6961522010-08-27 21:18:54 +00002461/// \brief If we're in a C++ virtual member function, add completion results
2462/// that invoke the functions we override, since it's common to invoke the
2463/// overridden function as well as adding new functionality.
2464///
2465/// \param S The semantic analysis object for which we are generating results.
2466///
2467/// \param InContext This context in which the nested-name-specifier preceding
2468/// the code-completion point
2469static void MaybeAddOverrideCalls(Sema &S, DeclContext *InContext,
2470 ResultBuilder &Results) {
2471 // Look through blocks.
2472 DeclContext *CurContext = S.CurContext;
2473 while (isa<BlockDecl>(CurContext))
2474 CurContext = CurContext->getParent();
2475
2476
2477 CXXMethodDecl *Method = dyn_cast<CXXMethodDecl>(CurContext);
2478 if (!Method || !Method->isVirtual())
2479 return;
2480
2481 // We need to have names for all of the parameters, if we're going to
2482 // generate a forwarding call.
2483 for (CXXMethodDecl::param_iterator P = Method->param_begin(),
2484 PEnd = Method->param_end();
2485 P != PEnd;
2486 ++P) {
2487 if (!(*P)->getDeclName())
2488 return;
2489 }
2490
2491 for (CXXMethodDecl::method_iterator M = Method->begin_overridden_methods(),
2492 MEnd = Method->end_overridden_methods();
2493 M != MEnd; ++M) {
2494 CodeCompletionString *Pattern = new CodeCompletionString;
2495 CXXMethodDecl *Overridden = const_cast<CXXMethodDecl *>(*M);
2496 if (Overridden->getCanonicalDecl() == Method->getCanonicalDecl())
2497 continue;
2498
2499 // If we need a nested-name-specifier, add one now.
2500 if (!InContext) {
2501 NestedNameSpecifier *NNS
2502 = getRequiredQualification(S.Context, CurContext,
2503 Overridden->getDeclContext());
2504 if (NNS) {
2505 std::string Str;
2506 llvm::raw_string_ostream OS(Str);
2507 NNS->print(OS, S.Context.PrintingPolicy);
2508 Pattern->AddTextChunk(OS.str());
2509 }
2510 } else if (!InContext->Equals(Overridden->getDeclContext()))
2511 continue;
2512
2513 Pattern->AddTypedTextChunk(Overridden->getNameAsString());
2514 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
2515 bool FirstParam = true;
2516 for (CXXMethodDecl::param_iterator P = Method->param_begin(),
2517 PEnd = Method->param_end();
2518 P != PEnd; ++P) {
2519 if (FirstParam)
2520 FirstParam = false;
2521 else
2522 Pattern->AddChunk(CodeCompletionString::CK_Comma);
2523
2524 Pattern->AddPlaceholderChunk((*P)->getIdentifier()->getName());
2525 }
2526 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
2527 Results.AddResult(CodeCompletionResult(Pattern,
2528 CCP_SuperCompletion,
2529 CXCursor_CXXMethod));
2530 Results.Ignore(Overridden);
2531 }
2532}
2533
Douglas Gregor01dfea02010-01-10 23:08:15 +00002534void Sema::CodeCompleteOrdinaryName(Scope *S,
Douglas Gregore6b1bb62010-08-11 21:23:17 +00002535 ParserCompletionContext CompletionContext) {
John McCall0a2c5e22010-08-25 06:19:51 +00002536 typedef CodeCompletionResult Result;
Douglas Gregor2ccccb32010-08-23 18:23:48 +00002537 ResultBuilder Results(*this);
Douglas Gregorf6961522010-08-27 21:18:54 +00002538 Results.EnterNewScope();
Douglas Gregor01dfea02010-01-10 23:08:15 +00002539
2540 // Determine how to filter results, e.g., so that the names of
2541 // values (functions, enumerators, function templates, etc.) are
2542 // only allowed where we can have an expression.
2543 switch (CompletionContext) {
Douglas Gregore6b1bb62010-08-11 21:23:17 +00002544 case PCC_Namespace:
2545 case PCC_Class:
2546 case PCC_ObjCInterface:
2547 case PCC_ObjCImplementation:
2548 case PCC_ObjCInstanceVariableList:
2549 case PCC_Template:
2550 case PCC_MemberTemplate:
Douglas Gregor72db1082010-08-24 01:11:00 +00002551 case PCC_Type:
Douglas Gregor01dfea02010-01-10 23:08:15 +00002552 Results.setFilter(&ResultBuilder::IsOrdinaryNonValueName);
2553 break;
2554
Douglas Gregore6b1bb62010-08-11 21:23:17 +00002555 case PCC_Statement:
Douglas Gregoreb0d0142010-08-24 23:58:17 +00002556 // For statements that are expressions, we prefer to call 'void' functions
2557 // rather than functions that return a result, since then the result would
2558 // be ignored.
2559 Results.setPreferredType(Context.VoidTy);
2560 // Fall through
2561
2562 case PCC_Expression:
Douglas Gregore6b1bb62010-08-11 21:23:17 +00002563 case PCC_ForInit:
2564 case PCC_Condition:
Douglas Gregor4710e5b2010-05-28 00:49:12 +00002565 if (WantTypesInContext(CompletionContext, getLangOptions()))
2566 Results.setFilter(&ResultBuilder::IsOrdinaryName);
2567 else
2568 Results.setFilter(&ResultBuilder::IsOrdinaryNonTypeName);
Douglas Gregorf6961522010-08-27 21:18:54 +00002569
2570 if (getLangOptions().CPlusPlus)
2571 MaybeAddOverrideCalls(*this, /*InContext=*/0, Results);
Douglas Gregor01dfea02010-01-10 23:08:15 +00002572 break;
Douglas Gregordc845342010-05-25 05:58:43 +00002573
Douglas Gregore6b1bb62010-08-11 21:23:17 +00002574 case PCC_RecoveryInFunction:
Douglas Gregordc845342010-05-25 05:58:43 +00002575 // Unfiltered
2576 break;
Douglas Gregor01dfea02010-01-10 23:08:15 +00002577 }
2578
Douglas Gregor3cdee122010-08-26 16:36:48 +00002579 // If we are in a C++ non-static member function, check the qualifiers on
2580 // the member function to filter/prioritize the results list.
2581 if (CXXMethodDecl *CurMethod = dyn_cast<CXXMethodDecl>(CurContext))
2582 if (CurMethod->isInstance())
2583 Results.setObjectTypeQualifiers(
2584 Qualifiers::fromCVRMask(CurMethod->getTypeQualifiers()));
2585
Douglas Gregor1ca6ae82010-01-14 01:09:38 +00002586 CodeCompletionDeclConsumer Consumer(Results, CurContext);
Douglas Gregor8071e422010-08-15 06:18:01 +00002587 LookupVisibleDecls(S, LookupOrdinaryName, Consumer,
2588 CodeCompleter->includeGlobals());
Douglas Gregor2a7925c2009-12-07 09:54:55 +00002589
Douglas Gregorbca403c2010-01-13 23:51:12 +00002590 AddOrdinaryNameResults(CompletionContext, S, *this, Results);
Douglas Gregor2a7925c2009-12-07 09:54:55 +00002591 Results.ExitScope();
2592
Douglas Gregoraa5f77b2010-08-23 21:54:33 +00002593 switch (CompletionContext) {
Douglas Gregor72db1082010-08-24 01:11:00 +00002594 case PCC_Expression:
2595 case PCC_Statement:
2596 case PCC_RecoveryInFunction:
2597 if (S->getFnParent())
2598 AddPrettyFunctionResults(PP.getLangOptions(), Results);
2599 break;
2600
2601 case PCC_Namespace:
2602 case PCC_Class:
2603 case PCC_ObjCInterface:
2604 case PCC_ObjCImplementation:
2605 case PCC_ObjCInstanceVariableList:
2606 case PCC_Template:
2607 case PCC_MemberTemplate:
2608 case PCC_ForInit:
2609 case PCC_Condition:
2610 case PCC_Type:
2611 break;
Douglas Gregoraa5f77b2010-08-23 21:54:33 +00002612 }
2613
Douglas Gregor0c8296d2009-11-07 00:00:49 +00002614 if (CodeCompleter->includeMacros())
Douglas Gregorbca403c2010-01-13 23:51:12 +00002615 AddMacroResults(PP, Results);
Douglas Gregoraa5f77b2010-08-23 21:54:33 +00002616
Douglas Gregore6b1bb62010-08-11 21:23:17 +00002617 HandleCodeCompleteResults(this, CodeCompleter,
2618 mapCodeCompletionContext(*this, CompletionContext),
2619 Results.data(),Results.size());
Douglas Gregor791215b2009-09-21 20:51:25 +00002620}
2621
Douglas Gregor2ccccb32010-08-23 18:23:48 +00002622void Sema::CodeCompleteDeclarator(Scope *S,
2623 bool AllowNonIdentifiers,
2624 bool AllowNestedNameSpecifiers) {
John McCall0a2c5e22010-08-25 06:19:51 +00002625 typedef CodeCompletionResult Result;
Douglas Gregor2ccccb32010-08-23 18:23:48 +00002626 ResultBuilder Results(*this);
2627 Results.EnterNewScope();
2628
2629 // Type qualifiers can come after names.
2630 Results.AddResult(Result("const"));
2631 Results.AddResult(Result("volatile"));
2632 if (getLangOptions().C99)
2633 Results.AddResult(Result("restrict"));
2634
2635 if (getLangOptions().CPlusPlus) {
2636 if (AllowNonIdentifiers) {
2637 Results.AddResult(Result("operator"));
2638 }
2639
2640 // Add nested-name-specifiers.
2641 if (AllowNestedNameSpecifiers) {
2642 Results.allowNestedNameSpecifiers();
2643 CodeCompletionDeclConsumer Consumer(Results, CurContext);
2644 LookupVisibleDecls(S, LookupNestedNameSpecifierName, Consumer,
2645 CodeCompleter->includeGlobals());
2646 }
2647 }
2648 Results.ExitScope();
2649
Douglas Gregor4497dd42010-08-24 04:59:56 +00002650 // Note that we intentionally suppress macro results here, since we do not
2651 // encourage using macros to produce the names of entities.
2652
Douglas Gregor2ccccb32010-08-23 18:23:48 +00002653 HandleCodeCompleteResults(this, CodeCompleter,
2654 AllowNestedNameSpecifiers
2655 ? CodeCompletionContext::CCC_PotentiallyQualifiedName
2656 : CodeCompletionContext::CCC_Name,
2657 Results.data(), Results.size());
2658}
2659
Douglas Gregorfb629412010-08-23 21:17:50 +00002660struct Sema::CodeCompleteExpressionData {
2661 CodeCompleteExpressionData(QualType PreferredType = QualType())
2662 : PreferredType(PreferredType), IntegralConstantExpression(false),
2663 ObjCCollection(false) { }
2664
2665 QualType PreferredType;
2666 bool IntegralConstantExpression;
2667 bool ObjCCollection;
2668 llvm::SmallVector<Decl *, 4> IgnoreDecls;
2669};
2670
Douglas Gregor5ac3bdb2010-05-30 01:49:25 +00002671/// \brief Perform code-completion in an expression context when we know what
2672/// type we're looking for.
Douglas Gregorf9578432010-07-28 21:50:18 +00002673///
2674/// \param IntegralConstantExpression Only permit integral constant
2675/// expressions.
Douglas Gregorfb629412010-08-23 21:17:50 +00002676void Sema::CodeCompleteExpression(Scope *S,
2677 const CodeCompleteExpressionData &Data) {
John McCall0a2c5e22010-08-25 06:19:51 +00002678 typedef CodeCompletionResult Result;
Douglas Gregor5ac3bdb2010-05-30 01:49:25 +00002679 ResultBuilder Results(*this);
2680
Douglas Gregorfb629412010-08-23 21:17:50 +00002681 if (Data.ObjCCollection)
2682 Results.setFilter(&ResultBuilder::IsObjCCollection);
2683 else if (Data.IntegralConstantExpression)
Douglas Gregorf9578432010-07-28 21:50:18 +00002684 Results.setFilter(&ResultBuilder::IsIntegralConstantValue);
Douglas Gregore6b1bb62010-08-11 21:23:17 +00002685 else if (WantTypesInContext(PCC_Expression, getLangOptions()))
Douglas Gregor5ac3bdb2010-05-30 01:49:25 +00002686 Results.setFilter(&ResultBuilder::IsOrdinaryName);
2687 else
2688 Results.setFilter(&ResultBuilder::IsOrdinaryNonTypeName);
Douglas Gregorfb629412010-08-23 21:17:50 +00002689
2690 if (!Data.PreferredType.isNull())
2691 Results.setPreferredType(Data.PreferredType.getNonReferenceType());
2692
2693 // Ignore any declarations that we were told that we don't care about.
2694 for (unsigned I = 0, N = Data.IgnoreDecls.size(); I != N; ++I)
2695 Results.Ignore(Data.IgnoreDecls[I]);
Douglas Gregor5ac3bdb2010-05-30 01:49:25 +00002696
2697 CodeCompletionDeclConsumer Consumer(Results, CurContext);
Douglas Gregor8071e422010-08-15 06:18:01 +00002698 LookupVisibleDecls(S, LookupOrdinaryName, Consumer,
2699 CodeCompleter->includeGlobals());
Douglas Gregor5ac3bdb2010-05-30 01:49:25 +00002700
2701 Results.EnterNewScope();
Douglas Gregore6b1bb62010-08-11 21:23:17 +00002702 AddOrdinaryNameResults(PCC_Expression, S, *this, Results);
Douglas Gregor5ac3bdb2010-05-30 01:49:25 +00002703 Results.ExitScope();
2704
Douglas Gregor590c7d52010-07-08 20:55:51 +00002705 bool PreferredTypeIsPointer = false;
Douglas Gregorfb629412010-08-23 21:17:50 +00002706 if (!Data.PreferredType.isNull())
2707 PreferredTypeIsPointer = Data.PreferredType->isAnyPointerType()
2708 || Data.PreferredType->isMemberPointerType()
2709 || Data.PreferredType->isBlockPointerType();
Douglas Gregor590c7d52010-07-08 20:55:51 +00002710
Douglas Gregoraa5f77b2010-08-23 21:54:33 +00002711 if (S->getFnParent() &&
2712 !Data.ObjCCollection &&
2713 !Data.IntegralConstantExpression)
2714 AddPrettyFunctionResults(PP.getLangOptions(), Results);
2715
Douglas Gregor5ac3bdb2010-05-30 01:49:25 +00002716 if (CodeCompleter->includeMacros())
Douglas Gregor590c7d52010-07-08 20:55:51 +00002717 AddMacroResults(PP, Results, PreferredTypeIsPointer);
Douglas Gregore6b1bb62010-08-11 21:23:17 +00002718 HandleCodeCompleteResults(this, CodeCompleter,
Douglas Gregorfb629412010-08-23 21:17:50 +00002719 CodeCompletionContext(CodeCompletionContext::CCC_Expression,
2720 Data.PreferredType),
Douglas Gregore6b1bb62010-08-11 21:23:17 +00002721 Results.data(),Results.size());
Douglas Gregor5ac3bdb2010-05-30 01:49:25 +00002722}
2723
2724
Douglas Gregor95ac6552009-11-18 01:29:26 +00002725static void AddObjCProperties(ObjCContainerDecl *Container,
Douglas Gregor322328b2009-11-18 22:32:06 +00002726 bool AllowCategories,
Douglas Gregor95ac6552009-11-18 01:29:26 +00002727 DeclContext *CurContext,
2728 ResultBuilder &Results) {
John McCall0a2c5e22010-08-25 06:19:51 +00002729 typedef CodeCompletionResult Result;
Douglas Gregor95ac6552009-11-18 01:29:26 +00002730
2731 // Add properties in this container.
2732 for (ObjCContainerDecl::prop_iterator P = Container->prop_begin(),
2733 PEnd = Container->prop_end();
2734 P != PEnd;
2735 ++P)
2736 Results.MaybeAddResult(Result(*P, 0), CurContext);
2737
2738 // Add properties in referenced protocols.
2739 if (ObjCProtocolDecl *Protocol = dyn_cast<ObjCProtocolDecl>(Container)) {
2740 for (ObjCProtocolDecl::protocol_iterator P = Protocol->protocol_begin(),
2741 PEnd = Protocol->protocol_end();
2742 P != PEnd; ++P)
Douglas Gregor322328b2009-11-18 22:32:06 +00002743 AddObjCProperties(*P, AllowCategories, CurContext, Results);
Douglas Gregor95ac6552009-11-18 01:29:26 +00002744 } else if (ObjCInterfaceDecl *IFace = dyn_cast<ObjCInterfaceDecl>(Container)){
Douglas Gregor322328b2009-11-18 22:32:06 +00002745 if (AllowCategories) {
2746 // Look through categories.
2747 for (ObjCCategoryDecl *Category = IFace->getCategoryList();
2748 Category; Category = Category->getNextClassCategory())
2749 AddObjCProperties(Category, AllowCategories, CurContext, Results);
2750 }
Douglas Gregor95ac6552009-11-18 01:29:26 +00002751
2752 // Look through protocols.
Ted Kremenek53b94412010-09-01 01:21:15 +00002753 for (ObjCInterfaceDecl::all_protocol_iterator
2754 I = IFace->all_referenced_protocol_begin(),
2755 E = IFace->all_referenced_protocol_end(); I != E; ++I)
Douglas Gregor322328b2009-11-18 22:32:06 +00002756 AddObjCProperties(*I, AllowCategories, CurContext, Results);
Douglas Gregor95ac6552009-11-18 01:29:26 +00002757
2758 // Look in the superclass.
2759 if (IFace->getSuperClass())
Douglas Gregor322328b2009-11-18 22:32:06 +00002760 AddObjCProperties(IFace->getSuperClass(), AllowCategories, CurContext,
2761 Results);
Douglas Gregor95ac6552009-11-18 01:29:26 +00002762 } else if (const ObjCCategoryDecl *Category
2763 = dyn_cast<ObjCCategoryDecl>(Container)) {
2764 // Look through protocols.
Ted Kremenek53b94412010-09-01 01:21:15 +00002765 for (ObjCCategoryDecl::protocol_iterator P = Category->protocol_begin(),
2766 PEnd = Category->protocol_end();
Douglas Gregor95ac6552009-11-18 01:29:26 +00002767 P != PEnd; ++P)
Douglas Gregor322328b2009-11-18 22:32:06 +00002768 AddObjCProperties(*P, AllowCategories, CurContext, Results);
Douglas Gregor95ac6552009-11-18 01:29:26 +00002769 }
2770}
2771
Douglas Gregor81b747b2009-09-17 21:32:03 +00002772void Sema::CodeCompleteMemberReferenceExpr(Scope *S, ExprTy *BaseE,
2773 SourceLocation OpLoc,
2774 bool IsArrow) {
2775 if (!BaseE || !CodeCompleter)
2776 return;
2777
John McCall0a2c5e22010-08-25 06:19:51 +00002778 typedef CodeCompletionResult Result;
Douglas Gregor86d9a522009-09-21 16:56:56 +00002779
Douglas Gregor81b747b2009-09-17 21:32:03 +00002780 Expr *Base = static_cast<Expr *>(BaseE);
2781 QualType BaseType = Base->getType();
Douglas Gregor86d9a522009-09-21 16:56:56 +00002782
2783 if (IsArrow) {
2784 if (const PointerType *Ptr = BaseType->getAs<PointerType>())
2785 BaseType = Ptr->getPointeeType();
2786 else if (BaseType->isObjCObjectPointerType())
Douglas Gregor3cdee122010-08-26 16:36:48 +00002787 /*Do nothing*/ ;
Douglas Gregor86d9a522009-09-21 16:56:56 +00002788 else
2789 return;
2790 }
2791
Douglas Gregoreb5758b2009-09-23 22:26:46 +00002792 ResultBuilder Results(*this, &ResultBuilder::IsMember);
Douglas Gregor95ac6552009-11-18 01:29:26 +00002793 Results.EnterNewScope();
2794 if (const RecordType *Record = BaseType->getAs<RecordType>()) {
Douglas Gregor3cdee122010-08-26 16:36:48 +00002795 // Indicate that we are performing a member access, and the cv-qualifiers
2796 // for the base object type.
2797 Results.setObjectTypeQualifiers(BaseType.getQualifiers());
2798
Douglas Gregor95ac6552009-11-18 01:29:26 +00002799 // Access to a C/C++ class, struct, or union.
Douglas Gregor45bcd432010-01-14 03:21:49 +00002800 Results.allowNestedNameSpecifiers();
Douglas Gregor0cc84042010-01-14 15:47:35 +00002801 CodeCompletionDeclConsumer Consumer(Results, CurContext);
Douglas Gregor8071e422010-08-15 06:18:01 +00002802 LookupVisibleDecls(Record->getDecl(), LookupMemberName, Consumer,
2803 CodeCompleter->includeGlobals());
Daniel Dunbar3a2838d2009-11-13 08:58:20 +00002804
Douglas Gregor95ac6552009-11-18 01:29:26 +00002805 if (getLangOptions().CPlusPlus) {
2806 if (!Results.empty()) {
2807 // The "template" keyword can follow "->" or "." in the grammar.
2808 // However, we only want to suggest the template keyword if something
2809 // is dependent.
2810 bool IsDependent = BaseType->isDependentType();
2811 if (!IsDependent) {
2812 for (Scope *DepScope = S; DepScope; DepScope = DepScope->getParent())
2813 if (DeclContext *Ctx = (DeclContext *)DepScope->getEntity()) {
2814 IsDependent = Ctx->isDependentContext();
2815 break;
2816 }
2817 }
Daniel Dunbar3a2838d2009-11-13 08:58:20 +00002818
Douglas Gregor95ac6552009-11-18 01:29:26 +00002819 if (IsDependent)
Douglas Gregora4477812010-01-14 16:01:26 +00002820 Results.AddResult(Result("template"));
Daniel Dunbar3a2838d2009-11-13 08:58:20 +00002821 }
Daniel Dunbar3a2838d2009-11-13 08:58:20 +00002822 }
Douglas Gregor95ac6552009-11-18 01:29:26 +00002823 } else if (!IsArrow && BaseType->getAsObjCInterfacePointerType()) {
2824 // Objective-C property reference.
2825
2826 // Add property results based on our interface.
2827 const ObjCObjectPointerType *ObjCPtr
2828 = BaseType->getAsObjCInterfacePointerType();
2829 assert(ObjCPtr && "Non-NULL pointer guaranteed above!");
Douglas Gregor322328b2009-11-18 22:32:06 +00002830 AddObjCProperties(ObjCPtr->getInterfaceDecl(), true, CurContext, Results);
Douglas Gregor95ac6552009-11-18 01:29:26 +00002831
2832 // Add properties from the protocols in a qualified interface.
2833 for (ObjCObjectPointerType::qual_iterator I = ObjCPtr->qual_begin(),
2834 E = ObjCPtr->qual_end();
2835 I != E; ++I)
Douglas Gregor322328b2009-11-18 22:32:06 +00002836 AddObjCProperties(*I, true, CurContext, Results);
Douglas Gregor95ac6552009-11-18 01:29:26 +00002837 } else if ((IsArrow && BaseType->isObjCObjectPointerType()) ||
John McCallc12c5bb2010-05-15 11:32:37 +00002838 (!IsArrow && BaseType->isObjCObjectType())) {
Douglas Gregor95ac6552009-11-18 01:29:26 +00002839 // Objective-C instance variable access.
2840 ObjCInterfaceDecl *Class = 0;
2841 if (const ObjCObjectPointerType *ObjCPtr
2842 = BaseType->getAs<ObjCObjectPointerType>())
2843 Class = ObjCPtr->getInterfaceDecl();
2844 else
John McCallc12c5bb2010-05-15 11:32:37 +00002845 Class = BaseType->getAs<ObjCObjectType>()->getInterface();
Douglas Gregor95ac6552009-11-18 01:29:26 +00002846
2847 // Add all ivars from this class and its superclasses.
Douglas Gregor80f4f4c2010-01-14 16:08:12 +00002848 if (Class) {
2849 CodeCompletionDeclConsumer Consumer(Results, CurContext);
2850 Results.setFilter(&ResultBuilder::IsObjCIvar);
Douglas Gregor8071e422010-08-15 06:18:01 +00002851 LookupVisibleDecls(Class, LookupMemberName, Consumer,
2852 CodeCompleter->includeGlobals());
Douglas Gregor95ac6552009-11-18 01:29:26 +00002853 }
Douglas Gregor86d9a522009-09-21 16:56:56 +00002854 }
Douglas Gregor95ac6552009-11-18 01:29:26 +00002855
2856 // FIXME: How do we cope with isa?
2857
2858 Results.ExitScope();
Daniel Dunbar3a2838d2009-11-13 08:58:20 +00002859
Daniel Dunbar3a2838d2009-11-13 08:58:20 +00002860 // Hand off the results found for code completion.
Douglas Gregore6b1bb62010-08-11 21:23:17 +00002861 HandleCodeCompleteResults(this, CodeCompleter,
2862 CodeCompletionContext(CodeCompletionContext::CCC_MemberAccess,
2863 BaseType),
2864 Results.data(),Results.size());
Douglas Gregor81b747b2009-09-17 21:32:03 +00002865}
2866
Douglas Gregor374929f2009-09-18 15:37:17 +00002867void Sema::CodeCompleteTag(Scope *S, unsigned TagSpec) {
2868 if (!CodeCompleter)
2869 return;
2870
John McCall0a2c5e22010-08-25 06:19:51 +00002871 typedef CodeCompletionResult Result;
Douglas Gregor86d9a522009-09-21 16:56:56 +00002872 ResultBuilder::LookupFilter Filter = 0;
Douglas Gregore6b1bb62010-08-11 21:23:17 +00002873 enum CodeCompletionContext::Kind ContextKind
2874 = CodeCompletionContext::CCC_Other;
Douglas Gregor374929f2009-09-18 15:37:17 +00002875 switch ((DeclSpec::TST)TagSpec) {
2876 case DeclSpec::TST_enum:
Douglas Gregor86d9a522009-09-21 16:56:56 +00002877 Filter = &ResultBuilder::IsEnum;
Douglas Gregore6b1bb62010-08-11 21:23:17 +00002878 ContextKind = CodeCompletionContext::CCC_EnumTag;
Douglas Gregor374929f2009-09-18 15:37:17 +00002879 break;
2880
2881 case DeclSpec::TST_union:
Douglas Gregor86d9a522009-09-21 16:56:56 +00002882 Filter = &ResultBuilder::IsUnion;
Douglas Gregore6b1bb62010-08-11 21:23:17 +00002883 ContextKind = CodeCompletionContext::CCC_UnionTag;
Douglas Gregor374929f2009-09-18 15:37:17 +00002884 break;
2885
2886 case DeclSpec::TST_struct:
Douglas Gregor374929f2009-09-18 15:37:17 +00002887 case DeclSpec::TST_class:
Douglas Gregor86d9a522009-09-21 16:56:56 +00002888 Filter = &ResultBuilder::IsClassOrStruct;
Douglas Gregore6b1bb62010-08-11 21:23:17 +00002889 ContextKind = CodeCompletionContext::CCC_ClassOrStructTag;
Douglas Gregor374929f2009-09-18 15:37:17 +00002890 break;
2891
2892 default:
2893 assert(false && "Unknown type specifier kind in CodeCompleteTag");
2894 return;
2895 }
Douglas Gregor86d9a522009-09-21 16:56:56 +00002896
John McCall0d6b1642010-04-23 18:46:30 +00002897 ResultBuilder Results(*this);
Douglas Gregor5d2fc402010-01-14 03:27:13 +00002898 CodeCompletionDeclConsumer Consumer(Results, CurContext);
John McCall0d6b1642010-04-23 18:46:30 +00002899
2900 // First pass: look for tags.
2901 Results.setFilter(Filter);
Douglas Gregor8071e422010-08-15 06:18:01 +00002902 LookupVisibleDecls(S, LookupTagName, Consumer,
2903 CodeCompleter->includeGlobals());
John McCall0d6b1642010-04-23 18:46:30 +00002904
Douglas Gregor8071e422010-08-15 06:18:01 +00002905 if (CodeCompleter->includeGlobals()) {
2906 // Second pass: look for nested name specifiers.
2907 Results.setFilter(&ResultBuilder::IsNestedNameSpecifier);
2908 LookupVisibleDecls(S, LookupNestedNameSpecifierName, Consumer);
2909 }
Douglas Gregor86d9a522009-09-21 16:56:56 +00002910
Douglas Gregore6b1bb62010-08-11 21:23:17 +00002911 HandleCodeCompleteResults(this, CodeCompleter, ContextKind,
2912 Results.data(),Results.size());
Douglas Gregor374929f2009-09-18 15:37:17 +00002913}
2914
Douglas Gregor1a480c42010-08-27 17:35:51 +00002915void Sema::CodeCompleteTypeQualifiers(DeclSpec &DS) {
2916 ResultBuilder Results(*this);
2917 Results.EnterNewScope();
2918 if (!(DS.getTypeQualifiers() & DeclSpec::TQ_const))
2919 Results.AddResult("const");
2920 if (!(DS.getTypeQualifiers() & DeclSpec::TQ_volatile))
2921 Results.AddResult("volatile");
2922 if (getLangOptions().C99 &&
2923 !(DS.getTypeQualifiers() & DeclSpec::TQ_restrict))
2924 Results.AddResult("restrict");
2925 Results.ExitScope();
2926 HandleCodeCompleteResults(this, CodeCompleter,
2927 CodeCompletionContext::CCC_TypeQualifiers,
2928 Results.data(), Results.size());
2929}
2930
Douglas Gregor3e1005f2009-09-21 18:10:23 +00002931void Sema::CodeCompleteCase(Scope *S) {
John McCall781472f2010-08-25 08:40:02 +00002932 if (getCurFunction()->SwitchStack.empty() || !CodeCompleter)
Douglas Gregor3e1005f2009-09-21 18:10:23 +00002933 return;
2934
John McCall781472f2010-08-25 08:40:02 +00002935 SwitchStmt *Switch = getCurFunction()->SwitchStack.back();
Douglas Gregorf9578432010-07-28 21:50:18 +00002936 if (!Switch->getCond()->getType()->isEnumeralType()) {
Douglas Gregorfb629412010-08-23 21:17:50 +00002937 CodeCompleteExpressionData Data(Switch->getCond()->getType());
2938 Data.IntegralConstantExpression = true;
2939 CodeCompleteExpression(S, Data);
Douglas Gregor3e1005f2009-09-21 18:10:23 +00002940 return;
Douglas Gregorf9578432010-07-28 21:50:18 +00002941 }
Douglas Gregor3e1005f2009-09-21 18:10:23 +00002942
2943 // Code-complete the cases of a switch statement over an enumeration type
2944 // by providing the list of
2945 EnumDecl *Enum = Switch->getCond()->getType()->getAs<EnumType>()->getDecl();
2946
2947 // Determine which enumerators we have already seen in the switch statement.
2948 // FIXME: Ideally, we would also be able to look *past* the code-completion
2949 // token, in case we are code-completing in the middle of the switch and not
2950 // at the end. However, we aren't able to do so at the moment.
2951 llvm::SmallPtrSet<EnumConstantDecl *, 8> EnumeratorsSeen;
Douglas Gregorb9d0ef72009-09-21 19:57:38 +00002952 NestedNameSpecifier *Qualifier = 0;
Douglas Gregor3e1005f2009-09-21 18:10:23 +00002953 for (SwitchCase *SC = Switch->getSwitchCaseList(); SC;
2954 SC = SC->getNextSwitchCase()) {
2955 CaseStmt *Case = dyn_cast<CaseStmt>(SC);
2956 if (!Case)
2957 continue;
2958
2959 Expr *CaseVal = Case->getLHS()->IgnoreParenCasts();
2960 if (DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(CaseVal))
2961 if (EnumConstantDecl *Enumerator
2962 = dyn_cast<EnumConstantDecl>(DRE->getDecl())) {
2963 // We look into the AST of the case statement to determine which
2964 // enumerator was named. Alternatively, we could compute the value of
2965 // the integral constant expression, then compare it against the
2966 // values of each enumerator. However, value-based approach would not
2967 // work as well with C++ templates where enumerators declared within a
2968 // template are type- and value-dependent.
2969 EnumeratorsSeen.insert(Enumerator);
2970
Douglas Gregorb9d0ef72009-09-21 19:57:38 +00002971 // If this is a qualified-id, keep track of the nested-name-specifier
2972 // so that we can reproduce it as part of code completion, e.g.,
Douglas Gregor3e1005f2009-09-21 18:10:23 +00002973 //
2974 // switch (TagD.getKind()) {
2975 // case TagDecl::TK_enum:
2976 // break;
2977 // case XXX
2978 //
Douglas Gregorb9d0ef72009-09-21 19:57:38 +00002979 // At the XXX, our completions are TagDecl::TK_union,
Douglas Gregor3e1005f2009-09-21 18:10:23 +00002980 // TagDecl::TK_struct, and TagDecl::TK_class, rather than TK_union,
2981 // TK_struct, and TK_class.
Douglas Gregora2813ce2009-10-23 18:54:35 +00002982 Qualifier = DRE->getQualifier();
Douglas Gregor3e1005f2009-09-21 18:10:23 +00002983 }
2984 }
2985
Douglas Gregorb9d0ef72009-09-21 19:57:38 +00002986 if (getLangOptions().CPlusPlus && !Qualifier && EnumeratorsSeen.empty()) {
2987 // If there are no prior enumerators in C++, check whether we have to
2988 // qualify the names of the enumerators that we suggest, because they
2989 // may not be visible in this scope.
2990 Qualifier = getRequiredQualification(Context, CurContext,
2991 Enum->getDeclContext());
2992
2993 // FIXME: Scoped enums need to start with "EnumDecl" as the context!
2994 }
2995
Douglas Gregor3e1005f2009-09-21 18:10:23 +00002996 // Add any enumerators that have not yet been mentioned.
2997 ResultBuilder Results(*this);
2998 Results.EnterNewScope();
2999 for (EnumDecl::enumerator_iterator E = Enum->enumerator_begin(),
3000 EEnd = Enum->enumerator_end();
3001 E != EEnd; ++E) {
3002 if (EnumeratorsSeen.count(*E))
3003 continue;
3004
John McCall0a2c5e22010-08-25 06:19:51 +00003005 Results.AddResult(CodeCompletionResult(*E, Qualifier),
Douglas Gregor608300b2010-01-14 16:14:35 +00003006 CurContext, 0, false);
Douglas Gregor3e1005f2009-09-21 18:10:23 +00003007 }
3008 Results.ExitScope();
Douglas Gregor2f880e42010-04-06 20:02:15 +00003009
Douglas Gregor0c8296d2009-11-07 00:00:49 +00003010 if (CodeCompleter->includeMacros())
Douglas Gregorbca403c2010-01-13 23:51:12 +00003011 AddMacroResults(PP, Results);
Douglas Gregore6b1bb62010-08-11 21:23:17 +00003012 HandleCodeCompleteResults(this, CodeCompleter,
3013 CodeCompletionContext::CCC_Expression,
3014 Results.data(),Results.size());
Douglas Gregor3e1005f2009-09-21 18:10:23 +00003015}
3016
Douglas Gregor9c6a0e92009-09-22 15:41:20 +00003017namespace {
3018 struct IsBetterOverloadCandidate {
3019 Sema &S;
John McCall5769d612010-02-08 23:07:23 +00003020 SourceLocation Loc;
Douglas Gregor9c6a0e92009-09-22 15:41:20 +00003021
3022 public:
John McCall5769d612010-02-08 23:07:23 +00003023 explicit IsBetterOverloadCandidate(Sema &S, SourceLocation Loc)
3024 : S(S), Loc(Loc) { }
Douglas Gregor9c6a0e92009-09-22 15:41:20 +00003025
3026 bool
3027 operator()(const OverloadCandidate &X, const OverloadCandidate &Y) const {
John McCall120d63c2010-08-24 20:38:10 +00003028 return isBetterOverloadCandidate(S, X, Y, Loc);
Douglas Gregor9c6a0e92009-09-22 15:41:20 +00003029 }
3030 };
3031}
3032
Douglas Gregord28dcd72010-05-30 06:10:08 +00003033static bool anyNullArguments(Expr **Args, unsigned NumArgs) {
3034 if (NumArgs && !Args)
3035 return true;
3036
3037 for (unsigned I = 0; I != NumArgs; ++I)
3038 if (!Args[I])
3039 return true;
3040
3041 return false;
3042}
3043
Douglas Gregor9c6a0e92009-09-22 15:41:20 +00003044void Sema::CodeCompleteCall(Scope *S, ExprTy *FnIn,
3045 ExprTy **ArgsIn, unsigned NumArgs) {
3046 if (!CodeCompleter)
3047 return;
Douglas Gregoref96eac2009-12-11 19:06:04 +00003048
3049 // When we're code-completing for a call, we fall back to ordinary
3050 // name code-completion whenever we can't produce specific
3051 // results. We may want to revisit this strategy in the future,
3052 // e.g., by merging the two kinds of results.
3053
Douglas Gregor9c6a0e92009-09-22 15:41:20 +00003054 Expr *Fn = (Expr *)FnIn;
3055 Expr **Args = (Expr **)ArgsIn;
Douglas Gregoref96eac2009-12-11 19:06:04 +00003056
Douglas Gregor9c6a0e92009-09-22 15:41:20 +00003057 // Ignore type-dependent call expressions entirely.
Douglas Gregord28dcd72010-05-30 06:10:08 +00003058 if (!Fn || Fn->isTypeDependent() || anyNullArguments(Args, NumArgs) ||
Douglas Gregoref96eac2009-12-11 19:06:04 +00003059 Expr::hasAnyTypeDependentArguments(Args, NumArgs)) {
Douglas Gregore6b1bb62010-08-11 21:23:17 +00003060 CodeCompleteOrdinaryName(S, PCC_Expression);
Douglas Gregor9c6a0e92009-09-22 15:41:20 +00003061 return;
Douglas Gregoref96eac2009-12-11 19:06:04 +00003062 }
Douglas Gregor9c6a0e92009-09-22 15:41:20 +00003063
John McCall3b4294e2009-12-16 12:17:52 +00003064 // Build an overload candidate set based on the functions we find.
John McCall5769d612010-02-08 23:07:23 +00003065 SourceLocation Loc = Fn->getExprLoc();
3066 OverloadCandidateSet CandidateSet(Loc);
John McCall3b4294e2009-12-16 12:17:52 +00003067
Douglas Gregor9c6a0e92009-09-22 15:41:20 +00003068 // FIXME: What if we're calling something that isn't a function declaration?
3069 // FIXME: What if we're calling a pseudo-destructor?
3070 // FIXME: What if we're calling a member function?
3071
Douglas Gregorc0265402010-01-21 15:46:19 +00003072 typedef CodeCompleteConsumer::OverloadCandidate ResultCandidate;
3073 llvm::SmallVector<ResultCandidate, 8> Results;
3074
John McCall3b4294e2009-12-16 12:17:52 +00003075 Expr *NakedFn = Fn->IgnoreParenCasts();
3076 if (UnresolvedLookupExpr *ULE = dyn_cast<UnresolvedLookupExpr>(NakedFn))
3077 AddOverloadedCallCandidates(ULE, Args, NumArgs, CandidateSet,
3078 /*PartialOverloading=*/ true);
3079 else if (DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(NakedFn)) {
3080 FunctionDecl *FDecl = dyn_cast<FunctionDecl>(DRE->getDecl());
Douglas Gregorc0265402010-01-21 15:46:19 +00003081 if (FDecl) {
Douglas Gregord28dcd72010-05-30 06:10:08 +00003082 if (!getLangOptions().CPlusPlus ||
3083 !FDecl->getType()->getAs<FunctionProtoType>())
Douglas Gregorc0265402010-01-21 15:46:19 +00003084 Results.push_back(ResultCandidate(FDecl));
3085 else
John McCall86820f52010-01-26 01:37:31 +00003086 // FIXME: access?
John McCall9aa472c2010-03-19 07:35:19 +00003087 AddOverloadCandidate(FDecl, DeclAccessPair::make(FDecl, AS_none),
3088 Args, NumArgs, CandidateSet,
Douglas Gregorc27d6c52010-04-16 17:41:49 +00003089 false, /*PartialOverloading*/true);
Douglas Gregorc0265402010-01-21 15:46:19 +00003090 }
John McCall3b4294e2009-12-16 12:17:52 +00003091 }
Douglas Gregor9c6a0e92009-09-22 15:41:20 +00003092
Douglas Gregor5ac3bdb2010-05-30 01:49:25 +00003093 QualType ParamType;
3094
Douglas Gregorc0265402010-01-21 15:46:19 +00003095 if (!CandidateSet.empty()) {
3096 // Sort the overload candidate set by placing the best overloads first.
3097 std::stable_sort(CandidateSet.begin(), CandidateSet.end(),
John McCall5769d612010-02-08 23:07:23 +00003098 IsBetterOverloadCandidate(*this, Loc));
Douglas Gregor9c6a0e92009-09-22 15:41:20 +00003099
Douglas Gregorc0265402010-01-21 15:46:19 +00003100 // Add the remaining viable overload candidates as code-completion reslults.
3101 for (OverloadCandidateSet::iterator Cand = CandidateSet.begin(),
3102 CandEnd = CandidateSet.end();
3103 Cand != CandEnd; ++Cand) {
3104 if (Cand->Viable)
3105 Results.push_back(ResultCandidate(Cand->Function));
3106 }
Douglas Gregor5ac3bdb2010-05-30 01:49:25 +00003107
3108 // From the viable candidates, try to determine the type of this parameter.
3109 for (unsigned I = 0, N = Results.size(); I != N; ++I) {
3110 if (const FunctionType *FType = Results[I].getFunctionType())
3111 if (const FunctionProtoType *Proto = dyn_cast<FunctionProtoType>(FType))
3112 if (NumArgs < Proto->getNumArgs()) {
3113 if (ParamType.isNull())
3114 ParamType = Proto->getArgType(NumArgs);
3115 else if (!Context.hasSameUnqualifiedType(
3116 ParamType.getNonReferenceType(),
3117 Proto->getArgType(NumArgs).getNonReferenceType())) {
3118 ParamType = QualType();
3119 break;
3120 }
3121 }
3122 }
3123 } else {
3124 // Try to determine the parameter type from the type of the expression
3125 // being called.
3126 QualType FunctionType = Fn->getType();
3127 if (const PointerType *Ptr = FunctionType->getAs<PointerType>())
3128 FunctionType = Ptr->getPointeeType();
3129 else if (const BlockPointerType *BlockPtr
3130 = FunctionType->getAs<BlockPointerType>())
3131 FunctionType = BlockPtr->getPointeeType();
3132 else if (const MemberPointerType *MemPtr
3133 = FunctionType->getAs<MemberPointerType>())
3134 FunctionType = MemPtr->getPointeeType();
3135
3136 if (const FunctionProtoType *Proto
3137 = FunctionType->getAs<FunctionProtoType>()) {
3138 if (NumArgs < Proto->getNumArgs())
3139 ParamType = Proto->getArgType(NumArgs);
3140 }
Douglas Gregor9c6a0e92009-09-22 15:41:20 +00003141 }
Douglas Gregoref96eac2009-12-11 19:06:04 +00003142
Douglas Gregor5ac3bdb2010-05-30 01:49:25 +00003143 if (ParamType.isNull())
Douglas Gregore6b1bb62010-08-11 21:23:17 +00003144 CodeCompleteOrdinaryName(S, PCC_Expression);
Douglas Gregor5ac3bdb2010-05-30 01:49:25 +00003145 else
3146 CodeCompleteExpression(S, ParamType);
3147
Douglas Gregor2e4c7a52010-04-06 20:19:47 +00003148 if (!Results.empty())
Douglas Gregoref96eac2009-12-11 19:06:04 +00003149 CodeCompleter->ProcessOverloadCandidates(*this, NumArgs, Results.data(),
3150 Results.size());
Douglas Gregor9c6a0e92009-09-22 15:41:20 +00003151}
3152
John McCalld226f652010-08-21 09:40:31 +00003153void Sema::CodeCompleteInitializer(Scope *S, Decl *D) {
3154 ValueDecl *VD = dyn_cast_or_null<ValueDecl>(D);
Douglas Gregor5ac3bdb2010-05-30 01:49:25 +00003155 if (!VD) {
Douglas Gregore6b1bb62010-08-11 21:23:17 +00003156 CodeCompleteOrdinaryName(S, PCC_Expression);
Douglas Gregor5ac3bdb2010-05-30 01:49:25 +00003157 return;
3158 }
3159
3160 CodeCompleteExpression(S, VD->getType());
3161}
3162
3163void Sema::CodeCompleteReturn(Scope *S) {
3164 QualType ResultType;
3165 if (isa<BlockDecl>(CurContext)) {
3166 if (BlockScopeInfo *BSI = getCurBlock())
3167 ResultType = BSI->ReturnType;
3168 } else if (FunctionDecl *Function = dyn_cast<FunctionDecl>(CurContext))
3169 ResultType = Function->getResultType();
3170 else if (ObjCMethodDecl *Method = dyn_cast<ObjCMethodDecl>(CurContext))
3171 ResultType = Method->getResultType();
3172
3173 if (ResultType.isNull())
Douglas Gregore6b1bb62010-08-11 21:23:17 +00003174 CodeCompleteOrdinaryName(S, PCC_Expression);
Douglas Gregor5ac3bdb2010-05-30 01:49:25 +00003175 else
3176 CodeCompleteExpression(S, ResultType);
3177}
3178
3179void Sema::CodeCompleteAssignmentRHS(Scope *S, ExprTy *LHS) {
3180 if (LHS)
3181 CodeCompleteExpression(S, static_cast<Expr *>(LHS)->getType());
3182 else
Douglas Gregore6b1bb62010-08-11 21:23:17 +00003183 CodeCompleteOrdinaryName(S, PCC_Expression);
Douglas Gregor5ac3bdb2010-05-30 01:49:25 +00003184}
3185
Jeffrey Yasskin9ab14542010-04-08 16:38:48 +00003186void Sema::CodeCompleteQualifiedId(Scope *S, CXXScopeSpec &SS,
Douglas Gregor81b747b2009-09-17 21:32:03 +00003187 bool EnteringContext) {
3188 if (!SS.getScopeRep() || !CodeCompleter)
3189 return;
3190
Douglas Gregor86d9a522009-09-21 16:56:56 +00003191 DeclContext *Ctx = computeDeclContext(SS, EnteringContext);
3192 if (!Ctx)
3193 return;
Douglas Gregord1cd31a2009-12-11 18:28:39 +00003194
3195 // Try to instantiate any non-dependent declaration contexts before
3196 // we look in them.
John McCall77bb1aa2010-05-01 00:40:08 +00003197 if (!isDependentScopeSpecifier(SS) && RequireCompleteDeclContext(SS, Ctx))
Douglas Gregord1cd31a2009-12-11 18:28:39 +00003198 return;
3199
Douglas Gregor86d9a522009-09-21 16:56:56 +00003200 ResultBuilder Results(*this);
Douglas Gregor86d9a522009-09-21 16:56:56 +00003201
Douglas Gregorf6961522010-08-27 21:18:54 +00003202 Results.EnterNewScope();
Douglas Gregor86d9a522009-09-21 16:56:56 +00003203 // The "template" keyword can follow "::" in the grammar, but only
3204 // put it into the grammar if the nested-name-specifier is dependent.
3205 NestedNameSpecifier *NNS = (NestedNameSpecifier *)SS.getScopeRep();
3206 if (!Results.empty() && NNS->isDependent())
Douglas Gregora4477812010-01-14 16:01:26 +00003207 Results.AddResult("template");
Douglas Gregorf6961522010-08-27 21:18:54 +00003208
3209 // Add calls to overridden virtual functions, if there are any.
3210 //
3211 // FIXME: This isn't wonderful, because we don't know whether we're actually
3212 // in a context that permits expressions. This is a general issue with
3213 // qualified-id completions.
3214 if (!EnteringContext)
3215 MaybeAddOverrideCalls(*this, Ctx, Results);
3216 Results.ExitScope();
Douglas Gregor86d9a522009-09-21 16:56:56 +00003217
Douglas Gregorf6961522010-08-27 21:18:54 +00003218 CodeCompletionDeclConsumer Consumer(Results, CurContext);
3219 LookupVisibleDecls(Ctx, LookupOrdinaryName, Consumer);
3220
Douglas Gregore6b1bb62010-08-11 21:23:17 +00003221 HandleCodeCompleteResults(this, CodeCompleter,
Douglas Gregorf6961522010-08-27 21:18:54 +00003222 CodeCompletionContext::CCC_Name,
Douglas Gregore6b1bb62010-08-11 21:23:17 +00003223 Results.data(),Results.size());
Douglas Gregor81b747b2009-09-17 21:32:03 +00003224}
Douglas Gregor49f40bd2009-09-18 19:03:04 +00003225
3226void Sema::CodeCompleteUsing(Scope *S) {
3227 if (!CodeCompleter)
3228 return;
3229
Douglas Gregor86d9a522009-09-21 16:56:56 +00003230 ResultBuilder Results(*this, &ResultBuilder::IsNestedNameSpecifier);
Douglas Gregor8e0a0e42009-09-22 23:31:26 +00003231 Results.EnterNewScope();
Douglas Gregor86d9a522009-09-21 16:56:56 +00003232
3233 // If we aren't in class scope, we could see the "namespace" keyword.
3234 if (!S->isClassScope())
John McCall0a2c5e22010-08-25 06:19:51 +00003235 Results.AddResult(CodeCompletionResult("namespace"));
Douglas Gregor86d9a522009-09-21 16:56:56 +00003236
3237 // After "using", we can see anything that would start a
3238 // nested-name-specifier.
Douglas Gregor5d2fc402010-01-14 03:27:13 +00003239 CodeCompletionDeclConsumer Consumer(Results, CurContext);
Douglas Gregor8071e422010-08-15 06:18:01 +00003240 LookupVisibleDecls(S, LookupOrdinaryName, Consumer,
3241 CodeCompleter->includeGlobals());
Douglas Gregor8e0a0e42009-09-22 23:31:26 +00003242 Results.ExitScope();
Douglas Gregor86d9a522009-09-21 16:56:56 +00003243
Douglas Gregore6b1bb62010-08-11 21:23:17 +00003244 HandleCodeCompleteResults(this, CodeCompleter,
3245 CodeCompletionContext::CCC_Other,
3246 Results.data(),Results.size());
Douglas Gregor49f40bd2009-09-18 19:03:04 +00003247}
3248
3249void Sema::CodeCompleteUsingDirective(Scope *S) {
3250 if (!CodeCompleter)
3251 return;
3252
Douglas Gregor86d9a522009-09-21 16:56:56 +00003253 // After "using namespace", we expect to see a namespace name or namespace
3254 // alias.
3255 ResultBuilder Results(*this, &ResultBuilder::IsNamespaceOrAlias);
Douglas Gregor8e0a0e42009-09-22 23:31:26 +00003256 Results.EnterNewScope();
Douglas Gregor5d2fc402010-01-14 03:27:13 +00003257 CodeCompletionDeclConsumer Consumer(Results, CurContext);
Douglas Gregor8071e422010-08-15 06:18:01 +00003258 LookupVisibleDecls(S, LookupOrdinaryName, Consumer,
3259 CodeCompleter->includeGlobals());
Douglas Gregor8e0a0e42009-09-22 23:31:26 +00003260 Results.ExitScope();
Douglas Gregore6b1bb62010-08-11 21:23:17 +00003261 HandleCodeCompleteResults(this, CodeCompleter,
Douglas Gregor8071e422010-08-15 06:18:01 +00003262 CodeCompletionContext::CCC_Namespace,
Douglas Gregore6b1bb62010-08-11 21:23:17 +00003263 Results.data(),Results.size());
Douglas Gregor49f40bd2009-09-18 19:03:04 +00003264}
3265
3266void Sema::CodeCompleteNamespaceDecl(Scope *S) {
3267 if (!CodeCompleter)
3268 return;
3269
Douglas Gregor86d9a522009-09-21 16:56:56 +00003270 ResultBuilder Results(*this, &ResultBuilder::IsNamespace);
3271 DeclContext *Ctx = (DeclContext *)S->getEntity();
3272 if (!S->getParent())
3273 Ctx = Context.getTranslationUnitDecl();
3274
3275 if (Ctx && Ctx->isFileContext()) {
3276 // We only want to see those namespaces that have already been defined
3277 // within this scope, because its likely that the user is creating an
3278 // extended namespace declaration. Keep track of the most recent
3279 // definition of each namespace.
3280 std::map<NamespaceDecl *, NamespaceDecl *> OrigToLatest;
3281 for (DeclContext::specific_decl_iterator<NamespaceDecl>
3282 NS(Ctx->decls_begin()), NSEnd(Ctx->decls_end());
3283 NS != NSEnd; ++NS)
3284 OrigToLatest[NS->getOriginalNamespace()] = *NS;
3285
3286 // Add the most recent definition (or extended definition) of each
3287 // namespace to the list of results.
Douglas Gregor8e0a0e42009-09-22 23:31:26 +00003288 Results.EnterNewScope();
Douglas Gregor86d9a522009-09-21 16:56:56 +00003289 for (std::map<NamespaceDecl *, NamespaceDecl *>::iterator
3290 NS = OrigToLatest.begin(), NSEnd = OrigToLatest.end();
3291 NS != NSEnd; ++NS)
John McCall0a2c5e22010-08-25 06:19:51 +00003292 Results.AddResult(CodeCompletionResult(NS->second, 0),
Douglas Gregor608300b2010-01-14 16:14:35 +00003293 CurContext, 0, false);
Douglas Gregor8e0a0e42009-09-22 23:31:26 +00003294 Results.ExitScope();
Douglas Gregor86d9a522009-09-21 16:56:56 +00003295 }
3296
Douglas Gregore6b1bb62010-08-11 21:23:17 +00003297 HandleCodeCompleteResults(this, CodeCompleter,
3298 CodeCompletionContext::CCC_Other,
3299 Results.data(),Results.size());
Douglas Gregor49f40bd2009-09-18 19:03:04 +00003300}
3301
3302void Sema::CodeCompleteNamespaceAliasDecl(Scope *S) {
3303 if (!CodeCompleter)
3304 return;
3305
Douglas Gregor86d9a522009-09-21 16:56:56 +00003306 // After "namespace", we expect to see a namespace or alias.
3307 ResultBuilder Results(*this, &ResultBuilder::IsNamespaceOrAlias);
Douglas Gregor5d2fc402010-01-14 03:27:13 +00003308 CodeCompletionDeclConsumer Consumer(Results, CurContext);
Douglas Gregor8071e422010-08-15 06:18:01 +00003309 LookupVisibleDecls(S, LookupOrdinaryName, Consumer,
3310 CodeCompleter->includeGlobals());
Douglas Gregore6b1bb62010-08-11 21:23:17 +00003311 HandleCodeCompleteResults(this, CodeCompleter,
Douglas Gregor8071e422010-08-15 06:18:01 +00003312 CodeCompletionContext::CCC_Namespace,
Douglas Gregore6b1bb62010-08-11 21:23:17 +00003313 Results.data(),Results.size());
Douglas Gregor49f40bd2009-09-18 19:03:04 +00003314}
3315
Douglas Gregored8d3222009-09-18 20:05:18 +00003316void Sema::CodeCompleteOperatorName(Scope *S) {
3317 if (!CodeCompleter)
3318 return;
Douglas Gregor86d9a522009-09-21 16:56:56 +00003319
John McCall0a2c5e22010-08-25 06:19:51 +00003320 typedef CodeCompletionResult Result;
Douglas Gregor86d9a522009-09-21 16:56:56 +00003321 ResultBuilder Results(*this, &ResultBuilder::IsType);
Douglas Gregor8e0a0e42009-09-22 23:31:26 +00003322 Results.EnterNewScope();
Douglas Gregored8d3222009-09-18 20:05:18 +00003323
Douglas Gregor86d9a522009-09-21 16:56:56 +00003324 // Add the names of overloadable operators.
3325#define OVERLOADED_OPERATOR(Name,Spelling,Token,Unary,Binary,MemberOnly) \
3326 if (std::strcmp(Spelling, "?")) \
Douglas Gregora4477812010-01-14 16:01:26 +00003327 Results.AddResult(Result(Spelling));
Douglas Gregor86d9a522009-09-21 16:56:56 +00003328#include "clang/Basic/OperatorKinds.def"
3329
3330 // Add any type names visible from the current scope
Douglas Gregor45bcd432010-01-14 03:21:49 +00003331 Results.allowNestedNameSpecifiers();
Douglas Gregor5d2fc402010-01-14 03:27:13 +00003332 CodeCompletionDeclConsumer Consumer(Results, CurContext);
Douglas Gregor8071e422010-08-15 06:18:01 +00003333 LookupVisibleDecls(S, LookupOrdinaryName, Consumer,
3334 CodeCompleter->includeGlobals());
Douglas Gregor86d9a522009-09-21 16:56:56 +00003335
3336 // Add any type specifiers
Douglas Gregorbca403c2010-01-13 23:51:12 +00003337 AddTypeSpecifierResults(getLangOptions(), Results);
Douglas Gregor8e0a0e42009-09-22 23:31:26 +00003338 Results.ExitScope();
Douglas Gregor86d9a522009-09-21 16:56:56 +00003339
Douglas Gregore6b1bb62010-08-11 21:23:17 +00003340 HandleCodeCompleteResults(this, CodeCompleter,
Douglas Gregor8071e422010-08-15 06:18:01 +00003341 CodeCompletionContext::CCC_Type,
Douglas Gregore6b1bb62010-08-11 21:23:17 +00003342 Results.data(),Results.size());
Douglas Gregored8d3222009-09-18 20:05:18 +00003343}
Douglas Gregor49f40bd2009-09-18 19:03:04 +00003344
Douglas Gregor0133f522010-08-28 00:00:50 +00003345void Sema::CodeCompleteConstructorInitializer(Decl *ConstructorD,
3346 CXXBaseOrMemberInitializer** Initializers,
3347 unsigned NumInitializers) {
3348 CXXConstructorDecl *Constructor
3349 = static_cast<CXXConstructorDecl *>(ConstructorD);
3350 if (!Constructor)
3351 return;
3352
3353 ResultBuilder Results(*this);
3354 Results.EnterNewScope();
3355
3356 // Fill in any already-initialized fields or base classes.
3357 llvm::SmallPtrSet<FieldDecl *, 4> InitializedFields;
3358 llvm::SmallPtrSet<CanQualType, 4> InitializedBases;
3359 for (unsigned I = 0; I != NumInitializers; ++I) {
3360 if (Initializers[I]->isBaseInitializer())
3361 InitializedBases.insert(
3362 Context.getCanonicalType(QualType(Initializers[I]->getBaseClass(), 0)));
3363 else
3364 InitializedFields.insert(cast<FieldDecl>(Initializers[I]->getMember()));
3365 }
3366
3367 // Add completions for base classes.
Douglas Gregor0c431c82010-08-29 19:27:27 +00003368 bool SawLastInitializer = (NumInitializers == 0);
Douglas Gregor0133f522010-08-28 00:00:50 +00003369 CXXRecordDecl *ClassDecl = Constructor->getParent();
3370 for (CXXRecordDecl::base_class_iterator Base = ClassDecl->bases_begin(),
3371 BaseEnd = ClassDecl->bases_end();
3372 Base != BaseEnd; ++Base) {
Douglas Gregor0c431c82010-08-29 19:27:27 +00003373 if (!InitializedBases.insert(Context.getCanonicalType(Base->getType()))) {
3374 SawLastInitializer
3375 = NumInitializers > 0 &&
3376 Initializers[NumInitializers - 1]->isBaseInitializer() &&
3377 Context.hasSameUnqualifiedType(Base->getType(),
3378 QualType(Initializers[NumInitializers - 1]->getBaseClass(), 0));
Douglas Gregor0133f522010-08-28 00:00:50 +00003379 continue;
Douglas Gregor0c431c82010-08-29 19:27:27 +00003380 }
Douglas Gregor0133f522010-08-28 00:00:50 +00003381
3382 CodeCompletionString *Pattern = new CodeCompletionString;
3383 Pattern->AddTypedTextChunk(
3384 Base->getType().getAsString(Context.PrintingPolicy));
3385 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
3386 Pattern->AddPlaceholderChunk("args");
3387 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
Douglas Gregor0c431c82010-08-29 19:27:27 +00003388 Results.AddResult(CodeCompletionResult(Pattern,
3389 SawLastInitializer? CCP_NextInitializer
3390 : CCP_MemberDeclaration));
3391 SawLastInitializer = false;
Douglas Gregor0133f522010-08-28 00:00:50 +00003392 }
3393
3394 // Add completions for virtual base classes.
3395 for (CXXRecordDecl::base_class_iterator Base = ClassDecl->vbases_begin(),
3396 BaseEnd = ClassDecl->vbases_end();
3397 Base != BaseEnd; ++Base) {
Douglas Gregor0c431c82010-08-29 19:27:27 +00003398 if (!InitializedBases.insert(Context.getCanonicalType(Base->getType()))) {
3399 SawLastInitializer
3400 = NumInitializers > 0 &&
3401 Initializers[NumInitializers - 1]->isBaseInitializer() &&
3402 Context.hasSameUnqualifiedType(Base->getType(),
3403 QualType(Initializers[NumInitializers - 1]->getBaseClass(), 0));
Douglas Gregor0133f522010-08-28 00:00:50 +00003404 continue;
Douglas Gregor0c431c82010-08-29 19:27:27 +00003405 }
Douglas Gregor0133f522010-08-28 00:00:50 +00003406
3407 CodeCompletionString *Pattern = new CodeCompletionString;
3408 Pattern->AddTypedTextChunk(
3409 Base->getType().getAsString(Context.PrintingPolicy));
3410 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
3411 Pattern->AddPlaceholderChunk("args");
3412 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
Douglas Gregor0c431c82010-08-29 19:27:27 +00003413 Results.AddResult(CodeCompletionResult(Pattern,
3414 SawLastInitializer? CCP_NextInitializer
3415 : CCP_MemberDeclaration));
3416 SawLastInitializer = false;
Douglas Gregor0133f522010-08-28 00:00:50 +00003417 }
3418
3419 // Add completions for members.
3420 for (CXXRecordDecl::field_iterator Field = ClassDecl->field_begin(),
3421 FieldEnd = ClassDecl->field_end();
3422 Field != FieldEnd; ++Field) {
Douglas Gregor0c431c82010-08-29 19:27:27 +00003423 if (!InitializedFields.insert(cast<FieldDecl>(Field->getCanonicalDecl()))) {
3424 SawLastInitializer
3425 = NumInitializers > 0 &&
3426 Initializers[NumInitializers - 1]->isMemberInitializer() &&
3427 Initializers[NumInitializers - 1]->getMember() == *Field;
Douglas Gregor0133f522010-08-28 00:00:50 +00003428 continue;
Douglas Gregor0c431c82010-08-29 19:27:27 +00003429 }
Douglas Gregor0133f522010-08-28 00:00:50 +00003430
3431 if (!Field->getDeclName())
3432 continue;
3433
3434 CodeCompletionString *Pattern = new CodeCompletionString;
3435 Pattern->AddTypedTextChunk(Field->getIdentifier()->getName());
3436 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
3437 Pattern->AddPlaceholderChunk("args");
3438 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
Douglas Gregor0c431c82010-08-29 19:27:27 +00003439 Results.AddResult(CodeCompletionResult(Pattern,
3440 SawLastInitializer? CCP_NextInitializer
Douglas Gregora67e03f2010-09-09 21:42:20 +00003441 : CCP_MemberDeclaration,
3442 CXCursor_MemberRef));
Douglas Gregor0c431c82010-08-29 19:27:27 +00003443 SawLastInitializer = false;
Douglas Gregor0133f522010-08-28 00:00:50 +00003444 }
3445 Results.ExitScope();
3446
3447 HandleCodeCompleteResults(this, CodeCompleter,
3448 CodeCompletionContext::CCC_Name,
3449 Results.data(), Results.size());
3450}
3451
Douglas Gregorb6ac2452010-01-13 21:24:21 +00003452// Macro that expands to @Keyword or Keyword, depending on whether NeedAt is
3453// true or false.
3454#define OBJC_AT_KEYWORD_NAME(NeedAt,Keyword) NeedAt? "@" #Keyword : #Keyword
Douglas Gregorbca403c2010-01-13 23:51:12 +00003455static void AddObjCImplementationResults(const LangOptions &LangOpts,
Douglas Gregorb6ac2452010-01-13 21:24:21 +00003456 ResultBuilder &Results,
3457 bool NeedAt) {
John McCall0a2c5e22010-08-25 06:19:51 +00003458 typedef CodeCompletionResult Result;
Douglas Gregorb6ac2452010-01-13 21:24:21 +00003459 // Since we have an implementation, we can end it.
Douglas Gregora4477812010-01-14 16:01:26 +00003460 Results.AddResult(Result(OBJC_AT_KEYWORD_NAME(NeedAt,end)));
Douglas Gregorb6ac2452010-01-13 21:24:21 +00003461
3462 CodeCompletionString *Pattern = 0;
3463 if (LangOpts.ObjC2) {
3464 // @dynamic
3465 Pattern = new CodeCompletionString;
3466 Pattern->AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt,dynamic));
3467 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
3468 Pattern->AddPlaceholderChunk("property");
Douglas Gregora4477812010-01-14 16:01:26 +00003469 Results.AddResult(Result(Pattern));
Douglas Gregorb6ac2452010-01-13 21:24:21 +00003470
3471 // @synthesize
3472 Pattern = new CodeCompletionString;
3473 Pattern->AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt,synthesize));
3474 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
3475 Pattern->AddPlaceholderChunk("property");
Douglas Gregora4477812010-01-14 16:01:26 +00003476 Results.AddResult(Result(Pattern));
Douglas Gregorb6ac2452010-01-13 21:24:21 +00003477 }
3478}
3479
Douglas Gregorbca403c2010-01-13 23:51:12 +00003480static void AddObjCInterfaceResults(const LangOptions &LangOpts,
Douglas Gregorb6ac2452010-01-13 21:24:21 +00003481 ResultBuilder &Results,
3482 bool NeedAt) {
John McCall0a2c5e22010-08-25 06:19:51 +00003483 typedef CodeCompletionResult Result;
Douglas Gregorb6ac2452010-01-13 21:24:21 +00003484
3485 // Since we have an interface or protocol, we can end it.
Douglas Gregora4477812010-01-14 16:01:26 +00003486 Results.AddResult(Result(OBJC_AT_KEYWORD_NAME(NeedAt,end)));
Douglas Gregorb6ac2452010-01-13 21:24:21 +00003487
3488 if (LangOpts.ObjC2) {
3489 // @property
Douglas Gregora4477812010-01-14 16:01:26 +00003490 Results.AddResult(Result(OBJC_AT_KEYWORD_NAME(NeedAt,property)));
Douglas Gregorb6ac2452010-01-13 21:24:21 +00003491
3492 // @required
Douglas Gregora4477812010-01-14 16:01:26 +00003493 Results.AddResult(Result(OBJC_AT_KEYWORD_NAME(NeedAt,required)));
Douglas Gregorb6ac2452010-01-13 21:24:21 +00003494
3495 // @optional
Douglas Gregora4477812010-01-14 16:01:26 +00003496 Results.AddResult(Result(OBJC_AT_KEYWORD_NAME(NeedAt,optional)));
Douglas Gregorb6ac2452010-01-13 21:24:21 +00003497 }
3498}
3499
Douglas Gregorbca403c2010-01-13 23:51:12 +00003500static void AddObjCTopLevelResults(ResultBuilder &Results, bool NeedAt) {
John McCall0a2c5e22010-08-25 06:19:51 +00003501 typedef CodeCompletionResult Result;
Douglas Gregorb6ac2452010-01-13 21:24:21 +00003502 CodeCompletionString *Pattern = 0;
3503
3504 // @class name ;
3505 Pattern = new CodeCompletionString;
3506 Pattern->AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt,class));
3507 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
Douglas Gregorc8bddde2010-05-28 00:22:41 +00003508 Pattern->AddPlaceholderChunk("name");
Douglas Gregora4477812010-01-14 16:01:26 +00003509 Results.AddResult(Result(Pattern));
Douglas Gregorb6ac2452010-01-13 21:24:21 +00003510
Douglas Gregorc8bddde2010-05-28 00:22:41 +00003511 if (Results.includeCodePatterns()) {
3512 // @interface name
3513 // FIXME: Could introduce the whole pattern, including superclasses and
3514 // such.
3515 Pattern = new CodeCompletionString;
3516 Pattern->AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt,interface));
3517 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
3518 Pattern->AddPlaceholderChunk("class");
3519 Results.AddResult(Result(Pattern));
Douglas Gregorb6ac2452010-01-13 21:24:21 +00003520
Douglas Gregorc8bddde2010-05-28 00:22:41 +00003521 // @protocol name
3522 Pattern = new CodeCompletionString;
3523 Pattern->AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt,protocol));
3524 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
3525 Pattern->AddPlaceholderChunk("protocol");
3526 Results.AddResult(Result(Pattern));
3527
3528 // @implementation name
3529 Pattern = new CodeCompletionString;
3530 Pattern->AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt,implementation));
3531 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
3532 Pattern->AddPlaceholderChunk("class");
3533 Results.AddResult(Result(Pattern));
3534 }
Douglas Gregorb6ac2452010-01-13 21:24:21 +00003535
3536 // @compatibility_alias name
3537 Pattern = new CodeCompletionString;
3538 Pattern->AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt,compatibility_alias));
3539 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
3540 Pattern->AddPlaceholderChunk("alias");
3541 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
3542 Pattern->AddPlaceholderChunk("class");
Douglas Gregora4477812010-01-14 16:01:26 +00003543 Results.AddResult(Result(Pattern));
Douglas Gregorb6ac2452010-01-13 21:24:21 +00003544}
3545
John McCalld226f652010-08-21 09:40:31 +00003546void Sema::CodeCompleteObjCAtDirective(Scope *S, Decl *ObjCImpDecl,
Douglas Gregorc464ae82009-12-07 09:27:33 +00003547 bool InInterface) {
John McCall0a2c5e22010-08-25 06:19:51 +00003548 typedef CodeCompletionResult Result;
Douglas Gregorc464ae82009-12-07 09:27:33 +00003549 ResultBuilder Results(*this);
3550 Results.EnterNewScope();
Douglas Gregorb6ac2452010-01-13 21:24:21 +00003551 if (ObjCImpDecl)
Douglas Gregorbca403c2010-01-13 23:51:12 +00003552 AddObjCImplementationResults(getLangOptions(), Results, false);
Douglas Gregorb6ac2452010-01-13 21:24:21 +00003553 else if (InInterface)
Douglas Gregorbca403c2010-01-13 23:51:12 +00003554 AddObjCInterfaceResults(getLangOptions(), Results, false);
Douglas Gregorb6ac2452010-01-13 21:24:21 +00003555 else
Douglas Gregorbca403c2010-01-13 23:51:12 +00003556 AddObjCTopLevelResults(Results, false);
Douglas Gregorc464ae82009-12-07 09:27:33 +00003557 Results.ExitScope();
Douglas Gregore6b1bb62010-08-11 21:23:17 +00003558 HandleCodeCompleteResults(this, CodeCompleter,
3559 CodeCompletionContext::CCC_Other,
3560 Results.data(),Results.size());
Douglas Gregorc464ae82009-12-07 09:27:33 +00003561}
3562
Douglas Gregorbca403c2010-01-13 23:51:12 +00003563static void AddObjCExpressionResults(ResultBuilder &Results, bool NeedAt) {
John McCall0a2c5e22010-08-25 06:19:51 +00003564 typedef CodeCompletionResult Result;
Douglas Gregor9a0c85e2009-12-07 09:51:25 +00003565 CodeCompletionString *Pattern = 0;
3566
3567 // @encode ( type-name )
3568 Pattern = new CodeCompletionString;
Douglas Gregorb6ac2452010-01-13 21:24:21 +00003569 Pattern->AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt,encode));
Douglas Gregor9a0c85e2009-12-07 09:51:25 +00003570 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
3571 Pattern->AddPlaceholderChunk("type-name");
3572 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
Douglas Gregora4477812010-01-14 16:01:26 +00003573 Results.AddResult(Result(Pattern));
Douglas Gregor9a0c85e2009-12-07 09:51:25 +00003574
3575 // @protocol ( protocol-name )
3576 Pattern = new CodeCompletionString;
Douglas Gregorb6ac2452010-01-13 21:24:21 +00003577 Pattern->AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt,protocol));
Douglas Gregor9a0c85e2009-12-07 09:51:25 +00003578 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
3579 Pattern->AddPlaceholderChunk("protocol-name");
3580 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
Douglas Gregora4477812010-01-14 16:01:26 +00003581 Results.AddResult(Result(Pattern));
Douglas Gregor9a0c85e2009-12-07 09:51:25 +00003582
3583 // @selector ( selector )
3584 Pattern = new CodeCompletionString;
Douglas Gregorb6ac2452010-01-13 21:24:21 +00003585 Pattern->AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt,selector));
Douglas Gregor9a0c85e2009-12-07 09:51:25 +00003586 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
3587 Pattern->AddPlaceholderChunk("selector");
3588 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
Douglas Gregora4477812010-01-14 16:01:26 +00003589 Results.AddResult(Result(Pattern));
Douglas Gregor9a0c85e2009-12-07 09:51:25 +00003590}
3591
Douglas Gregorbca403c2010-01-13 23:51:12 +00003592static void AddObjCStatementResults(ResultBuilder &Results, bool NeedAt) {
John McCall0a2c5e22010-08-25 06:19:51 +00003593 typedef CodeCompletionResult Result;
Douglas Gregor9a0c85e2009-12-07 09:51:25 +00003594 CodeCompletionString *Pattern = 0;
Douglas Gregorb6ac2452010-01-13 21:24:21 +00003595
Douglas Gregorc8bddde2010-05-28 00:22:41 +00003596 if (Results.includeCodePatterns()) {
3597 // @try { statements } @catch ( declaration ) { statements } @finally
3598 // { statements }
3599 Pattern = new CodeCompletionString;
3600 Pattern->AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt,try));
3601 Pattern->AddChunk(CodeCompletionString::CK_LeftBrace);
3602 Pattern->AddPlaceholderChunk("statements");
3603 Pattern->AddChunk(CodeCompletionString::CK_RightBrace);
3604 Pattern->AddTextChunk("@catch");
3605 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
3606 Pattern->AddPlaceholderChunk("parameter");
3607 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
3608 Pattern->AddChunk(CodeCompletionString::CK_LeftBrace);
3609 Pattern->AddPlaceholderChunk("statements");
3610 Pattern->AddChunk(CodeCompletionString::CK_RightBrace);
3611 Pattern->AddTextChunk("@finally");
3612 Pattern->AddChunk(CodeCompletionString::CK_LeftBrace);
3613 Pattern->AddPlaceholderChunk("statements");
3614 Pattern->AddChunk(CodeCompletionString::CK_RightBrace);
3615 Results.AddResult(Result(Pattern));
3616 }
Douglas Gregorb6ac2452010-01-13 21:24:21 +00003617
Douglas Gregor9a0c85e2009-12-07 09:51:25 +00003618 // @throw
3619 Pattern = new CodeCompletionString;
Douglas Gregorb6ac2452010-01-13 21:24:21 +00003620 Pattern->AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt,throw));
Douglas Gregor834389b2010-01-12 06:38:28 +00003621 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
Douglas Gregor9a0c85e2009-12-07 09:51:25 +00003622 Pattern->AddPlaceholderChunk("expression");
Douglas Gregora4477812010-01-14 16:01:26 +00003623 Results.AddResult(Result(Pattern));
Douglas Gregorb6ac2452010-01-13 21:24:21 +00003624
Douglas Gregorc8bddde2010-05-28 00:22:41 +00003625 if (Results.includeCodePatterns()) {
3626 // @synchronized ( expression ) { statements }
3627 Pattern = new CodeCompletionString;
3628 Pattern->AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt,synchronized));
3629 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
3630 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
3631 Pattern->AddPlaceholderChunk("expression");
3632 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
3633 Pattern->AddChunk(CodeCompletionString::CK_LeftBrace);
3634 Pattern->AddPlaceholderChunk("statements");
3635 Pattern->AddChunk(CodeCompletionString::CK_RightBrace);
3636 Results.AddResult(Result(Pattern));
3637 }
Douglas Gregorb6ac2452010-01-13 21:24:21 +00003638}
Douglas Gregor9a0c85e2009-12-07 09:51:25 +00003639
Douglas Gregorbca403c2010-01-13 23:51:12 +00003640static void AddObjCVisibilityResults(const LangOptions &LangOpts,
Douglas Gregorc38c3e12010-01-13 21:54:15 +00003641 ResultBuilder &Results,
3642 bool NeedAt) {
John McCall0a2c5e22010-08-25 06:19:51 +00003643 typedef CodeCompletionResult Result;
Douglas Gregora4477812010-01-14 16:01:26 +00003644 Results.AddResult(Result(OBJC_AT_KEYWORD_NAME(NeedAt,private)));
3645 Results.AddResult(Result(OBJC_AT_KEYWORD_NAME(NeedAt,protected)));
3646 Results.AddResult(Result(OBJC_AT_KEYWORD_NAME(NeedAt,public)));
Douglas Gregorc38c3e12010-01-13 21:54:15 +00003647 if (LangOpts.ObjC2)
Douglas Gregora4477812010-01-14 16:01:26 +00003648 Results.AddResult(Result(OBJC_AT_KEYWORD_NAME(NeedAt,package)));
Douglas Gregorc38c3e12010-01-13 21:54:15 +00003649}
3650
3651void Sema::CodeCompleteObjCAtVisibility(Scope *S) {
3652 ResultBuilder Results(*this);
3653 Results.EnterNewScope();
Douglas Gregorbca403c2010-01-13 23:51:12 +00003654 AddObjCVisibilityResults(getLangOptions(), Results, false);
Douglas Gregorc38c3e12010-01-13 21:54:15 +00003655 Results.ExitScope();
Douglas Gregore6b1bb62010-08-11 21:23:17 +00003656 HandleCodeCompleteResults(this, CodeCompleter,
3657 CodeCompletionContext::CCC_Other,
3658 Results.data(),Results.size());
Douglas Gregorc38c3e12010-01-13 21:54:15 +00003659}
3660
3661void Sema::CodeCompleteObjCAtStatement(Scope *S) {
Douglas Gregorb6ac2452010-01-13 21:24:21 +00003662 ResultBuilder Results(*this);
3663 Results.EnterNewScope();
Douglas Gregorbca403c2010-01-13 23:51:12 +00003664 AddObjCStatementResults(Results, false);
3665 AddObjCExpressionResults(Results, false);
Douglas Gregor9a0c85e2009-12-07 09:51:25 +00003666 Results.ExitScope();
Douglas Gregore6b1bb62010-08-11 21:23:17 +00003667 HandleCodeCompleteResults(this, CodeCompleter,
3668 CodeCompletionContext::CCC_Other,
3669 Results.data(),Results.size());
Douglas Gregor9a0c85e2009-12-07 09:51:25 +00003670}
3671
3672void Sema::CodeCompleteObjCAtExpression(Scope *S) {
3673 ResultBuilder Results(*this);
3674 Results.EnterNewScope();
Douglas Gregorbca403c2010-01-13 23:51:12 +00003675 AddObjCExpressionResults(Results, false);
Douglas Gregor9a0c85e2009-12-07 09:51:25 +00003676 Results.ExitScope();
Douglas Gregore6b1bb62010-08-11 21:23:17 +00003677 HandleCodeCompleteResults(this, CodeCompleter,
3678 CodeCompletionContext::CCC_Other,
3679 Results.data(),Results.size());
Douglas Gregor9a0c85e2009-12-07 09:51:25 +00003680}
3681
Douglas Gregor988358f2009-11-19 00:14:45 +00003682/// \brief Determine whether the addition of the given flag to an Objective-C
3683/// property's attributes will cause a conflict.
3684static bool ObjCPropertyFlagConflicts(unsigned Attributes, unsigned NewFlag) {
3685 // Check if we've already added this flag.
3686 if (Attributes & NewFlag)
3687 return true;
3688
3689 Attributes |= NewFlag;
3690
3691 // Check for collisions with "readonly".
3692 if ((Attributes & ObjCDeclSpec::DQ_PR_readonly) &&
3693 (Attributes & (ObjCDeclSpec::DQ_PR_readwrite |
3694 ObjCDeclSpec::DQ_PR_assign |
3695 ObjCDeclSpec::DQ_PR_copy |
3696 ObjCDeclSpec::DQ_PR_retain)))
3697 return true;
3698
3699 // Check for more than one of { assign, copy, retain }.
3700 unsigned AssignCopyRetMask = Attributes & (ObjCDeclSpec::DQ_PR_assign |
3701 ObjCDeclSpec::DQ_PR_copy |
3702 ObjCDeclSpec::DQ_PR_retain);
3703 if (AssignCopyRetMask &&
3704 AssignCopyRetMask != ObjCDeclSpec::DQ_PR_assign &&
3705 AssignCopyRetMask != ObjCDeclSpec::DQ_PR_copy &&
3706 AssignCopyRetMask != ObjCDeclSpec::DQ_PR_retain)
3707 return true;
3708
3709 return false;
3710}
3711
Douglas Gregora93b1082009-11-18 23:08:07 +00003712void Sema::CodeCompleteObjCPropertyFlags(Scope *S, ObjCDeclSpec &ODS) {
Steve Naroffece8e712009-10-08 21:55:05 +00003713 if (!CodeCompleter)
3714 return;
Douglas Gregord3c68542009-11-19 01:08:35 +00003715
Steve Naroffece8e712009-10-08 21:55:05 +00003716 unsigned Attributes = ODS.getPropertyAttributes();
3717
John McCall0a2c5e22010-08-25 06:19:51 +00003718 typedef CodeCompletionResult Result;
Steve Naroffece8e712009-10-08 21:55:05 +00003719 ResultBuilder Results(*this);
3720 Results.EnterNewScope();
Douglas Gregor988358f2009-11-19 00:14:45 +00003721 if (!ObjCPropertyFlagConflicts(Attributes, ObjCDeclSpec::DQ_PR_readonly))
John McCall0a2c5e22010-08-25 06:19:51 +00003722 Results.AddResult(CodeCompletionResult("readonly"));
Douglas Gregor988358f2009-11-19 00:14:45 +00003723 if (!ObjCPropertyFlagConflicts(Attributes, ObjCDeclSpec::DQ_PR_assign))
John McCall0a2c5e22010-08-25 06:19:51 +00003724 Results.AddResult(CodeCompletionResult("assign"));
Douglas Gregor988358f2009-11-19 00:14:45 +00003725 if (!ObjCPropertyFlagConflicts(Attributes, ObjCDeclSpec::DQ_PR_readwrite))
John McCall0a2c5e22010-08-25 06:19:51 +00003726 Results.AddResult(CodeCompletionResult("readwrite"));
Douglas Gregor988358f2009-11-19 00:14:45 +00003727 if (!ObjCPropertyFlagConflicts(Attributes, ObjCDeclSpec::DQ_PR_retain))
John McCall0a2c5e22010-08-25 06:19:51 +00003728 Results.AddResult(CodeCompletionResult("retain"));
Douglas Gregor988358f2009-11-19 00:14:45 +00003729 if (!ObjCPropertyFlagConflicts(Attributes, ObjCDeclSpec::DQ_PR_copy))
John McCall0a2c5e22010-08-25 06:19:51 +00003730 Results.AddResult(CodeCompletionResult("copy"));
Douglas Gregor988358f2009-11-19 00:14:45 +00003731 if (!ObjCPropertyFlagConflicts(Attributes, ObjCDeclSpec::DQ_PR_nonatomic))
John McCall0a2c5e22010-08-25 06:19:51 +00003732 Results.AddResult(CodeCompletionResult("nonatomic"));
Douglas Gregor988358f2009-11-19 00:14:45 +00003733 if (!ObjCPropertyFlagConflicts(Attributes, ObjCDeclSpec::DQ_PR_setter)) {
Douglas Gregor54f01612009-11-19 00:01:57 +00003734 CodeCompletionString *Setter = new CodeCompletionString;
3735 Setter->AddTypedTextChunk("setter");
3736 Setter->AddTextChunk(" = ");
3737 Setter->AddPlaceholderChunk("method");
John McCall0a2c5e22010-08-25 06:19:51 +00003738 Results.AddResult(CodeCompletionResult(Setter));
Douglas Gregor54f01612009-11-19 00:01:57 +00003739 }
Douglas Gregor988358f2009-11-19 00:14:45 +00003740 if (!ObjCPropertyFlagConflicts(Attributes, ObjCDeclSpec::DQ_PR_getter)) {
Douglas Gregor54f01612009-11-19 00:01:57 +00003741 CodeCompletionString *Getter = new CodeCompletionString;
3742 Getter->AddTypedTextChunk("getter");
3743 Getter->AddTextChunk(" = ");
3744 Getter->AddPlaceholderChunk("method");
John McCall0a2c5e22010-08-25 06:19:51 +00003745 Results.AddResult(CodeCompletionResult(Getter));
Douglas Gregor54f01612009-11-19 00:01:57 +00003746 }
Steve Naroffece8e712009-10-08 21:55:05 +00003747 Results.ExitScope();
Douglas Gregore6b1bb62010-08-11 21:23:17 +00003748 HandleCodeCompleteResults(this, CodeCompleter,
3749 CodeCompletionContext::CCC_Other,
3750 Results.data(),Results.size());
Steve Naroffece8e712009-10-08 21:55:05 +00003751}
Steve Naroffc4df6d22009-11-07 02:08:14 +00003752
Douglas Gregor4ad96852009-11-19 07:41:15 +00003753/// \brief Descripts the kind of Objective-C method that we want to find
3754/// via code completion.
3755enum ObjCMethodKind {
3756 MK_Any, //< Any kind of method, provided it means other specified criteria.
3757 MK_ZeroArgSelector, //< Zero-argument (unary) selector.
3758 MK_OneArgSelector //< One-argument selector.
3759};
3760
Douglas Gregor458433d2010-08-26 15:07:07 +00003761static bool isAcceptableObjCSelector(Selector Sel,
3762 ObjCMethodKind WantKind,
3763 IdentifierInfo **SelIdents,
3764 unsigned NumSelIdents) {
3765 if (NumSelIdents > Sel.getNumArgs())
3766 return false;
3767
3768 switch (WantKind) {
3769 case MK_Any: break;
3770 case MK_ZeroArgSelector: return Sel.isUnarySelector();
3771 case MK_OneArgSelector: return Sel.getNumArgs() == 1;
3772 }
3773
3774 for (unsigned I = 0; I != NumSelIdents; ++I)
3775 if (SelIdents[I] != Sel.getIdentifierInfoForSlot(I))
3776 return false;
3777
3778 return true;
3779}
3780
Douglas Gregor4ad96852009-11-19 07:41:15 +00003781static bool isAcceptableObjCMethod(ObjCMethodDecl *Method,
3782 ObjCMethodKind WantKind,
3783 IdentifierInfo **SelIdents,
3784 unsigned NumSelIdents) {
Douglas Gregor458433d2010-08-26 15:07:07 +00003785 return isAcceptableObjCSelector(Method->getSelector(), WantKind, SelIdents,
3786 NumSelIdents);
Douglas Gregor4ad96852009-11-19 07:41:15 +00003787}
3788
Douglas Gregor36ecb042009-11-17 23:22:23 +00003789/// \brief Add all of the Objective-C methods in the given Objective-C
3790/// container to the set of results.
3791///
3792/// The container will be a class, protocol, category, or implementation of
3793/// any of the above. This mether will recurse to include methods from
3794/// the superclasses of classes along with their categories, protocols, and
3795/// implementations.
3796///
3797/// \param Container the container in which we'll look to find methods.
3798///
3799/// \param WantInstance whether to add instance methods (only); if false, this
3800/// routine will add factory methods (only).
3801///
3802/// \param CurContext the context in which we're performing the lookup that
3803/// finds methods.
3804///
3805/// \param Results the structure into which we'll add results.
3806static void AddObjCMethods(ObjCContainerDecl *Container,
3807 bool WantInstanceMethods,
Douglas Gregor4ad96852009-11-19 07:41:15 +00003808 ObjCMethodKind WantKind,
Douglas Gregord3c68542009-11-19 01:08:35 +00003809 IdentifierInfo **SelIdents,
3810 unsigned NumSelIdents,
Douglas Gregor36ecb042009-11-17 23:22:23 +00003811 DeclContext *CurContext,
Douglas Gregor408be5a2010-08-25 01:08:01 +00003812 ResultBuilder &Results,
3813 bool InOriginalClass = true) {
John McCall0a2c5e22010-08-25 06:19:51 +00003814 typedef CodeCompletionResult Result;
Douglas Gregor36ecb042009-11-17 23:22:23 +00003815 for (ObjCContainerDecl::method_iterator M = Container->meth_begin(),
3816 MEnd = Container->meth_end();
3817 M != MEnd; ++M) {
Douglas Gregord3c68542009-11-19 01:08:35 +00003818 if ((*M)->isInstanceMethod() == WantInstanceMethods) {
3819 // Check whether the selector identifiers we've been given are a
3820 // subset of the identifiers for this particular method.
Douglas Gregor4ad96852009-11-19 07:41:15 +00003821 if (!isAcceptableObjCMethod(*M, WantKind, SelIdents, NumSelIdents))
Douglas Gregord3c68542009-11-19 01:08:35 +00003822 continue;
Douglas Gregor4ad96852009-11-19 07:41:15 +00003823
Douglas Gregord3c68542009-11-19 01:08:35 +00003824 Result R = Result(*M, 0);
3825 R.StartParameter = NumSelIdents;
Douglas Gregor4ad96852009-11-19 07:41:15 +00003826 R.AllParametersAreInformative = (WantKind != MK_Any);
Douglas Gregor408be5a2010-08-25 01:08:01 +00003827 if (!InOriginalClass)
3828 R.Priority += CCD_InBaseClass;
Douglas Gregord3c68542009-11-19 01:08:35 +00003829 Results.MaybeAddResult(R, CurContext);
3830 }
Douglas Gregor36ecb042009-11-17 23:22:23 +00003831 }
3832
3833 ObjCInterfaceDecl *IFace = dyn_cast<ObjCInterfaceDecl>(Container);
3834 if (!IFace)
3835 return;
3836
3837 // Add methods in protocols.
3838 const ObjCList<ObjCProtocolDecl> &Protocols= IFace->getReferencedProtocols();
3839 for (ObjCList<ObjCProtocolDecl>::iterator I = Protocols.begin(),
3840 E = Protocols.end();
3841 I != E; ++I)
Douglas Gregor4ad96852009-11-19 07:41:15 +00003842 AddObjCMethods(*I, WantInstanceMethods, WantKind, SelIdents, NumSelIdents,
Douglas Gregor408be5a2010-08-25 01:08:01 +00003843 CurContext, Results, false);
Douglas Gregor36ecb042009-11-17 23:22:23 +00003844
3845 // Add methods in categories.
3846 for (ObjCCategoryDecl *CatDecl = IFace->getCategoryList(); CatDecl;
3847 CatDecl = CatDecl->getNextClassCategory()) {
Douglas Gregor4ad96852009-11-19 07:41:15 +00003848 AddObjCMethods(CatDecl, WantInstanceMethods, WantKind, SelIdents,
Douglas Gregor408be5a2010-08-25 01:08:01 +00003849 NumSelIdents, CurContext, Results, InOriginalClass);
Douglas Gregor36ecb042009-11-17 23:22:23 +00003850
3851 // Add a categories protocol methods.
3852 const ObjCList<ObjCProtocolDecl> &Protocols
3853 = CatDecl->getReferencedProtocols();
3854 for (ObjCList<ObjCProtocolDecl>::iterator I = Protocols.begin(),
3855 E = Protocols.end();
3856 I != E; ++I)
Douglas Gregor4ad96852009-11-19 07:41:15 +00003857 AddObjCMethods(*I, WantInstanceMethods, WantKind, SelIdents,
Douglas Gregor408be5a2010-08-25 01:08:01 +00003858 NumSelIdents, CurContext, Results, false);
Douglas Gregor36ecb042009-11-17 23:22:23 +00003859
3860 // Add methods in category implementations.
3861 if (ObjCCategoryImplDecl *Impl = CatDecl->getImplementation())
Douglas Gregor4ad96852009-11-19 07:41:15 +00003862 AddObjCMethods(Impl, WantInstanceMethods, WantKind, SelIdents,
Douglas Gregor408be5a2010-08-25 01:08:01 +00003863 NumSelIdents, CurContext, Results, InOriginalClass);
Douglas Gregor36ecb042009-11-17 23:22:23 +00003864 }
3865
3866 // Add methods in superclass.
3867 if (IFace->getSuperClass())
Douglas Gregor4ad96852009-11-19 07:41:15 +00003868 AddObjCMethods(IFace->getSuperClass(), WantInstanceMethods, WantKind,
Douglas Gregor408be5a2010-08-25 01:08:01 +00003869 SelIdents, NumSelIdents, CurContext, Results, false);
Douglas Gregor36ecb042009-11-17 23:22:23 +00003870
3871 // Add methods in our implementation, if any.
3872 if (ObjCImplementationDecl *Impl = IFace->getImplementation())
Douglas Gregor4ad96852009-11-19 07:41:15 +00003873 AddObjCMethods(Impl, WantInstanceMethods, WantKind, SelIdents,
Douglas Gregor408be5a2010-08-25 01:08:01 +00003874 NumSelIdents, CurContext, Results, InOriginalClass);
Douglas Gregor4ad96852009-11-19 07:41:15 +00003875}
3876
3877
John McCalld226f652010-08-21 09:40:31 +00003878void Sema::CodeCompleteObjCPropertyGetter(Scope *S, Decl *ClassDecl,
3879 Decl **Methods,
Douglas Gregor4ad96852009-11-19 07:41:15 +00003880 unsigned NumMethods) {
John McCall0a2c5e22010-08-25 06:19:51 +00003881 typedef CodeCompletionResult Result;
Douglas Gregor4ad96852009-11-19 07:41:15 +00003882
3883 // Try to find the interface where getters might live.
John McCalld226f652010-08-21 09:40:31 +00003884 ObjCInterfaceDecl *Class = dyn_cast_or_null<ObjCInterfaceDecl>(ClassDecl);
Douglas Gregor4ad96852009-11-19 07:41:15 +00003885 if (!Class) {
3886 if (ObjCCategoryDecl *Category
John McCalld226f652010-08-21 09:40:31 +00003887 = dyn_cast_or_null<ObjCCategoryDecl>(ClassDecl))
Douglas Gregor4ad96852009-11-19 07:41:15 +00003888 Class = Category->getClassInterface();
3889
3890 if (!Class)
3891 return;
3892 }
3893
3894 // Find all of the potential getters.
3895 ResultBuilder Results(*this);
3896 Results.EnterNewScope();
3897
3898 // FIXME: We need to do this because Objective-C methods don't get
3899 // pushed into DeclContexts early enough. Argh!
3900 for (unsigned I = 0; I != NumMethods; ++I) {
3901 if (ObjCMethodDecl *Method
John McCalld226f652010-08-21 09:40:31 +00003902 = dyn_cast_or_null<ObjCMethodDecl>(Methods[I]))
Douglas Gregor4ad96852009-11-19 07:41:15 +00003903 if (Method->isInstanceMethod() &&
3904 isAcceptableObjCMethod(Method, MK_ZeroArgSelector, 0, 0)) {
3905 Result R = Result(Method, 0);
3906 R.AllParametersAreInformative = true;
3907 Results.MaybeAddResult(R, CurContext);
3908 }
3909 }
3910
3911 AddObjCMethods(Class, true, MK_ZeroArgSelector, 0, 0, CurContext, Results);
3912 Results.ExitScope();
Douglas Gregore6b1bb62010-08-11 21:23:17 +00003913 HandleCodeCompleteResults(this, CodeCompleter,
3914 CodeCompletionContext::CCC_Other,
3915 Results.data(),Results.size());
Douglas Gregor4ad96852009-11-19 07:41:15 +00003916}
3917
John McCalld226f652010-08-21 09:40:31 +00003918void Sema::CodeCompleteObjCPropertySetter(Scope *S, Decl *ObjCImplDecl,
3919 Decl **Methods,
Douglas Gregor4ad96852009-11-19 07:41:15 +00003920 unsigned NumMethods) {
John McCall0a2c5e22010-08-25 06:19:51 +00003921 typedef CodeCompletionResult Result;
Douglas Gregor4ad96852009-11-19 07:41:15 +00003922
3923 // Try to find the interface where setters might live.
3924 ObjCInterfaceDecl *Class
John McCalld226f652010-08-21 09:40:31 +00003925 = dyn_cast_or_null<ObjCInterfaceDecl>(ObjCImplDecl);
Douglas Gregor4ad96852009-11-19 07:41:15 +00003926 if (!Class) {
3927 if (ObjCCategoryDecl *Category
John McCalld226f652010-08-21 09:40:31 +00003928 = dyn_cast_or_null<ObjCCategoryDecl>(ObjCImplDecl))
Douglas Gregor4ad96852009-11-19 07:41:15 +00003929 Class = Category->getClassInterface();
3930
3931 if (!Class)
3932 return;
3933 }
3934
3935 // Find all of the potential getters.
3936 ResultBuilder Results(*this);
3937 Results.EnterNewScope();
3938
3939 // FIXME: We need to do this because Objective-C methods don't get
3940 // pushed into DeclContexts early enough. Argh!
3941 for (unsigned I = 0; I != NumMethods; ++I) {
3942 if (ObjCMethodDecl *Method
John McCalld226f652010-08-21 09:40:31 +00003943 = dyn_cast_or_null<ObjCMethodDecl>(Methods[I]))
Douglas Gregor4ad96852009-11-19 07:41:15 +00003944 if (Method->isInstanceMethod() &&
3945 isAcceptableObjCMethod(Method, MK_OneArgSelector, 0, 0)) {
3946 Result R = Result(Method, 0);
3947 R.AllParametersAreInformative = true;
3948 Results.MaybeAddResult(R, CurContext);
3949 }
3950 }
3951
3952 AddObjCMethods(Class, true, MK_OneArgSelector, 0, 0, CurContext, Results);
3953
3954 Results.ExitScope();
Douglas Gregore6b1bb62010-08-11 21:23:17 +00003955 HandleCodeCompleteResults(this, CodeCompleter,
3956 CodeCompletionContext::CCC_Other,
3957 Results.data(),Results.size());
Douglas Gregor36ecb042009-11-17 23:22:23 +00003958}
3959
Douglas Gregord32b0222010-08-24 01:06:58 +00003960void Sema::CodeCompleteObjCPassingType(Scope *S, ObjCDeclSpec &DS) {
John McCall0a2c5e22010-08-25 06:19:51 +00003961 typedef CodeCompletionResult Result;
Douglas Gregord32b0222010-08-24 01:06:58 +00003962 ResultBuilder Results(*this);
3963 Results.EnterNewScope();
3964
3965 // Add context-sensitive, Objective-C parameter-passing keywords.
3966 bool AddedInOut = false;
3967 if ((DS.getObjCDeclQualifier() &
3968 (ObjCDeclSpec::DQ_In | ObjCDeclSpec::DQ_Inout)) == 0) {
3969 Results.AddResult("in");
3970 Results.AddResult("inout");
3971 AddedInOut = true;
3972 }
3973 if ((DS.getObjCDeclQualifier() &
3974 (ObjCDeclSpec::DQ_Out | ObjCDeclSpec::DQ_Inout)) == 0) {
3975 Results.AddResult("out");
3976 if (!AddedInOut)
3977 Results.AddResult("inout");
3978 }
3979 if ((DS.getObjCDeclQualifier() &
3980 (ObjCDeclSpec::DQ_Bycopy | ObjCDeclSpec::DQ_Byref |
3981 ObjCDeclSpec::DQ_Oneway)) == 0) {
3982 Results.AddResult("bycopy");
3983 Results.AddResult("byref");
3984 Results.AddResult("oneway");
3985 }
3986
3987 // Add various builtin type names and specifiers.
3988 AddOrdinaryNameResults(PCC_Type, S, *this, Results);
3989 Results.ExitScope();
3990
3991 // Add the various type names
3992 Results.setFilter(&ResultBuilder::IsOrdinaryNonValueName);
3993 CodeCompletionDeclConsumer Consumer(Results, CurContext);
3994 LookupVisibleDecls(S, LookupOrdinaryName, Consumer,
3995 CodeCompleter->includeGlobals());
3996
3997 if (CodeCompleter->includeMacros())
3998 AddMacroResults(PP, Results);
3999
4000 HandleCodeCompleteResults(this, CodeCompleter,
4001 CodeCompletionContext::CCC_Type,
4002 Results.data(), Results.size());
4003}
4004
Douglas Gregor22f56992010-04-06 19:22:33 +00004005/// \brief When we have an expression with type "id", we may assume
4006/// that it has some more-specific class type based on knowledge of
4007/// common uses of Objective-C. This routine returns that class type,
4008/// or NULL if no better result could be determined.
4009static ObjCInterfaceDecl *GetAssumedMessageSendExprType(Expr *E) {
4010 ObjCMessageExpr *Msg = dyn_cast<ObjCMessageExpr>(E);
4011 if (!Msg)
4012 return 0;
4013
4014 Selector Sel = Msg->getSelector();
4015 if (Sel.isNull())
4016 return 0;
4017
4018 IdentifierInfo *Id = Sel.getIdentifierInfoForSlot(0);
4019 if (!Id)
4020 return 0;
4021
4022 ObjCMethodDecl *Method = Msg->getMethodDecl();
4023 if (!Method)
4024 return 0;
4025
4026 // Determine the class that we're sending the message to.
Douglas Gregor04badcf2010-04-21 00:45:42 +00004027 ObjCInterfaceDecl *IFace = 0;
4028 switch (Msg->getReceiverKind()) {
4029 case ObjCMessageExpr::Class:
John McCallc12c5bb2010-05-15 11:32:37 +00004030 if (const ObjCObjectType *ObjType
4031 = Msg->getClassReceiver()->getAs<ObjCObjectType>())
4032 IFace = ObjType->getInterface();
Douglas Gregor04badcf2010-04-21 00:45:42 +00004033 break;
4034
4035 case ObjCMessageExpr::Instance: {
4036 QualType T = Msg->getInstanceReceiver()->getType();
4037 if (const ObjCObjectPointerType *Ptr = T->getAs<ObjCObjectPointerType>())
4038 IFace = Ptr->getInterfaceDecl();
4039 break;
4040 }
4041
4042 case ObjCMessageExpr::SuperInstance:
4043 case ObjCMessageExpr::SuperClass:
4044 break;
Douglas Gregor22f56992010-04-06 19:22:33 +00004045 }
4046
4047 if (!IFace)
4048 return 0;
4049
4050 ObjCInterfaceDecl *Super = IFace->getSuperClass();
4051 if (Method->isInstanceMethod())
4052 return llvm::StringSwitch<ObjCInterfaceDecl *>(Id->getName())
4053 .Case("retain", IFace)
4054 .Case("autorelease", IFace)
4055 .Case("copy", IFace)
4056 .Case("copyWithZone", IFace)
4057 .Case("mutableCopy", IFace)
4058 .Case("mutableCopyWithZone", IFace)
4059 .Case("awakeFromCoder", IFace)
4060 .Case("replacementObjectFromCoder", IFace)
4061 .Case("class", IFace)
4062 .Case("classForCoder", IFace)
4063 .Case("superclass", Super)
4064 .Default(0);
4065
4066 return llvm::StringSwitch<ObjCInterfaceDecl *>(Id->getName())
4067 .Case("new", IFace)
4068 .Case("alloc", IFace)
4069 .Case("allocWithZone", IFace)
4070 .Case("class", IFace)
4071 .Case("superclass", Super)
4072 .Default(0);
4073}
4074
Douglas Gregor03d8aec2010-08-27 15:10:57 +00004075// Add a special completion for a message send to "super", which fills in the
4076// most likely case of forwarding all of our arguments to the superclass
4077// function.
4078///
4079/// \param S The semantic analysis object.
4080///
4081/// \param S NeedSuperKeyword Whether we need to prefix this completion with
4082/// the "super" keyword. Otherwise, we just need to provide the arguments.
4083///
4084/// \param SelIdents The identifiers in the selector that have already been
4085/// provided as arguments for a send to "super".
4086///
4087/// \param NumSelIdents The number of identifiers in \p SelIdents.
4088///
4089/// \param Results The set of results to augment.
4090///
4091/// \returns the Objective-C method declaration that would be invoked by
4092/// this "super" completion. If NULL, no completion was added.
4093static ObjCMethodDecl *AddSuperSendCompletion(Sema &S, bool NeedSuperKeyword,
4094 IdentifierInfo **SelIdents,
4095 unsigned NumSelIdents,
4096 ResultBuilder &Results) {
4097 ObjCMethodDecl *CurMethod = S.getCurMethodDecl();
4098 if (!CurMethod)
4099 return 0;
4100
4101 ObjCInterfaceDecl *Class = CurMethod->getClassInterface();
4102 if (!Class)
4103 return 0;
4104
4105 // Try to find a superclass method with the same selector.
4106 ObjCMethodDecl *SuperMethod = 0;
4107 while ((Class = Class->getSuperClass()) && !SuperMethod)
4108 SuperMethod = Class->getMethod(CurMethod->getSelector(),
4109 CurMethod->isInstanceMethod());
4110
4111 if (!SuperMethod)
4112 return 0;
4113
4114 // Check whether the superclass method has the same signature.
4115 if (CurMethod->param_size() != SuperMethod->param_size() ||
4116 CurMethod->isVariadic() != SuperMethod->isVariadic())
4117 return 0;
4118
4119 for (ObjCMethodDecl::param_iterator CurP = CurMethod->param_begin(),
4120 CurPEnd = CurMethod->param_end(),
4121 SuperP = SuperMethod->param_begin();
4122 CurP != CurPEnd; ++CurP, ++SuperP) {
4123 // Make sure the parameter types are compatible.
4124 if (!S.Context.hasSameUnqualifiedType((*CurP)->getType(),
4125 (*SuperP)->getType()))
4126 return 0;
4127
4128 // Make sure we have a parameter name to forward!
4129 if (!(*CurP)->getIdentifier())
4130 return 0;
4131 }
4132
4133 // We have a superclass method. Now, form the send-to-super completion.
4134 CodeCompletionString *Pattern = new CodeCompletionString;
4135
4136 // Give this completion a return type.
4137 AddResultTypeChunk(S.Context, SuperMethod, Pattern);
4138
4139 // If we need the "super" keyword, add it (plus some spacing).
4140 if (NeedSuperKeyword) {
4141 Pattern->AddTypedTextChunk("super");
4142 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
4143 }
4144
4145 Selector Sel = CurMethod->getSelector();
4146 if (Sel.isUnarySelector()) {
4147 if (NeedSuperKeyword)
4148 Pattern->AddTextChunk(Sel.getIdentifierInfoForSlot(0)->getName());
4149 else
4150 Pattern->AddTypedTextChunk(Sel.getIdentifierInfoForSlot(0)->getName());
4151 } else {
4152 ObjCMethodDecl::param_iterator CurP = CurMethod->param_begin();
4153 for (unsigned I = 0, N = Sel.getNumArgs(); I != N; ++I, ++CurP) {
4154 if (I > NumSelIdents)
4155 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
4156
4157 if (I < NumSelIdents)
4158 Pattern->AddInformativeChunk(
4159 Sel.getIdentifierInfoForSlot(I)->getName().str() + ":");
4160 else if (NeedSuperKeyword || I > NumSelIdents) {
4161 Pattern->AddTextChunk(
4162 Sel.getIdentifierInfoForSlot(I)->getName().str() + ":");
4163 Pattern->AddPlaceholderChunk((*CurP)->getIdentifier()->getName());
4164 } else {
4165 Pattern->AddTypedTextChunk(
4166 Sel.getIdentifierInfoForSlot(I)->getName().str() + ":");
4167 Pattern->AddPlaceholderChunk((*CurP)->getIdentifier()->getName());
4168 }
4169 }
4170 }
4171
4172 Results.AddResult(CodeCompletionResult(Pattern, CCP_SuperCompletion,
4173 SuperMethod->isInstanceMethod()
4174 ? CXCursor_ObjCInstanceMethodDecl
4175 : CXCursor_ObjCClassMethodDecl));
4176 return SuperMethod;
4177}
4178
Douglas Gregor8e254cf2010-05-27 23:06:34 +00004179void Sema::CodeCompleteObjCMessageReceiver(Scope *S) {
John McCall0a2c5e22010-08-25 06:19:51 +00004180 typedef CodeCompletionResult Result;
Douglas Gregor8e254cf2010-05-27 23:06:34 +00004181 ResultBuilder Results(*this);
4182
4183 // Find anything that looks like it could be a message receiver.
4184 Results.setFilter(&ResultBuilder::IsObjCMessageReceiver);
4185 CodeCompletionDeclConsumer Consumer(Results, CurContext);
4186 Results.EnterNewScope();
Douglas Gregor8071e422010-08-15 06:18:01 +00004187 LookupVisibleDecls(S, LookupOrdinaryName, Consumer,
4188 CodeCompleter->includeGlobals());
Douglas Gregor8e254cf2010-05-27 23:06:34 +00004189
4190 // If we are in an Objective-C method inside a class that has a superclass,
4191 // add "super" as an option.
4192 if (ObjCMethodDecl *Method = getCurMethodDecl())
4193 if (ObjCInterfaceDecl *Iface = Method->getClassInterface())
Douglas Gregor03d8aec2010-08-27 15:10:57 +00004194 if (Iface->getSuperClass()) {
Douglas Gregor8e254cf2010-05-27 23:06:34 +00004195 Results.AddResult(Result("super"));
Douglas Gregor03d8aec2010-08-27 15:10:57 +00004196
4197 AddSuperSendCompletion(*this, /*NeedSuperKeyword=*/true, 0, 0, Results);
4198 }
Douglas Gregor8e254cf2010-05-27 23:06:34 +00004199
4200 Results.ExitScope();
4201
4202 if (CodeCompleter->includeMacros())
4203 AddMacroResults(PP, Results);
Douglas Gregore6b1bb62010-08-11 21:23:17 +00004204 HandleCodeCompleteResults(this, CodeCompleter,
4205 CodeCompletionContext::CCC_ObjCMessageReceiver,
4206 Results.data(), Results.size());
Douglas Gregor8e254cf2010-05-27 23:06:34 +00004207
4208}
4209
Douglas Gregor2725ca82010-04-21 19:57:20 +00004210void Sema::CodeCompleteObjCSuperMessage(Scope *S, SourceLocation SuperLoc,
4211 IdentifierInfo **SelIdents,
4212 unsigned NumSelIdents) {
4213 ObjCInterfaceDecl *CDecl = 0;
4214 if (ObjCMethodDecl *CurMethod = getCurMethodDecl()) {
4215 // Figure out which interface we're in.
4216 CDecl = CurMethod->getClassInterface();
4217 if (!CDecl)
4218 return;
4219
4220 // Find the superclass of this class.
4221 CDecl = CDecl->getSuperClass();
4222 if (!CDecl)
4223 return;
4224
4225 if (CurMethod->isInstanceMethod()) {
4226 // We are inside an instance method, which means that the message
4227 // send [super ...] is actually calling an instance method on the
4228 // current object. Build the super expression and handle this like
4229 // an instance method.
4230 QualType SuperTy = Context.getObjCInterfaceType(CDecl);
4231 SuperTy = Context.getObjCObjectPointerType(SuperTy);
John McCall60d7b3a2010-08-24 06:29:42 +00004232 ExprResult Super
Douglas Gregor2725ca82010-04-21 19:57:20 +00004233 = Owned(new (Context) ObjCSuperExpr(SuperLoc, SuperTy));
4234 return CodeCompleteObjCInstanceMessage(S, (Expr *)Super.get(),
Douglas Gregor03d8aec2010-08-27 15:10:57 +00004235 SelIdents, NumSelIdents,
4236 /*IsSuper=*/true);
Douglas Gregor2725ca82010-04-21 19:57:20 +00004237 }
4238
4239 // Fall through to send to the superclass in CDecl.
4240 } else {
4241 // "super" may be the name of a type or variable. Figure out which
4242 // it is.
4243 IdentifierInfo *Super = &Context.Idents.get("super");
4244 NamedDecl *ND = LookupSingleName(S, Super, SuperLoc,
4245 LookupOrdinaryName);
4246 if ((CDecl = dyn_cast_or_null<ObjCInterfaceDecl>(ND))) {
4247 // "super" names an interface. Use it.
4248 } else if (TypeDecl *TD = dyn_cast_or_null<TypeDecl>(ND)) {
John McCallc12c5bb2010-05-15 11:32:37 +00004249 if (const ObjCObjectType *Iface
4250 = Context.getTypeDeclType(TD)->getAs<ObjCObjectType>())
4251 CDecl = Iface->getInterface();
Douglas Gregor2725ca82010-04-21 19:57:20 +00004252 } else if (ND && isa<UnresolvedUsingTypenameDecl>(ND)) {
4253 // "super" names an unresolved type; we can't be more specific.
4254 } else {
4255 // Assume that "super" names some kind of value and parse that way.
4256 CXXScopeSpec SS;
4257 UnqualifiedId id;
4258 id.setIdentifier(Super, SuperLoc);
John McCall60d7b3a2010-08-24 06:29:42 +00004259 ExprResult SuperExpr = ActOnIdExpression(S, SS, id, false, false);
Douglas Gregor2725ca82010-04-21 19:57:20 +00004260 return CodeCompleteObjCInstanceMessage(S, (Expr *)SuperExpr.get(),
4261 SelIdents, NumSelIdents);
4262 }
4263
4264 // Fall through
4265 }
4266
John McCallb3d87482010-08-24 05:47:05 +00004267 ParsedType Receiver;
Douglas Gregor2725ca82010-04-21 19:57:20 +00004268 if (CDecl)
John McCallb3d87482010-08-24 05:47:05 +00004269 Receiver = ParsedType::make(Context.getObjCInterfaceType(CDecl));
Douglas Gregor2725ca82010-04-21 19:57:20 +00004270 return CodeCompleteObjCClassMessage(S, Receiver, SelIdents,
Douglas Gregor03d8aec2010-08-27 15:10:57 +00004271 NumSelIdents, /*IsSuper=*/true);
Douglas Gregor2725ca82010-04-21 19:57:20 +00004272}
4273
John McCallb3d87482010-08-24 05:47:05 +00004274void Sema::CodeCompleteObjCClassMessage(Scope *S, ParsedType Receiver,
Douglas Gregord3c68542009-11-19 01:08:35 +00004275 IdentifierInfo **SelIdents,
4276 unsigned NumSelIdents) {
Douglas Gregor03d8aec2010-08-27 15:10:57 +00004277 CodeCompleteObjCClassMessage(S, Receiver, SelIdents, NumSelIdents, false);
4278}
4279
4280void Sema::CodeCompleteObjCClassMessage(Scope *S, ParsedType Receiver,
4281 IdentifierInfo **SelIdents,
4282 unsigned NumSelIdents,
4283 bool IsSuper) {
John McCall0a2c5e22010-08-25 06:19:51 +00004284 typedef CodeCompletionResult Result;
Douglas Gregor24a069f2009-11-17 17:59:40 +00004285 ObjCInterfaceDecl *CDecl = 0;
4286
Douglas Gregor24a069f2009-11-17 17:59:40 +00004287 // If the given name refers to an interface type, retrieve the
4288 // corresponding declaration.
Douglas Gregor2725ca82010-04-21 19:57:20 +00004289 if (Receiver) {
4290 QualType T = GetTypeFromParser(Receiver, 0);
4291 if (!T.isNull())
John McCallc12c5bb2010-05-15 11:32:37 +00004292 if (const ObjCObjectType *Interface = T->getAs<ObjCObjectType>())
4293 CDecl = Interface->getInterface();
Douglas Gregor24a069f2009-11-17 17:59:40 +00004294 }
4295
Douglas Gregor36ecb042009-11-17 23:22:23 +00004296 // Add all of the factory methods in this Objective-C class, its protocols,
4297 // superclasses, categories, implementation, etc.
Steve Naroffc4df6d22009-11-07 02:08:14 +00004298 ResultBuilder Results(*this);
4299 Results.EnterNewScope();
Douglas Gregor13438f92010-04-06 16:40:00 +00004300
Douglas Gregor03d8aec2010-08-27 15:10:57 +00004301 // If this is a send-to-super, try to add the special "super" send
4302 // completion.
4303 if (IsSuper) {
4304 if (ObjCMethodDecl *SuperMethod
4305 = AddSuperSendCompletion(*this, false, SelIdents, NumSelIdents,
4306 Results))
4307 Results.Ignore(SuperMethod);
4308 }
4309
Douglas Gregor265f7492010-08-27 15:29:55 +00004310 // If we're inside an Objective-C method definition, prefer its selector to
4311 // others.
4312 if (ObjCMethodDecl *CurMethod = getCurMethodDecl())
4313 Results.setPreferredSelector(CurMethod->getSelector());
4314
Douglas Gregor13438f92010-04-06 16:40:00 +00004315 if (CDecl)
4316 AddObjCMethods(CDecl, false, MK_Any, SelIdents, NumSelIdents, CurContext,
4317 Results);
Douglas Gregor2725ca82010-04-21 19:57:20 +00004318 else {
Douglas Gregor13438f92010-04-06 16:40:00 +00004319 // We're messaging "id" as a type; provide all class/factory methods.
4320
Douglas Gregor719770d2010-04-06 17:30:22 +00004321 // If we have an external source, load the entire class method
Sebastian Redl3c7f4132010-08-18 23:57:06 +00004322 // pool from the AST file.
Douglas Gregor719770d2010-04-06 17:30:22 +00004323 if (ExternalSource) {
John McCall76bd1f32010-06-01 09:23:16 +00004324 for (uint32_t I = 0, N = ExternalSource->GetNumExternalSelectors();
4325 I != N; ++I) {
4326 Selector Sel = ExternalSource->GetExternalSelector(I);
Sebastian Redldb9d2142010-08-02 23:18:59 +00004327 if (Sel.isNull() || MethodPool.count(Sel))
Douglas Gregor719770d2010-04-06 17:30:22 +00004328 continue;
4329
Sebastian Redldb9d2142010-08-02 23:18:59 +00004330 ReadMethodPool(Sel);
Douglas Gregor719770d2010-04-06 17:30:22 +00004331 }
4332 }
4333
Sebastian Redldb9d2142010-08-02 23:18:59 +00004334 for (GlobalMethodPool::iterator M = MethodPool.begin(),
4335 MEnd = MethodPool.end();
4336 M != MEnd; ++M) {
4337 for (ObjCMethodList *MethList = &M->second.second;
4338 MethList && MethList->Method;
Douglas Gregor13438f92010-04-06 16:40:00 +00004339 MethList = MethList->Next) {
4340 if (!isAcceptableObjCMethod(MethList->Method, MK_Any, SelIdents,
4341 NumSelIdents))
4342 continue;
4343
4344 Result R(MethList->Method, 0);
4345 R.StartParameter = NumSelIdents;
4346 R.AllParametersAreInformative = false;
4347 Results.MaybeAddResult(R, CurContext);
4348 }
4349 }
4350 }
4351
Steve Naroffc4df6d22009-11-07 02:08:14 +00004352 Results.ExitScope();
Douglas Gregore6b1bb62010-08-11 21:23:17 +00004353 HandleCodeCompleteResults(this, CodeCompleter,
4354 CodeCompletionContext::CCC_Other,
Douglas Gregor03d8aec2010-08-27 15:10:57 +00004355 Results.data(), Results.size());
Steve Naroffc4df6d22009-11-07 02:08:14 +00004356}
4357
Douglas Gregord3c68542009-11-19 01:08:35 +00004358void Sema::CodeCompleteObjCInstanceMessage(Scope *S, ExprTy *Receiver,
4359 IdentifierInfo **SelIdents,
4360 unsigned NumSelIdents) {
Douglas Gregor03d8aec2010-08-27 15:10:57 +00004361 CodeCompleteObjCInstanceMessage(S, Receiver, SelIdents, NumSelIdents, false);
4362}
4363
4364void Sema::CodeCompleteObjCInstanceMessage(Scope *S, ExprTy *Receiver,
4365 IdentifierInfo **SelIdents,
4366 unsigned NumSelIdents,
4367 bool IsSuper) {
John McCall0a2c5e22010-08-25 06:19:51 +00004368 typedef CodeCompletionResult Result;
Steve Naroffc4df6d22009-11-07 02:08:14 +00004369
4370 Expr *RecExpr = static_cast<Expr *>(Receiver);
Steve Naroffc4df6d22009-11-07 02:08:14 +00004371
Douglas Gregor36ecb042009-11-17 23:22:23 +00004372 // If necessary, apply function/array conversion to the receiver.
4373 // C99 6.7.5.3p[7,8].
Douglas Gregora873dfc2010-02-03 00:27:59 +00004374 DefaultFunctionArrayLvalueConversion(RecExpr);
Douglas Gregor36ecb042009-11-17 23:22:23 +00004375 QualType ReceiverType = RecExpr->getType();
Steve Naroffc4df6d22009-11-07 02:08:14 +00004376
Douglas Gregor36ecb042009-11-17 23:22:23 +00004377 // Build the set of methods we can see.
4378 ResultBuilder Results(*this);
4379 Results.EnterNewScope();
Douglas Gregor22f56992010-04-06 19:22:33 +00004380
Douglas Gregor03d8aec2010-08-27 15:10:57 +00004381 // If this is a send-to-super, try to add the special "super" send
4382 // completion.
4383 if (IsSuper) {
4384 if (ObjCMethodDecl *SuperMethod
4385 = AddSuperSendCompletion(*this, false, SelIdents, NumSelIdents,
4386 Results))
4387 Results.Ignore(SuperMethod);
4388 }
4389
Douglas Gregor265f7492010-08-27 15:29:55 +00004390 // If we're inside an Objective-C method definition, prefer its selector to
4391 // others.
4392 if (ObjCMethodDecl *CurMethod = getCurMethodDecl())
4393 Results.setPreferredSelector(CurMethod->getSelector());
4394
Douglas Gregor22f56992010-04-06 19:22:33 +00004395 // If we're messaging an expression with type "id" or "Class", check
4396 // whether we know something special about the receiver that allows
4397 // us to assume a more-specific receiver type.
4398 if (ReceiverType->isObjCIdType() || ReceiverType->isObjCClassType())
4399 if (ObjCInterfaceDecl *IFace = GetAssumedMessageSendExprType(RecExpr))
4400 ReceiverType = Context.getObjCObjectPointerType(
4401 Context.getObjCInterfaceType(IFace));
Douglas Gregor36ecb042009-11-17 23:22:23 +00004402
Douglas Gregorf74a4192009-11-18 00:06:18 +00004403 // Handle messages to Class. This really isn't a message to an instance
4404 // method, so we treat it the same way we would treat a message send to a
4405 // class method.
4406 if (ReceiverType->isObjCClassType() ||
4407 ReceiverType->isObjCQualifiedClassType()) {
4408 if (ObjCMethodDecl *CurMethod = getCurMethodDecl()) {
4409 if (ObjCInterfaceDecl *ClassDecl = CurMethod->getClassInterface())
Douglas Gregor4ad96852009-11-19 07:41:15 +00004410 AddObjCMethods(ClassDecl, false, MK_Any, SelIdents, NumSelIdents,
4411 CurContext, Results);
Douglas Gregorf74a4192009-11-18 00:06:18 +00004412 }
4413 }
4414 // Handle messages to a qualified ID ("id<foo>").
4415 else if (const ObjCObjectPointerType *QualID
4416 = ReceiverType->getAsObjCQualifiedIdType()) {
4417 // Search protocols for instance methods.
4418 for (ObjCObjectPointerType::qual_iterator I = QualID->qual_begin(),
4419 E = QualID->qual_end();
4420 I != E; ++I)
Douglas Gregor4ad96852009-11-19 07:41:15 +00004421 AddObjCMethods(*I, true, MK_Any, SelIdents, NumSelIdents, CurContext,
4422 Results);
Douglas Gregorf74a4192009-11-18 00:06:18 +00004423 }
4424 // Handle messages to a pointer to interface type.
4425 else if (const ObjCObjectPointerType *IFacePtr
4426 = ReceiverType->getAsObjCInterfacePointerType()) {
4427 // Search the class, its superclasses, etc., for instance methods.
Douglas Gregor4ad96852009-11-19 07:41:15 +00004428 AddObjCMethods(IFacePtr->getInterfaceDecl(), true, MK_Any, SelIdents,
4429 NumSelIdents, CurContext, Results);
Douglas Gregorf74a4192009-11-18 00:06:18 +00004430
4431 // Search protocols for instance methods.
4432 for (ObjCObjectPointerType::qual_iterator I = IFacePtr->qual_begin(),
4433 E = IFacePtr->qual_end();
4434 I != E; ++I)
Douglas Gregor4ad96852009-11-19 07:41:15 +00004435 AddObjCMethods(*I, true, MK_Any, SelIdents, NumSelIdents, CurContext,
4436 Results);
Douglas Gregorf74a4192009-11-18 00:06:18 +00004437 }
Douglas Gregor13438f92010-04-06 16:40:00 +00004438 // Handle messages to "id".
4439 else if (ReceiverType->isObjCIdType()) {
Douglas Gregor719770d2010-04-06 17:30:22 +00004440 // We're messaging "id", so provide all instance methods we know
4441 // about as code-completion results.
4442
4443 // If we have an external source, load the entire class method
Sebastian Redl3c7f4132010-08-18 23:57:06 +00004444 // pool from the AST file.
Douglas Gregor719770d2010-04-06 17:30:22 +00004445 if (ExternalSource) {
John McCall76bd1f32010-06-01 09:23:16 +00004446 for (uint32_t I = 0, N = ExternalSource->GetNumExternalSelectors();
4447 I != N; ++I) {
4448 Selector Sel = ExternalSource->GetExternalSelector(I);
Sebastian Redldb9d2142010-08-02 23:18:59 +00004449 if (Sel.isNull() || MethodPool.count(Sel))
Douglas Gregor719770d2010-04-06 17:30:22 +00004450 continue;
4451
Sebastian Redldb9d2142010-08-02 23:18:59 +00004452 ReadMethodPool(Sel);
Douglas Gregor719770d2010-04-06 17:30:22 +00004453 }
4454 }
4455
Sebastian Redldb9d2142010-08-02 23:18:59 +00004456 for (GlobalMethodPool::iterator M = MethodPool.begin(),
4457 MEnd = MethodPool.end();
4458 M != MEnd; ++M) {
4459 for (ObjCMethodList *MethList = &M->second.first;
4460 MethList && MethList->Method;
Douglas Gregor13438f92010-04-06 16:40:00 +00004461 MethList = MethList->Next) {
4462 if (!isAcceptableObjCMethod(MethList->Method, MK_Any, SelIdents,
4463 NumSelIdents))
4464 continue;
4465
4466 Result R(MethList->Method, 0);
4467 R.StartParameter = NumSelIdents;
4468 R.AllParametersAreInformative = false;
4469 Results.MaybeAddResult(R, CurContext);
4470 }
4471 }
4472 }
4473
Steve Naroffc4df6d22009-11-07 02:08:14 +00004474 Results.ExitScope();
Douglas Gregore6b1bb62010-08-11 21:23:17 +00004475 HandleCodeCompleteResults(this, CodeCompleter,
4476 CodeCompletionContext::CCC_Other,
4477 Results.data(),Results.size());
Steve Naroffc4df6d22009-11-07 02:08:14 +00004478}
Douglas Gregor55385fe2009-11-18 04:19:12 +00004479
Douglas Gregorfb629412010-08-23 21:17:50 +00004480void Sema::CodeCompleteObjCForCollection(Scope *S,
4481 DeclGroupPtrTy IterationVar) {
4482 CodeCompleteExpressionData Data;
4483 Data.ObjCCollection = true;
4484
4485 if (IterationVar.getAsOpaquePtr()) {
4486 DeclGroupRef DG = IterationVar.getAsVal<DeclGroupRef>();
4487 for (DeclGroupRef::iterator I = DG.begin(), End = DG.end(); I != End; ++I) {
4488 if (*I)
4489 Data.IgnoreDecls.push_back(*I);
4490 }
4491 }
4492
4493 CodeCompleteExpression(S, Data);
4494}
4495
Douglas Gregor458433d2010-08-26 15:07:07 +00004496void Sema::CodeCompleteObjCSelector(Scope *S, IdentifierInfo **SelIdents,
4497 unsigned NumSelIdents) {
4498 // If we have an external source, load the entire class method
4499 // pool from the AST file.
4500 if (ExternalSource) {
4501 for (uint32_t I = 0, N = ExternalSource->GetNumExternalSelectors();
4502 I != N; ++I) {
4503 Selector Sel = ExternalSource->GetExternalSelector(I);
4504 if (Sel.isNull() || MethodPool.count(Sel))
4505 continue;
4506
4507 ReadMethodPool(Sel);
4508 }
4509 }
4510
4511 ResultBuilder Results(*this);
4512 Results.EnterNewScope();
4513 for (GlobalMethodPool::iterator M = MethodPool.begin(),
4514 MEnd = MethodPool.end();
4515 M != MEnd; ++M) {
4516
4517 Selector Sel = M->first;
4518 if (!isAcceptableObjCSelector(Sel, MK_Any, SelIdents, NumSelIdents))
4519 continue;
4520
4521 CodeCompletionString *Pattern = new CodeCompletionString;
4522 if (Sel.isUnarySelector()) {
4523 Pattern->AddTypedTextChunk(Sel.getIdentifierInfoForSlot(0)->getName());
4524 Results.AddResult(Pattern);
4525 continue;
4526 }
4527
Douglas Gregor2d9e21f2010-08-26 16:46:39 +00004528 std::string Accumulator;
Douglas Gregor458433d2010-08-26 15:07:07 +00004529 for (unsigned I = 0, N = Sel.getNumArgs(); I != N; ++I) {
Douglas Gregor2d9e21f2010-08-26 16:46:39 +00004530 if (I == NumSelIdents) {
4531 if (!Accumulator.empty()) {
4532 Pattern->AddInformativeChunk(Accumulator);
4533 Accumulator.clear();
4534 }
4535 }
4536
4537 Accumulator += Sel.getIdentifierInfoForSlot(I)->getName().str();
4538 Accumulator += ':';
Douglas Gregor458433d2010-08-26 15:07:07 +00004539 }
Douglas Gregor2d9e21f2010-08-26 16:46:39 +00004540 Pattern->AddTypedTextChunk(Accumulator);
Douglas Gregor458433d2010-08-26 15:07:07 +00004541 Results.AddResult(Pattern);
4542 }
4543 Results.ExitScope();
4544
4545 HandleCodeCompleteResults(this, CodeCompleter,
4546 CodeCompletionContext::CCC_SelectorName,
4547 Results.data(), Results.size());
4548}
4549
Douglas Gregor55385fe2009-11-18 04:19:12 +00004550/// \brief Add all of the protocol declarations that we find in the given
4551/// (translation unit) context.
4552static void AddProtocolResults(DeclContext *Ctx, DeclContext *CurContext,
Douglas Gregor083128f2009-11-18 04:49:41 +00004553 bool OnlyForwardDeclarations,
Douglas Gregor55385fe2009-11-18 04:19:12 +00004554 ResultBuilder &Results) {
John McCall0a2c5e22010-08-25 06:19:51 +00004555 typedef CodeCompletionResult Result;
Douglas Gregor55385fe2009-11-18 04:19:12 +00004556
4557 for (DeclContext::decl_iterator D = Ctx->decls_begin(),
4558 DEnd = Ctx->decls_end();
4559 D != DEnd; ++D) {
4560 // Record any protocols we find.
4561 if (ObjCProtocolDecl *Proto = dyn_cast<ObjCProtocolDecl>(*D))
Douglas Gregor083128f2009-11-18 04:49:41 +00004562 if (!OnlyForwardDeclarations || Proto->isForwardDecl())
Douglas Gregor608300b2010-01-14 16:14:35 +00004563 Results.AddResult(Result(Proto, 0), CurContext, 0, false);
Douglas Gregor55385fe2009-11-18 04:19:12 +00004564
4565 // Record any forward-declared protocols we find.
4566 if (ObjCForwardProtocolDecl *Forward
4567 = dyn_cast<ObjCForwardProtocolDecl>(*D)) {
4568 for (ObjCForwardProtocolDecl::protocol_iterator
4569 P = Forward->protocol_begin(),
4570 PEnd = Forward->protocol_end();
4571 P != PEnd; ++P)
Douglas Gregor083128f2009-11-18 04:49:41 +00004572 if (!OnlyForwardDeclarations || (*P)->isForwardDecl())
Douglas Gregor608300b2010-01-14 16:14:35 +00004573 Results.AddResult(Result(*P, 0), CurContext, 0, false);
Douglas Gregor55385fe2009-11-18 04:19:12 +00004574 }
4575 }
4576}
4577
4578void Sema::CodeCompleteObjCProtocolReferences(IdentifierLocPair *Protocols,
4579 unsigned NumProtocols) {
4580 ResultBuilder Results(*this);
4581 Results.EnterNewScope();
4582
4583 // Tell the result set to ignore all of the protocols we have
4584 // already seen.
4585 for (unsigned I = 0; I != NumProtocols; ++I)
Douglas Gregorc83c6872010-04-15 22:33:43 +00004586 if (ObjCProtocolDecl *Protocol = LookupProtocol(Protocols[I].first,
4587 Protocols[I].second))
Douglas Gregor55385fe2009-11-18 04:19:12 +00004588 Results.Ignore(Protocol);
4589
4590 // Add all protocols.
Douglas Gregor083128f2009-11-18 04:49:41 +00004591 AddProtocolResults(Context.getTranslationUnitDecl(), CurContext, false,
4592 Results);
4593
4594 Results.ExitScope();
Douglas Gregore6b1bb62010-08-11 21:23:17 +00004595 HandleCodeCompleteResults(this, CodeCompleter,
4596 CodeCompletionContext::CCC_ObjCProtocolName,
4597 Results.data(),Results.size());
Douglas Gregor083128f2009-11-18 04:49:41 +00004598}
4599
4600void Sema::CodeCompleteObjCProtocolDecl(Scope *) {
4601 ResultBuilder Results(*this);
4602 Results.EnterNewScope();
4603
4604 // Add all protocols.
4605 AddProtocolResults(Context.getTranslationUnitDecl(), CurContext, true,
4606 Results);
Douglas Gregor55385fe2009-11-18 04:19:12 +00004607
4608 Results.ExitScope();
Douglas Gregore6b1bb62010-08-11 21:23:17 +00004609 HandleCodeCompleteResults(this, CodeCompleter,
4610 CodeCompletionContext::CCC_ObjCProtocolName,
4611 Results.data(),Results.size());
Douglas Gregor55385fe2009-11-18 04:19:12 +00004612}
Douglas Gregor3b49aca2009-11-18 16:26:39 +00004613
4614/// \brief Add all of the Objective-C interface declarations that we find in
4615/// the given (translation unit) context.
4616static void AddInterfaceResults(DeclContext *Ctx, DeclContext *CurContext,
4617 bool OnlyForwardDeclarations,
4618 bool OnlyUnimplemented,
4619 ResultBuilder &Results) {
John McCall0a2c5e22010-08-25 06:19:51 +00004620 typedef CodeCompletionResult Result;
Douglas Gregor3b49aca2009-11-18 16:26:39 +00004621
4622 for (DeclContext::decl_iterator D = Ctx->decls_begin(),
4623 DEnd = Ctx->decls_end();
4624 D != DEnd; ++D) {
Douglas Gregordeacbdc2010-08-11 12:19:30 +00004625 // Record any interfaces we find.
4626 if (ObjCInterfaceDecl *Class = dyn_cast<ObjCInterfaceDecl>(*D))
4627 if ((!OnlyForwardDeclarations || Class->isForwardDecl()) &&
4628 (!OnlyUnimplemented || !Class->getImplementation()))
4629 Results.AddResult(Result(Class, 0), CurContext, 0, false);
Douglas Gregor3b49aca2009-11-18 16:26:39 +00004630
4631 // Record any forward-declared interfaces we find.
4632 if (ObjCClassDecl *Forward = dyn_cast<ObjCClassDecl>(*D)) {
4633 for (ObjCClassDecl::iterator C = Forward->begin(), CEnd = Forward->end();
Douglas Gregordeacbdc2010-08-11 12:19:30 +00004634 C != CEnd; ++C)
4635 if ((!OnlyForwardDeclarations || C->getInterface()->isForwardDecl()) &&
4636 (!OnlyUnimplemented || !C->getInterface()->getImplementation()))
4637 Results.AddResult(Result(C->getInterface(), 0), CurContext,
Douglas Gregor608300b2010-01-14 16:14:35 +00004638 0, false);
Douglas Gregor3b49aca2009-11-18 16:26:39 +00004639 }
4640 }
4641}
4642
4643void Sema::CodeCompleteObjCInterfaceDecl(Scope *S) {
4644 ResultBuilder Results(*this);
4645 Results.EnterNewScope();
4646
4647 // Add all classes.
4648 AddInterfaceResults(Context.getTranslationUnitDecl(), CurContext, true,
4649 false, Results);
4650
4651 Results.ExitScope();
Douglas Gregore6b1bb62010-08-11 21:23:17 +00004652 HandleCodeCompleteResults(this, CodeCompleter,
4653 CodeCompletionContext::CCC_Other,
4654 Results.data(),Results.size());
Douglas Gregor3b49aca2009-11-18 16:26:39 +00004655}
4656
Douglas Gregorc83c6872010-04-15 22:33:43 +00004657void Sema::CodeCompleteObjCSuperclass(Scope *S, IdentifierInfo *ClassName,
4658 SourceLocation ClassNameLoc) {
Douglas Gregor3b49aca2009-11-18 16:26:39 +00004659 ResultBuilder Results(*this);
4660 Results.EnterNewScope();
4661
4662 // Make sure that we ignore the class we're currently defining.
4663 NamedDecl *CurClass
Douglas Gregorc83c6872010-04-15 22:33:43 +00004664 = LookupSingleName(TUScope, ClassName, ClassNameLoc, LookupOrdinaryName);
Douglas Gregor33ced0b2009-11-18 19:08:43 +00004665 if (CurClass && isa<ObjCInterfaceDecl>(CurClass))
Douglas Gregor3b49aca2009-11-18 16:26:39 +00004666 Results.Ignore(CurClass);
4667
4668 // Add all classes.
4669 AddInterfaceResults(Context.getTranslationUnitDecl(), CurContext, false,
4670 false, Results);
4671
4672 Results.ExitScope();
Douglas Gregore6b1bb62010-08-11 21:23:17 +00004673 HandleCodeCompleteResults(this, CodeCompleter,
4674 CodeCompletionContext::CCC_Other,
4675 Results.data(),Results.size());
Douglas Gregor3b49aca2009-11-18 16:26:39 +00004676}
4677
4678void Sema::CodeCompleteObjCImplementationDecl(Scope *S) {
4679 ResultBuilder Results(*this);
4680 Results.EnterNewScope();
4681
4682 // Add all unimplemented classes.
4683 AddInterfaceResults(Context.getTranslationUnitDecl(), CurContext, false,
4684 true, Results);
4685
4686 Results.ExitScope();
Douglas Gregore6b1bb62010-08-11 21:23:17 +00004687 HandleCodeCompleteResults(this, CodeCompleter,
4688 CodeCompletionContext::CCC_Other,
4689 Results.data(),Results.size());
Douglas Gregor3b49aca2009-11-18 16:26:39 +00004690}
Douglas Gregor33ced0b2009-11-18 19:08:43 +00004691
4692void Sema::CodeCompleteObjCInterfaceCategory(Scope *S,
Douglas Gregorc83c6872010-04-15 22:33:43 +00004693 IdentifierInfo *ClassName,
4694 SourceLocation ClassNameLoc) {
John McCall0a2c5e22010-08-25 06:19:51 +00004695 typedef CodeCompletionResult Result;
Douglas Gregor33ced0b2009-11-18 19:08:43 +00004696
4697 ResultBuilder Results(*this);
4698
4699 // Ignore any categories we find that have already been implemented by this
4700 // interface.
4701 llvm::SmallPtrSet<IdentifierInfo *, 16> CategoryNames;
4702 NamedDecl *CurClass
Douglas Gregorc83c6872010-04-15 22:33:43 +00004703 = LookupSingleName(TUScope, ClassName, ClassNameLoc, LookupOrdinaryName);
Douglas Gregor33ced0b2009-11-18 19:08:43 +00004704 if (ObjCInterfaceDecl *Class = dyn_cast_or_null<ObjCInterfaceDecl>(CurClass))
4705 for (ObjCCategoryDecl *Category = Class->getCategoryList(); Category;
4706 Category = Category->getNextClassCategory())
4707 CategoryNames.insert(Category->getIdentifier());
4708
4709 // Add all of the categories we know about.
4710 Results.EnterNewScope();
4711 TranslationUnitDecl *TU = Context.getTranslationUnitDecl();
4712 for (DeclContext::decl_iterator D = TU->decls_begin(),
4713 DEnd = TU->decls_end();
4714 D != DEnd; ++D)
4715 if (ObjCCategoryDecl *Category = dyn_cast<ObjCCategoryDecl>(*D))
4716 if (CategoryNames.insert(Category->getIdentifier()))
Douglas Gregor608300b2010-01-14 16:14:35 +00004717 Results.AddResult(Result(Category, 0), CurContext, 0, false);
Douglas Gregor33ced0b2009-11-18 19:08:43 +00004718 Results.ExitScope();
4719
Douglas Gregore6b1bb62010-08-11 21:23:17 +00004720 HandleCodeCompleteResults(this, CodeCompleter,
4721 CodeCompletionContext::CCC_Other,
4722 Results.data(),Results.size());
Douglas Gregor33ced0b2009-11-18 19:08:43 +00004723}
4724
4725void Sema::CodeCompleteObjCImplementationCategory(Scope *S,
Douglas Gregorc83c6872010-04-15 22:33:43 +00004726 IdentifierInfo *ClassName,
4727 SourceLocation ClassNameLoc) {
John McCall0a2c5e22010-08-25 06:19:51 +00004728 typedef CodeCompletionResult Result;
Douglas Gregor33ced0b2009-11-18 19:08:43 +00004729
4730 // Find the corresponding interface. If we couldn't find the interface, the
4731 // program itself is ill-formed. However, we'll try to be helpful still by
4732 // providing the list of all of the categories we know about.
4733 NamedDecl *CurClass
Douglas Gregorc83c6872010-04-15 22:33:43 +00004734 = LookupSingleName(TUScope, ClassName, ClassNameLoc, LookupOrdinaryName);
Douglas Gregor33ced0b2009-11-18 19:08:43 +00004735 ObjCInterfaceDecl *Class = dyn_cast_or_null<ObjCInterfaceDecl>(CurClass);
4736 if (!Class)
Douglas Gregorc83c6872010-04-15 22:33:43 +00004737 return CodeCompleteObjCInterfaceCategory(S, ClassName, ClassNameLoc);
Douglas Gregor33ced0b2009-11-18 19:08:43 +00004738
4739 ResultBuilder Results(*this);
4740
4741 // Add all of the categories that have have corresponding interface
4742 // declarations in this class and any of its superclasses, except for
4743 // already-implemented categories in the class itself.
4744 llvm::SmallPtrSet<IdentifierInfo *, 16> CategoryNames;
4745 Results.EnterNewScope();
4746 bool IgnoreImplemented = true;
4747 while (Class) {
4748 for (ObjCCategoryDecl *Category = Class->getCategoryList(); Category;
4749 Category = Category->getNextClassCategory())
4750 if ((!IgnoreImplemented || !Category->getImplementation()) &&
4751 CategoryNames.insert(Category->getIdentifier()))
Douglas Gregor608300b2010-01-14 16:14:35 +00004752 Results.AddResult(Result(Category, 0), CurContext, 0, false);
Douglas Gregor33ced0b2009-11-18 19:08:43 +00004753
4754 Class = Class->getSuperClass();
4755 IgnoreImplemented = false;
4756 }
4757 Results.ExitScope();
4758
Douglas Gregore6b1bb62010-08-11 21:23:17 +00004759 HandleCodeCompleteResults(this, CodeCompleter,
4760 CodeCompletionContext::CCC_Other,
4761 Results.data(),Results.size());
Douglas Gregor33ced0b2009-11-18 19:08:43 +00004762}
Douglas Gregor322328b2009-11-18 22:32:06 +00004763
John McCalld226f652010-08-21 09:40:31 +00004764void Sema::CodeCompleteObjCPropertyDefinition(Scope *S, Decl *ObjCImpDecl) {
John McCall0a2c5e22010-08-25 06:19:51 +00004765 typedef CodeCompletionResult Result;
Douglas Gregor322328b2009-11-18 22:32:06 +00004766 ResultBuilder Results(*this);
4767
4768 // Figure out where this @synthesize lives.
4769 ObjCContainerDecl *Container
John McCalld226f652010-08-21 09:40:31 +00004770 = dyn_cast_or_null<ObjCContainerDecl>(ObjCImpDecl);
Douglas Gregor322328b2009-11-18 22:32:06 +00004771 if (!Container ||
4772 (!isa<ObjCImplementationDecl>(Container) &&
4773 !isa<ObjCCategoryImplDecl>(Container)))
4774 return;
4775
4776 // Ignore any properties that have already been implemented.
4777 for (DeclContext::decl_iterator D = Container->decls_begin(),
4778 DEnd = Container->decls_end();
4779 D != DEnd; ++D)
4780 if (ObjCPropertyImplDecl *PropertyImpl = dyn_cast<ObjCPropertyImplDecl>(*D))
4781 Results.Ignore(PropertyImpl->getPropertyDecl());
4782
4783 // Add any properties that we find.
4784 Results.EnterNewScope();
4785 if (ObjCImplementationDecl *ClassImpl
4786 = dyn_cast<ObjCImplementationDecl>(Container))
4787 AddObjCProperties(ClassImpl->getClassInterface(), false, CurContext,
4788 Results);
4789 else
4790 AddObjCProperties(cast<ObjCCategoryImplDecl>(Container)->getCategoryDecl(),
4791 false, CurContext, Results);
4792 Results.ExitScope();
4793
Douglas Gregore6b1bb62010-08-11 21:23:17 +00004794 HandleCodeCompleteResults(this, CodeCompleter,
4795 CodeCompletionContext::CCC_Other,
4796 Results.data(),Results.size());
Douglas Gregor322328b2009-11-18 22:32:06 +00004797}
4798
4799void Sema::CodeCompleteObjCPropertySynthesizeIvar(Scope *S,
4800 IdentifierInfo *PropertyName,
John McCalld226f652010-08-21 09:40:31 +00004801 Decl *ObjCImpDecl) {
John McCall0a2c5e22010-08-25 06:19:51 +00004802 typedef CodeCompletionResult Result;
Douglas Gregor322328b2009-11-18 22:32:06 +00004803 ResultBuilder Results(*this);
4804
4805 // Figure out where this @synthesize lives.
4806 ObjCContainerDecl *Container
John McCalld226f652010-08-21 09:40:31 +00004807 = dyn_cast_or_null<ObjCContainerDecl>(ObjCImpDecl);
Douglas Gregor322328b2009-11-18 22:32:06 +00004808 if (!Container ||
4809 (!isa<ObjCImplementationDecl>(Container) &&
4810 !isa<ObjCCategoryImplDecl>(Container)))
4811 return;
4812
4813 // Figure out which interface we're looking into.
4814 ObjCInterfaceDecl *Class = 0;
4815 if (ObjCImplementationDecl *ClassImpl
4816 = dyn_cast<ObjCImplementationDecl>(Container))
4817 Class = ClassImpl->getClassInterface();
4818 else
4819 Class = cast<ObjCCategoryImplDecl>(Container)->getCategoryDecl()
4820 ->getClassInterface();
4821
4822 // Add all of the instance variables in this class and its superclasses.
4823 Results.EnterNewScope();
4824 for(; Class; Class = Class->getSuperClass()) {
4825 // FIXME: We could screen the type of each ivar for compatibility with
4826 // the property, but is that being too paternal?
4827 for (ObjCInterfaceDecl::ivar_iterator IVar = Class->ivar_begin(),
4828 IVarEnd = Class->ivar_end();
4829 IVar != IVarEnd; ++IVar)
Douglas Gregor608300b2010-01-14 16:14:35 +00004830 Results.AddResult(Result(*IVar, 0), CurContext, 0, false);
Douglas Gregor322328b2009-11-18 22:32:06 +00004831 }
4832 Results.ExitScope();
4833
Douglas Gregore6b1bb62010-08-11 21:23:17 +00004834 HandleCodeCompleteResults(this, CodeCompleter,
4835 CodeCompletionContext::CCC_Other,
4836 Results.data(),Results.size());
Douglas Gregor322328b2009-11-18 22:32:06 +00004837}
Douglas Gregore8f5a172010-04-07 00:21:17 +00004838
Douglas Gregor408be5a2010-08-25 01:08:01 +00004839// Mapping from selectors to the methods that implement that selector, along
4840// with the "in original class" flag.
4841typedef llvm::DenseMap<Selector, std::pair<ObjCMethodDecl *, bool> >
4842 KnownMethodsMap;
Douglas Gregore8f5a172010-04-07 00:21:17 +00004843
4844/// \brief Find all of the methods that reside in the given container
4845/// (and its superclasses, protocols, etc.) that meet the given
4846/// criteria. Insert those methods into the map of known methods,
4847/// indexed by selector so they can be easily found.
4848static void FindImplementableMethods(ASTContext &Context,
4849 ObjCContainerDecl *Container,
4850 bool WantInstanceMethods,
4851 QualType ReturnType,
4852 bool IsInImplementation,
Douglas Gregor408be5a2010-08-25 01:08:01 +00004853 KnownMethodsMap &KnownMethods,
4854 bool InOriginalClass = true) {
Douglas Gregore8f5a172010-04-07 00:21:17 +00004855 if (ObjCInterfaceDecl *IFace = dyn_cast<ObjCInterfaceDecl>(Container)) {
4856 // Recurse into protocols.
4857 const ObjCList<ObjCProtocolDecl> &Protocols
4858 = IFace->getReferencedProtocols();
4859 for (ObjCList<ObjCProtocolDecl>::iterator I = Protocols.begin(),
4860 E = Protocols.end();
4861 I != E; ++I)
4862 FindImplementableMethods(Context, *I, WantInstanceMethods, ReturnType,
Douglas Gregor408be5a2010-08-25 01:08:01 +00004863 IsInImplementation, KnownMethods,
4864 InOriginalClass);
Douglas Gregore8f5a172010-04-07 00:21:17 +00004865
4866 // If we're not in the implementation of a class, also visit the
4867 // superclass.
4868 if (!IsInImplementation && IFace->getSuperClass())
4869 FindImplementableMethods(Context, IFace->getSuperClass(),
4870 WantInstanceMethods, ReturnType,
Douglas Gregor408be5a2010-08-25 01:08:01 +00004871 IsInImplementation, KnownMethods,
4872 false);
Douglas Gregore8f5a172010-04-07 00:21:17 +00004873
4874 // Add methods from any class extensions (but not from categories;
4875 // those should go into category implementations).
Fariborz Jahanian80aa1cd2010-06-22 23:20:40 +00004876 for (const ObjCCategoryDecl *Cat = IFace->getFirstClassExtension(); Cat;
4877 Cat = Cat->getNextClassExtension())
4878 FindImplementableMethods(Context, const_cast<ObjCCategoryDecl*>(Cat),
4879 WantInstanceMethods, ReturnType,
Douglas Gregor408be5a2010-08-25 01:08:01 +00004880 IsInImplementation, KnownMethods,
4881 InOriginalClass);
Douglas Gregore8f5a172010-04-07 00:21:17 +00004882 }
4883
4884 if (ObjCCategoryDecl *Category = dyn_cast<ObjCCategoryDecl>(Container)) {
4885 // Recurse into protocols.
4886 const ObjCList<ObjCProtocolDecl> &Protocols
4887 = Category->getReferencedProtocols();
4888 for (ObjCList<ObjCProtocolDecl>::iterator I = Protocols.begin(),
4889 E = Protocols.end();
4890 I != E; ++I)
4891 FindImplementableMethods(Context, *I, WantInstanceMethods, ReturnType,
Douglas Gregor408be5a2010-08-25 01:08:01 +00004892 IsInImplementation, KnownMethods,
4893 InOriginalClass);
Douglas Gregore8f5a172010-04-07 00:21:17 +00004894 }
4895
4896 if (ObjCProtocolDecl *Protocol = dyn_cast<ObjCProtocolDecl>(Container)) {
4897 // Recurse into protocols.
4898 const ObjCList<ObjCProtocolDecl> &Protocols
4899 = Protocol->getReferencedProtocols();
4900 for (ObjCList<ObjCProtocolDecl>::iterator I = Protocols.begin(),
4901 E = Protocols.end();
4902 I != E; ++I)
4903 FindImplementableMethods(Context, *I, WantInstanceMethods, ReturnType,
Douglas Gregor408be5a2010-08-25 01:08:01 +00004904 IsInImplementation, KnownMethods, false);
Douglas Gregore8f5a172010-04-07 00:21:17 +00004905 }
4906
4907 // Add methods in this container. This operation occurs last because
4908 // we want the methods from this container to override any methods
4909 // we've previously seen with the same selector.
4910 for (ObjCContainerDecl::method_iterator M = Container->meth_begin(),
4911 MEnd = Container->meth_end();
4912 M != MEnd; ++M) {
4913 if ((*M)->isInstanceMethod() == WantInstanceMethods) {
4914 if (!ReturnType.isNull() &&
4915 !Context.hasSameUnqualifiedType(ReturnType, (*M)->getResultType()))
4916 continue;
4917
Douglas Gregor408be5a2010-08-25 01:08:01 +00004918 KnownMethods[(*M)->getSelector()] = std::make_pair(*M, InOriginalClass);
Douglas Gregore8f5a172010-04-07 00:21:17 +00004919 }
4920 }
4921}
4922
4923void Sema::CodeCompleteObjCMethodDecl(Scope *S,
4924 bool IsInstanceMethod,
John McCallb3d87482010-08-24 05:47:05 +00004925 ParsedType ReturnTy,
John McCalld226f652010-08-21 09:40:31 +00004926 Decl *IDecl) {
Douglas Gregore8f5a172010-04-07 00:21:17 +00004927 // Determine the return type of the method we're declaring, if
4928 // provided.
4929 QualType ReturnType = GetTypeFromParser(ReturnTy);
4930
4931 // Determine where we should start searching for methods, and where we
4932 ObjCContainerDecl *SearchDecl = 0, *CurrentDecl = 0;
4933 bool IsInImplementation = false;
John McCalld226f652010-08-21 09:40:31 +00004934 if (Decl *D = IDecl) {
Douglas Gregore8f5a172010-04-07 00:21:17 +00004935 if (ObjCImplementationDecl *Impl = dyn_cast<ObjCImplementationDecl>(D)) {
4936 SearchDecl = Impl->getClassInterface();
4937 CurrentDecl = Impl;
4938 IsInImplementation = true;
4939 } else if (ObjCCategoryImplDecl *CatImpl
4940 = dyn_cast<ObjCCategoryImplDecl>(D)) {
4941 SearchDecl = CatImpl->getCategoryDecl();
4942 CurrentDecl = CatImpl;
4943 IsInImplementation = true;
4944 } else {
4945 SearchDecl = dyn_cast<ObjCContainerDecl>(D);
4946 CurrentDecl = SearchDecl;
4947 }
4948 }
4949
4950 if (!SearchDecl && S) {
4951 if (DeclContext *DC = static_cast<DeclContext *>(S->getEntity())) {
4952 SearchDecl = dyn_cast<ObjCContainerDecl>(DC);
4953 CurrentDecl = SearchDecl;
4954 }
4955 }
4956
4957 if (!SearchDecl || !CurrentDecl) {
Douglas Gregore6b1bb62010-08-11 21:23:17 +00004958 HandleCodeCompleteResults(this, CodeCompleter,
4959 CodeCompletionContext::CCC_Other,
4960 0, 0);
Douglas Gregore8f5a172010-04-07 00:21:17 +00004961 return;
4962 }
4963
4964 // Find all of the methods that we could declare/implement here.
4965 KnownMethodsMap KnownMethods;
4966 FindImplementableMethods(Context, SearchDecl, IsInstanceMethod,
4967 ReturnType, IsInImplementation, KnownMethods);
4968
4969 // Erase any methods that have already been declared or
4970 // implemented here.
4971 for (ObjCContainerDecl::method_iterator M = CurrentDecl->meth_begin(),
4972 MEnd = CurrentDecl->meth_end();
4973 M != MEnd; ++M) {
4974 if ((*M)->isInstanceMethod() != IsInstanceMethod)
4975 continue;
4976
4977 KnownMethodsMap::iterator Pos = KnownMethods.find((*M)->getSelector());
4978 if (Pos != KnownMethods.end())
4979 KnownMethods.erase(Pos);
4980 }
4981
4982 // Add declarations or definitions for each of the known methods.
John McCall0a2c5e22010-08-25 06:19:51 +00004983 typedef CodeCompletionResult Result;
Douglas Gregore8f5a172010-04-07 00:21:17 +00004984 ResultBuilder Results(*this);
4985 Results.EnterNewScope();
4986 PrintingPolicy Policy(Context.PrintingPolicy);
4987 Policy.AnonymousTagLocations = false;
4988 for (KnownMethodsMap::iterator M = KnownMethods.begin(),
4989 MEnd = KnownMethods.end();
4990 M != MEnd; ++M) {
Douglas Gregor408be5a2010-08-25 01:08:01 +00004991 ObjCMethodDecl *Method = M->second.first;
Douglas Gregore8f5a172010-04-07 00:21:17 +00004992 CodeCompletionString *Pattern = new CodeCompletionString;
4993
4994 // If the result type was not already provided, add it to the
4995 // pattern as (type).
4996 if (ReturnType.isNull()) {
4997 std::string TypeStr;
4998 Method->getResultType().getAsStringInternal(TypeStr, Policy);
4999 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
5000 Pattern->AddTextChunk(TypeStr);
5001 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
5002 }
5003
5004 Selector Sel = Method->getSelector();
5005
5006 // Add the first part of the selector to the pattern.
5007 Pattern->AddTypedTextChunk(Sel.getIdentifierInfoForSlot(0)->getName());
5008
5009 // Add parameters to the pattern.
5010 unsigned I = 0;
5011 for (ObjCMethodDecl::param_iterator P = Method->param_begin(),
5012 PEnd = Method->param_end();
5013 P != PEnd; (void)++P, ++I) {
5014 // Add the part of the selector name.
5015 if (I == 0)
5016 Pattern->AddChunk(CodeCompletionString::CK_Colon);
5017 else if (I < Sel.getNumArgs()) {
5018 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
Douglas Gregor47c03a72010-08-17 15:53:35 +00005019 Pattern->AddTextChunk(Sel.getIdentifierInfoForSlot(I)->getName());
Douglas Gregore8f5a172010-04-07 00:21:17 +00005020 Pattern->AddChunk(CodeCompletionString::CK_Colon);
5021 } else
5022 break;
5023
5024 // Add the parameter type.
5025 std::string TypeStr;
5026 (*P)->getOriginalType().getAsStringInternal(TypeStr, Policy);
5027 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
5028 Pattern->AddTextChunk(TypeStr);
5029 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
5030
5031 if (IdentifierInfo *Id = (*P)->getIdentifier())
Douglas Gregore17794f2010-08-31 05:13:43 +00005032 Pattern->AddTextChunk(Id->getName());
Douglas Gregore8f5a172010-04-07 00:21:17 +00005033 }
5034
5035 if (Method->isVariadic()) {
5036 if (Method->param_size() > 0)
5037 Pattern->AddChunk(CodeCompletionString::CK_Comma);
5038 Pattern->AddTextChunk("...");
Douglas Gregore17794f2010-08-31 05:13:43 +00005039 }
Douglas Gregore8f5a172010-04-07 00:21:17 +00005040
Douglas Gregor447107d2010-05-28 00:57:46 +00005041 if (IsInImplementation && Results.includeCodePatterns()) {
Douglas Gregore8f5a172010-04-07 00:21:17 +00005042 // We will be defining the method here, so add a compound statement.
5043 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
5044 Pattern->AddChunk(CodeCompletionString::CK_LeftBrace);
5045 Pattern->AddChunk(CodeCompletionString::CK_VerticalSpace);
5046 if (!Method->getResultType()->isVoidType()) {
5047 // If the result type is not void, add a return clause.
5048 Pattern->AddTextChunk("return");
5049 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
5050 Pattern->AddPlaceholderChunk("expression");
5051 Pattern->AddChunk(CodeCompletionString::CK_SemiColon);
5052 } else
5053 Pattern->AddPlaceholderChunk("statements");
5054
5055 Pattern->AddChunk(CodeCompletionString::CK_VerticalSpace);
5056 Pattern->AddChunk(CodeCompletionString::CK_RightBrace);
5057 }
5058
Douglas Gregor408be5a2010-08-25 01:08:01 +00005059 unsigned Priority = CCP_CodePattern;
5060 if (!M->second.second)
5061 Priority += CCD_InBaseClass;
5062
5063 Results.AddResult(Result(Pattern, Priority,
Douglas Gregor16ed9ad2010-08-17 16:06:07 +00005064 Method->isInstanceMethod()
5065 ? CXCursor_ObjCInstanceMethodDecl
5066 : CXCursor_ObjCClassMethodDecl));
Douglas Gregore8f5a172010-04-07 00:21:17 +00005067 }
5068
5069 Results.ExitScope();
5070
Douglas Gregore6b1bb62010-08-11 21:23:17 +00005071 HandleCodeCompleteResults(this, CodeCompleter,
5072 CodeCompletionContext::CCC_Other,
5073 Results.data(),Results.size());
Douglas Gregore8f5a172010-04-07 00:21:17 +00005074}
Douglas Gregor1f5537a2010-07-08 23:20:03 +00005075
5076void Sema::CodeCompleteObjCMethodDeclSelector(Scope *S,
5077 bool IsInstanceMethod,
Douglas Gregor40ed9a12010-07-08 23:37:41 +00005078 bool AtParameterName,
John McCallb3d87482010-08-24 05:47:05 +00005079 ParsedType ReturnTy,
Douglas Gregor1f5537a2010-07-08 23:20:03 +00005080 IdentifierInfo **SelIdents,
5081 unsigned NumSelIdents) {
Douglas Gregor1f5537a2010-07-08 23:20:03 +00005082 // If we have an external source, load the entire class method
Sebastian Redl3c7f4132010-08-18 23:57:06 +00005083 // pool from the AST file.
Douglas Gregor1f5537a2010-07-08 23:20:03 +00005084 if (ExternalSource) {
5085 for (uint32_t I = 0, N = ExternalSource->GetNumExternalSelectors();
5086 I != N; ++I) {
5087 Selector Sel = ExternalSource->GetExternalSelector(I);
Sebastian Redldb9d2142010-08-02 23:18:59 +00005088 if (Sel.isNull() || MethodPool.count(Sel))
Douglas Gregor1f5537a2010-07-08 23:20:03 +00005089 continue;
Sebastian Redldb9d2142010-08-02 23:18:59 +00005090
5091 ReadMethodPool(Sel);
Douglas Gregor1f5537a2010-07-08 23:20:03 +00005092 }
5093 }
5094
5095 // Build the set of methods we can see.
John McCall0a2c5e22010-08-25 06:19:51 +00005096 typedef CodeCompletionResult Result;
Douglas Gregor1f5537a2010-07-08 23:20:03 +00005097 ResultBuilder Results(*this);
5098
5099 if (ReturnTy)
5100 Results.setPreferredType(GetTypeFromParser(ReturnTy).getNonReferenceType());
Sebastian Redldb9d2142010-08-02 23:18:59 +00005101
Douglas Gregor1f5537a2010-07-08 23:20:03 +00005102 Results.EnterNewScope();
Sebastian Redldb9d2142010-08-02 23:18:59 +00005103 for (GlobalMethodPool::iterator M = MethodPool.begin(),
5104 MEnd = MethodPool.end();
5105 M != MEnd; ++M) {
5106 for (ObjCMethodList *MethList = IsInstanceMethod ? &M->second.first :
5107 &M->second.second;
5108 MethList && MethList->Method;
Douglas Gregor1f5537a2010-07-08 23:20:03 +00005109 MethList = MethList->Next) {
5110 if (!isAcceptableObjCMethod(MethList->Method, MK_Any, SelIdents,
5111 NumSelIdents))
5112 continue;
5113
Douglas Gregor40ed9a12010-07-08 23:37:41 +00005114 if (AtParameterName) {
5115 // Suggest parameter names we've seen before.
5116 if (NumSelIdents && NumSelIdents <= MethList->Method->param_size()) {
5117 ParmVarDecl *Param = MethList->Method->param_begin()[NumSelIdents-1];
5118 if (Param->getIdentifier()) {
5119 CodeCompletionString *Pattern = new CodeCompletionString;
5120 Pattern->AddTypedTextChunk(Param->getIdentifier()->getName());
5121 Results.AddResult(Pattern);
5122 }
5123 }
5124
5125 continue;
5126 }
5127
Douglas Gregor1f5537a2010-07-08 23:20:03 +00005128 Result R(MethList->Method, 0);
5129 R.StartParameter = NumSelIdents;
5130 R.AllParametersAreInformative = false;
5131 R.DeclaringEntity = true;
5132 Results.MaybeAddResult(R, CurContext);
5133 }
5134 }
5135
5136 Results.ExitScope();
Douglas Gregore6b1bb62010-08-11 21:23:17 +00005137 HandleCodeCompleteResults(this, CodeCompleter,
5138 CodeCompletionContext::CCC_Other,
5139 Results.data(),Results.size());
Douglas Gregor1f5537a2010-07-08 23:20:03 +00005140}
Douglas Gregor87c08a52010-08-13 22:48:40 +00005141
Douglas Gregorf29c5232010-08-24 22:20:20 +00005142void Sema::CodeCompletePreprocessorDirective(bool InConditional) {
Douglas Gregorf44e8542010-08-24 19:08:16 +00005143 ResultBuilder Results(*this);
5144 Results.EnterNewScope();
5145
5146 // #if <condition>
5147 CodeCompletionString *Pattern = new CodeCompletionString;
5148 Pattern->AddTypedTextChunk("if");
5149 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
5150 Pattern->AddPlaceholderChunk("condition");
5151 Results.AddResult(Pattern);
5152
5153 // #ifdef <macro>
5154 Pattern = new CodeCompletionString;
5155 Pattern->AddTypedTextChunk("ifdef");
5156 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
5157 Pattern->AddPlaceholderChunk("macro");
5158 Results.AddResult(Pattern);
5159
5160 // #ifndef <macro>
5161 Pattern = new CodeCompletionString;
5162 Pattern->AddTypedTextChunk("ifndef");
5163 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
5164 Pattern->AddPlaceholderChunk("macro");
5165 Results.AddResult(Pattern);
5166
5167 if (InConditional) {
5168 // #elif <condition>
5169 Pattern = new CodeCompletionString;
5170 Pattern->AddTypedTextChunk("elif");
5171 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
5172 Pattern->AddPlaceholderChunk("condition");
5173 Results.AddResult(Pattern);
5174
5175 // #else
5176 Pattern = new CodeCompletionString;
5177 Pattern->AddTypedTextChunk("else");
5178 Results.AddResult(Pattern);
5179
5180 // #endif
5181 Pattern = new CodeCompletionString;
5182 Pattern->AddTypedTextChunk("endif");
5183 Results.AddResult(Pattern);
5184 }
5185
5186 // #include "header"
5187 Pattern = new CodeCompletionString;
5188 Pattern->AddTypedTextChunk("include");
5189 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
5190 Pattern->AddTextChunk("\"");
5191 Pattern->AddPlaceholderChunk("header");
5192 Pattern->AddTextChunk("\"");
5193 Results.AddResult(Pattern);
5194
5195 // #include <header>
5196 Pattern = new CodeCompletionString;
5197 Pattern->AddTypedTextChunk("include");
5198 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
5199 Pattern->AddTextChunk("<");
5200 Pattern->AddPlaceholderChunk("header");
5201 Pattern->AddTextChunk(">");
5202 Results.AddResult(Pattern);
5203
5204 // #define <macro>
5205 Pattern = new CodeCompletionString;
5206 Pattern->AddTypedTextChunk("define");
5207 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
5208 Pattern->AddPlaceholderChunk("macro");
5209 Results.AddResult(Pattern);
5210
5211 // #define <macro>(<args>)
5212 Pattern = new CodeCompletionString;
5213 Pattern->AddTypedTextChunk("define");
5214 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
5215 Pattern->AddPlaceholderChunk("macro");
5216 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
5217 Pattern->AddPlaceholderChunk("args");
5218 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
5219 Results.AddResult(Pattern);
5220
5221 // #undef <macro>
5222 Pattern = new CodeCompletionString;
5223 Pattern->AddTypedTextChunk("undef");
5224 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
5225 Pattern->AddPlaceholderChunk("macro");
5226 Results.AddResult(Pattern);
5227
5228 // #line <number>
5229 Pattern = new CodeCompletionString;
5230 Pattern->AddTypedTextChunk("line");
5231 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
5232 Pattern->AddPlaceholderChunk("number");
5233 Results.AddResult(Pattern);
5234
5235 // #line <number> "filename"
5236 Pattern = new CodeCompletionString;
5237 Pattern->AddTypedTextChunk("line");
5238 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
5239 Pattern->AddPlaceholderChunk("number");
5240 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
5241 Pattern->AddTextChunk("\"");
5242 Pattern->AddPlaceholderChunk("filename");
5243 Pattern->AddTextChunk("\"");
5244 Results.AddResult(Pattern);
5245
5246 // #error <message>
5247 Pattern = new CodeCompletionString;
5248 Pattern->AddTypedTextChunk("error");
5249 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
5250 Pattern->AddPlaceholderChunk("message");
5251 Results.AddResult(Pattern);
5252
5253 // #pragma <arguments>
5254 Pattern = new CodeCompletionString;
5255 Pattern->AddTypedTextChunk("pragma");
5256 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
5257 Pattern->AddPlaceholderChunk("arguments");
5258 Results.AddResult(Pattern);
5259
5260 if (getLangOptions().ObjC1) {
5261 // #import "header"
5262 Pattern = new CodeCompletionString;
5263 Pattern->AddTypedTextChunk("import");
5264 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
5265 Pattern->AddTextChunk("\"");
5266 Pattern->AddPlaceholderChunk("header");
5267 Pattern->AddTextChunk("\"");
5268 Results.AddResult(Pattern);
5269
5270 // #import <header>
5271 Pattern = new CodeCompletionString;
5272 Pattern->AddTypedTextChunk("import");
5273 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
5274 Pattern->AddTextChunk("<");
5275 Pattern->AddPlaceholderChunk("header");
5276 Pattern->AddTextChunk(">");
5277 Results.AddResult(Pattern);
5278 }
5279
5280 // #include_next "header"
5281 Pattern = new CodeCompletionString;
5282 Pattern->AddTypedTextChunk("include_next");
5283 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
5284 Pattern->AddTextChunk("\"");
5285 Pattern->AddPlaceholderChunk("header");
5286 Pattern->AddTextChunk("\"");
5287 Results.AddResult(Pattern);
5288
5289 // #include_next <header>
5290 Pattern = new CodeCompletionString;
5291 Pattern->AddTypedTextChunk("include_next");
5292 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
5293 Pattern->AddTextChunk("<");
5294 Pattern->AddPlaceholderChunk("header");
5295 Pattern->AddTextChunk(">");
5296 Results.AddResult(Pattern);
5297
5298 // #warning <message>
5299 Pattern = new CodeCompletionString;
5300 Pattern->AddTypedTextChunk("warning");
5301 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
5302 Pattern->AddPlaceholderChunk("message");
5303 Results.AddResult(Pattern);
5304
5305 // Note: #ident and #sccs are such crazy anachronisms that we don't provide
5306 // completions for them. And __include_macros is a Clang-internal extension
5307 // that we don't want to encourage anyone to use.
5308
5309 // FIXME: we don't support #assert or #unassert, so don't suggest them.
5310 Results.ExitScope();
5311
Douglas Gregorf44e8542010-08-24 19:08:16 +00005312 HandleCodeCompleteResults(this, CodeCompleter,
Douglas Gregor721f3592010-08-25 18:41:16 +00005313 CodeCompletionContext::CCC_PreprocessorDirective,
Douglas Gregorf44e8542010-08-24 19:08:16 +00005314 Results.data(), Results.size());
5315}
5316
5317void Sema::CodeCompleteInPreprocessorConditionalExclusion(Scope *S) {
Douglas Gregorf29c5232010-08-24 22:20:20 +00005318 CodeCompleteOrdinaryName(S,
John McCallf312b1e2010-08-26 23:41:50 +00005319 S->getFnParent()? Sema::PCC_RecoveryInFunction
5320 : Sema::PCC_Namespace);
Douglas Gregorf44e8542010-08-24 19:08:16 +00005321}
5322
Douglas Gregorf29c5232010-08-24 22:20:20 +00005323void Sema::CodeCompletePreprocessorMacroName(bool IsDefinition) {
Douglas Gregor1fbb4472010-08-24 20:21:13 +00005324 ResultBuilder Results(*this);
5325 if (!IsDefinition && (!CodeCompleter || CodeCompleter->includeMacros())) {
5326 // Add just the names of macros, not their arguments.
5327 Results.EnterNewScope();
5328 for (Preprocessor::macro_iterator M = PP.macro_begin(),
5329 MEnd = PP.macro_end();
5330 M != MEnd; ++M) {
5331 CodeCompletionString *Pattern = new CodeCompletionString;
5332 Pattern->AddTypedTextChunk(M->first->getName());
5333 Results.AddResult(Pattern);
5334 }
5335 Results.ExitScope();
5336 } else if (IsDefinition) {
5337 // FIXME: Can we detect when the user just wrote an include guard above?
5338 }
5339
5340 HandleCodeCompleteResults(this, CodeCompleter,
5341 IsDefinition? CodeCompletionContext::CCC_MacroName
5342 : CodeCompletionContext::CCC_MacroNameUse,
5343 Results.data(), Results.size());
5344}
5345
Douglas Gregorf29c5232010-08-24 22:20:20 +00005346void Sema::CodeCompletePreprocessorExpression() {
5347 ResultBuilder Results(*this);
5348
5349 if (!CodeCompleter || CodeCompleter->includeMacros())
5350 AddMacroResults(PP, Results);
5351
5352 // defined (<macro>)
5353 Results.EnterNewScope();
5354 CodeCompletionString *Pattern = new CodeCompletionString;
5355 Pattern->AddTypedTextChunk("defined");
5356 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
5357 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
5358 Pattern->AddPlaceholderChunk("macro");
5359 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
5360 Results.AddResult(Pattern);
5361 Results.ExitScope();
5362
5363 HandleCodeCompleteResults(this, CodeCompleter,
5364 CodeCompletionContext::CCC_PreprocessorExpression,
5365 Results.data(), Results.size());
5366}
5367
5368void Sema::CodeCompletePreprocessorMacroArgument(Scope *S,
5369 IdentifierInfo *Macro,
5370 MacroInfo *MacroInfo,
5371 unsigned Argument) {
5372 // FIXME: In the future, we could provide "overload" results, much like we
5373 // do for function calls.
5374
5375 CodeCompleteOrdinaryName(S,
John McCallf312b1e2010-08-26 23:41:50 +00005376 S->getFnParent()? Sema::PCC_RecoveryInFunction
5377 : Sema::PCC_Namespace);
Douglas Gregorf29c5232010-08-24 22:20:20 +00005378}
5379
Douglas Gregor55817af2010-08-25 17:04:25 +00005380void Sema::CodeCompleteNaturalLanguage() {
Douglas Gregor55817af2010-08-25 17:04:25 +00005381 HandleCodeCompleteResults(this, CodeCompleter,
Douglas Gregoraf1c6b52010-08-25 17:10:00 +00005382 CodeCompletionContext::CCC_NaturalLanguage,
Douglas Gregor55817af2010-08-25 17:04:25 +00005383 0, 0);
5384}
5385
Douglas Gregor87c08a52010-08-13 22:48:40 +00005386void Sema::GatherGlobalCodeCompletions(
John McCall0a2c5e22010-08-25 06:19:51 +00005387 llvm::SmallVectorImpl<CodeCompletionResult> &Results) {
Douglas Gregor87c08a52010-08-13 22:48:40 +00005388 ResultBuilder Builder(*this);
5389
Douglas Gregor8071e422010-08-15 06:18:01 +00005390 if (!CodeCompleter || CodeCompleter->includeGlobals()) {
5391 CodeCompletionDeclConsumer Consumer(Builder,
5392 Context.getTranslationUnitDecl());
5393 LookupVisibleDecls(Context.getTranslationUnitDecl(), LookupAnyName,
5394 Consumer);
5395 }
Douglas Gregor87c08a52010-08-13 22:48:40 +00005396
5397 if (!CodeCompleter || CodeCompleter->includeMacros())
5398 AddMacroResults(PP, Builder);
5399
5400 Results.clear();
5401 Results.insert(Results.end(),
5402 Builder.data(), Builder.data() + Builder.size());
5403}